feat(admin): 选人组件接入——UserCheckModal 加单选模式+UserSelectInput 单选封装;映射办理人/审批节点指定用户弃手输 ID 改弹窗选人 (/admin/user/tree);删休眠 UserCheckInput 死代码
build / build (push) Successful in 1m56s
build / build (push) Successful in 1m56s
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
// 办理人映射管理(概览 §4.7/§六):DEPT_KEY → 办理人;成员检索经 UserBase /oapi/user/byId 补姓名
|
||||
// 办理人映射管理(概览 §4.7/§六):DEPT_KEY → 办理人;办理人改为弹窗选人(参照 Notice 选人范式)
|
||||
import { ref, onMounted } from "vue";
|
||||
import { Message } from "view-ui-plus";
|
||||
import UserSelectInput from "@/components/UserSelectInput.vue";
|
||||
import { flowApi } from "@/api/module/flow";
|
||||
import Utils from "@/utils";
|
||||
|
||||
@@ -12,7 +13,6 @@ const rows = ref<any[]>([]);
|
||||
const saveVisible = ref(false);
|
||||
const saving = ref(false);
|
||||
const form = ref<any>({ deptKey: "", deptName: "", userId: null, userName: "" });
|
||||
const lookingUp = ref(false);
|
||||
|
||||
// 一键拉取教师组(预览确认后批量导入)
|
||||
const groupVisible = ref(false);
|
||||
@@ -79,26 +79,14 @@ function onAdd() {
|
||||
saveVisible.value = true;
|
||||
}
|
||||
|
||||
async function onLookup() {
|
||||
if (!form.value.userId) {
|
||||
Message.warning("请先填用户ID");
|
||||
return;
|
||||
}
|
||||
lookingUp.value = true;
|
||||
try {
|
||||
const u: any = await flowApi.mapLookupUser(form.value.userId).send();
|
||||
form.value.userName = u?.name || "";
|
||||
Message.success(`检索到用户:${u?.name || "-"}`);
|
||||
} catch {
|
||||
Message.error("UserBase 检索失败");
|
||||
} finally {
|
||||
lookingUp.value = false;
|
||||
}
|
||||
function onUserPick(u: any) {
|
||||
// 选人组件回传 id+name 同帧快照(姓名不再自查)
|
||||
form.value.userName = u?.name || "";
|
||||
}
|
||||
|
||||
async function onSave() {
|
||||
if (!form.value.deptKey.trim() || !form.value.userId) {
|
||||
Message.warning("科室编码与用户ID必填");
|
||||
Message.warning("科室编码与办理人必填");
|
||||
return;
|
||||
}
|
||||
saving.value = true;
|
||||
@@ -144,12 +132,14 @@ onMounted(load);
|
||||
<FormItem label="科室名称">
|
||||
<Input v-model="form.deptName" placeholder="如 医保办(可空)" />
|
||||
</FormItem>
|
||||
<FormItem label="用户ID">
|
||||
<Input v-model="form.userId" placeholder="UserBase 用户主键" />
|
||||
</FormItem>
|
||||
<FormItem label="姓名快照">
|
||||
<Input v-model="form.userName" placeholder="可留空,点检索自动补全" style="width: 180px" />
|
||||
<Button :loading="lookingUp" @click="onLookup" style="margin-left: 8px">检索</Button>
|
||||
<FormItem label="办理人">
|
||||
<UserSelectInput
|
||||
:model-value="form.userId"
|
||||
:display-name="form.userName"
|
||||
@update:model-value="form.userId = $event"
|
||||
@update:display-name="form.userName = $event"
|
||||
@on-change="onUserPick"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<template #footer>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
// 审批节点配置抽屉(方案 §3.4):打开时把节点值拷进本地表单,确定时写回——
|
||||
// 分段控件切换只改本地状态,不会因重渲染丢失未保存输入(原型阶段踩过该坑)。
|
||||
// 指定用户改为树形选人弹窗(参照 Notice 自定义组选人),id+name 同帧拿到,不再手输 ID。
|
||||
import { computed, inject, reactive, ref, watch } from "vue";
|
||||
import { Message } from "view-ui-plus";
|
||||
import UserCheckModal from "@/components/UserCheckModal.vue";
|
||||
import { flowApi } from "@/api/module/flow";
|
||||
import { ApprovalNode, EDITOR_CTX } from "../model";
|
||||
|
||||
@@ -28,8 +30,13 @@ const form = reactive({
|
||||
deadlineHours: null as number | null,
|
||||
});
|
||||
|
||||
const lookupId = ref<number | null>(null);
|
||||
const lookingUp = ref(false);
|
||||
const userCheckModal = ref<any>();
|
||||
const userModalSources = [
|
||||
{
|
||||
name: "基础平台",
|
||||
loader: () => flowApi.adminUserTree().send() as Promise<any[]>,
|
||||
},
|
||||
];
|
||||
|
||||
function syncFromNode(): void {
|
||||
const n = props.node;
|
||||
@@ -40,7 +47,6 @@ function syncFromNode(): void {
|
||||
form.userIds = n.assignee?.type === "USERS" ? [...n.assignee.userIds] : [];
|
||||
form.countersign = n.countersign;
|
||||
form.deadlineHours = n.deadlineHours;
|
||||
lookupId.value = null;
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -76,24 +82,19 @@ function userNameOf(id: number): string {
|
||||
return ctx.userNames[id] || `#${id}`;
|
||||
}
|
||||
|
||||
async function onLookup(): Promise<void> {
|
||||
if (!lookupId.value) {
|
||||
Message.warning("请先填用户ID");
|
||||
return;
|
||||
}
|
||||
const id = Number(lookupId.value);
|
||||
lookingUp.value = true;
|
||||
try {
|
||||
const u: any = await flowApi.mapLookupUser(id).send();
|
||||
ctx.userNames[id] = u?.name || `#${id}`;
|
||||
if (!form.userIds.includes(id)) form.userIds.push(id);
|
||||
lookupId.value = null;
|
||||
Message.success(`已添加:${u?.name || `#${id}`}`);
|
||||
} catch {
|
||||
Message.error("UserBase 检索失败");
|
||||
} finally {
|
||||
lookingUp.value = false;
|
||||
/** 选人弹窗提交:选中后的 id+name 合入本地 userIds 与姓名快照(不再逐个 byId 检索) */
|
||||
function onUsersPicked(arr: any[]): void {
|
||||
let added = 0;
|
||||
for (const u of arr || []) {
|
||||
if (u?.id == null) continue;
|
||||
const id = Number(u.id);
|
||||
if (!form.userIds.includes(id)) {
|
||||
form.userIds.push(id);
|
||||
added++;
|
||||
}
|
||||
if (u.name) ctx.userNames[id] = u.name;
|
||||
}
|
||||
Message.success(`已选择 ${added} 名用户`);
|
||||
}
|
||||
|
||||
function removeUser(id: number): void {
|
||||
@@ -162,8 +163,7 @@ function onRemove(): void {
|
||||
<div class="fld">
|
||||
<label>指定用户</label>
|
||||
<div class="user-add">
|
||||
<InputNumber v-model="lookupId" :min="1" placeholder="填 UserBase 用户ID" style="flex: 1" />
|
||||
<Button type="primary" :loading="lookingUp" @click="onLookup">检索并添加</Button>
|
||||
<Button type="primary" @click="userCheckModal?.show()">选择用户</Button>
|
||||
</div>
|
||||
<div class="user-tags">
|
||||
<Tag
|
||||
@@ -208,6 +208,13 @@ function onRemove(): void {
|
||||
<Button type="primary" @click="onOk">确定</Button>
|
||||
</div>
|
||||
</Drawer>
|
||||
|
||||
<UserCheckModal
|
||||
ref="userCheckModal"
|
||||
:sources="userModalSources"
|
||||
:userids="form.userIds"
|
||||
@on-submit="onUsersPicked"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user