diff --git a/src/assets/image/admin/orders/award.svg b/src/assets/image/admin/orders/award.svg
new file mode 100644
index 0000000..c8d21a6
--- /dev/null
+++ b/src/assets/image/admin/orders/award.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/assets/image/admin/reports/summery-bg.svg b/src/assets/image/admin/reports/summery-bg.svg
index ac29ad1..9556e17 100644
--- a/src/assets/image/admin/reports/summery-bg.svg
+++ b/src/assets/image/admin/reports/summery-bg.svg
@@ -2,8 +2,8 @@
-
+
-
+
diff --git a/src/components/PasswordDialog.vue b/src/components/PasswordDialog.vue
index c8cb965..36bc1df 100644
--- a/src/components/PasswordDialog.vue
+++ b/src/components/PasswordDialog.vue
@@ -69,31 +69,26 @@ const rules = {
{
required: true,
message: () => t("password.pleaseInputOld"),
- trigger: "blur",
},
],
newPassword: [
{
required: true,
message: () => t("password.pleaseInputNew"),
- trigger: "blur",
},
{
min: 6,
message: () => t("password.passwordTooShort"),
- trigger: "blur",
},
],
confirmPassword: [
{
required: true,
message: () => t("password.pleaseInputConfirm"),
- trigger: "blur",
},
{
validator: (_, val, cb) =>
val === form.newPassword ? cb() : cb(new Error(t("password.passwordMismatch"))),
- trigger: "blur",
},
],
};
diff --git a/src/views/admin/accounts/components/AccountEditDialog.vue b/src/views/admin/accounts/components/AccountEditDialog.vue
index 8bb5d8e..585c43d 100644
--- a/src/views/admin/accounts/components/AccountEditDialog.vue
+++ b/src/views/admin/accounts/components/AccountEditDialog.vue
@@ -240,13 +240,13 @@ const form = reactive(buildForm());
const rules = {
username: [
- { required: true, message: () => $t('placeholder.account'), trigger: "blur" },
+ { required: true, message: () => $t('placeholder.account') },
],
password: [
- { required: true, message: () => $t('placeholder.password'), trigger: "blur" },
+ { required: true, message: () => $t('placeholder.password') },
],
name: [
- { required: true, message: () => $t('account.pleaseInputName'), trigger: "blur" },
+ { required: true, message: () => $t('account.pleaseInputName') },
],
hospitalId: [
{
@@ -256,7 +256,6 @@ const rules = {
}
cb();
},
- trigger: "change",
},
],
role: [
@@ -267,7 +266,6 @@ const rules = {
}
cb();
},
- trigger: "change",
},
],
};
diff --git a/src/views/admin/accounts/edit.vue b/src/views/admin/accounts/edit.vue
index 9deae7c..446e0a0 100644
--- a/src/views/admin/accounts/edit.vue
+++ b/src/views/admin/accounts/edit.vue
@@ -112,10 +112,10 @@ const form = reactive({
});
const rules = {
- username: [{ required: true, message: () => $t('placeholder.account'), trigger: "blur" }],
- password: [{ required: true, message: () => $t('placeholder.password'), trigger: "blur" }],
- name: [{ required: true, message: () => $t('account.pleaseInputName'), trigger: "blur" }],
- userType: [{ required: true, message: () => $t('label.accountType'), trigger: "change" }],
+ username: [{ required: true, message: () => $t('placeholder.account') }],
+ password: [{ required: true, message: () => $t('placeholder.password') }],
+ name: [{ required: true, message: () => $t('account.pleaseInputName') }],
+ userType: [{ required: true, message: () => $t('label.accountType') }],
};
const loadDetail = async () => {
diff --git a/src/views/admin/hospitals/components/HospitalDetailDialog.vue b/src/views/admin/hospitals/components/HospitalDetailDialog.vue
index a9a68ea..f15294f 100644
--- a/src/views/admin/hospitals/components/HospitalDetailDialog.vue
+++ b/src/views/admin/hospitals/components/HospitalDetailDialog.vue
@@ -160,6 +160,7 @@ const goEdit = () => emit("edit", props.hospitalId);
white-space: nowrap;
flex-shrink: 0;
flex-grow: 0;
+ text-align: right;
}
.value {
diff --git a/src/views/admin/hospitals/components/HospitalEditDialog.vue b/src/views/admin/hospitals/components/HospitalEditDialog.vue
index 7d88e6c..3999308 100644
--- a/src/views/admin/hospitals/components/HospitalEditDialog.vue
+++ b/src/views/admin/hospitals/components/HospitalEditDialog.vue
@@ -176,30 +176,27 @@ const rules = {
{
required: true,
message: () => $t("placeholder.hospital"),
- trigger: "blur",
},
],
customerCategory: [
- { required: true, message: () => $t("label.category"), trigger: "change" },
+ { required: true, message: () => $t("label.category") },
],
signDate: [
- { required: true, message: () => $t("label.signDate"), trigger: "change" },
+ { required: true, message: () => $t("label.signDate") },
],
acceptDate: [
{
required: true,
message: () => $t("label.acceptDate"),
- trigger: "change",
},
],
contractYears: [
- { required: true, message: () => $t("label.years"), trigger: "blur" },
+ { required: true, message: () => $t("label.years") },
],
maintenanceEnd: [
{
required: true,
message: () => $t("label.maintenanceEndDate"),
- trigger: "change",
},
],
};
diff --git a/src/views/admin/hospitals/components/ServiceRecordDialog.vue b/src/views/admin/hospitals/components/ServiceRecordDialog.vue
index 319bc03..8976223 100644
--- a/src/views/admin/hospitals/components/ServiceRecordDialog.vue
+++ b/src/views/admin/hospitals/components/ServiceRecordDialog.vue
@@ -311,32 +311,32 @@ const form = reactive(defaultForm());
const buildRules = () => {
if (props.type === "call") {
return {
- callTime: [{ required: true, message: "请选择回访时间", trigger: "change" }],
- callPerson: [{ required: true, message: "请输入回访人", trigger: "blur" }],
- content: [{ required: true, message: "请输入回访内容", trigger: "blur" }],
+ callTime: [{ required: true, message: "请选择回访时间" }],
+ callPerson: [{ required: true, message: "请输入回访人" }],
+ content: [{ required: true, message: "请输入回访内容" }],
};
}
if (props.type === "inspection") {
console.log(111);
return {
- inspectionTime: [{ required: true, message: "请选择巡检时间", trigger: "change" }],
- inspectionPerson: [{ required: true, message: "请输入巡检人", trigger: "blur" }],
- content: [{ required: true, message: "请输入巡检内容", trigger: "blur" }],
+ inspectionTime: [{ required: true, message: "请选择巡检时间" }],
+ inspectionPerson: [{ required: true, message: "请输入巡检人" }],
+ content: [{ required: true, message: "请输入巡检内容" }],
};
}
if (props.type === "training") {
return {
- trainingDate: [{ required: true, message: "请选择培训日期", trigger: "change" }],
- participants: [{ required: true, message: "请输入参与人数", trigger: "blur" }],
- trainer: [{ required: true, message: "请输入培训人员", trigger: "blur" }],
- topic: [{ required: true, message: "请输入培训主题", trigger: "blur" }],
+ trainingDate: [{ required: true, message: "请选择培训日期" }],
+ participants: [{ required: true, message: "请输入参与人数" }],
+ trainer: [{ required: true, message: "请输入培训人员" }],
+ topic: [{ required: true, message: "请输入培训主题" }],
};
}
return {
- date: [{ required: true, message: "请选择年份", trigger: "change" }],
- quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
- name: [{ required: true, message: "请输入纪念品名称", trigger: "blur" }],
+ date: [{ required: true, message: "请选择年份" }],
+ quantity: [{ required: true, message: "请输入数量" }],
+ name: [{ required: true, message: "请输入纪念品名称" }],
};
};
diff --git a/src/views/admin/hospitals/service.vue b/src/views/admin/hospitals/service.vue
index e49c11b..2504a02 100644
--- a/src/views/admin/hospitals/service.vue
+++ b/src/views/admin/hospitals/service.vue
@@ -8,10 +8,21 @@
+
+ 客户分类
+
+
+
+
+
+ 维保截止日期
+
查询
-
+
@@ -113,7 +124,7 @@
-
+
-
+
@@ -164,7 +175,8 @@ import { useHospitalStore } from "@/stores/api/hospital";
import MaintenanceDetailDialog from "./components/MaintenanceDetailDialog.vue";
import ServiceRecordDialog from "./components/ServiceRecordDialog.vue";
import MonthlyViewDialog from "./components/MonthlyViewDialog.vue";
-
+import { dateRangeShortcuts } from "@/utils/dateShortcuts";
+const dateRange = ref([]);
const list = ref([]);
const loading = ref(false);
const expiringLoading = ref(false);
@@ -198,13 +210,19 @@ const formatExpiringDays = (n) => {
const loadList = async () => {
loading.value = true;
try {
- const res = await getAdminMaintenance({
+ const params = {
page: 1,
pageSize: 200,
keyword: filters.keyword || undefined,
+ category: filters.category || undefined,
year: currentMonth.value.year(),
month: currentMonth.value.month() + 1,
- });
+ }
+ if (dateRange.value?.length === 2) {
+ params.maintenanceStart = dateRange.value[0];
+ params.maintenanceEnd = dateRange.value[1];
+ }
+ const res = await getAdminMaintenance(params);
list.value = res?.list || [];
} finally {
loading.value = false;
@@ -252,7 +270,7 @@ const monthlyVisible = ref(false);
onMounted(() => {
hospitalStore.ensureLoaded();
loadList();
- loadExpiring();
+ // loadExpiring();
});
diff --git a/src/views/admin/orders/components/OrderAwardDialog.vue b/src/views/admin/orders/components/OrderAwardDialog.vue
new file mode 100644
index 0000000..319a88f
--- /dev/null
+++ b/src/views/admin/orders/components/OrderAwardDialog.vue
@@ -0,0 +1,83 @@
+
+ $emit('update:modelValue', v)">
+
+
![award]()
+
你真棒!
+
恭喜您完成服务工单
+
+{{ points }} 积分
+
+
+
+
+ 继续处理
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/admin/orders/components/OrderDetailDialog.vue b/src/views/admin/orders/components/OrderDetailDialog.vue
index 198b49d..8afb39d 100644
--- a/src/views/admin/orders/components/OrderDetailDialog.vue
+++ b/src/views/admin/orders/components/OrderDetailDialog.vue
@@ -28,6 +28,25 @@
{{ detail.serviceType }}
+
+
+
+
提出医院
+
{{ detail.hospitalName || '-' }}
+
+
+
提出科室
+
{{ detail.department || '-' }}
+
+
+
提出人员
+
{{ detail.submitter || '-' }}
+
+
+
提交时间
+
{{ detail.createdAt?.split('T').join(' ') || '-' }}
+
+
@@ -49,8 +68,7 @@
-
-
-
-
提出医院
-
{{ detail.hospitalName || '-' }}
-
-
-
提出科室
-
{{ detail.department || '-' }}
-
-
-
提出人员
-
{{ detail.submitter || '-' }}
-
-
-
提交时间
-
{{ detail.createdAt?.split('T').join(' ') || '-' }}
-
-
@@ -90,7 +89,12 @@
{{ log.toStatus }} · {{ log.operator }}
-
+
+
@@ -322,6 +326,7 @@ watch(
white-space: nowrap;
flex-shrink: 0;
flex-grow: 0;
+ text-align: right;
}
.value {
@@ -401,7 +406,7 @@ watch(
font-weight: 600;
}
-.log-remark {
+.remark-wrap {
color: #606266;
margin-top: 4px;
}
diff --git a/src/views/admin/orders/components/OrderFormDialog.vue b/src/views/admin/orders/components/OrderFormDialog.vue
index 02bcec9..d6a3445 100644
--- a/src/views/admin/orders/components/OrderFormDialog.vue
+++ b/src/views/admin/orders/components/OrderFormDialog.vue
@@ -253,35 +253,30 @@ const rules = {
{
required: true,
message: () => $t('msg.pleaseSelectHospital'),
- trigger: 'change',
},
],
title: [
{
required: true,
message: () => $t('msg.pleaseInputTitle'),
- trigger: 'blur',
},
],
serviceType: [
{
required: true,
message: () => $t('msg.pleaseSelectType'),
- trigger: 'blur',
},
],
priority: [
{
required: true,
message: () => $t('msg.pleaseSelectPriority'),
- trigger: 'change',
},
],
feedbackchannel: [
{
required: true,
message: () => $t('msg.pleaseSelectFeedbackChannel'),
- trigger: 'change',
},
],
department: [
@@ -289,7 +284,6 @@ const rules = {
required: true,
whitespace: true,
message: () => $t('msg.pleaseInputDept'),
- trigger: 'blur',
},
],
submitter: [
@@ -297,7 +291,6 @@ const rules = {
required: true,
whitespace: true,
message: () => $t('msg.pleaseInputName'),
- trigger: 'blur',
},
],
description: [
@@ -313,7 +306,6 @@ const rules = {
return callback(new Error($t('msg.pleaseInputDescription')));
callback();
},
- trigger: 'change',
},
],
};
diff --git a/src/views/admin/orders/components/OrderHandleDialog.vue b/src/views/admin/orders/components/OrderHandleDialog.vue
index af6fe57..f9d676a 100644
--- a/src/views/admin/orders/components/OrderHandleDialog.vue
+++ b/src/views/admin/orders/components/OrderHandleDialog.vue
@@ -106,8 +106,7 @@
-
+
diff --git a/src/views/admin/orders/components/OrderProcessDialog.vue b/src/views/admin/orders/components/OrderProcessDialog.vue
index 7aa0e6a..9605ad2 100644
--- a/src/views/admin/orders/components/OrderProcessDialog.vue
+++ b/src/views/admin/orders/components/OrderProcessDialog.vue
@@ -3,15 +3,27 @@
top="5vh" @update:model-value="(v) => $emit('update:modelValue', v)" @open="onOpen">
-
处理工单
+
{{ isCompleted ? '修改工单' : '处理工单' }}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -73,7 +85,7 @@
{{ $t("common.cancel") }}
{{
- $t("btn.confirm")
+ isCompleted ? '确认修改' : '确认处理'
}}
@@ -99,14 +111,16 @@ import {
} from "@/service/modular/admin";
import { useUserStore } from "@/stores/api/user";
+
const { t: $t } = useI18n();
const userStore = useUserStore();
const props = defineProps({
modelValue: { type: Boolean, default: false },
orderId: { type: [String, Number], default: "" },
+ isCompleted: { type: Boolean, default: false },
});
-const emit = defineEmits(["update:modelValue", "processed"]);
+const emit = defineEmits(["update:modelValue", "processed","openAward"]);
const loading = ref(false);
const submitting = ref(false);
@@ -133,7 +147,7 @@ const form = reactive({
const rules = {
status: [
- { required: true, message: () => $t("table.status"), trigger: "change" },
+ { required: true, message: () => $t("table.status") },
],
processRemark: [
{
@@ -148,7 +162,6 @@ const rules = {
return callback(new Error($t("placeholder.remark")));
callback();
},
- trigger: "change",
},
],
};
@@ -296,6 +309,7 @@ watch(
},
);
+
const submit = async () => {
if (!formRef.value) return;
await formRef.value.validate(async (valid) => {
@@ -309,7 +323,13 @@ const submit = async () => {
department: form.department,
submitter: form.submitter,
});
- ElMessage.success($t("msg.editSuccess"));
+
+ // 首次处理完成:弹出奖励层,不直接关闭原弹窗
+ if (!props.isCompleted) {
+ emit("openAward");
+ } else {
+ ElMessage.success($t("msg.editSuccess"));
+ }
emit("update:modelValue", false);
emit("processed");
} finally {
diff --git a/src/views/admin/orders/components/ReportDetailDialog.vue b/src/views/admin/orders/components/ReportDetailDialog.vue
index 4225b19..a4d7391 100644
--- a/src/views/admin/orders/components/ReportDetailDialog.vue
+++ b/src/views/admin/orders/components/ReportDetailDialog.vue
@@ -38,9 +38,9 @@
感谢贵院一直以来对上海康策的信任与配合。
- 本期我们累计处理服务工单:{{ 28
- }}次,完成率达:{{ 95 }}%;同时安排回访:{{ 3
- }}次、现场巡检:{{ 1 }}次及参与培训:{{ 1
+ 本期我们累计处理服务工单:{{detail.total
+ }}次,完成率达:{{ detail.rate }};同时安排回访:{{ detail.callRecord
+ }}次、现场巡检:{{ detail.inspectionRecord }}次及参与培训:{{ detail.trainingRecord
}}次,力求从响应、预防到能力共建,全方位护航医院信息化环境。
@@ -372,7 +372,7 @@ const loadDetail = async (overrideId) => {
// name: "现场",
// count: 3
// }, {
- // name: "钉钉",
+ // name: "钉钉",/
// count: 3
// }, {
// name: "其他",
@@ -527,7 +527,7 @@ const deptOption = computed(() => {
.sort((a, b) => b.count - a.count);
return {
- grid: { left: 10, right: 10, top: 10, bottom: 10 },
+ grid: { left: 10, right: 10, top: 20, bottom: 10 },
tooltip: {
trigger: "axis",
axisPointer: { type: "shadow" },
@@ -898,7 +898,7 @@ const statusClass = (s) =>
width: 100%;
position: relative;
height: 28px;
- background: #E7EDF6;
+ background: #C5D0E0;
border-radius: 12px 12px 12px 12px;
padding: 4px;
diff --git a/src/views/admin/orders/components/ReportGenerateDialog.vue b/src/views/admin/orders/components/ReportGenerateDialog.vue
index 27b63e0..356d47a 100644
--- a/src/views/admin/orders/components/ReportGenerateDialog.vue
+++ b/src/views/admin/orders/components/ReportGenerateDialog.vue
@@ -109,9 +109,9 @@ const form = reactive({
});
const rules = {
- hospitalId: [{ required: true, message: "请选择医院名称", trigger: "change" }],
- type: [{ required: true, message: "请选择报告类型", trigger: "change" }],
- year: [{ required: true, message: "请选择年份", trigger: "change" }],
+ hospitalId: [{ required: true, message: "请选择医院名称" }],
+ type: [{ required: true, message: "请选择报告类型" }],
+ year: [{ required: true, message: "请选择年份" }],
quarter: [
{
validator: (_, value, cb) => {
@@ -119,7 +119,6 @@ const rules = {
return cb(new Error("季度报告必须选择季度"));
cb();
},
- trigger: "change",
},
],
};
diff --git a/src/views/admin/orders/list.vue b/src/views/admin/orders/list.vue
index 98afc73..5f85389 100644
--- a/src/views/admin/orders/list.vue
+++ b/src/views/admin/orders/list.vue
@@ -108,8 +108,9 @@
- {{ row.title
- }}
+ {{ row.title
+ }}
@@ -133,7 +134,7 @@
{{
+ @click="goProcess(row.id, row.status === '已完成' ? true : false)">{{
row.status === "已完成" ? $t("btn.modify") : $t("btn.process")
}}
{{
@@ -156,10 +157,15 @@
-
+
+
+
+
+
@@ -183,7 +189,7 @@ import iconAll from "@/assets/image/admin/orders/all.svg";
import iconPending from "@/assets/image/admin/orders/pending.svg";
import iconComplete from "@/assets/image/admin/orders/complete.svg";
import iconHigh from "@/assets/image/admin/orders/high.svg";
-
+import OrderAwardDialog from "./components/OrderAwardDialog.vue";
const { t: $t } = useI18n();
const userStore = useUserStore();
const hospitalStore = useHospitalStore();
@@ -202,7 +208,12 @@ const filters = reactive({
type: "",
keyword: "",
});
-
+// 处理成功奖励弹窗可见性(仅首次处理时展示)
+const awardVisible = ref(false);
+// “继续处理”回调:关闭奖励弹窗 + 关闭处理弹窗 + 通知父组件刷新
+const onAwardContinue = () => {
+ awardVisible.value = false;
+};
const statusClass = (s) =>
s === "已完成" ? "done" : s === "待处理" ? "pending" : 'info';
@@ -305,14 +316,15 @@ const detailVisible = ref(false);
const processVisible = ref(false);
const handleVisible = ref(false);
const currentOrderId = ref("");
-
+const isCompleted = ref(false);
const goDetail = (id) => {
currentOrderId.value = id;
detailVisible.value = true;
};
-const goProcess = (id) => {
+const goProcess = (id, isCompletedFlag) => {
currentOrderId.value = id;
processVisible.value = true;
+ isCompleted.value = isCompletedFlag || false;
};
const goHandle = (id) => {
currentOrderId.value = id;
@@ -434,7 +446,7 @@ const formStyle = computed(() => {
border-radius: 12px 12px 12px 12px;
border: 1px solid #e0e0e0;
overflow: hidden;
-
+
// el-table 的 border 是用伪元素绘制外层 1px(左/右/上) + 内部 cell 的 border-right / border-bottom
// 这里把外层 3 条伪元素边框隐藏,仅保留 cell 之间的分隔线,避免与外层自加 border 叠加
@@ -503,7 +515,7 @@ const formStyle = computed(() => {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
- margin-bottom: 24px;
+ margin-bottom: 24px;
}
.stat-card {
diff --git a/src/views/admin/performance/score.vue b/src/views/admin/performance/score.vue
index ecfa777..133e61d 100644
--- a/src/views/admin/performance/score.vue
+++ b/src/views/admin/performance/score.vue
@@ -10,7 +10,7 @@
自定义
-
查询
@@ -133,6 +133,7 @@ import inspectorIcon from "@/assets/image/admin/score/inspector.svg";
import trainIcon from "@/assets/image/admin/score/train.svg";
import huifangIcon from "@/assets/image/admin/score/huifang.svg";
import complaintIcon from "@/assets/image/admin/score/complaint.svg";
+import { dateRangeShortcuts } from "@/utils/dateShortcuts";
import {
getManagerPointsDetails,
getManagerPointsLeaderboard,
diff --git a/src/views/hospital/AssetsDialog.vue b/src/views/hospital/AssetsDialog.vue
index c2d7cf8..05c5d44 100644
--- a/src/views/hospital/AssetsDialog.vue
+++ b/src/views/hospital/AssetsDialog.vue
@@ -42,7 +42,7 @@
今日提交工单
- +{{ todayOrder }} 积分
+ +{{ todayOrder }} 分
diff --git a/src/views/hospital/SignInDialog.vue b/src/views/hospital/SignInDialog.vue
index 0d34621..6950832 100644
--- a/src/views/hospital/SignInDialog.vue
+++ b/src/views/hospital/SignInDialog.vue
@@ -5,24 +5,26 @@
@@ -66,13 +68,8 @@
-
+