|
|
@ -26,94 +26,81 @@ |
|
|
|
<q-btn v-if="!Tools.isEmpty(displayValueComputed)" flat square unelevated dense icon="cancel" @click="fieldMethodsClass.clearValue"></q-btn> |
|
|
|
<q-btn flat square unelevated dense icon="person_search"> |
|
|
|
<q-popup-proxy v-model:model-value="isShow" anchor="bottom right" self="top right" :offset="[0, 10]"> |
|
|
|
<q-splitter v-model="leftWidthRef" style="width: 900px; height: 400px; position: relative"> |
|
|
|
<template #before> |
|
|
|
<q-list> |
|
|
|
<!-- 机构 --> |
|
|
|
<q-expansion-item icon="account_tree" label="机构"> |
|
|
|
<q-card class="p-0"> |
|
|
|
<q-card-section class="p-0"> |
|
|
|
<w-grid |
|
|
|
ref="orgGridRef" |
|
|
|
:dense="true" |
|
|
|
:tree="true" |
|
|
|
:height="250" |
|
|
|
:hide-header="true" |
|
|
|
separator="none" |
|
|
|
:fetch-data-url="Environment.apiContextPath('/api/system/org')" |
|
|
|
:config-button="false" |
|
|
|
:checkbox-selection="true" |
|
|
|
db-click-operation="expand" |
|
|
|
:columns="[{ name: 'name', label: $t('org') }]" |
|
|
|
@row-click="orgRowClick" |
|
|
|
@update-ticked="orgUpdateTicked" |
|
|
|
> |
|
|
|
</w-grid> |
|
|
|
</q-card-section> |
|
|
|
</q-card> |
|
|
|
</q-expansion-item> |
|
|
|
<q-separator /> |
|
|
|
|
|
|
|
<!-- 角色 --> |
|
|
|
<q-expansion-item icon="person" label="角色"> |
|
|
|
<q-card class="p-0"> |
|
|
|
<q-card-section class="p-0"> |
|
|
|
<w-grid |
|
|
|
ref="roleGridRef" |
|
|
|
:dense="true" |
|
|
|
:height="250" |
|
|
|
separator="none" |
|
|
|
:fetch-data-url="Environment.apiContextPath('/api/system/role')" |
|
|
|
:config-button="false" |
|
|
|
:checkbox-selection="true" |
|
|
|
db-click-operation="expand" |
|
|
|
:columns="[ |
|
|
|
{ name: 'code', label: $t('code') }, |
|
|
|
{ name: 'name', label: $t('org') }, |
|
|
|
]" |
|
|
|
@row-click="orgRowClick" |
|
|
|
> |
|
|
|
</w-grid> |
|
|
|
</q-card-section> |
|
|
|
</q-card> |
|
|
|
</q-expansion-item> |
|
|
|
<q-separator /> |
|
|
|
</q-list> |
|
|
|
</template> |
|
|
|
<template #after> |
|
|
|
<div class="h-full pl-1"> |
|
|
|
<w-grid |
|
|
|
ref="userGridRef" |
|
|
|
:checkbox-selection="props.multiple || false" |
|
|
|
:dense="true" |
|
|
|
:fetch-data-url="userGridFetchDataUrl" |
|
|
|
:config-button="false" |
|
|
|
title="用户列表" |
|
|
|
:sort-by="['loginName']" |
|
|
|
:query-form-cols-num="2" |
|
|
|
:query-form-fields="[ |
|
|
|
{ name: 'loginName', label: $t('loginName'), type: 'w-text' }, |
|
|
|
{ name: 'userName', label: $t('userName'), type: 'w-text' }, |
|
|
|
]" |
|
|
|
:toolbar-actions="['query', 'separator', 'reset']" |
|
|
|
:ticked-record="{ |
|
|
|
columnName: valueUseColumnName, |
|
|
|
data: typeof modelValue === 'string' ? [modelValue] : modelValue, |
|
|
|
}" |
|
|
|
:columns="[ |
|
|
|
{ name: 'loginName', label: $t('loginName') }, |
|
|
|
{ name: 'userName', label: $t('userName') }, |
|
|
|
{ name: 'description', label: $t('description') }, |
|
|
|
{ name: 'enable', label: $t('status'), format: Formater.enableTag() }, |
|
|
|
]" |
|
|
|
@row-click="userRowClick" |
|
|
|
@update-ticked="updateTicked" |
|
|
|
@update-tickeds="updateTickeds" |
|
|
|
> |
|
|
|
</w-grid> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</q-splitter> |
|
|
|
<div style="width: 750px; height: 350px"> |
|
|
|
<w-grid |
|
|
|
ref="userGridRef" |
|
|
|
:checkbox-selection="props.multiple || false" |
|
|
|
:dense="true" |
|
|
|
:fetch-data-url="userGridFetchDataUrl" |
|
|
|
:config-button="false" |
|
|
|
title="用户列表" |
|
|
|
:sort-by="['loginName']" |
|
|
|
:query-form-cols-num="4" |
|
|
|
:query-form-row-num="1" |
|
|
|
:toolbar-actions="['query', 'separator', 'reset']" |
|
|
|
:query-criteria="queryCriteriaRef" |
|
|
|
:query-form-fields="[ |
|
|
|
{ name: 'loginName', label: $t('loginName'), type: 'w-text' }, |
|
|
|
{ name: 'userName', label: $t('userName'), type: 'w-text' }, |
|
|
|
{ |
|
|
|
name: 'orgs', |
|
|
|
label: '所属机构', |
|
|
|
type: 'w-org-select', |
|
|
|
multiple: true, |
|
|
|
autogrow: false, |
|
|
|
queryCriteria: props.orgQueryCriteria, |
|
|
|
findByDefaultOrg: props.findByDefaultOrg, |
|
|
|
findByDefaultOrgWithSub: props.findByDefaultOrgWithSub, |
|
|
|
findByOrgId: props.findByOrgId, |
|
|
|
findByOrgIdWithSub: props.findByOrgIdWithSub, |
|
|
|
}, |
|
|
|
{ name: 'roles', label: '所属角色', type: 'w-role-select', multiple: true, autogrow: false, queryCriteria: props.roleQueryCriteria }, |
|
|
|
]" |
|
|
|
:ticked-record="{ |
|
|
|
columnName: valueUseColumnName, |
|
|
|
data: typeof modelValue === 'string' ? [modelValue] : modelValue, |
|
|
|
}" |
|
|
|
:columns="[ |
|
|
|
{ name: 'loginName', label: $t('loginName'), width: 100 }, |
|
|
|
{ name: 'userName', label: $t('userName'), width: 100 }, |
|
|
|
{ name: 'enable', label: $t('status'), format: Formater.enableTag(), width: 80 }, |
|
|
|
{ |
|
|
|
name: 'orgs', |
|
|
|
label: '已配置机构', |
|
|
|
sortable: false, |
|
|
|
width: 150, |
|
|
|
format: (val) => { |
|
|
|
if (val) { |
|
|
|
return val |
|
|
|
.map((item) => item['name']) |
|
|
|
.filter(Boolean) |
|
|
|
.join(','); |
|
|
|
} |
|
|
|
return ''; |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: 'roles', |
|
|
|
label: '已配置角色', |
|
|
|
width: '100%', |
|
|
|
sortable: false, |
|
|
|
format: (val) => { |
|
|
|
if (val) { |
|
|
|
return val |
|
|
|
.map((item) => item['name']) |
|
|
|
.filter(Boolean) |
|
|
|
.join(','); |
|
|
|
} |
|
|
|
return ''; |
|
|
|
}, |
|
|
|
}, |
|
|
|
]" |
|
|
|
@row-click="userRowClick" |
|
|
|
@update-ticked="updateTicked" |
|
|
|
@update-tickeds="updateTickeds" |
|
|
|
> |
|
|
|
</w-grid> |
|
|
|
</div> |
|
|
|
</q-popup-proxy> |
|
|
|
</q-btn> |
|
|
|
</template> |
|
|
@ -125,8 +112,8 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script setup lang="ts"> |
|
|
|
import { ref, computed, useAttrs, toRaw, watch, onMounted } from 'vue'; |
|
|
|
import { Tools, axios, Environment, Formater, $t } from '@/platform'; |
|
|
|
import { ref, reactive, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount } from 'vue'; |
|
|
|
import { Tools, axios, Environment, Formater, $t, SessionManager } from '@/platform'; |
|
|
|
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; |
|
|
|
import { FormFieldMethods } from '../form/FormField'; |
|
|
|
|
|
|
@ -134,13 +121,9 @@ const textSelectRef = ref(); |
|
|
|
const attrs = useAttrs(); |
|
|
|
const modelValue = defineModel<string | Array<string>>(); |
|
|
|
const modelObjectValue = ref(<any>[]); // 模型值包含实际值与显示值的对象集合。 |
|
|
|
const orgGridRef = ref(); |
|
|
|
const roleGridRef = ref(); |
|
|
|
const userGridRef = ref(); |
|
|
|
|
|
|
|
const userGridFetchDataUrl = Environment.apiContextPath('/api/system/user'); |
|
|
|
const userGridFetchDataByOrgUrl = Environment.apiContextPath('/api/system/user/queryUsersByOrgAndQueryParameter'); |
|
|
|
const leftWidthRef = ref(30); |
|
|
|
const userGridFetchDataUrl = Environment.apiContextPath('/api/lcdp/userSearch/queryUser'); |
|
|
|
const isShow = ref(false); |
|
|
|
|
|
|
|
interface FieldProps extends FormFieldProps { |
|
|
@ -148,6 +131,13 @@ interface FieldProps extends FormFieldProps { |
|
|
|
counter?: boolean; |
|
|
|
valueUseId?: boolean; |
|
|
|
displayValue?: string | ((args: object) => ''); |
|
|
|
findByDefaultOrg?: boolean; |
|
|
|
findByDefaultOrgWithSub?: boolean; |
|
|
|
findByOrgId?: string | Array<() => void>; |
|
|
|
findByOrgIdWithSub?: string | Array<() => void>; |
|
|
|
queryCriteria?: object; |
|
|
|
orgQueryCriteria?: object; |
|
|
|
roleQueryCriteria?: object; |
|
|
|
} |
|
|
|
const props = withDefaults(defineProps<FieldProps>(), { |
|
|
|
showIf: true, |
|
|
@ -169,6 +159,29 @@ const props = withDefaults(defineProps<FieldProps>(), { |
|
|
|
* } |
|
|
|
*/ |
|
|
|
displayValue: 'nameAppendCode', |
|
|
|
/** |
|
|
|
* 可选用户根据当前登录用户的默认机构进行过滤; |
|
|
|
* --若默认机构为空无法选择用户 |
|
|
|
* --为总行的用户可选全部用户 |
|
|
|
* 根据机构过滤的属性有5个,这些属性无法配合使用,只能生效一个; |
|
|
|
* 优先级如下:orgQueryCriteria > findByOrgIdWithSub > findByOrgId > findByDefaultOrgWithSub > findByDefaultOrg |
|
|
|
*/ |
|
|
|
findByDefaultOrg: false, |
|
|
|
/** |
|
|
|
* 与findByDefaultOrg逻辑一致并包含用户默认机构下的所有子机构。 |
|
|
|
*/ |
|
|
|
findByDefaultOrgWithSub: false, |
|
|
|
/** |
|
|
|
* 可选用户根据传入的机构ID或机构ID数组进行过滤 |
|
|
|
*/ |
|
|
|
findByOrgId: undefined, |
|
|
|
/** |
|
|
|
* 与findByOrgId逻辑一致并包含其所有子机构。 |
|
|
|
*/ |
|
|
|
findByOrgIdWithSub: undefined, |
|
|
|
queryCriteria: undefined, // 用户列表查询条件 |
|
|
|
orgQueryCriteria: undefined, // 机构查询条件 |
|
|
|
roleQueryCriteria: undefined, // 角色查询条件 |
|
|
|
}); |
|
|
|
class FieldMethods extends FormFieldMethods { |
|
|
|
updateValue = (value_) => { |
|
|
@ -218,6 +231,7 @@ class FieldMethods extends FormFieldMethods { |
|
|
|
} |
|
|
|
const fieldMethodsClass = new FieldMethods(); |
|
|
|
const valueUseColumnName = props.valueUseId ? 'id' : 'loginName'; |
|
|
|
const queryCriteriaRef = ref({}); |
|
|
|
|
|
|
|
const displayValueComputed = computed(() => { |
|
|
|
let result = ''; |
|
|
@ -234,7 +248,6 @@ const getActualDisplayValue = (row) => { |
|
|
|
if (!Tools.isEmpty(props.displayValue) && typeof props.displayValue === 'function') { |
|
|
|
return props.displayValue({ |
|
|
|
data: toRaw(row), |
|
|
|
orgGrid: orgGridRef.value, |
|
|
|
userGrid: userGridRef.value, |
|
|
|
}); |
|
|
|
} else if (!Tools.isEmpty(props.displayValue) && typeof props.displayValue === 'string') { |
|
|
@ -294,14 +307,6 @@ const userRowClick = (args) => { |
|
|
|
} |
|
|
|
isShow.value = false; |
|
|
|
}; |
|
|
|
const orgRowClick = (args) => { |
|
|
|
userGridRef.value.setFetchDataUrl(userGridFetchDataByOrgUrl + '?orgId=' + args.row['id']); |
|
|
|
userGridRef.value.refresh(); |
|
|
|
console.info('orgRowClick======================'); |
|
|
|
}; |
|
|
|
const orgUpdateTicked = (args) => { |
|
|
|
console.info('orgUpdateTicked======================'); |
|
|
|
}; |
|
|
|
|
|
|
|
watch( |
|
|
|
() => modelValue.value, |
|
|
@ -309,7 +314,7 @@ watch( |
|
|
|
if (newVal !== oldVal) { |
|
|
|
fieldMethodsClass.updateValue(newVal); |
|
|
|
} |
|
|
|
if (Tools.isEmpty(newVal)) { |
|
|
|
if (Tools.isEmpty(newVal) || (Array.isArray(modelValue.value) && modelValue.value.length === 0)) { |
|
|
|
fieldMethodsClass.clearObjectValue(); |
|
|
|
} else if (newVal !== oldVal) { |
|
|
|
if (modelObjectValue.value.length > 0) { |
|
|
@ -355,6 +360,69 @@ const setObjectValueByValue = async (value) => { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 获取最终生效的机构过滤属性 |
|
|
|
// orgQueryCriteria > findByOrgIdWithSub > findByOrgId > findByDefaultOrgWithSub > findByDefaultOrg |
|
|
|
const getOrgCriteria = () => { |
|
|
|
if (props.orgQueryCriteria) { |
|
|
|
return { |
|
|
|
fieldName: 'orgCriteria', |
|
|
|
operator: 'equals', |
|
|
|
value: JSON.stringify(props.orgQueryCriteria), |
|
|
|
}; |
|
|
|
} else if (props.findByOrgIdWithSub) { |
|
|
|
return { |
|
|
|
fieldName: 'findByOrgIdWithSub', |
|
|
|
operator: 'inSet', |
|
|
|
value: Array.isArray(props.findByOrgIdWithSub) ? props.findByOrgIdWithSub : [props.findByOrgIdWithSub], |
|
|
|
}; |
|
|
|
} else if (props.findByOrgId) { |
|
|
|
return { |
|
|
|
fieldName: 'findByOrgId', |
|
|
|
operator: 'inSet', |
|
|
|
value: Array.isArray(props.findByOrgId) ? props.findByOrgId : [props.findByOrgId], |
|
|
|
}; |
|
|
|
} else if (props.findByDefaultOrgWithSub) { |
|
|
|
return { |
|
|
|
fieldName: 'findByDefaultOrgWithSub', |
|
|
|
operator: 'equals', |
|
|
|
value: true, |
|
|
|
}; |
|
|
|
} else if (props.findByDefaultOrg) { |
|
|
|
return { |
|
|
|
fieldName: 'findByDefaultOrg', |
|
|
|
operator: 'equals', |
|
|
|
value: true, |
|
|
|
}; |
|
|
|
} else { |
|
|
|
return undefined; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* 挂载前根据orgCriteria与roleCriteria重新使用and操作构建用户列表的queryCriteria; |
|
|
|
* 后台再根据用户查询条件+机构查询条件+角色查询条件过滤可选用户。 |
|
|
|
*/ |
|
|
|
onBeforeMount(async () => { |
|
|
|
const orgCriteria = getOrgCriteria(); |
|
|
|
if (props.queryCriteria || orgCriteria || props.roleQueryCriteria) { |
|
|
|
queryCriteriaRef.value['operator'] = 'and'; |
|
|
|
queryCriteriaRef.value['criteria'] = []; |
|
|
|
if (props.queryCriteria) { |
|
|
|
queryCriteriaRef.value['criteria'].push(props.queryCriteria); |
|
|
|
} |
|
|
|
if (orgCriteria) { |
|
|
|
queryCriteriaRef.value['criteria'].push(orgCriteria); |
|
|
|
} |
|
|
|
if (props.roleQueryCriteria) { |
|
|
|
queryCriteriaRef.value['criteria'].push({ |
|
|
|
fieldName: 'roleCriteria', |
|
|
|
operator: 'equals', |
|
|
|
value: JSON.stringify(props.roleQueryCriteria), |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
setObjectValueByValue(modelValue.value); |
|
|
|
}); |
|
|
|