fix(wot-ui): 修复 v2 升级后部门和角色下拉不显示
Cascader/SelectPicker 在 v2 中不再自带触发单元格,拆分为 wd-form-item 触发 + 选择器弹出模式
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "youlai-app",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"scripts": {
|
||||
"dev:app": "uni -p app",
|
||||
"dev:app-android": "uni -p app-android",
|
||||
|
||||
@@ -44,15 +44,11 @@
|
||||
{{ formData.id ? "编辑部门" : "新增部门" }}
|
||||
</view>
|
||||
<wd-form ref="formRef" :model="formData" :schema="rules">
|
||||
<wd-form-item prop="parentId" title="上级部门" required>
|
||||
<wd-cascader
|
||||
v-model="parentSelected"
|
||||
:columns="parentColumns"
|
||||
:column-change="handleParentColumnChange"
|
||||
:display-format="displayParentFormat"
|
||||
@confirm="handleParentConfirm"
|
||||
/>
|
||||
</wd-form-item>
|
||||
<!-- 上级部门选择:触发交 wd-form-item,选择器只负责弹出 -->
|
||||
<wd-form-item title="上级部门" prop="parentId" required is-link
|
||||
:value="parentLabel" placeholder="请选择上级部门" @click="showParentPicker = true" />
|
||||
<wd-cascader v-model="parentSelected" v-model:visible="showParentPicker" :options="parentOptions"
|
||||
:lazy-load="handleParentLazyLoad" :display-format="displayParentFormat" @confirm="handleParentConfirm" />
|
||||
<wd-form-item prop="name" title="部门名称" required>
|
||||
<wd-input v-model="formData.name" placeholder="请输入部门名称" />
|
||||
</wd-form-item>
|
||||
@@ -60,7 +56,7 @@
|
||||
<wd-input v-model="formData.code" placeholder="请输入部门编号" />
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="sort" title="排序">
|
||||
<wd-input-number v-model="formData.sort" :min="0" />
|
||||
<wd-input-number v-model="formData.sort!" :min="0" />
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="status" title="状态">
|
||||
<wd-switch v-model="formData.status" :active-value="1" :inactive-value="0" />
|
||||
@@ -140,9 +136,10 @@ function transformDeptToTree(dept: DeptItem): any {
|
||||
}
|
||||
|
||||
// 上级部门选择器
|
||||
const showParentPicker = ref(false);
|
||||
const parentSelected = ref<(string | number)[]>([]);
|
||||
const parentColumns = ref<OptionType[][]>([]);
|
||||
const parentOptions = ref<OptionType[]>([]);
|
||||
const parentLabel = ref("");
|
||||
|
||||
// 格式化上级部门展示
|
||||
const displayParentFormat = (selectedItems: OptionType[]) => {
|
||||
@@ -168,8 +165,8 @@ function findDeptPath(data: OptionType[], targetId: string, path: string[] = [])
|
||||
return null;
|
||||
}
|
||||
|
||||
// 上级部门列变化
|
||||
const handleParentColumnChange = ({ selectedItem, resolve, finish }: any) => {
|
||||
// v2 Cascader 懒加载
|
||||
const handleParentLazyLoad = ({ selectedItem, resolve, finish }: any) => {
|
||||
if (String(selectedItem?.value) === "0") {
|
||||
finish();
|
||||
return;
|
||||
@@ -183,9 +180,10 @@ const handleParentColumnChange = ({ selectedItem, resolve, finish }: any) => {
|
||||
};
|
||||
|
||||
// 上级部门确认选择
|
||||
const handleParentConfirm = ({ value }: any) => {
|
||||
const handleParentConfirm = ({ value, selectedItems }: any) => {
|
||||
parentSelected.value = value;
|
||||
formData.parentId = Number(value[value.length - 1]) || 0;
|
||||
parentLabel.value = selectedItems.map((item: any) => item.label).join("/");
|
||||
};
|
||||
|
||||
const rules = toFormSchema({
|
||||
@@ -267,12 +265,11 @@ async function openDeptDialog(dept?: DeptItem) {
|
||||
formRef.value?.reset();
|
||||
Object.assign(formData, initialFormData);
|
||||
parentSelected.value = [];
|
||||
parentLabel.value = "";
|
||||
dialog.visible = true;
|
||||
|
||||
const data = await DeptAPI.getOptions();
|
||||
parentOptions.value = data;
|
||||
const firstColumn: OptionType[] = [{ value: "0", label: "顶级部门" }, ...data];
|
||||
parentColumns.value = [firstColumn];
|
||||
parentOptions.value = [{ value: "0", label: "顶级部门" }, ...data];
|
||||
|
||||
if (dept) {
|
||||
formData.id = dept.id;
|
||||
@@ -283,16 +280,6 @@ async function openDeptDialog(dept?: DeptItem) {
|
||||
const path = findDeptPath(data, String(form.parentId));
|
||||
if (path) {
|
||||
parentSelected.value = path;
|
||||
const columns: OptionType[][] = [firstColumn];
|
||||
let currentLevel = data;
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
const found = currentLevel.find((item: any) => String(item.value) === path[i]);
|
||||
if (found && found.children) {
|
||||
columns.push(found.children);
|
||||
currentLevel = found.children;
|
||||
}
|
||||
}
|
||||
parentColumns.value = columns;
|
||||
} else {
|
||||
parentSelected.value = [String(form.parentId)];
|
||||
}
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
</view>
|
||||
<scroll-view scroll-y class="max-h-60vh">
|
||||
<wd-form ref="formRef" :model="formData" :schema="rules">
|
||||
<wd-form-item prop="parentId" title="上级菜单" required>
|
||||
<wd-cascader v-model="parentSelected" :columns="parentColumns" :column-change="handleParentColumnChange"
|
||||
:display-format="displayParentFormat" @confirm="handleParentConfirm" />
|
||||
</wd-form-item>
|
||||
<!-- 上级菜单选择:触发交 wd-form-item,选择器只负责弹出 -->
|
||||
<wd-form-item title="上级菜单" prop="parentId" required is-link
|
||||
:value="parentLabel" placeholder="请选择上级菜单" @click="showParentPicker = true" />
|
||||
<wd-cascader v-model="parentSelected" v-model:visible="showParentPicker" :options="parentOptions"
|
||||
:lazy-load="handleParentLazyLoad" :display-format="displayParentFormat" @confirm="handleParentConfirm" />
|
||||
<wd-form-item prop="name" title="菜单名称" required>
|
||||
<wd-input v-model="formData.name" placeholder="请输入菜单名称" />
|
||||
</wd-form-item>
|
||||
@@ -167,9 +168,10 @@
|
||||
}
|
||||
|
||||
// 上级菜单选择器
|
||||
const showParentPicker = ref(false);
|
||||
const parentSelected = ref<(string | number)[]>([]);
|
||||
const parentColumns = ref<OptionType[][]>([]);
|
||||
const parentOptions = ref<OptionType[]>([]);
|
||||
const parentLabel = ref("");
|
||||
|
||||
const displayParentFormat = (selectedItems: Record<string, any>[]) => {
|
||||
if (!selectedItems || selectedItems.length === 0) return "";
|
||||
@@ -197,7 +199,8 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleParentColumnChange = ({ selectedItem, resolve, finish }: any) => {
|
||||
// v2 Cascader 懒加载
|
||||
const handleParentLazyLoad = ({ selectedItem, resolve, finish }: any) => {
|
||||
if (String(selectedItem?.value) === "0") {
|
||||
finish();
|
||||
return;
|
||||
@@ -210,9 +213,10 @@
|
||||
}
|
||||
};
|
||||
|
||||
const handleParentConfirm = ({ value }: any) => {
|
||||
const handleParentConfirm = ({ value, selectedItems }: any) => {
|
||||
parentSelected.value = value;
|
||||
formData.parentId = String(value[value.length - 1]) || "0";
|
||||
parentLabel.value = selectedItems.map((item: any) => item.label).join("/");
|
||||
};
|
||||
|
||||
const rules = toFormSchema({
|
||||
@@ -289,12 +293,11 @@
|
||||
formRef.value?.reset();
|
||||
Object.assign(formData, initialFormData);
|
||||
parentSelected.value = [];
|
||||
parentLabel.value = "";
|
||||
dialog.visible = true;
|
||||
|
||||
const data = await MenuAPI.getOptions(true);
|
||||
parentOptions.value = data;
|
||||
const firstColumn: OptionType[] = [{ value: "0", label: "顶级菜单" }, ...data];
|
||||
parentColumns.value = [firstColumn];
|
||||
parentOptions.value = [{ value: "0", label: "顶级菜单" }, ...data];
|
||||
|
||||
if (menu) {
|
||||
formData.id = menu.id;
|
||||
@@ -305,18 +308,6 @@
|
||||
const path = findMenuPath(data, String(form.parentId));
|
||||
if (path) {
|
||||
parentSelected.value = path;
|
||||
const columns: OptionType[][] = [firstColumn];
|
||||
let currentLevel = data;
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
const found = currentLevel.find((item: any) => String(item.value) === String(path[i]));
|
||||
if (found && found.children && found.children.length > 0) {
|
||||
columns.push(found.children);
|
||||
currentLevel = found.children;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parentColumns.value = columns;
|
||||
} else {
|
||||
parentSelected.value = [String(form.parentId)];
|
||||
}
|
||||
|
||||
@@ -58,9 +58,11 @@
|
||||
<wd-form-item prop="code" title="角色编码" required>
|
||||
<wd-input v-model="formData.code" placeholder="请输入角色编码" />
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="dataScope" title="数据权限" required>
|
||||
<wd-select-picker v-model="formData.dataScope" :columns="dataScopeOptions" />
|
||||
</wd-form-item>
|
||||
<!-- 数据权限选择:触发交 wd-form-item,选择器只负责弹出 -->
|
||||
<wd-form-item title="数据权限" prop="dataScope" required is-link
|
||||
:value="dataScopeLabel" placeholder="请选择数据权限" @click="showDataScopePicker = true" />
|
||||
<wd-select-picker v-model="formData.dataScope" v-model:visible="showDataScopePicker"
|
||||
:columns="dataScopeOptions" @confirm="handleDataScopeConfirm" />
|
||||
<wd-form-item prop="status" title="状态">
|
||||
<wd-switch v-model="formData.status" :active-value="1" :inactive-value="0" />
|
||||
</wd-form-item>
|
||||
@@ -124,6 +126,18 @@
|
||||
|
||||
const formData = reactive<RoleForm>({ ...initialFormData });
|
||||
|
||||
// 数据权限选择器状态
|
||||
const showDataScopePicker = ref(false);
|
||||
const dataScopeLabel = computed(() => {
|
||||
const opt = dataScopeOptions.value.find((o) => o.value === formData.dataScope);
|
||||
return opt?.label || "";
|
||||
});
|
||||
|
||||
// 数据权限确认
|
||||
const handleDataScopeConfirm = () => {
|
||||
// label 由 computed 自动计算
|
||||
};
|
||||
|
||||
const dataScopeOptions = ref<Record<string, any>[]>([
|
||||
{ label: "全部数据", value: 1 },
|
||||
{ label: "部门及子部门数据", value: 2 },
|
||||
|
||||
@@ -85,13 +85,17 @@
|
||||
<wd-form-item prop="nickname" title="昵称" required>
|
||||
<wd-input v-model="formData.nickname" placeholder="请输入昵称" />
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="deptId" title="部门" required>
|
||||
<wd-cascader v-model="deptSelected" :columns="deptColumns" :column-change="handleDeptColumnChange"
|
||||
:display-format="displayDeptFormat" @confirm="handleDeptConfirm" />
|
||||
</wd-form-item>
|
||||
<wd-form-item prop="roleIds" title="角色" required>
|
||||
<wd-select-picker v-model="formData.roleIds" :columns="roleOptions" />
|
||||
</wd-form-item>
|
||||
<!-- 部门选择:触发交 wd-form-item,选择器只负责弹出 -->
|
||||
<wd-form-item title="部门" prop="deptId" required is-link
|
||||
:value="deptLabel" placeholder="请选择部门" @click="showDeptPicker = true" />
|
||||
<wd-cascader v-model="deptSelected" v-model:visible="showDeptPicker" :options="deptOptions"
|
||||
:lazy-load="handleDeptLazyLoad" :display-format="displayDeptFormat" @confirm="handleDeptConfirm" />
|
||||
|
||||
<!-- 角色选择:触发交 wd-form-item,选择器只负责弹出 -->
|
||||
<wd-form-item title="角色" prop="roleIds" required is-link
|
||||
:value="roleLabel" placeholder="请选择角色" @click="showRolePicker = true" />
|
||||
<wd-select-picker v-model="formData.roleIds" v-model:visible="showRolePicker" :columns="roleOptions"
|
||||
@confirm="handleRoleConfirm" />
|
||||
<wd-form-item prop="mobile" title="手机号">
|
||||
<wd-input v-model="formData.mobile" placeholder="请输入手机号" />
|
||||
</wd-form-item>
|
||||
@@ -186,9 +190,14 @@
|
||||
const roleOptions = ref<Record<string, any>[]>([]);
|
||||
const deptOptions = ref<OptionType[]>([]);
|
||||
|
||||
// 部门多列选择器数据
|
||||
// 部门选择器状态
|
||||
const showDeptPicker = ref(false);
|
||||
const deptSelected = ref<(string | number)[]>([]);
|
||||
const deptColumns = ref<Record<string, any>[][]>([]);
|
||||
const deptLabel = ref("");
|
||||
|
||||
// 角色选择器状态
|
||||
const showRolePicker = ref(false);
|
||||
const roleLabel = ref("");
|
||||
|
||||
// 格式化部门展示
|
||||
const displayDeptFormat = (selectedItems: Record<string, any>[]) => {
|
||||
@@ -210,8 +219,8 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
// 部门列变化(动态加载子部门)
|
||||
const handleDeptColumnChange = ({ selectedItem, resolve, finish }: any) => {
|
||||
// v2 Cascader 懒加载
|
||||
const handleDeptLazyLoad = ({ selectedItem, resolve, finish }: any) => {
|
||||
const children = selectedItem.children;
|
||||
if (children && children.length > 0) {
|
||||
resolve(children);
|
||||
@@ -223,8 +232,13 @@
|
||||
// 部门确认选择
|
||||
const handleDeptConfirm = ({ value, selectedItems }: any) => {
|
||||
deptSelected.value = value;
|
||||
// 取最后一个选中的部门ID
|
||||
formData.deptId = value[value.length - 1];
|
||||
deptLabel.value = selectedItems.map((item: any) => item.label).join("/");
|
||||
};
|
||||
|
||||
// 角色确认选择
|
||||
const handleRoleConfirm = ({ selectedItems }: any) => {
|
||||
roleLabel.value = selectedItems.map((item: any) => item.label).join("、");
|
||||
};
|
||||
|
||||
const rules = toFormSchema({
|
||||
@@ -297,6 +311,8 @@
|
||||
formRef.value?.reset();
|
||||
Object.assign(formData, initialFormData);
|
||||
deptSelected.value = [];
|
||||
deptLabel.value = "";
|
||||
roleLabel.value = "";
|
||||
dialog.visible = true;
|
||||
roleOptions.value = await RoleAPI.getOptions();
|
||||
const deptData = await DeptAPI.getOptions();
|
||||
@@ -306,31 +322,22 @@
|
||||
formData.id = id;
|
||||
const data = await UserAPI.getFormData(id);
|
||||
Object.assign(formData, data, { id });
|
||||
// 编辑时回显部门选择(需要完整路径和预加载所有层级数据)
|
||||
// 编辑时回显部门
|
||||
if (data.deptId) {
|
||||
const path = findDeptPath(deptData, String(data.deptId));
|
||||
if (path) {
|
||||
deptSelected.value = path;
|
||||
// 预加载所有层级的 columns
|
||||
const columns: any[] = [deptData];
|
||||
let currentLevel = deptData;
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
const found = currentLevel.find((item: any) => item.value === path[i]);
|
||||
if (found && found.children) {
|
||||
columns.push(found.children);
|
||||
currentLevel = found.children;
|
||||
}
|
||||
}
|
||||
deptColumns.value = columns;
|
||||
} else {
|
||||
deptSelected.value = [String(data.deptId)];
|
||||
deptColumns.value = [deptData];
|
||||
}
|
||||
} else {
|
||||
deptColumns.value = [deptData];
|
||||
}
|
||||
} else {
|
||||
deptColumns.value = [deptData];
|
||||
// 回显角色
|
||||
if (data.roleIds && data.roleIds.length > 0) {
|
||||
const names = roleOptions.value
|
||||
.filter((r: any) => data.roleIds.includes(r.value))
|
||||
.map((r: any) => r.label);
|
||||
roleLabel.value = names.join("、");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user