lw-cdp-ui 1.2.23 → 1.2.25

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.
@@ -4,15 +4,18 @@
4
4
  class="title-name title-name-divider"
5
5
  :id="'divider-' + index"
6
6
  :data-index="index">
7
- {{ item.label }}
8
- <el-tooltip v-if="item.tips">
9
- <template #content>
10
- <span style="max-width: 300px; display: inline-block;">
11
- {{ item.tips }}
12
- </span>
13
- </template>
14
- <el-icon><el-icon-question-filled /></el-icon>
15
- </el-tooltip>
7
+ <span>
8
+ {{ item.label }}
9
+ <el-tooltip v-if="item.tips">
10
+ <template #content>
11
+ <span style="max-width: 300px; display: inline-block;">
12
+ {{ item.tips }}
13
+ </span>
14
+ </template>
15
+ <el-icon><el-icon-question-filled /></el-icon>
16
+ </el-tooltip>
17
+ </span>
18
+ <slot :name="item?.options?.component"></slot>
16
19
  </div>
17
20
 
18
21
  <!-- 表单内容 -->
@@ -376,6 +379,15 @@ export default {
376
379
  }
377
380
  }
378
381
 
382
+ .title-name {
383
+ font-size: 18px;
384
+ font-weight: bold;
385
+ margin-bottom: 10px;
386
+ margin-top: 25px;
387
+ border-top: 10px solid #f5f7fa;
388
+ padding-top: 20px;
389
+ }
390
+
379
391
  .form-mini {
380
392
  display: flex;
381
393
  width: 100%;
@@ -390,15 +402,6 @@ export default {
390
402
  width: 100px;
391
403
  }
392
404
 
393
- .title-name {
394
- font-size: 18px;
395
- font-weight: bold;
396
- margin-bottom: 10px;
397
- margin-top: 25px;
398
- border-top: 10px solid #f5f7fa;
399
- padding-top: 20px;
400
- }
401
-
402
405
  :deep(.form-item-name-null) {
403
406
  > .el-form-item__label {
404
407
  display: none !important;
@@ -0,0 +1,386 @@
1
+ <template>
2
+ <!-- 间隔标题 -->
3
+ <div v-if="item.component == 'divider'"
4
+ class="title-name title-name-divider"
5
+ :id="'divider-' + index"
6
+ :data-index="index">
7
+ <span>
8
+ {{ item.label }}
9
+ <el-tooltip v-if="item.tips">
10
+ <template #content>
11
+ <span style="max-width: 300px; display: inline-block;">
12
+ {{ item.tips }}
13
+ </span>
14
+ </template>
15
+ <el-icon><el-icon-question-filled /></el-icon>
16
+ </el-tooltip>
17
+ </span>
18
+ <slot :name="item?.options?.component"></slot>
19
+
20
+ </div>
21
+
22
+ <!-- 表单内容 -->
23
+ <el-form-item v-else
24
+ :class="{ 'form-item-name-null': !item?.label }"
25
+ :prop="getPropName(item)"
26
+ :rules="rulesHandle(item)">
27
+ <template #label>
28
+ {{ item.label }}
29
+ <el-tooltip v-if="item.tips"
30
+ :raw-content="item?.rawContent"
31
+ :content="item.tips">
32
+ <el-icon><el-icon-question-filled /></el-icon>
33
+ </el-tooltip>
34
+ </template>
35
+
36
+ <!-- input -->
37
+ <template v-if="item.component == 'input'">
38
+ <template
39
+ v-if="item?.options?.prepend">{{ item?.options.prepend }}</template>
40
+ <textToPassword v-model="objItem.value"
41
+ :password="item?.options?.password" />
42
+ <template
43
+ v-if="item?.options?.append">{{ item?.options.append }}</template>
44
+
45
+ </template>
46
+ <!-- upload -->
47
+ <template v-else-if="item.component == 'upload'">
48
+ <template v-for="(_item, _index) in objItem?.options.items"
49
+ :key="_index">
50
+ <lw-upload v-model="_item.value"
51
+ :height="item.height"
52
+ :width="item.width"
53
+ :maxSize="_item.maxSize"
54
+ :accept="_item.accept"
55
+ :title="_item.label"
56
+ :parseData="item.parseData"
57
+ :disabled="true"
58
+ :multiple="_item?.multiple"
59
+ :limit="_item?.limit"
60
+ :returnFile="_item?.returnFile"
61
+ :tip="_item?.tip"
62
+ :apiObj="item.apiObj"></lw-upload>
63
+
64
+ </template>
65
+ </template>
66
+ <!-- checkbox -->
67
+ <template v-else-if="item.component == 'checkbox'">
68
+ <template v-for="(_item, _index) in objItem?.options.items"
69
+ :key="_index">{{ getKeyToLabel(_item.value, objItem?.options.items) }}</template>
70
+ </template>
71
+ <!-- checkboxGroup 、select、radio -->
72
+ <template
73
+ v-else-if="item.component == 'checkboxGroup' || item.component == 'select' || item.component == 'radio'">
74
+ {{ getKeyToLabel(objItem.value, item?.options.items) }}
75
+ </template>
76
+
77
+ <!-- switch -->
78
+ <template v-else-if="item.component == 'switch'">
79
+ {{ objItem.value ? item?.options?.true || '是' : item?.options?.false || '否' }}
80
+ </template>
81
+ <!-- treeSelect -->
82
+ <template v-else-if="item.component == 'treeSelect'">
83
+ <el-tree-select v-model="objItem.value"
84
+ :props="item?.options?.props"
85
+ disabled
86
+ :node-Key="item?.options?.nodeKey"
87
+ :multiple="item?.options?.multiple"
88
+ :check-Strictly="item?.options?.checkStrictly"
89
+ :data="item?.options?.items"></el-tree-select>
90
+
91
+ </template>
92
+ <!-- cascader -->
93
+ <template v-else-if="item.component == 'cascader'">
94
+ <el-cascader v-model="objItem.value"
95
+ style="width: 100%;"
96
+ :props="item?.options?.props"
97
+ :separator="item?.options?.separator"
98
+ disabled
99
+ :options="item?.options.items"
100
+ clearable></el-cascader>
101
+ </template>
102
+ <!-- date -->
103
+ <template v-else-if="item.component == 'date'">
104
+ {{ dayjs(objItem.value).format(item?.options?.valueFormat || 'YYYY-MM-DD HH:mm:ss') }}
105
+ </template>
106
+ <!-- number -->
107
+ <template v-else-if="item.component == 'number'">
108
+ {{ objItem.value }}
109
+ <template v-if="item?.options?.suffix">
110
+ <span>{{ item?.options.suffix }}</span>
111
+ </template>
112
+ </template>
113
+ <!-- color -->
114
+ <template v-else-if="item.component == 'color'">
115
+ <el-color-picker v-model="objItem.value"
116
+ disabled />
117
+ </template>
118
+ <!-- rate -->
119
+ <template v-else-if="item.component == 'rate'">
120
+ <el-rate style="margin-top: 6px;"
121
+ v-model="objItem.value"
122
+ disabled></el-rate>
123
+ </template>
124
+ <!-- slider -->
125
+ <template v-else-if="item.component == 'slider'">
126
+ <el-slider v-model="objItem.value"
127
+ :marks="item?.options.marks"
128
+ disabled></el-slider>
129
+ </template>
130
+
131
+ <!-- tags -->
132
+ <template v-else-if="item.component == 'tags'">
133
+ <div class="tags-list">
134
+ <el-tag v-for="tag in objItem.value"
135
+ :key="tag">
136
+ {{ tag }}
137
+ </el-tag>
138
+ </div>
139
+ </template>
140
+
141
+ <!-- 没有组件是component值 就是插槽名称 -->
142
+ <template v-else>
143
+ <slot :name="item.component"
144
+ :itemCur="item"
145
+ :formCur="form">
146
+ <el-tag type="danger">[{{ item.component }}]
147
+ 没有这个默认组件也未自定义插槽内容</el-tag>
148
+ </slot>
149
+ </template>
150
+ <div v-if="item.message"
151
+ class="el-form-item-msg">{{ item.message }}</div>
152
+ </el-form-item>
153
+ </template>
154
+
155
+ <script>
156
+ import lwUpload from '../lwUpload'
157
+ import dayjs from 'dayjs'
158
+ import textToPassword from './textToPassword'
159
+ export default {
160
+ name: 'ViewItem',
161
+ data() {
162
+ return {
163
+ tagVisible: {},
164
+ dataForm: {},
165
+ objItem: {},
166
+ tagValue: ''
167
+ }
168
+ },
169
+ components: {
170
+ lwUpload,
171
+ textToPassword
172
+ },
173
+ props: {
174
+ item: {
175
+ type: Object,
176
+ default: () => { }
177
+ },
178
+ index: {
179
+ type: Number,
180
+ default: 0
181
+ },
182
+ form: {
183
+ type: Object,
184
+ default: () => { }
185
+ }
186
+ },
187
+ watch: {
188
+ item: {
189
+ handler(val) {
190
+ this.objItem = val
191
+ },
192
+ immediate: true,
193
+ deep: true
194
+ },
195
+ form: {
196
+ handler(val) {
197
+ if (this.item.component === 'checkbox' || this.item.component === 'upload') {
198
+ this.objItem.options?.items?.forEach((option) => {
199
+ option.value = this.flattenObject(this.form, option.name, option.value)
200
+ });
201
+ } else {
202
+ this.objItem.value = this.flattenObject(this.form, this.item.name, this.objItem.value)
203
+ }
204
+
205
+ },
206
+ immediate: true,
207
+ deep: true
208
+ },
209
+ objItem: {
210
+ handler(val) {
211
+ if (val.component === 'checkbox' || val.component === 'upload') {
212
+ val.options?.items?.forEach((option) => {
213
+ this.unflattenObject(this.form, option.name, option.value)
214
+ });
215
+ } else {
216
+ this.unflattenObject(this.form, val.name, val.value)
217
+ }
218
+ },
219
+ deep: true
220
+ },
221
+ },
222
+ methods: {
223
+ flattenObject(obj, key, defaultValue = '') {
224
+ if (!key || !obj) { return false }
225
+ const keys = key.split('.'); // 将路径拆分成数组
226
+
227
+ let current = obj;
228
+ // 遍历路径并逐层查找
229
+ for (let i = 0; i < keys.length; i++) {
230
+ // 如果当前层级不存在,则创建该层级对象
231
+ if (current[keys[i]] === undefined) {
232
+ current[keys[i]] = (i === keys.length - 1) ? defaultValue : {}; // 如果是最后一个层级,设为默认值,否则创建空对象
233
+ }
234
+ // 否则,继续向下查找
235
+ current = current[keys[i]];
236
+ }
237
+ return current;
238
+ },
239
+ unflattenObject(obj, path, value) {
240
+ if (!path || !obj) { return false }
241
+ const keys = path.split('.'); // 按点分隔路径
242
+
243
+ keys.forEach((key, index) => {
244
+ if (index === keys.length - 1) {
245
+ // 最后一级,直接赋值
246
+ obj[key] = value;
247
+ } else {
248
+ // 如果不存在该层级,创建空对象
249
+ if (!obj[key] || typeof obj[key] !== 'object') {
250
+ obj[key] = {};
251
+ }
252
+ obj = obj[key]; // 进入下一层
253
+ }
254
+ });
255
+
256
+ },
257
+ // prop NAME
258
+ getPropName(item) {
259
+ if (item.component == 'checkbox' || item.component == 'upload') {
260
+ return item?.options.items[0].name
261
+ } else {
262
+ return item.name
263
+ }
264
+ },
265
+ // 处理动态必填
266
+ rulesHandle(item) {
267
+ if (item.requiredHandle) {
268
+ try {
269
+ const requiredHandleFunc = new Function("form", `return ${item.requiredHandle.replace(/\$/g, "form")}`);
270
+ const exp = requiredHandleFunc(this.form);
271
+
272
+ const requiredRule = item.rules.find(t => 'required' in t);
273
+ if (requiredRule) {
274
+ requiredRule.required = exp;
275
+ }
276
+ } catch (error) {
277
+ console.error("Error requiredHandle function:", error);
278
+ }
279
+ }
280
+ return item.rules;
281
+ },
282
+ // key to label
283
+ getKeyToLabel(val, items = []) {
284
+ let item = items.find(item => { return item.value == val })
285
+ return item?.label || '--'
286
+ },
287
+ dayjs: dayjs
288
+ }
289
+ }
290
+ </script>
291
+
292
+
293
+ <style lang="scss" scoped>
294
+ :deep(.el-col) {
295
+ &:first-child {
296
+ .title-name {
297
+ border: 0;
298
+ padding-top: 25px;
299
+ margin-top: 0;
300
+ }
301
+ }
302
+ }
303
+
304
+ .title-name {
305
+ font-size: 18px;
306
+ font-weight: bold;
307
+ margin-bottom: 10px;
308
+ margin-top: 25px;
309
+ border-top: 10px solid #f5f7fa;
310
+ padding-top: 20px;
311
+ display: flex;
312
+ align-items: center;
313
+ justify-content: space-between;
314
+ }
315
+
316
+ .form-mini {
317
+ display: flex;
318
+ width: 100%;
319
+ box-sizing: border-box;
320
+ }
321
+ .form-affix {
322
+ min-width: 130px;
323
+ padding-left: 20px;
324
+ }
325
+
326
+ .w-20 {
327
+ width: 100px;
328
+ }
329
+
330
+ :deep(.form-item-name-null) {
331
+ > .el-form-item__label {
332
+ display: none !important;
333
+ }
334
+ }
335
+ .affix-body {
336
+ background-color: var(--el-fill-color-light);
337
+ border: 1px solid var(--el-border-color-light);
338
+ margin: 0;
339
+ position: relative;
340
+ &::after {
341
+ content: "";
342
+ position: absolute;
343
+ left: -2px;
344
+ right: 0;
345
+ height: 16px;
346
+ background-color: #ffffff;
347
+ top: -17px;
348
+ }
349
+ .anchor-link {
350
+ padding: 0 20px;
351
+ height: var(--el-tabs-header-height);
352
+ box-sizing: border-box;
353
+ list-style: none;
354
+ font-size: var(--el-font-size-base);
355
+ font-weight: bold;
356
+ color: var(--el-text-color-secondary);
357
+ position: relative;
358
+ height: 40px;
359
+ display: inline-block;
360
+ line-height: 40px;
361
+ cursor: pointer;
362
+ border-left: 1px solid transparent;
363
+ border-right: 1px solid transparent;
364
+ }
365
+ .active {
366
+ color: var(--el-color-primary);
367
+ background-color: var(--el-bg-color-overlay);
368
+ border-bottom: 1px solid var(--el-bg-color-overlay);
369
+ border-right-color: var(--el-border-color);
370
+ border-left: 1px solid var(--el-border-color-light);
371
+ border-right: 1px solid var(--el-border-color-light);
372
+ &:first-child {
373
+ border-left: 1px solid var(--el-fill-color-light);
374
+ }
375
+ }
376
+ }
377
+
378
+ :deep(.el-tag) {
379
+ & + .button-new-tag {
380
+ margin-left: 10px;
381
+ }
382
+ & + .w-20 {
383
+ margin-left: 10px;
384
+ }
385
+ }
386
+ </style>
@@ -24,18 +24,18 @@
24
24
  :label-width="config.labelWidth"
25
25
  :label-position="$i18n.locale == 'en-us' ? 'top' : config.labelPosition"
26
26
  v-loading="loading"
27
- :disabled="isView"
28
27
  element-loading-text="Loading...">
29
28
  <el-row :gutter="15">
30
29
 
31
30
  <template v-for="(item, index) in config.formItems">
32
31
  <el-col :span="item.span || 24"
33
32
  v-if="!hideHandle(item)">
34
- <FormItem :item="item"
33
+ <ViewItem v-if="isView"
34
+ :item="item"
35
35
  :form="form"
36
36
  :index="index">
37
37
  <!-- 没有组件是component值 就是插槽名称 -->
38
- <template v-if="!['input', 'upload', 'checkbox', 'checkboxGroup', 'switch', 'select', 'treeSelect', 'cascader', 'date', 'number', 'radio', 'color', 'rate', 'slider','tags'].includes(item.component)"
38
+ <template v-if="!['input', 'upload', 'checkbox', 'checkboxGroup', 'switch', 'select', 'treeSelect', 'cascader', 'date', 'number', 'radio', 'color', 'rate', 'slider','tags', 'divider'].includes(item.component)"
39
39
  v-slot:[item.component]>
40
40
  <slot :name="item.component"
41
41
  :itemCur="item"
@@ -44,10 +44,35 @@
44
44
  没有这个默认组件也未自定义插槽内容</el-tag>
45
45
  </slot>
46
46
  </template>
47
+ <template v-if="item?.options?.component"
48
+ v-slot:[item?.options?.component]>
49
+ <slot :name="item?.options?.component"></slot>
50
+ </template>
51
+
52
+ </ViewItem>
53
+ <FormItem v-else
54
+ :item="item"
55
+ :form="form"
56
+ :index="index">
57
+ <!-- 没有组件是component值 就是插槽名称 -->
58
+ <template v-if="!['input', 'upload', 'checkbox', 'checkboxGroup', 'switch', 'select', 'treeSelect', 'cascader', 'date', 'number', 'radio', 'color', 'rate', 'slider','tags', 'divider'].includes(item.component)"
59
+ v-slot:[item.component]>
60
+ <slot :name="item.component"
61
+ :itemCur="item"
62
+ :formCur="form">
63
+ <el-tag type="danger">[{{ item.component }}]
64
+ 没有这个默认组件也未自定义插槽内容</el-tag>
65
+ </slot>
66
+ </template>
67
+ <template v-if="item?.options?.component"
68
+ v-slot:[item?.options?.component]>
69
+ <slot :name="item?.options?.component"></slot>
70
+ </template>
47
71
  </FormItem>
48
72
  </el-col>
49
73
  </template>
50
- <el-col :span="24">
74
+ <el-col v-if="!isView"
75
+ :span="24">
51
76
  <el-form-item>
52
77
  <slot>
53
78
  <el-button type="primary"
@@ -61,9 +86,11 @@
61
86
 
62
87
  <script>
63
88
  import FormItem from './FormItem'
89
+ import ViewItem from './ViewItem'
64
90
  export default {
65
91
  components: {
66
- FormItem
92
+ FormItem,
93
+ ViewItem
67
94
  },
68
95
  props: {
69
96
  modelValue: { type: Object, default: () => { } },
@@ -223,6 +250,7 @@ export default {
223
250
  });
224
251
 
225
252
  delete obj[key]
253
+
226
254
  }
227
255
  return result;
228
256
  },
@@ -230,8 +258,13 @@ export default {
230
258
  //处理动态隐藏
231
259
  hideHandle(item) {
232
260
  if (typeof item?.hideHandle === 'string') {
233
- const func = new Function('form', `return ${item?.hideHandle.replace(/\$/g, "form")}`);
234
- return func(this.form);
261
+ try {
262
+ // 构造一个函数并执行,同时捕获潜在的异常
263
+ const func = new Function('form', `return ${item?.hideHandle.replace(/\$/g, "form")}`);
264
+ return func(this.form);
265
+ } catch (error) {
266
+ return false; // 或根据需求返回默认值
267
+ }
235
268
  } else if (typeof item?.hideHandle === 'boolean') {
236
269
  return item.hideHandle
237
270
  }
@@ -0,0 +1,61 @@
1
+ <template>
2
+ <span class="item-text"
3
+ :style="{width: textWidth}">
4
+ <!-- 根据加密状态显示加密或解密后的文本 -->
5
+ <span>{{ isEncrypted ? encryptedText : modelValue }}</span>
6
+ <!-- 切换加密/解密按钮 -->
7
+ <el-icon v-if="password"
8
+ class="primary"
9
+ @click="toggleEncryption"><el-icon-view /></el-icon>
10
+ </span>
11
+ </template>
12
+
13
+ <script>
14
+ export default {
15
+ props: {
16
+ modelValue: { type: String, default: '' }, // 传入的字符串
17
+ width: { type: String, default: '' },
18
+ password: { type: Boolean, default: false }, // 是否需要加密显示
19
+ },
20
+ data() {
21
+ return {
22
+ isEncrypted: this.password, // 根据传入的 password 值初始化加密状态
23
+ };
24
+ },
25
+ computed: {
26
+ encryptedText() {
27
+ // 将输入字符串加密成 *,长度与原字符串相同
28
+ return "*".repeat(this.modelValue.length);
29
+ },
30
+ textWidth() {
31
+ return this?.width ? `calc(100% - ${this.width} - 10px)` : "";
32
+ }
33
+ },
34
+ methods: {
35
+ toggleEncryption() {
36
+ // 切换加密和解密状态
37
+ this.isEncrypted = !this.isEncrypted;
38
+ // 如果是解密状态,可以更新父组件的值
39
+ if (!this.isEncrypted) {
40
+ this.$emit('update:modelValue', this.modelValue);
41
+ }
42
+ },
43
+ },
44
+ };
45
+ </script>
46
+ <style lang="scss" scoped>
47
+ .item-text {
48
+ display: inline-flex;
49
+ gap: 10px;
50
+ align-items: center;
51
+ span {
52
+ word-wrap: break-word;
53
+ word-break: break-all;
54
+ white-space: normal;
55
+ }
56
+ .primary{
57
+ cursor: pointer;
58
+ color: var(--el-color-primary);
59
+ }
60
+ }
61
+ </style>
@@ -324,13 +324,16 @@ export default {
324
324
  username: this.ruleForm.user,
325
325
  password: this.ruleForm.password,
326
326
  };
327
-
327
+ console.log(data)
328
328
  if (this.isEncryption) {
329
329
  const publicKey = await this.$api.auth.key()
330
- data = {
331
- username: this.encrypt(publicKey, this.ruleForm.user),
332
- password: this.encrypt(publicKey, this.ruleForm.password),
333
- };
330
+ console.log(publicKey)
331
+ if (publicKey) {
332
+ data = {
333
+ username: this.encrypt(publicKey, this.ruleForm.user),
334
+ password: this.encrypt(publicKey, this.ruleForm.password),
335
+ };
336
+ }
334
337
  }
335
338
 
336
339
  //获取token