| | |
| | | <el-dialog |
| | | title="短信发送" |
| | | :visible.sync="smsDialogVisible" |
| | | width="500px" |
| | | width="800px" |
| | | :close-on-click-modal="false" |
| | | append-to-body |
| | | > |
| | | <el-form ref="smsForm" :model="smsForm" label-width="100px"> |
| | | <el-form-item label="患者名称"> |
| | | <el-input v-model="smsForm.sendname" readonly></el-input> |
| | | <el-input v-model="smsForm.sendname"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="年龄"> |
| | | <el-input v-model="smsForm.age" readonly></el-input> |
| | | <el-input v-model="smsForm.age"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="电话"> |
| | | <el-input v-model="smsForm.telcode" readonly></el-input> |
| | | <el-input v-model="smsForm.telcode"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="科室"> |
| | | <el-input v-model="smsForm.deptname" readonly></el-input> |
| | | <el-input v-model="smsForm.deptname"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="病区"> |
| | | <el-input |
| | | v-model="smsForm.leavehospitaldistrictname" |
| | | readonly |
| | | ></el-input> |
| | | <el-input v-model="smsForm.leavehospitaldistrictname"></el-input> |
| | | </el-form-item> |
| | | <!-- 短信发送对话框 - 模板选择区域(增强版) --> |
| | | <el-form-item label="选择模板"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="7"> |
| | | <el-select |
| | | v-model="templateFilterDept" |
| | | placeholder="按科室" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | @change="filterTemplates" |
| | | > |
| | | <el-option |
| | | v-for="dept in departmentOptions" |
| | | :key="dept.value" |
| | | :label="dept.label" |
| | | :value="dept.value" |
| | | /> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="7"> |
| | | <el-select |
| | | v-model="templateFilterWard" |
| | | placeholder="按病区" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | @change="filterTemplates" |
| | | > |
| | | <el-option |
| | | v-for="ward in wardOptions" |
| | | :key="ward.value" |
| | | :label="ward.label" |
| | | :value="ward.value" |
| | | /> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <el-select |
| | | v-model="selectedTemplateId" |
| | | placeholder="请选择短信模板" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleTemplateSelect" |
| | | > |
| | | <el-option |
| | | v-for="tmpl in filteredTemplateOptions" |
| | | :key="tmpl.templetid" |
| | | :label="`【${tmpl.templetno}】${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> |
| | | </el-option> |
| | | </el-select> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | @click="openQuickCreateTemplate" |
| | | > |
| | | 新建 |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="短信内容"> |
| | | <el-input |
| | | type="textarea" |
| | |
| | | 确认发送 |
| | | </el-button> |
| | | </div> |
| | | <!-- 内嵌:快速新建模板对话框 --> |
| | | <!-- 快速新建模板对话框(增强版) --> |
| | | <el-dialog |
| | | title="新建短信模板" |
| | | :visible.sync="quickCreateVisible" |
| | | width="500px" |
| | | append-to-body |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-form |
| | | :model="quickTemplateForm" |
| | | :rules="quickTemplateRules" |
| | | ref="quickTemplateForm" |
| | | label-width="90px" |
| | | > |
| | | <el-form-item label="模板编号" prop="templetno"> |
| | | <el-input |
| | | v-model="quickTemplateForm.templetno" |
| | | placeholder="请输入模板编号" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="模板名称" prop="templetname"> |
| | | <el-input |
| | | v-model="quickTemplateForm.templetname" |
| | | placeholder="请输入模板名称" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="所属科室"> |
| | | <el-select |
| | | v-model="quickTemplateForm.deptCode" |
| | | placeholder="请选择科室" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | @change=" |
| | | (val) => { |
| | | const dept = departmentOptions.find((d) => d.value === val); |
| | | quickTemplateForm.deptName = dept ? dept.label : ''; |
| | | } |
| | | " |
| | | > |
| | | <el-option |
| | | v-for="dept in departmentOptions" |
| | | :key="dept.value" |
| | | :label="dept.label" |
| | | :value="dept.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="所属病区"> |
| | | <el-select |
| | | v-model="quickTemplateForm.wardCode" |
| | | placeholder="请选择病区" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="ward in wardOptions" |
| | | :key="ward.value" |
| | | :label="ward.label" |
| | | :value="ward.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="模板内容" prop="templetcontent"> |
| | | <el-input |
| | | v-model="quickTemplateForm.templetcontent" |
| | | type="textarea" |
| | | :rows="4" |
| | | placeholder="请输入短信模板内容" |
| | | maxlength="500" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer"> |
| | | <el-button @click="quickCreateVisible = false">取 消</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="submitQuickTemplate" |
| | | :loading="quickCreateLoading" |
| | | > |
| | | 保存并使用 |
| | | </el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getCurrentUserServiceSubtaskCount } from "@/api/AiCentre/index"; |
| | | import { sendMsg } from "@/api/AiCentre/index"; |
| | | import { |
| | | getCurrentUserServiceSubtaskCount, |
| | | sendMsg, |
| | | } from "@/api/AiCentre/index"; |
| | | import { |
| | | listSmstemplet, |
| | | getSmstemplet, |
| | | addSmstemplet, |
| | | updateSmstemplet, |
| | | delSmstemplet, |
| | | } from "@/api/smartor/smstemplet"; |
| | | export default { |
| | | name: "FloatBall", |
| | | |
| | |
| | | hideTimer: null, |
| | | updateTime: "", |
| | | roles: null, |
| | | templateOptions: [], // 模板下拉列表 |
| | | selectedTemplateId: "", // 选中的模板ID |
| | | templateLoading: false, // 模板列表加载状态 |
| | | // 模板筛选 |
| | | templateFilterDept: "", |
| | | templateFilterWard: "", // 新增:病区筛选 |
| | | filteredTemplateOptions: [], |
| | | |
| | | // 科室选项(从 Vuex 获取) |
| | | departmentOptions: [], |
| | | // 新增:病区选项(从 Vuex 获取) |
| | | wardOptions: [], |
| | | // 快速新建模板 |
| | | quickCreateVisible: false, |
| | | quickCreateLoading: false, |
| | | quickTemplateForm: { |
| | | templetno: "", |
| | | templetname: "", |
| | | templetcontent: "", |
| | | }, |
| | | quickTemplateRules: { |
| | | templetname: [ |
| | | { required: true, message: "请输入模板名称", trigger: "blur" }, |
| | | ], |
| | | templetcontent: [ |
| | | { required: true, message: "请输入模板内容", trigger: "blur" }, |
| | | ], |
| | | }, |
| | | // 短信发送对话框 |
| | | // smsDialogVisible: false, |
| | | smsLoading: false, // ✅ 新增加载状态 |
| | |
| | | }, |
| | | watch: { |
| | | // ✅ 监听 Vuex 对话框状态 |
| | | "$store.state.sms.smsDialogVisible"(val) { |
| | | "$store.state.sms.smsDialogVisible": { |
| | | handler(val) { |
| | | if (val) { |
| | | const patientData = this.$store.state.sms.patientData; |
| | | this.smsForm = { ...patientData }; |
| | |
| | | this.isHidden = false; |
| | | clearTimeout(this.hideTimer); |
| | | } |
| | | |
| | | // ★★★ 关键修复:在这里初始化模板相关数据 ★★★ |
| | | this.initTemplateData(); |
| | | } |
| | | }, |
| | | immediate: false, |
| | | }, |
| | | }, |
| | | mounted() { |
| | |
| | | }, |
| | | |
| | | methods: { |
| | | initTemplateData() { |
| | | // 初始化科室选项 |
| | | if (this.$store.getters.belongDepts) { |
| | | this.departmentOptions = this.$store.getters.belongDepts.map( |
| | | (dept) => ({ |
| | | label: dept.deptName, |
| | | value: dept.deptCode, |
| | | }) |
| | | ); |
| | | } |
| | | |
| | | // ★★★ 新增:初始化病区选项 ★★★ |
| | | if (this.$store.getters.belongWards) { |
| | | this.wardOptions = this.$store.getters.belongWards.map((ward) => ({ |
| | | label: ward.districtName, |
| | | value: ward.districtCode, |
| | | })); |
| | | } |
| | | |
| | | // 重置筛选 |
| | | this.templateFilterDept = ""; |
| | | this.templateFilterWard = ""; // 新增 |
| | | this.selectedTemplateId = ""; |
| | | |
| | | // 加载模板列表 |
| | | this.loadTemplates(); |
| | | }, |
| | | toggleExpand() { |
| | | this.isExpanded = !this.isExpanded; |
| | | if (this.isExpanded) { |
| | |
| | | this.updateStats(); |
| | | } |
| | | }, |
| | | async loadTemplates() { |
| | | this.templateLoading = true; |
| | | try { |
| | | // const { listSmstemplet } = await import("@/api/smartor/smstemplet"); |
| | | const res = await listSmstemplet({ pageNum: 1, pageSize: 999 }); |
| | | this.templateOptions = res.rows || []; |
| | | this.filterTemplates(); // 应用筛选 |
| | | } catch (error) { |
| | | console.error("加载短信模板失败:", error); |
| | | this.templateOptions = []; |
| | | this.filteredTemplateOptions = []; |
| | | } finally { |
| | | this.templateLoading = false; |
| | | } |
| | | }, |
| | | handleTemplateSelect(templateId) { |
| | | if (!templateId) { |
| | | this.smsContent = ""; |
| | | return; |
| | | } |
| | | const selected = this.templateOptions.find( |
| | | (t) => t.templetid === templateId |
| | | ); |
| | | if (selected) { |
| | | this.smsContent = selected.templetcontent || ""; |
| | | } |
| | | }, |
| | | openQuickCreateTemplate() { |
| | | this.quickTemplateForm = { |
| | | templetno: "", |
| | | templetname: "", |
| | | templetcontent: "", |
| | | }; |
| | | this.quickCreateVisible = true; |
| | | this.$nextTick(() => { |
| | | if (this.$refs.quickTemplateForm) { |
| | | this.$refs.quickTemplateForm.clearValidate(); |
| | | } |
| | | }); |
| | | }, |
| | | /** |
| | | * 提交快速新建模板 |
| | | */ |
| | | async submitQuickTemplate() { |
| | | this.$refs.quickTemplateForm.validate(async (valid) => { |
| | | if (!valid) return; |
| | | |
| | | this.quickCreateLoading = true; |
| | | try { |
| | | // const { addSmstemplet } = await import("@/api/smartor/smstemplet"); |
| | | const res = await addSmstemplet(this.quickTemplateForm); |
| | | |
| | | if (res.code === 200) { |
| | | this.$modal.msgSuccess("模板创建成功"); |
| | | |
| | | // 刷新模板列表 |
| | | await this.loadTemplates(); |
| | | |
| | | // 自动选中刚创建的模板 |
| | | const newTmpl = this.templateOptions.find( |
| | | (t) => t.templetname === this.quickTemplateForm.templetname |
| | | ); |
| | | if (newTmpl) { |
| | | this.selectedTemplateId = newTmpl.templetid; |
| | | this.smsContent = newTmpl.templetcontent; |
| | | } |
| | | |
| | | this.quickCreateVisible = false; |
| | | } else { |
| | | this.$modal.msgError(res.msg || "创建失败"); |
| | | } |
| | | } catch (error) { |
| | | console.error("创建模板失败:", error); |
| | | this.$modal.msgError("创建失败,请稍后重试"); |
| | | } finally { |
| | | this.quickCreateLoading = false; |
| | | } |
| | | }); |
| | | }, |
| | | handleMouseEnter() { |
| | | this.isHovering = true; |
| | | if (this.autoHide) { |
| | |
| | | } |
| | | }, |
| | | // 打开短信发送对话框 |
| | | openSmsDialog() { |
| | | // 从悬浮球内部打开时,清空表单(因为没有选中患者) |
| | | /** |
| | | * 改造原有的 openSmsDialog 方法 |
| | | */ |
| | | openSmsDialog(patientData = {}) { |
| | | // 重置筛选 |
| | | this.templateFilterDept = ""; |
| | | |
| | | // 重置选择 |
| | | this.selectedTemplateId = ""; |
| | | this.smsContent = patientData.smsTemplate || ""; |
| | | |
| | | // 加载模板列表 |
| | | this.loadTemplates(); |
| | | |
| | | // 打开对话框(通过 Vuex) |
| | | this.$store.dispatch("sms/openSmsDialog", { |
| | | name: "", |
| | | age: "", |
| | | phone: "", |
| | | deptName: "", |
| | | wardName: "", |
| | | smsTemplate: "", |
| | | name: patientData.name || "", |
| | | age: patientData.age || "", |
| | | phone: patientData.phone || "", |
| | | deptName: patientData.deptName || "", |
| | | wardName: patientData.wardName || "", |
| | | smsTemplate: patientData.smsTemplate || "", |
| | | }); |
| | | }, |
| | | // 新增:筛选模板 |
| | | filterTemplates() { |
| | | let filtered = [...this.templateOptions]; |
| | | |
| | | // 按科室筛选 |
| | | if (this.templateFilterDept) { |
| | | filtered = filtered.filter( |
| | | (tmpl) => tmpl.deptCode === this.templateFilterDept || !tmpl.deptCode |
| | | ); |
| | | } |
| | | |
| | | // ★★★ 新增:按病区筛选 ★★★ |
| | | if (this.templateFilterWard) { |
| | | filtered = filtered.filter( |
| | | (tmpl) => tmpl.wardCode === this.templateFilterWard || !tmpl.wardCode |
| | | ); |
| | | } |
| | | |
| | | this.filteredTemplateOptions = filtered; |
| | | |
| | | // 清空已选 |
| | | this.selectedTemplateId = ""; |
| | | this.smsContent = ""; |
| | | }, |
| | | // 发送短信 |
| | | async sendSms() { |
| | | if (!this.smsContent.trim()) { |
| | |
| | | this.$modal.msgError("发送失败,请稍后重试"); |
| | | } finally { |
| | | this.smsLoading = false; |
| | | this.selectedTemplateId = ""; |
| | | } |
| | | }, |
| | | async updateStats() { |