vue2-client 1.13.2 → 1.13.3

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.2",
3
+ "version": "1.13.3",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -48,10 +48,10 @@
48
48
  <template v-if="panel.type === 'picture'">
49
49
  <img :src="panel.configName" alt="图片" style="width: 100%; max-width: 500px;"/>
50
50
  </template>
51
- <template v-else-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', 'x-radio'].includes(panel.type)">
51
+ <template v-else-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', 'x-radio', 'x-text-card'].includes(panel.type)">
52
52
  <component
53
53
  :is="getComponentName(panel.type)"
54
- :ref="`dynamicComponent_${ panel.type }`"
54
+ :ref="`dynamicComponent_${ panel.type }_${ panelIndex }`"
55
55
  serverName="af-his"
56
56
  :queryParamsName="panel.configName"
57
57
  :parameter="panel.parameter"
@@ -89,7 +89,8 @@ export default {
89
89
  XList: () => import('@vue2-client/base-client/components/his/XList/XList.vue'),
90
90
  XInput: () => import('@vue2-client/base-client/components/common/XInput/XInput.vue'),
91
91
  XTimeLine: () => import('@vue2-client/base-client/components/common/XTimeline/XTimeline.vue'),
92
- XRadio: () => import('@vue2-client/base-client/components/his/XRadio/XRadio.vue')
92
+ XRadio: () => import('@vue2-client/base-client/components/his/XRadio/XRadio.vue'),
93
+ XTextCard: () => import('@vue2-client/base-client/components/his/XTextCard/XTextCard.vue')
93
94
  },
94
95
  data () {
95
96
  return {
@@ -0,0 +1,242 @@
1
+ <template>
2
+ <div>
3
+ <div class="text-card">
4
+ <!-- 添加顶部按钮区域 -->
5
+ <div class="text-card-header">
6
+ <div class="add-button" @click="handleAddClick">
7
+ <span class="plus-icon">+</span>
8
+ </div>
9
+ </div>
10
+ <div
11
+ v-for="(item, index) in displayItems"
12
+ :key="index"
13
+ class="text-item"
14
+ @click="handleItemClick(index)"
15
+ @contextmenu.prevent="handleContextMenu(index)">
16
+ <div class="text-content" :class="{ 'is-empty': !item.content }">
17
+ {{ item.content || '点击添加内容' }}
18
+ </div>
19
+ </div>
20
+ <!-- 编辑弹出框 -->
21
+ <div
22
+ v-if="showEdit"
23
+ class="edit-overlay"
24
+ @click.self="handleOverlayClick">
25
+ <div class="edit-card">
26
+ <a-textarea
27
+ v-model="editingContent"
28
+ :autoSize="{ minRows: 3 }"
29
+ @keyup.enter="handleSave"
30
+ ref="textarea"/>
31
+ </div>
32
+ </div>
33
+ <!-- 删除确认弹框 -->
34
+ <a-modal
35
+ v-model="showDeleteModal"
36
+ title="确认删除"
37
+ okText="确认"
38
+ cancelText="取消"
39
+ @ok="handleDeleteConfirm">
40
+ <p>确定要删除这条内容吗?</p>
41
+ </a-modal>
42
+ </div>
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ import { runLogic } from '@vue2-client/services/api/common'
48
+
49
+ export default {
50
+ name: 'XTextCard',
51
+ props: {
52
+ // logic配置名,要求返回一个数组[]
53
+ queryParamsName: {
54
+ type: String,
55
+ default: 'memorandumLOGIC'
56
+ },
57
+ queryParams: {
58
+ type: Object,
59
+ default: () => { return {} }
60
+ },
61
+ // 请求参数
62
+ parameter: {
63
+ type: Object,
64
+ default: () => { return {} }
65
+ }
66
+ },
67
+ data () {
68
+ return {
69
+ localItems: [], // 本地数据
70
+ showEdit: false, // 是否显示编辑框
71
+ editingIndex: -1, // 当前编辑的索引
72
+ editingContent: '', // 编辑框的内容
73
+ showDeleteModal: false, // 是否显示删除确认框
74
+ deleteIndex: -1, // 要删除的项目索引
75
+ }
76
+ },
77
+ computed: {
78
+ // 显示的列表,始终保持一个空行
79
+ displayItems () {
80
+ const items = [...this.localItems]
81
+ // 如果最后一项不是空的,添加一个空项
82
+ if (!items.length || items[items.length - 1].content) {
83
+ items.push({ content: '' })
84
+ }
85
+ return items
86
+ }
87
+ },
88
+ methods: {
89
+ // 添加新方法
90
+ handleAddClick () {
91
+ // 直接打开编辑框,索引设为数组长度(等同于点击最后一个空行)
92
+ this.editingIndex = this.localItems.length
93
+ this.editingContent = ''
94
+ this.showEdit = true
95
+ this.$nextTick(() => {
96
+ this.$refs.textarea?.focus()
97
+ })
98
+ },
99
+ // 点击项目
100
+ handleItemClick (index) {
101
+ this.editingIndex = index
102
+ this.editingContent = this.displayItems[index].content
103
+ this.showEdit = true
104
+ this.$nextTick(() => {
105
+ this.$refs.textarea?.focus()
106
+ })
107
+ },
108
+ // 点击遮罩层保存
109
+ handleOverlayClick () {
110
+ this.handleSave()
111
+ },
112
+ // 保存内容
113
+ handleSave () {
114
+ if (this.editingContent.trim()) {
115
+ if (this.editingIndex === this.localItems.length) {
116
+ // 如果是在最后一个空行添加,push新内容
117
+ this.localItems.push({ content: this.editingContent.trim() })
118
+ } else {
119
+ // 否则更新现有内容
120
+ this.localItems[this.editingIndex].content = this.editingContent.trim()
121
+ }
122
+ // 触发更新事件
123
+ this.$emit('add', this.editingContent.trim())
124
+ }
125
+ this.showEdit = false
126
+ this.editingIndex = -1
127
+ this.editingContent = ''
128
+ },
129
+ // 初始化数据
130
+ async initData (data, parameter) {
131
+ // 从配置中获取数据
132
+ const resData = await runLogic(data, parameter, 'af-his')
133
+ this.localItems = resData.map(content => ({ content: content }))
134
+ return resData
135
+ },
136
+ // 处理右键菜单
137
+ handleContextMenu (index) {
138
+ // 如果是最后一个空行,不显示删除框
139
+ if (index === this.localItems.length) {
140
+ return
141
+ }
142
+ this.deleteIndex = index
143
+ this.showDeleteModal = true
144
+ },
145
+ // 确认删除
146
+ handleDeleteConfirm () {
147
+ if (this.deleteIndex > -1) {
148
+ this.localItems.splice(this.deleteIndex, 1)
149
+ this.$emit('delete', [...this.localItems][this.deleteIndex])
150
+ this.deleteIndex = -1
151
+ }
152
+ this.showDeleteModal = false
153
+ }
154
+ },
155
+ watch: {
156
+ queryParamsName: {
157
+ immediate: true,
158
+ handler (newVal) {
159
+ this.initData(newVal, this.parameter)
160
+ },
161
+ deep: true
162
+ }
163
+ }
164
+ }
165
+ </script>
166
+
167
+ <style scoped lang="less">
168
+ .text-card {
169
+ position: relative;
170
+ width: 100%;
171
+ // 添加头部样式
172
+ .text-card-header {
173
+ padding: 8px 12px;
174
+ border-bottom: 1px solid #f0f0f0;
175
+ .add-button {
176
+ display: inline-flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+ width: 24px;
180
+ height: 24px;
181
+ border-radius: 4px;
182
+ cursor: pointer;
183
+ transition: all 0.3s;
184
+ &:hover {
185
+ background-color: #f5f5f5;
186
+ }
187
+ .plus-icon {
188
+ font-size: 20px;
189
+ line-height: 1;
190
+ color: #5D5C5C;
191
+ font-weight: bold;
192
+ }
193
+ }
194
+ }
195
+
196
+ .text-item {
197
+ padding: 8px 12px;
198
+ border-bottom: 1px solid #f0f0f0;
199
+ cursor: pointer;
200
+ transition: all 0.3s;
201
+ user-select: none; // 防止文本被选中
202
+
203
+ &:hover {
204
+ background-color: #f5f5f5;
205
+ }
206
+
207
+ .text-content {
208
+ white-space: nowrap;
209
+ overflow: hidden;
210
+ text-overflow: ellipsis;
211
+ line-height: 1.5;
212
+
213
+ &.is-empty {
214
+ color: #bfbfbf;
215
+ }
216
+ }
217
+ }
218
+ .edit-overlay {
219
+ position: fixed;
220
+ top: 0;
221
+ left: 0;
222
+ right: 0;
223
+ bottom: 0;
224
+ background-color: rgba(0, 0, 0, 0.45);
225
+ z-index: 1000;
226
+ display: flex;
227
+ align-items: center;
228
+ justify-content: center;
229
+ .edit-card {
230
+ background: white;
231
+ padding: 16px;
232
+ border-radius: 8px;
233
+ width: 90%;
234
+ max-width: 500px;
235
+ box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12);
236
+ .ant-input {
237
+ width: 100%;
238
+ }
239
+ }
240
+ }
241
+ }
242
+ </style>