Files
gpf_pet_hospital/frontend/src/pages/VisitPage.vue

292 lines
9.0 KiB
Vue

<template>
<div class="page">
<h2 class="page-title">就诊记录</h2>
<div class="panel">
<div class="inline-form">
<t-button theme="primary" @click="load">
<template #icon><t-icon name="refresh" /></template>
刷新
</t-button>
<t-button variant="outline" @click="openCreate">
<template #icon><t-icon name="add" /></template>
新增就诊
</t-button>
</div>
<t-table :data="list" :columns="columns" row-key="id" bordered stripe hover>
<template #status="{ row }">
<span class="status-badge" :class="getStatusClass(row.status)">
{{ getStatusText(row.status) }}
</span>
</template>
<template #paymentStatus="{ row }">
<span class="status-badge" :class="getPaymentStatusClass(row.paymentStatus)">
{{ getPaymentStatusText(row.paymentStatus) }}
</span>
</template>
<template #op="{ row }">
<div class="table-actions">
<t-button size="small" variant="outline" @click="openEdit(row)">
<template #icon><t-icon name="edit" /></template>
编辑
</t-button>
</div>
</template>
</t-table>
</div>
<t-dialog v-model:visible="dialogVisible" :header="dialogTitle" :on-confirm="submit" width="600">
<t-form :data="form" layout="vertical">
<div class="form-section-title">基本信息</div>
<t-form-item label="顾客" required>
<t-select v-model="form.customerId" :options="customerOptions" placeholder="请选择顾客" clearable />
</t-form-item>
<t-form-item label="宠物" required>
<t-select v-model="form.petId" :options="petOptions" placeholder="请选择宠物" clearable />
</t-form-item>
<t-form-item label="医生" required>
<t-select v-model="form.doctorId" :options="doctorOptions" placeholder="请选择医生" clearable />
</t-form-item>
<div class="form-section-title">就诊信息</div>
<t-form-item label="症状描述">
<t-textarea v-model="form.symptoms" placeholder="请输入症状描述" :maxlength="500" />
</t-form-item>
<t-form-item label="诊断结果">
<t-textarea v-model="form.diagnosis" placeholder="请输入诊断结果" :maxlength="500" />
</t-form-item>
<t-form-item label="治疗方案">
<t-textarea v-model="form.treatmentPlan" placeholder="请输入治疗方案" :maxlength="500" />
</t-form-item>
<div class="form-section-title">状态信息</div>
<t-row :gutter="[16, 16]">
<t-col :span="6">
<t-form-item label="就诊状态">
<t-select v-model="form.status" :options="statusOptions" />
</t-form-item>
</t-col>
<t-col :span="6">
<t-form-item label="支付状态">
<t-select v-model="form.paymentStatus" :options="payStatusOptions" />
</t-form-item>
</t-col>
<t-col :span="6">
<t-form-item label="支付方式">
<t-select v-model="form.paymentMethod" :options="payMethodOptions" />
</t-form-item>
</t-col>
<t-col :span="6">
<t-form-item label="总金额">
<t-input-number v-model="form.totalAmount" placeholder="0.00" suffix="元" />
</t-form-item>
</t-col>
</t-row>
</t-form>
</t-dialog>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, computed } from 'vue';
import { MessagePlugin } from 'tdesign-vue-next';
import { api } from '../api';
const list = ref([] as any[]);
const customers = ref([] as any[]);
const pets = ref([] as any[]);
const doctors = ref([] as any[]);
const dialogVisible = ref(false);
const dialogTitle = ref('新增就诊');
const editingId = ref<number | null>(null);
const form = reactive({
customerId: '',
petId: '',
doctorId: '',
status: 'IN_PROGRESS',
paymentStatus: 'UNPAID',
paymentMethod: 'OFFLINE',
});
const customerOptions = computed(() => {
return customers.value.map((customer: any) => ({
label: customer.username || `顾客${customer.id}`,
value: customer.id
}));
});
const petOptions = computed(() => {
return pets.value.map((pet: any) => ({
label: `${pet.name} (${pet.breed})`,
value: pet.id
}));
});
const doctorOptions = computed(() => {
return doctors.value.map((doctor: any) => ({
label: doctor.name,
value: doctor.id
}));
});
const getStatusText = (status: string) => {
const statusMap: Record<string, string> = {
'IN_PROGRESS': '就诊中',
'COMPLETED': '已完成',
'CANCELLED': '已取消'
};
return statusMap[status] || status;
};
const getStatusClass = (status: string) => {
const classMap: Record<string, string> = {
'IN_PROGRESS': 'status-pending',
'COMPLETED': 'status-active',
'CANCELLED': 'status-cancelled'
};
return classMap[status] || 'status-pending';
};
const getPaymentStatusText = (status: string) => {
const statusMap: Record<string, string> = {
'UNPAID': '未支付',
'PAID': '已支付',
'REFUNDING': '退款中',
'REFUNDED': '已退款',
'CANCELLED': '已取消'
};
return statusMap[status] || status;
};
const getPaymentStatusClass = (status: string) => {
const classMap: Record<string, string> = {
'UNPAID': 'status-pending',
'PAID': 'status-active',
'REFUNDING': 'status-warning',
'REFUNDED': 'status-cancelled',
'CANCELLED': 'status-cancelled'
};
return classMap[status] || 'status-pending';
};
const statusOptions = [
{ label: '就诊中', value: 'IN_PROGRESS' },
{ label: '已完成', value: 'COMPLETED' },
];
const payStatusOptions = [
{ label: '未支付', value: 'UNPAID' },
{ label: '已支付', value: 'PAID' },
{ label: '退款中', value: 'REFUNDING' },
{ label: '已退款', value: 'REFUNDED' },
];
const payMethodOptions = [
{ label: '线下', value: 'OFFLINE' },
{ label: '支付宝', value: 'ALIPAY' },
{ label: '微信', value: 'WECHAT' },
];
const columns = [
{ colKey: 'id', title: 'ID', width: 80 },
{ colKey: 'customerId', title: '顾客ID' },
{ colKey: 'petId', title: '宠物ID' },
{ colKey: 'doctorId', title: '医生ID' },
{ colKey: 'status', title: '就诊状态' },
{ colKey: 'paymentStatus', title: '支付状态' },
{ colKey: 'totalAmount', title: '总金额', width: 100 },
{ colKey: 'op', title: '操作', width: 120 },
];
const load = async () => {
const res = await api.visits({ page: 1, size: 20 });
if (res.code === 0) list.value = res.data.records || [];
};
const openCreate = () => {
dialogTitle.value = '新增就诊';
editingId.value = null;
form.customerId = '';
form.petId = '';
form.doctorId = '';
form.status = 'IN_PROGRESS';
form.paymentStatus = 'UNPAID';
form.paymentMethod = 'OFFLINE';
dialogVisible.value = true;
};
const openEdit = (row: any) => {
dialogTitle.value = '编辑就诊';
editingId.value = row.id;
form.customerId = row.customerId || '';
form.petId = row.petId || '';
form.doctorId = row.doctorId || '';
form.status = row.status || 'IN_PROGRESS';
form.paymentStatus = row.paymentStatus || 'UNPAID';
form.paymentMethod = row.paymentMethod || 'OFFLINE';
dialogVisible.value = true;
};
const loadCustomers = async () => {
try {
const res = await api.users({ page: 1, size: 100, role: 'CUSTOMER' }); // 获取所有顾客
if (res.code === 0) {
customers.value = res.data?.records || [];
} else {
MessagePlugin.error(res.message || '获取顾客列表失败');
}
} catch (error) {
console.error('获取顾客列表失败:', error);
MessagePlugin.error('获取顾客列表失败');
}
};
const loadPets = async () => {
try {
const res = await api.pets({ page: 1, size: 100 }); // 获取所有宠物
if (res.code === 0) {
pets.value = res.data?.records || [];
} else {
MessagePlugin.error(res.message || '获取宠物列表失败');
}
} catch (error) {
console.error('获取宠物列表失败:', error);
MessagePlugin.error('获取宠物列表失败');
}
};
const loadDoctors = async () => {
try {
const res = await api.users({ page: 1, size: 100, role: 'DOCTOR' }); // 获取所有医生
if (res.code === 0) {
doctors.value = res.data?.records || [];
} else {
MessagePlugin.error(res.message || '获取医生列表失败');
}
} catch (error) {
console.error('获取医生列表失败:', error);
MessagePlugin.error('获取医生列表失败');
}
};
const submit = async () => {
const payload = { ...form };
const res = editingId.value
? await api.updateVisit(editingId.value, payload)
: await api.createVisit(payload);
if (res.code === 0) {
MessagePlugin.success('保存成功');
dialogVisible.value = false;
load();
} else {
MessagePlugin.error(res.message || '保存失败');
}
};
onMounted(() => {
load();
loadCustomers();
loadPets();
loadDoctors();
});
</script>