| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- <template>
- <div class="vip-page">
- <div class="page-inner">
- <div class="page-title">患者身份等级管理</div>
- <!-- 搜索模块 -->
- <div class="card search-card">
- <div class="search-fields">
- <zy-form inline class="fw search-form">
- <zy-form-item label="权益名称:">
- <zy-input
- v-model="queryData.benefitName"
- placeholder="请输入权益名称"
- clearable
- />
- </zy-form-item>
- <zy-form-item label="当前状态:">
- <zy-select
- v-model="queryData.status"
- placeholder="全部"
- clearable
- >
- <zy-option
- v-for="item in statusOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </zy-select>
- </zy-form-item>
- </zy-form>
- <div class="search-actions">
- <zy-button class="btn-search" type="primary" @click="getTableData()">
- 查询
- </zy-button>
- <zy-button class="btn-create" @click="handleCreate">
- + 新建服务权益包
- </zy-button>
- </div>
- </div>
- </div>
- <!-- 表格模块 -->
- <div class="card table-card" v-loading="table.loading">
- <zy-table
- height="100%"
- :data="table.data"
- header-align="center"
- align="center"
- :border="true"
- :fit="true"
- >
- <zy-table-column
- prop="levelCode"
- label="身份等级编号"
- />
- <zy-table-column
- prop="levelIconLabel"
- label="身份等级图标"
- >
- <template #default="{ row }">
- <img
- v-if="row.levelIconLabel"
- :src="getImageUrl(row.levelIconLabel)"
- class="level-icon-img"
- alt="身份等级图标"
- />
- <span v-else class="level-tag" :class="row.iconTheme">{{ row.levelIconLabel || "VIP" }}</span>
- </template>
- </zy-table-column>
- <zy-table-column
- prop="levelName"
- label="身份等级名称"
- />
- <zy-table-column
- prop="theme"
- label="主题"
- />
- <zy-table-column
- prop="statusLabel"
- label="当前状态"
- />
- <zy-table-column
- label="操作"
- >
- <template #default="{ row }">
- <zy-button type="text" class="link-btn" @click="handleEdit(row)">编辑</zy-button>
- </template>
- </zy-table-column>
- </zy-table>
- </div>
- <!-- 分页 -->
- <div class="card pagination-card">
- <zy-pagination
- :page-size="table.page.PSize"
- :total="table.page.PCount"
- :pager-count="7"
- layout="pager"
- v-model:currentPage="table.page.PIndex"
- @current-change="getTableData"
- ></zy-pagination>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { getCurrentInstance, reactive, ref, onMounted } from "vue";
- import { useStore } from "vuex";
- import { useRoute, useRouter } from "vue-router";
- const { proxy } = getCurrentInstance() as any;
- const store = useStore();
- const route = useRoute();
- const router = useRouter();
- // 搜索条件
- let queryData = reactive({
- benefitName: "",
- status: "",
- });
- const statusOptions = [
- { label: "全部", value: "" },
- { label: "上架", value: "1" },
- { label: "下架", value: "0" },
- ];
- const table = reactive({
- loading: false,
- data: [] as any[],
- page: {
- PIndex: 1,
- PSize: 10,
- PCount: 0,
- },
- });
- const defaultThemeOptions = [
- { label: "金色", value: "gold" },
- { label: "银色", value: "silver" },
- { label: "蓝色", value: "blue" },
- ];
- const themeOptions = ref<Array<{ label: string; value: string }>>([...defaultThemeOptions]);
- const themeMap = ref<Record<string, string>>(
- defaultThemeOptions.reduce((acc, cur) => {
- acc[cur.value] = cur.label;
- return acc;
- }, {} as Record<string, string>)
- );
- const fillThemeMap = (options: Array<{ label: string; value: string }>) => {
- themeMap.value = options.reduce((acc, cur) => {
- if (cur?.value) {
- acc[cur.value] = cur.label;
- }
- return acc;
- }, {} as Record<string, string>);
- };
- const queryTheme = async () => {
- try {
- const { res } = await proxy.$interfaceEntry.vip.QueryDictList({
- dictType: "VipColor",
- });
- const data = res.data || {};
- const list =
- data.Data ||
- data.data ||
- data.result ||
- data.list ||
- [];
- if (Array.isArray(list) && list.length) {
- const parsed = list.map((item: any) => ({
- label: item.dictLabel,
- value: item.dictValue,
- }));
- themeOptions.value = parsed;
- fillThemeMap(parsed);
- } else {
- themeOptions.value = [...defaultThemeOptions];
- fillThemeMap(defaultThemeOptions);
- }
- } catch (e) {
- themeOptions.value = [...defaultThemeOptions];
- fillThemeMap(defaultThemeOptions);
- }
- };
- /* 获取表格数据 */
- const getTableData = async (e: any = undefined) => {
- !e && (table.page.PIndex = 1);
- table.loading = true;
- try {
- // 直接使用 status 值,空字符串转为 undefined,其他转为数字
- const status = queryData.status === "" ? undefined : Number(queryData.status);
- const { res } = await proxy.$interfaceEntry.vip.QueryPatientLevel({
- IdLevelName: queryData.benefitName || undefined,
- Status: status,
- PageIndex: table.page.PIndex,
- PageSize: table.page.PSize,
- });
-
- if (res.data?.RespCode != 10000) {
- proxy.$message.error(res.data?.errorMsg || res.data?.msg || "查询失败");
- table.data = [];
- table.page.PCount = 0;
- return;
- }
- // 数据结构:res.data.Data[0].DataList 是实际的数据列表
- const dataWrapper = res.data.Data?.[0] || {};
- const list = dataWrapper.DataList || res.data.Data || res.data.list || res.data.List || [];
-
- // 分页信息:从 Page 对象获取
- const pageInfo = res.data.Page || {};
- const totalCount = pageInfo.PCount || dataWrapper.Total || res.data.PCount || res.data.total || list.length;
- table.page.PCount = totalCount;
- table.data = list.map((item: any) => {
- // 后端返回的字段可能是 IdLevelIcon(大写)或 idLevelIcon(小写)
- const iconPath = item.IdLevelIcon || item.idLevelIcon || "";
- const themeValue = item.Theme || item.theme;
- return {
- levelCode: item.IdLevelCode || item.idLevelCode,
- levelIconLabel: iconPath,
- levelName: item.IdLevelName || item.idLevelName,
- theme: themeMap.value[themeValue] || themeValue || "-",
- statusLabel: (item.Status || item.status) === 1 ? "上架" : "下架",
- // 保存原始数据,编辑时可能需要
- rawData: item,
- };
- });
- } catch (err) {
- table.data = [];
- table.page.PCount = 0;
- proxy.$message.error("查询失败");
- } finally {
- table.loading = false;
- }
- };
- /** 重置搜索条件 */
- const resetData = () => {
- Object.keys(queryData).forEach((key: any) => {
- (queryData as any)[key] = "";
- });
- getTableData();
- };
- const handleCreate = () => {
- router.push({
- name: "vipEdit",
- query: {
- mode: "create",
- },
- });
- };
- // 获取图片完整 URL
- const getImageUrl = (iconPath: string) => {
- if (!iconPath) return "";
- // 如果路径不是以 http:// 或 https:// 或 / 开头,加上 / 前缀
- if (!iconPath.startsWith("http://") && !iconPath.startsWith("https://") && !iconPath.startsWith("/")) {
- return "/" + iconPath;
- }
- return iconPath;
- };
- const handleEdit = (row: any) => {
- router.push({
- name: "vipEdit",
- query: {
- mode: "edit",
- code: row.levelCode,
- name: row.levelName,
- theme: row.theme,
- status: row.statusLabel === "上架" ? "1" : "0",
- icon: row.levelIconLabel,
- },
- });
- };
- onMounted(async () => {
- await queryTheme();
- getTableData();
- });
- </script>
- <style scoped>
- .vip-page {
- min-height: 100%;
- background: #f5f7fb;
- padding: 24px 0 32px;
- box-sizing: border-box;
- }
- .page-inner {
- width: 1560px;
- margin: 0 auto;
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
- .page-title {
- font-size: 20px;
- font-weight: 600;
- color: var(--el-text-color-primary);
- }
- .card {
- background: #ffffff;
- border-radius: 8px;
- box-shadow: 0 6px 24px rgba(44, 69, 105, 0.08);
- padding: 18px 24px;
- box-sizing: border-box;
- }
- .search-card {
- display: flex;
- flex-direction: column;
- }
- .search-fields {
- display: flex;
- align-items: center;
- justify-content: flex-start;
- flex-wrap: nowrap;
- gap: 16px;
- }
- .search-form {
- display: flex;
- align-items: center;
- }
- .search-form :deep(.el-form-item) {
- margin: 0 16px 0 0;
- }
- .search-form :deep(.el-form-item__label) {
- color: #555;
- }
- .search-form :deep(.el-input__inner) {
- width: 220px;
- }
- .search-actions {
- display: flex;
- align-items: center;
- gap: 12px;
- margin-left: auto;
- white-space: nowrap;
- }
- .btn-search {
- background: var(--el-color-primary);
- border-color: var(--el-color-primary);
- color: #fff;
- padding: 10px 32px;
- }
- .btn-create {
- background: var(--el-color-primary-light-9);
- border-color: var(--el-color-primary-light-7);
- color: var(--el-color-primary);
- padding: 10px 24px;
- }
- .table-card {
- padding: 0;
- overflow: hidden;
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .table-card :deep(.el-table) {
- width: 100%;
- border: none;
- flex: 1;
- }
- .table-card :deep(.el-table__header th),
- .table-card :deep(.el-table__body td) {
- text-align: center;
- font-size: 14px;
- }
- .table-card :deep(.el-table__body-wrapper),
- .table-card :deep(.el-table__header-wrapper) {
- padding: 0;
- }
- /* 按 3:3:8:2:2:2 比例填满整行(共 20 份) */
- .table-card :deep(.el-table__header colgroup col:nth-child(1)),
- .table-card :deep(.el-table__body colgroup col:nth-child(1)) {
- width: 15% !important; /* 3/20 */
- }
- .table-card :deep(.el-table__header colgroup col:nth-child(2)),
- .table-card :deep(.el-table__body colgroup col:nth-child(2)) {
- width: 15% !important; /* 3/20 */
- }
- .table-card :deep(.el-table__header colgroup col:nth-child(3)),
- .table-card :deep(.el-table__body colgroup col:nth-child(3)) {
- width: 40% !important; /* 8/20 */
- }
- .table-card :deep(.el-table__header colgroup col:nth-child(4)),
- .table-card :deep(.el-table__body colgroup col:nth-child(4)) {
- width: 10% !important; /* 2/20 */
- }
- .table-card :deep(.el-table__header colgroup col:nth-child(5)),
- .table-card :deep(.el-table__body colgroup col:nth-child(5)) {
- width: 10% !important; /* 2/20 */
- }
- .table-card :deep(.el-table__header colgroup col:nth-child(6)),
- .table-card :deep(.el-table__body colgroup col:nth-child(6)) {
- width: 10% !important; /* 2/20 */
- }
- .level-icon-img {
- width: 60px;
- height: 60px;
- object-fit: contain;
- border-radius: 4px;
- }
- .level-tag {
- display: inline-block;
- padding: 6px 18px;
- border-radius: 6px;
- font-size: 14px;
- color: #fff;
- min-width: 60px;
- }
- .tag-vip {
- background: #f69c45;
- }
- .tag-svip {
- background: #f67f45;
- }
- .tag-wip {
- background: #f45d45;
- }
- .link-btn {
- color: #2e74c6;
- }
- .pagination-card {
- display: flex;
- justify-content: center;
- padding: 16px;
- margin-top: auto;
- margin-bottom: 0;
- }
- .pagination-card :deep(.el-pagination.is-background .el-pager li) {
- background-color: #fff;
- border: 1px solid #dcdfe6;
- color: var(--el-text-color-regular);
- margin: 0 6px;
- border-radius: 6px;
- min-width: 42px;
- height: 34px;
- line-height: 34px;
- }
- .pagination-card :deep(.el-pagination.is-background .el-pager li.is-active) {
- background-color: var(--el-color-primary);
- border-color: var(--el-color-primary);
- color: #fff;
- }
- </style>
|