hookehuyr

✨ feat(节点负责人控件): 根据API进行结构功能调整

1 /* 1 /*
2 * @Date: 2021-08-18 12:47:05 2 * @Date: 2021-08-18 12:47:05
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2023-10-27 11:05:12 4 + * @LastEditTime: 2023-11-21 15:29:14
5 * @FilePath: /vue-flow-editor/build/docs.js 5 * @FilePath: /vue-flow-editor/build/docs.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -40,9 +40,9 @@ module.exports = { ...@@ -40,9 +40,9 @@ module.exports = {
40 compress: true, 40 compress: true,
41 // 设置代理 41 // 设置代理
42 proxy: { 42 proxy: {
43 - '/srv/': { 43 + '/admin/': {
44 // filter: ['/op/', '/fi/', '/de/', '/st/', '/fr/', '/pr/', '/pu/', '/dl/', '/b/', '/t/', '/rpt/', '/mm/', '/mp/'], 44 // filter: ['/op/', '/fi/', '/de/', '/st/', '/fr/', '/pr/', '/pu/', '/dl/', '/b/', '/t/', '/rpt/', '/mm/', '/mp/'],
45 - target: 'https://oa.onwall.cn', 45 + target: 'https://oa-dev.onwall.cn',
46 changeOrigin: true, 46 changeOrigin: true,
47 // pathRewrite: { 47 // pathRewrite: {
48 // '^/api': '' 48 // '^/api': ''
......
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
101 v-if="state.userTags.length" 101 v-if="state.userTags.length"
102 v-for="tag in state.userTags" 102 v-for="tag in state.userTags"
103 :key="tag.name" 103 :key="tag.name"
104 - style="margin-left: 0.25rem; margin-right: 0.25rem;" 104 + style="margin: 0 0.25rem 0.5rem 0.25rem;"
105 > 105 >
106 {{ tag.name }} 106 {{ tag.name }}
107 </el-tag> 107 </el-tag>
...@@ -521,20 +521,20 @@ export default { ...@@ -521,20 +521,20 @@ export default {
521 521
522 onMounted(() => { 522 onMounted(() => {
523 document.title = '可视化流程设计器' 523 document.title = '可视化流程设计器'
524 - // 显示提示框的标志位 524 + // // 显示提示框的标志位
525 - var showConfirmation = true; 525 + // var showConfirmation = true;
526 - // 监听 beforeunload 事件 526 + // // 监听 beforeunload 事件
527 - window.addEventListener('beforeunload', function (event) { 527 + // window.addEventListener('beforeunload', function (event) {
528 - if (showConfirmation) { 528 + // if (showConfirmation) {
529 - // 取消事件的默认行为(弹出确认对话框) 529 + // // 取消事件的默认行为(弹出确认对话框)
530 - event.preventDefault(); 530 + // event.preventDefault();
531 - } 531 + // }
532 - }); 532 + // });
533 - // 监听 unload 事件 533 + // // 监听 unload 事件
534 - window.addEventListener('unload', function () { 534 + // window.addEventListener('unload', function () {
535 - // 设置标志位为 false,避免在刷新页面时再次显示提示框 535 + // // 设置标志位为 false,避免在刷新页面时再次显示提示框
536 - showConfirmation = false; 536 + // showConfirmation = false;
537 - }); 537 + // });
538 // 监听 resize 事件 538 // 监听 resize 事件
539 window.addEventListener('resize', function () { 539 window.addEventListener('resize', function () {
540 state.detailModel = null; 540 state.detailModel = null;
......
1 /* 1 /*
2 * @Date: 2023-10-27 11:12:24 2 * @Date: 2023-10-27 11:12:24
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2023-10-27 11:13:00 4 + * @LastEditTime: 2023-11-21 15:23:46
5 * @FilePath: /vue-flow-editor/doc/axios.js 5 * @FilePath: /vue-flow-editor/doc/axios.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
8 import axios from 'axios'; 8 import axios from 'axios';
9 9
10 axios.defaults.params = { 10 axios.defaults.params = {
11 - f: 'custom_form', 11 + m: 'mod',
12 + p: 'authority_my',
12 }; 13 };
13 14
14 /** 15 /**
......
1 <!-- 1 <!--
2 * @Date: 2023-11-01 10:18:53 2 * @Date: 2023-11-01 10:18:53
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2023-11-16 17:46:07 4 + * @LastEditTime: 2023-11-22 11:39:41
5 * @FilePath: /vue-flow-editor/doc/selectUserView.vue 5 * @FilePath: /vue-flow-editor/doc/selectUserView.vue
6 * @Description: 成员列表选择控件 6 * @Description: 成员列表选择控件
7 --> 7 -->
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 v-if="userTags.length" 16 v-if="userTags.length"
17 v-for="tag in userTags" 17 v-for="tag in userTags"
18 :key="tag.name" 18 :key="tag.name"
19 - style="margin-left: 0.25rem; margin-right: 0.25rem;" 19 + style="margin-left: 0.25rem; margin-right: 0.25rem; margin-bottom: 0.5rem;"
20 closable 20 closable
21 @close="handleTagClose(tag)" 21 @close="handleTagClose(tag)"
22 > 22 >
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
50 :id="item.id" 50 :id="item.id"
51 @click="handleTabClick(item, $event, index)" 51 @click="handleTabClick(item, $event, index)"
52 > 52 >
53 - {{ item.label }} 53 + {{ item.name }}
54 </div> 54 </div>
55 </div> 55 </div>
56 </div> 56 </div>
...@@ -79,35 +79,39 @@ ...@@ -79,35 +79,39 @@
79 </div> 79 </div>
80 </div> 80 </div>
81 <!-- 未激活搜索框 --> 81 <!-- 未激活搜索框 -->
82 - <div v-if="!is_active_search"> 82 + <div v-if="!is_active_search" style="max-height: 300px; overflow: scroll;">
83 <div v-for="(item, index) in userTabs" :key="index"> 83 <div v-for="(item, index) in userTabs" :key="index">
84 - <div v-if="item.id === activeTabId && item.type === 'select'"> 84 + <!-- 组织结构树 -->
85 + <div v-if="item.id === activeTabId && item.type === 'corp-tree'">
85 <el-row> 86 <el-row>
86 <el-col :span="24"> 87 <el-col :span="24">
87 - <el-checkbox-group 88 + <el-tree
88 - class="flow-checkbox-group" 89 + ref="corpTreeRef"
89 - v-model="checkedUserList" 90 + :data="item.data"
90 - > 91 + :props="defaultProps"
91 - <el-checkbox 92 + show-checkbox
92 - v-for="(user, idx) in userList" 93 + node-key="id"
93 - :key="idx" 94 + :default-expanded-keys="currentNodeKey"
94 - :label="user.id" 95 + :default-checked-keys="currentCheckedNodeKey"
95 - :disabled="user.disabled" 96 + :check-strictly="true"
96 - @change="handleCheckedUserListChange(user, $event)" 97 + empty-text="暂无数据"
97 - >{{ user.label }}</el-checkbox 98 + @check="checkNode"
98 - > 99 + style="margin-top: 10px;"
99 - </el-checkbox-group> 100 + />
100 - </el-col> 101 + </el-col>
101 - </el-row> 102 + </el-row>
102 </div> 103 </div>
103 - <div v-if="item.id === activeTabId && item.type === 'tree'"> 104 + <!-- 成员选择树 -->
105 + <div v-if="item.id === activeTabId && item.type === 'user-tree'">
104 <el-row> 106 <el-row>
105 <el-col :span="8"> 107 <el-col :span="8">
106 <el-tree 108 <el-tree
109 + ref="userTreeRef"
107 :data="item.data" 110 :data="item.data"
108 :props="defaultProps" 111 :props="defaultProps"
109 node-key="id" 112 node-key="id"
110 :default-expanded-keys="currentNodeKey" 113 :default-expanded-keys="currentNodeKey"
114 + :highlight-current="true"
111 empty-text="暂无数据" 115 empty-text="暂无数据"
112 @node-click="handleNodeClick" 116 @node-click="handleNodeClick"
113 style="margin-top: 10px;" 117 style="margin-top: 10px;"
...@@ -125,14 +129,34 @@ ...@@ -125,14 +129,34 @@
125 :label="user.id" 129 :label="user.id"
126 :disabled="user.disabled" 130 :disabled="user.disabled"
127 @change="handleCheckedUserListChange(user, $event)" 131 @change="handleCheckedUserListChange(user, $event)"
128 - >{{ user.label }}</el-checkbox 132 + >{{ user.name }}</el-checkbox
129 > 133 >
130 </el-checkbox-group> 134 </el-checkbox-group>
131 </div> 135 </div>
132 </el-col> 136 </el-col>
133 </el-row> 137 </el-row>
134 </div> 138 </div>
135 - <div v-if="item.id === activeTabId && item.type === 'list'"> 139 + <div v-if="item.id === activeTabId && item.type === 'role-list'">
140 + <el-row>
141 + <el-col :span="24">
142 + <el-checkbox-group
143 + class="flow-checkbox-group"
144 + v-model="checkedUserList"
145 + >
146 + <el-checkbox
147 + v-for="(user, idx) in userList"
148 + :key="idx"
149 + :label="user.id"
150 + :disabled="user.disabled"
151 + @change="handleCheckedUserListChange(user, $event)"
152 + >{{ user.name }}</el-checkbox
153 + >
154 + </el-checkbox-group>
155 + </el-col>
156 + </el-row>
157 + </div>
158 + <!-- 左右选择结构 -->
159 + <!-- <div v-if="item.id === activeTabId && item.type === ''">
136 <el-tabs 160 <el-tabs
137 tab-position="left" 161 tab-position="left"
138 style="" 162 style=""
...@@ -143,8 +167,8 @@ ...@@ -143,8 +167,8 @@
143 <el-tab-pane 167 <el-tab-pane
144 v-for="(role, idx) in item.data" 168 v-for="(role, idx) in item.data"
145 :key="idx" 169 :key="idx"
146 - :name="role.label" 170 + :name="role.name"
147 - :label="role.label" 171 + :label="role.name"
148 > 172 >
149 <el-checkbox-group 173 <el-checkbox-group
150 class="flow-checkbox-group" 174 class="flow-checkbox-group"
...@@ -161,7 +185,7 @@ ...@@ -161,7 +185,7 @@
161 </el-checkbox-group> 185 </el-checkbox-group>
162 </el-tab-pane> 186 </el-tab-pane>
163 </el-tabs> 187 </el-tabs>
164 - </div> 188 + </div> -->
165 </div> 189 </div>
166 </div> 190 </div>
167 <!-- 激活搜索框 --> 191 <!-- 激活搜索框 -->
...@@ -177,7 +201,7 @@ ...@@ -177,7 +201,7 @@
177 :label="user.id" 201 :label="user.id"
178 :disabled="user.disabled" 202 :disabled="user.disabled"
179 @change="handleCheckedUserListChange(user, $event)" 203 @change="handleCheckedUserListChange(user, $event)"
180 - >{{ user.label }}</el-checkbox 204 + >{{ user.name }}</el-checkbox
181 > 205 >
182 </el-checkbox-group> 206 </el-checkbox-group>
183 </div> 207 </div>
...@@ -196,20 +220,45 @@ import { ref, onMounted, watch, nextTick } from "vue"; ...@@ -196,20 +220,45 @@ import { ref, onMounted, watch, nextTick } from "vue";
196 import { useRoute, useRouter } from "vue-router"; 220 import { useRoute, useRouter } from "vue-router";
197 import axios from "./axios"; 221 import axios from "./axios";
198 import $ from "jquery"; 222 import $ from "jquery";
223 +import _ from "lodash";
199 224
200 const props = defineProps({ 225 const props = defineProps({
201 visible: Boolean 226 visible: Boolean
202 }); 227 });
203 const emit = defineEmits(["close", "confirm"]); 228 const emit = defineEmits(["close", "confirm"]);
204 229
230 +const corpTreeRef = ref(null); // 组织结构树的ref
231 +const userTreeRef = ref(null); // 成员选择树的ref
232 +
205 const dialogUserFormVisible = ref(false); 233 const dialogUserFormVisible = ref(false);
206 -const userTags = ref([]); 234 +const userTags = ref([]); // 现在只维护选中的用户列表,以它为基准维护其他列表选中情况
207 const currentNodeKey = ref([]); // 当前展开的节点 235 const currentNodeKey = ref([]); // 当前展开的节点
208 -const activeTabId = ref("tab-0"); // TODO: 需要获取默认第一个ID 236 +const currentCheckedNodeKey = ref([]); // 当前选中的节点
237 +const activeTabId = ref("tab-corp"); // TODO: 需要获取默认第一个ID
238 +const activeTabIdx = ref(0); // 默认激活tab的index
209 const activeTabContent = ref(""); 239 const activeTabContent = ref("");
210 -const userTabs = ref([]); 240 +const userTabs = ref([
241 + {
242 + id: "tab-corp",
243 + name: "组织结构",
244 + type: "corp-tree",
245 + data: []
246 + },
247 + {
248 + id: "tab-uer",
249 + name: "成员",
250 + type: "user-tree",
251 + data: []
252 + },
253 + {
254 + id: "tab-role",
255 + name: "角色",
256 + type: "role-list",
257 + data: []
258 + }
259 +]);
211 const tabSelectData = ref([]); 260 const tabSelectData = ref([]);
212 -const userTabType = ref("tree"); 261 +const userTabType = ref("user-tree");
213 const tabOffset = ref("0px"); 262 const tabOffset = ref("0px");
214 const tabTextWidth = ref("76px"); // 文字宽度需要打开弹框时重新计算 263 const tabTextWidth = ref("76px"); // 文字宽度需要打开弹框时重新计算
215 const is_active_search = ref(false); 264 const is_active_search = ref(false);
...@@ -220,187 +269,297 @@ const searchUserList = ref([]); // 搜索框 选中 用户ID ...@@ -220,187 +269,297 @@ const searchUserList = ref([]); // 搜索框 选中 用户ID
220 const checkedSearchUserList = ref([]); 269 const checkedSearchUserList = ref([]);
221 const defaultProps = ref({ 270 const defaultProps = ref({
222 children: "children", 271 children: "children",
223 - label: "label" 272 + label: "name"
224 }); 273 });
225 274
226 -onMounted(() => { 275 +// TAG: 接口获取数据
227 - // axios.get('/srv/?a=query_form_all_field') 276 +const getDeptList = () => {
228 - // .then(res => { 277 + return axios.get('/admin/?a=flow_dept_list')
229 - // console.warn(res.data); 278 +}
230 - // }); 279 +const getRoleList = () => {
280 + return axios.get('/admin/?a=flow_role_list')
281 +}
282 +
283 +const deptList = ref([]); // 部门列表
284 +const deptUserList = ref([]); // 部门用户列表
285 +const roleList = ref([]); // 角色列表
286 +
287 +onMounted(async () => {
288 + // TAG:接口获取组织结构数据
289 + const dept_list = await getDeptList();
290 + const role_list = await getRoleList();
291 + if (dept_list.data.code) {
292 + deptList.value = dept_list.data.data;
293 + deptUserList.value = _.cloneDeep(dept_list.data.data);
294 + }
295 + if (role_list.data.code) {
296 + roleList.value = role_list.data.data;
297 + }
298 + userTabs.value.forEach(item => {
299 + if (item.type === 'corp-tree') {
300 + item.data = deptList.value;
301 + }
302 + if (item.type === 'user-tree') {
303 + item.data = deptUserList.value;
304 + }
305 + if (item.type === 'role-list') {
306 + item.data = roleList.value;
307 + }
308 + });
231 // 根据数据获取选中的tag标签 309 // 根据数据获取选中的tag标签
232 // setTagsList(userTabs); 310 // setTagsList(userTabs);
233 // TODO: 查询到的用户选中列表数据 311 // TODO: 查询到的用户选中列表数据
234 - userTags.value = [{ id: "user-1-1", name: "用户1-1" }]; 312 + userTags.value = [{ id: 35697, name: "西园寺" },{ id: 492081, name: "营员" }];
313 + // //
314 + // const role_raw_data = [
315 + // {
316 + // "id": 624337,
317 + // "name": "八关斋戒"
318 + // },
319 + // {
320 + // "id": 82983,
321 + // "name": "场地管理"
322 + // },
323 + // {
324 + // "id": 83245,
325 + // "name": "场地使用"
326 + // },
327 + // ];
328 + // let role_list = ref([]);
329 + // role_raw_data.forEach(item => {
330 + // role_list.value.push({
331 + // id: item.id,
332 + // label: item.name,
333 + // checked: false,
334 + // disabled: false
335 + // })
336 + // })
337 + // const role_data = ref({
338 + // id: "tab-2",
339 + // label: "角色",
340 + // type: "select",
341 + // data: [
342 + // {
343 + // id: "",
344 + // label: "",
345 + // children: [],
346 + // list: role_list.value
347 + // },
348 + // ]
349 + // })
235 // TODO: 查询到的用户列表数据 350 // TODO: 查询到的用户列表数据
236 - userTabs.value = [ 351 + // userTabs.value = [
237 - { 352 + // {
238 - id: "tab-0", 353 + // id: "tab-0",
239 - label: "组织结构", 354 + // label: "组织架构",
240 - type: "select", 355 + // type: "corp-tree",
241 - data: [ 356 + // data: [
242 - { 357 + // {
243 - id: "corp-1", 358 + // id: "corp-1",
244 - label: "", 359 + // label: "组织结构 1",
245 - children: [], 360 + // children: [
246 - list: [ 361 + // {
247 - { 362 + // id: "dept-1-1",
248 - id: "corp-1-1", 363 + // label: "组织结构 1-1",
249 - label: "组织结构1-1", 364 + // children: [],
250 - checked: false, 365 + // list: [
251 - disabled: false 366 + // {
252 - } 367 + // id: "user-1-1",
253 - ] 368 + // label: "组织1-1",
254 - }, 369 + // checked: false,
255 - ] 370 + // disabled: false
256 - }, 371 + // },
257 - { 372 + // {
258 - id: "tab-1", 373 + // id: "user-1-2",
259 - label: "成员", 374 + // label: "组织1-2",
260 - type: "tree", 375 + // checked: false,
261 - data: [ 376 + // disabled: false
262 - { 377 + // },
263 - id: "dept-1", 378 + // {
264 - label: "上级部门 1", 379 + // id: "user-1-3",
265 - children: [ 380 + // label: "组织1-3",
266 - { 381 + // checked: false,
267 - id: "dept-1-1", 382 + // disabled: true
268 - label: "部门名称 1-1", 383 + // }
269 - children: [], 384 + // ]
270 - list: [ 385 + // }
271 - { 386 + // ]
272 - id: "user-1-1", 387 + // },
273 - label: "用户1-1", 388 + // {
274 - checked: false, 389 + // id: "dept-2",
275 - disabled: false 390 + // label: "上级部门 2",
276 - }, 391 + // children: [
277 - { 392 + // {
278 - id: "user-1-2", 393 + // id: "dept-2-1",
279 - label: "用户1-2", 394 + // label: "部门名称 2-1",
280 - checked: false, 395 + // children: [],
281 - disabled: false 396 + // list: [
282 - }, 397 + // {
283 - { 398 + // id: "user-2-1",
284 - id: "user-1-3", 399 + // label: "用户2-1",
285 - label: "用户1-3", 400 + // checked: false,
286 - checked: false, 401 + // disabled: false
287 - disabled: true 402 + // },
288 - } 403 + // {
289 - ] 404 + // id: "user-2-2",
290 - } 405 + // label: "用户2-2",
291 - ] 406 + // checked: false,
292 - }, 407 + // disabled: false
293 - { 408 + // },
294 - id: "dept-2", 409 + // {
295 - label: "上级部门 2", 410 + // id: "user-2-3",
296 - children: [ 411 + // label: "用户2-3",
297 - { 412 + // checked: false,
298 - id: "dept-2-1", 413 + // disabled: true
299 - label: "部门名称 2-1", 414 + // }
300 - children: [], 415 + // ]
301 - list: [ 416 + // }
302 - { 417 + // ]
303 - id: "user-2-1", 418 + // }
304 - label: "用户2-1", 419 + // ]
305 - checked: false, 420 + // },
306 - disabled: false 421 + // {
307 - }, 422 + // id: "tab-1",
308 - { 423 + // label: "成员",
309 - id: "user-2-2", 424 + // type: "user-tree",
310 - label: "用户2-2", 425 + // data: [
311 - checked: false, 426 + // {
312 - disabled: false 427 + // id: "dept-1",
313 - }, 428 + // label: "上级部门 1",
314 - { 429 + // children: [
315 - id: "user-2-3", 430 + // {
316 - label: "用户2-3", 431 + // id: "dept-1-1",
317 - checked: false, 432 + // label: "部门名称 1-1",
318 - disabled: true 433 + // children: [],
319 - } 434 + // list: [
320 - ] 435 + // {
321 - } 436 + // id: "user-1-1",
322 - ] 437 + // label: "用户1-1",
323 - } 438 + // checked: false,
324 - ] 439 + // disabled: false
325 - }, 440 + // },
326 - { 441 + // {
327 - id: "tab-2", 442 + // id: "user-1-2",
328 - label: "角色", 443 + // label: "用户1-2",
329 - type: "list", 444 + // checked: false,
330 - data: [ 445 + // disabled: false
331 - { 446 + // },
332 - id: "role-1-1", 447 + // {
333 - label: "流程发起人", 448 + // id: "user-1-3",
334 - children: [], 449 + // label: "用户1-3",
335 - list: [ 450 + // checked: false,
336 - { 451 + // disabled: true
337 - id: "user-1-1", 452 + // }
338 - label: "用户1-1", 453 + // ]
339 - checked: true, 454 + // }
340 - disabled: false 455 + // ]
341 - }, 456 + // },
342 - { 457 + // {
343 - id: "user-2-2", 458 + // id: "dept-2",
344 - label: "用户2-2", 459 + // label: "上级部门 2",
345 - checked: false, 460 + // children: [
346 - disabled: false 461 + // {
347 - }, 462 + // id: "dept-2-1",
348 - { 463 + // label: "部门名称 2-1",
349 - id: "role-1-4", 464 + // children: [],
350 - label: "选项 C", 465 + // list: [
351 - checked: false, 466 + // {
352 - disabled: true 467 + // id: "user-2-1",
353 - } 468 + // label: "用户2-1",
354 - ] 469 + // checked: false,
355 - }, 470 + // disabled: false
356 - { 471 + // },
357 - id: "role-1-2", 472 + // {
358 - label: "成员字段", 473 + // id: "user-2-2",
359 - children: [], 474 + // label: "用户2-2",
360 - list: [] 475 + // checked: false,
361 - }, 476 + // disabled: false
362 - { 477 + // },
363 - id: "role-1-3", 478 + // {
364 - label: "部门字段", 479 + // id: "user-2-3",
365 - children: [], 480 + // label: "用户2-3",
366 - list: [] 481 + // checked: false,
367 - }, 482 + // disabled: true
368 - { 483 + // }
369 - id: "role-1-4", 484 + // ]
370 - label: "主管", 485 + // }
371 - children: [], 486 + // ]
372 - list: [] 487 + // }
373 - } 488 + // ]
374 - ] 489 + // },
375 - } 490 + // {
376 - ]; 491 + // id: "tab-2",
492 + // label: "角色",
493 + // type: "role-list",
494 + // data: [
495 + // {
496 + // id: "role-1-1",
497 + // label: "流程发起人",
498 + // children: [],
499 + // list: [
500 + // {
501 + // id: "user-1-1",
502 + // label: "用户1-1",
503 + // checked: true,
504 + // disabled: false
505 + // },
506 + // {
507 + // id: "user-2-2",
508 + // label: "用户2-2",
509 + // checked: false,
510 + // disabled: false
511 + // },
512 + // {
513 + // id: "role-1-4",
514 + // label: "选项 C",
515 + // checked: false,
516 + // disabled: true
517 + // }
518 + // ]
519 + // },
520 + // {
521 + // id: "role-1-2",
522 + // label: "成员字段",
523 + // children: [],
524 + // list: []
525 + // },
526 + // {
527 + // id: "role-1-3",
528 + // label: "部门字段",
529 + // children: [],
530 + // list: []
531 + // },
532 + // {
533 + // id: "role-1-4",
534 + // label: "主管",
535 + // children: [],
536 + // list: []
537 + // }
538 + // ]
539 + // }
540 + // ];
541 + // userTabs.value = userTabs.value.concat(role_data.value);
377 // 对比选中的用户的 ID,选中的 ID 同步状态到 userTabs 的数据结构上 542 // 对比选中的用户的 ID,选中的 ID 同步状态到 userTabs 的数据结构上
378 - userTags.value.forEach(ele => { 543 + // userTags.value.forEach(ele => {
379 - modifyFieldValue(userTabs.value, "id", ele.id, "checked", true); 544 + // modifyFieldValue(userTabs.value, "id", ele.id, "checked", true);
380 - }); 545 + // });
546 + // TODO: 组织结构处理可能需要优化
547 + // 因为第一个是组织结构树,默认展开第一个节点
548 + if (userTabs.value[activeTabIdx.value]['type'] === 'corp-tree') {
549 + if (userTabs.value[activeTabIdx.value]['data'].length) {
550 + currentNodeKey.value = [userTabs.value[activeTabIdx.value]['data'][0]['id']];
551 + // 把选中的节点注入树结构显示选中状态
552 + nextTick(() => {
553 + currentCheckedNodeKey.value = userTags.value.map(ele => ele.id);
554 + });
555 + }
556 + }
381 }); 557 });
382 558
383 watch(() => { 559 watch(() => {
384 - // 监听弹框状态 560 + // TAG:监听弹框状态
385 if (props.visible) { 561 if (props.visible) {
386 dialogUserFormVisible.value = true; 562 dialogUserFormVisible.value = true;
387 - // 第一个类型为多选,获取类型为多选的数据结构
388 - if (userTabs.value[0]['type'] === 'select') {
389 - userTabs.value.forEach(ele => {
390 - if (ele.type === "select") {
391 - ele.data.forEach(ele => {
392 - userList.value = ele.list;
393 - checkedUserList.value = ele.list
394 - .filter(ele => {
395 - return ele.checked;
396 - })
397 - .map(ele => {
398 - return ele.id;
399 - });
400 - });
401 - }
402 - });
403 - }
404 } else { 563 } else {
405 dialogUserFormVisible.value = false; 564 dialogUserFormVisible.value = false;
406 } 565 }
...@@ -414,7 +573,7 @@ watch(() => { ...@@ -414,7 +573,7 @@ watch(() => {
414 * @param {number} idx - The index of the clicked tab. 573 * @param {number} idx - The index of the clicked tab.
415 */ 574 */
416 const handleTabClick = (tab, event, idx) => { 575 const handleTabClick = (tab, event, idx) => {
417 - tabSelectData.value = tab.data; // tab选中数据提供给list类型使用 576 + // tabSelectData.value = tab.data; // tab选中数据提供给list类型使用
418 userList.value = []; // 清空用户列表 577 userList.value = []; // 清空用户列表
419 checkedUserList.value = []; // 清空选中用户列表 578 checkedUserList.value = []; // 清空选中用户列表
420 activeTabContent.value = ""; // 清空侧边栏显示 579 activeTabContent.value = ""; // 清空侧边栏显示
...@@ -422,6 +581,7 @@ const handleTabClick = (tab, event, idx) => { ...@@ -422,6 +581,7 @@ const handleTabClick = (tab, event, idx) => {
422 // 设置当前激活的tab 581 // 设置当前激活的tab
423 userTabType.value = tab.type; 582 userTabType.value = tab.type;
424 activeTabId.value = tab.id; 583 activeTabId.value = tab.id;
584 + activeTabIdx.value = idx;
425 // 子容器相对于父容器的相对x轴位移, 第一项为0 585 // 子容器相对于父容器的相对x轴位移, 第一项为0
426 if (idx) { 586 if (idx) {
427 tabOffset.value = $("#" + tab.id).position().left + 20 + "px"; 587 tabOffset.value = $("#" + tab.id).position().left + 20 + "px";
...@@ -430,35 +590,29 @@ const handleTabClick = (tab, event, idx) => { ...@@ -430,35 +590,29 @@ const handleTabClick = (tab, event, idx) => {
430 } 590 }
431 // 文字宽度 591 // 文字宽度
432 tabTextWidth.value = $("#" + tab.id).width() + "px"; 592 tabTextWidth.value = $("#" + tab.id).width() + "px";
433 - // 获取类型为多选的数据结构 593 + //
434 - if (tab.type === 'select') { 594 + console.warn(tab);
435 - userTabs.value.forEach(ele => { 595 + // 组织结构树,默认展开第一个节点, 把选中用户ID显示到数
436 - if (ele.type === "select") { 596 + if (tab.type === 'corp-tree') {
437 - ele.data.forEach(ele => { 597 + if (tab.data.length) {
438 - userList.value = ele.list; 598 + currentNodeKey.value = [tab.data[0]['id']];
439 - checkedUserList.value = ele.list 599 + nextTick(() => {
440 - .filter(ele => { 600 + // 把选中的节点注入树结构显示选中状态
441 - return ele.checked; 601 + corpTreeRef.value.setCheckedKeys(userTags.value.map(ele => ele.id), false)
442 - }) 602 + })
443 - .map(ele => { 603 + }
444 - return ele.id; 604 + }
445 - }); 605 + // 成员选择树
446 - }); 606 + if (tab.type === 'user-tree') {
447 - } 607 + if (tab.data.length) {
448 - }); 608 + currentNodeKey.value = [tab.data[0]['id']];
609 + }
610 + }
611 + // 角色选择列表
612 + if (tab.type === 'role-list') {
613 + userList.value = tab.data;
614 + checkedUserList.value = userTags.value.map(ele => ele.id);
449 } 615 }
450 - // 检查列表第一项是否有值
451 - // if (tab?.data[0]?.list) {
452 - // let list = tab.data[0].list;
453 - // userList.value = list;
454 - // checkedUserList.value = list
455 - // .filter(ele => {
456 - // return ele.checked;
457 - // })
458 - // .map(ele => {
459 - // return ele.id;
460 - // });
461 - // }
462 }; 616 };
463 617
464 /** 618 /**
...@@ -469,7 +623,8 @@ const handleTabClick = (tab, event, idx) => { ...@@ -469,7 +623,8 @@ const handleTabClick = (tab, event, idx) => {
469 */ 623 */
470 const handleTabContentClick = (tab, event) => { 624 const handleTabContentClick = (tab, event) => {
471 tabSelectData.value.forEach(ele => { 625 tabSelectData.value.forEach(ele => {
472 - if (ele.label === tab.props.label) { 626 + if (ele.name === tab.props.name) {
627 + console.warn(ele);
473 // 设置右侧显示数据 628 // 设置右侧显示数据
474 userList.value = ele.list; 629 userList.value = ele.list;
475 checkedUserList.value = ele.list 630 checkedUserList.value = ele.list
...@@ -484,19 +639,16 @@ const handleTabContentClick = (tab, event) => { ...@@ -484,19 +639,16 @@ const handleTabContentClick = (tab, event) => {
484 }; 639 };
485 640
486 /** 641 /**
487 - * 树形结构点击回调 642 + * 成员选择树 点击回调
488 * 643 *
489 * @param {object} data - The data associated with the clicked node. 644 * @param {object} data - The data associated with the clicked node.
490 * @return {void} 645 * @return {void}
491 */ 646 */
492 const handleNodeClick = data => { 647 const handleNodeClick = data => {
493 - if (data.list) { 648 + if (data.user) {
494 - // 如果节点下存在 list 字段,设置为右侧显示数据列表 649 + // 如果节点下存在 user 字段,设置为右侧显示数据列表
495 - userList.value = data.list; 650 + userList.value = data.user;
496 - checkedUserList.value = data.list 651 + checkedUserList.value = userTags.value
497 - .filter(ele => {
498 - return ele.checked;
499 - })
500 .map(ele => { 652 .map(ele => {
501 return ele.id; 653 return ele.id;
502 }); 654 });
...@@ -506,6 +658,33 @@ const handleNodeClick = data => { ...@@ -506,6 +658,33 @@ const handleNodeClick = data => {
506 }; 658 };
507 659
508 /** 660 /**
661 + * 组织结构树形结构 选中回调
662 + *
663 + * @param {*} obj 传递给 data 属性的数组中该节点所对应的对象
664 + * @param {*} status 树目前的选中状态对象,包含 checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
665 + * @return {void}
666 + */
667 +const checkNode = (obj, status) => {
668 + // console.log(obj);
669 + // console.log(status);
670 + // 判断当前节点是选中还是取消选中
671 + if (status.checkedKeys.indexOf(obj.id) > -1) { // 选中
672 + // 新增勾选的用户
673 + let check_nodes = status.checkedNodes.map(ele => {
674 + return { id: ele.id, name: ele.name };
675 + });
676 + userTags.value = userTags.value.concat(check_nodes);
677 + // 如果ID相同,需要数据去重
678 + userTags.value = _.uniqBy(userTags.value, 'id');
679 + } else {
680 + // 移除勾选的用户
681 + userTags.value = userTags.value.filter(ele => {
682 + return ele.id!== obj.id;
683 + });
684 + }
685 +}
686 +
687 +/**
509 * 递归查找匹配字段,并修改字段的值为新值 688 * 递归查找匹配字段,并修改字段的值为新值
510 * 689 *
511 * @param {object} obj - 修改对象 690 * @param {object} obj - 修改对象
...@@ -536,8 +715,16 @@ function modifyFieldValue(obj, fieldName, fieldValue, targetName, newValue) { ...@@ -536,8 +715,16 @@ function modifyFieldValue(obj, fieldName, fieldValue, targetName, newValue) {
536 * @return {type} description of return value 715 * @return {type} description of return value
537 */ 716 */
538 const handleCheckedUserListChange = (user, checked) => { 717 const handleCheckedUserListChange = (user, checked) => {
539 - // 修改选中值状态 718 + if (checked) { // 新增勾选的用户
540 - modifyFieldValue(userTabs.value, "id", user.id, "checked", checked); 719 + userTags.value = userTags.value.concat({ id: user.id, name: user.name });
720 + // 如果ID相同,需要数据去重
721 + userTags.value = _.uniqBy(userTags.value, 'id');
722 + } else {
723 + // 移除勾选的用户
724 + userTags.value = userTags.value.filter(ele => {
725 + return ele.id!== user.id;
726 + });
727 + }
541 }; 728 };
542 729
543 /** 730 /**
...@@ -591,7 +778,7 @@ const setTagsList = val => { ...@@ -591,7 +778,7 @@ const setTagsList = val => {
591 .map(ele => { 778 .map(ele => {
592 return { 779 return {
593 id: ele.id, 780 id: ele.id,
594 - name: ele.label 781 + name: ele.name
595 }; 782 };
596 }); 783 });
597 }; 784 };
...@@ -602,7 +789,7 @@ watch( ...@@ -602,7 +789,7 @@ watch(
602 val => { 789 val => {
603 if (val) { 790 if (val) {
604 // 更新 tags 选中列表显示 791 // 更新 tags 选中列表显示
605 - setTagsList(val); 792 + // setTagsList(val);
606 } 793 }
607 }, 794 },
608 { deep: true } 795 { deep: true }
...@@ -616,29 +803,42 @@ watch( ...@@ -616,29 +803,42 @@ watch(
616 */ 803 */
617 const handleTagClose = tag => { 804 const handleTagClose = tag => {
618 userTags.value.splice(userTags.value.indexOf(tag), 1); // 删除标签列表中的项 805 userTags.value.splice(userTags.value.indexOf(tag), 1); // 删除标签列表中的项
619 - // 移除数据结构中的选中值 806 + // 处理不同分支选中显示问题
620 - modifyFieldValue(userTabs.value, "id", tag.id, "checked", false); 807 + switch (activeTabId.value) {
621 - // ID集合 808 + case 'tab-corp': // 组织结构
622 - let tagsId = userTags.value.map(ele => { 809 + // 把选中的节点注入树结构显示选中状态
623 - return ele.id; 810 + corpTreeRef.value.setCheckedKeys(userTags.value.map(ele => ele.id), false)
624 - }); 811 + break;
625 - // 处理tags列表和下面选中列表同步问题 812 + case 'tab-uer': // 成员
626 - let checkDataList = []; 813 +
627 - if (is_active_search.value) { 814 + break;
628 - // 激活搜索状态 815 + case 'tab-role': // 角色
629 - checkDataList = checkedSearchUserList.value; 816 +
630 - } else { 817 + break;
631 - // 激活非搜索状态
632 - checkDataList = checkedUserList.value;
633 - }
634 - // 获取 tags 中已删除的, 勾选列表中还勾选的值
635 - let result = checkDataList.filter(value => !tagsId.includes(value));
636 - // 如果存在不同步的值,需要在列表中删除勾选列表中的项
637 - if (result.length) {
638 - result.forEach(ele => {
639 - checkDataList.splice(checkDataList.indexOf(ele), 1);
640 - });
641 } 818 }
819 + // // 移除数据结构中的选中值
820 + // modifyFieldValue(userTabs.value, "id", tag.id, "checked", false);
821 + // // ID集合
822 + // let tagsId = userTags.value.map(ele => {
823 + // return ele.id;
824 + // });
825 + // // 处理tags列表和下面选中列表同步问题
826 + // let checkDataList = [];
827 + // if (is_active_search.value) {
828 + // // 激活搜索状态
829 + // checkDataList = checkedSearchUserList.value;
830 + // } else {
831 + // // 激活非搜索状态
832 + // checkDataList = checkedUserList.value;
833 + // }
834 + // // 获取 tags 中已删除的, 勾选列表中还勾选的值
835 + // let result = checkDataList.filter(value => !tagsId.includes(value));
836 + // // 如果存在不同步的值,需要在列表中删除勾选列表中的项
837 + // if (result.length) {
838 + // result.forEach(ele => {
839 + // checkDataList.splice(checkDataList.indexOf(ele), 1);
840 + // });
841 + // }
642 }; 842 };
643 843
644 /** 844 /**
...@@ -731,19 +931,19 @@ const onSearch = () => { ...@@ -731,19 +931,19 @@ const onSearch = () => {
731 searchUserList.value = [ 931 searchUserList.value = [
732 { 932 {
733 id: "user-1-1", 933 id: "user-1-1",
734 - label: "用户1-1", 934 + name: "用户1-1",
735 checked: false, 935 checked: false,
736 disabled: false 936 disabled: false
737 }, 937 },
738 { 938 {
739 id: "user-1-2", 939 id: "user-1-2",
740 - label: "用户1-2", 940 + name: "用户1-2",
741 checked: false, 941 checked: false,
742 disabled: false 942 disabled: false
743 }, 943 },
744 { 944 {
745 id: "user-1-3", 945 id: "user-1-3",
746 - label: "用户1-3", 946 + name: "用户1-3",
747 checked: false, 947 checked: false,
748 disabled: true 948 disabled: true
749 } 949 }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
28 "echarts": "^5.1.2", 28 "echarts": "^5.1.2",
29 "element-plus": "^2.4.1", 29 "element-plus": "^2.4.1",
30 "jquery": "^3.7.1", 30 "jquery": "^3.7.1",
31 + "lodash": "^4.17.21",
31 "sass": "^1.69.4", 32 "sass": "^1.69.4",
32 "sass-loader": "10.1.1", 33 "sass-loader": "10.1.1",
33 "vue": "^3.0.0", 34 "vue": "^3.0.0",
......