Merge branch 'master' of http://101.42.27.146:5001/r/ltkj_peisweb
New file |
| | |
| | | // src/main.js |
| | | import Vue from "vue"; |
| | | import Cookies from "js-cookie"; |
| | | import "babel-polyfill"; |
| | | import Element from "element-ui"; |
| | | import "./assets/styles/element-variables.scss"; |
| | | import "@/assets/styles/index.scss"; |
| | | import "@/assets/styles/ruoyi.scss"; |
| | | import App from "./App"; |
| | | import store from "./store"; |
| | | import router from "./router"; |
| | | import directive from "./directive"; |
| | | import plugins from "./plugins"; |
| | | import { download } from "@/utils/request"; |
| | | import Print from "vue-print-nb"; |
| | | import JsonExcel from "vue-json-excel"; |
| | | import "./assets/icons"; |
| | | import "./permission"; |
| | | import { getDicts } from "@/api/system/dict/data"; |
| | | import { getConfigKey } from "@/api/system/config"; |
| | | import { |
| | | parseTime, |
| | | resetForm, |
| | | addDateRange, |
| | | selectDictLabel, |
| | | selectDictLabels, |
| | | handleTree, |
| | | } from "@/utils/ruoyi"; |
| | | import Pagination from "@/components/Pagination"; |
| | | import Editor from "@/components/Editor"; |
| | | import FileUpload from "@/components/FileUpload"; |
| | | import ImageUpload from "@/components/ImageUpload"; |
| | | import ImagePreview from "@/components/ImagePreview"; |
| | | import DictTag from "@/components/DictTag"; |
| | | import VueMeta from "vue-meta"; |
| | | import DictData from "@/components/DictData"; |
| | | import * as echarts from "echarts"; |
| | | import VueBarcode from "vue-barcode"; |
| | | |
| | | Vue.component("downloadExcel", JsonExcel); |
| | | Vue.component("barcode", VueBarcode); |
| | | Vue.component("DictTag", DictTag); |
| | | Vue.component("Pagination", Pagination); |
| | | Vue.component("Editor", Editor); |
| | | Vue.component("FileUpload", FileUpload); |
| | | Vue.component("ImageUpload", ImageUpload); |
| | | Vue.component("ImagePreview", ImagePreview); |
| | | |
| | | Vue.prototype.getDicts = getDicts; |
| | | Vue.prototype.getConfigKey = getConfigKey; |
| | | Vue.prototype.parseTime = parseTime; |
| | | Vue.prototype.resetForm = resetForm; |
| | | Vue.prototype.addDateRange = addDateRange; |
| | | Vue.prototype.selectDictLabel = selectDictLabel; |
| | | Vue.prototype.selectDictLabels = selectDictLabels; |
| | | Vue.prototype.download = download; |
| | | Vue.prototype.handleTree = handleTree; |
| | | Vue.prototype.$echarts = echarts; |
| | | |
| | | // 保留 $showNotification,支持手动触发通知 |
| | | Vue.prototype.$showNotification = function (type, title, message, onClick) { |
| | | console.log('触发通知:', { type, title, message }, new Date().toLocaleString()); |
| | | Vue.prototype.$notify({ |
| | | title, |
| | | message, |
| | | type, |
| | | duration: 5000, |
| | | position: 'top-right', |
| | | offset: 50, |
| | | onClick, |
| | | customClass: 'global-notification', |
| | | appendTo: document.body |
| | | }); |
| | | }; |
| | | |
| | | // 监听路由变化 |
| | | router.afterEach(() => { |
| | | console.log('路由切换完成,当前路径:', router.currentRoute.path); |
| | | }); |
| | | |
| | | const app = new Vue({ |
| | | el: "#app", |
| | | router, |
| | | store, |
| | | render: (h) => h(App) |
| | | }); |
| | | |
| | | Vue.use(directive); |
| | | Vue.use(plugins); |
| | | Vue.use(VueMeta); |
| | | Vue.use(Print); |
| | | Vue.use(Element, { |
| | | size: Cookies.get("size") || "medium", |
| | | }); |
| | | DictData.install(); |
| | | |
| | | Vue.config.productionTip = false; |
| | |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 新增参数配置 |
| | | export function yidu(data) { |
| | | return request({ |
| | | url: '/system/notice/readNotice ', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // 修改参数配置 |
| | | export function updateConfig(data) { |
| | | return request({ |
| | |
| | | import "./assets/icons"; |
| | | import "./permission"; |
| | | import { getDicts } from "@/api/system/dict/data"; |
| | | import { getConfigKey } from "@/api/system/config"; |
| | | import { getConfigKey, yidu } from "@/api/system/config"; |
| | | import { |
| | | parseTime, |
| | | resetForm, |
| | |
| | | import DictData from "@/components/DictData"; |
| | | import * as echarts from "echarts"; |
| | | import VueBarcode from "vue-barcode"; |
| | | import { initWebSocket, closeWebSocket } from "@/utils/websocket"; |
| | | import RightToolbar from "@/components/RightToolbar" |
| | | |
| | | // 注册全局组件 |
| | | Vue.component("downloadExcel", JsonExcel); |
| | | Vue.component("barcode", VueBarcode); |
| | | Vue.component("DictTag", DictTag); |
| | |
| | | Vue.component("FileUpload", FileUpload); |
| | | Vue.component("ImageUpload", ImageUpload); |
| | | Vue.component("ImagePreview", ImagePreview); |
| | | Vue.component("RightToolbar", RightToolbar); |
| | | |
| | | // 注册全局方法 |
| | | Vue.prototype.getDicts = getDicts; |
| | | Vue.prototype.getConfigKey = getConfigKey; |
| | | Vue.prototype.parseTime = parseTime; |
| | |
| | | Vue.prototype.handleTree = handleTree; |
| | | Vue.prototype.$echarts = echarts; |
| | | |
| | | // 保留 $showNotification,支持手动触发通知 |
| | | Vue.prototype.$showNotification = function (type, title, message, onClick) { |
| | | console.log('触发通知:', { type, title, message }, new Date().toLocaleString()); |
| | | Vue.prototype.$notify({ |
| | | title, |
| | | message, |
| | | // 通知管理:跟踪当前通知和偏移量 |
| | | const notificationManager = { |
| | | notifications: [], // 存储当前显示的通知实例 |
| | | baseOffset: 50, // 基础偏移量 |
| | | notificationHeight: 80, // 每个通知的估计高度(包括间距) |
| | | maxNotifications: 5, // 最大同时显示的通知数量 |
| | | addNotification(notification) { |
| | | if (this.notifications.length >= this.maxNotifications) { |
| | | // 关闭最早的通知 |
| | | const oldest = this.notifications.shift(); |
| | | oldest.close(); |
| | | } |
| | | this.notifications.push(notification); |
| | | // 设置动态 offset 和 z-index |
| | | notification.offset = this.baseOffset + this.notifications.length * this.notificationHeight; |
| | | notification.customClass += ` notification-${this.notifications.length}`; // 为 z-index 添加唯一类 |
| | | // 监听通知关闭 |
| | | notification.onClose = () => { |
| | | const index = this.notifications.indexOf(notification); |
| | | if (index > -1) { |
| | | this.notifications.splice(index, 1); |
| | | // 更新后续通知的 offset |
| | | this.updateOffsets(); |
| | | } |
| | | }; |
| | | }, |
| | | updateOffsets() { |
| | | this.notifications.forEach((notification, index) => { |
| | | notification.offset = this.baseOffset + (index + 1) * this.notificationHeight; |
| | | notification.customClass = notification.customClass.replace(/notification-\d+/, `notification-${index + 1}`); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // 全局通知方法,添加“已读”按钮 |
| | | Vue.prototype.$showNotification = function (type, title, message, onClick, noticeId) { |
| | | console.log('触发通知:', { type, title, message, noticeId, noticeIdType: typeof noticeId }); // 调试:记录 noticeId 和类型 |
| | | const h = this.$createElement; |
| | | const notification = this.$notify({ |
| | | title: title, |
| | | message: h('div', { class: 'notification-content' }, [ |
| | | h('div', { class: 'notification-message' }, message), |
| | | noticeId ? h('el-button', { |
| | | class: 'read-button', |
| | | style: { marginLeft: '10px', float: 'right', cursor: 'pointer' }, |
| | | props: { type: 'primary', size: 'mini' }, |
| | | on: { |
| | | click: async () => { |
| | | console.log('点击“已读”按钮,noticeId:', noticeId, 'type:', typeof noticeId); // 调试:记录点击时的 noticeId |
| | | try { |
| | | await yidu({ noticeId: String(noticeId) }); |
| | | console.log(`通知 ${noticeId} 已标记为已读`); |
| | | this.$message.success('标记为已读成功'); |
| | | notification.close(); |
| | | } catch (error) { |
| | | console.error('标记已读失败:', error, 'noticeId:', noticeId); |
| | | this.$message.error('标记已读失败'); |
| | | } |
| | | } |
| | | } |
| | | }, '已读') : null |
| | | ]), |
| | | type, |
| | | duration: 5000, |
| | | position: 'top-right', |
| | | offset: 50, |
| | | onClick, |
| | | offset: notificationManager.baseOffset, // 初始 offset |
| | | onClick: null, // 不跳转 |
| | | customClass: 'global-notification', |
| | | dangerouslyUseHTMLString: false, |
| | | appendTo: document.body |
| | | }); |
| | | notificationManager.addNotification(notification); // 添加到通知管理 |
| | | }; |
| | | |
| | | // 监听路由变化 |
| | |
| | | console.log('路由切换完成,当前路径:', router.currentRoute.path); |
| | | }); |
| | | |
| | | // 定义 WebSocket 初始化标志,防止重复连接 |
| | | let isWebSocketInitialized = false; |
| | | |
| | | const app = new Vue({ |
| | | el: "#app", |
| | | router, |
| | | store, |
| | | render: (h) => h(App) |
| | | render: (h) => h(App), |
| | | mounted() { |
| | | const token = store.state.user.token || Cookies.get('token') || ''; |
| | | if (token && !isWebSocketInitialized) { |
| | | console.log('初始化 WebSocket,Token:', token); |
| | | isWebSocketInitialized = true; |
| | | initWebSocket(token, (type, data) => { |
| | | console.log('WebSocket 收到消息:', { type, data }); // 调试:记录原始数据 |
| | | if (type === 'error') { |
| | | Vue.prototype.$showNotification.call(this, 'error', '错误', data); |
| | | return; |
| | | } |
| | | try { |
| | | if (typeof data === 'string' && data.trim().startsWith('{')) { |
| | | // 替换大整数字段,防止精度丢失 |
| | | const normalizedData = data.replace(/"(noticeId|notice_id|id)":\s*(\d+)/g, '"$1":"$2"'); |
| | | const message = JSON.parse(normalizedData); |
| | | console.log('WebSocket 解析后消息:', message); // 调试:记录解析后的消息 |
| | | if (message.noticeId || message.notice_id || message.id) { |
| | | const noticeTypeLabel = message.noticeType === '1' ? '通知' : '公告'; |
| | | const noticeTitle = message.noticeTitle ? message.noticeTitle.replace(/<[^>]+>/g, '') : '无标题'; |
| | | const contentPreview = message.noticeContent |
| | | ? message.noticeContent.replace(/<[^>]+>/g, '').substring(0, 20) + '...' |
| | | : '无内容'; |
| | | const noticeId = String(message.noticeId || message.notice_id || message.id); |
| | | console.log('准备触发通知,noticeId:', noticeId, 'type:', typeof noticeId); // 调试:记录传递的 noticeId |
| | | Vue.prototype.$showNotification.call( |
| | | this, |
| | | 'success', |
| | | `新${noticeTypeLabel}`, |
| | | `${noticeTitle} - ${contentPreview}`, |
| | | null, |
| | | noticeId |
| | | ); |
| | | } else { |
| | | console.log('未知消息类型:', message); |
| | | Vue.prototype.$showNotification.call(this, 'info', '消息', '收到未知格式的消息'); |
| | | } |
| | | } else { |
| | | console.log('WebSocket 非 JSON 消息:', data); |
| | | |
| | | } |
| | | } catch (error) { |
| | | console.error('消息解析失败:', error, '原始数据:', data); |
| | | Vue.prototype.$showNotification.call(this, 'error', '消息解析失败', `服务器回应字符串: ${data}`); |
| | | } |
| | | }); |
| | | } else if (!token) { |
| | | console.error('未找到 token,无法初始化 WebSocket'); |
| | | } else { |
| | | console.log('WebSocket 已初始化,跳过重复连接'); |
| | | } |
| | | }, |
| | | beforeDestroy() { |
| | | if (isWebSocketInitialized) { |
| | | closeWebSocket(); |
| | | isWebSocketInitialized = false; |
| | | console.log('Vue 实例销毁,WebSocket 已清理'); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // 注册插件 |
| | | Vue.use(directive); |
| | | Vue.use(plugins); |
| | | Vue.use(VueMeta); |
| | |
| | | // src/utils/websocket.js |
| | | let ws = null; |
| | | let reconnectAttempts = 0; |
| | | let pingTimer = null; // 用于管理心跳定时器 |
| | | const maxReconnectAttempts = 5; |
| | | const reconnectInterval = 5000; // 5秒重连间隔 |
| | | const pingInterval = 5000; // 5秒发送ping |
| | |
| | | return; |
| | | } |
| | | |
| | | const wsUrl = `ws://192.168.1.2:5011/ws?token=${token}`; |
| | | // 如果 ws 已存在且连接活跃,则跳过初始化 |
| | | if (ws && ws.readyState === WebSocket.OPEN) { |
| | | console.log('WebSocket 已连接,跳过重复初始化'); |
| | | return; |
| | | } |
| | | |
| | | // 如果 ws 存在但未关闭,先关闭旧连接 |
| | | if (ws) { |
| | | console.warn('发现旧 WebSocket 连接,正在关闭...'); |
| | | closeWebSocket(); |
| | | } |
| | | |
| | | const wsUrl = `ws://192.168.1.244:5011/ws?token=${token}`; |
| | | ws = new WebSocket(wsUrl); |
| | | |
| | | ws.onopen = () => { |
| | | console.log('WebSocket 连接成功'); |
| | | reconnectAttempts = 0; |
| | | reconnectAttempts = 0; // 重置重连计数 |
| | | |
| | | // 启动心跳机制 |
| | | const pingTimer = setInterval(() => { |
| | | if (ws.readyState === WebSocket.OPEN) { |
| | | console.log('发送 ping 消息'); |
| | | if (pingTimer) clearInterval(pingTimer); // 清理旧定时器 |
| | | pingTimer = setInterval(() => { |
| | | if (ws && ws.readyState === WebSocket.OPEN) { |
| | | ws.send('ping'); |
| | | } else { |
| | | console.warn('WebSocket 未连接,停止 ping'); |
| | | clearInterval(pingTimer); |
| | | pingTimer = null; |
| | | } |
| | | }, pingInterval); |
| | | }; |
| | |
| | | console.log('WebSocket 收到原始消息:', data); |
| | | if (data === 'pong') { |
| | | console.log('收到 pong 响应,连接活跃'); |
| | | reconnectAttempts = 0; // 重置重连计数,确保活跃连接不触发重连 |
| | | return; |
| | | } |
| | | onMessage('message', data); |
| | |
| | | |
| | | ws.onerror = (error) => { |
| | | console.error('WebSocket 错误:', error); |
| | | onMessage('error', 'WebSocket 连接错误'); |
| | | }; |
| | | |
| | | ws.onclose = () => { |
| | | console.warn('WebSocket 连接关闭'); |
| | | console.warn('WebSocket 连接关闭,时间:', new Date()); |
| | | if (pingTimer) { |
| | | clearInterval(pingTimer); |
| | | pingTimer = null; |
| | | } |
| | | if (reconnectAttempts < maxReconnectAttempts) { |
| | | reconnectAttempts++; |
| | | console.log(`尝试重连 (${reconnectAttempts}/${maxReconnectAttempts})...`); |
| | |
| | | |
| | | // 清理 WebSocket |
| | | window.addEventListener('beforeunload', () => { |
| | | if (ws) { |
| | | ws.close(); |
| | | ws = null; |
| | | console.log('WebSocket 已清理'); |
| | | } |
| | | }); |
| | | closeWebSocket(); |
| | | }, { once: true }); // 确保事件监听只添加一次 |
| | | } |
| | | |
| | | export function closeWebSocket() { |
| | | if (ws) { |
| | | ws.close(); |
| | | ws = null; |
| | | if (pingTimer) { |
| | | clearInterval(pingTimer); |
| | | pingTimer = null; |
| | | } |
| | | console.log('WebSocket 已关闭'); |
| | | } |
| | | } |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px" @submit.native.prevent> |
| | | <el-form |
| | | :model="queryParams" |
| | | ref="queryForm" |
| | | size="small" |
| | | :inline="true" |
| | | label-width="68px" |
| | | @submit.native.prevent |
| | | > |
| | | <el-form-item label="体检号" prop="reportDoctorCode"> |
| | | <el-input ref="inputName" v-model="queryParams.tjNum" placeholder="请输入体检号" clearable |
| | | @keyup.enter.native="handleQuery" style="width: 170px" /> |
| | | <el-input |
| | | ref="inputName" |
| | | v-model="queryParams.tjNum" |
| | | placeholder="请输入体检号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | style="width: 170px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery" style="margin-right: 15px"> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | size="mini" |
| | | @click="handleQuery" |
| | | style="margin-right: 15px" |
| | | > |
| | | 查询 |
| | | </el-button> |
| | | <el-button icon="el-icon-refresh" type="primary" size="mini" @click="resetQuery"> |
| | | <el-button |
| | | icon="el-icon-refresh" |
| | | type="primary" |
| | | size="mini" |
| | | @click="resetQuery" |
| | | > |
| | | 重置 |
| | | </el-button> |
| | | <el-button icon="el-icon-check" type="primary" size="mini" style="margin-right: 15px" @click="tongbu"> |
| | | <el-button |
| | | icon="el-icon-check" |
| | | type="primary" |
| | | size="mini" |
| | | style="margin-right: 15px" |
| | | @click="tongbu" |
| | | > |
| | | 同步 |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="box"> |
| | | <div class="table-header"> |
| | | 检验记录 |
| | | </div> |
| | | <div class="table-header">检验记录</div> |
| | | <div> |
| | | <el-table :data="exaLists" border style="width: 100%" @selection-change="handleSelectionChange" |
| | | :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }" height="350" ref="firstTable"> |
| | | <el-table |
| | | :data="exaLists" |
| | | border |
| | | style="width: 100%" |
| | | @selection-change="handleSelectionChange" |
| | | :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }" |
| | | height="350" |
| | | ref="firstTable" |
| | | > |
| | | <el-table-column fixed type="selection" align="center" label="选择" width="50" /> |
| | | <el-table-column label="姓名" align="center" prop="name" width="80" /> |
| | | <el-table-column label="性别" align="center" prop="gender" width="80" /> |
| | | <el-table-column label="年龄" align="center" prop="patientAge" width="80" /> |
| | | <el-table-column label="送检科室" align="center" prop="deptName" width="100" /> |
| | | <el-table-column label="检验项目" align="center" prop="checkParts" width="350" :show-overflow-tooltip="true" /> |
| | | <el-table-column |
| | | label="检验项目" |
| | | align="center" |
| | | prop="checkParts" |
| | | width="350" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column label="项目编号" align="center" prop="jcxmid" width="150" /> |
| | | <el-table-column label="审核医师" align="center" prop="shys" width="150" /> |
| | | <el-table-column label="报告时间" align="center" prop="examinationDate" width="150" /> |
| | |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-title"> |
| | | <h3> |
| | | 体检记录: |
| | | <span class="highlight">姓名:{{ infoList.tjCustomerName || "暂无" }}</span> |
| | | <span class="highlight">性别:{{ infoList.tjCustomerSex == 0 ? "男" : infoList.tjCustomerSex == 1 ? "女" : "暂无" }}</span> |
| | | <span class="highlight">年龄:{{ infoList.tjCustomerAge || "暂无" }}</span> |
| | | <span class="highlight">门诊号:{{ infoList.cardId || "暂无" }}</span> |
| | | </h3> |
| | | </div> |
| | | <el-table border height="350" ref="tab1" :data="checkList" v-loading="loading" style="width: 100%" |
| | | <h3> |
| | | 体检记录: |
| | | <span class="highlight">姓名:{{ infoList.tjCustomerName || "暂无" }}</span> |
| | | <span class="highlight"> |
| | | 性别: |
| | | {{ |
| | | infoList.tjCustomerSex == 0 |
| | | ? "男" |
| | | : infoList.tjCustomerSex == 1 |
| | | ? "女" |
| | | : "暂无" |
| | | }} |
| | | </span> |
| | | <span class="highlight">年龄:{{ infoList.tjCustomerAge || "暂无" }}</span> |
| | | <span class="highlight">门诊号:{{ infoList.cardId || "暂无" }}</span> |
| | | </h3> |
| | | </div> |
| | | |
| | | <el-table |
| | | border |
| | | height="350" |
| | | ref="tab1" |
| | | :data="checkList" |
| | | v-loading="loading" |
| | | style="width: 100%" |
| | | @selection-change="handleSelectionChangeSecond" |
| | | :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }"> |
| | | :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }" |
| | | > |
| | | <el-table-column type="selection" width="60" /> |
| | | <el-table-column label="状态" align="center" prop="type" :show-overflow-tooltip="true" min-width="60"> |
| | | <el-table-column |
| | | label="状态" |
| | | align="center" |
| | | prop="type" |
| | | :show-overflow-tooltip="true" |
| | | min-width="60" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.type == '0'">未检</span> |
| | | <span v-if="scope.row.type == '1'">已检</span> |
| | |
| | | </el-table> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getlisList, getJyTjList, asyncPacs } from "@/api/doctor/pacsCheck"; |
| | | import { getOrderList } from "@/api/hosp/order"; |
| | | import moment from "moment"; |
| | | |
| | | export default { |
| | | dicts: ["dict_tj_status"], |
| | | data() { |
| | | return { |
| | | isProcessing: false, // 防止死循环 |
| | | isDeselection: false, // 标记是否为取消选中 |
| | | infoList: {}, |
| | | dis: false, |
| | | code: null, |
| | | createTimeList: "", |
| | | total: 0, |
| | | loading: false, |
| | | isSyncing: false, |
| | | isFetchingRightTableData: false, |
| | | queryParams: { |
| | | name: null, |
| | | start: null, |
| | | end: null, |
| | | tjNum: null, |
| | | }, |
| | | checkStatus: "0", |
| | | exaLists: [], |
| | | selectedFirstTable: null, |
| | | selectedSecondTable: [], |
| | | form: {}, |
| | | clearTimeSet: null, |
| | | tjNumbers: "", |
| | | multipleSelection: "", |
| | | tjnum: "", |
| | | xiangmuList: [], |
| | | checkList: [], |
| | | tg: true, |
| | | bh: true, |
| | | pickerOptions: { |
| | | shortcuts: [ |
| | | { |
| | | text: "最近一周", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | { |
| | | text: "最近一个月", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | { |
| | | text: "最近三个月", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | infoList: {}, |
| | | selectedFirstTable: [], |
| | | selectedSecondTable: [], |
| | | loading: false, |
| | | isProcessingSelection: false, |
| | | }; |
| | | }, |
| | | |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.$refs.inputName.focus(); |
| | | }); |
| | | }, |
| | | |
| | | methods: { |
| | | handleDateChange(val) { |
| | | if (val && val.length === 2) { |
| | | this.queryParams.start = val[0]; |
| | | this.queryParams.end = val[1]; |
| | | } else { |
| | | this.queryParams.start = null; |
| | | this.queryParams.end = null; |
| | | } |
| | | console.log("Query Params:", this.queryParams); |
| | | }, |
| | | |
| | | tableRowClassName({ row }) { |
| | | return !row.brid ? "row-disabled" : ""; |
| | | }, |
| | | |
| | | handleSelectionChange(val) { |
| | | // 防止重复触发 |
| | | if (this.isProcessingSelection) { |
| | | console.log('正在处理选择,跳过重复触发'); |
| | | return; |
| | | } |
| | | this.isProcessingSelection = true; |
| | | |
| | | // 如果没有选中行,清空所有选择并跳过接口调用 |
| | | if (val.length === 0) { |
| | | console.log('检测到取消选中,清空所有选择'); |
| | | this.$refs.firstTable.clearSelection(); |
| | | this.selectedFirstTable = null; |
| | | this.checkList = []; |
| | | this.isDeselection = true; |
| | | this.$nextTick(() => { |
| | | this.isProcessingSelection = false; |
| | | this.$refs.firstTable.$forceUpdate(); // 强制刷新表格 |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否点击了全选按钮(val 长度等于表格总行数) |
| | | if (val.length === this.exaLists.length) { |
| | | console.log('检测到全选,选中所有行'); |
| | | this.selectedFirstTable = [...this.exaLists]; // 选中所有行 |
| | | this.$refs.firstTable.clearSelection(); |
| | | this.exaLists.forEach(row => { |
| | | if (!row.brid) { |
| | | console.warn(`名称为 ${row.name} 的行没有申请单号,跳过选择`); |
| | | return; |
| | | } |
| | | this.$refs.firstTable.toggleRowSelection(row, true, false); |
| | | }); |
| | | } else { |
| | | // 获取最新选中的行 |
| | | const latestSelectedRow = val[val.length - 1]; |
| | | |
| | | // 检查是否点击了已选中的行(取消所有选中) |
| | | const isTogglingSelectedRow = this.selectedFirstTable && this.selectedFirstTable.some(row => row.tempId === latestSelectedRow.tempId); |
| | | if (isTogglingSelectedRow) { |
| | | console.log('点击已选中行,取消所有选中'); |
| | | this.$refs.firstTable.clearSelection(); |
| | | this.selectedFirstTable = null; |
| | | this.checkList = []; |
| | | this.isDeselection = true; |
| | | this.$nextTick(() => { |
| | | this.isProcessingSelection = false; |
| | | this.$refs.firstTable.$forceUpdate(); // 强制刷新表格 |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 正常选中逻辑:根据 brid 筛选 |
| | | const filterKey = 'brid'; |
| | | const filterValue = latestSelectedRow.brid; |
| | | console.log(`按 ${filterKey} 筛选: ${filterValue}`); |
| | | |
| | | // 清空所有选中状态 |
| | | this.$refs.firstTable.clearSelection(); |
| | | |
| | | // 选中与 brid 匹配的行 |
| | | const rowsToSelect = this.exaLists.filter(row => row.brid === filterValue); |
| | | rowsToSelect.forEach(row => { |
| | | if (!row.brid) { |
| | | console.warn(`名称为 ${row.name} 的行没有申请单号,跳过选择`); |
| | | return; |
| | | } |
| | | this.$refs.firstTable.toggleRowSelection(row, true, false); |
| | | }); |
| | | |
| | | // 更新 selectedFirstTable 为 brid 匹配的行 |
| | | this.selectedFirstTable = rowsToSelect; |
| | | } |
| | | |
| | | // 调用右侧表格数据 |
| | | if (!this.isFetchingRightTableData && this.selectedFirstTable.length > 0) { |
| | | this.isFetchingRightTableData = true; |
| | | this.fetchRightTableData().finally(() => { |
| | | this.isFetchingRightTableData = false; |
| | | this.$nextTick(() => { |
| | | // 仅更新样式,不触发新事件 |
| | | this.$refs.firstTable.$forceUpdate(); |
| | | this.isProcessingSelection = false; |
| | | }); |
| | | }); |
| | | } else { |
| | | this.isProcessingSelection = false; |
| | | } |
| | | |
| | | // 重置 isDeselection 状态 |
| | | this.isDeselection = false; |
| | | }, |
| | | fetchRightTableData() { |
| | | const code = this.queryParams.tjNum; |
| | | if (!code) { |
| | | console.warn('未提供体检号,跳过 fetchRightTableData'); |
| | | this.checkList = []; |
| | | this.loading = false; |
| | | return Promise.resolve(); |
| | | } |
| | | this.loading = true; |
| | | return getJyTjList(code) |
| | | .then((response) => { |
| | | this.checkList = response.data || []; |
| | | this.loading = false; |
| | | }) |
| | | .catch((error) => { |
| | | console.error('获取 checkList 失败:', error); |
| | | this.checkList = []; |
| | | this.loading = false; |
| | | throw error; |
| | | }); |
| | | }, |
| | | |
| | | handleSelectionChangeSecond(selectedRows) { |
| | | this.selectedSecondTable = selectedRows; |
| | | if (selectedRows.length > 1) { |
| | | let del_row = selectedRows.shift(); |
| | | this.$refs.tab1.toggleRowSelection(del_row, false); |
| | | } |
| | | console.log("当前选中的行数据:", this.selectedSecondTable); |
| | | }, |
| | | |
| | | async handleQuery() { |
| | | if (!this.queryParams.tjNum) { |
| | | this.$message.error("体检号不能为空"); |
| | | return; |
| | | } |
| | | |
| | | this.loading = true; |
| | | try { |
| | | // 并行执行两个查询 |
| | | const [orderResponse, lisResponse] = await Promise.all([ |
| | | getOrderList(this.queryParams).catch((error) => { |
| | | console.error('获取 orderList 失败:', error); |
| | | return { data: { list: [] } }; // 返回空数据以继续执行 |
| | | }), |
| | | getOrderList(this.queryParams).catch(() => ({ data: { list: [] } })), |
| | | getlisList(this.queryParams), |
| | | ]); |
| | | |
| | | // 处理 getOrderList 结果 |
| | | if (orderResponse.data?.list?.length > 0) { |
| | | this.infoList = orderResponse.data.list[0]; |
| | | } else { |
| | | this.infoList = {}; |
| | | console.warn('getOrderList 返回空列表'); |
| | | } |
| | | |
| | | // 处理 getlisList 结果 |
| | | if (lisResponse.code === 200) { |
| | | this.exaLists = lisResponse.data.map((item, index) => ({ |
| | | ...item, |
| | | brid: item.brid?.trim(), // 清理空格 |
| | | mzh: item.mzh?.trim(), |
| | | tempId: index, |
| | | })); |
| | | console.log('Loaded exaLists:', this.exaLists); |
| | | |
| | | // 获取右侧表格数据 |
| | | await this.fetchRightTableData(); |
| | | } else { |
| | | this.exaLists = []; |
| | | this.$message.error(lisResponse.msg || "查询检验记录失败"); |
| | | } |
| | | } catch (error) { |
| | | console.error('查询失败:', error); |
| | | this.$message.error(error?.msg || "查询失败,请稍后重试"); |
| | | this.exaLists = []; |
| | | this.checkList = []; |
| | | this.infoList = {}; |
| | | this.infoList = orderResponse.data.list?.[0] || {}; |
| | | this.exaLists = lisResponse.data.map((item, index) => ({ |
| | | ...item, |
| | | brid: item.brid?.trim(), |
| | | tempId: index, |
| | | })); |
| | | await this.fetchRightTableData(); |
| | | } catch (e) { |
| | | console.error(e); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | |
| | | // 处理时间范围 |
| | | if (this.createTimeList) { |
| | | this.queryParams.start = this.createTimeList[0]; |
| | | this.queryParams.end = this.createTimeList[1]; |
| | | } else { |
| | | this.queryParams.start = null; |
| | | this.queryParams.end = null; |
| | | } |
| | | }, |
| | | |
| | | resetQuery() { |
| | | this.createTimeList = []; |
| | | this.resetForm("queryForm"); |
| | | this.queryParams = { |
| | | name: null, |
| | | start: null, |
| | | end: null, |
| | | tjNum: null, |
| | | }; |
| | | this.checkList = []; |
| | | this.queryParams.tjNum = null; |
| | | this.exaLists = []; |
| | | this.checkList = []; |
| | | this.infoList = {}; |
| | | }, |
| | | handleSelectionChange(selected) { |
| | | if (this.isProcessingSelection) return; |
| | | this.isProcessingSelection = true; |
| | | |
| | | handleCurrentChange(row) { |
| | | this.currentRow = row; |
| | | // 找到用户刚操作的那一条(对比之前和现在的差异) |
| | | const old = this.selectedFirstTable; |
| | | let changedRow = null; |
| | | |
| | | if (selected.length > old.length) { |
| | | // 新增:找出新增的 |
| | | changedRow = selected.find(row => !old.includes(row)); |
| | | } else { |
| | | // 删除:找出删除的 |
| | | changedRow = old.find(row => !selected.includes(row)); |
| | | } |
| | | |
| | | if (changedRow) { |
| | | const group = this.exaLists.filter(r => r.brid === changedRow.brid); |
| | | const isAdding = selected.length > old.length; |
| | | |
| | | this.$refs.firstTable.clearSelection(); |
| | | if (isAdding) { |
| | | // 添加,整个组选上 + 原有选的 brid 也选上 |
| | | const allBrids = new Set(); |
| | | selected.forEach(row => allBrids.add(row.brid)); |
| | | allBrids.add(changedRow.brid); |
| | | const newSelection = this.exaLists.filter(row => allBrids.has(row.brid)); |
| | | newSelection.forEach(row => { |
| | | this.$refs.firstTable.toggleRowSelection(row, true); |
| | | }); |
| | | this.selectedFirstTable = newSelection; |
| | | } else { |
| | | // 删除,整个组取消,再把剩下 brid 分组补回去 |
| | | const remaining = old.filter(row => row.brid !== changedRow.brid); |
| | | const remainBrids = [...new Set(remaining.map(r => r.brid))]; |
| | | const newSelection = this.exaLists.filter(row => remainBrids.includes(row.brid)); |
| | | newSelection.forEach(row => { |
| | | this.$refs.firstTable.toggleRowSelection(row, true); |
| | | }); |
| | | this.selectedFirstTable = newSelection; |
| | | } |
| | | } else { |
| | | this.selectedFirstTable = selected; |
| | | } |
| | | |
| | | this.fetchRightTableData(); |
| | | this.isProcessingSelection = false; |
| | | }, |
| | | |
| | | |
| | | handleSelectionChangeSecond(selected) { |
| | | this.selectedSecondTable = selected.slice(0, 1); |
| | | }, |
| | | |
| | | setTime() { |
| | | this.clearTimeSet = setInterval(() => { |
| | | this.$modal.closeLoading(); |
| | | }, 300000); |
| | | fetchRightTableData() { |
| | | if (!this.queryParams.tjNum) return; |
| | | this.loading = true; |
| | | return getJyTjList(this.queryParams.tjNum) |
| | | .then(res => { |
| | | this.checkList = res.data || []; |
| | | }) |
| | | .finally(() => { |
| | | this.loading = false; |
| | | }); |
| | | }, |
| | | |
| | | tongbu() { |
| | | this.$modal.loading("正在同步,请稍候..."); |
| | | this.setTime(); |
| | | const requestData = { |
| | | lis: this.selectedFirstTable ? this.selectedFirstTable.map((item) => ({ |
| | | ...item, |
| | | tjNum: this.queryParams.tjNum, |
| | | })) : [], |
| | | jcxmid: this.selectedFirstTable && this.selectedFirstTable.length > 0 ? this.selectedFirstTable[0].jcxmid : null, |
| | | shys: this.selectedFirstTable && this.selectedFirstTable.length > 0 ? this.selectedFirstTable[0].shys : null, |
| | | lis: this.selectedFirstTable, |
| | | tj: this.selectedSecondTable[0], |
| | | }; |
| | | asyncPacs(requestData) |
| | | .then((res) => { |
| | | if (res.code === 200) { |
| | | this.fetchRightTableData(); |
| | | clearInterval(this.clearTimeSet); |
| | | this.clearTimeSet = null; |
| | | this.$modal.closeLoading(); |
| | | this.$modal.msgSuccess("同步成功!"); |
| | | } else { |
| | | this.$message.error(res.message || "同步失败,请稍后重试"); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | clearInterval(this.clearTimeSet); |
| | | this.clearTimeSet = null; |
| | | this.$modal.closeLoading(); |
| | | }); |
| | | asyncPacs(requestData).then(res => { |
| | | if (res.code === 200) { |
| | | this.$message.success("同步成功!"); |
| | | this.fetchRightTableData(); |
| | | } else { |
| | | this.$message.error(res.message || "同步失败"); |
| | | } |
| | | }); |
| | | }, |
| | | }, |
| | | };</script> |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | background: #f5f7fa; |
| | | } |
| | | |
| | | .table-header { |
| | | text-align: center; |
| | | background-color: #aad8df; |
| | |
| | | margin-top: 10px; |
| | | border-radius: 4px 4px 0 0; |
| | | } |
| | | |
| | | .table-title { |
| | | text-align: left; |
| | | margin: 20px 0; |
| | | padding: 10px 0; |
| | | } |
| | | |
| | | .table-title h3 { |
| | | font-size: 16px; |
| | | color: #333; |
| | |
| | | flex-wrap: wrap; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .table-title .highlight { |
| | | font-weight: bold; |
| | | color: #2c3e50; |
| | | } |
| | | |
| | | .el-table { |
| | | border-radius: 4px; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .el-table .warning-row { |
| | | background: #e5f3ff !important; |
| | | } |
| | | |
| | | ::v-deep .el-table__body tr.current-row > td { |
| | | background: #edf2fa !important; |
| | | } |
| | | |
| | | .row-disabled { |
| | | color: #999; |
| | | background-color: #f5f5f5; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="app-container" v-loading="pageLoading"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="4" :xs="24"> |
| | | <div class="head-container"> |
| | |
| | | style="margin-bottom: 15px" |
| | | /> |
| | | </div> |
| | | <div class="scrollable-container"> |
| | | <div class="scrollable-container" v-loading="loadings"> |
| | | <div class="content"> |
| | | <el-tree |
| | | :data="deptOptions" |
| | |
| | | highlight-current |
| | | @node-click="handleNodeClick" |
| | | :render-content="renderContent" |
| | | v-loading="loadings" |
| | | /> |
| | | </div> |
| | | </div> |
| | |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleUpdate1" |
| | | :loading="updateLoading" |
| | | v-hasPermi="['hosp:project:add']" |
| | | >修改</el-button |
| | | > |
| | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | style="width: 100%" |
| | | :data="projectList" |
| | | ref="tableRef" |
| | | height="580" |
| | |
| | | width="1200px" |
| | | append-to-body |
| | | :before-close="handleClose" |
| | | v-loading="loading" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-form |
| | |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="是否外送" prop="proDelivery"> |
| | | <el-select v-model="form.proDelivery" placeholder="请选择是否外送" style="width: 200px"> |
| | | <el-option v-for="dict in wsTypesy" :key="dict.value" :label="dict.label" |
| | | :value="dict.value"></el-option> |
| | | <el-form-item label="是否外送" prop="proDelivery"> |
| | | <el-select |
| | | v-model="form.proDelivery" |
| | | placeholder="请选择是否外送" |
| | | style="width: 200px" |
| | | > |
| | | <el-option |
| | | v-for="dict in wsTypesy" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | deptOptions: [], |
| | | dialogTableVisible: false, |
| | | isPriceDisabled: false, |
| | | pageLoading: true, |
| | | sfxmList: [], |
| | | deptOptionstree: [], |
| | | defaultPropstree: { |
| | |
| | | label: "否", |
| | | }, |
| | | ], |
| | | wsTypesy: [ |
| | | wsTypesy: [ |
| | | { |
| | | value:"1", |
| | | label:"是" |
| | | value: "1", |
| | | label: "是", |
| | | }, |
| | | { |
| | | value:"0", |
| | | label:"否" |
| | | } |
| | | value: "0", |
| | | label: "否", |
| | | }, |
| | | ], |
| | | xmmc: "", |
| | | chargeId: [], |
| | |
| | | ChangeList: [], |
| | | loading: true, |
| | | loadings: false, |
| | | addLoading: false, |
| | | updateLoading: false, |
| | | key: "", |
| | | ids: [], |
| | | single: true, |
| | |
| | | this.$nextTick(() => { |
| | | const lastId = newVal[newVal.length - 1] || "532"; |
| | | const node = this.findNodeById(this.deptOptions, lastId); |
| | | this.queryParams.proId = lastId |
| | | this.getList() |
| | | if (node) { |
| | | this.$refs.tree1.setCurrentKey(lastId); |
| | | const nodeElement = document.querySelector( |
| | |
| | | }, |
| | | }, |
| | | created() { |
| | | this.getConsumables(); |
| | | this.getDeptList(); |
| | | // this.getConsumables(); |
| | | // this.getDeptList(); |
| | | // this.getDeptTree().then(() => { |
| | | // this.precomputePinyin(); |
| | | // }); |
| | | }, |
| | | mounted() { |
| | | this.getDeptTree().then(() => { |
| | | this.precomputePinyin(); |
| | | }); |
| | | // this.getDeptTree().then(() => { |
| | | // this.precomputePinyin(); |
| | | // }); |
| | | // this.precomputePinyin(); |
| | | this.loadPage(); |
| | | }, |
| | | methods: { |
| | | debounceFilter: debounce(function (val) { |
| | |
| | | }; |
| | | traverse(this.deptOptions); |
| | | }, |
| | | |
| | | async loadPage() { |
| | | this.pageLoading = true; |
| | | try { |
| | | await Promise.all([ |
| | | this.getDeptTree(), // 获取左侧树 |
| | | //this.getList(), 获取右侧表格 |
| | | ]); |
| | | } catch (error) { |
| | | console.error("加载页面出错", error); |
| | | } finally { |
| | | this.pageLoading = false; // 两个都加载完再关闭 loading |
| | | } |
| | | }, |
| | | |
| | | async getDeptTree() { |
| | | this.loadings = true; |
| | | try { |
| | | const response = await deptTree111(); |
| | | this.deptOptions = response.data; |
| | | |
| | | // 保证 treeId 是数组格式 |
| | | this.treeId = []; |
| | | |
| | | if (this.treeDate?.id) { |
| | | this.treeId.push(this.treeDate.id); |
| | | |
| | | } else { |
| | | this.treeId.push("532"); |
| | | } |
| | | } catch (error) { |
| | | console.error("加载部门树失败:", error); |
| | | } finally { |
| | | this.loadings = false; // loading 状态结束 |
| | | } |
| | | }, |
| | | |
| | | async getList() { |
| | | this.loading = true; |
| | | let data = { |
| | | proName: this.queryParams.proName, |
| | | checkType: this.queryParams.checkType, |
| | | deptId: this.queryParams.deptId, |
| | | proId: this.queryParams.proId, |
| | | }; |
| | | try { |
| | | const res = await getAllChildListById(data); // 替换成你实际的接口 |
| | | this.projectList = res.data.list; |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | filterNode(value, data) { |
| | | if (!value) return true; |
| | | const cached = this.pinyinCache.get(data.id); |
| | |
| | | }); |
| | | }, |
| | | getDeptTree() { |
| | | return deptTree111().then((response) => { |
| | | this.deptOptions = response.data; |
| | | this.treeId = []; |
| | | if (this.treeDate.id) { |
| | | this.treeId.push(this.treeDate.id); |
| | | } else { |
| | | this.treeId.push("532"); |
| | | } |
| | | }); |
| | | this.loadings = true; |
| | | return deptTree111() |
| | | .then((response) => { |
| | | this.deptOptions = response.data; |
| | | this.treeId = []; |
| | | if (this.treeDate.id) { |
| | | this.treeId.push(this.treeDate.id); |
| | | } else { |
| | | this.treeId.push("532"); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error("加载部门树失败:", err); |
| | | }) |
| | | .finally(() => { |
| | | this.loadings = false; // 无论成功或失败,结束加载 |
| | | }); |
| | | }, |
| | | handleNodeClick(date) { |
| | | this.treeDate = date; |
| | |
| | | } |
| | | }, |
| | | handleUpdate1() { |
| | | this.updateLoading = true; |
| | | this.form = {}; |
| | | this.form = this.xiugaiList; |
| | | this.form.proStatus = this.form.proStatus.toString(); |
| | | this.form.sfcyyc = this.form.sfcyyc.toString(); |
| | | this.proParent = true; |
| | | this.isPriceDisabled = true; |
| | | getlist().then((response) => { |
| | | if (response.code == 200) { |
| | | this.loading = false; |
| | | this.projectOptions = []; |
| | | const project = { proId: 0, proName: "主类目", children: [] }; |
| | | project.children = this.handleTree(response.data.list, "proId"); |
| | | this.key = response.data.key; |
| | | this.projectOptions.push(project); |
| | | } |
| | | }); |
| | | getlist() |
| | | .then((response) => { |
| | | if (response.code == 200) { |
| | | this.loading = false; |
| | | this.projectOptions = []; |
| | | const project = { proId: 0, proName: "主类目", children: [] }; |
| | | project.children = this.handleTree(response.data.list, "proId"); |
| | | this.key = response.data.key; |
| | | this.projectOptions.push(project); |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | this.updateLoading = false; |
| | | }); |
| | | this.open = true; |
| | | }, |
| | | handleUpdate(row) { |
| | |
| | | }[item.tjType] || item.tjType; |
| | | }); |
| | | } |
| | | getlist().then((response) => { |
| | | getlist().then((response) => { |
| | | if (response.code == 200) { |
| | | this.loading = false; |
| | | // this.loading = false; |
| | | this.projectOptions = []; |
| | | const project = { proId: 0, proName: "主类目", children: [] }; |
| | | project.children = this.handleTree(response.data.list, "proId"); |
| | |
| | | this.projectOptions.push(project); |
| | | } |
| | | }); |
| | | // this.loadPage(); |
| | | this.open = true; |
| | | this.title = "体检项目信息维护"; |
| | | }); |
| | |
| | | }, |
| | | submitForm() { |
| | | this.noclick = true; |
| | | this.pageLoading = true; |
| | | this.$refs["form"].validate((valid) => { |
| | | if (valid) { |
| | | const isUpdate = this.form.proId != null; |
| | |
| | | this.form.lisXmbm = this.form.lisXmbm; |
| | | if (this.key === "N") { |
| | | this.processSubmission(isUpdate, false); |
| | | this.open = false; |
| | | // this.pageLoading = false; |
| | | } else if (this.key === "Y") { |
| | | this.form.sfxmId = this.sfxmId; |
| | | this.processSubmission(isUpdate, true); |
| | | this.open = false; |
| | | // this.pageLoading = false; |
| | | } |
| | | } |
| | | }); |
| | |
| | | } |
| | | } |
| | | }, |
| | | handleSuccess(isY) { |
| | | /* handleSuccess(isY) { |
| | | this.cancel(); |
| | | this.getList(); |
| | | // this.getList(); |
| | | if (this.proParent || isY) { |
| | | this.getDeptTree().then(() => { |
| | | this.precomputePinyin(); |
| | | }); |
| | | } |
| | | console.log(this.treeId); |
| | | }, |
| | | }, */ |
| | | async handleSuccess(isY) { |
| | | this.cancel(); |
| | | |
| | | if (this.proParent || isY) { |
| | | // 等待左侧树加载和拼音处理 |
| | | await this.getDeptTree(); |
| | | this.precomputePinyin(); |
| | | } |
| | | |
| | | // 等待右侧表格刷新 |
| | | await this.getList(); |
| | | |
| | | this.pageLoading = false; // ✅ 统一加载状态控制 |
| | | }, |
| | | submit() { |
| | | this.ChangeList.forEach((item) => { |
| | | this.form.proPrice = item.ckdj; |
| | |
| | | style="width: 160px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="单位名称" prop="company"> |
| | | <el-form-item label="单位名称" prop="companyId"> |
| | | <el-select |
| | | :remote-method="getRemoteData" |
| | | v-model="formIn.company" |
| | | v-model="formIn.companyId" |
| | | remote |
| | | default-first-option |
| | | allow-create |
| | |
| | | cusSex: null, |
| | | cusBrithday: null, |
| | | cusAddr: null, |
| | | cusPhone: null, |
| | | phone: null, |
| | | yykssj: "", // 预约开始时间 |
| | | yyjssj: "", // 预约结束时间 |
| | | cusPostcode: null, |
| | |
| | | // cusAddr: [ |
| | | // { required: true, message: "现居住地址不能为空", trigger: "blur" }, |
| | | // ], |
| | | cusPhone: [ |
| | | phone: [ |
| | | { required: true, validator: checkPhoneNum, trigger: "blur" }, |
| | | ], |
| | | reservationTime: [ |
| | |
| | | cusSex: null, |
| | | cusBrithday: null, |
| | | cusAddr: null, |
| | | cusPhone: null, |
| | | phone: null, |
| | | yykssj: "", // 预约开始时间 |
| | | yyjssj: "", // 预约结束时间 |
| | | cusPostcode: null, |
| | |
| | | name: this.formIn.name, |
| | | nation: this.formIn.nation, |
| | | pacId, |
| | | phoe: this.formIn.cusPhone, |
| | | phoe: this.formIn.phoe, |
| | | reservationTime: this.formIn.reservationTime, |
| | | sex: this.formIn.sex, |
| | | timeRegion: this.formIn.timeRegion, |
| | |
| | | }; |
| | | } |
| | | tjReappoint(data).then((res) => { |
| | | console.log("接口响应", res); |
| | | if (res.code === 200) { |
| | | this.$modal.msgSuccess("预约成功"); |
| | | Object.assign(this.formIn, data); |
| | | this.getList(); |
| | | this.$tab.refreshPage(); |
| | | _this.drawer = false; |
| | |
| | | [process.env.VUE_APP_BASE_API]: { |
| | | // target: `https://ltpeis.xaltjdkj.cn:5801/`, |
| | | // target: `http://192.168.1.99:5012`, |
| | | target: `http://192.168.1.113:5011`, |
| | | // target: `http://192.168.1.244:5011`, |
| | | // target: `http://192.168.1.113:5011`, |
| | | target: `http://192.168.1.244:5011`, |
| | | // // target: `http://192.168.0.99:8080/ltkj-admin`, |
| | | // target: `https://ltpeis.xaltjdkj.cn:5011/ltkj-admin`, |
| | | // target: `http://10.168.0.9:5011`, |