209 lines
5.7 KiB
Vue
209 lines
5.7 KiB
Vue
<template>
|
|
<full-page pageClass="record-page" :customScroll="true">
|
|
<view class="page-body">
|
|
<view class="profile-card">
|
|
<view class="profile-title">{{ customerName || "未选择档案" }}</view>
|
|
<view class="profile-sub">治疗记录</view>
|
|
</view>
|
|
|
|
<view v-if="loading" class="empty">加载中...</view>
|
|
<view v-else-if="!records.length" class="empty">暂无治疗记录</view>
|
|
<view v-else class="record-list">
|
|
<view v-for="item in records" :key="item._id" class="record-card">
|
|
<view class="record-head">
|
|
<view class="record-title">{{ item.projectName || "未命名项目" }}</view>
|
|
<view class="status-tag" :class="statusClass(item)">{{ statusText(item) }}</view>
|
|
</view>
|
|
<view class="record-row">
|
|
<text class="row-label">治疗科室</text>
|
|
<text class="row-value">{{ item.treatmentDeptName || "-" }}</text>
|
|
</view>
|
|
<view class="record-row">
|
|
<text class="row-label">购买数量</text>
|
|
<text class="row-value">{{ item.usageCount || 0 }}</text>
|
|
</view>
|
|
<view class="record-row">
|
|
<text class="row-label">剩余数量</text>
|
|
<text class="row-value strong">{{ item.restUsageCount || 0 }}</text>
|
|
</view>
|
|
<view class="record-row">
|
|
<text class="row-label">有效期</text>
|
|
<text class="row-value">{{ formatValidTime(item.validTime) }}</text>
|
|
</view>
|
|
<view class="record-row">
|
|
<text class="row-label">购买日期</text>
|
|
<text class="row-value">{{ formatTime(item.createTreatementTime || item.billTime) }}</text>
|
|
</view>
|
|
<view v-if="item.packageName" class="record-row">
|
|
<text class="row-label">所属套餐</text>
|
|
<text class="row-value">{{ item.packageName }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</full-page>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from "vue";
|
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
import api from "@/utils/api";
|
|
import { normalizeCorpId } from "@/utils/api-base-config";
|
|
import { toast } from "@/utils/widget";
|
|
import FullPage from "@/components/full-page.vue";
|
|
|
|
const corpId = ref("");
|
|
const customerId = ref("");
|
|
const customerName = ref("");
|
|
const records = ref([]);
|
|
const loading = ref(false);
|
|
|
|
const statusMap = {
|
|
init: { label: "待治疗", className: "status-wait" },
|
|
pending: { label: "治疗中", className: "status-doing" },
|
|
treated: { label: "已治疗", className: "status-done" },
|
|
void: { label: "已作废", className: "status-cancel" },
|
|
};
|
|
|
|
function formatTime(ts) {
|
|
if (!ts) return "-";
|
|
const d = new Date(Number(ts));
|
|
if (Number.isNaN(d.getTime())) return "-";
|
|
const y = d.getFullYear();
|
|
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
const day = String(d.getDate()).padStart(2, "0");
|
|
const h = String(d.getHours()).padStart(2, "0");
|
|
const min = String(d.getMinutes()).padStart(2, "0");
|
|
return `${y}-${m}-${day} ${h}:${min}`;
|
|
}
|
|
|
|
function formatValidTime(ts) {
|
|
if (!ts) return "无限期";
|
|
return formatTime(ts).slice(0, 10);
|
|
}
|
|
|
|
function statusText(item) {
|
|
return statusMap[item?.treatmentStatus]?.label || item?.treatmentStatusStr || "-";
|
|
}
|
|
|
|
function statusClass(item) {
|
|
return statusMap[item?.treatmentStatus]?.className || "status-wait";
|
|
}
|
|
|
|
async function loadRecords() {
|
|
if (!corpId.value || !customerId.value) {
|
|
records.value = [];
|
|
return;
|
|
}
|
|
loading.value = true;
|
|
try {
|
|
const res = await api(
|
|
"getTreatmentRecord",
|
|
{
|
|
corpId: corpId.value,
|
|
customerId: customerId.value,
|
|
page: 1,
|
|
pageSize: 200,
|
|
},
|
|
false
|
|
);
|
|
if (!res?.success) {
|
|
toast(res?.message || "加载治疗记录失败");
|
|
records.value = [];
|
|
return;
|
|
}
|
|
records.value = res.list || res.data?.list || [];
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
onLoad(async (options = {}) => {
|
|
uni.setNavigationBarTitle({ title: "治疗记录" });
|
|
corpId.value = normalizeCorpId(options.corpId || "");
|
|
customerId.value = options.customerId || options.id || "";
|
|
customerName.value = options.name ? decodeURIComponent(options.name) : "";
|
|
await loadRecords();
|
|
});
|
|
|
|
onShow(() => {
|
|
if (corpId.value && customerId.value) loadRecords();
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.page-body {
|
|
min-height: 100%;
|
|
padding: 24rpx;
|
|
box-sizing: border-box;
|
|
background: #f5f6fa;
|
|
}
|
|
.profile-card,
|
|
.record-card {
|
|
background: #fff;
|
|
border-radius: 18rpx;
|
|
padding: 24rpx;
|
|
margin-bottom: 20rpx;
|
|
box-shadow: 0 8rpx 24rpx rgba(15, 23, 42, 0.06);
|
|
}
|
|
.profile-title {
|
|
font-size: 34rpx;
|
|
font-weight: 600;
|
|
color: #1f2329;
|
|
}
|
|
.profile-sub {
|
|
margin-top: 8rpx;
|
|
font-size: 24rpx;
|
|
color: #8a8f99;
|
|
}
|
|
.record-head,
|
|
.record-row {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 20rpx;
|
|
}
|
|
.record-head {
|
|
margin-bottom: 18rpx;
|
|
}
|
|
.record-title {
|
|
flex: 1;
|
|
min-width: 0;
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #1f2329;
|
|
}
|
|
.status-tag {
|
|
flex-shrink: 0;
|
|
padding: 6rpx 16rpx;
|
|
border-radius: 999rpx;
|
|
font-size: 22rpx;
|
|
}
|
|
.status-wait { color: #065bd6; background: rgba(6, 91, 214, 0.1); }
|
|
.status-doing { color: #d97706; background: rgba(217, 119, 6, 0.12); }
|
|
.status-done { color: #16a34a; background: rgba(22, 163, 74, 0.12); }
|
|
.status-cancel { color: #8a8f99; background: #f1f2f4; }
|
|
.record-row {
|
|
padding: 10rpx 0;
|
|
font-size: 26rpx;
|
|
}
|
|
.row-label {
|
|
flex-shrink: 0;
|
|
color: #8a8f99;
|
|
}
|
|
.row-value {
|
|
min-width: 0;
|
|
text-align: right;
|
|
color: #1f2329;
|
|
}
|
|
.strong {
|
|
color: #065bd6;
|
|
font-weight: 600;
|
|
}
|
|
.empty {
|
|
padding: 120rpx 0;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
}
|
|
</style> |