| | |
| | | v-for="(item, index) in statsItems" |
| | | :key="index" |
| | | class="stat-item" |
| | | :class="{ 'stat-item-highlight': item.highlight }" |
| | | :class="{ |
| | | 'stat-item-highlight': item.highlight, |
| | | 'stat-item-top': item.id === 'myTasks', |
| | | }" |
| | | @click="handleItemClick(item)" |
| | | > |
| | | <div class="stat-icon"> |
| | |
| | | <path |
| | | d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" |
| | | /> |
| | | </svg> |
| | | <svg |
| | | v-else-if="item.icon === 'IconClock'" |
| | | viewBox="0 0 24 24" |
| | | fill="none" |
| | | stroke="currentColor" |
| | | stroke-width="2" |
| | | > |
| | | <circle cx="12" cy="12" r="9" /> |
| | | <path d="M12 7v5l3 3" /> |
| | | </svg> |
| | | </div> |
| | | <div class="stat-info"> |
| | |
| | | <el-form-item label="病区"> |
| | | <el-input v-model="smsForm.leavehospitaldistrictname"></el-input> |
| | | </el-form-item> |
| | | <!-- 短信发送对话框 - 模板选择区域(增强版) --> |
| | | <el-form-item label="选择模板"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="7"> |
| | |
| | | <el-option |
| | | v-for="tmpl in filteredTemplateOptions" |
| | | :key="tmpl.templetid" |
| | | :label="`【${tmpl.templetno}】${tmpl.templetname}`" |
| | | :label="tmpl.templetname" |
| | | :value="tmpl.templetid" |
| | | > |
| | | <span style="float: left">{{ tmpl.templetname }}</span> |
| | | <span style="float: right; color: #909399; font-size: 12px"> |
| | | {{ tmpl.deptName || "通用" }} / |
| | | {{ tmpl.wardName || "全部" }} |
| | | </span> |
| | | <div class="template-option-content"> |
| | | <div class="template-option-text"> |
| | | {{ tmpl.templetcontent || "暂无内容" }} |
| | | </div> |
| | | <div class="template-option-meta"> |
| | | <span>{{ tmpl.deptName || "通用" }}</span> |
| | | <span class="meta-separator">/</span> |
| | | <span>{{ tmpl.wardName || "全部" }}</span> |
| | | </div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-col> |
| | |
| | | import { |
| | | getCurrentUserServiceSubtaskCount, |
| | | sendMsg, |
| | | getNearTimeoutCount, |
| | | } from "@/api/AiCentre/index"; |
| | | import { |
| | | listSmstemplet, |
| | |
| | | // 统计数据 |
| | | statsItems: [ |
| | | { |
| | | id: "myTasks", |
| | | label: "我的任务", |
| | | value: "0", |
| | | unread: 0, |
| | | urltype: 5, |
| | | icon: "IconTask", |
| | | url: "/followvisit/discharge", |
| | | trend: { type: "stable", arrow: "", value: "" }, |
| | | }, |
| | | { |
| | | id: "pending", |
| | | label: "待随访", |
| | | value: "0", |
| | |
| | | trend: { type: "up", arrow: "", value: "" }, |
| | | }, |
| | | { |
| | | id: "myTasks", |
| | | label: "我的任务", |
| | | id: "nearTimeout", |
| | | label: "临近超时任务", |
| | | value: "0", |
| | | unread: 0, |
| | | urltype: 5, |
| | | icon: "IconTask", |
| | | icon: "IconClock", |
| | | url: "/followvisit/discharge", |
| | | trend: { type: "stable", arrow: "", value: "" }, |
| | | }, |
| | |
| | | }, |
| | | |
| | | handleItemClick(item) { |
| | | // 临近超时任务:打开登录后弹窗,而非跳转列表页 |
| | | if (item.id === "nearTimeout") { |
| | | this.$root.$emit("open-near-timeout"); |
| | | this.toggleExpand(); |
| | | return; |
| | | } |
| | | |
| | | if (item.url) { |
| | | console.log(item.url, "item.url"); |
| | | |
| | |
| | | |
| | | // 模拟数据更新 |
| | | const mockData = { |
| | | myTasks: { |
| | | value: "156", |
| | | unread: null, |
| | | trend: { type: "stable", arrow: "→", value: "0" }, |
| | | }, |
| | | pending: { |
| | | value: "128", |
| | | unread: null, |
| | |
| | | unread: null, |
| | | trend: { type: "up", arrow: "↑", value: "3" }, |
| | | }, |
| | | myTasks: { |
| | | value: "156", |
| | | nearTimeout: { |
| | | value: "0", |
| | | unread: null, |
| | | trend: { type: "stable", arrow: "→", value: "0" }, |
| | | }, |
| | |
| | | mockData.failed.value = response.failedVisitCount; |
| | | mockData.abnormal.value = response.abnormalVisitCount; |
| | | mockData.myTasks.value = response.allVisitCount; |
| | | // 临近超时任务数量(接口未就绪,先用 mock) |
| | | mockData.nearTimeout.value = await getNearTimeoutCount(); |
| | | this.statsItems = this.statsItems.map((item) => { |
| | | const data = mockData[item.id] || {}; |
| | | return { |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .wide-template-popper { |
| | | width: 420px !important; /* 进一步加宽,适应内容展示 */ |
| | | } |
| | | |
| | | .template-option-content { |
| | | padding: 8px 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 6px; |
| | | } |
| | | |
| | | .template-option-text { |
| | | font-size: 13px; |
| | | color: #303133; |
| | | line-height: 1.6; |
| | | display: -webkit-box; |
| | | -webkit-line-clamp: 3; /* 最多显示3行 */ |
| | | -webkit-box-orient: vertical; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .template-option-meta { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 4px; |
| | | } |
| | | |
| | | .meta-separator { |
| | | color: #dcdfe6; |
| | | } |
| | | .float-ball { |
| | | position: fixed; |
| | | z-index: 9999; |
| | |
| | | background: linear-gradient(to bottom right, #f0f9ff, #f8fafc); |
| | | } |
| | | |
| | | .stat-item-top { |
| | | grid-column: 1 / -1; |
| | | display: flex; |
| | | align-items: center; |
| | | flex-direction: row; |
| | | gap: 16px; |
| | | } |
| | | |
| | | .stat-item-top .stat-icon { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .stat-icon { |
| | | width: 32px; |
| | | height: 32px; |