| | |
| | | // data: data, |
| | | }); |
| | | } |
| | | |
| | | export function getTaskFollowupList(data) { |
| | | return request({ |
| | | url: "/smartor/ivrTaskTemplate/list", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | // 新增随访模板分类树 |
| | | export function addFollowupclassify(data) { |
| | | return request({ |
| | |
| | | method: "get", |
| | | }); |
| | | } |
| | | // 获取语音任务模板详情 |
| | | export function selectInfoByCondition(data) { |
| | | return request({ |
| | | url: "/smartor/ivrTaskTemplate/selectInfoByCondition", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | // 任务模板新增修改 |
| | | export function TaskTemplatecomit(data) { |
| | | return request({ |
| | |
| | | data: data, |
| | | }); |
| | | } |
| | | // 满意度明细查询 |
| | | export function getSfStatisticsJoydetails(data) { |
| | | // 满意度统计 |
| | | export function getSfStatisticsJoy(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtask/getSfStatisticsJoydetails", |
| | | url: "/smartor/serviceSubtask/getSfStatisticsCount", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | }// 满意度统计 |
| | | export function getSfStatisticsJoy(data) { |
| | | } |
| | | // 满意度统计详情 |
| | | export function getSfStatisticsJoyInfo(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtask/getSfStatisticsJoy", |
| | | url: "/smartor/serviceSubtask/getSfStatisticsCountDetails", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | |
| | | } |
| | | |
| | | // 任务随访率统计表的下钻明细 |
| | | // sendstate = 2 待随访 5 待随访失败 |
| | | // sendstate = 2 待随访 5 待随访失败 |
| | | // preachform = 任务形式(1,人工 2,纸质 3,电话 4,短信 5.微信公众号 6.微信小程序 7.支付宝小程序 8.智能机器人 9.钉钉) |
| | | export function querySubtaskList(data) { |
| | | return request({ |
| | |
| | | sipStatus: "未连接", |
| | | sipStatusClass: "status-disconnected", |
| | | sipConfig: { |
| | | wsUrl: "wss://192.168.10.124:7443", |
| | | sipUri: "", |
| | | // 移除硬编码的wsUrl和domain |
| | | wsUrl:'', |
| | | sipUri:'', |
| | | password: "Smartor@2023", |
| | | displayName: "Web 小龙", |
| | | // realm: "9.208.5.18:8090", |
| | |
| | | }, |
| | | |
| | | async mounted() { |
| | | if (localStorage.getItem("orgname")=='景宁畲族自治县人民医院') { |
| | | return |
| | | const orgName = localStorage.getItem("orgname"); |
| | | if (orgName == "景宁畲族自治县人民医院") { |
| | | return; |
| | | } |
| | | await this.CallgetList(); |
| | | this.isRegistering = true; // 开始注册 |
| | |
| | | const res = await CallgetList(); |
| | | this.randomNum = res.data[0].tel; |
| | | this.randomID = res.data[0].id; |
| | | // 正确设置 sipUri |
| | | this.sipConfig.sipUri = `${this.randomNum}@192.168.10.124`; |
| | | // 动态设置sipUri,域名部分会在sipService中动态处理 |
| | | const orgName = localStorage.getItem("orgname"); |
| | | if (orgName == "丽水市中医院") { |
| | | this.sipConfig.sipUri = `${this.randomNum}@192.168.10.124`; |
| | | } else if (orgName == "龙泉市人民医院") { |
| | | this.sipConfig.sipUri = `${this.randomNum}@10.10.0.220`; |
| | | } |
| | | } catch (error) { |
| | | console.error("获取分机号失败:", error); |
| | | // this.updateStatus("failed", "获取分机号失败"); |
| | |
| | | import JsSIP from "jssip"; |
| | | import { Notification, MessageBox, Message, Loading } from "element-ui"; |
| | | |
| | | // 医院机构与SIP服务器映射配置 |
| | | const HOSPITAL_CONFIG = { |
| | | 丽水市中医院: { |
| | | wsUrl: "wss://192.168.10.124:7443", |
| | | domain: "192.168.10.124", |
| | | }, |
| | | 龙泉市人民医院: { |
| | | wsUrl: "wss://10.10.0.220:7443", |
| | | domain: "10.10.0.220", |
| | | }, |
| | | // 可以继续添加其他医院配置 |
| | | default: { |
| | | wsUrl: "wss://192.168.10.124:7443", |
| | | domain: "192.168.10.124", |
| | | }, |
| | | }; |
| | | class SipService { |
| | | constructor() { |
| | | this.ua = null; |
| | |
| | | this.onIncomingCall = null; |
| | | this.isRegistered = false; // 新增注册状态标志 |
| | | this.registrationTime = null; // 新增注册成功时间戳 |
| | | this.currentConfig = null; // 存储当前配置 |
| | | } |
| | | |
| | | init(config) { |
| | | // 获取医院配置方法 |
| | | getHospitalConfig() { |
| | | const orgName=localStorage.getItem("orgname"); |
| | | return HOSPITAL_CONFIG[orgName] || HOSPITAL_CONFIG.default; |
| | | } |
| | | init(baseConfig) { |
| | | try { |
| | | this.updateStatus("connecting", "连接中;..."); |
| | | // 获取机构名称,如果没有传入则从localStorage读取 |
| | | const orgName = baseConfig.orgName || localStorage.getItem("orgname"); |
| | | |
| | | // 根据机构名称获取对应的服务器配置 |
| | | const hospitalConfig = this.getHospitalConfig(orgName); |
| | | console.log(hospitalConfig,'88'); |
| | | |
| | | // 合并配置 |
| | | this.currentConfig = { |
| | | ...baseConfig, |
| | | ...hospitalConfig, |
| | | }; |
| | | |
| | | console.log( |
| | | `当前机构: ${orgName}, 使用服务器: ${this.currentConfig.domain}` |
| | | ); |
| | | |
| | | this.updateStatus("connecting", "连接中..."); |
| | | console.log(baseConfig.sipUri,'baseConfig.sipUri'); |
| | | |
| | | this.ua = new JsSIP.UA({ |
| | | sockets: [new JsSIP.WebSocketInterface(config.wsUrl)], |
| | | uri: config.sipUri, |
| | | password: config.password, |
| | | display_name: config.displayName, |
| | | sockets: [new JsSIP.WebSocketInterface(this.currentConfig.wsUrl)], |
| | | uri: baseConfig.sipUri, // 这里使用基础的sipUri,domain部分会被动态替换 |
| | | password: baseConfig.password, |
| | | display_name: baseConfig.displayName, |
| | | iceServers: [], |
| | | register: true, |
| | | sessionExpires: 1800, |
| | |
| | | const remaining = minDelay - timeSinceRegistration; |
| | | return { |
| | | canCall: false, |
| | | reason: `注册成功,资源加载中请等待 ${Math.ceil(remaining / 1000)} 秒后再呼叫`, |
| | | reason: `注册成功,资源加载中请等待 ${Math.ceil( |
| | | remaining / 1000 |
| | | )} 秒后再呼叫`, |
| | | }; |
| | | } |
| | | |
| | |
| | | if (!this.ua.isRegistered()) { |
| | | throw new Error("SIP未注册,无法呼叫"); |
| | | } |
| | | |
| | | const targetUri = `sip:${targetNumber}@${this.currentConfig.domain}`; |
| | | console.log(`呼叫目标: ${targetUri}`); |
| | | const options = { |
| | | sessionTimers: true, // 启用会话计时器 |
| | | sessionTimersExpires: 150, |
| | |
| | | }, |
| | | }; |
| | | |
| | | this.currentSession = this.ua.call( |
| | | `sip:${targetNumber}@192.168.10.124`, |
| | | options |
| | | ); |
| | | this.currentSession = this.ua.call(targetUri, options); |
| | | |
| | | this.setupPeerConnection(this.currentSession); |
| | | this.setupAudio(this.currentSession); |
| | |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // if (this.endOut == 0) { |
| | | // this.topqueryParams.endSendDateTime = this.formatDateToYYYYMMDDHHMMSS( |
| | | // this.getEndOfDay() |
| | | // ); |
| | | // } else { |
| | | // this.topqueryParams.endSendDateTime = null; |
| | | // } |
| | | if (this.endOut == 0) { |
| | | this.topqueryParams.endSendDateTime = this.formatDateToYYYYMMDDHHMMSS( |
| | | this.getEndOfDay() |
| | | ); |
| | | } else { |
| | | this.topqueryParams.endSendDateTime = null; |
| | | } |
| | | // 接受异常跳转 |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | @change="handleChange" |
| | | ></el-cascader> |
| | | </el-form-item> |
| | | <el-form-item label="日期限制" prop="status"> |
| | | <el-select v-model="endOut" placeholder="请选择"> |
| | | <el-option |
| | | v-for="item in endOuts" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="诊断名称" prop="leavediagname"> |
| | | <el-input |
| | | v-model="topqueryParams.leavediagname" |
| | |
| | | }, |
| | | value: [], |
| | | list: [], |
| | | |
| | | endOut: localStorage.getItem("orgname") == "丽水市中医院" ? 0 : 1, //0 出院时间(正序) 1 出院时间(倒序) 2 发送时间(正序) 3 发送时间(倒序) 7应随访日期(倒序) 应随访日期(正序) |
| | | endOuts: [ |
| | | { |
| | | value: 0, |
| | | label: "截止至当日服务", |
| | | }, |
| | | { |
| | | value: 1, |
| | | label: "全部服务", |
| | | }, |
| | | ], |
| | | sourcetype: [ |
| | | { |
| | | value: 1, |
| | |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | if (this.endOut == 0) { |
| | | this.topqueryParams.endSendDateTime = this.formatDateToYYYYMMDDHHMMSS( |
| | | this.getEndOfDay() |
| | | ); |
| | | } else { |
| | | this.topqueryParams.endSendDateTime = null; |
| | | } |
| | | // 接受异常跳转 |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | this.total = response.total; |
| | | }); |
| | | }, |
| | | |
| | | //患者360跳转 |
| | | gettoken360(sfzh, drcode, drname) { |
| | | // this.$modal.msgWarning('360功能暂未开通'); |
| | |
| | | } |
| | | }); |
| | | }, |
| | | getEndOfDay() { |
| | | const date = new Date(); // 创建一个表示当前时间的Date对象 |
| | | date.setHours(23, 59, 59, 0); // 将时间设置为23:59:59.000 |
| | | return date; |
| | | }, |
| | | formatDateToYYYYMMDDHHMMSS(date) { |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份补零 |
| | | const day = String(date.getDate()).padStart(2, "0"); // 日期补零 |
| | | const hours = String(date.getHours()).padStart(2, "0"); |
| | | const minutes = String(date.getMinutes()).padStart(2, "0"); |
| | | const seconds = String(date.getSeconds()).padStart(2, "0"); |
| | | |
| | | return `${year}-${month}-${day}`; |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | |
| | | <div class="home" style="margin-top: 40px; margin-left: 20px"> |
| | | <!-- 头部两个 --> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="11"> |
| | | <el-col :span="8"> |
| | | <!-- 就诊统计盒子 --> |
| | | <div class="grid-content bg-purple headerBox bgc1"> |
| | | <div class="title"> |
| | |
| | | </el-row> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="9"> |
| | | <el-col :span="12"> |
| | | <div class="grid-content bg-purple headerBox bgc2"> |
| | | <div class="title"> |
| | | 出院服务 |
| | |
| | | <span>{{ endatd }} ~ {{ statd }}</span> |
| | | </div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="10"> |
| | | <!-- 出院就诊量 --> |
| | | <el-col :span="6"> |
| | | <div class="home-user-task-stats"> |
| | | <p style="color: red">{{ DischargeData.rc }}</p> |
| | | </div> |
| | |
| | | <p>出院就诊量(人次)</p> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <!-- 首次服务 --> |
| | | <el-col :span="6"> |
| | | <div class="home-user-task-stats"> |
| | | <p style="color: red">{{ DischargeData.rs }}</p> |
| | | <div class="text-color2"> |
| | | <p>出院服务量(人次)</p> |
| | | </div> |
| | | <p style="color: #67c23a">{{ DischargeData.scsf }}</p> |
| | | </div> |
| | | <div class="text-color2" style="color: #67c23a"> |
| | | <p>首次服务(人次)</p> |
| | | </div> |
| | | </el-col> |
| | | <!-- 再次服务 --> |
| | | <el-col :span="6"> |
| | | <div class="home-user-task-stats"> |
| | | <p style="color: #e6a23c">{{ DischargeData.zcsf }}</p> |
| | | </div> |
| | | <div class="text-color2" style="color: #e6a23c"> |
| | | <p>再次服务(人次)</p> |
| | | </div> |
| | | </el-col> |
| | | <!-- 专病服务 --> |
| | | <el-col :span="6"> |
| | | <div class="home-user-task-stats"> |
| | | <p style="color: #409eff">{{ DischargeData.zbsf }}</p> |
| | | </div> |
| | | <div class="text-color2" style="color: #409eff"> |
| | | <p>专病服务(人次)</p> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | 年: "year", |
| | | }, |
| | | DischargeData: { |
| | | rs: "", |
| | | rc: "", |
| | | rc: "", // 出院就诊量(总人次) |
| | | rs: "", // 出院服务量(总人次) |
| | | scsf: 0, // 新增:首次服务人次 |
| | | zcsf: 0, // 新增:再次服务人次 |
| | | zbsf: 0, // 新增:专病服务人次 |
| | | }, |
| | | OutpatientData: { |
| | | rs: "", |
| | |
| | | <el-radio |
| | | v-for="( |
| | | items, index |
| | | ) in item.ivrTaskScriptTargetoptionList" |
| | | ) in item.ivrLibaScriptTargetoptionList" |
| | | :key="index" |
| | | :label="index" |
| | | >{{ items.targetvalue }}</el-radio |
| | |
| | | <el-checkbox |
| | | v-for="( |
| | | items, index |
| | | ) in item.ivrTaskScriptTargetoptionList" |
| | | ) in item.ivrLibaScriptTargetoptionList" |
| | | :key="index" |
| | | :label="index" |
| | | > |
| | |
| | | getbaseopera, |
| | | getFollowuplist, |
| | | getvFollowup, |
| | | selectInfoByCondition, |
| | | Taskparticty, |
| | | deleteTaskparticty, |
| | | getTaskInfo, |
| | |
| | | // 疾病 |
| | | this.getillness(this.form.libtemplateid); |
| | | |
| | | getvFollowup({ id: this.form.libtemplateid }).then((res) => { |
| | | selectInfoByCondition({id:this.form.templateid} ).then((res) => { |
| | | if (res.code == 200) { |
| | | this.previewtf = true; |
| | | this.previewtftype = 1; |
| | | this.questionList = res.data.ivrLibaTemplateScriptVOList; |
| | | this.objyl.ivrLibaTemplateScriptVOList = |
| | | res.data.ivrLibaTemplateScriptVOList; |
| | | this.questionList = res.data.ivrTaskTemplateScriptVOList; |
| | | this.questionList.forEach((item) => { |
| | | item.qremark = []; |
| | | item.ivrLibaScriptTargetoptionList = |
| | | item.ivrTaskScriptTargetoptionList; |
| | | }); |
| | | this.objyl.ivrLibaScriptTargetoptionList = |
| | | res.data.ivrTaskScriptTargetoptionList; |
| | | } else { |
| | | } |
| | | }); |
| | |
| | | this.objyl.suitway = this.objyl.suitway.join(","); |
| | | } |
| | | this.objyl.ivrLibaTemplateScriptVOList.forEach((item) => { |
| | | item.ivrTaskScriptTargetoptionList = item.ivrTaskScriptTargetoptionList; |
| | | item.ivrTaskScriptTargetoptionList = item.ivrLibaScriptTargetoptionList; |
| | | }); |
| | | this.objyl.ivrTaskTemplateScriptVOList = |
| | | this.objyl.ivrLibaTemplateScriptVOList; |
| | |
| | | this.objyl.isoperation = 1; |
| | | this.objyl.ivrLibaTemplateScriptVOList.forEach((item) => { |
| | | item.ivrTaskScriptTargetoptionList = |
| | | item.ivrTaskScriptTargetoptionList; |
| | | item.ivrLibaScriptTargetoptionList; |
| | | }); |
| | | this.objyl.ivrTaskTemplateScriptVOList = |
| | | this.objyl.ivrLibaTemplateScriptVOList; |
| | |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | :default-time="['00:00:00', '23:59:59']"> |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | > |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | |
| | |
| | | key="pendingFollowUp" |
| | | prop="pendingFollowUp" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | viewDetails( |
| | | scope.row.pendingFollowUpInfo, |
| | | scope.row.leavehospitaldistrictname + '待随访列表' |
| | | ) |
| | | " |
| | | ><span class="button-zx">{{ |
| | | scope.row.pendingFollowUp |
| | | }}</span></el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="随访成功" |
| | |
| | | key="followUpFail" |
| | | prop="followUpFail" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | viewDetails( |
| | | scope.row.followUpFailInfo, |
| | | scope.row.leavehospitaldistrictname + '随访失败列表' |
| | | ) |
| | | " |
| | | ><span class="button-zx">{{ |
| | | scope.row.followUpFail |
| | | }}</span></el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="随访率" |
| | |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- 各类详情 --> |
| | | <el-dialog |
| | | :title="infotitle" |
| | | :visible.sync="infotitleVisible" |
| | | v-loading="infotitloading" |
| | | width="70%" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <div class="examine-jic"> |
| | | <div class="jic-value"> |
| | | <el-row :gutter="20"> |
| | | <!-- 选择患者列表 --> |
| | | <el-table :data="infotitlelist" height="660" style="width: 100%"> |
| | | <el-table-column |
| | | prop="sendname" |
| | | align="center" |
| | | label="姓名" |
| | | width="100" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="taskName" |
| | | align="center" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | label="任务名称" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="sendstate" |
| | | align="center" |
| | | width="200" |
| | | label="任务状态" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <div v-if="scope.row.sendstate == 1"> |
| | | <el-tag type="primary" :disable-transitions="false" |
| | | >表单已领取</el-tag |
| | | > |
| | | </div> |
| | | <div v-if="scope.row.sendstate == 2"> |
| | | <el-tag type="primary" :disable-transitions="false" |
| | | >待随访</el-tag |
| | | > |
| | | </div> |
| | | <div v-if="scope.row.sendstate == 3"> |
| | | <el-tag type="success" :disable-transitions="false" |
| | | >表单已发送</el-tag |
| | | > |
| | | </div> |
| | | <div v-if="scope.row.sendstate == 4"> |
| | | <el-tag type="info" :disable-transitions="false" |
| | | >不执行</el-tag |
| | | > |
| | | </div> |
| | | <div v-if="scope.row.sendstate == 5"> |
| | | <el-tag type="danger" :disable-transitions="false" |
| | | >发送失败</el-tag |
| | | > |
| | | </div> |
| | | <div v-if="scope.row.sendstate == 6"> |
| | | <el-tag type="success" :disable-transitions="false" |
| | | >已完成</el-tag |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="visitTime" |
| | | align="center" |
| | | label="应随访时间" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="finishtime" |
| | | align="center" |
| | | label="随访完成时间" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="出院日期" |
| | | width="200" |
| | | align="center" |
| | | key="endtime" |
| | | prop="endtime" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatTime(scope.row.endtime) }}</span> |
| | | </template></el-table-column |
| | | > |
| | | <el-table-column |
| | | label="责任护士" |
| | | width="120" |
| | | align="center" |
| | | key="nurseName" |
| | | prop="nurseName" |
| | | /> |
| | | <el-table-column |
| | | label="主治医生" |
| | | width="120" |
| | | align="center" |
| | | key="drname" |
| | | prop="drname" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="结果状态" |
| | | align="center" |
| | | key="excep" |
| | | prop="excep" |
| | | width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="dict.type.sys_yujing" |
| | | :value="scope.row.excep" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="处理意见" |
| | | align="center" |
| | | key="suggest" |
| | | prop="suggest" |
| | | width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="dict.type.sys_suggest" |
| | | :value="scope.row.suggest" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="templatename" |
| | | align="center" |
| | | label="服务模板" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="remark" |
| | | align="center" |
| | | label="服务记录" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | > |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="bankcardno" |
| | | align="center" |
| | | label="呼叫状态" |
| | | width="210" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="操作" |
| | | fixed="right" |
| | | align="center" |
| | | width="200" |
| | | class-name="small-padding fixed-width" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click="SeedetailsgGo(scope.row)" |
| | | ><span class="button-zx" |
| | | ><i class="el-icon-s-order"></i>查看</span |
| | | ></el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-row> |
| | | <pagination |
| | | v-show="patienttotal > 0 && this.patientqueryParams.allhosp != 6" |
| | | :total="patienttotal" |
| | | :page.sync="patientqueryParams.pn" |
| | | :limit.sync="patientqueryParams.ps" |
| | | @pagination="Seedetails" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | activeName: "first", //侧边选择 |
| | | orgname: "", |
| | | expands: [], |
| | | infotitlelist: [], |
| | | // 遮罩层 |
| | | loading: false, |
| | | Seedloading: false, |
| | | chartDialogVisible: false, |
| | | infotitleVisible: false, |
| | | infotitloading: false, |
| | | infotitle: "", |
| | | pieChart: null, |
| | | barLineChart: null, |
| | | // 选中数组 |
| | |
| | | this.Seedloading = false; |
| | | }); |
| | | }, |
| | | viewDetails(row, title) { |
| | | this.infotitleVisible = true; |
| | | this.infotitle = title; |
| | | this.infotitlelist = row; |
| | | }, |
| | | SeedetailsgGo(row) { |
| | | this.SeedetailsVisible = false; |
| | | let type = ""; |
| | |
| | | const excelName = `${currentMonth}月出院随访统计表.xlsx`; |
| | | // 创建新的工作簿和工作表 |
| | | const workbook = new ExcelJS.Workbook(); |
| | | const worksheet = workbook.addWorksheet("随访统计"); |
| | | |
| | | const worksheet = workbook.addWorksheet(`${currentMonth}月出院随访统计表`); |
| | | // 定义样式(新增总标题样式) |
| | | const titleStyle = { |
| | | font: { |
| | | name: "微软雅黑", |
| | | size: 16, |
| | | bold: true, |
| | | color: { argb: "FF000000" }, |
| | | }, |
| | | fill: { |
| | | type: "pattern", |
| | | pattern: "solid", |
| | | fgColor: { argb: "FFE6F3FF" }, |
| | | }, |
| | | alignment: { |
| | | vertical: "middle", |
| | | horizontal: "center", |
| | | wrapText: true, |
| | | }, |
| | | border: { |
| | | top: { style: "thin", color: { argb: "FFD0D0D0" } }, |
| | | left: { style: "thin", color: { argb: "FFD0D0D0" } }, |
| | | bottom: { style: "thin", color: { argb: "FFD0D0D0" } }, |
| | | right: { style: "thin", color: { argb: "FFD0D0D0" } }, |
| | | }, |
| | | }; |
| | | // 定义样式 |
| | | const headerStyle = { |
| | | font: { |
| | |
| | | right: { style: "thin", color: { argb: "FFD0D0D0" } }, |
| | | }, |
| | | }; |
| | | |
| | | // 1. 添加总标题行(第一行) |
| | | worksheet.mergeCells(1, 1, 1, 23); // 合并A1到W1的所有列[1,4](@ref) |
| | | const titleCell = worksheet.getCell(1, 1); |
| | | titleCell.value = `${currentMonth}月出院随访统计表`; // 使用文件名作为总标题 |
| | | titleCell.style = titleStyle; |
| | | worksheet.getRow(1).height = 35; // 设置总标题行高 |
| | | // 1. 首先,创建并设置第二行(子表头)的所有单元格 |
| | | const secondRowHeaders = [ |
| | | "", // A2 展开列占位(其值将由第一行合并后的主单元格决定) |
| | |
| | | "微信", |
| | | ]; |
| | | |
| | | // 添加第二行并设置样式 |
| | | secondRowHeaders.forEach((header, index) => { |
| | | // 注意:列索引从1开始,对应A列是1,B列是2,以此类推。 |
| | | const cell = worksheet.getCell(2, index + 1); |
| | | cell.value = header; |
| | | cell.style = headerStyle; |
| | | }); |
| | | // 添加第二行(原第一行下移) |
| | | secondRowHeaders.forEach((header, index) => { |
| | | const cell = worksheet.getCell(3, index + 1); // 改为第3行 |
| | | cell.value = header; |
| | | cell.style = headerStyle; |
| | | }); |
| | | |
| | | // 2. 然后,创建第一行的主标题单元格并设置样式,紧接着进行纵向合并 |
| | | // 合并 A1:A2 并设置值 |
| | | worksheet.mergeCells(1, 1, 2, 1); // 合并 A1 到 A2 |
| | | worksheet.getCell(1, 1).value = ""; // 设置主单元格(A1)的值 |
| | | worksheet.getCell(1, 1).style = headerStyle; // 设置主单元格样式 |
| | | // 3. 调整原合并单元格位置(原第1行合并单元格下移到第2行) |
| | | // 合并 A2:A3 |
| | | worksheet.mergeCells(2, 1, 3, 1); |
| | | worksheet.getCell(2, 1).value = ""; |
| | | worksheet.getCell(2, 1).style = headerStyle; |
| | | |
| | | // 合并 B1:B2 并设置值 |
| | | worksheet.mergeCells(1, 2, 2, 2); // 合并 B1 到 B2 |
| | | worksheet.getCell(1, 2).value = "出院病区"; |
| | | worksheet.getCell(1, 2).style = headerStyle; |
| | | // 合并 B2:B3 |
| | | worksheet.mergeCells(2, 2, 3, 2); |
| | | worksheet.getCell(2, 2).value = "出院病区"; |
| | | worksheet.getCell(2, 2).style = headerStyle; |
| | | |
| | | // 合并 C1:C2 并设置值 |
| | | worksheet.mergeCells(1, 3, 2, 3); // 合并 C1 到 C2 |
| | | worksheet.getCell(1, 3).value = "科室"; |
| | | worksheet.getCell(1, 3).style = headerStyle; |
| | | // 合并 C2:C3 |
| | | worksheet.mergeCells(2, 3, 3, 3); |
| | | worksheet.getCell(2, 3).value = "科室"; |
| | | worksheet.getCell(2, 3).style = headerStyle; |
| | | |
| | | // 合并 D1:D2 并设置值 |
| | | worksheet.mergeCells(1, 4, 2, 4); // 合并 D1 到 D2 |
| | | worksheet.getCell(1, 4).value = "出院人次"; |
| | | worksheet.getCell(1, 4).style = headerStyle; |
| | | // 合并 D2:D3 |
| | | worksheet.mergeCells(2, 4, 3, 4); |
| | | worksheet.getCell(2, 4).value = "出院人次"; |
| | | worksheet.getCell(2, 4).style = headerStyle; |
| | | |
| | | // 合并 E1:E2 并设置值 |
| | | worksheet.mergeCells(1, 5, 2, 5); // 合并 E1 到 E2 |
| | | worksheet.getCell(1, 5).value = "无需随访人次"; |
| | | worksheet.getCell(1, 5).style = headerStyle; |
| | | // 合并 E2:E3 |
| | | worksheet.mergeCells(2, 5, 3, 5); |
| | | worksheet.getCell(2, 5).value = "无需随访人次"; |
| | | worksheet.getCell(2, 5).style = headerStyle; |
| | | |
| | | // 合并 F1:F2 并设置值 |
| | | worksheet.mergeCells(1, 6, 2, 6); // 合并 F1 到 F2 |
| | | worksheet.getCell(1, 6).value = "应随访人次"; |
| | | worksheet.getCell(1, 6).style = headerStyle; |
| | | // 合并 F2:F3 |
| | | worksheet.mergeCells(2, 6, 3, 6); |
| | | worksheet.getCell(2, 6).value = "应随访人次"; |
| | | worksheet.getCell(2, 6).style = headerStyle; |
| | | |
| | | // 3. 设置第一行的横向合并标题(这些保持不变,因为只涉及第一行) |
| | | // 首次出院随访(合并G1到O1) |
| | | worksheet.mergeCells("G1:O1"); |
| | | worksheet.getCell("G1").value = "首次出院随访"; |
| | | worksheet.getCell("G1").style = headerStyle; |
| | | // 4. 调整横向合并标题位置(下移到第2行) |
| | | // 首次出院随访(合并G2:O2) |
| | | worksheet.mergeCells(2, 7, 2, 15); // G2:O2 |
| | | worksheet.getCell(2, 7).value = "首次出院随访"; |
| | | worksheet.getCell(2, 7).style = headerStyle; |
| | | |
| | | // 再次出院随访(合并P1到W1) |
| | | worksheet.mergeCells("P1:W1"); |
| | | worksheet.getCell("P1").value = "再次出院随访"; |
| | | worksheet.getCell("P1").style = headerStyle; |
| | | // 再次出院随访(合并P2:W2) |
| | | worksheet.mergeCells(2, 16, 2, 23); // P2:W2 |
| | | worksheet.getCell(2, 16).value = "再次出院随访"; |
| | | worksheet.getCell(2, 16).style = headerStyle; |
| | | |
| | | // 4. 设置行高(可选,但建议设置) |
| | | worksheet.getRow(1).height = 28; // 第一行行高 |
| | | worksheet.getRow(2).height = 25; // 第二行行高 |
| | | // 5. 设置行高 |
| | | worksheet.getRow(1).height = 35; // 总标题行高 |
| | | worksheet.getRow(2).height = 28; // 原第一行下移 |
| | | worksheet.getRow(3).height = 25; // 原第二行下移 |
| | | |
| | | // 添加数据行 |
| | | this.userList.forEach((item, rowIndex) => { |
| | | const dataRow = worksheet.addRow([ |
| | | "", // 展开列 |
| | | item.leavehospitaldistrictname || "", |
| | | item.deptname || "", |
| | | item.dischargeCount || 0, |
| | | item.nonFollowUp || 0, |
| | | item.followUpNeeded || 0, |
| | | // 首次出院随访数据 |
| | | item.needFollowUp || 0, |
| | | item.pendingFollowUp || 0, |
| | | item.followUpSuccess || 0, |
| | | item.followUpFail || 0, |
| | | item.followUpRate || "0%", |
| | | item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%", |
| | | item.manual || 0, |
| | | item.sms || 0, |
| | | item.weChat || 0, |
| | | // 再次出院随访数据 |
| | | item.needFollowUpAgain || 0, |
| | | item.pendingFollowUpAgain || 0, |
| | | item.followUpSuccessAgain || 0, |
| | | item.followUpFailAgain || 0, |
| | | item.followUpRateAgain || "0%", |
| | | item.manualAgain || 0, |
| | | item.smsAgain || 0, |
| | | item.weChatAgain || 0, |
| | | ]); |
| | | // 6. 添加数据行(注意行索引需要+1,因为上面插入了一行) |
| | | this.userList.forEach((item, rowIndex) => { |
| | | const dataRow = worksheet.addRow([ |
| | | "", // 展开列 |
| | | item.leavehospitaldistrictname || "", |
| | | item.deptname || "", |
| | | item.dischargeCount || 0, |
| | | item.nonFollowUp || 0, |
| | | item.followUpNeeded || 0, |
| | | // 首次出院随访数据 |
| | | item.needFollowUp || 0, |
| | | item.pendingFollowUp || 0, |
| | | item.followUpSuccess || 0, |
| | | item.followUpFail || 0, |
| | | item.followUpRate || "0%", |
| | | item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%", |
| | | item.manual || 0, |
| | | item.sms || 0, |
| | | item.weChat || 0, |
| | | // 再次出院随访数据 |
| | | item.needFollowUpAgain || 0, |
| | | item.pendingFollowUpAgain || 0, |
| | | item.followUpSuccessAgain || 0, |
| | | item.followUpFailAgain || 0, |
| | | item.followUpRateAgain || "0%", |
| | | item.manualAgain || 0, |
| | | item.smsAgain || 0, |
| | | item.weChatAgain || 0, |
| | | ], rowIndex + 4); // 从第4行开始添加数据(原第3行) |
| | | |
| | | // 应用数据行样式 |
| | | dataRow.eachCell((cell) => { |
| | | cell.style = cellStyle; |
| | | }); |
| | | dataRow.height = 24; |
| | | }); |
| | | // 应用数据行样式 |
| | | dataRow.eachCell((cell) => { |
| | | cell.style = cellStyle; |
| | | }); |
| | | dataRow.height = 24; |
| | | }); |
| | | |
| | | // 添加合计行 |
| | | const summaries = this.getSummaries({ |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="统计题目" prop="userName"> |
| | | <el-form-item label="服务类型" prop="userName"> |
| | | <el-select |
| | | v-model="queryParams.serviceType" |
| | | multiple |
| | |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span class="button-zx" |
| | | >{{ |
| | | (Number(scope.row.joyTotal) * 100).toFixed(2) |
| | | }}%</span |
| | | > |
| | | >{{ (Number(scope.row.joyTotal) * 100).toFixed(2) }}%</span |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- <pagination |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> --> |
| | | /> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | |
| | | </div> |
| | | </el-dialog> |
| | | <!-- 单科室统计详情 --> |
| | | <el-dialog :visible.sync="topicVisible" width="45%"> |
| | | <el-dialog :visible.sync="topicVisible" width="45%"> |
| | | <div class="topicdia"> |
| | | <div class="top-text">{{ topicvalue.name }}</div> |
| | | <div class="top-mintext">随访完成数{{ topicvalue.number }}</div> |
| | |
| | | } from "@/api/system/label"; |
| | | import store from "@/store"; |
| | | import { |
| | | getSfStatisticsJoydetails, |
| | | getSfStatisticsJoy, |
| | | getSfStatisticsJoyInfo, |
| | | selectTimelyRate, |
| | | } from "@/api/system/user"; |
| | | |
| | |
| | | type: 1, |
| | | }, |
| | | ], |
| | | tableData: [ |
| | | tableData: [ |
| | | { |
| | | date: "好", |
| | | name: 12, |
| | |
| | | getList() { |
| | | // 处理查询参数 |
| | | const params = { |
| | | configKey: "joyCount", |
| | | ...this.queryParams, |
| | | // 如果选择了"全部",则传所有病区/科室代码 |
| | | leavehospitaldistrictcodes: |
| | |
| | | delete params.deptcodes.all; |
| | | getSfStatisticsJoy(params).then((response) => { |
| | | console.log(response); |
| | | // this.total = response.total; |
| | | this.total = response.total; |
| | | this.userList = response.data; |
| | | }); |
| | | }, |
| | |
| | | // 调起详情 |
| | | getinfo(row) { |
| | | this.topicVisible = true; |
| | | // 处理查询参数 |
| | | const params = { |
| | | configKey: "joyCount", |
| | | ...this.queryParams, |
| | | }; |
| | | if (this.queryParams.statisticaltype == 1) { |
| | | params.leavehospitaldistrictcodes = [row.leavehospitaldistrictcode]; |
| | | } else { |
| | | params.deptcodes = [row.deptcode]; |
| | | } |
| | | |
| | | // 移除可能存在的"all"值 |
| | | delete params.leavehospitaldistrictcodes.all; |
| | | delete params.deptcodes.all; |
| | | getSfStatisticsJoyInfo(params).then((response) => { |
| | | console.log(response); |
| | | this.total = response.total; |
| | | this.userList = response.data; |
| | | }); |
| | | }, |
| | | // 添加/修改标签 |
| | | Maintenancetag() { |
| | |
| | | // detail: https://cli.vuejs.org/config/#devserver-proxy |
| | | [process.env.VUE_APP_BASE_API]: { |
| | | // target: `https://www.health-y.cn/lssf`, |
| | | target: `http://192.168.100.10:8096`, |
| | | // target: `http://192.168.100.10:8096`, |
| | | // target: `http://192.168.100.10:8094`,//省立同德 |
| | | // target: `http://192.168.100.10:8095`,//新华 |
| | | // target:`http://localhost:8095`, |
| | | target:`http://localhost:8095`, |
| | | // target:`http://35z1t16164.qicp.vip`, |
| | | // target: `http://192.168.100.111:8095`, |
| | | // target: `http://192.168.101.166:8093`, |