@wp1001/ui 2.9.13
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/.env +6 -0
- package/@vant-D4fmGxs6.js +3891 -0
- package/index.js +8419 -0
- package/package.json +59 -0
- package/packages/assets/devtools-detector.js +2 -0
- package/packages/components/xarray/index.js +64 -0
- package/packages/components/xarray/xarray.vue +57 -0
- package/packages/components/xautorows/index.js +35 -0
- package/packages/components/xautorows/xautorows.vue +29 -0
- package/packages/components/xbutton/mobile.js +3 -0
- package/packages/components/xbutton/mobile.vue +9 -0
- package/packages/components/xbutton/pc.js +3 -0
- package/packages/components/xbutton/pc.vue +9 -0
- package/packages/components/xbuttons/mobile.js +51 -0
- package/packages/components/xbuttons/mobile.vue +12 -0
- package/packages/components/xbuttons/pc.js +51 -0
- package/packages/components/xbuttons/pc.vue +16 -0
- package/packages/components/xchart/constants.js +58 -0
- package/packages/components/xchart/index.js +263 -0
- package/packages/components/xchart/utils.js +121 -0
- package/packages/components/xchart/xchart.vue +173 -0
- package/packages/components/xcheckboxs/mobile.js +58 -0
- package/packages/components/xcheckboxs/mobile.vue +38 -0
- package/packages/components/xcheckboxs/pc.js +49 -0
- package/packages/components/xcheckboxs/pc.vue +42 -0
- package/packages/components/xcol/mobile.js +10 -0
- package/packages/components/xcol/mobile.vue +9 -0
- package/packages/components/xcol/pc.js +10 -0
- package/packages/components/xcol/pc.vue +9 -0
- package/packages/components/xdatepicker/mobile.js +71 -0
- package/packages/components/xdatepicker/mobile.vue +44 -0
- package/packages/components/xdatepicker/pc.js +9 -0
- package/packages/components/xdatepicker/pc.vue +12 -0
- package/packages/components/xdialog/mobile.js +60 -0
- package/packages/components/xdialog/mobile.vue +43 -0
- package/packages/components/xdialog/pc.js +64 -0
- package/packages/components/xdialog/pc.vue +51 -0
- package/packages/components/xdict/index.js +47 -0
- package/packages/components/xdict/xdict.vue +9 -0
- package/packages/components/xdistrictselect/mobile.js +79 -0
- package/packages/components/xdistrictselect/mobile.vue +28 -0
- package/packages/components/xdistrictselect/pc.js +127 -0
- package/packages/components/xdistrictselect/pc.vue +32 -0
- package/packages/components/xform/mobile.js +29 -0
- package/packages/components/xform/mobile.vue +43 -0
- package/packages/components/xform/pc.js +42 -0
- package/packages/components/xform/pc.vue +76 -0
- package/packages/components/xform/utils.js +95 -0
- package/packages/components/xformitem/mobile.js +56 -0
- package/packages/components/xformitem/mobile.vue +3 -0
- package/packages/components/xformitem/pc.js +72 -0
- package/packages/components/xformitem/pc.vue +10 -0
- package/packages/components/xformitem/utils.jsx +181 -0
- package/packages/components/xicon/mobile.js +35 -0
- package/packages/components/xicon/mobile.vue +9 -0
- package/packages/components/xicon/pc.js +35 -0
- package/packages/components/xicon/pc.vue +11 -0
- package/packages/components/xinfo/index.js +100 -0
- package/packages/components/xinfo/xinfo.vue +140 -0
- package/packages/components/xlooper/index.js +7 -0
- package/packages/components/xlooper/xlooper.vue +20 -0
- package/packages/components/xpagination/mobile.js +21 -0
- package/packages/components/xpagination/mobile.vue +31 -0
- package/packages/components/xpagination/pc.js +21 -0
- package/packages/components/xpagination/pc.vue +16 -0
- package/packages/components/xpicker/index.js +38 -0
- package/packages/components/xpicker/xpicker.vue +29 -0
- package/packages/components/xradios/mobile.js +40 -0
- package/packages/components/xradios/mobile.vue +22 -0
- package/packages/components/xradios/pc.js +53 -0
- package/packages/components/xradios/pc.vue +43 -0
- package/packages/components/xrow/mobile.js +9 -0
- package/packages/components/xrow/mobile.vue +23 -0
- package/packages/components/xrow/pc.js +9 -0
- package/packages/components/xrow/pc.vue +22 -0
- package/packages/components/xscan/mobile.js +24 -0
- package/packages/components/xscan/mobile.vue +21 -0
- package/packages/components/xscan/pc.js +20 -0
- package/packages/components/xscan/pc.vue +18 -0
- package/packages/components/xsearcher/index.js +198 -0
- package/packages/components/xsearcher/xsearcher.vue +170 -0
- package/packages/components/xselect/mobile.js +86 -0
- package/packages/components/xselect/mobile.vue +24 -0
- package/packages/components/xselect/pc.js +114 -0
- package/packages/components/xselect/pc.vue +55 -0
- package/packages/components/xselect/util.js +66 -0
- package/packages/components/xselectv2/index.js +91 -0
- package/packages/components/xselectv2/xselectv2.vue +46 -0
- package/packages/components/xtable/mobile.js +108 -0
- package/packages/components/xtable/mobile.vue +246 -0
- package/packages/components/xtable/pc.js +143 -0
- package/packages/components/xtable/pc.vue +421 -0
- package/packages/components/xtable/searcher.js +477 -0
- package/packages/components/xtable/searcher.jsx +330 -0
- package/packages/components/xtable/searcher.vue +133 -0
- package/packages/components/xtable/settings.js +80 -0
- package/packages/components/xtable/settings.vue +77 -0
- package/packages/components/xtable/utils.js +692 -0
- package/packages/components/xtabletools/mobile.js +25 -0
- package/packages/components/xtabletools/mobile.vue +126 -0
- package/packages/components/xtabletools/pc.js +18 -0
- package/packages/components/xtabletools/pc.vue +135 -0
- package/packages/components/xtablev2/index.js +53 -0
- package/packages/components/xtablev2/utils.jsx +214 -0
- package/packages/components/xtablev2/xtablev2.vue +147 -0
- package/packages/components/xtags/mobile.js +17 -0
- package/packages/components/xtags/mobile.vue +21 -0
- package/packages/components/xtags/pc.js +17 -0
- package/packages/components/xtags/pc.vue +22 -0
- package/packages/components/xtinymce/index.js +71 -0
- package/packages/components/xtinymce/xtinymce.vue +9 -0
- package/packages/components/xuploader/xfileuploader.js +48 -0
- package/packages/components/xuploader/xfileuploader.vue +54 -0
- package/packages/components/xuploader/ximageuploader.js +53 -0
- package/packages/components/xuploader/ximageuploader.vue +52 -0
- package/packages/comps.js +108 -0
- package/packages/controllers/BaseController.js +125 -0
- package/packages/controllers/CrudController.js +907 -0
- package/packages/controllers/TempCrudController.js +32 -0
- package/packages/controllers/index.js +15 -0
- package/packages/directives/el-table-infinite-scroll.js +55 -0
- package/packages/directives/index.js +5 -0
- package/packages/index.js +81 -0
- package/packages/index.scss +4 -0
- package/packages/layout/breadcrumb/breadcrumb.vue +31 -0
- package/packages/layout/breadcrumb/index.js +41 -0
- package/packages/layout/header/header.vue +281 -0
- package/packages/layout/header/inner.js +11 -0
- package/packages/layout/header/inner.vue +3 -0
- package/packages/layout/mobile-menu.vue +83 -0
- package/packages/layout/mobile-tabs.vue +54 -0
- package/packages/layout/pc.vue +85 -0
- package/packages/layout/screenlock/index.js +129 -0
- package/packages/layout/screenlock/screenlock.vue +85 -0
- package/packages/layout/sidebar/item.js +16 -0
- package/packages/layout/sidebar/item.vue +16 -0
- package/packages/layout/sidebar/menu.js +72 -0
- package/packages/layout/sidebar/menu.vue +106 -0
- package/packages/layout/sidebar/sidebar.vue +147 -0
- package/packages/layout/tagsview/ScrollPane.js +65 -0
- package/packages/layout/tagsview/ScrollPane.vue +24 -0
- package/packages/layout/tagsview/index.js +169 -0
- package/packages/layout/tagsview/index.vue +124 -0
- package/packages/plop/actions/make-fill-admin-partials-action.js +95 -0
- package/packages/plop/generators/make-admin-page.js +39 -0
- package/packages/plop/generators/make-database-admin-pages.js +84 -0
- package/packages/plop/generators/make-page-generator.js +52 -0
- package/packages/plop/generators/make-simple-page.js +20 -0
- package/packages/plop/plopfile.js +24 -0
- package/packages/plop/templates/admin_page/controller.js +3 -0
- package/packages/plop/templates/admin_page/model.js +24 -0
- package/packages/plop/templates/admin_page/{{snakeCase pagename}}-scoped.scss +3 -0
- package/packages/plop/templates/admin_page/{{snakeCase pagename}}.vue +11 -0
- package/packages/plop/templates/simple_page/controller.js +3 -0
- package/packages/plop/templates/simple_page/model.js +6 -0
- package/packages/plop/templates/simple_page/{{snakeCase pagename}}-scoped.scss +3 -0
- package/packages/plop/templates/simple_page/{{snakeCase pagename}}.vue +7 -0
- package/packages/plop/utils/index.js +168 -0
- package/packages/plop/utils/plop-utils.js +86 -0
- package/packages/styles/common.scss +137 -0
- package/packages/styles/element-ui.scss +142 -0
- package/packages/styles/vant.scss +133 -0
- package/packages/styles/variables.scss +23 -0
- package/packages/utils/crypt.js +24 -0
- package/packages/utils/decorators.js +67 -0
- package/packages/utils/disallowDevtools.js +53 -0
- package/packages/utils/effects.js +173 -0
- package/packages/utils/funcs.js +78 -0
- package/packages/utils/index.js +95 -0
- package/packages/utils/message.js +110 -0
- package/packages/utils/middlewares.js +86 -0
- package/packages/utils/model.js +71 -0
- package/packages/utils/modelUtils.js +203 -0
- package/packages/utils/request.js +57 -0
- package/packages/utils/site.js +33 -0
- package/packages/vite-plugins.js +141 -0
- package/publish.sh +12 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { h, resolveComponent } from 'vue'
|
|
2
|
+
|
|
3
|
+
export const OPS = {
|
|
4
|
+
eq: { text: '等于', value: 'eq' },
|
|
5
|
+
ne: { text: '不等于', value: 'ne' },
|
|
6
|
+
gt: { text: '大于', value: 'gt' },
|
|
7
|
+
gte: { text: '大于等于', value: 'gte' },
|
|
8
|
+
lt: { text: '小于', value: 'lt' },
|
|
9
|
+
lte: { text: '小于等于', value: 'lte' },
|
|
10
|
+
'in': { text: '包含', value: 'in' },
|
|
11
|
+
like: { text: '模糊匹配', value: 'like' },
|
|
12
|
+
notIn: { text: '不包含', value: 'notIn' },
|
|
13
|
+
notLike: { text: '模糊不匹配', value: 'notLike' },
|
|
14
|
+
between: { text: '介于', value: 'between' },
|
|
15
|
+
special: { text: '特殊值', value: 'special' }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const SPECIAL_OPTIONS = [
|
|
19
|
+
{ text: 'NULL', value: 'NULL' },
|
|
20
|
+
{ text: '空文本', value: 'BLANK' },
|
|
21
|
+
{ text: '非NULL', value: 'NOT_NULL' },
|
|
22
|
+
{ text: '非空文本', value: 'NE_BLANK' },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
export const COMPONENT_OPS = {
|
|
26
|
+
'XSelect': ['eq', 'ne', 'in', 'notIn', 'special'],
|
|
27
|
+
'XRadios': ['eq', 'ne', 'special'],
|
|
28
|
+
'XCheckboxs': ['eq', 'ne', 'in', 'notIn', 'special'],
|
|
29
|
+
'XSearcher': ['eq', 'ne', 'special'],
|
|
30
|
+
'ElDatePicker': ['eq', 'gt', 'gte', 'lt', 'lte', 'between', 'in', 'notIn', 'special'],
|
|
31
|
+
'ElInputNumber': ['eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'between', 'in', 'notIn', 'special'],
|
|
32
|
+
'ElInput': ['eq', 'ne', 'like', 'notLike', 'between', 'in', 'notIn', 'special'],
|
|
33
|
+
'universal': ['eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'in', 'like', 'notIn', 'notLike', 'between', 'special']
|
|
34
|
+
}
|
|
35
|
+
COMPONENT_OPS['x-select'] = COMPONENT_OPS['XSelect']
|
|
36
|
+
COMPONENT_OPS['XSelectV2'] = COMPONENT_OPS['XSelect']
|
|
37
|
+
COMPONENT_OPS['x-select-v2'] = COMPONENT_OPS['XSelect']
|
|
38
|
+
COMPONENT_OPS['x-radios'] = COMPONENT_OPS['XRadios']
|
|
39
|
+
COMPONENT_OPS['x-checkboxs'] = COMPONENT_OPS['XCheckboxs']
|
|
40
|
+
COMPONENT_OPS['x-searcher'] = COMPONENT_OPS['XSearcher']
|
|
41
|
+
COMPONENT_OPS['XImageUploader'] = COMPONENT_OPS['ElInput']
|
|
42
|
+
COMPONENT_OPS['x-image-uploader'] = COMPONENT_OPS['ElInput']
|
|
43
|
+
COMPONENT_OPS['XFileUploader'] = COMPONENT_OPS['ElInput']
|
|
44
|
+
COMPONENT_OPS['x-file-uploader'] = COMPONENT_OPS['ElInput']
|
|
45
|
+
COMPONENT_OPS['el-date-picker'] = COMPONENT_OPS['ElDatePicker']
|
|
46
|
+
COMPONENT_OPS['el-input-number'] = COMPONENT_OPS['ElInputNumber']
|
|
47
|
+
COMPONENT_OPS['el-input'] = COMPONENT_OPS['ElInput']
|
|
48
|
+
|
|
49
|
+
export default function () {
|
|
50
|
+
const size = window.isMobile ? 'small' : ''
|
|
51
|
+
const {
|
|
52
|
+
$attrs, config, columns, visible, conditions, expression, uid, views, viewName, sorts, currentView,
|
|
53
|
+
handleSearch, handleReset, handleAdd, handleDelete, handleSelectField, handleSelectOp,
|
|
54
|
+
handleSelectView, handleSaveView, handleDeleteView, handleSearchView
|
|
55
|
+
} = this
|
|
56
|
+
|
|
57
|
+
const tourGuide = h(resolveComponent('el-tour'), {
|
|
58
|
+
modelValue: this.tourGuide.visible,
|
|
59
|
+
'onUpdate:modelValue': value => this.tourGuide.visible = value
|
|
60
|
+
}, this.tourGuide.steps.map(s => h(resolveComponent('el-tour-step'), s, {
|
|
61
|
+
default: () => h('div', { innerHTML: s.description })
|
|
62
|
+
})))
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<x-dialog
|
|
66
|
+
append-to-body
|
|
67
|
+
drawer
|
|
68
|
+
width="700px"
|
|
69
|
+
title={$attrs.title || '高级查询'}
|
|
70
|
+
class="searcher"
|
|
71
|
+
cancel-text="重置"
|
|
72
|
+
submit-text={$attrs['submit-text'] || '查询'}
|
|
73
|
+
{...{
|
|
74
|
+
modelValue: visible,
|
|
75
|
+
'onUpdate:modelValue': value => this.visible = value,
|
|
76
|
+
onCancel: handleReset,
|
|
77
|
+
onSubmit: handleSearch
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
<el-tabs
|
|
81
|
+
{...{
|
|
82
|
+
modelValue: this.activeName,
|
|
83
|
+
'onUpdate:modelValue': value => this.activeName = value,
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
<el-tab-pane name="search" label="查询设置" class="search">
|
|
87
|
+
{
|
|
88
|
+
config.traditional
|
|
89
|
+
? null
|
|
90
|
+
: <el-row gutter={10} class="searcher-tools">
|
|
91
|
+
<el-col span={8}>
|
|
92
|
+
<x-button
|
|
93
|
+
type="primary"
|
|
94
|
+
size={size}
|
|
95
|
+
icon="plus"
|
|
96
|
+
class="add-condition"
|
|
97
|
+
onClick={handleAdd}
|
|
98
|
+
>新增条件</x-button>
|
|
99
|
+
</el-col>
|
|
100
|
+
<el-col span={16} class="views-select">
|
|
101
|
+
{
|
|
102
|
+
uid && conditions.length
|
|
103
|
+
? <el-button
|
|
104
|
+
type="primary"
|
|
105
|
+
text
|
|
106
|
+
class="save-view"
|
|
107
|
+
onClick={() => handleSaveView()}
|
|
108
|
+
>保存当前视图</el-button>
|
|
109
|
+
: null
|
|
110
|
+
}
|
|
111
|
+
{
|
|
112
|
+
views.length
|
|
113
|
+
? <el-select
|
|
114
|
+
placeholder={views.length ? '选择查询视图' : '自查询条件可保存为视图'}
|
|
115
|
+
clearable
|
|
116
|
+
class="views-select"
|
|
117
|
+
{...{
|
|
118
|
+
modelValue: viewName,
|
|
119
|
+
'onUpdate:modelValue': value => this.viewName = value
|
|
120
|
+
}}
|
|
121
|
+
onChange={name => handleSelectView(name)}
|
|
122
|
+
>
|
|
123
|
+
{views.map((view, index) => (
|
|
124
|
+
<el-option
|
|
125
|
+
label={view.name}
|
|
126
|
+
value={view.name}
|
|
127
|
+
class="view-option flex-center"
|
|
128
|
+
>
|
|
129
|
+
<span>{view.name}</span>
|
|
130
|
+
{
|
|
131
|
+
view.is_system
|
|
132
|
+
? <el-tag type="success">系统</el-tag>
|
|
133
|
+
: <el-button
|
|
134
|
+
type="danger"
|
|
135
|
+
plain
|
|
136
|
+
size="small"
|
|
137
|
+
icon="DeleteFilled"
|
|
138
|
+
class="delete-view"
|
|
139
|
+
onClick={e => handleDeleteView(view, index, e)}
|
|
140
|
+
/>
|
|
141
|
+
}
|
|
142
|
+
</el-option>
|
|
143
|
+
))}
|
|
144
|
+
</el-select>
|
|
145
|
+
: null
|
|
146
|
+
}
|
|
147
|
+
</el-col>
|
|
148
|
+
</el-row>
|
|
149
|
+
}
|
|
150
|
+
<div class="conditions">
|
|
151
|
+
{
|
|
152
|
+
conditions.map((condition, index) => {
|
|
153
|
+
return (
|
|
154
|
+
<div class="condition flex-center" key={condition.no}>
|
|
155
|
+
{
|
|
156
|
+
config.traditional
|
|
157
|
+
? null
|
|
158
|
+
: <el-button
|
|
159
|
+
type="danger"
|
|
160
|
+
size={size}
|
|
161
|
+
plain
|
|
162
|
+
icon="Delete"
|
|
163
|
+
onClick={() => handleDelete(index)}
|
|
164
|
+
/>
|
|
165
|
+
}
|
|
166
|
+
{
|
|
167
|
+
config.traditional
|
|
168
|
+
? null
|
|
169
|
+
: <span class="title">{condition.no}</span>
|
|
170
|
+
}
|
|
171
|
+
<div class="expression">
|
|
172
|
+
{
|
|
173
|
+
config.traditional
|
|
174
|
+
? <el-input modelValue={condition.item.label} readonly />
|
|
175
|
+
: <pc-x-select
|
|
176
|
+
modelValue={condition.prop}
|
|
177
|
+
onChange={value => handleSelectField(condition, value)}
|
|
178
|
+
options={columns}
|
|
179
|
+
text="label"
|
|
180
|
+
value="prop"
|
|
181
|
+
class="field-select"
|
|
182
|
+
></pc-x-select>
|
|
183
|
+
}
|
|
184
|
+
<pc-x-select
|
|
185
|
+
modelValue={condition.op}
|
|
186
|
+
onChange={value => handleSelectOp(condition, value)}
|
|
187
|
+
options={condition.ops}
|
|
188
|
+
class="condition-select"
|
|
189
|
+
/>
|
|
190
|
+
<div class="value-container">
|
|
191
|
+
{calcConditionValueComponent(this, condition)}
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
)
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
</div>
|
|
199
|
+
{
|
|
200
|
+
config.traditional ? null : <div>
|
|
201
|
+
<el-input
|
|
202
|
+
type="textarea"
|
|
203
|
+
autosize={{ minRows: 3, maxRows: 10 }}
|
|
204
|
+
placeholder="分组条件表达式, 使用 () and or 组合上述条件, 示例: 1, 1 and 2, (1 or 2) and 3"
|
|
205
|
+
class="condition-expression"
|
|
206
|
+
{...{
|
|
207
|
+
modelValue: expression,
|
|
208
|
+
'onUpdate:modelValue': value => this.expression = value
|
|
209
|
+
}}
|
|
210
|
+
></el-input>
|
|
211
|
+
</div>
|
|
212
|
+
}
|
|
213
|
+
{
|
|
214
|
+
config.traditional ? null : <div class="view-tags">
|
|
215
|
+
<el-button type="primary" link class="guide" onClick={() => this.tourGuide.visible = true}>高级查询-使用指南</el-button>
|
|
216
|
+
<span class="search-views">搜索视图:</span>
|
|
217
|
+
{
|
|
218
|
+
views.map((view, index) => (
|
|
219
|
+
<el-tag type="success" key={index} onClick={() => handleSearchView(view)}>{ view.name }</el-tag>
|
|
220
|
+
))
|
|
221
|
+
}
|
|
222
|
+
</div>
|
|
223
|
+
}
|
|
224
|
+
{tourGuide}
|
|
225
|
+
</el-tab-pane>
|
|
226
|
+
{
|
|
227
|
+
!currentView || currentView.is_system
|
|
228
|
+
? null
|
|
229
|
+
: <el-tab-pane name="sorts" label={'多列排序 [视图: ' + currentView?.name + ']'} class="sorts">
|
|
230
|
+
<el-button type="primary" icon="Plus" onClick={this.handleAddSort}>添加排序</el-button>
|
|
231
|
+
<div class="sort-list">
|
|
232
|
+
{
|
|
233
|
+
sorts.map((sort, index) => (
|
|
234
|
+
<div
|
|
235
|
+
key={sort[0]}
|
|
236
|
+
data-prop={sort[0]}
|
|
237
|
+
class="row flex-center"
|
|
238
|
+
>
|
|
239
|
+
<x-select
|
|
240
|
+
{...{
|
|
241
|
+
modelValue: sort[0],
|
|
242
|
+
'onUpdate:modelValue': value => sort[0] = value
|
|
243
|
+
}}
|
|
244
|
+
options={this.sortableColumns}
|
|
245
|
+
text="label"
|
|
246
|
+
value="prop"
|
|
247
|
+
teleported={false}
|
|
248
|
+
clearable={false}
|
|
249
|
+
/>
|
|
250
|
+
<x-radios
|
|
251
|
+
{...{
|
|
252
|
+
modelValue: sort[1],
|
|
253
|
+
'onUpdate:modelValue': value => sort[1] = value
|
|
254
|
+
}}
|
|
255
|
+
options={this.sortOptions}
|
|
256
|
+
/>
|
|
257
|
+
<el-button
|
|
258
|
+
type="danger" plain icon="DeleteFilled"
|
|
259
|
+
onClick={() => sorts.splice(index, 1)}
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
))
|
|
263
|
+
}
|
|
264
|
+
</div>
|
|
265
|
+
</el-tab-pane>
|
|
266
|
+
}
|
|
267
|
+
</el-tabs>
|
|
268
|
+
</x-dialog>
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function calcConditionValueComponent (vm, condition) {
|
|
273
|
+
const component = (options) => {
|
|
274
|
+
let comp = options?.component || condition.component
|
|
275
|
+
if (comp.startsWith('x-select')) {
|
|
276
|
+
comp = 'pc-' + comp
|
|
277
|
+
}
|
|
278
|
+
if (comp.includes('ploader')) comp = 'ElInput'
|
|
279
|
+
return h(
|
|
280
|
+
resolveComponent(comp),
|
|
281
|
+
Object.assign(
|
|
282
|
+
{},
|
|
283
|
+
{ ...condition.config, style: undefined },
|
|
284
|
+
{
|
|
285
|
+
modelValue: condition.value,
|
|
286
|
+
'onUpdate:modelValue': (value) => condition.value = value,
|
|
287
|
+
onKeyup: e => {
|
|
288
|
+
if (e.key === 'Enter' && (!comp || !/select/i.test(comp))) {
|
|
289
|
+
vm.handleSearch()
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
options
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
const options = { multiple: false }
|
|
298
|
+
if (condition.op === 'between') {
|
|
299
|
+
return <div class="col-2">
|
|
300
|
+
{
|
|
301
|
+
component({
|
|
302
|
+
...options,
|
|
303
|
+
modelValue: condition.value[0],
|
|
304
|
+
'onUpdate:modelValue': (value) => condition.value[0] = value
|
|
305
|
+
})
|
|
306
|
+
}
|
|
307
|
+
{
|
|
308
|
+
component({
|
|
309
|
+
...options,
|
|
310
|
+
modelValue: condition.value[1],
|
|
311
|
+
'onUpdate:modelValue': (value) => condition.value[1] = value
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
</div>
|
|
315
|
+
} else if (['in', 'notIn'].includes(condition.op)) {
|
|
316
|
+
options.multiple = true
|
|
317
|
+
if (!condition.item.options) {
|
|
318
|
+
options.placeholder = '可以填写多项,用英文逗号分割'
|
|
319
|
+
}
|
|
320
|
+
return component(options)
|
|
321
|
+
} else if (condition.op === 'special') {
|
|
322
|
+
return component({
|
|
323
|
+
...options,
|
|
324
|
+
component: 'pc-x-select',
|
|
325
|
+
placeholder: '请选择特殊值',
|
|
326
|
+
options: SPECIAL_OPTIONS
|
|
327
|
+
})
|
|
328
|
+
}
|
|
329
|
+
return component()
|
|
330
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export { default } from './searcher.js'
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<style lang="scss" scoped>
|
|
6
|
+
.searcher {
|
|
7
|
+
.views-select {
|
|
8
|
+
position: relative;
|
|
9
|
+
.el-select {
|
|
10
|
+
position: absolute;
|
|
11
|
+
right: 5px;
|
|
12
|
+
top: 0;
|
|
13
|
+
width: calc(100% - 115px);
|
|
14
|
+
}
|
|
15
|
+
.el-button {
|
|
16
|
+
width: 100px;
|
|
17
|
+
margin-right: 10px;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
.view-tags {
|
|
21
|
+
margin-bottom: 10px;
|
|
22
|
+
.guide {
|
|
23
|
+
margin-top: 10px;
|
|
24
|
+
margin-right: 10px;
|
|
25
|
+
}
|
|
26
|
+
.search-views {
|
|
27
|
+
display: inline-block;
|
|
28
|
+
margin-top: 10px;
|
|
29
|
+
line-height: 24px;
|
|
30
|
+
vertical-align: top;
|
|
31
|
+
}
|
|
32
|
+
.el-tag {
|
|
33
|
+
margin-right: 10px;
|
|
34
|
+
margin-top: 10px;
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
&:hover {
|
|
37
|
+
opacity: 0.7;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
.conditions {
|
|
42
|
+
margin: 10px 0;
|
|
43
|
+
max-height: 60vh;
|
|
44
|
+
overflow-y: auto;
|
|
45
|
+
border-top: 1px solid #d0dddd;
|
|
46
|
+
}
|
|
47
|
+
.condition {
|
|
48
|
+
border: 1px solid #d0dddd;
|
|
49
|
+
border-top: 0;
|
|
50
|
+
padding: 7px;
|
|
51
|
+
}
|
|
52
|
+
.el-tag {
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
flex: 1;
|
|
55
|
+
}
|
|
56
|
+
.title {
|
|
57
|
+
margin: 0 10px;
|
|
58
|
+
flex: 1;
|
|
59
|
+
}
|
|
60
|
+
.expression {
|
|
61
|
+
flex: 30;
|
|
62
|
+
display: grid;
|
|
63
|
+
grid-template-columns: 27% 19% 50%;
|
|
64
|
+
column-gap: 10px;
|
|
65
|
+
& > * {
|
|
66
|
+
width: 100%;
|
|
67
|
+
}
|
|
68
|
+
.field-select {
|
|
69
|
+
max-width: 151px;
|
|
70
|
+
}
|
|
71
|
+
.condition-select {
|
|
72
|
+
max-width: 106px;
|
|
73
|
+
}
|
|
74
|
+
:deep(.value-container) > * {
|
|
75
|
+
width: 100%;
|
|
76
|
+
max-width: 280px;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
.col-2 {
|
|
80
|
+
display: grid;
|
|
81
|
+
grid-template-columns: repeat(2, 1fr);
|
|
82
|
+
column-gap: 10px;
|
|
83
|
+
position: relative;
|
|
84
|
+
&::after {
|
|
85
|
+
content: '-';
|
|
86
|
+
position: absolute;
|
|
87
|
+
left: 50%;
|
|
88
|
+
top: 50%;
|
|
89
|
+
transform: translate(-50%, -50%);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
.el-tabs {
|
|
93
|
+
height: 100%;
|
|
94
|
+
margin-top: -15px;
|
|
95
|
+
:deep(.el-tabs__content) {
|
|
96
|
+
height: calc(100% - 40px);
|
|
97
|
+
.el-tab-pane {
|
|
98
|
+
height: 100%;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
.sorts {
|
|
103
|
+
.sort-list {
|
|
104
|
+
height: calc(100% - 10px);
|
|
105
|
+
overflow-y: auto;
|
|
106
|
+
}
|
|
107
|
+
.row {
|
|
108
|
+
justify-content: start;
|
|
109
|
+
margin: 10px 0;
|
|
110
|
+
}
|
|
111
|
+
.el-select {
|
|
112
|
+
width: 200px;
|
|
113
|
+
margin-right: 10px;
|
|
114
|
+
}
|
|
115
|
+
.el-radio-group {
|
|
116
|
+
width: 180px;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
:deep(.col-2) > * {
|
|
121
|
+
width: 100% !important;
|
|
122
|
+
}
|
|
123
|
+
.mobile-x-dialog .expression {
|
|
124
|
+
display: block;
|
|
125
|
+
& > * {
|
|
126
|
+
margin: 3px 0;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
.view-option {
|
|
130
|
+
justify-content: space-between;
|
|
131
|
+
padding: 0 10px;
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Confirm } from '../../utils/message.js'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: 'Settings',
|
|
5
|
+
props: {
|
|
6
|
+
modelValue: Object
|
|
7
|
+
},
|
|
8
|
+
emits: ['update:modelValue', 'reset', 'init', 'save'],
|
|
9
|
+
data () {
|
|
10
|
+
return {
|
|
11
|
+
activeName: 'columns',
|
|
12
|
+
columns: []
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
computed: {
|
|
16
|
+
hideColumns () {
|
|
17
|
+
const value = this.$attrs['hide-settings-columns']
|
|
18
|
+
return value === '' || value === true
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
watch: {
|
|
22
|
+
modelValue: {
|
|
23
|
+
handler (value) {
|
|
24
|
+
this.columns = value.columns.map(col => {
|
|
25
|
+
return {
|
|
26
|
+
...col,
|
|
27
|
+
show: col.show !== false,
|
|
28
|
+
width: col.width || col.minWidth
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
},
|
|
32
|
+
immediate: true
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async mounted () {
|
|
36
|
+
await window.DynamicLibs?.use('Sortable')
|
|
37
|
+
this.initDraggable()
|
|
38
|
+
},
|
|
39
|
+
beforeUnmount () {
|
|
40
|
+
this.sortable?.destroy()
|
|
41
|
+
},
|
|
42
|
+
methods: {
|
|
43
|
+
initDraggable () {
|
|
44
|
+
const dict = {}
|
|
45
|
+
this.columns.forEach(col => dict[col.prop] = col)
|
|
46
|
+
this.sortable = new window.Sortable(this.$refs.colsTable, {
|
|
47
|
+
sort: true,
|
|
48
|
+
draggable: '.row',
|
|
49
|
+
onEnd: (e) => {
|
|
50
|
+
const props = [...e.to.querySelectorAll('.row')].map(e => e.dataset.prop)
|
|
51
|
+
this.columns = props.map(p => dict[p])
|
|
52
|
+
this.update()
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
},
|
|
56
|
+
async handleResetColumns () {
|
|
57
|
+
if (!await Confirm.w({ message: '确定重置吗?', title: '警告' })) return
|
|
58
|
+
this.columns = []
|
|
59
|
+
this.update()
|
|
60
|
+
this.$emit('init')
|
|
61
|
+
},
|
|
62
|
+
handleToggle (column) {
|
|
63
|
+
column.show = !column.show
|
|
64
|
+
this.update()
|
|
65
|
+
},
|
|
66
|
+
update () {
|
|
67
|
+
this.columns.forEach(col => {
|
|
68
|
+
col.hide = !col.show
|
|
69
|
+
})
|
|
70
|
+
const modelValue = {
|
|
71
|
+
...this.modelValue,
|
|
72
|
+
columns: this.columns.map(col => {
|
|
73
|
+
const { prop, label, show, hide, width } = col
|
|
74
|
+
return { prop, label, show, hide, width }
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
this.$emit('save', modelValue)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export { default } from './settings.js'
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div>
|
|
7
|
+
<el-popover
|
|
8
|
+
placement="bottom"
|
|
9
|
+
trigger="hover"
|
|
10
|
+
popper-class="table-settings"
|
|
11
|
+
v-bind="$attrs"
|
|
12
|
+
>
|
|
13
|
+
<template #reference>
|
|
14
|
+
<el-button class="settings-reference" icon="Setting" />
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<el-tabs v-model="activeName">
|
|
18
|
+
<el-tab-pane v-if="!hideColumns" name="columns" label="展示列">
|
|
19
|
+
<el-button type="warning" plain icon="Close" @click="handleResetColumns">重置</el-button>
|
|
20
|
+
<div class="table" ref="colsTable">
|
|
21
|
+
<div
|
|
22
|
+
v-for="column in columns"
|
|
23
|
+
:key="column.prop"
|
|
24
|
+
:data-prop="column.prop"
|
|
25
|
+
class="row flex-center"
|
|
26
|
+
>
|
|
27
|
+
<el-icon><Sort /></el-icon>
|
|
28
|
+
<ElCheckbox v-model="column.show" @change="update" />
|
|
29
|
+
<span class="label overflow-text" :title="column.label" @click="handleToggle(column)">
|
|
30
|
+
{{ column.label }}
|
|
31
|
+
</span>
|
|
32
|
+
<el-input-number v-model="column.width" @change="update" />
|
|
33
|
+
<span class="unit">px</span>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</el-tab-pane>
|
|
37
|
+
</el-tabs>
|
|
38
|
+
</el-popover>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<style lang="scss" scoped>
|
|
43
|
+
.table-settings {
|
|
44
|
+
.el-tabs {
|
|
45
|
+
:deep(.el-tabs__content) {
|
|
46
|
+
max-height: 60vh !important;
|
|
47
|
+
overflow-y: auto;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
.el-checkbox {
|
|
51
|
+
margin: 0 5px;
|
|
52
|
+
}
|
|
53
|
+
.table {
|
|
54
|
+
margin-top: 10px;
|
|
55
|
+
border-top: 1px solid #d0dddd;
|
|
56
|
+
min-height: 200px;
|
|
57
|
+
}
|
|
58
|
+
.row {
|
|
59
|
+
justify-content: space-between;
|
|
60
|
+
border: 1px solid #d0dddd;
|
|
61
|
+
padding: 5px 10px;
|
|
62
|
+
border-top: 0;
|
|
63
|
+
}
|
|
64
|
+
.label {
|
|
65
|
+
display: inline-block;
|
|
66
|
+
width: calc(100% - 200px);
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
}
|
|
69
|
+
.el-input-number {
|
|
70
|
+
width: 130px;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
.settings-reference {
|
|
74
|
+
padding: 0 10px;
|
|
75
|
+
font-size: 18px;
|
|
76
|
+
}
|
|
77
|
+
</style>
|