药品流向管理内容优化-初步

This commit is contained in:
Cheng Zhou
2026-01-13 19:42:28 +08:00
parent 1db36f40b0
commit ef1e67218c
21 changed files with 344 additions and 480 deletions
+88 -23
View File
@@ -11,13 +11,23 @@
<el-card class="filter-card">
<el-form :inline="true" :model="filters">
<el-form-item :label="TEXT.common.fields.site">
<el-input v-model="filters.site_name" :placeholder="TEXT.common.placeholders.input + TEXT.common.fields.site" clearable />
<el-select v-model="filters.center_id" :placeholder="TEXT.common.placeholders.select" clearable style="width: 200px">
<el-option
v-for="site in sites"
:key="site.id"
:label="site.name || TEXT.common.fallback"
:value="site.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="TEXT.common.fields.trackingNo">
<el-input v-model="filters.tracking_no" :placeholder="TEXT.common.placeholders.input + TEXT.common.fields.trackingNo" clearable />
<el-form-item :label="TEXT.common.fields.direction">
<el-select v-model="filters.direction" :placeholder="TEXT.common.placeholders.select" clearable style="width: 160px">
<el-option :label="TEXT.enums.shipmentDirection.SEND" value="SEND" />
<el-option :label="TEXT.enums.shipmentDirection.RETURN" value="RETURN" />
</el-select>
</el-form-item>
<el-form-item :label="TEXT.common.fields.status">
<el-select v-model="filters.status" :placeholder="TEXT.common.placeholders.select" clearable>
<el-select v-model="filters.status" :placeholder="TEXT.common.placeholders.select" clearable style="width: 160px">
<el-option :label="TEXT.enums.shipmentStatus.PENDING" value="PENDING" />
<el-option :label="TEXT.enums.shipmentStatus.IN_TRANSIT" value="IN_TRANSIT" />
<el-option :label="TEXT.enums.shipmentStatus.SIGNED" value="SIGNED" />
@@ -33,23 +43,42 @@
</el-card>
<el-card>
<el-table :data="items" v-loading="loading" style="width: 100%">
<el-table-column prop="direction" :label="TEXT.common.fields.direction" width="100">
<template #default="scope">{{ displayEnum(TEXT.enums.shipmentDirection, scope.row.direction) }}</template>
<el-table :data="items" v-loading="loading" style="width: 100%" @row-click="onRowClick">
<el-table-column prop="site_name" :label="TEXT.common.fields.site" min-width="160">
<template #default="scope">{{ scope.row.site_name || TEXT.common.fallback }}</template>
</el-table-column>
<el-table-column prop="direction" :label="TEXT.common.fields.direction" width="100">
<template #default="scope">
<el-tag :type="scope.row.direction === 'SEND' ? 'primary' : 'warning'" disable-transitions>
{{ displayEnum(TEXT.enums.shipmentDirection, scope.row.direction) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="site_name" :label="TEXT.common.fields.site" min-width="160" />
<el-table-column prop="tracking_no" :label="TEXT.common.fields.trackingNo" min-width="160" />
<el-table-column prop="ship_date" :label="TEXT.common.fields.shipDate" width="140">
<template #default="scope">{{ displayDate(scope.row.ship_date) }}</template>
</el-table-column>
<el-table-column prop="status" :label="TEXT.common.fields.status" width="120">
<template #default="scope">{{ displayEnum(TEXT.enums.shipmentStatus, scope.row.status) }}</template>
<el-table-column prop="receive_date" :label="TEXT.common.fields.receiveDate" width="140">
<template #default="scope">{{ displayDate(scope.row.receive_date) }}</template>
</el-table-column>
<el-table-column :label="TEXT.common.labels.actions" width="200">
<el-table-column prop="quantity" :label="TEXT.common.fields.quantity" width="120" align="right">
<template #default="scope">{{ typeof scope.row.quantity === "number" ? scope.row.quantity : TEXT.common.fallback }}</template>
</el-table-column>
<el-table-column prop="batch_no" :label="TEXT.common.fields.batchNo" min-width="140">
<template #default="scope">{{ scope.row.batch_no || TEXT.common.fallback }}</template>
</el-table-column>
<el-table-column prop="status" :label="TEXT.common.fields.status" width="120">
<template #default="scope">
<el-button link type="primary" size="small" @click="goDetail(scope.row.id)">{{ TEXT.common.actions.view }}</el-button>
<el-button link type="primary" size="small" @click="goEdit(scope.row.id)">{{ TEXT.common.actions.edit }}</el-button>
<el-button link type="danger" size="small" @click="remove(scope.row)">{{ TEXT.common.actions.delete }}</el-button>
<el-tag :type="statusType(scope.row.status)" disable-transitions>
{{ displayEnum(TEXT.enums.shipmentStatus, scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" :label="TEXT.common.fields.remark" min-width="160" show-overflow-tooltip>
<template #default="scope">{{ scope.row.remark || TEXT.common.fallback }}</template>
</el-table-column>
<el-table-column :label="TEXT.common.labels.actions" width="120" fixed="right">
<template #default="scope">
<el-button link type="danger" size="small" @click.stop="remove(scope.row)">{{ TEXT.common.actions.delete }}</el-button>
</template>
</el-table-column>
</el-table>
@@ -64,6 +93,7 @@ import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { useStudyStore } from "../../store/study";
import { listDrugShipments, deleteDrugShipment } from "../../api/drugShipments";
import { fetchSites } from "../../api/sites";
import { displayDate, displayEnum } from "../../utils/display";
import StateEmpty from "../../components/StateEmpty.vue";
import { TEXT } from "../../locales";
@@ -72,20 +102,32 @@ const router = useRouter();
const study = useStudyStore();
const loading = ref(false);
const items = ref<any[]>([]);
const sites = ref<any[]>([]);
const filters = reactive({
site_name: "",
tracking_no: "",
center_id: "",
direction: "",
status: "",
});
const loadSites = async () => {
const studyId = study.currentStudy?.id;
if (!studyId) return;
try {
const { data } = await fetchSites(studyId, { limit: 500 });
sites.value = Array.isArray(data) ? data : data.items || [];
} catch {
sites.value = [];
}
};
const load = async () => {
const studyId = study.currentStudy?.id;
if (!studyId) return;
loading.value = true;
try {
const { data } = await listDrugShipments(studyId, {
site_name: filters.site_name || undefined,
tracking_no: filters.tracking_no || undefined,
center_id: filters.center_id || undefined,
direction: filters.direction || undefined,
status: filters.status || undefined,
});
items.value = Array.isArray(data) ? data : data.items || [];
@@ -97,15 +139,35 @@ const load = async () => {
};
const resetFilters = () => {
filters.site_name = "";
filters.tracking_no = "";
filters.center_id = "";
filters.direction = "";
filters.status = "";
load();
};
const goNew = () => router.push("/drug/shipments/new");
const goDetail = (id: string) => router.push(`/drug/shipments/${id}`);
const goEdit = (id: string) => router.push(`/drug/shipments/${id}/edit`);
const onRowClick = (row: any) => {
if (!row?.id) return;
goDetail(row.id);
};
const statusType = (status: string) => {
switch (status) {
case "PENDING":
return "info";
case "IN_TRANSIT":
return "primary";
case "SIGNED":
return "success";
case "RETURNED":
return "warning";
case "EXCEPTION":
return "danger";
default:
return "info";
}
};
const remove = async (row: any) => {
const studyId = study.currentStudy?.id;
@@ -121,7 +183,10 @@ const remove = async (row: any) => {
}
};
onMounted(load);
onMounted(async () => {
await loadSites();
load();
});
</script>
<style scoped>