@xuekl/cli-components 1.8.0 → 1.9.145

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/XklForm.vue CHANGED
@@ -1,58 +1,101 @@
1
1
  <template>
2
- <el-form ref="XklFormRef" :model="form" :label-width="opts.labelWidth" v-bind="formProps"
2
+ <el-form ref="XklFormRef" :model="form" :label-width="labelWidth()" v-bind="formProps"
3
3
  @keyup.enter.native="enterSubmit()">
4
4
  <div class="hide-input">
5
- <input type="text" />
6
- <input type="password" />
5
+ <el-input></el-input>
6
+ </div>
7
+ <div v-if="table" class="history-link">
8
+
9
+ <div class="save-handle">
10
+ <div class="save-tip" v-if="!isDoSave && !isDoHistory">
11
+ <div>
12
+ 您可以<el-link type="primary" class="ml-4 mr-4 " @click="toSave()">保存</el-link>当前查询条件,并可以在 <el-link
13
+ type="success" class="ml-4 mr-4" @click="toHistory()">历史记录</el-link>中查看以便于快捷查询。
14
+ </div>
15
+ <div v-if="attrs.onAdvanced">
16
+ <span>或者在 <el-link class="ml-4 mr-4" type="danger"
17
+ @click="advancedQuery()">高级查询</el-link>中定制查询条件。</span>
18
+ </div>
19
+ </div>
20
+ <div v-if="isDoSave" class="do_save">
21
+ <el-link class="mr-10 fs-18" @click="back()"><icon-svg name="back"></icon-svg></el-link>
22
+ <el-input class="w-200" v-model="queryName" :maxlength="20" placeholder="命名当前查询条件" size="small"
23
+ clearable></el-input>
24
+ <el-link type="primary" class="ml-10" @click="doSave()">保存</el-link>
25
+ </div>
26
+ <div v-if="isDoHistory" class="do_save">
27
+ <el-link class="mr-10 fs-18" @click="back()"><icon-svg name="back"></icon-svg></el-link>
28
+ <div v-if="isToDelete" class="history-list">
29
+ <span class="delete-item" :title="item.label" v-for="item in histories"
30
+ @click="deleteHistory(item)">{{ item.label }}</span>
31
+ </div>
32
+ <xkl-select style="width: 2rem!important;" v-else v-model="historyId" placeholder="选择一条历史记录"
33
+ :config="historySelectConfig" :cache="false" size="small" @item-change="doHistory"
34
+ @loaded="historyLoaded"></xkl-select>
35
+ <el-link v-if="!isToDelete" class="ml-10 fs-14" @click="toDelete()"><icon-svg
36
+ name="delete"></icon-svg></el-link>
37
+ </div>
38
+ </div>
7
39
  </div>
8
40
  <el-row>
9
41
  <template v-for="item in formList" :key="item.prop">
10
42
  <el-col :span="item.span" v-if="item.show()">
11
- <el-form-item :label="item.label" :label-width="item.labelWidth" :prop="item.prop"
43
+ <el-form-item :label="item.label" :label-width="labelWidth(item)" :prop="item.prop"
12
44
  :rules="item.refRules">
13
- <el-input v-if="item.type === 'input'" v-model="form[item.prop]" v-bind="item.element"
14
- v-on="item.events" :disabled="item.disabled()"></el-input>
15
- <el-input-number v-else-if="item.type === 'input-number'" v-model="form[item.prop]"
16
- v-bind="item.element" v-on="item.events" :disabled="item.disabled()"
17
- style="width: 100%;"></el-input-number>
18
- <el-input v-else-if="item.type === 'textarea'" v-model="form[item.prop]" v-bind="item.element"
19
- :disabled="item.disabled()" v-on="item.events" type="textarea"></el-input>
20
- <XklSelect v-else-if="item.type === 'select'" v-model="form[item.prop]"
21
- v-model:label="form[item.prop + 'Label']" :list="item.list" :config="{}" v-bind="item.element"
22
- v-on="item.events" :disabled="item.disabled()">
23
- </XklSelect>
24
- <XklDict v-else-if="item.type === 'dict-select'" v-model="form[item.prop]"
25
- v-model:label="form[item.prop + 'Label']" :config="item.config" v-bind="item.element"
26
- v-on="item.events" :disabled="item.disabled()"></XklDict>
27
- <XklSelect v-else-if="item.type === 'url-select'" v-model="form[item.prop]" :key="item.key()"
28
- v-model:label="form[item.prop + 'Label']" :config="item.config" v-bind="item.element"
29
- v-on="item.events" :disabled="item.disabled()">
30
- </XklSelect>
31
- <XklTreeSelect v-else-if="item.type === 'tree-select'" v-model="form[item.prop]"
32
- :config="item.config" v-bind="item.element" v-on="item.events" :disabled="item.disabled()">
33
- </XklTreeSelect>
34
- <el-radio-group v-else-if="item.type === 'radio'" v-model="form[item.prop]" v-bind="item.element"
35
- v-on="item.events" :disabled="item.disabled()">
36
- <el-radio v-for="ra in item.list" :label="ra.value" :key="ra.value">{{ ra.label }}</el-radio>
37
- </el-radio-group>
38
- <el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="form[item.prop]"
39
- v-bind="item.element" v-on="item.events" :disabled="item.disabled()">
40
- <el-checkbox v-for="ch in item.list" :label="ch.value" :key="ch.value">{{ ch.label
41
- }}</el-checkbox>
42
- </el-checkbox-group>
43
- <XklDatePicker v-else-if="item.type === 'date-picker'" v-model="form[item.prop]"
44
- v-bind="item.element" v-on="item.events" style="width: 100%;"></XklDatePicker>
45
- <XklUpload v-else-if="item.type === 'upload'" :key="form[item.prop].length > 0"
46
- v-model="form[item.prop]" :config="item.config" v-bind="item.element" v-on="item.events">
47
- </XklUpload>
48
- <slot v-else :name="item.prop"></slot>
45
+ <div class="xkl-item-inner">
46
+ <el-input v-if="item.type === 'input'" v-model="form[item.prop]" v-bind="item.element"
47
+ v-on="item.events" :disabled="item.disabled()"></el-input>
48
+ <el-input-number v-else-if="item.type === 'input-number'" v-model="form[item.prop]"
49
+ v-bind="item.element" v-on="item.events" :disabled="item.disabled()"
50
+ style="width: 100%;"></el-input-number>
51
+ <el-input v-else-if="item.type === 'textarea'" v-model="form[item.prop]"
52
+ v-bind="item.element" :disabled="item.disabled()" v-on="item.events"
53
+ type="textarea"></el-input>
54
+ <XklSelect v-else-if="item.type === 'select'" v-model="form[item.prop]"
55
+ v-model:label="form[item.prop + 'Label']" :list="item.list" :config="{}"
56
+ v-bind="item.element" v-on="item.events" :disabled="item.disabled()">
57
+ </XklSelect>
58
+ <XklDict v-else-if="item.type === 'dict-select'" v-model="form[item.prop]"
59
+ v-model:label="form[item.prop + 'Label']" :config="item.config" v-bind="item.element"
60
+ v-on="item.events" :disabled="item.disabled()"></XklDict>
61
+ <XklSelect v-else-if="item.type === 'url-select'" v-model="form[item.prop]"
62
+ :key="item.key()" v-model:label="form[item.prop + 'Label']" :config="item.config"
63
+ v-bind="item.element" v-on="item.events" :disabled="item.disabled()">
64
+ </XklSelect>
65
+ <XklTreeSelect v-else-if="item.type === 'tree-select'" v-model="form[item.prop]"
66
+ :config="item.config" v-bind="item.element" v-on="item.events"
67
+ :disabled="item.disabled()">
68
+ </XklTreeSelect>
69
+ <el-radio-group v-else-if="item.type === 'radio'" v-model="form[item.prop]"
70
+ v-bind="item.element" v-on="item.events" :disabled="item.disabled()">
71
+ <el-radio v-for="ra in item.list" :label="ra.value" :key="ra.value">{{ ra.label
72
+ }}</el-radio>
73
+ </el-radio-group>
74
+ <el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="form[item.prop]"
75
+ v-bind="item.element" v-on="item.events" :disabled="item.disabled()">
76
+ <el-checkbox v-for="ch in item.list" :label="ch.value" :key="ch.value">{{ ch.label
77
+ }}</el-checkbox>
78
+ </el-checkbox-group>
79
+ <XklDatePicker v-else-if="item.type === 'date-picker'" v-model="form[item.prop]"
80
+ v-bind="item.element" v-on="item.events" style="width: 100%;"
81
+ :disabled="item.disabled()">
82
+ </XklDatePicker>
83
+ <XklUpload v-else-if="item.type === 'upload'" :key="form[item.prop].length > 0"
84
+ v-model="form[item.prop]" :config="item.config" v-bind="item.element"
85
+ v-on="item.events">
86
+ </XklUpload>
87
+ <slot v-else :name="item.prop"></slot>
88
+ <slot :name="item.prop + 'Suffix'"></slot>
89
+ </div>
49
90
  </el-form-item>
50
91
  </el-col>
51
92
  </template>
52
- <el-col :span="searchSpan">
93
+ <el-col v-if="opts.queryVisible !== false" :span="searchSpan">
53
94
  <el-form-item label-width="0">
54
95
  <div class="query-action">
55
- <slot name="_action"></slot>
96
+ <div @click.capture="actionClick()">
97
+ <slot name="_action"></slot>
98
+ </div>
56
99
  <span class="collapsible" v-if="opts.collapsible" @click="doCollapse()">
57
100
  {{ isCollapse ? '展开' : '收起' }}
58
101
  <icon-svg name="down" :class="[isCollapse ? '' : 'rotate']"></icon-svg>
@@ -61,6 +104,9 @@
61
104
  </el-form-item>
62
105
  </el-col>
63
106
  </el-row>
107
+ <AdvancedQuery ref="advancedQueryRef" v-if="advanceQueryShow" :form="form" :table="table"
108
+ @advanced="advancedHandle" @reset="resetHandle">
109
+ </AdvancedQuery>
64
110
  </el-form>
65
111
  </template>
66
112
  <script lang="ts">
@@ -71,33 +117,60 @@ export default {
71
117
  <script setup lang="ts">
72
118
  import { setUpperFirst } from '@xuekl/cli-utils'
73
119
  import { FormItem } from '@xuekl/cli-base/type.d'
74
- import { ref, watch, onMounted, Ref } from 'vue'
120
+ import { ref, watch, onMounted, Ref, computed, shallowRef, DefineComponent, defineComponent, h, nextTick, useAttrs, onBeforeUnmount, onUnmounted } from 'vue'
121
+ import { useRoute } from 'vue-router'
75
122
  import XklSelect from './XklSelect.vue'
76
123
  import XklTreeSelect from './XklTreeSelect.vue'
77
124
  import XklDict from './XklDict.vue'
78
125
  import XklDatePicker from './XklDatePicker.vue'
79
126
  import { formConf } from './index'
127
+ import http from '@/utils/httpRequest'
128
+ import { ElMessage } from 'element-plus'
129
+ const startLoading = window.startLoading
130
+ const finishLoading = window.finishLoading
80
131
 
81
- const props = defineProps(['form'])
132
+ const props = defineProps(['form', 'table'])
82
133
  const emit = defineEmits(['enter'])
134
+ const attrs: any = useAttrs()
135
+ const route = useRoute()
83
136
  const XklFormRef = ref(null)
84
- const { form } = props
137
+ const { form, table } = props
85
138
  const sourceFormList: FormItem[] = []
86
139
  const formList: Ref<FormItem[]> = ref([])
87
140
  const opts = form._opts || {}
88
141
  const isCollapse = ref(true)
142
+ let isByAdvanced = false // 通过高级查询
143
+ let conditionItemList: any[] = [] // 通过高级查询
89
144
  if (typeof opts.defaultCollapse !== 'undefined') {
90
145
  isCollapse.value = opts.defaultCollapse
91
146
  }
147
+ const formConfig = formConf || {} as any
148
+ const formProps = Object.assign({}, formConfig.element, opts.element)
149
+
150
+ form._isAlive = true
151
+
152
+ const labelWidth = computed(() => {
153
+ const docEl = document.documentElement
154
+ const width = docEl.getBoundingClientRect().width;
155
+ const rem = width / 10;
156
+ return (item?) => {
157
+ if (item && item.labelWidth) {
158
+ return ((item.labelWidth / rem) * (rem / 100)) + 'rem'
159
+ }
160
+ return ((opts.labelWidth / rem) * (rem / 100)) + 'rem'
161
+ }
162
+ })
92
163
 
93
- const formProps = Object.assign({}, formConf?.element, opts.element)
94
164
 
95
165
  const enterSubmit = () => {
96
166
  emit('enter')
97
167
  }
98
168
  // 获取符合mode的字段
99
- const modeFields: any = {}
100
- Object.keys(form).forEach(prop => {
169
+ let modeFields: any = {}
170
+ form._sort = form._sort || []
171
+ let formKeys = Object.keys(form)
172
+ formKeys = [...form._sort, ...formKeys.filter(key => !form._sort.includes(key))]
173
+ formKeys.forEach(prop => {
101
174
  if (form['get' + setUpperFirst(prop)]) {
102
175
  let field: FormItem = form['get' + setUpperFirst(prop)]()
103
176
  if (['query', 'search'].includes(opts.mode)) {
@@ -113,12 +186,13 @@ Object.keys(form).forEach(prop => {
113
186
  field.key = field.key || (() => prop)
114
187
  field.disabled = field.disabled || (() => false)
115
188
  const placeholderStart = ['input', 'textarea'].includes(field.type) ? '请输入' : '请选择'
189
+ const placeholder = placeholderStart + field.label.replace(':', '').replace(':', '')
116
190
  if (!['query', 'search'].includes(opts.mode)) {
117
191
  if (field.required) {
118
192
  // 如果穿了required函数监听required的变化
119
193
  watch(field.required, (val) => {
120
194
  if (val) {
121
- field.refRules.value.push({ required: true, message: placeholderStart + field.label, trigger: 'blur' })
195
+ field.refRules.value.push({ required: true, message: placeholder, trigger: 'blur' })
122
196
  } else {
123
197
  field.refRules.value = field.refRules.value.filter(res => !res.required)
124
198
  }
@@ -126,21 +200,21 @@ Object.keys(form).forEach(prop => {
126
200
  }
127
201
  field.required = field.required || (() => false)
128
202
  if (field.required()) {
129
- field.refRules.value.push({ required: true, message: placeholderStart + field.label, trigger: 'blur' })
203
+ field.refRules.value.push({ required: true, message: placeholder, trigger: 'blur' })
130
204
  }
131
205
  } else {
132
206
  field.refRules.value = field.refRules.value.filter(res => !res.required)
133
207
  }
134
208
  if (!field.element) {
135
209
  field.element = {
136
- placeholder: placeholderStart + field.label.replace(':', '').replace(':', ''),
210
+ placeholder: placeholder,
137
211
  clearable: true
138
212
  }
139
213
  if (opts.placeholder === false) {
140
214
  field.element.placeholder = ''
141
215
  }
142
216
  } else {
143
- field.element.placeholder = field.element.placeholder || placeholderStart + field.label.replace(':', '').replace(':', '')
217
+ field.element.placeholder = field.element.placeholder || placeholder
144
218
  field.element.clearable = typeof field.element.clearable === 'undefined' ? true : field.element.clearable
145
219
  if (opts.placeholder === false) {
146
220
  field.element.placeholder = ''
@@ -223,6 +297,9 @@ if (opts.collapsible) {
223
297
  }
224
298
 
225
299
 
300
+ const actionClick = () => {
301
+ isByAdvanced = false
302
+ }
226
303
 
227
304
  const doCollapse = () => {
228
305
  isCollapse.value = !isCollapse.value
@@ -248,9 +325,15 @@ const regProto = () => {
248
325
  });
249
326
  (XklFormRef.value as any).validate((valid: boolean) => {
250
327
  if (valid) {
328
+ if (form.enableLoading && startLoading) {
329
+ startLoading()
330
+ }
251
331
  callback(() => {
252
332
  setTimeout(() => {
253
333
  enableSubmit = true
334
+ if (finishLoading) {
335
+ finishLoading()
336
+ }
254
337
  }, 300)
255
338
  }, modeFields)
256
339
  } else {
@@ -261,21 +344,219 @@ const regProto = () => {
261
344
  }
262
345
  }
263
346
 
264
- form.getBinds = () => {
265
- sourceFormList.forEach(field => {
266
- modeFields[field.prop] = (form as any)[field.prop]
267
- });
347
+ form.getBinds = (extraForBinds: Object = {}, forAdvanced: string[] = []) => {
348
+ modeFields = {}
349
+ let forBinds: any = {}
350
+ if (isByAdvanced) {
351
+ if (forAdvanced.length) {
352
+ forAdvanced.forEach(key => {
353
+ // 如果高级查询列表中,不存在对应需要补充的键值,才可进行补充
354
+ const conditionItem: any = conditionItemList.find(res => res.field
355
+ && ((res.field.includes(key) || key.includes(res.field))
356
+ || (res.field.includes('logOperationOrg') && key.includes('logOperationOrg')))
357
+ && ['in', 'eq'].includes(res.regulation))
358
+ if (!conditionItem) {
359
+ if (extraForBinds.hasOwnProperty(key)) {
360
+ forBinds[key] = extraForBinds[key]
361
+ } else {
362
+ forBinds[key] = (form as any)[key]
363
+ }
364
+ } else {
365
+ if (Array.isArray((form as any)[key])) {
366
+ if (conditionItem.multipleValue.length) {
367
+ forBinds[key] = conditionItem.multipleValue
368
+ } else {
369
+ forBinds[key] = [conditionItem.fieldValue1]
370
+ }
371
+
372
+ } else {
373
+ if (conditionItem.multipleValue.length) {
374
+ forBinds[key] = conditionItem.multipleValue[0]
375
+ } else {
376
+ forBinds[key] = conditionItem.fieldValue1
377
+ }
378
+ }
379
+ }
380
+ })
381
+ } else {
382
+ forBinds = extraForBinds
383
+ }
384
+ modeFields.conditionItemList = conditionItemList
385
+ } else {
386
+ forBinds = extraForBinds
387
+ sourceFormList.forEach(field => {
388
+ modeFields[field.prop] = (form as any)[field.prop]
389
+ });
390
+ }
391
+ Object.assign(modeFields, forBinds)
268
392
  return modeFields
269
393
  }
270
394
 
271
395
  form.getRef = () => XklFormRef.value
272
396
  }
273
397
 
398
+ const queryName = ref('')
399
+ const historyId = ref('')
400
+ const histories: any = ref([])
401
+ const isDoSave = ref(false)
402
+ const isDoHistory = ref(false)
403
+ const isToDelete = ref(false)
404
+ const queryCondition = ref({})
405
+
406
+ const historySelectConfig = ref({
407
+ url: formConfig.historyApi.query || '/base/mgt/queryMemory/queryMemorySelector',
408
+ // valueTarget: 'expandField1',
409
+ params: () => ({
410
+ pageId: route.name,
411
+ tableId: table.id
412
+ })
413
+ })
414
+
415
+ const toSave = () => {
416
+ isDoSave.value = true
417
+ }
418
+ const doSave = () => {
419
+ if (!props.table) {
420
+ ElMessage.warning("请绑定一个被查询的表格")
421
+ return
422
+ }
423
+ if (!queryName.value) {
424
+ ElMessage.warning("请输入名称")
425
+ return
426
+ }
427
+ http({
428
+ url: http.adornUrl(formConfig.historyApi.add || '/base/mgt/queryMemory/add'),
429
+ method: 'post',
430
+ data: http.adornData({
431
+ pageId: route.name,
432
+ tableId: table.id,
433
+ queryName: queryName.value,
434
+ queryCondition: JSON.stringify(form.getBinds())
435
+ })
436
+ }).then(({ data }) => {
437
+ if (data.code === '0') {
438
+ isDoSave.value = false
439
+ queryName.value = ''
440
+ ElMessage.success("保存成功")
441
+ } else {
442
+ ElMessage.error(data.message)
443
+ }
444
+ })
445
+ }
446
+
447
+ const historyLoaded = (list) => {
448
+ histories.value = list
449
+ }
450
+
451
+ const toHistory = () => {
452
+ isDoHistory.value = true
453
+ }
454
+
455
+ const doHistory = (item) => {
456
+ if (item) {
457
+ queryCondition.value = JSON.parse(item.expandField1)
458
+ form.setForm(queryCondition.value)
459
+ } else {
460
+ form.clear()
461
+ }
462
+ }
463
+
464
+ const toDelete = () => {
465
+ if (!histories.value.length) {
466
+ ElMessage.warning("暂无历史记录")
467
+ return
468
+ }
469
+ isToDelete.value = true
470
+ }
471
+
472
+ const deleteHistory = (item) => {
473
+ http({
474
+ url: http.adornUrl(`${formConfig.historyApi.delete || '/base/mgt/queryMemory/deleteByIds'}/${item.value}`),
475
+ method: 'get',
476
+ params: http.adornParams({
477
+ })
478
+ }).then(({ data }) => {
479
+ if (data.code === '0') {
480
+ histories.value = histories.value.filter(res => res.value !== item.value)
481
+ if (historyId.value === item.value) {
482
+ historyId.value = ''
483
+ }
484
+ if (!histories.value.length) {
485
+ back()
486
+ }
487
+ ElMessage.success("删除成功")
488
+ } else {
489
+ ElMessage.error(data.message)
490
+ }
491
+ })
492
+ }
493
+
494
+ const back = () => {
495
+ if (isToDelete.value) {
496
+ isToDelete.value = false
497
+ return
498
+ }
499
+ isDoSave.value = false
500
+ isDoHistory.value = false
501
+ historyId.value = ''
502
+ }
503
+
504
+ let clear = form.clear.bind(form)
505
+
506
+ form.clear = () => {
507
+ // if (!isByAdvanced) {
508
+
509
+ clear()
510
+ historyId.value = ''
511
+ // }
512
+ // modeFields.conditionItemList = []
513
+ // advancedQueryRef.value?.resetData()
514
+ }
515
+
516
+ const advanceQueryShow = ref(false)
517
+ const advancedQueryRef = ref()
518
+
519
+ const advancedQuery = () => {
520
+ advanceQueryShow.value = true
521
+ nextTick(() => {
522
+ advancedQueryRef.value.init(form, table)
523
+ })
524
+ }
525
+
526
+ const advancedHandle = (conditions) => {
527
+ // modeFields.conditionItemList = conditions
528
+ // emit('advanced', conditions)
529
+ isByAdvanced = true
530
+ conditionItemList = conditions
531
+ attrs.onAdvanced(conditions)
532
+ //modeFields.conditionItemList = []
533
+ }
534
+
535
+ const resetHandle = (conditions) => {
536
+ // modeFields.conditionItemList = conditions
537
+ isByAdvanced = true
538
+ conditionItemList = conditions
539
+ attrs.onReset(conditions)
540
+ }
541
+
274
542
  onMounted(() => {
275
543
  regProto()
544
+ if (form.defaultAdvance) {
545
+ advanceQueryShow.value = true
546
+ nextTick(() => {
547
+ advancedQueryRef.value.useDefaultValues(form, table)
548
+ })
549
+ }
276
550
  })
277
551
 
278
-
552
+ onBeforeUnmount(() => {
553
+ form.clear = clear
554
+ form.submit = null
555
+ form.getRef = null
556
+ form._isAlive = false
557
+ // form.getBinds = null
558
+ // sourceFormList.length = 0
559
+ })
279
560
 
280
561
  </script>
281
562
  <style lang="scss" scoped>
@@ -301,4 +582,82 @@ onMounted(() => {
301
582
  position: absolute;
302
583
  left: -5000px;
303
584
  }
585
+
586
+ .xkl-item-inner {
587
+ width: 100%;
588
+ display: flex;
589
+ align-items: center;
590
+ }
591
+
592
+ .history-link {
593
+ display: flex;
594
+ justify-content: flex-end;
595
+ align-items: center;
596
+ // padding-bottom: 18px;
597
+ font-size: 14px;
598
+ color: #666;
599
+ min-height: 26px;
600
+ margin-bottom: 18px;
601
+
602
+ .do_save {
603
+ // width: 300px;
604
+ display: flex;
605
+ align-items: center;
606
+ }
607
+
608
+ .save-handle {
609
+ display: flex;
610
+ align-items: center;
611
+ }
612
+
613
+ .save-tip {
614
+ display: flex;
615
+ align-items: center;
616
+ flex-wrap: wrap;
617
+ justify-content: flex-end;
618
+ gap: 6px;
619
+ }
620
+ }
621
+
622
+ .history-list {
623
+ border: 1px solid #f0f2f5;
624
+ max-height: 100px;
625
+ overflow-y: auto;
626
+ padding: 5px;
627
+ // width: 300px;
628
+
629
+ .delete-item {
630
+ display: inline-block;
631
+ padding: 2px 5px;
632
+ background-color: #f0f2f5;
633
+ margin-right: 5px;
634
+ margin-bottom: 5px;
635
+ border-radius: 4px;
636
+ font-size: 12px;
637
+ cursor: pointer;
638
+ max-width: 200px;
639
+ text-overflow: ellipsis;
640
+ overflow: hidden;
641
+ white-space: nowrap;
642
+ position: relative;
643
+ padding-right: 22px;
644
+
645
+ &::after {
646
+ content: 'x';
647
+ display: inline-flex;
648
+ color: #909399;
649
+ height: 16px;
650
+ width: 16px;
651
+ border-radius: 8px;
652
+ font-size: 12px;
653
+ align-items: center;
654
+ justify-content: center;
655
+ margin-left: 5px;
656
+ position: absolute;
657
+ right: 0;
658
+ top: 50%;
659
+ transform: translateY(-50%);
660
+ }
661
+ }
662
+ }
304
663
  </style>