@jzt-packages/components 1.0.0

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.
Files changed (145) hide show
  1. package/package.json +68 -0
  2. package/src/JztBackTop/index.vue +255 -0
  3. package/src/JztButtonList/index.vue +88 -0
  4. package/src/JztChart/index.vue +95 -0
  5. package/src/JztCharts/index.vue +317 -0
  6. package/src/JztClassTabs/index.vue +156 -0
  7. package/src/JztDateSelect/dateSelect.vue +186 -0
  8. package/src/JztDateSelect/dateType.vue +54 -0
  9. package/src/JztDateSelect/index.ts +135 -0
  10. package/src/JztDateSelect/interface/index.ts +13 -0
  11. package/src/JztDialog/index.vue +249 -0
  12. package/src/JztEllipsisTooltip/index.vue +61 -0
  13. package/src/JztEmpty/index.vue +45 -0
  14. package/src/JztErrorPage/403.vue +30 -0
  15. package/src/JztErrorPage/404.vue +19 -0
  16. package/src/JztErrorPage/500.vue +18 -0
  17. package/src/JztErrorPage/assets/401.png +0 -0
  18. package/src/JztErrorPage/assets/403.png +0 -0
  19. package/src/JztErrorPage/assets/404.png +0 -0
  20. package/src/JztErrorPage/assets/500.png +0 -0
  21. package/src/JztErrorPage/index.scss +35 -0
  22. package/src/JztErrorPage/index.vue +35 -0
  23. package/src/JztFilePreview/components/pdfViewer.vue +221 -0
  24. package/src/JztFilePreview/hooks/useImageMethod.ts +256 -0
  25. package/src/JztFilePreview/index.scss +171 -0
  26. package/src/JztFilePreview/index.vue +68 -0
  27. package/src/JztFilePreview/interface/index.ts +18 -0
  28. package/src/JztFilePreview/previewFile.vue +371 -0
  29. package/src/JztFormGrid/README.md +520 -0
  30. package/src/JztFormGrid/components/formItem.vue +209 -0
  31. package/src/JztFormGrid/components/formItemValue.vue +384 -0
  32. package/src/JztFormGrid/components/showDetailForm.vue +172 -0
  33. package/src/JztFormGrid/index.scss +60 -0
  34. package/src/JztFormGrid/index.vue +513 -0
  35. package/src/JztFormGrid/interface/index.ts +106 -0
  36. package/src/JztGrid/components/GridItem.vue +68 -0
  37. package/src/JztGrid/index.vue +179 -0
  38. package/src/JztGrid/interface/index.ts +6 -0
  39. package/src/JztImportExcel/assets/delete.png +0 -0
  40. package/src/JztImportExcel/index.scss +46 -0
  41. package/src/JztImportExcel/index.vue +430 -0
  42. package/src/JztImportExcel/interface/index.ts +25 -0
  43. package/src/JztLabelTitle/index.vue +65 -0
  44. package/src/JztLeftRightMode/components/CollapseButton.vue +80 -0
  45. package/src/JztLeftRightMode/components/LeftCard.vue +203 -0
  46. package/src/JztLeftRightMode/components/LeftLayout.vue +173 -0
  47. package/src/JztLeftRightMode/components/RightHeader.vue +186 -0
  48. package/src/JztLeftRightMode/components/RightLayout.vue +235 -0
  49. package/src/JztLeftRightMode/components/RightTableHeader.vue +43 -0
  50. package/src/JztLeftRightMode/hooks/useCollapse.ts +17 -0
  51. package/src/JztLeftRightMode/hooks/useDefaultProps.ts +19 -0
  52. package/src/JztLeftRightMode/hooks/useLeftLayout.ts +201 -0
  53. package/src/JztLeftRightMode/hooks/useMode.ts +20 -0
  54. package/src/JztLeftRightMode/hooks/usePrevNext.ts +60 -0
  55. package/src/JztLeftRightMode/hooks/useRightLayout.ts +215 -0
  56. package/src/JztLeftRightMode/hooks/useSlots.ts +15 -0
  57. package/src/JztLeftRightMode/index.ts +3 -0
  58. package/src/JztLeftRightMode/index.vue +494 -0
  59. package/src/JztLeftRightMode/types/index.ts +457 -0
  60. package/src/JztLoading/fullScreen.ts +45 -0
  61. package/src/JztLoading/index.scss +67 -0
  62. package/src/JztLoading/index.vue +18 -0
  63. package/src/JztLogin/components/LoginFooter.vue +17 -0
  64. package/src/JztLogin/components/LoginForm.vue +99 -0
  65. package/src/JztLogin/hooks/useLogin.ts +186 -0
  66. package/src/JztLogin/index.scss +142 -0
  67. package/src/JztLogin/index.vue +31 -0
  68. package/src/JztLogin/interface/index.ts +47 -0
  69. package/src/JztNumericalRange/index.vue +81 -0
  70. package/src/JztPageCard/comm/datePicker.vue +151 -0
  71. package/src/JztPageCard/comm/details.vue +60 -0
  72. package/src/JztPageCard/comm/export.vue +24 -0
  73. package/src/JztPageCard/comm/tabs.vue +94 -0
  74. package/src/JztPageCard/comm/tooltip.vue +31 -0
  75. package/src/JztPageCard/index.vue +287 -0
  76. package/src/JztPagination/index.vue +70 -0
  77. package/src/JztProductInfo/components/imagePreview.vue +275 -0
  78. package/src/JztProductInfo/components/qxUnique.vue +101 -0
  79. package/src/JztProductInfo/components/records.vue +265 -0
  80. package/src/JztProductInfo/hooks/useParams.ts +143 -0
  81. package/src/JztProductInfo/hooks/useQxUnique.tsx +466 -0
  82. package/src/JztProductInfo/images/defaultProduct.png +0 -0
  83. package/src/JztProductInfo/index.ts +116 -0
  84. package/src/JztProductInfo/index.vue +108 -0
  85. package/src/JztProductInfo/interface/index.ts +15 -0
  86. package/src/JztQueryDetailTable/index.scss +100 -0
  87. package/src/JztQueryDetailTable/index.vue +400 -0
  88. package/src/JztQueryDetailTable/interface/index.ts +10 -0
  89. package/src/JztQueryTable/QueryTable /345/212/237/350/203/275.md" +1580 -0
  90. package/src/JztQueryTable/README.md +567 -0
  91. package/src/JztQueryTable/components/ColSetting.vue +67 -0
  92. package/src/JztQueryTable/components/ColumnsSetting.vue +404 -0
  93. package/src/JztQueryTable/components/ColumnsSetting1.vue +220 -0
  94. package/src/JztQueryTable/components/DeployToAccountLevelSetting.vue +351 -0
  95. package/src/JztQueryTable/components/Pagination.vue +54 -0
  96. package/src/JztQueryTable/components/TableColumn.vue +109 -0
  97. package/src/JztQueryTable/const.ts +1 -0
  98. package/src/JztQueryTable/hooks/useQueryTable.ts +194 -0
  99. package/src/JztQueryTable/hooks/useSelection.ts +47 -0
  100. package/src/JztQueryTable/hooks/useTableSetting.ts +197 -0
  101. package/src/JztQueryTable/hooks/useTemplate.ts +127 -0
  102. package/src/JztQueryTable/index.scss +91 -0
  103. package/src/JztQueryTable/index.vue +1445 -0
  104. package/src/JztQueryTable/interface/index.ts +185 -0
  105. package/src/JztRegionSelect/index.vue +134 -0
  106. package/src/JztSearchForm/components/SearchFormItem.vue +473 -0
  107. package/src/JztSearchForm/index.vue +530 -0
  108. package/src/JztSearchForm/interface/index.ts +100 -0
  109. package/src/JztSelectFilter/index.scss +63 -0
  110. package/src/JztSelectFilter/index.vue +110 -0
  111. package/src/JztSelectTable/index.vue +257 -0
  112. package/src/JztTable/index.scss +72 -0
  113. package/src/JztTable/index.vue +353 -0
  114. package/src/JztTable/interface/index.ts +1 -0
  115. package/src/JztTime/comm/agencySelect.vue +112 -0
  116. package/src/JztTime/comm/collapseRow.vue +132 -0
  117. package/src/JztTime/comm/dateSelect.vue +292 -0
  118. package/src/JztTime/comm/deptSelect.vue +193 -0
  119. package/src/JztTime/comm/typeSelect.vue +97 -0
  120. package/src/JztTime/index.ts +216 -0
  121. package/src/JztTime/index.vue +303 -0
  122. package/src/JztTime/interface/index.ts +23 -0
  123. package/src/JztTreeFilter/index.scss +44 -0
  124. package/src/JztTreeFilter/index.vue +177 -0
  125. package/src/JztUploadFile/interface/index.ts +21 -0
  126. package/src/JztUploadFile/multiple.scss +215 -0
  127. package/src/JztUploadFile/multiple.vue +318 -0
  128. package/src/JztUploadFile/single.scss +226 -0
  129. package/src/JztUploadFile/single.vue +274 -0
  130. package/src/JztUploadImg/Img.vue +294 -0
  131. package/src/JztUploadImg/Imgs.vue +411 -0
  132. package/src/JztUploadImg/index.scss +138 -0
  133. package/src/JztUploadImg/interface/index.ts +22 -0
  134. package/src/SelectIcon/index.scss +39 -0
  135. package/src/SelectIcon/index.vue +106 -0
  136. package/src/SvgIcon/index.vue +22 -0
  137. package/src/hooks/useAuthButtons.ts +58 -0
  138. package/src/hooks/useFormByUserType.ts +90 -0
  139. package/src/hooks/useTableEvents.ts +30 -0
  140. package/src/hooks/useUploadFileHook.ts +262 -0
  141. package/src/index.ts +91 -0
  142. package/src/typings/global.d.ts +101 -0
  143. package/src/utils/index.ts +107 -0
  144. package/src/utils/tree.ts +57 -0
  145. package/tsconfig.json +45 -0
@@ -0,0 +1,353 @@
1
+ <template>
2
+ <div :class="['spd-card jzt-table-card', isFullscreen ? 'fullscreen-page' : '', isFullHeight ? 'is-fullHeight' : '']">
3
+ <div class="table-header flx-between-center">
4
+ <div class="header-button-lf">
5
+ <slot name="headerButton">
6
+ <JztButtonList :buttonList="topList" @onClick="handleButtonClick" />
7
+ </slot>
8
+ </div>
9
+ <div v-if="toolButton" class="header-button-ri">
10
+ <slot name="toolButton">
11
+ <el-button
12
+ v-if="showToolButton('refresh')"
13
+ :icon="Refresh"
14
+ title="刷新"
15
+ class="tool_btn"
16
+ @click="onRefresh"
17
+ />
18
+ <el-button
19
+ v-if="showToolButton('fullScreen')"
20
+ :title="isFullscreen ? '退出全屏' : '全屏'"
21
+ class="tool_btn"
22
+ @click="isFullscreen = !isFullscreen"
23
+ >
24
+ <i :class="['iconfont', isFullscreen ? 'icon-shiyingchuangkou' : 'icon-manping']"></i>
25
+ </el-button>
26
+ <!-- <ColumnsSetting
27
+ v-if="showToolButton('setting') && tableColumns.length"
28
+ v-model:columns="tableColumns"
29
+ :column-types="columnTypes"
30
+ >
31
+ <template #reference>
32
+ <el-button title="列设置" :icon="Setting" class="tool_btn" />
33
+ </template>
34
+ </ColumnsSetting> -->
35
+ </slot>
36
+ </div>
37
+ </div>
38
+ <div class="table-content-box">
39
+ <el-table
40
+ ref="jztTableRef"
41
+ v-bind="$attrs"
42
+ :id="uuid"
43
+ :data="tableData"
44
+ :border="false"
45
+ :row-key="rowKey"
46
+ @selection-change="selectionChange"
47
+ @header-dragend="headerDragend"
48
+ :height="isFullscreen ? '100%' : tableHeight"
49
+ >
50
+ <!-- 默认插槽 -->
51
+ <slot />
52
+ <template v-for="(item, index) in selectColumns" :key="item">
53
+ <el-table-column
54
+ v-if="item.type && columnTypes.includes(item.type)"
55
+ v-bind="item"
56
+ :align="item.align ?? 'center'"
57
+ :reserve-selection="item.type == 'selection'"
58
+ >
59
+ <template #default="scope">
60
+ <template v-if="item.type == 'expand'">
61
+ <component :is="item.render" v-bind="scope" v-if="item.render" />
62
+ <slot v-else :name="item.type" v-bind="scope" />
63
+ </template>
64
+
65
+ <el-radio
66
+ v-if="item.type == 'radio'"
67
+ v-model="radio"
68
+ :name="'radio' + index"
69
+ :label="scope.row[rowKey]"
70
+ @change="radioChange(scope.row[rowKey], scope.row)"
71
+ >
72
+ <i></i>
73
+ </el-radio>
74
+
75
+ <el-tag v-if="item.type == 'sort'" class="move" size="small">
76
+ <el-icon><DCaret /></el-icon>
77
+ </el-tag>
78
+ </template>
79
+ </el-table-column>
80
+ </template>
81
+ <template v-for="item in tableColumns" :key="item">
82
+ <!-- other -->
83
+ <TableColumn v-if="item.prop !== 'operation'" :column="item">
84
+ <template v-for="slot in Object.keys($slots)" #[slot]="scope">
85
+ <slot :name="slot" v-bind="scope" />
86
+ </template>
87
+ </TableColumn>
88
+ <!-- 自定义表格操作列 -->
89
+ <el-table-column
90
+ v-else-if="item.prop === 'operation' && item.isShow"
91
+ v-bind="item"
92
+ :align="item.align ?? 'left'"
93
+ >
94
+ <template #default="{ row }">
95
+ <template v-for="(btnItem, index) in item.btnLList" :key="index">
96
+ <span v-if="(btnItem.hideFun ? !btnItem.hideFun(row) : true) && hasPermission(btnItem.hasPerm)">
97
+ <component v-if="btnItem.render" :is="btnItem.render" v-bind="row" style="margin: 0 12px" />
98
+ <span v-else-if="btnItem.slotName">
99
+ <slot :name="btnItem.slotName" v-bind="row" />
100
+ </span>
101
+ <el-button
102
+ v-else
103
+ @click="btnItem.fun && tableOperationFn(btnItem, row)"
104
+ :disabled="btnItem.disabledFn && btnItem.disabledFn(row)"
105
+ :link="btnItem.link === false ? false : true"
106
+ :type="btnItem.type || ''"
107
+ :icon="btnItem.icon || ''"
108
+ v-bind="(btnItem as any).$attr"
109
+ style="margin: 0 6px"
110
+ >
111
+ <span>{{ btnItem.text }}</span>
112
+ </el-button>
113
+ </span>
114
+ </template>
115
+ </template>
116
+ </el-table-column>
117
+ </template>
118
+ <!-- 插入表格最后一行之后的插槽 -->
119
+ <template #append>
120
+ <slot name="append" />
121
+ </template>
122
+ <!-- 无数据 -->
123
+ <template #empty>
124
+ <div class="table-empty">
125
+ <slot name="empty">
126
+ <JztEmpty />
127
+ </slot>
128
+ </div>
129
+ </template>
130
+ </el-table>
131
+ <!-- 分页组件 -->
132
+ <slot v-if="pagination" name="pagination">
133
+ <jzt-pagination v-model:pageable="pageQuery" @changePageable="onPageableChange" />
134
+ </slot>
135
+ </div>
136
+ </div>
137
+ </template>
138
+
139
+ <script setup lang="ts" name="ProTable">
140
+ import { ElTableColumn, ElTable, ElMessageBox, ElMessage } from 'element-plus'
141
+ import { ref, watch, provide, onMounted, unref, computed, reactive } from 'vue'
142
+ import { useTable } from '../JztQueryTable/hooks/useQueryTable'
143
+ import { useSelection } from '../JztQueryTable/hooks/useSelection'
144
+ import {
145
+ ColumnProps,
146
+ PageableProps,
147
+ TypeProps,
148
+ TopButtonProps,
149
+ TableConfigProps
150
+ } from '../JztQueryTable/interface/index'
151
+ import { Refresh, Setting, Search } from '@element-plus/icons-vue'
152
+ import { generateUUID } from '../utils/index'
153
+ import JztPagination from '../JztPagination/index.vue'
154
+ // import ColumnsSetting from '../JztQueryTable/components/ColumnsSetting.vue'
155
+ import TableColumn from '../JztQueryTable/components/TableColumn.vue'
156
+ import JztButtonList from '../JztButtonList/index.vue'
157
+ import Sortable from 'sortablejs'
158
+ import JztEmpty from '../JztEmpty/index.vue'
159
+ // import { hasPermission } from '../hooks/useAuthButtons'
160
+ import { hasPermission } from '@jzt-spd/utils'
161
+ import { useTableEvents } from '../hooks/useTableEvents'
162
+
163
+ const { useButtonClickFn } = useTableEvents()
164
+
165
+ export interface ProTableProps {
166
+ tableConfig: TableConfigProps // 列配置项 ==> 必传
167
+ tableData?: any[] // 静态 table data 数据
168
+ pagination?: boolean // 是否需要分页组件 ==> 非必传(默认为true)
169
+ border?: boolean // 是否带有纵向边框 ==> 非必传(默认为false)
170
+ toolButton?: ('refresh' | 'setting' | 'fullScreen')[] | boolean // 是否显示表格功能按钮 ==> 非必传(默认为true)
171
+ rowKey?: string // 行数据的 Key,用来优化 Table 的渲染,当表格数据多选时,所指定的 id ==> 非必传(默认为 id)
172
+ pageable?: PageableProps // 分页数据
173
+ tableHeight?: string
174
+ isFullHeight?: boolean // 是否
175
+ }
176
+
177
+ // 接受父组件参数,配置默认值
178
+ const props = withDefaults(defineProps<ProTableProps>(), {
179
+ tableData: () => [],
180
+ pagination: true,
181
+ border: false,
182
+ toolButton: true,
183
+ rowKey: 'id',
184
+ tableHeight: '100%',
185
+ isFullHeight: false,
186
+ pageable: () => {
187
+ return {
188
+ pageIndex: 1, // 当前页
189
+ pageSize: 10, // 每页显示条数
190
+ total: 0 // 总条数s
191
+ }
192
+ }
193
+ })
194
+ // 分页
195
+ const pageQuery = computed({
196
+ get() {
197
+ return props.pageable
198
+ },
199
+ set(val: PageableProps) {
200
+ emit('update:pageable', val)
201
+ }
202
+ })
203
+
204
+ // 表格全屏
205
+ const isFullscreen = ref(false)
206
+ // table 实例
207
+ const jztTableRef = ref<InstanceType<typeof ElTable>>()
208
+
209
+ // 生成组件唯一id
210
+ const uuid = ref('id-' + generateUUID())
211
+
212
+ // 接收 topList 并设置为响应式 TopButtonProps
213
+ const topList = computed<TopButtonProps[]>(() => props.tableConfig.topList || [])
214
+ // column 列类型
215
+ const columnTypes: TypeProps[] = ['selection', 'radio', 'index', 'expand', 'sort']
216
+ // 控制 ToolButton 显示
217
+ const showToolButton = (key: 'refresh' | 'setting' | 'fullScreen') => {
218
+ return Array.isArray(props.toolButton) ? props.toolButton.includes(key) : props.toolButton
219
+ }
220
+
221
+ // 单选值
222
+ const radio = ref('')
223
+ const tableColumns = ref<ColumnProps[]>([])
224
+
225
+ watch(
226
+ () => props.tableConfig.columns,
227
+ columns => {
228
+ flatColumnsFunc(columns)
229
+ },
230
+ {
231
+ deep: true
232
+ }
233
+ )
234
+
235
+ // 扁平化 columns 的方法 处理字典数据 、 过滤表格部分渲染数据
236
+ const flatColumnsFunc = (columns: ColumnProps[], flatArr: ColumnProps[] = []) => {
237
+ tableColumns.value = []
238
+ columns.forEach(async col => {
239
+ if (col.prop && !col.type) {
240
+ tableColumns.value.push(col)
241
+ if (col._children?.length) flatArr.push(...flatColumnsFunc(col._children))
242
+ flatArr.push(col)
243
+ // column 添加默认 isShow && isSetting && isFilterEnum 属性值
244
+ col.isShow = col.isShow ?? true
245
+ col.isSetting = col.isSetting ?? true
246
+ col.isFilterEnum = col.isFilterEnum ?? true
247
+ }
248
+ })
249
+ return flatArr.filter(item => !item._children?.length)
250
+ }
251
+ flatColumnsFunc(props.tableConfig.columns)
252
+
253
+ // 表格多选 Hooks
254
+ const { selectionChange, selectedList, selectedListIds, isSelected, headerDragend } = useSelection(props.rowKey)
255
+
256
+ const onPageableChange = (pageable: PageableProps) => {
257
+ const { pageIndex, pageSize } = pageable
258
+ emit('refresh', { pageIndex, pageSize })
259
+ }
260
+
261
+ // 刷新表格】
262
+ const onRefresh = () => {
263
+ const { pageIndex, pageSize } = pageQuery.value
264
+ emit('refresh', { pageIndex, pageSize })
265
+ }
266
+
267
+ // 清空选中数据列表
268
+ const clearSelection = () => jztTableRef.value!.clearSelection()
269
+
270
+ // 初始化表格数据 && 拖拽排序
271
+ onMounted(() => {
272
+ dragSort()
273
+ })
274
+
275
+ // 列表操作列 'index', 'selection', 'radio', 'expand', 'sort'
276
+ const selectColumns = computed<ColumnProps[]>(() => {
277
+ return props.tableConfig.columns.filter(item => item.isShow !== false && item.type && columnTypes.includes(item.type))
278
+ })
279
+
280
+ // 定义 emit 事件
281
+ const emit = defineEmits<{
282
+ dragSort: [{ newIndex?: number; oldIndex?: number }]
283
+ radioChange: [string, any]
284
+ tabChange: [any]
285
+ refresh: [PageableProps]
286
+ 'update:pageable': PageableProps
287
+ }>()
288
+ // 单选change
289
+ const radioChange = (rowKey, row) => {
290
+ emit('radioChange', rowKey, row)
291
+ }
292
+
293
+ // 表格拖拽排序
294
+ const dragSort = () => {
295
+ const tbody = document.querySelector(`#${uuid.value} tbody`) as HTMLElement
296
+ Sortable.create(tbody, {
297
+ handle: '.move',
298
+ animation: 300,
299
+ onEnd({ newIndex, oldIndex }) {
300
+ // const [removedItem] = processTableData.value.splice(oldIndex!, 1);
301
+ // processTableData.value.splice(newIndex!, 0, removedItem);
302
+ emit('dragSort', { newIndex, oldIndex })
303
+ }
304
+ })
305
+ }
306
+ // 是否显示表格操作按钮
307
+ // const hasPermission = (item: any) => {
308
+ // // return false;
309
+ // return !!item.hasPerm;
310
+ // };
311
+ // 操作列点击操作
312
+ const tableOperationFn = (item: any, row: any) => {
313
+ useButtonClickFn(item, row)
314
+ // if (item.id === 'delete') {
315
+ // ElMessageBox.confirm('确定删除该条数据吗?', '警告', {
316
+ // confirmButtonText: '确定',
317
+ // cancelButtonText: '取消',
318
+ // type: 'warning'
319
+ // })
320
+ // .then(() => {
321
+ // item.fun(row)
322
+ // })
323
+ // .catch(() => {
324
+ // console.log(12)
325
+ // })
326
+ // } else {
327
+ // item.fun(row)
328
+ // }
329
+ }
330
+ // 按钮点击
331
+ const handleButtonClick = fun => {
332
+ fun &&
333
+ fun({
334
+ isSelected: isSelected.value,
335
+ selectedList: selectedList.value,
336
+ selectedListIds: selectedListIds.value
337
+ })
338
+ }
339
+ // 暴露给父组件的参数和方法 (外部需要什么,都可以从这里暴露出去)
340
+ defineExpose({
341
+ element: jztTableRef,
342
+ radio,
343
+ isSelected,
344
+ selectedList,
345
+ selectedListIds,
346
+
347
+ // 下面为 function
348
+ clearSelection
349
+ })
350
+ </script>
351
+ <style lang="scss" scoped>
352
+ @use './index';
353
+ </style>
@@ -0,0 +1 @@
1
+ export * from "../../JztQueryTable/interface/index";
@@ -0,0 +1,112 @@
1
+ <template>
2
+ <el-select
3
+ class="select mb8"
4
+ v-model="selectAgentId"
5
+ :style="{ width: width }"
6
+ :placeholder="selectPla"
7
+ :disabled="!selectDisabled"
8
+ @change="selectChangeHandle"
9
+ filterable
10
+ >
11
+ <el-option
12
+ v-for="item in options"
13
+ :key="item[fieldNames.value]"
14
+ :label="item[fieldNames.label]"
15
+ :value="item[fieldNames.value]"
16
+ />
17
+ </el-select>
18
+ </template>
19
+
20
+ <script setup lang="ts" name="JztTime">
21
+ import { computed, onMounted, ref } from 'vue'
22
+ import { isEmpty, localGetUserId, localGetUserType } from '@jzt-spd/utils'
23
+ import { getUserAgencySupplierApi } from '@jzt-spd/utils/commonApi'
24
+ import { localGetAgencyId } from '@jzt-spd/utils'
25
+
26
+ // 机构默认传参
27
+ const userParams = ref({
28
+ UserId: localGetUserId() || '',
29
+ Key: '',
30
+ EnterpriseType: localGetUserType()
31
+ })
32
+
33
+ export interface AgencySelectProps {
34
+ width?: string // 宽度
35
+ selectPla?: string // 机构选择框提示语
36
+ selectValue?: string | number // 选择框默认值
37
+ selectNames?: {
38
+ label: string // label字段名称
39
+ value: string // value字段名称
40
+ }
41
+ selectApi?: (params: any) => Promise<any> // 选择框数据接口
42
+ selectParams?: any // 选择框接口参数
43
+ selectDisabled?: boolean //是否置灰机构 -- 非医共体置灰
44
+ }
45
+ // 默认值
46
+ const props = withDefaults(defineProps<AgencySelectProps>(), {
47
+ selectPla: '请选择机构',
48
+ selectDisabled: true,
49
+ selectParams: {},
50
+ dateSelectProps: () => ({})
51
+ })
52
+ const emit = defineEmits(['update:modelValue', 'update:selectValue', 'selectChange'])
53
+
54
+ // 下拉框选项
55
+ const options = ref<any[]>([])
56
+ // 下拉框字段
57
+ const fieldNames = computed(() => {
58
+ return {
59
+ label: props.selectNames?.label ?? 'enterpriseIdName',
60
+ value: props.selectNames?.value ?? 'enterpriseId'
61
+ }
62
+ })
63
+
64
+ const selectInfo = ref({})
65
+ // 下拉框值
66
+ const selectAgentId = computed({
67
+ get() {
68
+ return props.selectValue
69
+ },
70
+ set(val) {
71
+ emit('update:selectValue', val)
72
+ }
73
+ })
74
+ // 下拉框改变
75
+ const selectChangeHandle = (val: string | number | undefined) => {
76
+ const selectItem = options.value?.filter((item: any) => item[fieldNames.value.value] === val)[0] || null
77
+ selectAgentId.value = selectItem?.[fieldNames.value.value]
78
+ selectInfo.value = selectItem
79
+ emit('selectChange', {
80
+ agencyId: selectAgentId.value,
81
+ agencyInfo: selectInfo.value
82
+ })
83
+
84
+ // emit('selectChange', 'agencySelectChange', { selectInfo: selectInfo.value })
85
+ }
86
+ // 初始化
87
+ const initData = async () => {
88
+ try {
89
+ // 默认值
90
+ const fn = props.selectApi ? props.selectApi : getUserAgencySupplierApi
91
+ const res = await fn({ ...userParams.value, ...props.selectParams })
92
+ options.value = res?.result || []
93
+ setTimeout(async () => {
94
+ const defaultSelectId = !isEmpty(props.selectValue) ? props.selectValue : localGetAgencyId()
95
+ selectAgentId.value = defaultSelectId
96
+ selectChangeHandle(defaultSelectId)
97
+ }, 200)
98
+ } catch (error) {}
99
+ }
100
+
101
+ onMounted(() => {
102
+ initData()
103
+ })
104
+ defineExpose({
105
+ selectInfo
106
+ })
107
+ </script>
108
+
109
+ <style lang="scss" scoped>
110
+ .select {
111
+ }
112
+ </style>
@@ -0,0 +1,132 @@
1
+ <template>
2
+ <div class="auto-collapse-row" :style="showToggle ? { paddingBottom: '24px' } : {}">
3
+ <div ref="containerRef" class="content" :class="{ collapsed: isCollapsed }" :style="collapsedStyle">
4
+ <slot />
5
+ </div>
6
+
7
+ <div v-if="showToggle" class="toggle" @click="toggle">
8
+ {{ isCollapsed ? expandText : collapseText }}
9
+ <el-icon class="el-icon--right">
10
+ <component :is="isCollapsed ? ArrowDownBold : ArrowUpBold"></component>
11
+ </el-icon>
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script setup lang="ts">
17
+ import { debounce } from 'lodash-es'
18
+ import { ref, nextTick, onMounted, onUnmounted, computed, watch } from 'vue'
19
+ import { ArrowDownBold, ArrowUpBold } from '@element-plus/icons-vue'
20
+
21
+ interface Props {
22
+ defaultCollapsed?: boolean
23
+ expandText?: string
24
+ collapseText?: string
25
+ }
26
+
27
+ const props = withDefaults(defineProps<Props>(), {
28
+ defaultCollapsed: true,
29
+ expandText: '展开',
30
+ collapseText: '收起'
31
+ })
32
+
33
+ const containerRef = ref<HTMLElement | null>(null)
34
+ const isCollapsed = ref(props.defaultCollapsed)
35
+ const showToggle = ref(false)
36
+ const collapsedHeight = ref(40)
37
+
38
+ const collapsedStyle = computed(() => {
39
+ if (!isCollapsed.value) return {}
40
+ return {
41
+ height: collapsedHeight.value + 'px',
42
+ overflow: 'hidden'
43
+ }
44
+ })
45
+
46
+ const toggle = () => {
47
+ isCollapsed.value = !isCollapsed.value
48
+ }
49
+
50
+ const calculate = async () => {
51
+ await nextTick()
52
+ const container = containerRef.value
53
+ if (!container) return
54
+ const children = Array.from(container.children) as HTMLElement[]
55
+ if (!children.length) {
56
+ showToggle.value = false
57
+ return
58
+ }
59
+ // 第一行高度
60
+ const firstRowTop = children[0].offsetTop
61
+ const secondRowElement = children.find(el => el.offsetTop > firstRowTop)
62
+ if (secondRowElement) {
63
+ showToggle.value = true
64
+ collapsedHeight.value = secondRowElement.offsetTop - 4
65
+ } else {
66
+ showToggle.value = false
67
+ }
68
+ }
69
+ // 创建一个稳定的防抖函数(不要放在 observer 里面)
70
+ const debounceCalculate = debounce(() => {
71
+ calculate()
72
+ }, 300)
73
+ let observer: ResizeObserver
74
+
75
+ onMounted(() => {
76
+ observer = new ResizeObserver(() => {
77
+ debounceCalculate()
78
+ })
79
+
80
+ if (containerRef.value) {
81
+ observer.observe(containerRef.value)
82
+ }
83
+
84
+ calculate()
85
+ })
86
+
87
+ onUnmounted(() => {
88
+ observer?.disconnect()
89
+ debounceCalculate.cancel()
90
+ })
91
+ </script>
92
+
93
+ <style scoped lang="scss">
94
+ .auto-collapse-row {
95
+ position: relative;
96
+ width: 100%;
97
+ display: flex;
98
+ flex-direction: column;
99
+ // align-items: flex-start;
100
+ // justify-content: flex-start;
101
+ }
102
+
103
+ .content {
104
+ display: flex;
105
+ flex-wrap: wrap;
106
+ transition: height 0.3s ease;
107
+ }
108
+
109
+ .toggle {
110
+ width: 100%;
111
+ height: 24px;
112
+ line-height: 24px;
113
+ position: absolute;
114
+ bottom: 0px;
115
+ left: 50%;
116
+ transform: translate(-50%, 0);
117
+ // padding: 0 20px;
118
+ color: #999;
119
+ text-align: center;
120
+ font-size: 12px;
121
+ cursor: pointer;
122
+ -webkit-user-select: none;
123
+ -moz-user-select: none;
124
+ user-select: none;
125
+ // border-radius: 10px;
126
+ border-bottom-left-radius: 8px;
127
+ border-bottom-right-radius: 8px;
128
+ background: linear-gradient(180deg, #ffffff00 0%, #ffffff 40%);
129
+ color: var(--el-color-primary);
130
+ // background: #fff;
131
+ }
132
+ </style>