vue2-client 1.12.71 → 1.12.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,7 @@
25
25
  </template>
26
26
  <template v-else-if="cell.type === 'slot'">
27
27
  <template
28
- v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse','x-h-descriptions', 'x-sidebar', 'x-list','x-input'].includes(cell.slotType)">
28
+ v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse','x-h-descriptions', 'x-sidebar', 'x-list','x-input','x-time-line'].includes(cell.slotType)">
29
29
  <component
30
30
  :is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
31
31
  :key="cellIndex"
@@ -60,7 +60,7 @@
60
60
  </template>
61
61
  <template v-else-if="cell.type === 'slot'">
62
62
  <template
63
- v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse', 'x-h-descriptions', 'x-sidebar', 'x-list','x-input'].includes(cell.slotType)">
63
+ v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse', 'x-h-descriptions', 'x-sidebar', 'x-list','x-input','x-time-line'].includes(cell.slotType)">
64
64
  <component
65
65
  :is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
66
66
  :key="cellIndex"
@@ -110,6 +110,7 @@ export default {
110
110
  XSidebar: () => import('@vue2-client/base-client/components/his/XSidebar/XSidebar.vue'),
111
111
  XList: () => import('@vue2-client/base-client/components/his/XList/XList.vue'),
112
112
  XInput: () => import('@vue2-client/base-client/components/common/XInput/XInput.vue'),
113
+ XTimeline: () => import('@vue2-client/base-client/components/common/XTimeline/XTimeline.vue'),
113
114
  },
114
115
  props: {
115
116
  // 每一行的配置
@@ -0,0 +1,342 @@
1
+ <template>
2
+ <!-- 时间轴主容器 -->
3
+ <div class='x-timeline'>
4
+ <!-- 时间轴导航栏 -->
5
+ <div class='x-timeline-nav'>
6
+ <!-- 导航按钮:前一周、前一天 -->
7
+ <a-button type="link" @click='goToPrevWeek'>
8
+ <a-icon type="double-left" />
9
+ {{ config?.prevWeekText || '前一周' }}
10
+ </a-button>
11
+ <a-button type="link" @click='goToPrevDay'>
12
+ <a-icon type="left" />
13
+ {{ config?.prevDayText || '前一天' }}
14
+ </a-button>
15
+ <!-- 日期显示区域 -->
16
+ <div class='timeline-dates'>
17
+ <div v-for='(date, index) in displayDates'
18
+ :key='index'
19
+ class='date-item'
20
+ :class='{
21
+ "ant-btn-primary": isCurrentDate(date),
22
+ "date-weekend": isWeekend(date),
23
+ "ant-btn-disabled": isDisabled(date)
24
+ }'
25
+ @click='selectDate(date)'
26
+ >
27
+ <div class='weekday'>{{ getWeekDay(date) }}</div>
28
+ <div class='date'>{{ formatDate(date) }}</div>
29
+ </div>
30
+ </div>
31
+ <!-- 导航按钮:后一天、后一周 -->
32
+ <a-button type="link" @click='goToNextDay'>
33
+ {{ config?.nextDayText || '后一天' }}
34
+ <a-icon type="right" />
35
+ </a-button>
36
+ <a-button type="link" @click='goToNextWeek'>
37
+ {{ config?.nextWeekText || '后一周' }}
38
+ <a-icon type="double-right" />
39
+ </a-button>
40
+ </div>
41
+ </div>
42
+ </template>
43
+
44
+ <script>
45
+ import dayjs from 'dayjs'
46
+ import 'dayjs/locale/zh-cn'
47
+ import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
48
+
49
+ // 设置 dayjs 为中文语言环境
50
+ dayjs.locale('zh-cn')
51
+
52
+ export default ({
53
+ name: 'XTimeline',
54
+ components: {
55
+ },
56
+ props: {
57
+ // 当前选中日期,默认为空(不选中)
58
+ modelValue: {
59
+ type: String,
60
+ default: ''
61
+ },
62
+ // 配置参数名称,用于获取时间轴配置
63
+ queryParamsName: {
64
+ type: String,
65
+ default: 'XTimelineExampleConfig'
66
+ }
67
+ },
68
+
69
+ // 定义组件事件
70
+ emits: ['update:modelValue', 'change', 'prev-week', 'next-week', 'prev-day', 'next-day'],
71
+
72
+ data () {
73
+ return {
74
+ currentDate: this.modelValue, // 当前选中日期
75
+ baseDate: dayjs().format('YYYY-MM-DD'), // 基准日期,默认今天,用于计算显示范围
76
+ config: null, // 时间轴配置
77
+ disabledDates: [] // 禁用日期列表
78
+ }
79
+ },
80
+ computed: {
81
+ // 计算需要显示的日期范围
82
+ displayDates () {
83
+ const dates = []
84
+ const range = this.config?.range || 7 // 显示天数,默认7天
85
+ const halfRange = Math.floor(range / 2)
86
+ let currentDate = dayjs(this.baseDate).subtract(halfRange, 'day')
87
+ for (let i = 0; i < range; i++) {
88
+ dates.push(currentDate.format('YYYY-MM-DD'))
89
+ currentDate = currentDate.add(1, 'day')
90
+ }
91
+ return dates
92
+ }
93
+ },
94
+
95
+ watch: {
96
+ // 监听外部传入的选中日期变化
97
+ modelValue: {
98
+ handler (newVal) {
99
+ this.currentDate = newVal
100
+ if (newVal) {
101
+ this.baseDate = newVal
102
+ }
103
+ },
104
+ immediate: true
105
+ },
106
+ // 监听配置参数名称变化
107
+ queryParamsName: {
108
+ handler (newValue) {
109
+ this.getData(newValue)
110
+ },
111
+ immediate: true
112
+ }
113
+ },
114
+
115
+ created () {
116
+ // 组件创建时获取配置
117
+ this.getData(this.queryParamsName)
118
+ },
119
+
120
+ methods: {
121
+ // 获取时间轴配置数据
122
+ async getData (data) {
123
+ getConfigByName(data, 'af-his', res => {
124
+ // var res = {
125
+ // // 基础配置
126
+ // range: 7, // 显示的天数范围,默认7天
127
+ // defaultValue: '', // 默认选中日期,不设置则默认今天
128
+ // // 日期格式化
129
+ // dateFormat: 'MM/DD', // 日期显示格式,如 03/21
130
+ // weekFormat: '周dd', // 星期显示格式,如 周四
131
+ // // 按钮文字配置
132
+ // prevWeekText: '前一周', // 上一周按钮文字
133
+ // nextWeekText: '后一周', // 下一周按钮文字
134
+ // prevDayText: '前一天', // 前一天按钮文字
135
+ // nextDayText: '后一天', // 后一天按钮文字
136
+ // // 日期范围限制
137
+ // minDate: '2024-01-01', // 最小可选日期
138
+ // maxDate: '2025-12-31', // 最大可选日期
139
+ // // 周末高亮配置
140
+ // highlightWeekend: true, // 是否高亮周末
141
+ // // 业务逻辑配置
142
+ // logicName: 'getDisabledDates', // 获取禁用日期的逻辑名称
143
+ // parameter: {
144
+ // userId: 'xxx',
145
+ // type: 'workday'
146
+ // }
147
+ // }
148
+ this.config = res
149
+ if (res.defaultValue) {
150
+ // 如果有默认值,则设置当前选中日期和基准日期
151
+ this.currentDate = res.defaultValue
152
+ this.baseDate = res.defaultValue
153
+ this.$emit('update:modelValue', res.defaultValue)
154
+ }
155
+
156
+ // 执行配置中指定的业务逻辑
157
+ if (res.logicName) {
158
+ runLogic(res.logicName, res.parameter, 'af-his').then(result => {
159
+ // var result = {
160
+ // disabledDates: [ // 禁用的日期列表
161
+ // '2025-03-23', // 周六
162
+ // '2025-03-24', // 周日
163
+ // '2025-03-25' // 其他需要禁用的日期
164
+ // ],
165
+ // currentDate: '' // 指定当前选中日期(可选)
166
+ // }
167
+ if (result) {
168
+ this.handleLogicResult(result)
169
+ }
170
+ })
171
+ }
172
+ })
173
+ },
174
+
175
+ // 处理业务逻辑返回结果
176
+ handleLogicResult (result) {
177
+ if (result.disabledDates) {
178
+ this.disabledDates = result.disabledDates
179
+ }
180
+ if (result.currentDate) {
181
+ this.currentDate = result.currentDate
182
+ this.baseDate = result.currentDate
183
+ this.$emit('update:modelValue', result.currentDate)
184
+ }
185
+ },
186
+
187
+ // 格式化日期显示
188
+ formatDate (date) {
189
+ const format = this.config?.dateFormat || 'MM/DD'
190
+ return dayjs(date).format(format)
191
+ },
192
+
193
+ // 获取星期显示
194
+ getWeekDay (date) {
195
+ const format = this.config?.weekFormat || '周dd'
196
+ return dayjs(date).format(format)
197
+ },
198
+
199
+ // 判断是否为周末
200
+ isWeekend (date) {
201
+ if (!this.config?.highlightWeekend) return false
202
+ const day = dayjs(date).day()
203
+ return day === 0 || day === 6
204
+ },
205
+
206
+ // 判断日期是否禁用
207
+ isDisabled (date) {
208
+ if (this.config?.minDate && dayjs(date).isBefore(this.config.minDate)) {
209
+ return true
210
+ }
211
+ if (this.config?.maxDate && dayjs(date).isAfter(this.config.maxDate)) {
212
+ return true
213
+ }
214
+ return this.disabledDates.includes(date)
215
+ },
216
+
217
+ // 判断是否为当前选中日期
218
+ isCurrentDate (date) {
219
+ if (!this.currentDate) return false
220
+ return dayjs(date).format('YYYY-MM-DD') === dayjs(this.currentDate).format('YYYY-MM-DD')
221
+ },
222
+
223
+ // 选择日期
224
+ selectDate (date) {
225
+ if (this.isDisabled(date)) return
226
+ this.currentDate = date
227
+ this.$emit('update:modelValue', date)
228
+ this.$emit('change', date)
229
+ },
230
+
231
+ // 前一天
232
+ goToPrevDay () {
233
+ const newDate = dayjs(this.baseDate).subtract(1, 'day')
234
+ if (this.config?.minDate && newDate.isBefore(this.config.minDate)) {
235
+ return
236
+ }
237
+ this.baseDate = newDate.format('YYYY-MM-DD')
238
+ this.$emit('prev-day', this.baseDate)
239
+ },
240
+
241
+ // 后一天
242
+ goToNextDay () {
243
+ const newDate = dayjs(this.baseDate).add(1, 'day')
244
+ if (this.config?.maxDate && newDate.isAfter(this.config.maxDate)) {
245
+ return
246
+ }
247
+ this.baseDate = newDate.format('YYYY-MM-DD')
248
+ this.$emit('next-day', this.baseDate)
249
+ },
250
+
251
+ // 前一周
252
+ goToPrevWeek () {
253
+ const newDate = dayjs(this.baseDate).subtract(7, 'day')
254
+ if (this.config?.minDate && newDate.isBefore(this.config.minDate)) {
255
+ return
256
+ }
257
+ this.baseDate = newDate.format('YYYY-MM-DD')
258
+ this.$emit('prev-week', this.baseDate)
259
+ },
260
+
261
+ // 后一周
262
+ goToNextWeek () {
263
+ const newDate = dayjs(this.baseDate).add(7, 'day')
264
+ if (this.config?.maxDate && newDate.isAfter(this.config.maxDate)) {
265
+ return
266
+ }
267
+ this.baseDate = newDate.format('YYYY-MM-DD')
268
+ this.$emit('next-week', this.baseDate)
269
+ }
270
+ }
271
+ })
272
+ </script>
273
+
274
+ <style scoped>
275
+ .x-timeline {
276
+ width: 100%;
277
+ border: 1px solid #f0f0f0;
278
+ border-radius: 2px;
279
+ }
280
+
281
+ .x-timeline-nav {
282
+ display: flex;
283
+ align-items: center;
284
+ padding: 16px;
285
+ border-bottom: 1px solid #f0f0f0;
286
+ width: 100%;
287
+ justify-content: space-between;
288
+ }
289
+
290
+ .timeline-dates {
291
+ display: flex;
292
+ flex: 1;
293
+ justify-content: space-around;
294
+ align-items: center;
295
+ margin: 0 16px;
296
+ }
297
+
298
+ .date-item {
299
+ padding: 8px 12px;
300
+ text-align: center;
301
+ cursor: pointer;
302
+ border-radius: 2px;
303
+ flex: 1;
304
+ margin: 0 8px;
305
+ transition: all 0.3s;
306
+ }
307
+
308
+ .date-item:hover:not(.ant-btn-disabled) {
309
+ background: #fafafa;
310
+ }
311
+
312
+ .date-item.ant-btn-primary {
313
+ background: #1890ff;
314
+ color: #fff;
315
+ }
316
+
317
+ .date-item.ant-btn-primary .weekday,
318
+ .date-item.ant-btn-primary .date {
319
+ color: #fff;
320
+ }
321
+
322
+ .date-item.date-weekend:not(.ant-btn-disabled):not(.ant-btn-primary) {
323
+ color: #ff4d4f;
324
+ }
325
+
326
+ .date-item.ant-btn-disabled {
327
+ color: rgba(0, 0, 0, 0.25);
328
+ background: #f5f5f5;
329
+ cursor: not-allowed;
330
+ }
331
+
332
+ .weekday {
333
+ font-size: 12px;
334
+ margin-bottom: 8px;
335
+ color: rgba(0, 0, 0, 0.45);
336
+ }
337
+
338
+ .date {
339
+ font-size: 14px;
340
+ color: rgba(0, 0, 0, 0.85);
341
+ }
342
+ </style>
@@ -88,6 +88,7 @@
88
88
  <script>
89
89
 
90
90
  import { runLogic } from '@vue2-client/services/api/common'
91
+ import { initDiagnosisDropdown } from './diagnosisAutocomplete'
91
92
 
92
93
  export default {
93
94
  name: 'XHisEditor',
@@ -163,12 +164,42 @@ export default {
163
164
  },
164
165
  methods: {
165
166
  runLogic,
167
+ async initDiagnosisAutocomplete (dropDownBoxParams) {
168
+ if (!this.editorRef || !this.editorRef.document) {
169
+ return
170
+ }
171
+
172
+ // 添加参数检查
173
+ if (!dropDownBoxParams || !Array.isArray(dropDownBoxParams) || dropDownBoxParams.length === 0) {
174
+ return
175
+ }
176
+
177
+ dropDownBoxParams.forEach(async (param) => {
178
+ if (param.identificationCode && param.dataLogic) {
179
+ try {
180
+ let preliDiagnoData = null
181
+ // 保留获取后端数据的逻辑
182
+ await runLogic(param.dataLogic,
183
+ {}, 'af-his').then(res => {
184
+ preliDiagnoData = res
185
+ })
186
+ const scriptElement = this.editorRef.document.createElement('script')
187
+ scriptElement.textContent = `(${initDiagnosisDropdown.toString()})(editor,${JSON.stringify(preliDiagnoData)},'${param.identificationCode}')`
188
+ this.editorRef.document.body.appendChild(scriptElement)
189
+ } catch (error) {
190
+
191
+ }
192
+ }
193
+ })
194
+ },
166
195
  // 初始化文档
167
- onload: function (e) {
168
- this.editorRef = e.target.contentWindow.editor
169
- this.$emit('init', {})
196
+ onload (e) {
197
+ if (e && e.target && e.target.contentWindow) {
198
+ this.editorRef = e.target.contentWindow.editor
199
+ // 等待文档加载完成
200
+ this.$emit('init', {})
201
+ }
170
202
  },
171
- // 初始化组件
172
203
  init (params) {
173
204
  const {
174
205
  fileUrl,
@@ -177,6 +208,7 @@ export default {
177
208
  bindObject,
178
209
  saveDataLogicName,
179
210
  logicExtraParams,
211
+ dropDownBoxParams,
180
212
  serviceName,
181
213
  showModeChoose = true,
182
214
  modeType = 'readonly'
@@ -194,29 +226,36 @@ export default {
194
226
  this.showModeChoose = showModeChoose
195
227
  this.modeType = modeType
196
228
  this.ready = true
197
- this.loadFile(fileUrl, bindObject, currResData)
229
+ // 先加载文件
230
+ this.loadFile(fileUrl, bindObject, currResData).then(() => {
231
+ // 文件加载完成后再初始化自动完成
232
+ this.initDiagnosisAutocomplete(dropDownBoxParams)
233
+ })
198
234
  this.loadResList()
199
235
  },
200
236
  // 加载文档
201
237
  loadFile (fileUrl, bindObject, currResData) {
202
238
  this.loading = true
203
- this.editorRef.loadUrl(fileUrl).then(() => {
204
- if (bindObject) {
205
- this.editorRef.setBindObject(bindObject)
206
- if (bindObject.template) {
207
- for (const key of Object.keys(bindObject.template)) {
208
- this.editorRef.bindDataList(key, bindObject.template[key])
239
+ return new Promise((resolve) => {
240
+ this.editorRef.loadUrl(fileUrl).then(() => {
241
+ if (bindObject) {
242
+ this.editorRef.setBindObject(bindObject)
243
+ if (bindObject.template) {
244
+ for (const key of Object.keys(bindObject.template)) {
245
+ this.editorRef.bindDataList(key, bindObject.template[key])
246
+ }
209
247
  }
210
248
  }
211
- }
212
- this.changeMode()
213
- this.fileUrl = fileUrl
214
- if (!currResData.f_file_name) {
215
- currResData.f_file_name = '未命名'
216
- }
217
- this.currResData = currResData
218
- this.loading = false
219
- this.$emit('afterLoadFile', {})
249
+ this.changeMode()
250
+ this.fileUrl = fileUrl
251
+ if (!currResData.f_file_name) {
252
+ currResData.f_file_name = '未命名'
253
+ }
254
+ this.currResData = currResData
255
+ this.loading = false
256
+ this.$emit('afterLoadFile', {})
257
+ resolve()
258
+ })
220
259
  })
221
260
  },
222
261
  // 加载文档列表
@@ -270,7 +309,7 @@ export default {
270
309
  },
271
310
  // 重新加载
272
311
  reload (params) {
273
- runLogic('getMedicalRecord', params, this.serviceName).then(res => {
312
+ runLogic('getFileInformation', params, this.serviceName).then(res => {
274
313
  this.resDataModalVisible = false
275
314
  this.init({
276
315
  modeType: this.modeType,
@@ -280,7 +319,8 @@ export default {
280
319
  bindObject: res.bindObject,
281
320
  saveDataLogicName: this.saveDataLogicName,
282
321
  serviceName: this.serviceName,
283
- logicExtraParams: this.logicExtraParams
322
+ logicExtraParams: this.logicExtraParams,
323
+ dropDownBoxParams: this.dropDownBoxParams
284
324
  })
285
325
  })
286
326
  },