vue2-client 1.13.18 → 1.13.20

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.13.18",
3
+ "version": "1.13.20",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -1,121 +1,128 @@
1
- <template>
2
- <div class="x-input-wrapper">
3
- <div class="input-container">
4
- <span v-if="config?.label" class="input-label">{{ config.label }}</span>
5
- <div class="input-wrapper">
6
- <a-input
7
- v-model="innerValue"
8
- v-bind="$attrs"
9
- :placeholder="config?.placeholder"
10
- :size="config?.size"
11
- :maxLength="config?.maxLength"
12
- :disabled="config?.disabled"
13
- :allowClear="config?.allowClear"
14
- @change="handleInput"
15
- @pressEnter="handleSearch"
16
- >
17
- <template v-if="config?.prefix" #prefix>
18
- <a-icon :type="config.prefix" @click="handleSearch" class="clickable-icon" />
19
- </template>
20
- <template v-if="config?.suffix" #suffix>
21
- <a-icon :type="config.suffix" @click="handleSearch" class="clickable-icon" />
22
- </template>
23
- </a-input>
24
- </div>
25
- </div>
26
- </div>
27
- </template>
28
-
29
- <script>
30
- import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
31
-
32
- export default {
33
- name: 'XInput',
34
- inheritAttrs: false,
35
- props: {
36
- value: {
37
- type: [String, Number],
38
- default: ''
39
- },
40
- queryParamsName: {
41
- type: String,
42
- default: ''
43
- }
44
- },
45
- data () {
46
- return {
47
- innerValue: this.value || '',
48
- config: null
49
- }
50
- },
51
- created () {
52
- this.getData(this.queryParamsName)
53
- },
54
- emits: ['search'],
55
- methods: {
56
- runLogic,
57
- async getData (data) {
58
- getConfigByName(data, 'af-his', res => {
59
- this.config = res
60
- if (res.defaultValue !== undefined) {
61
- this.innerValue = res.defaultValue
62
- }
63
- })
64
- },
65
- handleInput (e) {
66
- const value = e.target.value
67
- this.innerValue = value
68
- this.$emit('search', value)
69
- },
70
- handleSearch () {
71
- // 统一的搜索事件:将当前输入值发送给父组件
72
- this.$emit('search', this.innerValue)
73
- }
74
- },
75
- watch: {
76
- value: {
77
- handler (newValue) {
78
- this.innerValue = newValue
79
- },
80
- immediate: true
81
- },
82
- queryParamsName: {
83
- handler (newValue) {
84
- this.getData(newValue)
85
- },
86
- deep: true
87
- }
88
- }
89
- }
90
- </script>
91
-
92
- <style scoped>
93
- .x-input-wrapper {
94
- position: relative;
95
- display: inline-block;
96
- width: 100%;
97
- }
98
-
99
- .input-container {
100
- display: flex;
101
- align-items: center;
102
- }
103
-
104
- .input-label {
105
- white-space: nowrap;
106
- color: rgba(0, 0, 0, 0.85);
107
- padding-right: 8px; /* 标签右侧固定间距 */
108
- }
109
-
110
- .input-wrapper {
111
- flex: 1; /* 输入框占据剩余空间 */
112
- }
113
-
114
- :deep(.clickable-icon) {
115
- cursor: pointer;
116
- }
117
-
118
- :deep(.clickable-icon:hover) {
119
- color: #1890ff;
120
- }
121
- </style>
1
+ <template>
2
+ <div class="x-input-wrapper">
3
+ <div class="input-container">
4
+ <span v-if="config?.label" class="input-label">{{ config.label }}</span>
5
+ <div class="input-wrapper">
6
+ <a-input
7
+ v-model="innerValue"
8
+ v-bind="$attrs"
9
+ :placeholder="config?.placeholder"
10
+ :size="config?.size"
11
+ :maxLength="config?.maxLength"
12
+ :disabled="config?.disabled"
13
+ :allowClear="config?.allowClear"
14
+ @change="handleInput"
15
+ @pressEnter="handleSearch"
16
+ >
17
+ <template v-if="config?.prefix" #prefix>
18
+ <a-icon :type="config.prefix" @click="handleSearch" class="clickable-icon" />
19
+ </template>
20
+ <template v-if="config?.suffix" #suffix>
21
+ <a-icon :type="config.suffix" @click="handleSearch" class="clickable-icon" />
22
+ </template>
23
+ </a-input>
24
+ </div>
25
+ <span v-if="config?.tail" class="input-tail">{{ config.tail }}</span>
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script>
31
+ import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
32
+
33
+ export default {
34
+ name: 'XInput',
35
+ inheritAttrs: false,
36
+ props: {
37
+ value: {
38
+ type: [String, Number],
39
+ default: ''
40
+ },
41
+ queryParamsName: {
42
+ type: String,
43
+ default: ''
44
+ }
45
+ },
46
+ data () {
47
+ return {
48
+ innerValue: this.value || '',
49
+ config: null
50
+ }
51
+ },
52
+ created () {
53
+ this.getData(this.queryParamsName)
54
+ },
55
+ emits: ['search'],
56
+ methods: {
57
+ runLogic,
58
+ async getData (data) {
59
+ getConfigByName(data, 'af-his', res => {
60
+ this.config = res
61
+ if (res.defaultValue !== undefined) {
62
+ this.innerValue = res.defaultValue
63
+ }
64
+ })
65
+ },
66
+ handleInput (e) {
67
+ const value = e.target.value
68
+ this.innerValue = value
69
+ this.$emit('search', value)
70
+ },
71
+ handleSearch () {
72
+ // 统一的搜索事件:将当前输入值发送给父组件
73
+ this.$emit('search', this.innerValue)
74
+ }
75
+ },
76
+ watch: {
77
+ value: {
78
+ handler (newValue) {
79
+ this.innerValue = newValue
80
+ },
81
+ immediate: true
82
+ },
83
+ queryParamsName: {
84
+ handler (newValue) {
85
+ this.getData(newValue)
86
+ },
87
+ deep: true
88
+ }
89
+ }
90
+ }
91
+ </script>
92
+
93
+ <style scoped>
94
+ .x-input-wrapper {
95
+ position: relative;
96
+ display: inline-block;
97
+ width: 100%;
98
+ }
99
+
100
+ .input-container {
101
+ display: flex;
102
+ align-items: center;
103
+ }
104
+
105
+ .input-label {
106
+ white-space: nowrap;
107
+ color: rgba(0, 0, 0, 0.85);
108
+ padding-right: 8px; /* 标签右侧固定间距 */
109
+ }
110
+
111
+ .input-label {
112
+ white-space: nowrap;
113
+ color: rgba(0, 0, 0, 0.85);
114
+ padding-left: 4px; /* 标签左侧固定间距 */
115
+ }
116
+
117
+ .input-wrapper {
118
+ flex: 1; /* 输入框占据剩余空间 */
119
+ }
120
+
121
+ :deep(.clickable-icon) {
122
+ cursor: pointer;
123
+ }
124
+
125
+ :deep(.clickable-icon:hover) {
126
+ color: #1890ff;
127
+ }
128
+ </style>
@@ -13,16 +13,18 @@ XInput 是一个封装了 Ant Design Vue 的输入框组件,提供搜索功能
13
13
 
14
14
  组件通过 `queryParamsName` 属性获取配置,配置内容如下:
15
15
 
16
- | 参数 | 说明 | 类型 | 默认值 |
17
- | --- | --- | --- | --- |
18
- | size | 输入框大小 | string | 'default' |
19
- | prefix | 前缀图标类型 | string | '' |
20
- | defaultValue | 默认值 | string/number | '' |
21
- | disabled | 是否禁用 | boolean | false |
22
- | placeholder | 占位文本 | string | '' |
23
- | allowClear | 是否允许清除 | boolean | true |
24
- | suffix | 后缀图标类型 | string | 'search' |
25
- | maxLength | 最大输入长度 | number | 50 |
16
+ | 参数 | 说明 | 类型 | 默认值 |
17
+ |--------------|--------|---------------| --- |
18
+ | size | 输入框大小 | string | 'default' |
19
+ | prefix | 前缀图标类型 | string | '' |
20
+ | defaultValue | 默认值 | string/number | '' |
21
+ | disabled | 是否禁用 | boolean | false |
22
+ | placeholder | 占位文本 | string | '' |
23
+ | allowClear | 是否允许清除 | boolean | true |
24
+ | suffix | 后缀图标类型 | string | 'search' |
25
+ | maxLength | 最大输入长度 | number | 50 |
26
+ | label | 输入框前文字 | String | '' |
27
+ | tail | 输入框后文字 | String | '' |
26
28
 
27
29
  ## 事件
28
30
 
@@ -36,8 +38,8 @@ XInput 是一个封装了 Ant Design Vue 的输入框组件,提供搜索功能
36
38
 
37
39
  ```vue
38
40
  <template>
39
- <x-input
40
- v-model="searchValue"
41
+ <x-input
42
+ v-model="searchValue"
41
43
  @search="handleSearch"
42
44
  />
43
45
  </template>
@@ -80,8 +82,8 @@ export default {
80
82
 
81
83
  ```vue
82
84
  <template>
83
- <x-input
84
- v-model="searchValue"
85
+ <x-input
86
+ v-model="searchValue"
85
87
  query-params-name="customInputConfig"
86
88
  @search="handleSearch"
87
89
  />
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <a-card :bordered="false">
3
- <a-tabs :tabBarGutter="10" :activeKey="activeKey" @change="tabPaneChange">
3
+ <a-tabs :tabBarGutter="10" :activeKey="activeKey" @change="tabPaneChange" :hideAdd="true" :tabBarStyle="{ display: showTabBar ? 'block' : 'none' }">
4
4
  <a-tab-pane
5
5
  :forceRender="true"
6
6
  v-for="(tab, index) in config.data"
@@ -50,7 +50,8 @@ export default {
50
50
  activeKey: 0,
51
51
  // 配置
52
52
  config: undefined,
53
- attr: {}
53
+ attr: {},
54
+ showTabBar: true // 默认显示页签
54
55
  }
55
56
  },
56
57
  computed: {
@@ -133,11 +134,15 @@ export default {
133
134
  this.getConfig()
134
135
  } else if (this.localConfig) {
135
136
  this.config = this.localConfig
137
+ // 设置是否显示页签
138
+ this.showTabBar = this.localConfig.showTabBar !== false
136
139
  }
137
140
  },
138
141
  getConfig () {
139
142
  getConfigByName(this.configName, this.serverName, res => {
140
143
  this.config = res
144
+ // 设置是否显示页签
145
+ this.showTabBar = res.showTabBar !== false
141
146
  }, this.env === 'dev')
142
147
  },
143
148
  getEventHandlers (tab, index) {
@@ -162,10 +162,11 @@ export default {
162
162
  }
163
163
  }
164
164
  },
165
- // 初始化 保存后 加载文件后
166
- emits: ['init', 'saveafter', 'afterLoadFile'],
165
+ // 初始化 保存后 加载文件后 诊断选择
166
+ emits: ['init', 'saveafter', 'afterLoadFile', 'selected'],
167
167
  methods: {
168
168
  runLogic,
169
+ /* eslint-disable */
169
170
  async initDiagnosisAutocomplete (dropDownBoxParams) {
170
171
  if (!this.editorRef || !this.editorRef.document) {
171
172
  return
@@ -176,7 +177,21 @@ export default {
176
177
  return
177
178
  }
178
179
 
179
- dropDownBoxParams.forEach(async (param) => {
180
+ // 创建一个简单的自定义事件系统
181
+ // 1. 创建一个隐藏的DOM元素作为事件通道
182
+ const eventChannel = this.editorRef.document.createElement('div');
183
+ eventChannel.id = 'diagnosis-event-channel';
184
+ eventChannel.style.display = 'none';
185
+ this.editorRef.document.body.appendChild(eventChannel);
186
+ // 2. 在iframe文档中监听自定义事件
187
+ const that = this;
188
+ this.editorRef.document.addEventListener('diagnosis-selected', function(e) {
189
+ if (e && e.detail) {
190
+ that.$emit('selected', { item: e.detail, editor: that.editorRef });
191
+ }
192
+ });
193
+
194
+ for (const param of dropDownBoxParams) {
180
195
  if (param.identificationCode && param.dataLogic) {
181
196
  try {
182
197
  let preliDiagnoData = null
@@ -185,15 +200,38 @@ export default {
185
200
  {}, 'af-his').then(res => {
186
201
  preliDiagnoData = res
187
202
  })
203
+
204
+ // 创建脚本元素
188
205
  const scriptElement = this.editorRef.document.createElement('script')
189
- scriptElement.textContent = `(${initDiagnosisDropdown.toString()})(editor,${JSON.stringify(preliDiagnoData)},'${param.identificationCode}')`
190
- this.editorRef.document.body.appendChild(scriptElement)
191
- } catch (error) {
192
206
 
207
+ // 注入自定义事件触发函数和初始化代码
208
+ scriptElement.textContent = `
209
+ // 定义一个函数来触发自定义事件
210
+ function triggerDiagnosisSelected(data) {
211
+ const event = new CustomEvent('diagnosis-selected', {
212
+ detail: data,
213
+ bubbles: true
214
+ });
215
+ document.dispatchEvent(event);
216
+ }
217
+
218
+ // 初始化诊断下拉菜单,使用自定义事件触发函数
219
+ (${initDiagnosisDropdown.toString()})(
220
+ editor,
221
+ ${JSON.stringify(preliDiagnoData)},
222
+ '${param.identificationCode}',
223
+ triggerDiagnosisSelected
224
+ );
225
+ `;
226
+
227
+ this.editorRef.document.body.appendChild(scriptElement);
228
+ } catch (error) {
229
+ console.error('初始化诊断自动完成失败:', error);
193
230
  }
194
231
  }
195
- })
232
+ }
196
233
  },
234
+ /* eslint-disable */
197
235
  // 初始化文档
198
236
  onload (e) {
199
237
  if (e && e.target && e.target.contentWindow) {
@@ -229,9 +267,9 @@ export default {
229
267
  this.modeType = modeType
230
268
  this.ready = true
231
269
  // 先加载文件
232
- this.loadFile(fileUrl, bindObject, currResData).then(() => {
270
+ this.loadFile(fileUrl, bindObject, currResData).then(async () => {
233
271
  // 文件加载完成后再初始化自动完成
234
- this.initDiagnosisAutocomplete(dropDownBoxParams)
272
+ await this.initDiagnosisAutocomplete(dropDownBoxParams)
235
273
  })
236
274
  this.loadResList()
237
275
  },
@@ -1,4 +1,5 @@
1
- export function initDiagnosisDropdown (editor, data, identificationCode) {
1
+ /* eslint-disable */
2
+ export function initDiagnosisDropdown (editor, data, identificationCode, emitFunc) {
2
3
  if (typeof editor === 'undefined' || !editor.$) {
3
4
  return
4
5
  }
@@ -213,6 +214,27 @@ export function initDiagnosisDropdown (editor, data, identificationCode) {
213
214
  e.stopPropagation()
214
215
  if (isEditableMode()) {
215
216
  const name = editor.$(this).find('.ant-list-item-title').text()
217
+ const code = editor.$(this).find('.ant-list-item-description').text()
218
+ // 根据选中的name和code查找完整数据
219
+ const selectedItem = mockDiagnosisList.find(item =>
220
+ item.name === name && item.code === code
221
+ )
222
+
223
+ // 打印完整数据,包括id、name和code
224
+ if (selectedItem) {
225
+ // 使用传入的emit函数触发事件
226
+ if (typeof emitFunc === 'function') {
227
+ // 只传递数据参数,不再传递事件名
228
+ emitFunc(selectedItem)
229
+ }
230
+ } else {
231
+ // 如果找不到完整数据,至少打印出已知信息
232
+ // 使用传入的emit函数触发事件,发送部分数据
233
+ if (typeof emitFunc === 'function') {
234
+ // 只传递数据参数,不再传递事件名
235
+ emitFunc({name, code, element: identificationCode})
236
+ }
237
+ }
216
238
  fieldElement.textContent = name
217
239
  dropdownList.style.display = 'none'
218
240
  fieldElement.focus()