liudan 2 місяців тому
батько
коміт
1cf892fa2b
3 змінених файлів з 278 додано та 6 видалено
  1. BIN
      dist.zip
  2. 0 1
      src/config/https.js
  3. 278 5
      src/pages/staticPages/patientHistory/patientHistory.vue

+ 0 - 1
src/config/https.js

@@ -34,7 +34,6 @@ export const $http = {
     } else {
       session.push({});
     }
-    console.log(isStaticPage(), '11111');
     if (noSessionCode.indexOf(formData.code) < 0 && !isLogin && !isStaticPage()) {
       // 单点登录进行中时,不跳登录页,等待 SSO 完成后页面会自动刷新
       let ssoPending = false;

+ 278 - 5
src/pages/staticPages/patientHistory/patientHistory.vue

@@ -84,12 +84,12 @@
                 <view class="timeline-item" v-for="(node, index) in timeline" :key="node.key || index">
                     <view class="timeline-dot"></view>
                     <view class="timeline-line" v-if="index !== timeline.length - 1"></view>
-                    <view class="timeline-content">
+                    <view class="timeline-content" @tap="openPage(node)">
                         <view class="timeline-title-row">
-                            <text class="timeline-title">{{ node.desc }}</text>
+                            <text :class="node.desc.indexOf('病历') > -1 ? 'timeline-title blue' : 'timeline-title'">{{ node.desc }}</text>
                             <text class="timeline-time">{{ node.datetime }}</text>
                         </view>
-                        <view class="timeline-tags" v-if="node.oper && node.oper !== '用户152'">
+                        <view class="timeline-tags" v-if="node.oper && node.oper.indexOf('用户') < 0">
                             <text class="timeline-tag">{{ node.oper}}</text>
                         </view>
                     </view>
@@ -255,11 +255,62 @@
                 </view>
             </view>
         </scroll-view>
+
+        <!-- 信息采集单(只读查看,复用 medicalRecord 的信息采集单模块) -->
+        <view class="info-form-mask" v-if="infoFormVisible" @tap="closeInfoForm">
+            <view class="info-form-panel" @tap.stop>
+                <view class="info-form-header">
+                    <text class="info-form-title">门诊病历</text>
+                    <text class="info-form-close" @tap="closeInfoForm">关闭</text>
+                </view>
+                <scroll-view class="info-form-body" scroll-y>
+                    <view class="ph-info-collection" v-if="formData.length > 0">
+                        <view class="ph-info-item" v-for="(item, index) in formData" :key="index">
+                            <view class="ph-info-label">{{ item.label }}</view>
+                            <!-- 图片类型:只读展示 -->
+                            <view v-if="item.type === 'casepluginimage'" class="ph-info-image-box">
+                                <block v-if="getImageList(item.key).length > 0">
+                                    <view class="ph-info-image-item" v-for="(imgUrl, imgIdx) in getImageList(item.key)" :key="imgIdx">
+                                        <image
+                                            class="ph-info-image"
+                                            :src="urlImage(imgUrl)"
+                                            mode="aspectFill"
+                                            @error="onImageError(item.key, imgIdx)"
+                                            @tap="previewImage(item.key, imgIdx)"
+                                        />
+                                    </view>
+                                </block>
+                                <view v-else class="ph-info-image-empty">暂无图片</view>
+                            </view>
+                            <!-- 下拉/单选等带选项类型:只读展示 label -->
+                            <view
+                                v-else-if="item.type === 'select' || item.type === 'radio' || item.type === 'checkbox'"
+                                class="ph-info-value"
+                                :class="{ 'ph-info-placeholder': !getDisplayValue(item) }"
+                            >
+                                {{ getDisplayValue(item) || '暂无' }}
+                            </view>
+                            <!-- 其他类型(input/date/textarea 等):只读值 -->
+                            <view v-else class="ph-info-value" :class="{ 'ph-info-placeholder': !getDisplayValue(item) }">
+                                {{ getDisplayValue(item) || '暂无' }}
+                            </view>
+                        </view>
+                    </view>
+                    <view class="ph-placeholder-box" v-if="infoFormLoading">
+                        <text class="ph-placeholder-text">加载中...</text>
+                    </view>
+                    <view class="ph-placeholder-box" v-if="!infoFormLoading && formData.length === 0">
+                        <text class="ph-placeholder-text">暂无信息采集数据</text>
+                    </view>
+                </scroll-view>
+            </view>
+        </view>
     </view>
 </template>
 
 <script>
 import { $http } from '../../../config/https.js';
+import httpConfig from '../../../config/httpConfig.js';
 
 export default {
     data() {
@@ -287,7 +338,15 @@ export default {
             // 药品信息
             drug: [],
             // 其他医嘱
-            otherOrder: []
+            otherOrder: [],
+            // 信息采集单(只读查看)
+            infoFormVisible: false,
+            infoFormLoading: false,
+            formData: [],
+            dataKeyObj: {},
+            formDataSource: {},
+            imageLoadError: {},
+            TempHtmlStr: ''
         };
     },
     onLoad(options) {
@@ -366,6 +425,114 @@ export default {
                 urls: urls.length ? urls : [item.picture]
             });
         },
+        openPage(node) {
+            if (node.desc && node.desc.indexOf('病历') > -1) {
+                // 打开信息采集单(只读查看,不修改不保存)
+                this.loadInfoForm(node.recordID);
+            }
+        },
+        // 关闭信息采集单弹窗
+        closeInfoForm() {
+            this.infoFormVisible = false;
+        },
+        // 加载信息采集单:拉取模板 + 历史详情回显
+        loadInfoForm(recordID) {
+            if (!recordID) return;
+            this.infoFormVisible = true;
+            this.infoFormLoading = true;
+            this.formData = [];
+            this.dataKeyObj = {};
+            this.formDataSource = {};
+            this.imageLoadError = {};
+            // 1. 获取模板信息(含 templateHtmlUrl,用于确认模板存在)
+            $http.post('', this, {
+                code: '06010115',
+                data: { params: [{ admID: this.admID }] },
+                success: (res) => {
+                    let result = res.result || {};
+                    this.TempHtmlStr = result.templateHtmlUrl || '';
+                    if (!this.TempHtmlStr) {
+                        this.infoFormLoading = false;
+                        uni.showToast({ title: '未获取到信息采集单模板', icon: 'none' });
+                    }
+                }
+            });
+            // 2. 拉取历史病历详情(用于回显)
+            $http.post('', this, {
+                code: '06010117',
+                data: {
+                    emrCode: '18060011',
+                    params: [{
+                        recordID: recordID
+                    }]
+                },
+                success: (res) => {
+                    let result = res.result || res.data || {};
+                    let list = result.data || result.recordDetail || [];
+                    // 构建 formData(标签/类型/key)与 formDataSource(值)
+                    let formList = [];
+                    let sourceMap = {};
+                    (list || []).forEach((item) => {
+                        let key = item.uniqueCode || item.metaDataCode || '';
+                        let type = item.filedType || 'input';
+                        if (type === 'image') type = 'casepluginimage';
+                        if (!key) return;
+                        formList.push({ key: key, label: item.uniqueName || item.metaDataDesc || key, type: type });
+                        sourceMap[key] = item.filedText !== undefined ? item.filedText : '';
+                    });
+                    this.formData = formList;
+                    this.formDataSource = sourceMap;
+                    this.infoFormLoading = false;
+                },
+                fail: () => {
+                    this.infoFormLoading = false;
+                }
+            });
+        },
+        // 拼接图片地址
+        urlImage(val) {
+            if (!val) return '';
+            if (val.indexOf('http') === 0 || val.indexOf('//') === 0) return val;
+            let base = httpConfig.urlAddress || '';
+            return base + (val.indexOf('/') === 0 ? val : '/' + val);
+        },
+        // 获取某字段的图片地址数组
+        getImageList(key) {
+            let val = this.formDataSource[key];
+            if (!val) return [];
+            let arr = [];
+            if (typeof val === 'string') {
+                arr = val.split(',').filter((s) => s && s.trim());
+            } else if (Array.isArray(val)) {
+                arr = val;
+            } else {
+                arr = [val];
+            }
+            let errs = this.imageLoadError[key] || [];
+            return arr.map((s, idx) => (errs.indexOf(idx) > -1 ? '' : s)).filter(Boolean);
+        },
+        onImageError(key, idx) {
+            if (!this.imageLoadError[key]) {
+                this.$set(this.imageLoadError, key, []);
+            }
+            this.imageLoadError[key].push(idx);
+        },
+        previewImage(key, idx) {
+            const urls = this.getImageList(key);
+            if (!urls.length) return;
+            uni.previewImage({ current: urls[idx], urls: urls });
+        },
+        // 计算只读展示值
+        getDisplayValue(item) {
+            if (!item) return '';
+            let val = this.formDataSource[item.key];
+            if (val === undefined || val === null || val === '') return '';
+            if (item.type === 'casepluginimage') {
+                return this.getImageList(item.key).length > 0 ? '图片' : '';
+            }
+            // 接口已返回中文文本(filedText),直接展示
+            return val;
+        },
         // 语音播放
         playAudio(e) {
             const item = e.currentTarget.dataset.page;
@@ -454,7 +621,8 @@ export default {
                     // 历程时间线(result.data)
                     if (Array.isArray(result.data)) {
                         that.timeline = result.data.map((n) => ({
-                            key: n.key,
+                            key: n.index,
+                            recordID: n.key,
                             desc: n.desc || '',
                             datetime: n.datetime || '',
                             oper: n.oper || ''
@@ -822,6 +990,10 @@ export default {
     font-weight: 600;
     color: #1f2329;
 }
+.timeline-title.blue{
+    color: #2B84FF;
+    font-weight: 700;
+}
 
 .timeline-time {
     font-size: 24rpx;
@@ -1268,4 +1440,105 @@ export default {
     font-size: 24rpx;
     color: #4a5160;
 }
+
+/* 信息采集单弹窗(只读查看) */
+.info-form-mask {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background: rgba(0, 0, 0, 0.5);
+    z-index: 999;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+.info-form-panel {
+    width: 86%;
+    max-height: 80vh;
+    background: #ffffff;
+    border-radius: 20rpx;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+}
+.info-form-header {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+    padding: 28rpx 32rpx;
+    border-bottom: 1rpx solid #eef0f4;
+}
+.info-form-title {
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #222;
+}
+.info-form-close {
+    font-size: 28rpx;
+    color: #4f7cff;
+}
+.info-form-body {
+    padding: 24rpx 32rpx 40rpx;
+    max-height: 64vh;
+}
+.ph-info-collection {
+    display: flex;
+    flex-direction: column;
+}
+.ph-info-item {
+    display: flex;
+    flex-direction: row;
+    padding: 20rpx 0;
+    border-bottom: 1rpx solid #f2f3f6;
+}
+.ph-info-label {
+    width: 220rpx;
+    flex-shrink: 0;
+    font-size: 28rpx;
+    color: #8a909c;
+}
+.ph-info-value {
+    flex: 1;
+    font-size: 28rpx;
+    color: #222;
+    word-break: break-all;
+}
+.ph-info-placeholder {
+    color: #b6bac2;
+}
+.ph-info-image-box {
+    flex: 1;
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    gap: 16rpx;
+}
+.ph-info-image-item {
+    width: 160rpx;
+    height: 160rpx;
+    border-radius: 12rpx;
+    overflow: hidden;
+    background: #f2f3f6;
+}
+.ph-info-image {
+    width: 160rpx;
+    height: 160rpx;
+}
+.ph-info-image-empty {
+    font-size: 28rpx;
+    color: #b6bac2;
+}
+.ph-placeholder-box {
+    padding: 80rpx 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+.ph-placeholder-text {
+    font-size: 28rpx;
+    color: #b6bac2;
+}
 </style>