sohelp-eleplus 1.1.22 → 1.1.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.
@@ -0,0 +1,358 @@
1
+ <template>
2
+ <div class="sohelp-table-select">
3
+ <div class="sohelp-table-select-trigger">
4
+ <slot name="trigger" :selected="selectedList">
5
+ <el-input readonly :placeholder="placeholder" :model-value="displayValue">
6
+ <template #append>
7
+ <el-icon @click="open"><Search /></el-icon
8
+ ></template>
9
+ </el-input>
10
+ </slot>
11
+ </div>
12
+
13
+ <sohelp-modal
14
+ v-model="visible"
15
+ :title="title"
16
+ width="1000px"
17
+ :close-on-click-modal="false"
18
+ append-to-body
19
+ destroy-on-close
20
+ top="5vh"
21
+ class="sohelp-table-select-dialog"
22
+ >
23
+ <div class="sohelp-table-select-body">
24
+ <div class="middle-panel">
25
+ <sohelp-grid-view
26
+ ref="gridRef"
27
+ :refid="refid"
28
+ @checkboxChange="checkboxChange"
29
+ @pageChange="pageChange"
30
+ @radioChange="radioChange"
31
+ ></sohelp-grid-view>
32
+ </div>
33
+
34
+ <div class="right-panel" v-if="multiple">
35
+ <div class="selected-header">
36
+ <span>已选择 {{ selectedList.length }} 个</span>
37
+ <el-button type="danger" link @click="clearSelection">清空</el-button>
38
+ </div>
39
+ <el-scrollbar>
40
+ <div v-for="item in selectedList" :key="item.value" class="selected-item">
41
+ <span>{{ item.label }}</span>
42
+ <el-icon class="close-icon" @click="removeSelected(item)"><Close /></el-icon>
43
+ </div>
44
+ </el-scrollbar>
45
+ </div>
46
+ </div>
47
+
48
+ <template #footer>
49
+ <el-button @click="close">关闭</el-button>
50
+ <el-button type="primary" @click="handleConfirm">确定</el-button>
51
+ </template>
52
+ </sohelp-modal>
53
+ </div>
54
+ </template>
55
+
56
+ <script setup>
57
+ import { ref, computed, nextTick, watch } from 'vue';
58
+ import { Search } from '@element-plus/icons-vue';
59
+ import { uniqBy } from 'lodash';
60
+ import SohelpGridView from './../sohelp-grid-view/index.vue';
61
+ import SohelpModal from './../sohelp-modal/index.vue';
62
+
63
+ const props = defineProps({
64
+ multiple: {
65
+ type: Boolean,
66
+ default: false
67
+ },
68
+ placeholder: {
69
+ type: String,
70
+ default: '请选择'
71
+ },
72
+ title: {
73
+ type: String,
74
+ default: '请选择'
75
+ },
76
+ valueField: {
77
+ type: String,
78
+ default: 'id'
79
+ },
80
+ labelField: {
81
+ type: String,
82
+ default: 'label'
83
+ },
84
+ refid: {
85
+ type: String,
86
+ default: ''
87
+ }
88
+ });
89
+
90
+ const modelValue = defineModel('modelValue');
91
+ const data = defineModel('data');
92
+ const emit = defineEmits(['change']);
93
+ const modelValueArray = ref([]);
94
+
95
+ const gridRef = ref(null);
96
+ const visible = ref(false);
97
+ const selectedList = ref([]);
98
+ const originData = ref([]);
99
+
100
+ /**
101
+ * 格式化数据数组为 { label, value } 格式
102
+ * @param rows 原始数据数组
103
+ * @returns 格式化后的数组
104
+ */
105
+ const formatRows = (rows) => {
106
+ if (!Array.isArray(rows)) return [];
107
+ return rows.map((item) => ({
108
+ label: item[props.labelField],
109
+ value: item[props.valueField]
110
+ }));
111
+ };
112
+
113
+ /**
114
+ * 分页变更处理
115
+ * @param config 分页配置
116
+ */
117
+ const pageChange = (config) => {
118
+ nextTick(() => {
119
+ if (props.multiple) {
120
+ gridRef.value?.setCheckboxRowKey(
121
+ selectedList.value.map((item) => item.value),
122
+ true
123
+ );
124
+ } else {
125
+ if (selectedList.value?.length > 0) {
126
+ gridRef.value?.setRadioRowKey(selectedList.value[0].value);
127
+ }
128
+ }
129
+ });
130
+ };
131
+
132
+ /**
133
+ * 复选框变更处理
134
+ * @param _rows 当前选中的行数据
135
+ * @param checked 是否选中
136
+ * @param type 选择类型
137
+ */
138
+
139
+ const checkboxChange = (_rows, checked, type) => {
140
+ const rows = formatRows(_rows);
141
+ if (checked) {
142
+ selectedList.value = uniqBy([...selectedList.value, ...rows], 'value');
143
+ } else {
144
+ const data = formatRows(gridRef.value?.getData());
145
+ if (type === 'all') {
146
+ selectedList.value = selectedList.value.filter((item) => !data.some((row) => item.value === row.value));
147
+ } else {
148
+ const uncheckedValues = new Set(
149
+ data.filter((item) => !rows.some((row) => item.value === row.value)).map((row) => row.value)
150
+ );
151
+ selectedList.value = selectedList.value.filter((item) => !uncheckedValues.has(item.value));
152
+ }
153
+ }
154
+ };
155
+
156
+ /**
157
+ * 单选变更处理
158
+ * @param param0
159
+ */
160
+ const radioChange = ({ newValue }) => {
161
+ selectedList.value = [];
162
+ if (newValue) {
163
+ const formatted = formatRows([newValue]);
164
+ selectedList.value = formatted.length > 0 ? [formatted[0]] : [];
165
+ }
166
+ };
167
+
168
+ /**
169
+ * 显示值
170
+ */
171
+ const displayValue = computed(() => {
172
+ return modelValueArray.value?.map((item) => {
173
+ return [...originData.value, ...selectedList.value].find((selected) => selected.value === item)?.label;
174
+ });
175
+ });
176
+
177
+ /**
178
+ * 打开选择器
179
+ */
180
+ const open = () => {
181
+ visible.value = true;
182
+ };
183
+
184
+ /**
185
+ * 移除选中的项
186
+ */
187
+ const removeSelected = (item) => {
188
+ gridRef.value?.setCheckboxRowKey(item.value, false);
189
+ selectedList.value = selectedList.value.filter((row) => row.value !== item.value);
190
+ };
191
+
192
+ /**
193
+ * 清空选中
194
+ */
195
+ const clearSelection = () => {
196
+ gridRef.value?.setCheckboxRowKey(
197
+ selectedList.value?.map((item) => item.value),
198
+ false
199
+ );
200
+ selectedList.value = [];
201
+ };
202
+
203
+ /**
204
+ * 确认
205
+ */
206
+ const handleConfirm = () => {
207
+ originData.value = [];
208
+ const _data = selectedList.value.map((item) => {
209
+ return {
210
+ [props.valueField]: item.value,
211
+ [props.labelField]: item.label
212
+ };
213
+ });
214
+
215
+ if (props.multiple) {
216
+ modelValue.value = selectedList.value.map((item) => item.value);
217
+ data.value = _data;
218
+ } else {
219
+ modelValue.value = selectedList.value[0]?.value || '';
220
+ data.value = _data[0] || {};
221
+ }
222
+
223
+ emit('change', selectedList.value);
224
+ visible.value = false;
225
+ };
226
+
227
+ const close = () => {
228
+ selectedList.value = [...originData.value];
229
+ visible.value = false;
230
+ };
231
+
232
+ /**
233
+ * modelValue变更处理
234
+ */
235
+ watch(
236
+ () => modelValue.value,
237
+ (val) => {
238
+ selectedList.value = [];
239
+ if (val?.length && val != '0') {
240
+ modelValueArray.value = Array.isArray(val) ? val : [val];
241
+ if (data.value && data.value != '0') {
242
+ const dataArray = Array.isArray(data.value) ? data.value : [data.value];
243
+ selectedList.value = formatRows(
244
+ dataArray.filter((item) => modelValueArray.value.includes(item[props.valueField]))
245
+ );
246
+
247
+ originData.value = [...selectedList.value];
248
+ }
249
+ }
250
+ },
251
+ {
252
+ immediate: true
253
+ }
254
+ );
255
+ </script>
256
+
257
+ <script>
258
+ export default {
259
+ name: 'SohelpTableSelect'
260
+ };
261
+ </script>
262
+
263
+ <style scoped lang="scss">
264
+ .sohelp-table-select {
265
+ :deep(.el-input-group__append) {
266
+ padding: 0px !important;
267
+
268
+ .el-icon {
269
+ height: 100%;
270
+ padding: 0 10px;
271
+ }
272
+ }
273
+ }
274
+ .sohelp-table-select-trigger {
275
+ cursor: pointer;
276
+ display: inline-block;
277
+ width: 100%;
278
+ border-radius: var(--el-border-radius-base);
279
+ background: #fff;
280
+ }
281
+
282
+ .sohelp-table-select-body {
283
+ display: flex;
284
+ height: 600px;
285
+ border: 1px solid #eee;
286
+
287
+ .left-panel {
288
+ width: 250px;
289
+ padding: 10px;
290
+ border-right: 1px solid #eee;
291
+ display: flex;
292
+ flex-direction: column;
293
+
294
+ :deep(.el-tree) {
295
+ min-width: 100%;
296
+ display: inline-block;
297
+ }
298
+ }
299
+
300
+ .middle-panel {
301
+ flex: 1;
302
+ padding: 10px;
303
+ display: flex;
304
+ flex-direction: column;
305
+ overflow: hidden;
306
+
307
+ .filter-form {
308
+ margin-bottom: 10px;
309
+ }
310
+
311
+ .user-grid {
312
+ flex: 1;
313
+ overflow: hidden;
314
+ }
315
+ }
316
+
317
+ .right-panel {
318
+ width: 200px;
319
+ border-left: 1px solid #eee;
320
+ padding: 10px;
321
+ display: flex;
322
+ flex-direction: column;
323
+ background-color: #f8f8f8;
324
+
325
+ .selected-header {
326
+ display: flex;
327
+ justify-content: space-between;
328
+ align-items: center;
329
+ margin-bottom: 10px;
330
+ font-size: 14px;
331
+ font-weight: bold;
332
+ }
333
+
334
+ .selected-item {
335
+ display: flex;
336
+ justify-content: space-between;
337
+ align-items: center;
338
+ padding: 8px;
339
+ background: #fff;
340
+ margin-bottom: 5px;
341
+ border-radius: 4px;
342
+ font-size: 13px;
343
+
344
+ .close-icon {
345
+ cursor: pointer;
346
+ color: #999;
347
+ &:hover {
348
+ color: #f56c6c;
349
+ }
350
+ }
351
+ }
352
+ }
353
+ }
354
+
355
+ .mb-10 {
356
+ margin-bottom: 10px;
357
+ }
358
+ </style>
@@ -63893,7 +63893,6 @@ const _sfc_main$C = {
63893
63893
  },
63894
63894
  methods: {
63895
63895
  toolbarClick(event) {
63896
- console.log("toolbarClick", event);
63897
63896
  this.$emit("toolbarButtonClick", event);
63898
63897
  },
63899
63898
  onCheckboxChange(event) {
@@ -18,12 +18,7 @@
18
18
  :edit-render="getEditor(item)"
19
19
  :key="item.name"
20
20
  ></vxe-column>
21
- <vxe-pager
22
- v-model:currentPage="page"
23
- v-model:pageSize="limit"
24
- :total="datasource.total"
25
- @page-change="reload"
26
- >
21
+ <vxe-pager v-model:currentPage="page" v-model:pageSize="limit" :total="datasource.total" @page-change="reload">
27
22
  </vxe-pager>
28
23
  </vxe-table>
29
24
  </template>
@@ -32,7 +27,7 @@
32
27
  import { EleMessage } from '@/components/ele-admin-plus/components';
33
28
  import { DragOutlined } from '../sohelp-icon-select/icons';
34
29
  import Sortable from 'sortablejs';
35
- import {moduleCache} from '../cache/ModuleCache';
30
+ import { moduleCache } from '../cache/ModuleCache';
36
31
 
37
32
  export default {
38
33
  name: 'SohelpVxeTable',
@@ -82,18 +77,18 @@
82
77
  header: property.label,
83
78
  width: property.with || 100,
84
79
  edit: property.edit,
85
- editor:property.editor
80
+ editor: property.editor
86
81
  };
87
82
  };
88
83
 
89
84
  /***初始化网格列表配置**/
90
85
  const initProTableConfiguration = () => {
91
- props.drag && rowDrop()
86
+ props.drag && rowDrop();
92
87
  };
93
88
 
94
89
  /**获取列表配置*/
95
90
  moduleCache.getGrid(props.refid).then((data) => {
96
- if(!data){
91
+ if (!data) {
97
92
  return;
98
93
  }
99
94
  Object.assign(sohelpConfig, { ...data });
@@ -103,7 +98,7 @@
103
98
  });
104
99
  /**添加操作列**/
105
100
  columns.push({
106
- columnKey: 'action',
101
+ field: 'action',
107
102
  label: '操作',
108
103
  width: 200,
109
104
  align: 'center',
@@ -120,39 +115,32 @@
120
115
  Object.assign(datasource, { total: 0, results: [] });
121
116
  return;
122
117
  }
123
- const res = await SohelpHttp.get(
124
- props.url || sohelpConfig.requestValue,
125
- {
126
- page,
127
- limit,
128
- ...props.where
129
- }
130
- ).catch((e) => {
118
+ const res = await SohelpHttp.get(props.url || sohelpConfig.requestValue, {
119
+ page,
120
+ limit,
121
+ ...props.where
122
+ }).catch((e) => {
131
123
  EleMessage.error(e.message);
132
124
  });
133
125
  Object.assign(datasource, { ...res.data });
134
126
  };
135
127
 
136
- const getEditor = (item) =>{
137
- if(item.edit){
138
- return {'name':'input'}
139
- }else{
128
+ const getEditor = (item) => {
129
+ if (item.edit) {
130
+ return { name: 'input' };
131
+ } else {
140
132
  return null;
141
133
  }
142
-
143
- }
134
+ };
144
135
 
145
136
  // 行拖拽
146
137
  const rowDrop = () => {
147
138
  nextTick(() => {
148
139
  const xGTable = sohelpVxeTableRef.value;
149
- sortable.value = Sortable.create(
150
- xGTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'),
151
- {
152
- handle: '.drag-btn',
153
- onEnd: ({ newIndex, oldIndex }) => {}
154
- }
155
- );
140
+ sortable.value = Sortable.create(xGTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
141
+ handle: '.drag-btn',
142
+ onEnd: ({ newIndex, oldIndex }) => {}
143
+ });
156
144
  });
157
145
  };
158
146
 
@@ -26,7 +26,7 @@
26
26
  const formValue = ref(null);
27
27
  const entityFormRef = ref(null);
28
28
 
29
- const refid = ref(props.data.refid.split('!')[0]);
29
+ const refid = ref(props.data?.refid?.split('!')[0]);
30
30
 
31
31
  const load = async () => {
32
32
  const { id, refid } = props.data || {};
@@ -1,5 +1,4 @@
1
1
  <template>
2
- fff
3
2
  <sohelp-vxe-grid
4
3
  style="padding-top: 10px"
5
4
  url="/engine/web/workflow/getTasks"
@@ -25,8 +25,8 @@
25
25
 
26
26
  <ele-text style="margin-top: 5px">
27
27
  <div style="display: flex; gap: 5px; flex-wrap: wrap">
28
- <ele-text v-if="item.task_type == 1">办理人:</ele-text>
29
28
  <ele-text v-if="item.task_type == 0">申请人:</ele-text>
29
+ <ele-text v-if="item.task_type == 1">办理人:</ele-text>
30
30
  <ele-text v-if="item.task_type == 2" type="info">抄送人:</ele-text>
31
31
  <span v-for="row in item?.actorList" :key="row.actor_id">
32
32
  <vxe-tag status="primary">{{ row.actor_name }}</vxe-tag>
@@ -34,8 +34,8 @@
34
34
  </div>
35
35
  </ele-text>
36
36
  <div style="display: flex; gap: 5px; flex-wrap: wrap">
37
- <ele-text v-if="item.task_type === 1">办理意见:</ele-text>
38
37
  <ele-text v-if="item.task_type === 0">申请理由:</ele-text>
38
+ <ele-text v-if="item.task_type === 1">办理意见:</ele-text>
39
39
  <ele-text v-if="item.task_type !== 2">{{ getVariable(item)?.reason }}</ele-text>
40
40
  <ele-text v-if="item.type !== 'done'" type="info">指派人:</ele-text>
41
41
 
@@ -1,5 +1,10 @@
1
1
  <template>
2
2
  <div v-loading="loading" class="workflow-wrap">
3
+ <div class="tips">
4
+ <span class="tips-item done">已通过</span>
5
+ <span class="tips-item do">办理中</span>
6
+ <span class="tips-item undo">未处理</span>
7
+ </div>
3
8
  <draw-box class="workflow-scroll">
4
9
  <sohelp-workflow class="workflow" ref="workflowRef" v-model="workflow.nodeConfig" v-if="workflow?.nodeConfig" />
5
10
  </draw-box>
@@ -65,4 +70,27 @@
65
70
  align-items: center;
66
71
  margin: 0 20px 20px auto;
67
72
  }
73
+ .tips {
74
+ display: flex;
75
+ gap: 10px;
76
+ width: 100%;
77
+ align-items: center;
78
+ justify-content: center;
79
+ margin: 0 20px 20px auto;
80
+ .tips-item {
81
+ padding: 2px 10px;
82
+ height: 20px;
83
+ border-radius: 6px;
84
+ line-height: 20px;
85
+ }
86
+ .tips-item.done {
87
+ border: 3px solid #409eff;
88
+ }
89
+ .tips-item.do {
90
+ border: 3px dashed #e6a23c;
91
+ }
92
+ .tips-item.undo {
93
+ border: 3px solid #ccc;
94
+ }
95
+ }
68
96
  </style>