widget.qw 1.0.24 → 1.0.25

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 (101) hide show
  1. package/.env.development +9 -9
  2. package/.env.production +8 -8
  3. package/README.md +73 -73
  4. package/build/style.css +468 -482
  5. package/build/widget.qw.es.js +1628 -2374
  6. package/build/widget.qw.umd.js +1540 -2286
  7. package/index.html +17 -17
  8. package/package.json +47 -47
  9. package/src/App.vue +26 -26
  10. package/src/api/index.js +149 -141
  11. package/src/components/AuditBar.vue +340 -340
  12. package/src/components/BillCard.vue +155 -155
  13. package/src/components/CascaderPicker.vue +87 -87
  14. package/src/components/CascaderPop.vue +319 -330
  15. package/src/components/CheckGroup.vue +113 -113
  16. package/src/components/DatetimePicker/DatetimePop.vue +342 -342
  17. package/src/components/DatetimePicker/index.vue +112 -112
  18. package/src/components/DayDropdown.vue +56 -56
  19. package/src/components/FilePicker.vue +113 -113
  20. package/src/components/Input.vue +71 -71
  21. package/src/components/MonthDropdown.vue +51 -51
  22. package/src/components/MultiPicker.vue +123 -123
  23. package/src/components/SecretNotify.js +5 -5
  24. package/src/components/Sheet.vue +92 -92
  25. package/src/components/SingleApiPicker.vue +112 -112
  26. package/src/components/SinglePicker.vue +102 -102
  27. package/src/components/SingleUserSelector.vue +425 -425
  28. package/src/components/Switch.vue +64 -64
  29. package/src/components/TreePicker.vue +113 -113
  30. package/src/components/UserPicker.vue +106 -106
  31. package/src/components/UserProfile.vue +131 -131
  32. package/src/components/UsersPicker.vue +118 -118
  33. package/src/components/YearDropdown.vue +59 -59
  34. package/src/components/data_selector.vue +280 -280
  35. package/src/components/image_picker.vue +114 -114
  36. package/src/components/images_picker.vue +139 -139
  37. package/src/components/index.js +157 -157
  38. package/src/components/mult_list_selector.vue +155 -155
  39. package/src/components/subdepartment_selector.vue +481 -481
  40. package/src/components/user_selector.vue +639 -639
  41. package/src/components/widget/DataPop.vue +95 -95
  42. package/src/components/widget/TreePop.vue +88 -88
  43. package/src/components/widget/UserPop.vue +347 -347
  44. package/src/main.js +117 -117
  45. package/src/router/index.ts +168 -168
  46. package/src/util/array_util.js +32 -32
  47. package/src/util/auth_util.js +72 -72
  48. package/src/util/bool_util.js +5 -5
  49. package/src/util/bus.js +1 -1
  50. package/src/util/cache_util.js +18 -18
  51. package/src/util/errer_code.js +6 -6
  52. package/src/util/eval_util.js +19 -19
  53. package/src/util/icon_util.js +36 -36
  54. package/src/util/image_util.js +27 -27
  55. package/src/util/index.js +55 -55
  56. package/src/util/num_util.js +70 -70
  57. package/src/util/obj_util.js +28 -28
  58. package/src/util/request.js +73 -73
  59. package/src/util/request_json.js +71 -71
  60. package/src/util/request_json_mute.js +65 -65
  61. package/src/util/request_upload.js +79 -79
  62. package/src/util/route_util.js +31 -31
  63. package/src/util/str_util.js +143 -143
  64. package/src/util/time_util.js +406 -406
  65. package/src/util/toast_util.js +24 -24
  66. package/src/util/tree_util.js +153 -153
  67. package/src/util/validate.js +182 -182
  68. package/src/util/vue_filter.js +223 -223
  69. package/src/views/auditbar/index.vue +65 -65
  70. package/src/views/billcard/index.vue +45 -45
  71. package/src/views/cascaderpicker/index copy.vue +0 -0
  72. package/src/views/cascaderpicker/index.vue +0 -0
  73. package/src/views/cascaderpop/index.vue +90 -90
  74. package/src/views/checkgroup/index.vue +35 -35
  75. package/src/views/dataSelector/index.vue +48 -48
  76. package/src/views/datetimepicker/index.vue +34 -34
  77. package/src/views/daydropdown/index.vue +31 -31
  78. package/src/views/filepicker/index.vue +31 -31
  79. package/src/views/imagepicker/index.vue +31 -31
  80. package/src/views/imagespicker/index.vue +31 -31
  81. package/src/views/input/index.vue +34 -34
  82. package/src/views/monthdropdown/index.vue +31 -31
  83. package/src/views/multListSelector/index.vue +61 -61
  84. package/src/views/multipicker/index.vue +36 -36
  85. package/src/views/productSelector/index.vue +35 -35
  86. package/src/views/projectdropdown/index.vue +31 -31
  87. package/src/views/projectpicker/index.vue +41 -41
  88. package/src/views/secretnotify/index.vue +27 -27
  89. package/src/views/sheet/index.vue +45 -45
  90. package/src/views/singlepicker/index.vue +35 -35
  91. package/src/views/subdepartmentSelector/index.vue +40 -40
  92. package/src/views/switch/index.vue +34 -34
  93. package/src/views/treepicker/index.vue +41 -41
  94. package/src/views/userSelector/index.vue +54 -54
  95. package/src/views/userSelectorNew/index.vue +45 -45
  96. package/src/views/userpicker/index.vue +43 -43
  97. package/src/views/userprofile/index.vue +30 -30
  98. package/src/views/userspicker/index.vue +43 -43
  99. package/src/views/yeardropdown/index.vue +32 -32
  100. package/src/vm/index.js +1 -1
  101. package/vite.config.ts +122 -122
@@ -1,331 +1,320 @@
1
- <template>
2
- <van-popup v-model:show="show" round position="bottom" class="cascader-pop">
3
- <div class="cascader-selector">
4
- <div class="cascader-header">
5
- <div class="header-left">
6
- <van-button @click="onBack" icon="arrow-left" size="small" />
7
- </div>
8
-
9
- <!-- 移除header-center包装,直接使用current-path -->
10
- <div class="current-path">{{ pathsLabel }}</div>
11
-
12
- <div class="header-right">
13
- <van-button size="small" @click="onCancel" class="cancel-btn">取消</van-button>
14
-
15
- <van-button type="primary" size="small" @click="onSubmit" class="confirm-btn">确定</van-button>
16
- </div>
17
- </div>
18
-
19
- <!-- 搜索框 -->
20
- <van-search v-model="data.keyword" :placeholder="props.placeholder" @clear="onClear" @search="onSearch"
21
- @cancel="onClear" show-action>
22
- <template #action>
23
- <div @click="onSearch">搜索</div>
24
- </template>
25
- </van-search>
26
-
27
- <div class="scroll-container">
28
- <!-- 遍历子节点列表 -->
29
- <van-cell-group>
30
- <van-cell v-for="(item, i) in optionNodes" :key="i">
31
- <template #title>
32
- <div class="cell-content">
33
- <div class="circle-selector" v-if="item.canCheck" @click.stop="onToggle(item)">
34
- <van-icon v-if="data.selectedNodeId === item.id" name="success" size="20"
35
- color="#409eff" />
36
- <van-icon v-if="data.selectedNodeId != item.id" name="circle" size="20"
37
- color="#e0e0e0" />
38
- </div>
39
- <span class="name">{{ item.label }}</span>
40
- </div>
41
- </template>
42
- <template #right-icon v-if="item.hasChildren && item.canExpand">
43
- <van-icon name="arrow" @click.stop="onNextLevel(item)" />
44
- </template>
45
- </van-cell>
46
- </van-cell-group>
47
- </div>
48
- </div>
49
- </van-popup>
50
- </template>
51
-
52
- <script setup>
53
- import { ref, onMounted, watch, reactive, computed } from "vue";
54
- import util from "@/util"
55
- import { useVModel } from '@vueuse/core'
56
-
57
- const props = defineProps({
58
- modelValue: {
59
- type: String,
60
- default: ''
61
- },
62
- show: {
63
- type: Boolean,
64
- default: false,
65
- },
66
- placeholder: {
67
- type: String,
68
- default: ''
69
- },
70
- keywordQueryNode: {
71
- type: Function,
72
- default: () => { }
73
- },
74
- idQueryNode: {
75
- type: Function,
76
- default: () => { }
77
- },
78
- });
79
- // 定义emit
80
- const emit = defineEmits(["update:modelValue", "update:show", "select"]);
81
- // 弹出?
82
- const show = useVModel(props, 'show', emit)
83
- const modelValue = useVModel(props, 'modelValue', emit)
84
- const data = reactive({
85
- //当前父节点
86
- parentNode: null,
87
- // 搜索关键字
88
- keyword: "",
89
- //勾选的子节点id
90
- selectedNodeId: ''
91
- })
92
-
93
- onMounted(() => {
94
- //查询根节点
95
- props.idQueryNode({ id: '', isReturnParent: true }, (node) => {
96
- data.parentNode = node
97
- })
98
- })
99
-
100
- // 待选节点列表
101
- const optionNodes = computed(() => {
102
- return data.parentNode?.children ? data.parentNode.children : []
103
- })
104
-
105
- //选中节点的路径:父/子/孙
106
- const pathsLabel = computed(() => {
107
- return data.parentNode?.path ? data.parentNode.path : ''
108
- })
109
-
110
- // 关键字查询节点列表
111
- const keywordQueryNode = () => {
112
- props.keywordQueryNode({ keyword: data.keyword, isReturnParent: true }, (node) => {
113
- data.parentNode = node
114
- })
115
- }
116
-
117
- // 关键字查询
118
- const onSearch = () => {
119
- keywordQueryNode()
120
- }
121
-
122
- // 返回上一级
123
- const onBack = () => {
124
- if (!data.parentNode || !data.parentNode.parentId)
125
- return
126
-
127
- data.keyword = ""
128
- props.idQueryNode({ id: data.parentNode.parentId, isReturnParent: true }, (node) => {
129
- data.parentNode = node
130
- })
131
- }
132
-
133
- const onClear = () => {
134
- data.keyword = ''
135
- }
136
-
137
- // 清除掉选中节点
138
- const reset = () => {
139
- // 搜索关键字
140
- data.keyword = ""
141
- }
142
-
143
- // 确认按钮
144
- const onSubmit = () => {
145
- if (!data.selectedNodeId) {
146
- util.warnToast("请选择")
147
- return
148
- }
149
-
150
- modelValue.value = data.selectedNodeId
151
- show.value = false
152
-
153
- reset()
154
- }
155
-
156
- // 取消按钮
157
- const onCancel = () => {
158
- show.value = false
159
- reset()
160
- }
161
-
162
- const onToggle = (node) => {
163
- if (data.selectedNodeId == node.id)
164
- data.selectedNodeId = ''
165
- else
166
- data.selectedNodeId = node.id
167
- }
168
-
169
- const onNextLevel = (node) => {
170
- props.idQueryNode({ id: node.id, isReturnParent: false }, (node) => {
171
- data.parentNode = node
172
- })
173
- }
174
-
175
- //首页加载
176
- onMounted(async () => {
177
- props.idQueryNode({ id: '', isReturnParent: true }, (node) => {
178
- data.parentNode = node
179
- })
180
- })
181
-
182
- watch(() => modelValue.value, async (n, o) => {
183
- data.selectedNodeId = modelValue.value
184
-
185
- let params = {}
186
- params.id = modelValue.value
187
- params.isReturnParent = true
188
- params.hasChildren = true
189
-
190
- await props.idQueryNode(params, (node) => {
191
- data.parentNode = node
192
-
193
- if (!modelValue.value)
194
- return
195
-
196
- let childNode = util.findNode(modelValue.value, data.parentNode.children)
197
- emit('select', childNode)
198
- })
199
- }, {
200
- immediate: true
201
- })
202
- </script>
203
-
204
- <style scoped>
205
- .cascader-pop {
206
- width: 100%;
207
- overflow: hidden;
208
- }
209
-
210
- .cascader-selector {
211
- padding: 10px;
212
- }
213
-
214
- .search-buttons {
215
- display: flex;
216
- gap: 10px;
217
- }
218
-
219
- .clear-btn {
220
- background-color: #f2f3f5;
221
- border: none;
222
- border-radius: 4px;
223
- padding: 4px 8px;
224
- font-size: 14px;
225
- }
226
-
227
- .confirm-btn {
228
- background-color: #1989fa;
229
- color: white;
230
- border: none;
231
- border-radius: 4px;
232
- padding: 4px 8px;
233
- font-size: 14px;
234
- }
235
-
236
- .no-results {
237
- text-align: center;
238
- padding: 20px;
239
- color: #969799;
240
- }
241
-
242
- .cascader-header {
243
- padding: 10px;
244
- border-bottom: 1px solid #ebedf0;
245
- display: flex;
246
- justify-content: space-between;
247
- align-items: center;
248
- }
249
-
250
- .current-path {
251
- flex: 1;
252
- font-size: 14px;
253
- color: #323233;
254
- white-space: nowrap;
255
- overflow: hidden;
256
- text-overflow: ellipsis;
257
- }
258
-
259
- .header-right {
260
- display: flex;
261
- gap: 8px;
262
- margin-left: auto;
263
- }
264
-
265
- .cancel-btn {
266
- color: #969799;
267
- margin-right: 5px;
268
- }
269
-
270
- .scroll-container {
271
- height: calc(80vh - 150px);
272
- overflow-y: auto;
273
- }
274
-
275
-
276
- .cell-content {
277
- display: flex;
278
- align-items: center;
279
- gap: 12px;
280
- }
281
-
282
- .circle-selector {
283
- width: 20px;
284
- height: 20px;
285
- border-radius: 50%;
286
- display: flex;
287
- align-items: center;
288
- justify-content: center;
289
- transition: all 0.2s;
290
- flex-shrink: 0;
291
- }
292
-
293
- .circle-selector.selected {
294
- background-color: #1989fa;
295
- border-color: #1989fa;
296
- }
297
-
298
- .circle-selector.selected .van-icon {
299
- color: white;
300
- font-size: 14px;
301
- }
302
-
303
- .van-cell__right-icon {
304
- color: #969799;
305
- font-size: 16px;
306
- margin-left: 8px;
307
- }
308
-
309
- .name {
310
- flex: 1;
311
- overflow: hidden;
312
- text-overflow: ellipsis;
313
- white-space: nowrap;
314
- }
315
-
316
- .cancel-btn {
317
- color: #969799;
318
- }
319
-
320
- .search-field {
321
- background: #fff;
322
- padding: 10px 16px;
323
- border-bottom: 1px solid #ebedf0;
324
- position: sticky;
325
- top: 0;
326
- z-index: 999;
327
- margin-bottom: 10px;
328
- flex-shrink: 0;
329
- /* 防止压缩 */
330
- }
1
+ <template>
2
+ <van-popup v-model:show="show" round position="bottom" class="cascader-pop">
3
+ <div class="cascader-selector">
4
+ <div class="cascader-header">
5
+ <div class="header-left">
6
+ <van-button @click="onBack" icon="arrow-left" size="small" />
7
+ </div>
8
+
9
+ <!-- 移除header-center包装,直接使用current-path -->
10
+ <div class="current-path">{{ pathsLabel }}</div>
11
+
12
+ <div class="header-right">
13
+ <van-button size="small" @click="onCancel" class="cancel-btn">取消</van-button>
14
+
15
+ <van-button type="primary" size="small" @click="onSubmit" class="confirm-btn">确定</van-button>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- 搜索框 -->
20
+ <van-search v-model="data.keyword" :placeholder="props.placeholder" @clear="onClear" @search="onSearch"
21
+ @cancel="onClear" show-action>
22
+ <template #action>
23
+ <div @click="onSearch">搜索</div>
24
+ </template>
25
+ </van-search>
26
+
27
+ <div class="scroll-container">
28
+ <!-- 遍历子节点列表 -->
29
+ <van-cell-group>
30
+ <van-cell v-for="(item, i) in optionNodes" :key="i">
31
+ <template #title>
32
+ <div class="cell-content">
33
+ <div class="circle-selector" v-if="item.canCheck" @click.stop="onToggle(item)">
34
+ <van-icon v-if="data.selectedNodeId === item.id" name="success" size="20"
35
+ color="#409eff" />
36
+ <van-icon v-if="data.selectedNodeId != item.id" name="circle" size="20"
37
+ color="#e0e0e0" />
38
+ </div>
39
+ <span class="name">{{ item.label }}</span>
40
+ </div>
41
+ </template>
42
+ <template #right-icon v-if="item.canExpand">
43
+ <van-icon name="arrow" @click.stop="onNextLevel(item)" />
44
+ </template>
45
+ </van-cell>
46
+ </van-cell-group>
47
+ </div>
48
+ </div>
49
+ </van-popup>
50
+ </template>
51
+
52
+ <script setup>
53
+ import { ref, onMounted, watch, reactive, computed } from "vue";
54
+ import util from "@/util"
55
+ import { useVModel } from '@vueuse/core'
56
+
57
+ const props = defineProps({
58
+ modelValue: {
59
+ type: String,
60
+ default: ''
61
+ },
62
+ show: {
63
+ type: Boolean,
64
+ default: false,
65
+ },
66
+ placeholder: {
67
+ type: String,
68
+ default: ''
69
+ },
70
+ keywordQueryNode: {
71
+ type: Function,
72
+ default: () => { }
73
+ },
74
+ idQueryNode: {
75
+ type: Function,
76
+ default: () => { }
77
+ },
78
+ });
79
+ // 定义emit
80
+ const emit = defineEmits(["update:modelValue", "update:show", "select"]);
81
+ // 弹出?
82
+ const show = useVModel(props, 'show', emit)
83
+ const modelValue = useVModel(props, 'modelValue', emit)
84
+ const data = reactive({
85
+ //当前父节点
86
+ parentNode: null,
87
+ // 搜索关键字
88
+ keyword: "",
89
+ //勾选的子节点id
90
+ selectedNodeId: ''
91
+ })
92
+
93
+ onMounted(() => {
94
+ })
95
+
96
+ // 待选节点列表
97
+ const optionNodes = computed(() => {
98
+ return data.parentNode?.children ? data.parentNode.children : []
99
+ })
100
+
101
+ //选中节点的路径:父/子/孙
102
+ const pathsLabel = computed(() => {
103
+ return data.parentNode?.path ? data.parentNode.path : ''
104
+ })
105
+
106
+ // 关键字查询节点列表
107
+ const keywordQueryNode = () => {
108
+ props.keywordQueryNode({ keyword: data.keyword, isReturnParent: true }, (node) => {
109
+ data.parentNode = node
110
+ })
111
+ }
112
+
113
+ // 关键字查询
114
+ const onSearch = () => {
115
+ keywordQueryNode()
116
+ }
117
+
118
+ // 返回上一级
119
+ const onBack = () => {
120
+ if (!data.parentNode || !data.parentNode.parentId)
121
+ return
122
+
123
+ data.keyword = ""
124
+ props.idQueryNode({ id: data.parentNode.parentId, isReturnParent: false }, (node) => {
125
+ data.parentNode = node
126
+ })
127
+ }
128
+
129
+ const onClear = () => {
130
+ data.keyword = ''
131
+ }
132
+
133
+ // 清除掉选中节点
134
+ const reset = () => {
135
+ // 搜索关键字
136
+ data.keyword = ""
137
+ }
138
+
139
+ // 确认按钮
140
+ const onSubmit = () => {
141
+ if (!data.selectedNodeId) {
142
+ util.warnToast("请选择")
143
+ return
144
+ }
145
+
146
+ modelValue.value = data.selectedNodeId
147
+ show.value = false
148
+
149
+ reset()
150
+ }
151
+
152
+ // 取消按钮
153
+ const onCancel = () => {
154
+ show.value = false
155
+ reset()
156
+ }
157
+
158
+ const onToggle = (node) => {
159
+ if (data.selectedNodeId == node.id)
160
+ data.selectedNodeId = ''
161
+ else
162
+ data.selectedNodeId = node.id
163
+ }
164
+
165
+ const onNextLevel = (node) => {
166
+ props.idQueryNode({ id: node.id, isReturnParent: false }, (node) => {
167
+ data.parentNode = node
168
+ })
169
+ }
170
+
171
+ watch(() => modelValue.value, async (n, o) => {
172
+ data.selectedNodeId = modelValue.value
173
+
174
+ let params = {}
175
+ params.id = modelValue.value
176
+ params.isReturnParent = true
177
+ params.hasChildren = true
178
+
179
+ await props.idQueryNode(params, (node) => {
180
+ data.parentNode = node
181
+
182
+ if (!modelValue.value)
183
+ return
184
+
185
+ let childNode = util.findNode(modelValue.value, data.parentNode.children)
186
+ emit('select', childNode)
187
+ })
188
+ }, {
189
+ immediate: true
190
+ })
191
+ </script>
192
+
193
+ <style scoped>
194
+ .cascader-pop {
195
+ width: 100%;
196
+ overflow: hidden;
197
+ }
198
+
199
+ .cascader-selector {
200
+ padding: 10px;
201
+ }
202
+
203
+ .search-buttons {
204
+ display: flex;
205
+ gap: 10px;
206
+ }
207
+
208
+ .clear-btn {
209
+ background-color: #f2f3f5;
210
+ border: none;
211
+ border-radius: 4px;
212
+ padding: 4px 8px;
213
+ font-size: 14px;
214
+ }
215
+
216
+ .confirm-btn {
217
+ background-color: #1989fa;
218
+ color: white;
219
+ border: none;
220
+ border-radius: 4px;
221
+ padding: 4px 8px;
222
+ font-size: 14px;
223
+ }
224
+
225
+ .no-results {
226
+ text-align: center;
227
+ padding: 20px;
228
+ color: #969799;
229
+ }
230
+
231
+ .cascader-header {
232
+ padding: 10px;
233
+ border-bottom: 1px solid #ebedf0;
234
+ display: flex;
235
+ justify-content: space-between;
236
+ align-items: center;
237
+ }
238
+
239
+ .current-path {
240
+ flex: 1;
241
+ font-size: 14px;
242
+ color: #323233;
243
+ white-space: nowrap;
244
+ overflow: hidden;
245
+ text-overflow: ellipsis;
246
+ }
247
+
248
+ .header-right {
249
+ display: flex;
250
+ gap: 8px;
251
+ margin-left: auto;
252
+ }
253
+
254
+ .cancel-btn {
255
+ color: #969799;
256
+ margin-right: 5px;
257
+ }
258
+
259
+ .scroll-container {
260
+ height: calc(80vh - 150px);
261
+ overflow-y: auto;
262
+ }
263
+
264
+
265
+ .cell-content {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 12px;
269
+ }
270
+
271
+ .circle-selector {
272
+ width: 20px;
273
+ height: 20px;
274
+ border-radius: 50%;
275
+ display: flex;
276
+ align-items: center;
277
+ justify-content: center;
278
+ transition: all 0.2s;
279
+ flex-shrink: 0;
280
+ }
281
+
282
+ .circle-selector.selected {
283
+ background-color: #1989fa;
284
+ border-color: #1989fa;
285
+ }
286
+
287
+ .circle-selector.selected .van-icon {
288
+ color: white;
289
+ font-size: 14px;
290
+ }
291
+
292
+ .van-cell__right-icon {
293
+ color: #969799;
294
+ font-size: 16px;
295
+ margin-left: 8px;
296
+ }
297
+
298
+ .name {
299
+ flex: 1;
300
+ overflow: hidden;
301
+ text-overflow: ellipsis;
302
+ white-space: nowrap;
303
+ }
304
+
305
+ .cancel-btn {
306
+ color: #969799;
307
+ }
308
+
309
+ .search-field {
310
+ background: #fff;
311
+ padding: 10px 16px;
312
+ border-bottom: 1px solid #ebedf0;
313
+ position: sticky;
314
+ top: 0;
315
+ z-index: 999;
316
+ margin-bottom: 10px;
317
+ flex-shrink: 0;
318
+ /* 防止压缩 */
319
+ }
331
320
  </style>