@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.
- package/package.json +68 -0
- package/src/JztBackTop/index.vue +255 -0
- package/src/JztButtonList/index.vue +88 -0
- package/src/JztChart/index.vue +95 -0
- package/src/JztCharts/index.vue +317 -0
- package/src/JztClassTabs/index.vue +156 -0
- package/src/JztDateSelect/dateSelect.vue +186 -0
- package/src/JztDateSelect/dateType.vue +54 -0
- package/src/JztDateSelect/index.ts +135 -0
- package/src/JztDateSelect/interface/index.ts +13 -0
- package/src/JztDialog/index.vue +249 -0
- package/src/JztEllipsisTooltip/index.vue +61 -0
- package/src/JztEmpty/index.vue +45 -0
- package/src/JztErrorPage/403.vue +30 -0
- package/src/JztErrorPage/404.vue +19 -0
- package/src/JztErrorPage/500.vue +18 -0
- package/src/JztErrorPage/assets/401.png +0 -0
- package/src/JztErrorPage/assets/403.png +0 -0
- package/src/JztErrorPage/assets/404.png +0 -0
- package/src/JztErrorPage/assets/500.png +0 -0
- package/src/JztErrorPage/index.scss +35 -0
- package/src/JztErrorPage/index.vue +35 -0
- package/src/JztFilePreview/components/pdfViewer.vue +221 -0
- package/src/JztFilePreview/hooks/useImageMethod.ts +256 -0
- package/src/JztFilePreview/index.scss +171 -0
- package/src/JztFilePreview/index.vue +68 -0
- package/src/JztFilePreview/interface/index.ts +18 -0
- package/src/JztFilePreview/previewFile.vue +371 -0
- package/src/JztFormGrid/README.md +520 -0
- package/src/JztFormGrid/components/formItem.vue +209 -0
- package/src/JztFormGrid/components/formItemValue.vue +384 -0
- package/src/JztFormGrid/components/showDetailForm.vue +172 -0
- package/src/JztFormGrid/index.scss +60 -0
- package/src/JztFormGrid/index.vue +513 -0
- package/src/JztFormGrid/interface/index.ts +106 -0
- package/src/JztGrid/components/GridItem.vue +68 -0
- package/src/JztGrid/index.vue +179 -0
- package/src/JztGrid/interface/index.ts +6 -0
- package/src/JztImportExcel/assets/delete.png +0 -0
- package/src/JztImportExcel/index.scss +46 -0
- package/src/JztImportExcel/index.vue +430 -0
- package/src/JztImportExcel/interface/index.ts +25 -0
- package/src/JztLabelTitle/index.vue +65 -0
- package/src/JztLeftRightMode/components/CollapseButton.vue +80 -0
- package/src/JztLeftRightMode/components/LeftCard.vue +203 -0
- package/src/JztLeftRightMode/components/LeftLayout.vue +173 -0
- package/src/JztLeftRightMode/components/RightHeader.vue +186 -0
- package/src/JztLeftRightMode/components/RightLayout.vue +235 -0
- package/src/JztLeftRightMode/components/RightTableHeader.vue +43 -0
- package/src/JztLeftRightMode/hooks/useCollapse.ts +17 -0
- package/src/JztLeftRightMode/hooks/useDefaultProps.ts +19 -0
- package/src/JztLeftRightMode/hooks/useLeftLayout.ts +201 -0
- package/src/JztLeftRightMode/hooks/useMode.ts +20 -0
- package/src/JztLeftRightMode/hooks/usePrevNext.ts +60 -0
- package/src/JztLeftRightMode/hooks/useRightLayout.ts +215 -0
- package/src/JztLeftRightMode/hooks/useSlots.ts +15 -0
- package/src/JztLeftRightMode/index.ts +3 -0
- package/src/JztLeftRightMode/index.vue +494 -0
- package/src/JztLeftRightMode/types/index.ts +457 -0
- package/src/JztLoading/fullScreen.ts +45 -0
- package/src/JztLoading/index.scss +67 -0
- package/src/JztLoading/index.vue +18 -0
- package/src/JztLogin/components/LoginFooter.vue +17 -0
- package/src/JztLogin/components/LoginForm.vue +99 -0
- package/src/JztLogin/hooks/useLogin.ts +186 -0
- package/src/JztLogin/index.scss +142 -0
- package/src/JztLogin/index.vue +31 -0
- package/src/JztLogin/interface/index.ts +47 -0
- package/src/JztNumericalRange/index.vue +81 -0
- package/src/JztPageCard/comm/datePicker.vue +151 -0
- package/src/JztPageCard/comm/details.vue +60 -0
- package/src/JztPageCard/comm/export.vue +24 -0
- package/src/JztPageCard/comm/tabs.vue +94 -0
- package/src/JztPageCard/comm/tooltip.vue +31 -0
- package/src/JztPageCard/index.vue +287 -0
- package/src/JztPagination/index.vue +70 -0
- package/src/JztProductInfo/components/imagePreview.vue +275 -0
- package/src/JztProductInfo/components/qxUnique.vue +101 -0
- package/src/JztProductInfo/components/records.vue +265 -0
- package/src/JztProductInfo/hooks/useParams.ts +143 -0
- package/src/JztProductInfo/hooks/useQxUnique.tsx +466 -0
- package/src/JztProductInfo/images/defaultProduct.png +0 -0
- package/src/JztProductInfo/index.ts +116 -0
- package/src/JztProductInfo/index.vue +108 -0
- package/src/JztProductInfo/interface/index.ts +15 -0
- package/src/JztQueryDetailTable/index.scss +100 -0
- package/src/JztQueryDetailTable/index.vue +400 -0
- package/src/JztQueryDetailTable/interface/index.ts +10 -0
- package/src/JztQueryTable/QueryTable /345/212/237/350/203/275.md" +1580 -0
- package/src/JztQueryTable/README.md +567 -0
- package/src/JztQueryTable/components/ColSetting.vue +67 -0
- package/src/JztQueryTable/components/ColumnsSetting.vue +404 -0
- package/src/JztQueryTable/components/ColumnsSetting1.vue +220 -0
- package/src/JztQueryTable/components/DeployToAccountLevelSetting.vue +351 -0
- package/src/JztQueryTable/components/Pagination.vue +54 -0
- package/src/JztQueryTable/components/TableColumn.vue +109 -0
- package/src/JztQueryTable/const.ts +1 -0
- package/src/JztQueryTable/hooks/useQueryTable.ts +194 -0
- package/src/JztQueryTable/hooks/useSelection.ts +47 -0
- package/src/JztQueryTable/hooks/useTableSetting.ts +197 -0
- package/src/JztQueryTable/hooks/useTemplate.ts +127 -0
- package/src/JztQueryTable/index.scss +91 -0
- package/src/JztQueryTable/index.vue +1445 -0
- package/src/JztQueryTable/interface/index.ts +185 -0
- package/src/JztRegionSelect/index.vue +134 -0
- package/src/JztSearchForm/components/SearchFormItem.vue +473 -0
- package/src/JztSearchForm/index.vue +530 -0
- package/src/JztSearchForm/interface/index.ts +100 -0
- package/src/JztSelectFilter/index.scss +63 -0
- package/src/JztSelectFilter/index.vue +110 -0
- package/src/JztSelectTable/index.vue +257 -0
- package/src/JztTable/index.scss +72 -0
- package/src/JztTable/index.vue +353 -0
- package/src/JztTable/interface/index.ts +1 -0
- package/src/JztTime/comm/agencySelect.vue +112 -0
- package/src/JztTime/comm/collapseRow.vue +132 -0
- package/src/JztTime/comm/dateSelect.vue +292 -0
- package/src/JztTime/comm/deptSelect.vue +193 -0
- package/src/JztTime/comm/typeSelect.vue +97 -0
- package/src/JztTime/index.ts +216 -0
- package/src/JztTime/index.vue +303 -0
- package/src/JztTime/interface/index.ts +23 -0
- package/src/JztTreeFilter/index.scss +44 -0
- package/src/JztTreeFilter/index.vue +177 -0
- package/src/JztUploadFile/interface/index.ts +21 -0
- package/src/JztUploadFile/multiple.scss +215 -0
- package/src/JztUploadFile/multiple.vue +318 -0
- package/src/JztUploadFile/single.scss +226 -0
- package/src/JztUploadFile/single.vue +274 -0
- package/src/JztUploadImg/Img.vue +294 -0
- package/src/JztUploadImg/Imgs.vue +411 -0
- package/src/JztUploadImg/index.scss +138 -0
- package/src/JztUploadImg/interface/index.ts +22 -0
- package/src/SelectIcon/index.scss +39 -0
- package/src/SelectIcon/index.vue +106 -0
- package/src/SvgIcon/index.vue +22 -0
- package/src/hooks/useAuthButtons.ts +58 -0
- package/src/hooks/useFormByUserType.ts +90 -0
- package/src/hooks/useTableEvents.ts +30 -0
- package/src/hooks/useUploadFileHook.ts +262 -0
- package/src/index.ts +91 -0
- package/src/typings/global.d.ts +101 -0
- package/src/utils/index.ts +107 -0
- package/src/utils/tree.ts +57 -0
- package/tsconfig.json +45 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<jzt-dialog
|
|
3
|
+
v-model="dialogVisible"
|
|
4
|
+
:title="title"
|
|
5
|
+
width="80%"
|
|
6
|
+
:showFooter="false"
|
|
7
|
+
@close="closeDialog"
|
|
8
|
+
dialogClass="noTopBody"
|
|
9
|
+
>
|
|
10
|
+
<div v-if="dialogVisible" v-loading="loading" class="product-container">
|
|
11
|
+
<el-tabs v-model="tabActive" class="table-tabs" @tab-change="handleTabChange">
|
|
12
|
+
<el-tab-pane
|
|
13
|
+
v-for="tab in tabsList.filter(item => item.isShow)"
|
|
14
|
+
:label="tab.label"
|
|
15
|
+
:name="tab.name"
|
|
16
|
+
></el-tab-pane>
|
|
17
|
+
</el-tabs>
|
|
18
|
+
<div class="container">
|
|
19
|
+
<div v-if="tabActive === 'records'" class="container-item">
|
|
20
|
+
<records
|
|
21
|
+
:productInfo="productInfo"
|
|
22
|
+
:srcList="productPictureList"
|
|
23
|
+
v-model:openFold="openFold"
|
|
24
|
+
:medicalType="medicalType"
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
<div v-else-if="tabActive === 'qxUnique'" class="container-item">
|
|
28
|
+
<qxUnique :productInfo="productInfo" />
|
|
29
|
+
</div>
|
|
30
|
+
<div v-else-if="tabActive === 'instruction'" class="container-item">
|
|
31
|
+
<previewFile ref="previewFileRef" />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</jzt-dialog>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script setup lang="ts" name="JztProductInfo">
|
|
39
|
+
import JztDialog from '../JztDialog/index.vue'
|
|
40
|
+
import previewFile from '../JztFilePreview/previewFile.vue'
|
|
41
|
+
import qxUnique from './components/qxUnique.vue'
|
|
42
|
+
import records from './components/records.vue'
|
|
43
|
+
import { useEvents, useParams } from './hooks/useParams'
|
|
44
|
+
|
|
45
|
+
export interface ProductInfo {
|
|
46
|
+
title?: string
|
|
47
|
+
}
|
|
48
|
+
const props = withDefaults(defineProps<ProductInfo>(), {
|
|
49
|
+
title: '查看产品信息'
|
|
50
|
+
})
|
|
51
|
+
const {
|
|
52
|
+
loading,
|
|
53
|
+
dialogVisible,
|
|
54
|
+
tabActive,
|
|
55
|
+
tabsList,
|
|
56
|
+
previewFileRef,
|
|
57
|
+
productInfo,
|
|
58
|
+
productPictureList,
|
|
59
|
+
openFold,
|
|
60
|
+
medicalType
|
|
61
|
+
} = useParams()
|
|
62
|
+
const { getDetailByCode, closeDialog, handleTabChange } = useEvents()
|
|
63
|
+
const openDialog = (paramsValue: string | object, type?: string) => {
|
|
64
|
+
let params = {}
|
|
65
|
+
if (typeof paramsValue === 'string') {
|
|
66
|
+
params = { productCode: paramsValue }
|
|
67
|
+
} else {
|
|
68
|
+
params = paramsValue
|
|
69
|
+
}
|
|
70
|
+
getDetailByCode(params, type)
|
|
71
|
+
}
|
|
72
|
+
defineExpose({
|
|
73
|
+
openDialog
|
|
74
|
+
})
|
|
75
|
+
</script>
|
|
76
|
+
<style lang="scss" scoped>
|
|
77
|
+
:deep(.dialog-content) {
|
|
78
|
+
height: calc(75vh - 60px);
|
|
79
|
+
}
|
|
80
|
+
.product-container {
|
|
81
|
+
height: calc(100% - 20px);
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
padding: 0 10px;
|
|
85
|
+
:deep(.el-tabs__content) {
|
|
86
|
+
display: none;
|
|
87
|
+
}
|
|
88
|
+
.table-tabs {
|
|
89
|
+
// height: 55px;
|
|
90
|
+
position: sticky;
|
|
91
|
+
top: 0;
|
|
92
|
+
left: 0;
|
|
93
|
+
right: 0;
|
|
94
|
+
z-index: 999;
|
|
95
|
+
background-color: #fff;
|
|
96
|
+
}
|
|
97
|
+
.container {
|
|
98
|
+
flex: 1;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
.container-item {
|
|
101
|
+
height: 100%;
|
|
102
|
+
flex: 1;
|
|
103
|
+
height: 100%;
|
|
104
|
+
overflow: hidden;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { VNode, ComponentPublicInstance, Ref } from 'vue'
|
|
2
|
+
import { ProductInfo } from '../index.vue'
|
|
3
|
+
|
|
4
|
+
export type ProductInfoRefInstance = keyof ComponentPublicInstance | keyof ProductInfo
|
|
5
|
+
export type ProductInfoRef = {
|
|
6
|
+
openDialog: (param: string | object) => any
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// export interface FileItemProps {
|
|
10
|
+
// arrayIndex: number
|
|
11
|
+
// id: string
|
|
12
|
+
// url: string
|
|
13
|
+
// name: string
|
|
14
|
+
// fileType: string
|
|
15
|
+
// }
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
.el-popover {
|
|
2
|
+
min-width: 200px;
|
|
3
|
+
max-width: 300px;
|
|
4
|
+
}
|
|
5
|
+
.fullscreen-page {
|
|
6
|
+
position: absolute;
|
|
7
|
+
top: 0;
|
|
8
|
+
left: 0;
|
|
9
|
+
width: 100vw;
|
|
10
|
+
height: 100vh;
|
|
11
|
+
z-index: 99;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* queryTable */
|
|
15
|
+
.table-main {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex: 1;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
padding: 8px 0 0 0;
|
|
23
|
+
background-color: aquamarine;
|
|
24
|
+
|
|
25
|
+
// 表格 header 样式
|
|
26
|
+
.table-header {
|
|
27
|
+
.header-button-lf,
|
|
28
|
+
.header-button-ri {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-wrap: wrap;
|
|
31
|
+
// gap: 15px 12px;
|
|
32
|
+
gap: 5px 2px;
|
|
33
|
+
margin-bottom: 2px;
|
|
34
|
+
.el-button:not(.el-input .el-button) {
|
|
35
|
+
margin-left: 0;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
.header-button-lf {
|
|
39
|
+
float: left;
|
|
40
|
+
}
|
|
41
|
+
.header-button-ri {
|
|
42
|
+
float: right;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.el-button {
|
|
46
|
+
margin: 5px !important;
|
|
47
|
+
}
|
|
48
|
+
// .tool_btn {
|
|
49
|
+
// width: 30px;
|
|
50
|
+
// height: 30px;
|
|
51
|
+
// }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.table-top-box {
|
|
55
|
+
padding: 0 10px;
|
|
56
|
+
|
|
57
|
+
.el-tabs {
|
|
58
|
+
margin-left: 6px;
|
|
59
|
+
margin-bottom: 5px;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.table-content-box {
|
|
64
|
+
flex: 1;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
padding: 6px 10px 10px 10px;
|
|
67
|
+
.table-left-box,
|
|
68
|
+
.table-right-box {
|
|
69
|
+
box-shadow: var(--el-box-shadow-light);
|
|
70
|
+
height: calc(100%);
|
|
71
|
+
border-radius: 8px;
|
|
72
|
+
overflow: hidden;
|
|
73
|
+
}
|
|
74
|
+
.table-right-box {
|
|
75
|
+
margin-left: 10px;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.el-tabs .el-tabs__header.is-top {
|
|
80
|
+
margin-bottom: 2px !important;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.el-table {
|
|
85
|
+
.el-scrollbar {
|
|
86
|
+
min-height: 150px;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.el-dialog {
|
|
91
|
+
.table-search {
|
|
92
|
+
padding-top: 0;
|
|
93
|
+
margin-bottom: 0;
|
|
94
|
+
}
|
|
95
|
+
.spd-card {
|
|
96
|
+
border: none !important;
|
|
97
|
+
box-shadow: none !important;
|
|
98
|
+
padding: 0 10px;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 查询表单 -->
|
|
3
|
+
<JztSearchForm
|
|
4
|
+
ref="searchFormRef"
|
|
5
|
+
v-show="isShowSearch"
|
|
6
|
+
:search="_search"
|
|
7
|
+
:reset="_reset"
|
|
8
|
+
:allow-collapsed="allowCollapsed"
|
|
9
|
+
:collapsed="collapsed"
|
|
10
|
+
:query-items="searchColumns"
|
|
11
|
+
:search-param="searchParam"
|
|
12
|
+
:search-col="searchCol"
|
|
13
|
+
/>
|
|
14
|
+
|
|
15
|
+
<!-- 表格主体 -->
|
|
16
|
+
<div :class="['spd-card table-main', isFullscreen ? 'fullscreen-page' : '']">
|
|
17
|
+
<div class="table-top-box">
|
|
18
|
+
<!-- 表格头部 操作按钮 -->
|
|
19
|
+
<div class="table-header">
|
|
20
|
+
<JztButtonList :buttonList="topList" @onClick="handleButtonClick">
|
|
21
|
+
</JztButtonList>
|
|
22
|
+
<slot name="tableHeader" />
|
|
23
|
+
</div>
|
|
24
|
+
<!-- 表格上方el-tabs -->
|
|
25
|
+
<el-tabs
|
|
26
|
+
v-if="tabsList && tabsList.length"
|
|
27
|
+
v-model="initParam[tabActiveName as keyof string]"
|
|
28
|
+
class="table-tabs"
|
|
29
|
+
@tab-change="handleTabChange"
|
|
30
|
+
>
|
|
31
|
+
<el-tab-pane
|
|
32
|
+
v-for="tab in tabsList"
|
|
33
|
+
:label="tab[tabsProps?.label || 'label']"
|
|
34
|
+
:name="tab[tabsProps?.value || 'value']"
|
|
35
|
+
></el-tab-pane>
|
|
36
|
+
</el-tabs>
|
|
37
|
+
<slot name="tableTops" />
|
|
38
|
+
</div>
|
|
39
|
+
<!--表格区域 -->
|
|
40
|
+
<div class="flx-left-top table-content-box">
|
|
41
|
+
<div
|
|
42
|
+
class="table-left-box"
|
|
43
|
+
:style="{
|
|
44
|
+
width: tableStyle.leftWidth,
|
|
45
|
+
}"
|
|
46
|
+
>
|
|
47
|
+
<JztTable
|
|
48
|
+
ref="jztTableRef"
|
|
49
|
+
:tableData="processTableData"
|
|
50
|
+
:tableConfig="rightTableConfig"
|
|
51
|
+
v-model:pageable="pageable"
|
|
52
|
+
v-bind="$attrs"
|
|
53
|
+
@drag-sort="sortTable"
|
|
54
|
+
@refresh="_search"
|
|
55
|
+
:isFullHeight="true"
|
|
56
|
+
@selection-change="selectionChange"
|
|
57
|
+
@radioChange="radioChange"
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
<div
|
|
61
|
+
:style="{
|
|
62
|
+
width: tableStyle.rightWidth,
|
|
63
|
+
}"
|
|
64
|
+
class="table-right-box"
|
|
65
|
+
>
|
|
66
|
+
<slot name="table-right"> </slot>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script setup lang="ts" name="ProTable">
|
|
73
|
+
import { ElTableColumn, ElTable, ElMessageBox, ElMessage } from "element-plus";
|
|
74
|
+
import { ref, watch, provide, onMounted, unref, computed, reactive } from "vue";
|
|
75
|
+
import { useTable } from "../JztQueryTable/hooks/useQueryTable";
|
|
76
|
+
import { useSelection } from "../JztQueryTable/hooks/useSelection";
|
|
77
|
+
import { BreakPoint } from "../JztGrid/interface";
|
|
78
|
+
import { isEmpty, removeEmpty } from "@jzt-spd/utils";
|
|
79
|
+
import { GUIDNoneValue } from "@jzt-spd/utils/consts";
|
|
80
|
+
import { cloneDeep } from "lodash-es";
|
|
81
|
+
import {
|
|
82
|
+
ColumnProps,
|
|
83
|
+
TypeProps,
|
|
84
|
+
QueryItemsProps,
|
|
85
|
+
TopButtonProps,
|
|
86
|
+
DetailTableConfigProps,
|
|
87
|
+
ColumnConfigProps,
|
|
88
|
+
tabsListProps,
|
|
89
|
+
} from "../JztQueryDetailTable/interface/index";
|
|
90
|
+
|
|
91
|
+
import JztButtonList from "../JztButtonList/index.vue";
|
|
92
|
+
|
|
93
|
+
import { generateUUID, handleProp } from "../utils";
|
|
94
|
+
import JztSearchForm from "../JztSearchForm/index.vue";
|
|
95
|
+
import Sortable from "sortablejs";
|
|
96
|
+
import JztTable from "../JztTable/index.vue";
|
|
97
|
+
|
|
98
|
+
export interface ProTableProps {
|
|
99
|
+
tabActiveName?: string | number; // tabs绑定值
|
|
100
|
+
tabsList?: tabsListProps[]; //tablist list数据
|
|
101
|
+
tabsProps?: tabsListProps; // tablist 配置项
|
|
102
|
+
tableConfig: DetailTableConfigProps; // 列配置项 ==> 必传
|
|
103
|
+
columnConfig?: ColumnConfigProps; // 列多选,显示序号,单选等配置项 非必传
|
|
104
|
+
data?: any[]; // 静态 table data 数据,若存在则不会使用 requestApi 返回的 data ==> 非必传
|
|
105
|
+
// initData?: boolean // 是否默认初始化数据
|
|
106
|
+
requestApi?: (params: any) => Promise<any>; // 请求表格数据的 api ==> 非必传
|
|
107
|
+
requestAuto?: boolean; // 是否自动执行请求 api ==> 非必传(默认为true)
|
|
108
|
+
requestError?: (params: any) => void; // 表格 api 请求错误监听 ==> 非必传
|
|
109
|
+
dataCallback?: (data: any) => any; // 返回数据的回调函数,可以对数据进行处理 ==> 非必传
|
|
110
|
+
tableLoaded?: (data: any) => void; // 表格加载完成的回调函数 ==> 非必传
|
|
111
|
+
title?: string; // 表格标题 ==> 非必传
|
|
112
|
+
pagination?: boolean; // 是否需要分页组件 ==> 非必传(默认为true)
|
|
113
|
+
initParam?: any; // 初始化请求参数 ==> 非必传(默认为{})
|
|
114
|
+
border?: boolean; // 是否带有纵向边框 ==> 非必传(默认为true)
|
|
115
|
+
toolButton?: ("refresh" | "setting" | "search" | "fullScreen")[] | boolean; // 是否显示表格功能按钮 ==> 非必传(默认为true)
|
|
116
|
+
rowKey?: string; // 行数据的 Key,用来优化 Table 的渲染,当表格数据多选时,所指定的 id ==> 非必传(默认为 id)
|
|
117
|
+
searchCol?: number | Record<BreakPoint, number>; // 表格搜索项 每列占比配置 ==> 非必传 { xs: 1, sm: 2, md: 3, lg: 4, xl: 5,xxl:6 }
|
|
118
|
+
searchFilter?: (data: any) => Record<string, any>; // 查询时处理数据的函数 可对查询前的数据进行编辑后再查询 ==> 非必传
|
|
119
|
+
allowCollapsed?: boolean; // 查询表单是否折叠
|
|
120
|
+
collapsed?: boolean; // 查询表单默认是否折叠
|
|
121
|
+
isDetail?: boolean; //
|
|
122
|
+
tableStyle?: Record<string, string>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 接受父组件参数,配置默认值
|
|
126
|
+
const props = withDefaults(defineProps<ProTableProps>(), {
|
|
127
|
+
tabsProps: () => {
|
|
128
|
+
return {
|
|
129
|
+
label: "label",
|
|
130
|
+
value: "value",
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
columns: () => [],
|
|
134
|
+
requestAuto: true,
|
|
135
|
+
pagination: true,
|
|
136
|
+
initParam: {},
|
|
137
|
+
border: true,
|
|
138
|
+
toolButton: true,
|
|
139
|
+
rowKey: "id",
|
|
140
|
+
searchCol: () => ({ xs: 1, sm: 2, md: 3, lg: 4, xl: 5, xxl: 6 }),
|
|
141
|
+
allowCollapsed: true,
|
|
142
|
+
collapsed: true,
|
|
143
|
+
isDetail: false,
|
|
144
|
+
tableStyle: () => ({ leftWidth: "60%", rightWidth: "60%" }),
|
|
145
|
+
});
|
|
146
|
+
// 表格全屏
|
|
147
|
+
const isFullscreen = ref(false);
|
|
148
|
+
const searchFormRef = ref();
|
|
149
|
+
// table 实例
|
|
150
|
+
const tableRef = ref<InstanceType<typeof ElTable>>();
|
|
151
|
+
|
|
152
|
+
// 生成组件唯一id
|
|
153
|
+
const uuid = ref("id-" + generateUUID());
|
|
154
|
+
const loading = ref<boolean>(false); //小丽掉了 我加上了
|
|
155
|
+
// 是否显示搜索模块
|
|
156
|
+
const isShowSearch = ref(true);
|
|
157
|
+
|
|
158
|
+
const formatterForm = (form) => {
|
|
159
|
+
let searchForm = cloneDeep(form);
|
|
160
|
+
searchColumns.value.forEach((item) => {
|
|
161
|
+
// isSetEmptyData:空值默认值&& 未选择或输入数据 -> 设置默认值进行查询
|
|
162
|
+
if (
|
|
163
|
+
item?.search &&
|
|
164
|
+
item.search?.isSetEmptyData &&
|
|
165
|
+
isEmpty(searchForm[item.prop])
|
|
166
|
+
) {
|
|
167
|
+
searchForm[item.prop] = item.search.emptyNullValue || GUIDNoneValue;
|
|
168
|
+
}
|
|
169
|
+
// 如果是数组 切设置了切割字段 -> 切割数组到开始与结束字段 并删除原字段
|
|
170
|
+
if (item.search && item.search?.startField && item.search?.endField) {
|
|
171
|
+
const { startField, endField } = item.search;
|
|
172
|
+
const timeList = searchForm[item.prop] || [];
|
|
173
|
+
searchForm[startField] = timeList[0] ?? "";
|
|
174
|
+
searchForm[endField] = timeList[1] ?? "";
|
|
175
|
+
delete searchForm[item.prop];
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
const endFrom = removeEmpty(searchForm);
|
|
179
|
+
return endFrom;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// 效验查询条件必填
|
|
183
|
+
const validateSearchForm = async () => {
|
|
184
|
+
if (props.requestAuto || !searchFormRef.value) {
|
|
185
|
+
// 需要初始化数据
|
|
186
|
+
return true;
|
|
187
|
+
} else {
|
|
188
|
+
const validate = await searchFormRef.value.validateForm();
|
|
189
|
+
return validate;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
const handleTabChange = (val: string | number) => {
|
|
193
|
+
emit("tabChange", val);
|
|
194
|
+
};
|
|
195
|
+
// 表格多选 Hooks
|
|
196
|
+
const { selectionChange, selectedList, selectedListIds, isSelected } =
|
|
197
|
+
useSelection(props.rowKey);
|
|
198
|
+
|
|
199
|
+
// 表格操作 Hooks
|
|
200
|
+
const {
|
|
201
|
+
tableData,
|
|
202
|
+
pageable,
|
|
203
|
+
searchParam,
|
|
204
|
+
searchInitParam,
|
|
205
|
+
getTableList,
|
|
206
|
+
search,
|
|
207
|
+
reset,
|
|
208
|
+
} = useTable(
|
|
209
|
+
validateSearchForm,
|
|
210
|
+
props.requestApi,
|
|
211
|
+
props.initParam,
|
|
212
|
+
props.pagination,
|
|
213
|
+
props.dataCallback,
|
|
214
|
+
props.requestError,
|
|
215
|
+
props.searchFilter,
|
|
216
|
+
props.tableLoaded,
|
|
217
|
+
loading,
|
|
218
|
+
formatterForm
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
const radio = ref("");
|
|
222
|
+
// 清空选中数据列表
|
|
223
|
+
const clearSelection = () => tableRef.value!.clearSelection();
|
|
224
|
+
|
|
225
|
+
// 初始化表格数据 && 拖拽排序
|
|
226
|
+
onMounted(() => {
|
|
227
|
+
props.requestAuto && getTableList();
|
|
228
|
+
props.data && (pageable.value.total = props.data.length);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// 处理表格数据
|
|
232
|
+
const processTableData = computed(() => {
|
|
233
|
+
if (!props.data) return tableData.value;
|
|
234
|
+
if (!props.pagination) return props.data;
|
|
235
|
+
return props.data.slice(
|
|
236
|
+
(pageable.value.pageIndex - 1) * pageable.value.pageSize,
|
|
237
|
+
pageable.value.pageSize * pageable.value.pageIndex
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// 监听页面 initParam 改化,重新获取表格数据
|
|
242
|
+
watch(() => props.initParam, getTableList, { deep: true });
|
|
243
|
+
|
|
244
|
+
// 接收 queryItems 并设置为响应式
|
|
245
|
+
const queryItems = computed(() => props.tableConfig.queryItems || []);
|
|
246
|
+
|
|
247
|
+
// 接收 topList 并设置为响应式 TopButtonProps
|
|
248
|
+
const topList = computed(() => props.tableConfig.topList || []);
|
|
249
|
+
// 接收 tableConfig 并设置为响应式(左侧表格)
|
|
250
|
+
const rightTableConfig = computed(() => {
|
|
251
|
+
return {
|
|
252
|
+
topList: props.tableConfig.leftTopList,
|
|
253
|
+
columns: props.tableConfig.columns,
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// 定义 enumMap 存储 enum 值(避免异步请求无法格式化单元格内容 || 无法填充搜索下拉选择)
|
|
258
|
+
const enumMap = ref(new Map<string, { [key: string]: any }[]>());
|
|
259
|
+
const setEnumMap = async ({ prop, enum: enumValue }: ColumnProps) => {
|
|
260
|
+
if (!enumValue) return;
|
|
261
|
+
|
|
262
|
+
// 如果当前 enumMap 存在相同的值 return
|
|
263
|
+
if (
|
|
264
|
+
enumMap.value.has(prop!) &&
|
|
265
|
+
(typeof enumValue === "function" || enumMap.value.get(prop!) === enumValue)
|
|
266
|
+
)
|
|
267
|
+
return;
|
|
268
|
+
|
|
269
|
+
// 当前 enum 为静态数据,则直接存储到 enumMap
|
|
270
|
+
if (typeof enumValue !== "function")
|
|
271
|
+
return enumMap.value.set(prop!, unref(enumValue!));
|
|
272
|
+
|
|
273
|
+
// 为了防止接口执行慢,而存储慢,导致重复请求,所以预先存储为[],接口返回后再二次存储
|
|
274
|
+
enumMap.value.set(prop!, []);
|
|
275
|
+
|
|
276
|
+
// 当前 enum 为后台数据需要请求数据,则调用该请求接口,并存储到 enumMap
|
|
277
|
+
const res = await enumValue();
|
|
278
|
+
let list = res?.result || [];
|
|
279
|
+
enumMap.value.set(prop!, list);
|
|
280
|
+
// console.log(enumMap.value);
|
|
281
|
+
};
|
|
282
|
+
// 扁平化 columns 的方法 处理字典数据 、 过滤表格部分渲染数据
|
|
283
|
+
const flatColumnsFunc = (
|
|
284
|
+
columns: ColumnProps[],
|
|
285
|
+
flatArr: ColumnProps[] = []
|
|
286
|
+
) => {
|
|
287
|
+
columns.forEach(async (col) => {
|
|
288
|
+
if (col.prop && !col.type) {
|
|
289
|
+
if (col._children?.length)
|
|
290
|
+
flatArr.push(...flatColumnsFunc(col._children));
|
|
291
|
+
flatArr.push(col);
|
|
292
|
+
|
|
293
|
+
// column 添加默认 isShow && isSetting && isFilterEnum 属性值
|
|
294
|
+
col.isShow = col.isShow ?? true;
|
|
295
|
+
col.isSetting = col.isSetting ?? true;
|
|
296
|
+
col.isFilterEnum = col.isFilterEnum ?? true;
|
|
297
|
+
|
|
298
|
+
// 设置 enumMap
|
|
299
|
+
await setEnumMap(col);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
return flatArr.filter((item) => !item._children?.length);
|
|
303
|
+
};
|
|
304
|
+
flatColumnsFunc(props.tableConfig.columns);
|
|
305
|
+
|
|
306
|
+
// 过滤需要搜索的配置项 && 排序
|
|
307
|
+
const searchColumns = computed(() => {
|
|
308
|
+
return queryItems.value
|
|
309
|
+
?.filter((item) => item.search?.el || item.search?.render)
|
|
310
|
+
.sort((a, b) => a.search!.order! - b.search!.order!);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// 设置 搜索表单默认排序 && 搜索表单项的默认值
|
|
314
|
+
searchColumns.value?.forEach((column, index) => {
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
column.search!.order = column.search?.order ?? index + 2;
|
|
318
|
+
const key = column.search?.key ?? handleProp(column.prop!);
|
|
319
|
+
const defaultValue1 = props.initParam[column.prop] || "";
|
|
320
|
+
const defaultValue = column.search?.defaultValue || defaultValue1;
|
|
321
|
+
if (defaultValue !== undefined && defaultValue !== null) {
|
|
322
|
+
searchParam.value[key] = defaultValue;
|
|
323
|
+
searchInitParam.value[key] = defaultValue;
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// 定义 emit 事件
|
|
328
|
+
const emit = defineEmits<{
|
|
329
|
+
search: [any];
|
|
330
|
+
reset: [];
|
|
331
|
+
dragSort: [{ newIndex?: number; oldIndex?: number }];
|
|
332
|
+
radioChange: [string, any];
|
|
333
|
+
tabChange: [any];
|
|
334
|
+
}>();
|
|
335
|
+
// 单选change
|
|
336
|
+
const radioChange = (rowKey, row) => {
|
|
337
|
+
emit("radioChange", rowKey, row);
|
|
338
|
+
};
|
|
339
|
+
const _search = () => {
|
|
340
|
+
search();
|
|
341
|
+
// 处理格式化数据
|
|
342
|
+
const searchForm = formatterForm({
|
|
343
|
+
...searchParam.value,
|
|
344
|
+
...props.initParam,
|
|
345
|
+
});
|
|
346
|
+
emit("search", searchForm);
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const _reset = () => {
|
|
350
|
+
reset();
|
|
351
|
+
emit("reset");
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const sortTable = ({
|
|
355
|
+
newIndex,
|
|
356
|
+
oldIndex,
|
|
357
|
+
}: {
|
|
358
|
+
newIndex?: number;
|
|
359
|
+
oldIndex?: number;
|
|
360
|
+
}) => {
|
|
361
|
+
emit("dragSort", { newIndex, oldIndex });
|
|
362
|
+
};
|
|
363
|
+
// 按钮点击
|
|
364
|
+
const handleButtonClick = (fun) => {
|
|
365
|
+
const searchForm = formatterForm({
|
|
366
|
+
...searchParam.value,
|
|
367
|
+
...props.initParam,
|
|
368
|
+
});
|
|
369
|
+
fun &&
|
|
370
|
+
fun({
|
|
371
|
+
radio: radio.value,
|
|
372
|
+
isSelected: isSelected.value,
|
|
373
|
+
selectedList: selectedList.value,
|
|
374
|
+
selectedListIds: selectedListIds.value,
|
|
375
|
+
searchParam: searchParam.value,
|
|
376
|
+
searchForm, // 经过格式化的数据 ,未删除searchParam, 兼容上面被使用的情况
|
|
377
|
+
});
|
|
378
|
+
};
|
|
379
|
+
// 暴露给父组件的参数和方法 (外部需要什么,都可以从这里暴露出去)
|
|
380
|
+
defineExpose({
|
|
381
|
+
element: tableRef,
|
|
382
|
+
tableData: processTableData,
|
|
383
|
+
pageable,
|
|
384
|
+
searchParam,
|
|
385
|
+
searchInitParam,
|
|
386
|
+
isSelected,
|
|
387
|
+
selectedList,
|
|
388
|
+
selectedListIds,
|
|
389
|
+
|
|
390
|
+
// 下面为 function
|
|
391
|
+
getTableList,
|
|
392
|
+
search,
|
|
393
|
+
reset,
|
|
394
|
+
clearSelection,
|
|
395
|
+
enumMap,
|
|
396
|
+
});
|
|
397
|
+
</script>
|
|
398
|
+
<style lang="scss" scoped>
|
|
399
|
+
@use "./index";
|
|
400
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TableConfigProps,
|
|
3
|
+
TopButtonProps,
|
|
4
|
+
} from "../../JztQueryTable/interface/index";
|
|
5
|
+
|
|
6
|
+
export * from "../../JztQueryTable/interface/index";
|
|
7
|
+
|
|
8
|
+
export interface DetailTableConfigProps extends TableConfigProps {
|
|
9
|
+
leftTopList?: TopButtonProps[];
|
|
10
|
+
}
|