| | |
| | | </div> |
| | | <div class="Followuserinfos"> |
| | | <div> |
| | | <el-form ref="form" :model="form" label-width="120px"> |
| | | <el-form |
| | | ref="userform" |
| | | :model="form" |
| | | :rules="userrules" |
| | | label-width="120px" |
| | | > |
| | | <div class="headline"> |
| | | <div>人工处理</div> |
| | | <el-row :gutter="20"> |
| | |
| | | <el-input |
| | | placeholder="联系电话缺失" |
| | | v-model="userform.telcode" |
| | | > |
| | | <el-button |
| | | slot="append" |
| | | icon="el-icon-phone" |
| | | @click="handleCall(userform.telcode, 'tel')" |
| | | :disabled="!isValidPhone(userform.telcode)" |
| | | ></el-button |
| | | ></el-input> </el-form-item |
| | | ></el-col> |
| | | <el-col :span="8" |
| | |
| | | <el-input |
| | | placeholder="联系人电话缺失" |
| | | v-model="userform.relativetelcode" |
| | | > |
| | | <el-button |
| | | slot="append" |
| | | icon="el-icon-phone" |
| | | @click="handleCall(userform.relativetelcode, 'relative')" |
| | | :disabled="!isValidPhone(userform.relativetelcode)" |
| | | ></el-button |
| | | ></el-input> </el-form-item |
| | | ></el-col> |
| | | <el-col :span="8" |
| | |
| | | ></el-input> </el-form-item |
| | | ></el-col> |
| | | </el-row> |
| | | |
| | | <div style="margin-left: 30px"> |
| | | <el-button type="primary" plain @click="Editsingletasksonyic('')" |
| | | >保存服务</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | <el-row :gutter="20" v-if="callStatus !== 'idle'"> |
| | | <el-col :span="24"> |
| | | <el-alert |
| | | :title="callStatusText" |
| | | :type="callStatusType" |
| | | :closable="false" |
| | | show-icon |
| | | /> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- 挂断按钮(仅在通话中显示) --> |
| | | <el-row :gutter="20" v-if="callStatus === 'connected'"> |
| | | <el-col :span="24" style="text-align: center; margin-top: 10px"> |
| | | <el-button |
| | | type="danger" |
| | | icon="el-icon-phone" |
| | | @click="endCurrentCall" |
| | | :loading="isEndingCall" |
| | | > |
| | | 挂断电话 |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="随访记录"> |
| | | <el-input type="textarea" v-model="form.remark"></el-input> |
| | | </el-form-item> |
| | |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | | </div> |
| | | </div> |
| | | <div> |
| | | <h2>一键呼叫功能</h2> |
| | | <CallButton |
| | | ref="callButton" |
| | | :phoneNumber="currentPhoneNumber" |
| | | style="display: none" |
| | | /> |
| | | </div> |
| | | <div> |
| | | <el-tabs v-model="activeName" type="border-card"> |
| | |
| | | 完整语音: |
| | | <mini-audio |
| | | :audio-source=" |
| | | voice ? voice : 'https://example.com/example.mp3' |
| | | voice ? voice : '@assets/order/example.mp3' |
| | | " |
| | | ></mini-audio> |
| | | </div> |
| | |
| | | :audio-source=" |
| | | item.questionvoice |
| | | ? item.questionvoice |
| | | : 'https://example.com/example.mp3' |
| | | : '@assets/order/example.mp3' |
| | | " |
| | | ></mini-audio> |
| | | </div> |
| | |
| | | v-model="form.endtime" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <div class="headline">上次随访</div> |
| | | <el-divider></el-divider> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="随访方式"> |
| | | <el-select |
| | | v-model="form.visitType2" |
| | | filterable |
| | | allow-create |
| | | default-first-option |
| | | disabled |
| | | placeholder="请选择随访方式" |
| | | class="custom-disabled" |
| | | > |
| | | <el-option |
| | | v-for="item in options" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="随访时间"> |
| | | <el-date-picker |
| | | type="date" |
| | | disabled |
| | | placeholder="选择日期" |
| | | :picker-options="pickerOptions" |
| | | align="right" |
| | | v-model="form.date2" |
| | | class="custom-disabled" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form-item label="随访记录"> |
| | | <el-input |
| | | class="custom-disabled" |
| | | type="textarea" |
| | | disabled |
| | | v-model="form.remark2" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <div class="headline">下次随访</div> |
| | | <el-divider></el-divider> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="随访方式" prop="date1"> |
| | | <el-select |
| | | v-model="form.visitType" |
| | | filterable |
| | | allow-create |
| | | default-first-option |
| | | @change="visitChange" |
| | | placeholder="请选择随访方式(依出院时间技计算)" |
| | | > |
| | | <el-option |
| | | v-for="item in options" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="随访时间" prop="date1"> |
| | | <el-date-picker |
| | | type="date" |
| | | placeholder="选择日期" |
| | | :picker-options="pickerOptions" |
| | | align="right" |
| | | v-model="form.date1" |
| | | class="custom-disabled" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="随访方式" prop="resource"> |
| | | <el-radio-group v-model="form.resource"> |
| | | <el-radio label="1">本病区随访</el-radio> |
| | | <el-radio label="2">随访中心随访</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="即刻发送"> |
| | | <el-switch v-model="zcform.delivery"></el-switch> |
| | | </el-form-item> --> |
| | | <el-form-item label="随访时间" prop="date1"> |
| | | <el-date-picker |
| | | type="date" |
| | | placeholder="选择日期" |
| | | :picker-options="pickerOptions" |
| | | align="right" |
| | | v-model="form.date1" |
| | | style="width: 100%" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="随访记录"> |
| | | <el-input type="textarea" v-model="form.remark"></el-input> |
| | | </el-form-item> |
| | |
| | | alterpatient, |
| | | listcontactinformation, |
| | | } from "@/api/patient/homepage"; |
| | | import CallButton from "@/components/CallButton"; |
| | | export default { |
| | | components: { |
| | | CallButton, |
| | | }, |
| | | |
| | | dicts: ["sys_normal_disable", "sys_user_sex", "sys_yujing", "sys_suggest"], |
| | | data() { |
| | | const validatePhone = (rule, value, callback) => { |
| | | if (!value) { |
| | | return callback(new Error("请输入联系电话")); |
| | | } |
| | | setTimeout(() => { |
| | | if (!/^1[3-9]\d{9}$/.test(value)) { |
| | | callback(new Error("请输入正确的11位手机号码")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, 300); |
| | | }; |
| | | return { |
| | | userid: "", |
| | | currentPhoneNumber: "", |
| | | callType: "", // 用于区分是哪个电话 |
| | | // 已有数据... |
| | | callStatus: "idle", // idle, calling, connected, ended, failed |
| | | isEndingCall: false, |
| | | currentCall: null, // 当前通话对象 |
| | | input: "今天身体还不错", |
| | | radio: "2", |
| | | taskname: "", |
| | |
| | | voiceDatatop: [], //题目表 |
| | | dynamicTags: [], |
| | | zcrules: { |
| | | date1: [ |
| | | resource: [ |
| | | { required: true, message: "请选择随访方式", trigger: "change" }, |
| | | ], |
| | | resource: [ |
| | | { required: true, message: "请选择随访时间", trigger: "blur" }, |
| | | ], |
| | | date1: [{ required: true, message: "请选择随访时间", trigger: "blur" }], |
| | | }, |
| | | userrules: { |
| | | telcode: [{ validator: validatePhone, trigger: "blur" }], |
| | | relativetelcode: [{ validator: validatePhone, trigger: "blur" }], |
| | | }, |
| | | url: "http://9.208.2.190:8090/smartor/serviceExternal/query360PatInfo", |
| | | postData: { |
| | |
| | | }, |
| | | }, |
| | | pickerOptions: { |
| | | disabledDate(time) { |
| | | // 禁用今天及之前的日期 |
| | | return time.getTime() < Date.now() - 24 * 60 * 60 * 1000; |
| | | }, |
| | | shortcuts: [ |
| | | { |
| | | text: "七天后", |
| | |
| | | }, |
| | | }, |
| | | { |
| | | text: "30天后", |
| | | text: "一个月后", |
| | | onClick(picker) { |
| | | const date = new Date(); |
| | | date.setTime(date.getTime() + 3600 * 1000 * 24 * 30); |
| | | picker.$emit("pick", date); |
| | | }, |
| | | }, |
| | | { |
| | | text: "三个月后", |
| | | onClick(picker) { |
| | | const date = new Date(); |
| | | date.setTime(date.getTime() + 3600 * 1000 * 24 * 90); |
| | | picker.$emit("pick", date); |
| | | }, |
| | | }, |
| | | { |
| | | text: "六个月后", |
| | | onClick(picker) { |
| | | const date = new Date(); |
| | | date.setTime(date.getTime() + 3600 * 1000 * 24 * 180); |
| | | picker.$emit("pick", date); |
| | | }, |
| | | }, |
| | | { |
| | | text: "一年后", |
| | | onClick(picker) { |
| | | const date = new Date(); |
| | | date.setTime(date.getTime() + 3600 * 1000 * 24 * 365); |
| | | picker.$emit("pick", date); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | options: [ |
| | | { |
| | | value: "七天后", |
| | | label: "七天后", |
| | | }, |
| | | { |
| | | value: "15天后", |
| | | label: "15天后", |
| | | }, |
| | | { |
| | | value: "一个月后", |
| | | label: "一个月后", |
| | | }, |
| | | { |
| | | value: "三个月后", |
| | | label: "三个月后", |
| | | }, |
| | | { |
| | | value: "六个月后", |
| | | label: "六个月后", |
| | | }, |
| | | { |
| | | value: "一年后", |
| | | label: "一年后", |
| | | }, |
| | | ], |
| | | userform: {}, |
| | | Whetherall: true, //是否全部记录展示 |
| | | dialogFormVisible: false, |
| | | Voicetype: 0, //是否为语音服务 |
| | | visitCount: null, |
| | | logsheetlist: [], |
| | | topicobj: {}, |
| | | sendname: null, |
| | |
| | | patid: null, |
| | | }; |
| | | }, |
| | | |
| | | computed: { |
| | | callStatusText() { |
| | | const statusMap = { |
| | | idle: "准备呼叫", |
| | | calling: `正在呼叫 ${this.currentPhoneNumber}...`, |
| | | connected: `已接通 ${this.currentPhoneNumber}`, |
| | | ended: "通话已结束", |
| | | failed: "呼叫失败", |
| | | }; |
| | | return statusMap[this.callStatus]; |
| | | }, |
| | | callStatusType() { |
| | | const typeMap = { |
| | | idle: "info", |
| | | calling: "warning", |
| | | connected: "success", |
| | | ended: "info", |
| | | failed: "error", |
| | | }; |
| | | return typeMap[this.callStatus]; |
| | | }, |
| | | }, |
| | | created() { |
| | | this.taskid = this.$route.query.taskid; |
| | | this.id = this.$route.query.id; |
| | |
| | | this.patid = this.$route.query.patid; |
| | | this.again = this.$route.query.again; |
| | | this.Voicetype = this.$route.query.Voicetype; |
| | | this.visitCount = this.$route.query.visitCount; |
| | | this.serviceType = this.$route.query.serviceType; |
| | | |
| | | this.getTaskservelist(); |
| | |
| | | } |
| | | }); |
| | | }, |
| | | // 再次随访时间选取 |
| | | visitChange(value) { |
| | | // 根据选择的随访方式设置时间 |
| | | const now = new Date(); |
| | | if (value.includes("七天后")) { |
| | | this.form.date1 = new Date( |
| | | Date.parse(this.form.endtime) + 3600 * 1000 * 24 * 7 |
| | | ); |
| | | } else if (value.includes("15天后")) { |
| | | this.form.date1 = new Date( |
| | | Date.parse(this.form.endtime) + 3600 * 1000 * 24 * 15 |
| | | ); |
| | | } else if (value.includes("一个月后")) { |
| | | this.form.date1 = new Date( |
| | | Date.parse(this.form.endtime) + 3600 * 1000 * 24 * 30 |
| | | ); |
| | | } else if (value.includes("三个月后")) { |
| | | this.form.date1 = new Date( |
| | | Date.parse(this.form.endtime) + 3600 * 1000 * 24 * 90 |
| | | ); |
| | | } else if (value.includes("六个月后")) { |
| | | this.form.date1 = new Date( |
| | | Date.parse(this.form.endtime) + 3600 * 1000 * 24 * 180 |
| | | ); |
| | | } else if (value.includes("一年后")) { |
| | | this.form.date1 = new Date( |
| | | Date.parse(this.form.endtime) + 3600 * 1000 * 24 * 365 |
| | | ); |
| | | } |
| | | }, |
| | | |
| | | // 获取语音数据 |
| | | getPersonVoices(id) { |
| | | let obj = { |
| | |
| | | ) |
| | | .then(() => { |
| | | document.querySelector("#app").scrollTo(0, 0); |
| | | this.formtidy(); |
| | | this.dialogFormVisible = true; |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { |
| | | if (this.form.serviceType == 13) { |
| | | if (this.visitCount!=1) { |
| | | this.$router.push({ |
| | | path: "/logisticsservice/zbAgain", |
| | | }); |
| | | } else { |
| | | this.$router.push({ |
| | | path: "/logisticsservice/record", |
| | | }); |
| | | } |
| | | } else if (this.form.serviceType == 2) { |
| | | if (this.visitCount!=1) { |
| | | this.$router.push({ |
| | | path: "/logisticsservice/again", |
| | | }); |
| | | } else { |
| | | this.$router.push({ |
| | | path: "/followvisit/discharge", |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }) |
| | | .catch((error) => { |
| | | // 如果有任何一个异步操作失败,会进入这里 |
| | | console.error("发生错误:", error); |
| | | }); |
| | | }, |
| | | // 验证电话号码格式并返回错误信息 |
| | | validatePhoneNumber(phone) { |
| | | if (!phone) { |
| | | return { isValid: false, message: "请输入电话号码" }; |
| | | } |
| | | |
| | | // 手机号正则 |
| | | const mobileRegex = /^1[3-9]\d{9}$/; |
| | | |
| | | // 带区号的固定电话(完整格式) |
| | | const landlineFullRegex = /^0\d{2,3}-?\d{7,8}$/; |
| | | |
| | | // 不带区号的固定电话(仅本地号码) |
| | | const landlineLocalRegex = /^\d{7,8}$/; |
| | | |
| | | if (mobileRegex.test(phone)) { |
| | | return { isValid: true, type: "mobile" }; |
| | | } else if (landlineFullRegex.test(phone)) { |
| | | return { isValid: true, type: "landline" }; |
| | | } else if (landlineLocalRegex.test(phone)) { |
| | | return { |
| | | isValid: false, |
| | | message: "本地号码请添加区号(如028-1234567)", |
| | | }; |
| | | } else { |
| | | return { |
| | | isValid: false, |
| | | message: "请输入正确的电话号码(手机号或带区号的固定电话)", |
| | | }; |
| | | } |
| | | }, |
| | | |
| | | // 使用示例 |
| | | isValidPhone(phone) { |
| | | return this.validatePhoneNumber(phone).isValid; |
| | | }, |
| | | handleCall(phone, type) { |
| | | if (!this.isValidPhone(phone)) { |
| | | this.$message.error("请输入正确的手机号码"); |
| | | return; |
| | | } |
| | | |
| | | this.currentPhoneNumber = phone; |
| | | this.callType = type; |
| | | this.callStatus = "calling"; |
| | | |
| | | this.$nextTick(() => { |
| | | this.$refs.callButton.startCall(); |
| | | |
| | | // 监听通话状态变化 |
| | | this.$refs.callButton.$on("call-status-change", (status) => { |
| | | this.handleCallStatusChange(status); |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 处理通话状态变化 |
| | | handleCallStatusChange(status) { |
| | | console.log(status, "status"); |
| | | |
| | | this.callStatus = status.type; |
| | | |
| | | if (status.type === "connected") { |
| | | this.currentCall = { |
| | | phone: this.currentPhoneNumber, |
| | | type: this.callType, |
| | | startTime: new Date(), |
| | | }; |
| | | } else if (status.type === "ended" || status.type === "failed") { |
| | | this.currentCall = null; |
| | | } |
| | | |
| | | // 可以根据状态执行其他操作 |
| | | if (status.type === "failed") { |
| | | this.$message.error(`呼叫失败: ${status.text}`); |
| | | } |
| | | }, |
| | | |
| | | // 结束当前通话 |
| | | endCurrentCall() { |
| | | if (!this.currentCall) return; |
| | | |
| | | this.isEndingCall = true; |
| | | this.$refs.callButton.endCall(); |
| | | |
| | | // 3秒后重置状态 |
| | | setTimeout(() => { |
| | | this.isEndingCall = false; |
| | | }, 3000); |
| | | }, |
| | | yuyingetdetail() { |
| | | this.tableDatatop.forEach((item, index) => { |
| | |
| | | ) |
| | | .then(() => { |
| | | document.querySelector("#app").scrollTo(0, 0); |
| | | this.formtidy(); |
| | | this.dialogFormVisible = true; |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { |
| | | if (this.form.serviceType == 13) { |
| | | if (this.visitCount != 1) { |
| | | this.$router.push({ |
| | | path: "/logisticsservice/zbAgain", |
| | | }); |
| | | } else { |
| | | this.$router.push({ |
| | | path: "/logisticsservice/record", |
| | | }); |
| | | } |
| | | } else if (form.serviceType == 2) { |
| | | if (this.visitCount != 1) { |
| | | this.$router.push({ |
| | | path: "/followvisit/again", |
| | | }); |
| | | } else { |
| | | this.$router.push({ |
| | | path: "/followvisit/discharge", |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 再次随访数据更替 |
| | | formtidy() { |
| | | this.form.visitType2 = this.form.visitType; |
| | | this.form.date2 = this.form.longSendTime; |
| | | this.form.remark2 = this.form.remark; |
| | | }, |
| | | // 获取患者记录 |
| | | getTaskservelist(id) { |
| | | if (id) { |
| | |
| | | this.form = res.rows[0].serviceSubtaskList.find( |
| | | (item) => item.id == this.id |
| | | ); |
| | | console.log(this.form.serviceType, "serviceType"); |
| | | |
| | | this.logsheetlist = res.rows[0].serviceSubtaskList; |
| | | this.templateid = this.logsheetlist[0].templateid; |
| | | const targetDate = new Date(this.form.longSendTime); // 目标日期 |
| | | const now = new Date(); // 当前时间 |
| | | this.form.endtime = this.formatTime(this.form.endtime); |
| | | if (now < targetDate && this.form.sendstate == 2) { |
| | | this.$confirm("当前服务未到发送时间请谨慎修改", "提示", { |
| | | confirmButtonText: "确定", |
| | |
| | | sendAgain() { |
| | | document.querySelector("#app").scrollTo(0, 0); |
| | | // scrollTo(0, 0) |
| | | this.formtidy(); |
| | | this.dialogFormVisible = true; |
| | | }, |
| | | // 查看详情 |
| | |
| | | setupsubtask() { |
| | | this.$refs["zcform"].validate((valid) => { |
| | | if (valid) { |
| | | if (this.form.date1 && new Date(this.form.date1) < new Date()) { |
| | | this.$message.error("随访时间不能小于当前时间"); |
| | | return false; |
| | | } |
| | | this.form.remark = |
| | | this.form.remark + "【" + this.getCurrentTime() + "】"; |
| | | let form = structuredClone(this.form); |
| | |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | | form.serviceType = 13; |
| | | form.visitDeptCode = localStorage.getItem("deptCode"); |
| | | form.visitDeptName = "随访中心"; |
| | | } else { |
| | | form.visitDeptCode = form.deptcode; |
| | | form.visitDeptName = form.deptname; |
| | | } |
| | | } else { |
| | | this.$modal.msgError("未选择随访方式"); |
| | | return; |
| | | } |
| | | // form.id = null; |
| | | form.sendstate = 2; |
| | | console.log(form.serviceType, "form.serviceType"); |
| | | |
| | | addserviceSubtask(form).then((res) => { |
| | | if (res.code == 200) { |
| | | this.$modal.msgSuccess("创建成功"); |
| | | if (form.serviceType == 13) { |
| | | this.$router.push({ |
| | | path: "/logisticsservice/record", |
| | | path: "/logisticsservice/zbAgain", |
| | | }); |
| | | } else if (form.serviceType == 2) { |
| | | this.$router.push({ |
| | | path: "/followvisit/discharge", |
| | | path: "/logisticsservice/again", |
| | | }); |
| | | } |
| | | } else { |
| | |
| | | background-color: #f57676; |
| | | border-color: #f57676; |
| | | } |
| | | .el-icon-phone { |
| | | transition: all 0.3s; |
| | | } |
| | | .el-button[disabled] .el-icon-phone { |
| | | color: #c0c4cc; |
| | | } |
| | | .el-button:not([disabled]) .el-icon-phone { |
| | | color: #409eff; |
| | | } |
| | | .el-button:not([disabled]):hover .el-icon-phone { |
| | | color: #66b1ff; |
| | | transform: scale(1.1); |
| | | } |
| | | .mulsz { |
| | | font-size: 25px; |
| | | margin-top: 20px; |
| | | } |
| | | .el-input.is-disabled .el-input__inner { |
| | | background-color: #fff; /* 背景颜色 */ |
| | | border-color: #dcdfe6; /* 边框颜色 */ |
| | | color: #080808 !important; /* 文字颜色 */ |
| | | cursor: not-allowed; /* 鼠标样式 */ |
| | | } |
| | | .el-textarea.is-disabled .el-textarea__inner { |
| | | background-color: #fff; /* 背景颜色 */ |
| | | border-color: #dcdfe6; /* 边框颜色 */ |
| | | color: #080808 !important; /* 文字颜色 */ |
| | | cursor: not-allowed; /* 鼠标样式 */ |
| | | } |
| | | </style> |