Showing
3 changed files
with
502 additions
and
479 deletions
| ... | ... | @@ -14,9 +14,10 @@ |
| 14 | 14 | </Button> |
| 15 | 15 | <BasicTree |
| 16 | 16 | v-if="organizationTreeData.length" |
| 17 | + :check-strictly="checkStrictly" | |
| 17 | 18 | v-model:value="model[field]" |
| 18 | 19 | :treeData="organizationTreeData" |
| 19 | - :checked-keys="checkGroup" | |
| 20 | + :checked-keys="checkedKeys" | |
| 20 | 21 | :expandedKeys="treeExpandData" |
| 21 | 22 | ref="basicTreeRef" |
| 22 | 23 | @check="handleCheckClick" |
| ... | ... | @@ -25,6 +26,7 @@ |
| 25 | 26 | checkable |
| 26 | 27 | toolbar |
| 27 | 28 | @change="handleTreeSelect" |
| 29 | + :replace-fields="{ children: 'children', title: 'name', key: 'id' }" | |
| 28 | 30 | /> |
| 29 | 31 | </template> |
| 30 | 32 | <template #roleSlot="{ model, field }"> |
| ... | ... | @@ -53,8 +55,8 @@ |
| 53 | 55 | </BasicModal> |
| 54 | 56 | <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" /> |
| 55 | 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 | 60 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| 59 | 61 | import { BasicForm, useForm } from '/@/components/Form/index'; |
| 60 | 62 | import { accountFormSchema } from './account.data'; |
| ... | ... | @@ -64,262 +66,264 @@ |
| 64 | 66 | SaveOrUpdateUserInfo, |
| 65 | 67 | filterRoleList, |
| 66 | 68 | } from '/@/api/system/system'; |
| 67 | - import { BasicTree, TreeItem, CheckKeys, CheckEvent } from '/@/components/Tree'; | |
| 69 | + import { BasicTree, TreeItem, CheckKeys } from '/@/components/Tree'; | |
| 68 | 70 | import { findCurrentUserGroups } from '/@/api/system/group'; |
| 69 | 71 | import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; |
| 70 | 72 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 71 | - import { copyTransTreeFun } from '/@/utils/fnUtils'; | |
| 72 | 73 | import { TOption } from '/@/views/rule/linkedge/config/config.data'; |
| 73 | 74 | import { PlusOutlined } from '@ant-design/icons-vue'; |
| 74 | 75 | import { useDrawer } from '/@/components/Drawer'; |
| 75 | 76 | import RoleDrawer from '../../role/CustomRoleDrawer.vue'; |
| 76 | 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 | 327 | </script> |
| 324 | 328 | <style scoped lang="less"> |
| 325 | 329 | :deep(.vben-basic-tree) { | ... | ... |
| ... | ... | @@ -14,9 +14,10 @@ |
| 14 | 14 | </Button> |
| 15 | 15 | <BasicTree |
| 16 | 16 | v-if="organizationTreeData.length" |
| 17 | + :check-strictly="checkStrictly" | |
| 17 | 18 | v-model:value="model[field]" |
| 18 | 19 | :treeData="organizationTreeData" |
| 19 | - :checked-keys="checkGroup" | |
| 20 | + :checked-keys="checkedKeys" | |
| 20 | 21 | :expandedKeys="treeExpandData" |
| 21 | 22 | ref="basicTreeRef" |
| 22 | 23 | @check="handleCheckClick" |
| ... | ... | @@ -25,6 +26,7 @@ |
| 25 | 26 | checkable |
| 26 | 27 | toolbar |
| 27 | 28 | @change="handleTreeSelect" |
| 29 | + :replace-fields="{ children: 'children', title: 'name', key: 'id' }" | |
| 28 | 30 | /> |
| 29 | 31 | </template> |
| 30 | 32 | <template #roleSlot="{ model, field }"> |
| ... | ... | @@ -53,19 +55,18 @@ |
| 53 | 55 | </BasicModal> |
| 54 | 56 | <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" /> |
| 55 | 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 | 60 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| 59 | 61 | import { BasicForm, useForm } from '/@/components/Form/index'; |
| 60 | 62 | import { accountFormSchema } from './config'; |
| 61 | 63 | import { Button } from 'ant-design-vue'; |
| 62 | 64 | import { findCurrentUserRelation, filterRoleList } from '/@/api/system/system'; |
| 63 | 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 | 67 | import { findCurrentUserGroups } from '/@/api/system/group'; |
| 66 | 68 | import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel'; |
| 67 | 69 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 68 | - import { copyTransTreeFun } from '/@/utils/fnUtils'; | |
| 69 | 70 | import { TOption } from '/@/views/rule/linkedge/config/config.data'; |
| 70 | 71 | import { PlusOutlined } from '@ant-design/icons-vue'; |
| 71 | 72 | import { useDrawer } from '/@/components/Drawer'; |
| ... | ... | @@ -74,267 +75,285 @@ |
| 74 | 75 | import { useUserStore } from '/@/store/modules/user'; |
| 75 | 76 | import { IsPhoneExist } from '/@/api/system/system'; |
| 76 | 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 | 235 | } else { |
| 240 | 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 | 357 | </script> |
| 339 | 358 | <style scoped lang="less"> |
| 340 | 359 | :deep(.vben-basic-tree) { | ... | ... |