管理后台前后端逻辑、UI美化

This commit is contained in:
Cheng Zhou
2026-01-16 13:50:08 +08:00
parent 05c1f9579a
commit 7fdcfdaadd
82 changed files with 3210 additions and 549 deletions
+46 -5
View File
@@ -3,7 +3,6 @@
<div class="page-header">
<div>
<h1 class="page-title">{{ TEXT.modules.drugShipments.title }}</h1>
<p class="page-subtitle">{{ TEXT.modules.drugShipments.subtitle }}</p>
</div>
<el-button type="primary" @click="goNew">{{ TEXT.modules.drugShipments.newTitle }}</el-button>
</div>
@@ -43,7 +42,13 @@
</el-card>
<el-card>
<el-table :data="items" v-loading="loading" style="width: 100%" @row-click="onRowClick">
<el-table
:data="sortedItems"
v-loading="loading"
style="width: 100%"
:row-class-name="shipmentRowClass"
@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>
@@ -78,17 +83,25 @@
</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>
<el-button
link
type="danger"
size="small"
:disabled="isInactiveSite(scope.row.center_id)"
@click.stop="remove(scope.row)"
>
{{ TEXT.common.actions.delete }}
</el-button>
</template>
</el-table-column>
</el-table>
<StateEmpty v-if="!loading && items.length === 0" :description="TEXT.modules.drugShipments.empty" />
<StateEmpty v-if="!loading && sortedItems.length === 0" :description="TEXT.modules.drugShipments.empty" />
</el-card>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { computed, onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { useStudyStore } from "../../store/study";
@@ -103,6 +116,7 @@ const study = useStudyStore();
const loading = ref(false);
const items = ref<any[]>([]);
const sites = ref<any[]>([]);
const siteActiveMap = ref<Record<string, boolean>>({});
const filters = reactive({
center_id: "",
direction: "",
@@ -115,8 +129,13 @@ const loadSites = async () => {
try {
const { data } = await fetchSites(studyId, { limit: 500 });
sites.value = Array.isArray(data) ? data : data.items || [];
siteActiveMap.value = sites.value.reduce((acc: Record<string, boolean>, site: any) => {
acc[site.id] = !!site.is_active;
return acc;
}, {});
} catch {
sites.value = [];
siteActiveMap.value = {};
}
};
@@ -151,6 +170,12 @@ const onRowClick = (row: any) => {
if (!row?.id) return;
goDetail(row.id);
};
const isInactiveSite = (siteId?: string) => !!siteId && siteActiveMap.value[siteId] === false;
const shipmentRowClass = ({ row }: { row: any }) =>
`${row?.id ? "clickable-row" : ""}${isInactiveSite(row?.center_id) ? " row-inactive" : ""}`.trim();
const sortedItems = computed(() =>
[...items.value].sort((a, b) => Number(isInactiveSite(a?.center_id)) - Number(isInactiveSite(b?.center_id)))
);
const statusType = (status: string) => {
switch (status) {
@@ -172,6 +197,10 @@ const statusType = (status: string) => {
const remove = async (row: any) => {
const studyId = study.currentStudy?.id;
if (!studyId) return;
if (isInactiveSite(row?.center_id)) {
ElMessage.warning("中心已停用");
return;
}
const ok = await ElMessageBox.confirm(TEXT.modules.drugShipments.confirmDelete, TEXT.common.labels.tips).catch(() => null);
if (!ok) return;
try {
@@ -196,6 +225,7 @@ onMounted(async () => {
gap: 16px;
}
.page-header {
display: flex;
justify-content: space-between;
@@ -218,3 +248,14 @@ onMounted(async () => {
margin-bottom: 0;
}
</style>
<style>
.row-inactive td {
color: var(--ctms-text-secondary);
background-color: #fff7d6 !important;
}
.row-inactive .el-tag {
opacity: 0.6;
}
</style>