Showing
3 changed files
with
502 additions
and
479 deletions
@@ -14,9 +14,10 @@ | @@ -14,9 +14,10 @@ | ||
14 | </Button> | 14 | </Button> |
15 | <BasicTree | 15 | <BasicTree |
16 | v-if="organizationTreeData.length" | 16 | v-if="organizationTreeData.length" |
17 | + :check-strictly="checkStrictly" | ||
17 | v-model:value="model[field]" | 18 | v-model:value="model[field]" |
18 | :treeData="organizationTreeData" | 19 | :treeData="organizationTreeData" |
19 | - :checked-keys="checkGroup" | 20 | + :checked-keys="checkedKeys" |
20 | :expandedKeys="treeExpandData" | 21 | :expandedKeys="treeExpandData" |
21 | ref="basicTreeRef" | 22 | ref="basicTreeRef" |
22 | @check="handleCheckClick" | 23 | @check="handleCheckClick" |
@@ -25,6 +26,7 @@ | @@ -25,6 +26,7 @@ | ||
25 | checkable | 26 | checkable |
26 | toolbar | 27 | toolbar |
27 | @change="handleTreeSelect" | 28 | @change="handleTreeSelect" |
29 | + :replace-fields="{ children: 'children', title: 'name', key: 'id' }" | ||
28 | /> | 30 | /> |
29 | </template> | 31 | </template> |
30 | <template #roleSlot="{ model, field }"> | 32 | <template #roleSlot="{ model, field }"> |
@@ -53,8 +55,8 @@ | @@ -53,8 +55,8 @@ | ||
53 | </BasicModal> | 55 | </BasicModal> |
54 | <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" /> | 56 | <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" /> |
55 | </template> | 57 | </template> |
56 | -<script lang="ts"> | ||
57 | - import { defineComponent, ref, computed, unref, reactive, onMounted } from 'vue'; | 58 | +<script lang="ts" setup> |
59 | + import { ref, computed, unref, reactive, onMounted, toRaw } from 'vue'; | ||
58 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 60 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
59 | import { BasicForm, useForm } from '/@/components/Form/index'; | 61 | import { BasicForm, useForm } from '/@/components/Form/index'; |
60 | import { accountFormSchema } from './account.data'; | 62 | import { accountFormSchema } from './account.data'; |
@@ -64,262 +66,264 @@ | @@ -64,262 +66,264 @@ | ||
64 | SaveOrUpdateUserInfo, | 66 | SaveOrUpdateUserInfo, |
65 | filterRoleList, | 67 | filterRoleList, |
66 | } from '/@/api/system/system'; | 68 | } from '/@/api/system/system'; |
67 | - import { BasicTree, TreeItem, CheckKeys, CheckEvent } from '/@/components/Tree'; | 69 | + import { BasicTree, TreeItem, CheckKeys } from '/@/components/Tree'; |
68 | import { findCurrentUserGroups } from '/@/api/system/group'; | 70 | import { findCurrentUserGroups } from '/@/api/system/group'; |
69 | import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; | 71 | import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; |
70 | import { useMessage } from '/@/hooks/web/useMessage'; | 72 | import { useMessage } from '/@/hooks/web/useMessage'; |
71 | - import { copyTransTreeFun } from '/@/utils/fnUtils'; | ||
72 | import { TOption } from '/@/views/rule/linkedge/config/config.data'; | 73 | import { TOption } from '/@/views/rule/linkedge/config/config.data'; |
73 | import { PlusOutlined } from '@ant-design/icons-vue'; | 74 | import { PlusOutlined } from '@ant-design/icons-vue'; |
74 | import { useDrawer } from '/@/components/Drawer'; | 75 | import { useDrawer } from '/@/components/Drawer'; |
75 | import RoleDrawer from '../../role/CustomRoleDrawer.vue'; | 76 | import RoleDrawer from '../../role/CustomRoleDrawer.vue'; |
76 | import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; | 77 | import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; |
78 | + import { GroupListResultModel } from '/@/api/system/model/groupModel'; | ||
79 | + import { isArray } from '/@/utils/is'; | ||
77 | 80 | ||
78 | - export default defineComponent({ | ||
79 | - name: 'AccountModal', | ||
80 | - components: { | ||
81 | - BasicModal, | ||
82 | - BasicForm, | ||
83 | - Button, | ||
84 | - BasicTree, | ||
85 | - OrganizationDrawer, | ||
86 | - PlusOutlined, | ||
87 | - RoleDrawer, | ||
88 | - VNodes: (_, { attrs }) => { | ||
89 | - return attrs.vnodes; | ||
90 | - }, | ||
91 | - }, | ||
92 | - emits: ['success', 'register'], | ||
93 | - setup(_, { emit }) { | ||
94 | - const roleOptions = ref<TOption[]>([]); | ||
95 | - const isUpdate = ref(true); | ||
96 | - const rowId = ref(''); | ||
97 | - const organizationTreeData = ref<TreeItem[]>([]); | ||
98 | - const basicTreeRef = ref(); | ||
99 | - const checkGroup = ref<string[]>([]); | ||
100 | - const treeExpandData = ref([]); | ||
101 | - const olderPhoneNumber = ref(); | ||
102 | - const postData = reactive({}); | ||
103 | - const singleEditPostPhoneNumber = reactive({ | ||
104 | - phoneNumber: '', | ||
105 | - }); | ||
106 | - const checkedKeysWithHalfChecked = ref<(string | number)[]>([]); | ||
107 | - const getRoleList = async () => { | ||
108 | - const res = await filterRoleList(); | ||
109 | - roleOptions.value = res.map((m) => { | ||
110 | - return { | ||
111 | - label: m.name, | ||
112 | - value: m.id, | ||
113 | - }; | ||
114 | - }); | ||
115 | - }; | ||
116 | - onMounted(async () => { | ||
117 | - await getRoleList(); | ||
118 | - }); | ||
119 | - const [registerRoleDrawer, { openDrawer }] = useDrawer(); | 81 | + const VNodes = (_, { attrs }) => { |
82 | + return attrs.vnodes; | ||
83 | + }; | ||
120 | 84 | ||
121 | - const handleOpenRole = () => { | ||
122 | - openDrawer(true, { | ||
123 | - isUpdate: false, | ||
124 | - }); | ||
125 | - }; | ||
126 | - const clearValidateByField = (field: string) => { | ||
127 | - clearValidate(field); | ||
128 | - }; | ||
129 | - const handleRoleSelect = (e) => { | ||
130 | - if (e?.length > 0) clearValidateByField('roleIds'); | ||
131 | - else validateFields(['roleIds']); | ||
132 | - }; | ||
133 | - const handleTreeSelect = (e) => { | ||
134 | - if (e) clearValidateByField('organizationIds'); | ||
135 | - }; | ||
136 | - const handleSuccess = async () => { | ||
137 | - await getRoleList(); | 85 | + const emit = defineEmits(['register', 'success']); |
86 | + | ||
87 | + const checkStrictly = ref(true); | ||
88 | + const roleOptions = ref<TOption[]>([]); | ||
89 | + const isUpdate = ref(true); | ||
90 | + const rowId = ref(''); | ||
91 | + const organizationTreeData = ref<TreeItem[]>([]); | ||
92 | + const basicTreeRef = ref(); | ||
93 | + const checkedKeys = reactive<CheckKeys>({ checked: [], halfChecked: [] }); | ||
94 | + const treeExpandData = ref([]); | ||
95 | + const olderPhoneNumber = ref(); | ||
96 | + const postData = reactive({}); | ||
97 | + const singleEditPostPhoneNumber = reactive({ | ||
98 | + phoneNumber: '', | ||
99 | + }); | ||
100 | + const checkedKeysWithHalfChecked = ref<(string | number)[]>([]); | ||
101 | + const getRoleList = async () => { | ||
102 | + const res = await filterRoleList(); | ||
103 | + roleOptions.value = res.map((m) => { | ||
104 | + return { | ||
105 | + label: m.name, | ||
106 | + value: m.id, | ||
138 | }; | 107 | }; |
139 | - const [ | ||
140 | - registerForm, | ||
141 | - { | ||
142 | - setFieldsValue, | ||
143 | - updateSchema, | ||
144 | - resetFields, | ||
145 | - validate, | ||
146 | - getFieldsValue, | ||
147 | - clearValidate, | ||
148 | - validateFields, | ||
149 | - }, | ||
150 | - ] = useForm({ | ||
151 | - labelWidth: 100, | ||
152 | - schemas: accountFormSchema, | ||
153 | - showActionButtonGroup: false, | ||
154 | - actionColOptions: { | ||
155 | - span: 18, | ||
156 | - }, | 108 | + }); |
109 | + }; | ||
110 | + onMounted(async () => { | ||
111 | + await getRoleList(); | ||
112 | + }); | ||
113 | + const [registerRoleDrawer, { openDrawer }] = useDrawer(); | ||
114 | + | ||
115 | + const handleOpenRole = () => { | ||
116 | + openDrawer(true, { | ||
117 | + isUpdate: false, | ||
118 | + }); | ||
119 | + }; | ||
120 | + const clearValidateByField = (field: string) => { | ||
121 | + clearValidate(field); | ||
122 | + }; | ||
123 | + const handleRoleSelect = (e) => { | ||
124 | + if (e?.length > 0) clearValidateByField('roleIds'); | ||
125 | + else validateFields(['roleIds']); | ||
126 | + }; | ||
127 | + const handleTreeSelect = (e) => { | ||
128 | + if (e) clearValidateByField('organizationIds'); | ||
129 | + }; | ||
130 | + const handleSuccess = async () => { | ||
131 | + await getRoleList(); | ||
132 | + }; | ||
133 | + const [ | ||
134 | + registerForm, | ||
135 | + { | ||
136 | + setFieldsValue, | ||
137 | + updateSchema, | ||
138 | + resetFields, | ||
139 | + validate, | ||
140 | + getFieldsValue, | ||
141 | + clearValidate, | ||
142 | + validateFields, | ||
143 | + }, | ||
144 | + ] = useForm({ | ||
145 | + labelWidth: 100, | ||
146 | + schemas: accountFormSchema, | ||
147 | + showActionButtonGroup: false, | ||
148 | + actionColOptions: { | ||
149 | + span: 18, | ||
150 | + }, | ||
151 | + }); | ||
152 | + //获取所有父级id | ||
153 | + function findForAllId(data = [], arr = []) { | ||
154 | + for (const item of data) { | ||
155 | + arr.push(item.id); | ||
156 | + } | ||
157 | + return arr; | ||
158 | + } | ||
159 | + | ||
160 | + const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
161 | + checkStrictly.value = true; | ||
162 | + await resetFields(); | ||
163 | + setModalProps({ confirmLoading: false }); | ||
164 | + isUpdate.value = !!data?.isUpdate; | ||
165 | + const groupListModel = await findCurrentUserGroups(); | ||
166 | + if (!unref(organizationTreeData).length) { | ||
167 | + organizationTreeData.value = groupListModel; | ||
168 | + buildNodeMap(toRaw(unref(groupListModel))); | ||
169 | + const getAllIds = findForAllId(organizationTreeData.value as any, []); | ||
170 | + //设置要展开的id | ||
171 | + treeExpandData.value = getAllIds; | ||
172 | + } | ||
173 | + if (unref(isUpdate)) { | ||
174 | + rowId.value = data.record.id; | ||
175 | + const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); | ||
176 | + olderPhoneNumber.value = data.record.phoneNumber; | ||
177 | + singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber; | ||
178 | + findCurrentUserRelation(roleParams).then((result) => { | ||
179 | + Reflect.set(data.record, 'roleIds', result); | ||
180 | + Reflect.set(data.record, 'password', '******'); | ||
181 | + setFieldsValue(data.record); | ||
157 | }); | 182 | }); |
158 | - //获取所有父级id | ||
159 | - function findForAllId(data = [], arr = []) { | ||
160 | - for (const item of data) { | ||
161 | - arr.push(item.id); | ||
162 | - } | ||
163 | - return arr; | 183 | + const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); |
184 | + const checked = await findCurrentUserRelation(organizationParams); | ||
185 | + const halfChecked = getHalfCheckedNode(checked); | ||
186 | + Object.assign(checkedKeys, { checked, halfChecked }); | ||
187 | + setFieldsValue({ organizationIds: toRaw(checkedKeys) }); | ||
188 | + } | ||
189 | + await updateSchema([ | ||
190 | + { | ||
191 | + field: 'username', | ||
192 | + dynamicDisabled: unref(isUpdate), | ||
193 | + }, | ||
194 | + { | ||
195 | + field: 'password', | ||
196 | + ifShow: !unref(isUpdate), | ||
197 | + }, | ||
198 | + ]); | ||
199 | + }); | ||
200 | + const getTitle = computed(() => (!unref(isUpdate) ? '新增客户账号' : '编辑客户账号')); | ||
201 | + | ||
202 | + const getFormatValues = (values: Recordable) => { | ||
203 | + const organizationIds = values.organizationIds; | ||
204 | + if (!organizationIds || isArray(organizationIds)) return values; | ||
205 | + | ||
206 | + values.organizationIds = values?.organizationIds?.checked; | ||
207 | + | ||
208 | + return values; | ||
209 | + }; | ||
210 | + | ||
211 | + async function handleSubmit() { | ||
212 | + setModalProps({ confirmLoading: true }); | ||
213 | + try { | ||
214 | + const { createMessage } = useMessage(); | ||
215 | + if (unref(isUpdate)) { | ||
216 | + Object.assign(postData, singleEditPostPhoneNumber); | ||
164 | } | 217 | } |
218 | + const values = await validate([ | ||
219 | + 'id', | ||
220 | + 'username', | ||
221 | + 'realName', | ||
222 | + 'password', | ||
223 | + 'roleIds', | ||
224 | + 'email', | ||
225 | + 'accountExpireTime', | ||
226 | + 'enabled', | ||
227 | + 'remark', | ||
228 | + 'organizationIds', | ||
229 | + olderPhoneNumber.value === getFieldsValue().phoneNumber ? '' : 'phoneNumber', | ||
230 | + ]); | ||
165 | 231 | ||
166 | - const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
167 | - await resetFields(); | ||
168 | - setModalProps({ confirmLoading: false }); | ||
169 | - isUpdate.value = !!data?.isUpdate; | ||
170 | - const groupListModel = await findCurrentUserGroups(); | ||
171 | - if (!unref(organizationTreeData).length) { | ||
172 | - copyTransTreeFun(groupListModel); | ||
173 | - organizationTreeData.value = groupListModel; | ||
174 | - const getAllIds = findForAllId(organizationTreeData.value as any, []); | ||
175 | - //设置要展开的id | ||
176 | - treeExpandData.value = getAllIds; | 232 | + values.accountExpireTime = |
233 | + typeof values.accountExpireTime != 'undefined' && values.accountExpireTime != null | ||
234 | + ? values.accountExpireTime.format('YYYY-MM-DD HH:mm:ss') | ||
235 | + : null; | ||
236 | + | ||
237 | + Object.assign(postData, getFormatValues(values)); | ||
238 | + if (unref(isUpdate)) { | ||
239 | + if (values.email == '') { | ||
240 | + delete postData.email; | ||
177 | } | 241 | } |
178 | - if (unref(isUpdate)) { | ||
179 | - rowId.value = data.record.id; | ||
180 | - const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); | ||
181 | - olderPhoneNumber.value = data.record.phoneNumber; | ||
182 | - singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber; | ||
183 | - findCurrentUserRelation(roleParams).then((result) => { | ||
184 | - Reflect.set(data.record, 'roleIds', result); | ||
185 | - Reflect.set(data.record, 'password', '******'); | ||
186 | - setFieldsValue(data.record); | ||
187 | - }); | ||
188 | - const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); | ||
189 | - checkGroup.value = await findCurrentUserRelation(organizationParams); | 242 | + } else { |
243 | + if (values.email == '') { | ||
244 | + delete postData.email; | ||
190 | } | 245 | } |
191 | - await updateSchema([ | ||
192 | - { | ||
193 | - field: 'username', | ||
194 | - dynamicDisabled: unref(isUpdate), | ||
195 | - }, | ||
196 | - { | ||
197 | - field: 'password', | ||
198 | - ifShow: !unref(isUpdate), | ||
199 | - }, | ||
200 | - ]); | ||
201 | - }); | ||
202 | - const getTitle = computed(() => (!unref(isUpdate) ? '新增客户账号' : '编辑客户账号')); | 246 | + } |
247 | + if (!Reflect.get(values, 'accountExpireTime')) { | ||
248 | + Reflect.deleteProperty(postData, 'accountExpireTime'); | ||
249 | + } | ||
250 | + await SaveOrUpdateUserInfo(postData as any, unref(isUpdate)); | ||
251 | + closeModal(); | ||
252 | + emit('success'); | ||
253 | + createMessage.success(unref(isUpdate) ? '编辑成功' : '新增成功'); | ||
254 | + } finally { | ||
255 | + setTimeout(() => { | ||
256 | + setModalProps({ confirmLoading: false }); | ||
257 | + }, 300); | ||
258 | + } | ||
259 | + } | ||
260 | + // 取消全部的时候清除回显时获取的 | ||
261 | + const handleUnSelectAll = () => { | ||
262 | + checkedKeysWithHalfChecked.value = []; | ||
263 | + }; | ||
264 | + | ||
265 | + const strictlyStatus = ref(false); //层级关联或独立的状态 false为层级关联 true为层级独立 | ||
203 | 266 | ||
204 | - async function handleSubmit() { | ||
205 | - setModalProps({ confirmLoading: true }); | ||
206 | - try { | ||
207 | - const { createMessage } = useMessage(); | ||
208 | - if (unref(isUpdate)) { | ||
209 | - Object.assign(postData, singleEditPostPhoneNumber); | ||
210 | - } | ||
211 | - const values = await validate([ | ||
212 | - 'id', | ||
213 | - 'username', | ||
214 | - 'realName', | ||
215 | - 'password', | ||
216 | - 'roleIds', | ||
217 | - 'email', | ||
218 | - 'accountExpireTime', | ||
219 | - 'enabled', | ||
220 | - 'remark', | ||
221 | - 'organizationIds', | ||
222 | - olderPhoneNumber.value === getFieldsValue().phoneNumber ? '' : 'phoneNumber', | ||
223 | - ]); | ||
224 | - let treeCheckedKeys: string[] | CheckKeys = | ||
225 | - (unref(basicTreeRef)?.getCheckedKeys() as string[] | CheckKeys) || []; | ||
226 | - //fix 取消层级独立后(unref(treeRef)?.getCheckedKeys() as string[])的数据不是数组,是{checked:[],halfChecked:[]}对象,迭代报错 | ||
227 | - if (!Array.isArray(treeCheckedKeys)) { | ||
228 | - treeCheckedKeys = treeCheckedKeys?.checked; | ||
229 | - } | ||
230 | - const organizationIds = [ | ||
231 | - ...new Set([...unref(checkedKeysWithHalfChecked), ...treeCheckedKeys]), | ||
232 | - ]; | ||
233 | - values.accountExpireTime = | ||
234 | - typeof values.accountExpireTime != 'undefined' && values.accountExpireTime != null | ||
235 | - ? values.accountExpireTime.format('YYYY-MM-DD HH:mm:ss') | ||
236 | - : null; | ||
237 | - values.organizationIds = organizationIds; | ||
238 | - Object.assign(postData, values); | ||
239 | - if (unref(isUpdate)) { | ||
240 | - if (values.email == '') { | ||
241 | - delete postData.email; | ||
242 | - } | ||
243 | - } else { | ||
244 | - if (values.email == '') { | ||
245 | - delete postData.email; | ||
246 | - } | ||
247 | - } | ||
248 | - if (!Reflect.get(values, 'accountExpireTime')) { | ||
249 | - Reflect.deleteProperty(postData, 'accountExpireTime'); | ||
250 | - } | ||
251 | - await SaveOrUpdateUserInfo(postData as any, unref(isUpdate)); | ||
252 | - closeModal(); | ||
253 | - emit('success'); | ||
254 | - createMessage.success(unref(isUpdate) ? '编辑成功' : '新增成功'); | ||
255 | - } finally { | ||
256 | - setTimeout(() => { | ||
257 | - setModalProps({ confirmLoading: false }); | ||
258 | - }, 300); | 267 | + const handleStrictlyStatus = (status) => (strictlyStatus.value = status); |
268 | + | ||
269 | + const handleCheckClick = () => { | ||
270 | + if (unref(checkStrictly)) { | ||
271 | + checkStrictly.value = false; | ||
272 | + } | ||
273 | + }; | ||
274 | + | ||
275 | + const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer(); | ||
276 | + | ||
277 | + const handleOpenCreate = () => { | ||
278 | + addOpenDrawer(true, { isUpdate: false }); | ||
279 | + }; | ||
280 | + const handleReload = async () => { | ||
281 | + const groupListModel = await findCurrentUserGroups(); | ||
282 | + organizationTreeData.value = groupListModel; | ||
283 | + buildNodeMap(toRaw(unref(groupListModel))); | ||
284 | + }; | ||
285 | + | ||
286 | + const treeNodeMap = ref<Record<string, { parentId?: string; children?: string[] }>>(); | ||
287 | + | ||
288 | + function buildNodeMap(tree: GroupListResultModel) { | ||
289 | + const nodeMap: Record<string, { parentId?: string; children?: string[] }> = {}; | ||
290 | + | ||
291 | + function traverse(tree: GroupListResultModel) { | ||
292 | + for (let node of tree) { | ||
293 | + Reflect.set(nodeMap, node.id, { | ||
294 | + parentId: node.parentId, | ||
295 | + children: node.children?.map((item) => item.id), | ||
296 | + }); | ||
297 | + | ||
298 | + if (node.children && node.children.length) { | ||
299 | + traverse(node.children); | ||
259 | } | 300 | } |
260 | } | 301 | } |
261 | - // 取消全部的时候清除回显时获取的 | ||
262 | - const handleUnSelectAll = () => { | ||
263 | - checkedKeysWithHalfChecked.value = []; | ||
264 | - }; | 302 | + } |
303 | + traverse(tree); | ||
265 | 304 | ||
266 | - const strictlyStatus = ref(false); //层级关联或独立的状态 false为层级关联 true为层级独立 | 305 | + treeNodeMap.value = nodeMap; |
306 | + } | ||
267 | 307 | ||
268 | - const handleStrictlyStatus = (status) => (strictlyStatus.value = status); | 308 | + function getHalfCheckedNode(keys: string[]) { |
309 | + const relation = unref(treeNodeMap) || {}; | ||
310 | + const halfChecked: string[] = []; | ||
269 | 311 | ||
270 | - const handleCheckClick = (selectedKeys: CheckKeys, event: CheckEvent) => { | ||
271 | - //fix 取消层级独立后selectedKeys不是数组,是{checked:[],halfChecked:[]}对象 迭代报错 | ||
272 | - // 层级独立 | ||
273 | - if (strictlyStatus.value) { | ||
274 | - if (!Array.isArray(selectedKeys)) { | ||
275 | - selectedKeys = selectedKeys?.checked; | ||
276 | - event.halfCheckedKeys = []; | ||
277 | - } | ||
278 | - } else { | ||
279 | - // 层级关联 | ||
280 | - event.halfCheckedKeys = []; | ||
281 | - } | ||
282 | - checkedKeysWithHalfChecked.value = [ | ||
283 | - ...selectedKeys, | ||
284 | - ...(event.halfCheckedKeys as string[]), | ||
285 | - ]; | ||
286 | - }; | 312 | + for (const key of keys) { |
313 | + let current = relation[key]; | ||
287 | 314 | ||
288 | - const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer(); | 315 | + while (current) { |
316 | + if (keys.includes(current.parentId!) || !current.parentId) { | ||
317 | + break; | ||
318 | + } | ||
289 | 319 | ||
290 | - const handleOpenCreate = () => { | ||
291 | - addOpenDrawer(true, { isUpdate: false }); | ||
292 | - }; | ||
293 | - const handleReload = async () => { | ||
294 | - const groupListModel = await findCurrentUserGroups(); | ||
295 | - copyTransTreeFun(groupListModel); | ||
296 | - organizationTreeData.value = groupListModel; | ||
297 | - }; | 320 | + halfChecked.push(current.parentId!); |
321 | + current = relation[current.parentId!]; | ||
322 | + } | ||
323 | + } | ||
298 | 324 | ||
299 | - return { | ||
300 | - registerModal, | ||
301 | - registerForm, | ||
302 | - handleSubmit, | ||
303 | - getTitle, | ||
304 | - organizationTreeData, | ||
305 | - checkGroup, | ||
306 | - basicTreeRef, | ||
307 | - treeExpandData, | ||
308 | - roleOptions, | ||
309 | - registerRoleDrawer, | ||
310 | - handleOpenRole, | ||
311 | - handleSuccess, | ||
312 | - handleRoleSelect, | ||
313 | - handleTreeSelect, | ||
314 | - handleCheckClick, | ||
315 | - handleUnSelectAll, | ||
316 | - handleStrictlyStatus, | ||
317 | - handleOpenCreate, | ||
318 | - registerDrawer, | ||
319 | - handleReload, | ||
320 | - }; | ||
321 | - }, | ||
322 | - }); | 325 | + return Array.from(new Set(halfChecked)); |
326 | + } | ||
323 | </script> | 327 | </script> |
324 | <style scoped lang="less"> | 328 | <style scoped lang="less"> |
325 | :deep(.vben-basic-tree) { | 329 | :deep(.vben-basic-tree) { |
@@ -14,9 +14,10 @@ | @@ -14,9 +14,10 @@ | ||
14 | </Button> | 14 | </Button> |
15 | <BasicTree | 15 | <BasicTree |
16 | v-if="organizationTreeData.length" | 16 | v-if="organizationTreeData.length" |
17 | + :check-strictly="checkStrictly" | ||
17 | v-model:value="model[field]" | 18 | v-model:value="model[field]" |
18 | :treeData="organizationTreeData" | 19 | :treeData="organizationTreeData" |
19 | - :checked-keys="checkGroup" | 20 | + :checked-keys="checkedKeys" |
20 | :expandedKeys="treeExpandData" | 21 | :expandedKeys="treeExpandData" |
21 | ref="basicTreeRef" | 22 | ref="basicTreeRef" |
22 | @check="handleCheckClick" | 23 | @check="handleCheckClick" |
@@ -25,6 +26,7 @@ | @@ -25,6 +26,7 @@ | ||
25 | checkable | 26 | checkable |
26 | toolbar | 27 | toolbar |
27 | @change="handleTreeSelect" | 28 | @change="handleTreeSelect" |
29 | + :replace-fields="{ children: 'children', title: 'name', key: 'id' }" | ||
28 | /> | 30 | /> |
29 | </template> | 31 | </template> |
30 | <template #roleSlot="{ model, field }"> | 32 | <template #roleSlot="{ model, field }"> |
@@ -53,19 +55,18 @@ | @@ -53,19 +55,18 @@ | ||
53 | </BasicModal> | 55 | </BasicModal> |
54 | <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" /> | 56 | <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" /> |
55 | </template> | 57 | </template> |
56 | -<script lang="ts"> | ||
57 | - import { defineComponent, ref, computed, unref, reactive, onMounted } from 'vue'; | 58 | +<script lang="ts" setup> |
59 | + import { ref, computed, unref, reactive, onMounted } from 'vue'; | ||
58 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 60 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
59 | import { BasicForm, useForm } from '/@/components/Form/index'; | 61 | import { BasicForm, useForm } from '/@/components/Form/index'; |
60 | import { accountFormSchema } from './config'; | 62 | import { accountFormSchema } from './config'; |
61 | import { Button } from 'ant-design-vue'; | 63 | import { Button } from 'ant-design-vue'; |
62 | import { findCurrentUserRelation, filterRoleList } from '/@/api/system/system'; | 64 | import { findCurrentUserRelation, filterRoleList } from '/@/api/system/system'; |
63 | import { addTenantList } from '/@/api/system/account'; | 65 | import { addTenantList } from '/@/api/system/account'; |
64 | - import { BasicTree, TreeItem, CheckKeys, CheckEvent } from '/@/components/Tree'; | 66 | + import { BasicTree, TreeItem, CheckKeys } from '/@/components/Tree'; |
65 | import { findCurrentUserGroups } from '/@/api/system/group'; | 67 | import { findCurrentUserGroups } from '/@/api/system/group'; |
66 | import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; | 68 | import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; |
67 | import { useMessage } from '/@/hooks/web/useMessage'; | 69 | import { useMessage } from '/@/hooks/web/useMessage'; |
68 | - import { copyTransTreeFun } from '/@/utils/fnUtils'; | ||
69 | import { TOption } from '/@/views/rule/linkedge/config/config.data'; | 70 | import { TOption } from '/@/views/rule/linkedge/config/config.data'; |
70 | import { PlusOutlined } from '@ant-design/icons-vue'; | 71 | import { PlusOutlined } from '@ant-design/icons-vue'; |
71 | import { useDrawer } from '/@/components/Drawer'; | 72 | import { useDrawer } from '/@/components/Drawer'; |
@@ -74,267 +75,285 @@ | @@ -74,267 +75,285 @@ | ||
74 | import { useUserStore } from '/@/store/modules/user'; | 75 | import { useUserStore } from '/@/store/modules/user'; |
75 | import { IsPhoneExist } from '/@/api/system/system'; | 76 | import { IsPhoneExist } from '/@/api/system/system'; |
76 | import { phoneRegexp } from '/@/utils/rules'; | 77 | import { phoneRegexp } from '/@/utils/rules'; |
78 | + import { GroupListResultModel } from '/@/api/system/model/groupModel'; | ||
79 | + import { toRaw } from 'vue'; | ||
80 | + import { isArray } from '/@/utils/is'; | ||
77 | 81 | ||
78 | - export default defineComponent({ | ||
79 | - name: 'TenantModal', | ||
80 | - components: { | ||
81 | - BasicModal, | ||
82 | - BasicForm, | ||
83 | - Button, | ||
84 | - BasicTree, | ||
85 | - OrganizationDrawer, | ||
86 | - PlusOutlined, | ||
87 | - RoleDrawer, | ||
88 | - VNodes: (_, { attrs }) => { | ||
89 | - return attrs.vnodes; | ||
90 | - }, | ||
91 | - }, | ||
92 | - emits: ['success', 'register'], | ||
93 | - setup(_, { emit }) { | ||
94 | - const [registerRoleDrawer, { openDrawer }] = useDrawer(); | ||
95 | - const { createMessage } = useMessage(); | ||
96 | - const userInfo = useUserStore(); | 82 | + const VNodes = (_, { attrs }) => { |
83 | + return attrs.vnodes; | ||
84 | + }; | ||
97 | 85 | ||
98 | - const roleOptions = ref<TOption[]>([]); | ||
99 | - const isAdd = ref(true); | ||
100 | - const rowId = ref(''); | ||
101 | - const organizationTreeData = ref<TreeItem[]>([]); | ||
102 | - const basicTreeRef = ref(); | ||
103 | - const checkGroup = ref<string[]>([]); | ||
104 | - const treeExpandData = ref([]); | ||
105 | - const olderPhoneNumber = ref(); | ||
106 | - const singleEditPostPhoneNumber = reactive({ | ||
107 | - phoneNumber: '', | ||
108 | - }); | ||
109 | - const checkedKeysWithHalfChecked = ref<(string | number)[]>([]); | ||
110 | - const getRoleList = async () => { | ||
111 | - const res = await filterRoleList({ roleType: 'TENANT_ADMIN' }); | ||
112 | - roleOptions.value = res.map((m) => { | ||
113 | - return { | ||
114 | - label: m.name, | ||
115 | - value: m.id, | ||
116 | - }; | ||
117 | - }); | ||
118 | - }; | 86 | + const emit = defineEmits(['register', 'success']); |
119 | 87 | ||
120 | - onMounted(async () => { | ||
121 | - await getRoleList(); | ||
122 | - }); | ||
123 | - const handleOpenRole = () => { | ||
124 | - openDrawer(true, { | ||
125 | - isAdd: false, | ||
126 | - }); | ||
127 | - }; | ||
128 | - const clearValidateByField = (field: string) => { | ||
129 | - clearValidate(field); | ||
130 | - }; | ||
131 | - const handleRoleSelect = (e) => { | ||
132 | - if (e?.length > 0) clearValidateByField('roleIds'); | ||
133 | - else validateFields(['roleIds']); | ||
134 | - }; | ||
135 | - const handleTreeSelect = (e) => { | ||
136 | - if (e) clearValidateByField('organizationIds'); | ||
137 | - }; | ||
138 | - const handleSuccess = async () => { | ||
139 | - await getRoleList(); | 88 | + const [registerRoleDrawer, { openDrawer }] = useDrawer(); |
89 | + const { createMessage } = useMessage(); | ||
90 | + const userInfo = useUserStore(); | ||
91 | + | ||
92 | + const checkStrictly = ref(true); | ||
93 | + | ||
94 | + const roleOptions = ref<TOption[]>([]); | ||
95 | + const isAdd = ref(true); | ||
96 | + const rowId = ref(''); | ||
97 | + const organizationTreeData = ref<TreeItem[]>([]); | ||
98 | + const basicTreeRef = ref(); | ||
99 | + const checkedKeys = reactive<CheckKeys>({ checked: [], halfChecked: [] }); | ||
100 | + const treeExpandData = ref([]); | ||
101 | + const olderPhoneNumber = ref(); | ||
102 | + const singleEditPostPhoneNumber = reactive({ | ||
103 | + phoneNumber: '', | ||
104 | + }); | ||
105 | + const checkedKeysWithHalfChecked = ref<(string | number)[]>([]); | ||
106 | + const getRoleList = async () => { | ||
107 | + const res = await filterRoleList({ roleType: 'TENANT_ADMIN' }); | ||
108 | + roleOptions.value = res.map((m) => { | ||
109 | + return { | ||
110 | + label: m.name, | ||
111 | + value: m.id, | ||
140 | }; | 112 | }; |
141 | - const [ | ||
142 | - registerForm, | ||
143 | - { | ||
144 | - setFieldsValue, | ||
145 | - updateSchema, | ||
146 | - resetFields, | ||
147 | - validate, | ||
148 | - getFieldsValue, | ||
149 | - clearValidate, | ||
150 | - validateFields, | ||
151 | - }, | ||
152 | - ] = useForm({ | ||
153 | - labelWidth: 100, | ||
154 | - schemas: accountFormSchema, | ||
155 | - showActionButtonGroup: false, | ||
156 | - actionColOptions: { | ||
157 | - span: 18, | ||
158 | - }, | ||
159 | - }); | ||
160 | - //获取所有父级id | ||
161 | - function findForAllId(data = [], arr = []) { | ||
162 | - for (const item of data) { | ||
163 | - arr.push(item.id); | ||
164 | - } | ||
165 | - return arr; | ||
166 | - } | 113 | + }); |
114 | + }; | ||
167 | 115 | ||
168 | - const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { | ||
169 | - await resetFields(); | ||
170 | - setModalProps({ confirmLoading: false }); | ||
171 | - isAdd.value = !!data?.isAdd; | ||
172 | - const groupListModel = await findCurrentUserGroups(); | ||
173 | - if (!unref(organizationTreeData).length) { | ||
174 | - copyTransTreeFun(groupListModel); | ||
175 | - organizationTreeData.value = groupListModel; | ||
176 | - const getAllIds = findForAllId(organizationTreeData.value as any, []); | ||
177 | - //设置要展开的id | ||
178 | - treeExpandData.value = getAllIds; | ||
179 | - } | 116 | + onMounted(async () => { |
117 | + await getRoleList(); | ||
118 | + }); | ||
119 | + const handleOpenRole = () => { | ||
120 | + openDrawer(true, { | ||
121 | + isAdd: false, | ||
122 | + }); | ||
123 | + }; | ||
124 | + const clearValidateByField = (field: string) => { | ||
125 | + clearValidate(field); | ||
126 | + }; | ||
127 | + const handleRoleSelect = (e) => { | ||
128 | + if (e?.length > 0) clearValidateByField('roleIds'); | ||
129 | + else validateFields(['roleIds']); | ||
130 | + }; | ||
131 | + const handleTreeSelect = (e) => { | ||
132 | + if (e) clearValidateByField('organizationIds'); | ||
133 | + }; | ||
134 | + const handleSuccess = async () => { | ||
135 | + await getRoleList(); | ||
136 | + }; | ||
137 | + const [ | ||
138 | + registerForm, | ||
139 | + { | ||
140 | + setFieldsValue, | ||
141 | + updateSchema, | ||
142 | + resetFields, | ||
143 | + validate, | ||
144 | + getFieldsValue, | ||
145 | + clearValidate, | ||
146 | + validateFields, | ||
147 | + }, | ||
148 | + ] = useForm({ | ||
149 | + labelWidth: 100, | ||
150 | + schemas: accountFormSchema, | ||
151 | + showActionButtonGroup: false, | ||
152 | + actionColOptions: { | ||
153 | + span: 18, | ||
154 | + }, | ||
155 | + }); | ||
156 | + //获取所有父级id | ||
157 | + function findForAllId(data = [], arr = []) { | ||
158 | + for (const item of data) { | ||
159 | + arr.push(item.id); | ||
160 | + } | ||
161 | + return arr; | ||
162 | + } | ||
180 | 163 | ||
181 | - if (!unref(isAdd)) { | ||
182 | - rowId.value = data.record.id; | ||
183 | - const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); | ||
184 | - olderPhoneNumber.value = data.record.phoneNumber; | ||
185 | - singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber; | ||
186 | - findCurrentUserRelation(roleParams).then((result) => { | ||
187 | - Reflect.set(data.record, 'roleIds', result); | ||
188 | - setFieldsValue(data.record); | ||
189 | - }); | ||
190 | - updateSchema([ | ||
191 | - { | ||
192 | - field: 'phoneNumber', | ||
193 | - dynamicRules: () => { | ||
194 | - return [ | ||
195 | - { | ||
196 | - required: true, | ||
197 | - validator(_, value) { | ||
198 | - return new Promise((resolve, reject) => { | ||
199 | - if (value == '') { | ||
200 | - reject('请输入手机号'); | ||
201 | - } else if (!phoneRegexp.test(value)) { | ||
202 | - reject('请输入正确的手机号'); | ||
203 | - } else { | ||
204 | - resolve(); | ||
205 | - } | ||
206 | - }); | ||
207 | - }, | ||
208 | - }, | ||
209 | - ]; | 164 | + const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
165 | + await resetFields(); | ||
166 | + checkStrictly.value = true; | ||
167 | + setModalProps({ confirmLoading: false }); | ||
168 | + isAdd.value = !!data?.isAdd; | ||
169 | + const groupListModel = await findCurrentUserGroups(); | ||
170 | + if (!unref(organizationTreeData).length) { | ||
171 | + organizationTreeData.value = groupListModel; | ||
172 | + buildNodeMap(toRaw(unref(organizationTreeData) as GroupListResultModel)); | ||
173 | + const getAllIds = findForAllId(organizationTreeData.value as any, []); | ||
174 | + //设置要展开的id | ||
175 | + treeExpandData.value = getAllIds; | ||
176 | + } | ||
177 | + | ||
178 | + if (!unref(isAdd)) { | ||
179 | + rowId.value = data.record.id; | ||
180 | + const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); | ||
181 | + olderPhoneNumber.value = data.record.phoneNumber; | ||
182 | + singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber; | ||
183 | + findCurrentUserRelation(roleParams).then((result) => { | ||
184 | + Reflect.set(data.record, 'roleIds', result); | ||
185 | + setFieldsValue(data.record); | ||
186 | + }); | ||
187 | + updateSchema([ | ||
188 | + { | ||
189 | + field: 'phoneNumber', | ||
190 | + dynamicRules: () => { | ||
191 | + return [ | ||
192 | + { | ||
193 | + required: true, | ||
194 | + validator(_, value) { | ||
195 | + return new Promise((resolve, reject) => { | ||
196 | + if (value == '') { | ||
197 | + reject('请输入手机号'); | ||
198 | + } else if (!phoneRegexp.test(value)) { | ||
199 | + reject('请输入正确的手机号'); | ||
200 | + } else { | ||
201 | + resolve(); | ||
202 | + } | ||
203 | + }); | ||
204 | + }, | ||
210 | }, | 205 | }, |
211 | - }, | ||
212 | - ]); | ||
213 | - const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); | ||
214 | - checkGroup.value = await findCurrentUserRelation(organizationParams); | ||
215 | - } else { | ||
216 | - updateSchema([ | ||
217 | - { | ||
218 | - field: 'phoneNumber', | ||
219 | - dynamicRules: ({ values }) => { | ||
220 | - return [ | ||
221 | - { | ||
222 | - required: true, | ||
223 | - validator(_, value) { | ||
224 | - return new Promise((resolve, reject) => { | ||
225 | - if (value == '') { | ||
226 | - reject('请输入手机号'); | ||
227 | - } else if (!phoneRegexp.test(value)) { | ||
228 | - reject('请输入正确的手机号'); | ||
229 | - } else { | ||
230 | - if (values.phoneNumber != undefined) { | ||
231 | - // 此处可以用防抖函数优化性能 | ||
232 | - IsPhoneExist(value).then(({ data }) => { | ||
233 | - if (data != null) { | ||
234 | - reject('手机号已存在'); | ||
235 | - } else { | ||
236 | - resolve(); | ||
237 | - } | ||
238 | - }); | 206 | + ]; |
207 | + }, | ||
208 | + }, | ||
209 | + ]); | ||
210 | + const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); | ||
211 | + const checked = await findCurrentUserRelation(organizationParams); | ||
212 | + const halfChecked = getHalfCheckedNode(checked); | ||
213 | + Object.assign(checkedKeys, { checked, halfChecked }); | ||
214 | + setFieldsValue({ organizationIds: toRaw(checkedKeys) }); | ||
215 | + } else { | ||
216 | + updateSchema([ | ||
217 | + { | ||
218 | + field: 'phoneNumber', | ||
219 | + dynamicRules: ({ values }) => { | ||
220 | + return [ | ||
221 | + { | ||
222 | + required: true, | ||
223 | + validator(_, value) { | ||
224 | + return new Promise((resolve, reject) => { | ||
225 | + if (value == '') { | ||
226 | + reject('请输入手机号'); | ||
227 | + } else if (!phoneRegexp.test(value)) { | ||
228 | + reject('请输入正确的手机号'); | ||
229 | + } else { | ||
230 | + if (values.phoneNumber != undefined) { | ||
231 | + // 此处可以用防抖函数优化性能 | ||
232 | + IsPhoneExist(value).then(({ data }) => { | ||
233 | + if (data != null) { | ||
234 | + reject('手机号已存在'); | ||
239 | } else { | 235 | } else { |
240 | resolve(); | 236 | resolve(); |
241 | } | 237 | } |
242 | - } | ||
243 | - }); | ||
244 | - }, | ||
245 | - }, | ||
246 | - ]; | 238 | + }); |
239 | + } else { | ||
240 | + resolve(); | ||
241 | + } | ||
242 | + } | ||
243 | + }); | ||
244 | + }, | ||
247 | }, | 245 | }, |
248 | - }, | ||
249 | - ]); | ||
250 | - } | ||
251 | - await updateSchema([ | ||
252 | - { | ||
253 | - field: 'username', | ||
254 | - dynamicDisabled: !unref(isAdd), | 246 | + ]; |
255 | }, | 247 | }, |
256 | - ]); | 248 | + }, |
249 | + ]); | ||
250 | + } | ||
251 | + await updateSchema([ | ||
252 | + { | ||
253 | + field: 'username', | ||
254 | + dynamicDisabled: !unref(isAdd), | ||
255 | + }, | ||
256 | + ]); | ||
257 | + }); | ||
258 | + const getTitle = computed(() => (unref(isAdd) ? '新增管理员账号' : '编辑管理员账号')); | ||
259 | + | ||
260 | + const getFormatValues = (values: Recordable) => { | ||
261 | + const organizationIds = values.organizationIds; | ||
262 | + if (!organizationIds || isArray(organizationIds)) return values; | ||
263 | + | ||
264 | + values.organizationIds = values?.organizationIds?.checked; | ||
265 | + | ||
266 | + return values; | ||
267 | + }; | ||
268 | + | ||
269 | + async function handleSubmit() { | ||
270 | + setModalProps({ confirmLoading: true }); | ||
271 | + try { | ||
272 | + const values = getFieldsValue(); | ||
273 | + if (!('organizationIds' in values)) { | ||
274 | + createMessage.error('组织必选'); | ||
275 | + } | ||
276 | + | ||
277 | + await validate(); | ||
278 | + await addTenantList({ | ||
279 | + ...getFormatValues(values), | ||
280 | + level: 4, | ||
281 | + tenantId: userInfo.getUserInfo.tenantId!, | ||
257 | }); | 282 | }); |
258 | - const getTitle = computed(() => (unref(isAdd) ? '新增管理员账号' : '编辑管理员账号')); | 283 | + createMessage.success(unref(isAdd) ? '新增成功' : '编辑成功'); |
284 | + closeModal(); | ||
285 | + emit('success'); | ||
286 | + } finally { | ||
287 | + setModalProps({ confirmLoading: false }); | ||
288 | + } | ||
289 | + } | ||
290 | + // 取消全部的时候清除回显时获取的 | ||
291 | + const handleUnSelectAll = () => { | ||
292 | + checkedKeysWithHalfChecked.value = []; | ||
293 | + }; | ||
294 | + | ||
295 | + const strictlyStatus = ref(false); //层级关联或独立的状态 false为层级关联 true为层级独立 | ||
296 | + | ||
297 | + const handleStrictlyStatus = (status) => (strictlyStatus.value = status); | ||
298 | + | ||
299 | + const handleCheckClick = () => { | ||
300 | + if (unref(checkStrictly)) { | ||
301 | + checkStrictly.value = false; | ||
302 | + } | ||
303 | + }; | ||
304 | + | ||
305 | + const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer(); | ||
306 | + | ||
307 | + const handleOpenCreate = () => { | ||
308 | + addOpenDrawer(true, { isAdd: false }); | ||
309 | + }; | ||
310 | + const handleReload = async () => { | ||
311 | + const groupListModel = await findCurrentUserGroups(); | ||
312 | + organizationTreeData.value = groupListModel; | ||
313 | + buildNodeMap(toRaw(unref(groupListModel))); | ||
314 | + }; | ||
315 | + | ||
316 | + const treeNodeMap = ref<Record<string, { parentId?: string; children?: string[] }>>(); | ||
259 | 317 | ||
260 | - async function handleSubmit() { | ||
261 | - setModalProps({ confirmLoading: true }); | ||
262 | - try { | ||
263 | - const values = getFieldsValue(); | ||
264 | - if (!('organizationIds' in values)) { | ||
265 | - createMessage.error('组织必选'); | ||
266 | - } | ||
267 | - await validate(); | ||
268 | - await addTenantList({ ...values, level: 4, tenantId: userInfo.getUserInfo.tenantId! }); | ||
269 | - createMessage.success(unref(isAdd) ? '新增成功' : '编辑成功'); | ||
270 | - closeModal(); | ||
271 | - emit('success'); | ||
272 | - } finally { | ||
273 | - setModalProps({ confirmLoading: false }); | 318 | + function buildNodeMap(tree: GroupListResultModel) { |
319 | + const nodeMap: Record<string, { parentId?: string; children?: string[] }> = {}; | ||
320 | + | ||
321 | + function traverse(tree: GroupListResultModel) { | ||
322 | + for (let node of tree) { | ||
323 | + Reflect.set(nodeMap, node.id, { | ||
324 | + parentId: node.parentId, | ||
325 | + children: node.children?.map((item) => item.id), | ||
326 | + }); | ||
327 | + | ||
328 | + if (node.children && node.children.length) { | ||
329 | + traverse(node.children); | ||
274 | } | 330 | } |
275 | } | 331 | } |
276 | - // 取消全部的时候清除回显时获取的 | ||
277 | - const handleUnSelectAll = () => { | ||
278 | - checkedKeysWithHalfChecked.value = []; | ||
279 | - }; | 332 | + } |
333 | + traverse(tree); | ||
280 | 334 | ||
281 | - const strictlyStatus = ref(false); //层级关联或独立的状态 false为层级关联 true为层级独立 | 335 | + treeNodeMap.value = nodeMap; |
336 | + } | ||
282 | 337 | ||
283 | - const handleStrictlyStatus = (status) => (strictlyStatus.value = status); | 338 | + function getHalfCheckedNode(keys: string[]) { |
339 | + const relation = unref(treeNodeMap) || {}; | ||
340 | + const halfChecked: string[] = []; | ||
284 | 341 | ||
285 | - const handleCheckClick = (selectedKeys: CheckKeys, event: CheckEvent) => { | ||
286 | - //fix 取消层级独立后selectedKeys不是数组,是{checked:[],halfChecked:[]}对象 迭代报错 | ||
287 | - // 层级独立 | ||
288 | - if (strictlyStatus.value) { | ||
289 | - if (!Array.isArray(selectedKeys)) { | ||
290 | - selectedKeys = selectedKeys?.checked; | ||
291 | - event.halfCheckedKeys = []; | ||
292 | - } | ||
293 | - } else { | ||
294 | - // 层级关联 | ||
295 | - event.halfCheckedKeys = []; | ||
296 | - } | ||
297 | - checkedKeysWithHalfChecked.value = [ | ||
298 | - ...selectedKeys, | ||
299 | - ...(event.halfCheckedKeys as string[]), | ||
300 | - ]; | ||
301 | - }; | 342 | + for (const key of keys) { |
343 | + let current = relation[key]; | ||
302 | 344 | ||
303 | - const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer(); | 345 | + while (current) { |
346 | + if (keys.includes(current.parentId!) || !current.parentId) { | ||
347 | + break; | ||
348 | + } | ||
304 | 349 | ||
305 | - const handleOpenCreate = () => { | ||
306 | - addOpenDrawer(true, { isAdd: false }); | ||
307 | - }; | ||
308 | - const handleReload = async () => { | ||
309 | - const groupListModel = await findCurrentUserGroups(); | ||
310 | - copyTransTreeFun(groupListModel); | ||
311 | - organizationTreeData.value = groupListModel; | ||
312 | - }; | 350 | + halfChecked.push(current.parentId!); |
351 | + current = relation[current.parentId!]; | ||
352 | + } | ||
353 | + } | ||
313 | 354 | ||
314 | - return { | ||
315 | - registerModal, | ||
316 | - registerForm, | ||
317 | - handleSubmit, | ||
318 | - getTitle, | ||
319 | - organizationTreeData, | ||
320 | - checkGroup, | ||
321 | - basicTreeRef, | ||
322 | - treeExpandData, | ||
323 | - roleOptions, | ||
324 | - registerRoleDrawer, | ||
325 | - handleOpenRole, | ||
326 | - handleSuccess, | ||
327 | - handleRoleSelect, | ||
328 | - handleTreeSelect, | ||
329 | - handleCheckClick, | ||
330 | - handleUnSelectAll, | ||
331 | - handleStrictlyStatus, | ||
332 | - handleOpenCreate, | ||
333 | - registerDrawer, | ||
334 | - handleReload, | ||
335 | - }; | ||
336 | - }, | ||
337 | - }); | 355 | + return Array.from(new Set(halfChecked)); |
356 | + } | ||
338 | </script> | 357 | </script> |
339 | <style scoped lang="less"> | 358 | <style scoped lang="less"> |
340 | :deep(.vben-basic-tree) { | 359 | :deep(.vben-basic-tree) { |