@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.
Files changed (177) hide show
  1. package/.env +6 -0
  2. package/@vant-D4fmGxs6.js +3891 -0
  3. package/index.js +8419 -0
  4. package/package.json +59 -0
  5. package/packages/assets/devtools-detector.js +2 -0
  6. package/packages/components/xarray/index.js +64 -0
  7. package/packages/components/xarray/xarray.vue +57 -0
  8. package/packages/components/xautorows/index.js +35 -0
  9. package/packages/components/xautorows/xautorows.vue +29 -0
  10. package/packages/components/xbutton/mobile.js +3 -0
  11. package/packages/components/xbutton/mobile.vue +9 -0
  12. package/packages/components/xbutton/pc.js +3 -0
  13. package/packages/components/xbutton/pc.vue +9 -0
  14. package/packages/components/xbuttons/mobile.js +51 -0
  15. package/packages/components/xbuttons/mobile.vue +12 -0
  16. package/packages/components/xbuttons/pc.js +51 -0
  17. package/packages/components/xbuttons/pc.vue +16 -0
  18. package/packages/components/xchart/constants.js +58 -0
  19. package/packages/components/xchart/index.js +263 -0
  20. package/packages/components/xchart/utils.js +121 -0
  21. package/packages/components/xchart/xchart.vue +173 -0
  22. package/packages/components/xcheckboxs/mobile.js +58 -0
  23. package/packages/components/xcheckboxs/mobile.vue +38 -0
  24. package/packages/components/xcheckboxs/pc.js +49 -0
  25. package/packages/components/xcheckboxs/pc.vue +42 -0
  26. package/packages/components/xcol/mobile.js +10 -0
  27. package/packages/components/xcol/mobile.vue +9 -0
  28. package/packages/components/xcol/pc.js +10 -0
  29. package/packages/components/xcol/pc.vue +9 -0
  30. package/packages/components/xdatepicker/mobile.js +71 -0
  31. package/packages/components/xdatepicker/mobile.vue +44 -0
  32. package/packages/components/xdatepicker/pc.js +9 -0
  33. package/packages/components/xdatepicker/pc.vue +12 -0
  34. package/packages/components/xdialog/mobile.js +60 -0
  35. package/packages/components/xdialog/mobile.vue +43 -0
  36. package/packages/components/xdialog/pc.js +64 -0
  37. package/packages/components/xdialog/pc.vue +51 -0
  38. package/packages/components/xdict/index.js +47 -0
  39. package/packages/components/xdict/xdict.vue +9 -0
  40. package/packages/components/xdistrictselect/mobile.js +79 -0
  41. package/packages/components/xdistrictselect/mobile.vue +28 -0
  42. package/packages/components/xdistrictselect/pc.js +127 -0
  43. package/packages/components/xdistrictselect/pc.vue +32 -0
  44. package/packages/components/xform/mobile.js +29 -0
  45. package/packages/components/xform/mobile.vue +43 -0
  46. package/packages/components/xform/pc.js +42 -0
  47. package/packages/components/xform/pc.vue +76 -0
  48. package/packages/components/xform/utils.js +95 -0
  49. package/packages/components/xformitem/mobile.js +56 -0
  50. package/packages/components/xformitem/mobile.vue +3 -0
  51. package/packages/components/xformitem/pc.js +72 -0
  52. package/packages/components/xformitem/pc.vue +10 -0
  53. package/packages/components/xformitem/utils.jsx +181 -0
  54. package/packages/components/xicon/mobile.js +35 -0
  55. package/packages/components/xicon/mobile.vue +9 -0
  56. package/packages/components/xicon/pc.js +35 -0
  57. package/packages/components/xicon/pc.vue +11 -0
  58. package/packages/components/xinfo/index.js +100 -0
  59. package/packages/components/xinfo/xinfo.vue +140 -0
  60. package/packages/components/xlooper/index.js +7 -0
  61. package/packages/components/xlooper/xlooper.vue +20 -0
  62. package/packages/components/xpagination/mobile.js +21 -0
  63. package/packages/components/xpagination/mobile.vue +31 -0
  64. package/packages/components/xpagination/pc.js +21 -0
  65. package/packages/components/xpagination/pc.vue +16 -0
  66. package/packages/components/xpicker/index.js +38 -0
  67. package/packages/components/xpicker/xpicker.vue +29 -0
  68. package/packages/components/xradios/mobile.js +40 -0
  69. package/packages/components/xradios/mobile.vue +22 -0
  70. package/packages/components/xradios/pc.js +53 -0
  71. package/packages/components/xradios/pc.vue +43 -0
  72. package/packages/components/xrow/mobile.js +9 -0
  73. package/packages/components/xrow/mobile.vue +23 -0
  74. package/packages/components/xrow/pc.js +9 -0
  75. package/packages/components/xrow/pc.vue +22 -0
  76. package/packages/components/xscan/mobile.js +24 -0
  77. package/packages/components/xscan/mobile.vue +21 -0
  78. package/packages/components/xscan/pc.js +20 -0
  79. package/packages/components/xscan/pc.vue +18 -0
  80. package/packages/components/xsearcher/index.js +198 -0
  81. package/packages/components/xsearcher/xsearcher.vue +170 -0
  82. package/packages/components/xselect/mobile.js +86 -0
  83. package/packages/components/xselect/mobile.vue +24 -0
  84. package/packages/components/xselect/pc.js +114 -0
  85. package/packages/components/xselect/pc.vue +55 -0
  86. package/packages/components/xselect/util.js +66 -0
  87. package/packages/components/xselectv2/index.js +91 -0
  88. package/packages/components/xselectv2/xselectv2.vue +46 -0
  89. package/packages/components/xtable/mobile.js +108 -0
  90. package/packages/components/xtable/mobile.vue +246 -0
  91. package/packages/components/xtable/pc.js +143 -0
  92. package/packages/components/xtable/pc.vue +421 -0
  93. package/packages/components/xtable/searcher.js +477 -0
  94. package/packages/components/xtable/searcher.jsx +330 -0
  95. package/packages/components/xtable/searcher.vue +133 -0
  96. package/packages/components/xtable/settings.js +80 -0
  97. package/packages/components/xtable/settings.vue +77 -0
  98. package/packages/components/xtable/utils.js +692 -0
  99. package/packages/components/xtabletools/mobile.js +25 -0
  100. package/packages/components/xtabletools/mobile.vue +126 -0
  101. package/packages/components/xtabletools/pc.js +18 -0
  102. package/packages/components/xtabletools/pc.vue +135 -0
  103. package/packages/components/xtablev2/index.js +53 -0
  104. package/packages/components/xtablev2/utils.jsx +214 -0
  105. package/packages/components/xtablev2/xtablev2.vue +147 -0
  106. package/packages/components/xtags/mobile.js +17 -0
  107. package/packages/components/xtags/mobile.vue +21 -0
  108. package/packages/components/xtags/pc.js +17 -0
  109. package/packages/components/xtags/pc.vue +22 -0
  110. package/packages/components/xtinymce/index.js +71 -0
  111. package/packages/components/xtinymce/xtinymce.vue +9 -0
  112. package/packages/components/xuploader/xfileuploader.js +48 -0
  113. package/packages/components/xuploader/xfileuploader.vue +54 -0
  114. package/packages/components/xuploader/ximageuploader.js +53 -0
  115. package/packages/components/xuploader/ximageuploader.vue +52 -0
  116. package/packages/comps.js +108 -0
  117. package/packages/controllers/BaseController.js +125 -0
  118. package/packages/controllers/CrudController.js +907 -0
  119. package/packages/controllers/TempCrudController.js +32 -0
  120. package/packages/controllers/index.js +15 -0
  121. package/packages/directives/el-table-infinite-scroll.js +55 -0
  122. package/packages/directives/index.js +5 -0
  123. package/packages/index.js +81 -0
  124. package/packages/index.scss +4 -0
  125. package/packages/layout/breadcrumb/breadcrumb.vue +31 -0
  126. package/packages/layout/breadcrumb/index.js +41 -0
  127. package/packages/layout/header/header.vue +281 -0
  128. package/packages/layout/header/inner.js +11 -0
  129. package/packages/layout/header/inner.vue +3 -0
  130. package/packages/layout/mobile-menu.vue +83 -0
  131. package/packages/layout/mobile-tabs.vue +54 -0
  132. package/packages/layout/pc.vue +85 -0
  133. package/packages/layout/screenlock/index.js +129 -0
  134. package/packages/layout/screenlock/screenlock.vue +85 -0
  135. package/packages/layout/sidebar/item.js +16 -0
  136. package/packages/layout/sidebar/item.vue +16 -0
  137. package/packages/layout/sidebar/menu.js +72 -0
  138. package/packages/layout/sidebar/menu.vue +106 -0
  139. package/packages/layout/sidebar/sidebar.vue +147 -0
  140. package/packages/layout/tagsview/ScrollPane.js +65 -0
  141. package/packages/layout/tagsview/ScrollPane.vue +24 -0
  142. package/packages/layout/tagsview/index.js +169 -0
  143. package/packages/layout/tagsview/index.vue +124 -0
  144. package/packages/plop/actions/make-fill-admin-partials-action.js +95 -0
  145. package/packages/plop/generators/make-admin-page.js +39 -0
  146. package/packages/plop/generators/make-database-admin-pages.js +84 -0
  147. package/packages/plop/generators/make-page-generator.js +52 -0
  148. package/packages/plop/generators/make-simple-page.js +20 -0
  149. package/packages/plop/plopfile.js +24 -0
  150. package/packages/plop/templates/admin_page/controller.js +3 -0
  151. package/packages/plop/templates/admin_page/model.js +24 -0
  152. package/packages/plop/templates/admin_page/{{snakeCase pagename}}-scoped.scss +3 -0
  153. package/packages/plop/templates/admin_page/{{snakeCase pagename}}.vue +11 -0
  154. package/packages/plop/templates/simple_page/controller.js +3 -0
  155. package/packages/plop/templates/simple_page/model.js +6 -0
  156. package/packages/plop/templates/simple_page/{{snakeCase pagename}}-scoped.scss +3 -0
  157. package/packages/plop/templates/simple_page/{{snakeCase pagename}}.vue +7 -0
  158. package/packages/plop/utils/index.js +168 -0
  159. package/packages/plop/utils/plop-utils.js +86 -0
  160. package/packages/styles/common.scss +137 -0
  161. package/packages/styles/element-ui.scss +142 -0
  162. package/packages/styles/vant.scss +133 -0
  163. package/packages/styles/variables.scss +23 -0
  164. package/packages/utils/crypt.js +24 -0
  165. package/packages/utils/decorators.js +67 -0
  166. package/packages/utils/disallowDevtools.js +53 -0
  167. package/packages/utils/effects.js +173 -0
  168. package/packages/utils/funcs.js +78 -0
  169. package/packages/utils/index.js +95 -0
  170. package/packages/utils/message.js +110 -0
  171. package/packages/utils/middlewares.js +86 -0
  172. package/packages/utils/model.js +71 -0
  173. package/packages/utils/modelUtils.js +203 -0
  174. package/packages/utils/request.js +57 -0
  175. package/packages/utils/site.js +33 -0
  176. package/packages/vite-plugins.js +141 -0
  177. 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>