ci-plus 1.4.3 → 1.4.4

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": "ci-plus",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "ci组件库",
5
5
  "main": "./index.ts",
6
6
  "scripts": {
@@ -14,7 +14,7 @@
14
14
 
15
15
  <script setup lang="ts">
16
16
  import { onMounted, nextTick, watch } from 'vue'
17
- import JsBarcode from 'jsbarcode' //'./jsbarcode.js' //'https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/+esm'
17
+ import JsBarcode from './jsbarcode.js' //'./jsbarcode.js' //'https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/+esm'
18
18
  interface Props {
19
19
  value: String // 条码文本
20
20
  type?: String // 类型
@@ -1,38 +1,52 @@
1
1
  <template>
2
- <div style="width: 100%">
3
- <el-select-v2
4
- :size="props.size ?? 'small'"
5
- placeholder="请选择"
6
- :model-value="props.modelValue"
7
- @update:model-value="(val) => emits('update:modelValue', val)"
8
- :options="temporary_options"
9
- @change="
10
- (val) =>
11
- emits('change', val, temporary_options.find((v) => v[props.prop.value] == val) ?? null)
12
- "
13
- filterable
14
- style="width: 100%"
15
- remote
16
- :remote-method="getOptions"
17
- :props="props.prop"
18
- :height="200"
19
- :disabled="props.disabled"
20
- :loading="select_loading"
21
- v-bind="$attrs"
22
- >
23
- <template #prefix>
24
- <span class="el-input-number__increase" @click.stop="openTable">
25
- <el-icon>
26
- <Operation />
27
- </el-icon>
28
- </span>
29
- </template>
30
- <template #loading>
31
- <svg class="circular" viewBox="0 0 50 50">
32
- <circle class="path" cx="25" cy="25" r="20" fill="none" />
33
- </svg>
34
- </template>
35
- </el-select-v2>
2
+ <div class="ll-vue-div">
3
+ <div style="display: flex; width: 100%">
4
+ <el-select-v2
5
+ :size="props.size ?? 'small'"
6
+ placeholder="请搜索"
7
+ :model-value="props.modelValue"
8
+ @update:model-value="(val: any) => emits('update:modelValue', val)"
9
+ :options="temporary_options"
10
+ @change="(val: string | string[]) => onSelectChange(val)"
11
+ filterable
12
+ remote
13
+ :remote-method="getOptions"
14
+ :props="props.prop"
15
+ :height="200"
16
+ :disabled="props.disabled"
17
+ :loading="select_loading"
18
+ v-bind="$attrs"
19
+ :multiple="props.mul"
20
+ :collapse-tags="props.mul"
21
+ collapse-tags-tooltip
22
+ popper-class="l-popper"
23
+ style="flex: 1"
24
+ >
25
+ <template #loading>
26
+ <svg class="circular" viewBox="0 0 50 50">
27
+ <circle class="path" cx="25" cy="25" r="20" fill="none" />
28
+ </svg>
29
+ </template>
30
+ <template #footer>
31
+ <div v-if="basic.footerShow">以上为选中数据,非全部选项,请远程搜索</div>
32
+ <div v-else>
33
+ <el-pagination
34
+ v-model:current-page="basic.s_page"
35
+ small
36
+ layout="prev, pager, next"
37
+ :pager-count="5"
38
+ :page-size="10"
39
+ :total="basic.s_count"
40
+ />
41
+ </div>
42
+ </template>
43
+ </el-select-v2>
44
+ <span class="l_increase" @click.stop="openTable">
45
+ <el-icon>
46
+ <Operation />
47
+ </el-icon>
48
+ </span>
49
+ </div>
36
50
  <el-dialog
37
51
  class="L-dialog"
38
52
  v-model="basic.is_dialogTable"
@@ -60,7 +74,7 @@
60
74
  </template>
61
75
  <el-button-group>
62
76
  <el-tooltip
63
- v-if="aim && chooseRow.length"
77
+ v-if="chooseRow.length"
64
78
  effect="dark"
65
79
  content="清空选项"
66
80
  placement="top-start"
@@ -75,7 +89,7 @@
75
89
  ></el-button>
76
90
  </el-tooltip>
77
91
  <el-tooltip
78
- v-if="chooseRow.length"
92
+ v-if="aim && chooseRow.length"
79
93
  effect="dark"
80
94
  :content="is_aim ? '取消查询' : '查询已选中信息'"
81
95
  placement="top-start"
@@ -92,8 +106,8 @@
92
106
  </el-col>
93
107
  <el-col v-else :span="16" class="flex">
94
108
  <el-tag v-if="props.modelValue && props.modelValue.length" closable @close="closeTag">
95
- {{ tagLabel }}</el-tag
96
- >
109
+ {{ tagLabel }}
110
+ </el-tag>
97
111
  </el-col>
98
112
  <el-col :span="8">
99
113
  <el-input
@@ -103,7 +117,7 @@
103
117
  @change="getTableData({}, true)"
104
118
  >
105
119
  <template #append>
106
- <el-button icon="Search" @click="getTableData({}, true)" />
120
+ <el-button :icon="Search" @click="getTableData({}, true)" />
107
121
  </template>
108
122
  </el-input>
109
123
  </el-col>
@@ -142,13 +156,17 @@
142
156
  @next-click="getTableData()"
143
157
  style="margin-top: 3px"
144
158
  />
159
+ <div>
160
+ <el-button @click="basic.is_dialogTable = false" style="float: right"> 关闭 </el-button>
161
+ </div>
145
162
  </div>
146
163
  </el-dialog>
147
164
  </div>
148
165
  </template>
149
166
 
150
167
  <script setup lang="ts">
151
- import { reactive, h, ref, onMounted, toRef, watch } from 'vue'
168
+ import { reactive, h, ref, onMounted, watch } from 'vue'
169
+ import { Operation, Search } from '@element-plus/icons-vue'
152
170
  import { ElMessage, ElTable } from 'element-plus'
153
171
  import axios from 'axios'
154
172
  import { SelectSuffix, Basic, AnyO } from './types'
@@ -162,13 +180,17 @@ const basic = reactive<Basic>({
162
180
  page: 1,
163
181
  limit: 30,
164
182
  count: 0,
183
+ s_page: 1,
184
+ s_count: 0,
165
185
  loading: false,
166
186
  is_dialogTable: false,
187
+ footerShow: false,
167
188
  search: ''
168
189
  })
169
190
  const select_loading = ref(false)
170
191
  const is_aim = ref(false)
171
192
  const tagLabel = ref('')
193
+ const filterkey = ref('')
172
194
  const tableData = ref<AnyO[]>([])
173
195
  const temporary_options = ref<AnyO[]>([])
174
196
  const chooseRow = ref<AnyO[]>([])
@@ -177,11 +199,19 @@ const tableRowColor = ({ row, rowIndex }: { row: AnyO; rowIndex: number }) => {
177
199
  return 'success-row'
178
200
  return ''
179
201
  }
202
+ watch(
203
+ () => basic.s_page,
204
+ () => {
205
+ getOptions(filterkey.value, true)
206
+ }
207
+ )
180
208
  const rowClick = (row: AnyO) => {
181
209
  if (!props.mul) {
210
+ temporary_options.value = [row]
211
+ basic.footerShow = true
212
+ tagLabel.value = row[props.prop.label]
182
213
  emits('update:modelValue', row[props.prop.value])
183
214
  emits('change', row[props.prop.value], row)
184
- tagLabel.value = row[props.prop.label]
185
215
  if (!props.isExist) basic.is_dialogTable = false
186
216
  } else {
187
217
  if (chooseRow.value.find((v) => v[props.prop.value] == row[props.prop.value]))
@@ -190,10 +220,28 @@ const rowClick = (row: AnyO) => {
190
220
  1
191
221
  )
192
222
  else chooseRow.value.push(row)
193
- // tableRef.value.toggleRowSelection(row, undefined)
194
223
  sendMulValue()
195
224
  }
196
225
  }
226
+ //下拉框选择
227
+ const onSelectChange = (val: string | string[]) => {
228
+ if (Array.isArray(val) && props.mul) {
229
+ let thisPageChooseRows = temporary_options.value.filter(
230
+ (v) => !v.disabled && val.some((k: string) => k == v[props.prop.value])
231
+ )
232
+ thisPageChooseRows.forEach((v) => {
233
+ if (!chooseRow.value.find((x) => x[props.prop.value] == v[props.prop.value])) {
234
+ chooseRow.value.push(v)
235
+ }
236
+ })
237
+ chooseRow.value = chooseRow.value.filter((v) =>
238
+ val.some((k: string) => k == v[props.prop.value])
239
+ )
240
+ emits('change', val, chooseRow.value)
241
+ } else {
242
+ emits('change', val, temporary_options.value.find((v) => v[props.prop.value] == val) ?? null)
243
+ }
244
+ }
197
245
  const closeTag = (row?: AnyO) => {
198
246
  if (!props.mul) {
199
247
  emits('update:modelValue', '')
@@ -213,29 +261,38 @@ const empty = () => {
213
261
  }
214
262
  const sendMulValue = () => {
215
263
  let values = chooseRow.value.map((v) => v[props.prop.value])
264
+ basic.footerShow = true
265
+ temporary_options.value = chooseRow.value
216
266
  emits('update:modelValue', values)
217
267
  emits('change', values, chooseRow.value)
218
268
  }
269
+ // const openTable = () => {
270
+ // basic.is_dialogTable = true
271
+ // if (!tableData.value.length) getTableData()
272
+ // let searchObj: AnyO = {}
273
+ // searchObj[props.searchKey ? props.searchKey : 'search'] = props.modelValue
274
+ // if (props.modelValue && props.modelValue.length)
275
+ // getAxios(props.where ? props.where : searchObj, true).then((res) => {
276
+ // if (res.code == 200 && res.data.length) {
277
+ // if (props.mul) chooseRow.value = res.data
278
+ // else tagLabel.value = res.data[0]?.[props.prop.label]
279
+ // } else {
280
+ // tagLabel.value = ''
281
+ // chooseRow.value = []
282
+ // }
283
+ // setCurrent()
284
+ // })
285
+ // else {
286
+ // tagLabel.value = ''
287
+ // chooseRow.value = []
288
+ // }
289
+ // }
219
290
  const openTable = () => {
220
291
  basic.is_dialogTable = true
221
292
  if (!tableData.value.length) getTableData()
222
- let searchObj: AnyO = {}
223
- searchObj[props.searchKey ? props.searchKey : 'search'] = props.modelValue
224
- if (props.modelValue && props.modelValue.length)
225
- getAxios(props.where ? props.where : searchObj, true).then((res) => {
226
- if (res.code == 200 && res.data.length) {
227
- if (props.mul) chooseRow.value = res.data
228
- else tagLabel.value = res.data[0]?.[props.prop.label]
229
- } else {
230
- tagLabel.value = ''
231
- chooseRow.value = []
232
- }
233
- setCurrent()
234
- })
235
- else {
236
- tagLabel.value = ''
237
- chooseRow.value = []
238
- }
293
+ else setCurrent(true)
294
+ otherChangeTo()
295
+ // temporary_options.value = chooseRow.value
239
296
  }
240
297
  const appointGet = () => {
241
298
  if (!is_aim.value) {
@@ -254,15 +311,16 @@ const getTableData = (obj = {}, page1 = false) => {
254
311
  setCurrent()
255
312
  })
256
313
  }
257
- const setCurrent = () => {
314
+ //单页数据
315
+ const setCurrent = (openTable?: boolean) => {
258
316
  if (props.mul) {
317
+ if (openTable) chooseRow.value = []
259
318
  let clickRows = tableData.value.filter((v) =>
260
319
  (props.modelValue || []).includes(v[props.prop.value])
261
320
  )
262
321
  clickRows.forEach((v) => {
263
322
  if (!chooseRow.value.find((x) => x[props.prop.value] == v[props.prop.value])) {
264
323
  chooseRow.value.push(v)
265
- // tableRef.value!.toggleRowSelection(v,true)
266
324
  }
267
325
  })
268
326
  } else {
@@ -297,15 +355,22 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
297
355
  })
298
356
  return data
299
357
  }
300
- const getOptions = (val: string) => {
301
- if (!val) return
358
+ const getOptions = (val: string, is_return = false) => {
359
+ // 5/28 解决如果先点击选择框然后点表格选择,无法展示下拉选项,需要初始化下拉数据
360
+ if (!val && !is_return) return
361
+ if (filterkey.value !== val) {
362
+ filterkey.value = val
363
+ basic.s_page = 1
364
+ }
365
+ basic.footerShow = false
302
366
  select_loading.value = true
303
367
  let searchObj: AnyO = {}
304
368
  searchObj[props.searchKey ? props.searchKey : 'search'] = val
305
369
  axios({
306
370
  ...props.axiosConfig,
307
371
  params: {
308
- page: 1,
372
+ page: basic.s_page,
373
+ limit: 10,
309
374
  ...searchObj,
310
375
  ...props.axiosConfig.params
311
376
  }
@@ -314,24 +379,65 @@ const getOptions = (val: string) => {
314
379
  let res = res_.data
315
380
  select_loading.value = false
316
381
  if (res.code !== 200) return ElMessage.warning(res.msg)
382
+ basic.s_count = res.count ?? res.data.length
317
383
  if (props.getData) temporary_options.value = props.getData(res.data) || []
318
384
  else temporary_options.value = res.data || []
319
- temporary_options.value = res.data
385
+ if (props.mul) {
386
+ let ohterPageChoose = chooseRow.value.filter(
387
+ (v) => !temporary_options.value.some((x) => x[props.prop.value] == v[props.prop.value])
388
+ )
389
+ ohterPageChoose.forEach((v) => (v.disabled = true))
390
+ temporary_options.value.push(...ohterPageChoose)
391
+ }
320
392
  })
321
393
  .catch((err) => {
322
394
  select_loading.value = false
323
395
  ElMessage.error(err.code)
324
396
  })
325
397
  }
398
+ const otherChangeTo = () => {
399
+ let searchObj: AnyO = {}
400
+ searchObj[props.searchKey ? props.searchKey : 'search'] = props.mul
401
+ ? JSON.stringify(props.modelValue)
402
+ : props.modelValue
403
+ if (props.modelValue && props.modelValue.length)
404
+ getAxios(props.where ? props.where : searchObj, true).then((res) => {
405
+ if (res.code == 200 && res.data.length) {
406
+ if (!props.mul) tagLabel.value = res.data[0]?.[props.prop.label]
407
+ temporary_options.value = res.data
408
+ basic.footerShow = true
409
+ } else {
410
+ tagLabel.value = ''
411
+ chooseRow.value = []
412
+ }
413
+ })
414
+ else {
415
+ tagLabel.value = ''
416
+ chooseRow.value = []
417
+ }
418
+ }
419
+ onMounted(() => {
420
+ if (!props.modelValue) getOptions('', true)
421
+ else otherChangeTo()
422
+ })
423
+ defineExpose({ otherChangeTo })
326
424
  </script>
327
425
 
328
426
  <style lang="scss">
427
+ .el-table .success-row {
428
+ --el-table-tr-bg-color: #cdedff;
429
+ }
430
+
329
431
  .L-dialog {
330
432
  .flex {
331
433
  display: flex;
332
434
  align-items: center;
333
435
  }
334
436
 
437
+ .el-dialog__body {
438
+ height: calc(100% - 27px);
439
+ }
440
+
335
441
  .el-table__body tr.current-row > td.el-table__cell {
336
442
  background-color: #bbe7ff !important;
337
443
  }
@@ -342,8 +448,33 @@ const getOptions = (val: string) => {
342
448
  }
343
449
  }
344
450
 
345
- .el-table .success-row {
346
- --el-table-tr-bg-color: #cdedff;
451
+ .ll-vue-div {
452
+ width: 100%;
453
+ }
454
+
455
+ .l_increase {
456
+ align-items: center;
457
+ background: var(--el-fill-color-light);
458
+ color: var(--el-text-color-regular);
459
+ box-shadow: 0 0 0 1px var(--el-border-color) inset;
460
+ border-top-right-radius: var(--el-border-radius-base);
461
+ border-bottom-right-radius: var(--el-border-radius-base);
462
+ cursor: pointer;
463
+ display: flex;
464
+ font-size: 13px;
465
+ height: auto;
466
+ justify-content: center;
467
+ -webkit-user-select: none;
468
+ -moz-user-select: none;
469
+ -ms-user-select: none;
470
+ user-select: none;
471
+ width: 32px;
472
+ z-index: 1;
473
+ }
474
+
475
+ .el-select__wrapper {
476
+ border-top-right-radius: unset;
477
+ border-bottom-right-radius: unset;
347
478
  }
348
479
 
349
480
  .circular {
@@ -362,4 +493,20 @@ const getOptions = (val: string) => {
362
493
  stroke: var(--el-color-primary);
363
494
  stroke-linecap: round;
364
495
  }
496
+
497
+ .el-select-dropdown__list.el-vl__window {
498
+ min-width: 200px;
499
+ }
500
+
501
+ .el-select-dropdown {
502
+ min-width: 200px;
503
+ }
504
+
505
+ .l-popper {
506
+ min-width: 200px;
507
+ }
508
+
509
+ .el-select-dropdown__footer {
510
+ padding: 3px;
511
+ }
365
512
  </style>
@@ -3,44 +3,76 @@ import { TableColumnInstance, ColumnCls } from 'element-plus'
3
3
  import { AxiosRequestConfig } from 'axios';
4
4
  export type Props<T> = Partial<Omit<T, `$${string}` | `_${string}` | '$' | '_'>>
5
5
  export interface Scope<T> {
6
- row: T,
7
- $index: number,
8
- column: ColumnCls<T>
6
+ row: T,
7
+ $index: number,
8
+ column: ColumnCls<T>
9
9
  }
10
10
  export interface AnyO {
11
- [key: string]: any
11
+ [key: string]: any
12
12
  }
13
13
  export interface SelectColumn {
14
- col: Props<TableColumnInstance>
15
- scope?(props: any): string
16
- component?: (createVNode: typeof h, data: Scope<any>) => ComponentIns
14
+ col: Props<TableColumnInstance>
15
+ scope?(props: any): string
16
+ component?: (createVNode: typeof h, data: Scope<any>) => ComponentIns
17
17
  }
18
18
  export interface SelectSuffix {
19
- title?: string //弹出层标题
20
- modelValue?: string | string[] //下拉框value
21
- columns: SelectColumn[] // 表格列配置
22
- mul?: boolean //多选
23
- aim?: boolean
24
- disabled?: boolean
25
- size?: "" | "default" | "small" | "large"
26
- prop: { //下拉框字段
27
- label: string
28
- value: string
29
- }
30
- where?: { //弹出层打开需要展示Label的请求的params
31
- [key: string]: string
32
- }
33
- axiosConfig: AxiosRequestConfig //Axios请求配置
34
- isExist?: boolean // 是否选中关闭,单选默认true,多选默认false
35
- searchKey?: string // 模糊搜索字段,默认search,
36
- // selectConfig?:Props<ISelectV2Props>
37
- getData?: (params: any) => any[] // 获取数据的方法::getData="(data: any) => data.data"
19
+ title?: string //弹出层标题
20
+ modelValue?: string | string[] //下拉框value
21
+ columns: SelectColumn[] // 表格列配置
22
+ mul?: boolean //多选
23
+ aim?: boolean
24
+ disabled?: boolean
25
+ size?: "" | "default" | "small" | "large"
26
+ prop: { //下拉框字段
27
+ label: string
28
+ value: string
29
+ }
30
+ where?: { //弹出层打开需要展示Label的请求的params
31
+ [key: string]: any
32
+ }
33
+ axiosConfig: AxiosRequestConfig //Axios请求配置
34
+ isExist?: boolean // 是否选中关闭,单选默认true,多选默认false
35
+ searchKey?: string // 模糊搜索字段,默认search,
36
+ onChange?: (value: string, row: AnyO) => void
37
+ // selectConfig?:Props<ISelectV2Props>
38
+ getData?: (params: any) => any[] // 获取数据的方法::getData="(data: any) => data.data"
38
39
  }
39
40
  export interface Basic {
40
- page: number
41
- limit: number
42
- count: number
43
- is_dialogTable: boolean
44
- loading: boolean
45
- search: string
41
+ page: number
42
+ limit: number
43
+ count: number
44
+ s_page: number
45
+ s_count: number
46
+ is_dialogTable: boolean
47
+ loading: boolean
48
+ footerShow: boolean
49
+ search: string
50
+ }
51
+ type FormListBase = {
52
+ name: string
53
+ label: string
54
+ col?: number
55
+ type?: string
56
+ hide?: { judgment: string, value: any }[]
57
+ mul?: boolean
58
+ range?: boolean
59
+ sub?: string[]
60
+ listen?: (val: any) => any
61
+ }
62
+ type no_select = { sign: 1 | 4 }
63
+ type is_select = {
64
+ sign: 3
65
+ select?: { url: string, pName: string, sign?: number, where?: object }
66
+ options?: {
67
+ label: string
68
+ value: number
69
+ [propName: string]: any
70
+ }[]
71
+ }
72
+ type is_suffix = {
73
+ sign: 2,
74
+ whereKey?: string
75
+ suffixConfig: SelectSuffix
46
76
  }
77
+
78
+ export type FormList = FormListBase & (no_select | is_select | is_suffix)