Merge branch 'feature-purchase' into developer

This commit is contained in:
吴红兵
2026-03-04 12:47:07 +08:00
4 changed files with 317 additions and 219 deletions

View File

@@ -11,32 +11,58 @@
:rules="dataRules"
label-width="120px"
v-loading="loading">
<!-- 新增时先选取用户选后自动带出姓名工号 -->
<el-form-item label="选取用户" prop="userId">
<org-selector
v-model:orgList="userList"
type="user"
:multiple="false"
@update:orgList="handleUserChange" />
<el-form-item label="选择人员" prop="userId">
<el-select
v-model="form.userId"
placeholder="请输入姓名或工号搜索"
filterable
remote
clearable
reserve-keyword
:remote-method="searchUser"
:loading="userLoading"
style="width: 100%"
@change="handleUserChange"
>
<el-option
v-for="item in userOptions"
:key="item.teacherNo"
:label="(item.commonDeptName ? item.commonDeptName + ' - ' : '') + (item.realName || item.name) + ' (' + item.teacherNo + ')'"
:value="item.teacherNo"
>
<span>{{ item.commonDeptName ? item.commonDeptName + ' - ' : '' }}{{ item.realName || item.name }}</span>
<span style="color: #999; font-size: 12px; margin-left: 8px;">{{ item.teacherNo }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input
v-model="form.name"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="用户工号" prop="username">
<el-input
v-model="form.username"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="部门" prop="deptId">
<org-selector
v-model:orgList="deptList"
type="dept"
:multiple="false"
@update:orgList="handleDeptChange" />
<el-select
v-model="form.deptId"
placeholder="请选择部门"
filterable
clearable
style="width: 100%"
@change="handleDeptChange"
>
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="部门名称" prop="deptName">
<el-input
@@ -65,16 +91,15 @@
<script setup lang="ts" name="PurchasingBusinessDeptForm">
import { reactive, ref, nextTick } from 'vue'
import { getObj, addObj, putObj } from '/@/api/purchase/purchasingBusinessDept';
import { searchTeachers, getSecondDeptList } from '/@/api/purchase/purchasingrequisition';
import { useMessage } from '/@/hooks/message';
import orgSelector from '/@/components/OrgSelector/index.vue';
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dataFormRef = ref();
const deptList = ref<any[]>([]);
const userList = ref<any[]>([]);
const deptOptions = ref<any[]>([]);
const userOptions = ref<any[]>([]);
const userLoading = ref(false);
const form = reactive({
id: '',
deptId: '',
@@ -89,46 +114,72 @@ const loading = ref(false);
const dataRules = ref({
userId: [
{ required: true, message: '请选取用户(分管负责人)', trigger: 'change' }
{ required: true, message: '请选择人员', trigger: 'change' }
],
deptId: [
{ required: true, message: '请选择部门', trigger: 'change' }
],
name: [
{ required: true, message: '请先选取用户', trigger: 'blur' }
{ required: true, message: '请先选择人员', trigger: 'blur' }
],
username: [
{ required: true, message: '请先选取用户', trigger: 'blur' }
{ required: true, message: '请先选择人员', trigger: 'blur' }
],
});
// 处理部门选择变化
const handleDeptChange = (list: any[]) => {
if (list && list.length > 0) {
const dept = list[0];
form.deptId = dept.deptId || dept.id || '';
form.deptName = dept.name || dept.deptName || '';
} else {
form.deptId = '';
form.deptName = '';
const loadDeptOptions = async () => {
try {
const res = await getSecondDeptList();
deptOptions.value = res?.data || [];
} catch (_) {
deptOptions.value = [];
}
};
// 处理用户选择变化(选取用户后自动带出姓名、工号)
const handleUserChange = (list: any[]) => {
if (list && list.length > 0) {
const user = list[0];
form.userId = user.userId || user.id || '';
form.username = user.username || user.userName || '';
form.name = user.name || user.realName || '';
} else {
const searchUser = async (query: string) => {
if (!query) {
userOptions.value = [];
return;
}
userLoading.value = true;
try {
const res = await searchTeachers(query);
userOptions.value = res?.data || [];
} catch (_) {
userOptions.value = [];
} finally {
userLoading.value = false;
}
};
const handleDeptChange = (deptId: string) => {
if (!deptId) {
form.deptId = '';
form.deptName = '';
return;
}
const selected = deptOptions.value.find((item: any) => item.deptId === deptId);
if (selected) {
form.deptId = selected.deptId;
form.deptName = selected.deptName;
}
};
const handleUserChange = (teacherNo: string) => {
if (!teacherNo) {
form.userId = '';
form.username = '';
form.name = '';
return;
}
const selected = userOptions.value.find((item: any) => item.teacherNo === teacherNo);
if (selected) {
form.userId = selected.teacherNo;
form.username = selected.teacherNo;
form.name = selected.realName || selected.name;
}
};
// 打开弹窗
const openDialog = async (id?: string) => {
visible.value = true;
form.id = '';
@@ -138,13 +189,13 @@ const openDialog = async (id?: string) => {
form.username = '';
form.name = '';
form.remark = '';
deptList.value = [];
userList.value = [];
userOptions.value = [];
await loadDeptOptions();
nextTick(() => {
dataFormRef.value?.resetFields();
if (id) {
// 编辑时,先获取详情数据
loading.value = true;
getObj({ id }).then((res: any) => {
if (res.data && res.data.length > 0) {
@@ -158,26 +209,8 @@ const openDialog = async (id?: string) => {
name: data.name || '',
remark: data.remark || '',
});
// 设置部门列表用于回显
if (data.deptId) {
deptList.value = [{
deptId: data.deptId,
name: data.deptName,
id: data.deptId,
type: 'dept',
}];
}
// 设置用户列表用于回显
if (data.userId) {
userList.value = [{
userId: data.userId,
username: data.username,
name: data.name,
id: data.userId,
userName: data.username,
realName: data.name,
type: 'user',
}];
if (form.userId) {
userOptions.value = [{ teacherNo: form.userId, realName: form.name, name: form.name }];
}
}
loading.value = false;
@@ -189,9 +222,7 @@ const openDialog = async (id?: string) => {
});
};
// 提交
const onSubmit = async () => {
// 立即设置 loading防止重复点击
if (loading.value) return;
loading.value = true;
@@ -218,7 +249,6 @@ const onSubmit = async () => {
}
};
// 暴露变量
defineExpose({
openDialog,
});

View File

@@ -11,23 +11,40 @@
:rules="dataRules"
label-width="120px"
v-loading="loading">
<el-form-item label="选取用户" prop="userId">
<org-selector
v-model:orgList="userList"
type="user"
:multiple="false"
@update:orgList="handleUserChange" />
<el-form-item label="选择人员" prop="userId">
<el-select
v-model="form.userId"
placeholder="请输入姓名或工号搜索"
filterable
remote
clearable
reserve-keyword
:remote-method="searchUser"
:loading="userLoading"
style="width: 100%"
@change="handleUserChange"
>
<el-option
v-for="item in userOptions"
:key="item.teacherNo"
:label="(item.commonDeptName ? item.commonDeptName + ' - ' : '') + (item.realName || item.name) + ' (' + item.teacherNo + ')'"
:value="item.teacherNo"
>
<span>{{ item.commonDeptName ? item.commonDeptName + ' - ' : '' }}{{ item.realName || item.name }}</span>
<span style="color: #999; font-size: 12px; margin-left: 8px;">{{ item.teacherNo }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input
v-model="form.name"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="用户工号" prop="username">
<el-input
v-model="form.username"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="备注" prop="remark">
@@ -51,15 +68,14 @@
<script setup lang="ts" name="PurchasingBusinessLeaderForm">
import { reactive, ref, nextTick } from 'vue'
import { getObj, addObj, putObj } from '/@/api/purchase/purchasingBusinessLeader';
import { searchTeachers } from '/@/api/purchase/purchasingrequisition';
import { useMessage } from '/@/hooks/message';
import orgSelector from '/@/components/OrgSelector/index.vue';
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dataFormRef = ref();
const userList = ref<any[]>([]);
const userOptions = ref<any[]>([]);
const userLoading = ref(false);
const form = reactive({
id: '',
userId: '',
@@ -72,31 +88,47 @@ const loading = ref(false);
const dataRules = ref({
userId: [
{ required: true, message: '请选取用户', trigger: 'change' }
{ required: true, message: '请选择人员', trigger: 'change' }
],
name: [
{ required: true, message: '请先选取用户', trigger: 'blur' }
{ required: true, message: '请先选择人员', trigger: 'blur' }
],
username: [
{ required: true, message: '请先选取用户', trigger: 'blur' }
{ required: true, message: '请先选择人员', trigger: 'blur' }
],
});
// 处理用户选择变化
const handleUserChange = (list: any[]) => {
if (list && list.length > 0) {
const user = list[0];
form.userId = user.userId || user.id || '';
form.username = user.username || user.userName || '';
form.name = user.name || user.realName || '';
} else {
form.userId = '';
form.username = '';
form.name = '';
const searchUser = async (query: string) => {
if (!query) {
userOptions.value = [];
return;
}
userLoading.value = true;
try {
const res = await searchTeachers(query);
userOptions.value = res?.data || [];
} catch (_) {
userOptions.value = [];
} finally {
userLoading.value = false;
}
};
const handleUserChange = (teacherNo: string) => {
if (!teacherNo) {
form.userId = '';
form.username = '';
form.name = '';
return;
}
const selected = userOptions.value.find((item: any) => item.teacherNo === teacherNo);
if (selected) {
form.userId = selected.teacherNo;
form.username = selected.teacherNo;
form.name = selected.realName || selected.name;
}
};
// 打开弹窗
const openDialog = async (id?: string) => {
visible.value = true;
form.id = '';
@@ -104,12 +136,11 @@ const openDialog = async (id?: string) => {
form.username = '';
form.name = '';
form.remark = '';
userList.value = [];
userOptions.value = [];
nextTick(() => {
dataFormRef.value?.resetFields();
if (id) {
// 编辑时,先获取详情数据
loading.value = true;
getObj(id).then((res: any) => {
if (res.data && res.data.length > 0) {
@@ -121,17 +152,8 @@ const openDialog = async (id?: string) => {
name: data.name || '',
remark: data.remark || '',
});
// 设置用户列表用于回显
if (data.userId) {
userList.value = [{
userId: data.userId,
username: data.username,
name: data.name,
id: data.userId,
userName: data.username,
realName: data.name,
type: 'user',
}];
if (form.userId) {
userOptions.value = [{ teacherNo: form.userId, realName: form.name, name: form.name }];
}
}
loading.value = false;
@@ -143,9 +165,7 @@ const openDialog = async (id?: string) => {
});
};
// 提交
const onSubmit = async () => {
// 立即设置 loading防止重复点击
if (loading.value) return;
loading.value = true;
@@ -172,11 +192,10 @@ const onSubmit = async () => {
}
};
// 暴露变量
defineExpose({
openDialog,
});
</script>
<style scoped>
</style>
</style>

View File

@@ -11,32 +11,58 @@
:rules="dataRules"
label-width="120px"
v-loading="loading">
<!-- 新增时先选取用户选后自动带出姓名工号 -->
<el-form-item label="选取用户" prop="userId">
<org-selector
v-model:orgList="userList"
type="user"
:multiple="false"
@update:orgList="handleUserChange" />
<el-form-item label="选择人员" prop="userId">
<el-select
v-model="form.userId"
placeholder="请输入姓名或工号搜索"
filterable
remote
clearable
reserve-keyword
:remote-method="searchUser"
:loading="userLoading"
style="width: 100%"
@change="handleUserChange"
>
<el-option
v-for="item in userOptions"
:key="item.teacherNo"
:label="(item.commonDeptName ? item.commonDeptName + ' - ' : '') + (item.realName || item.name) + ' (' + item.teacherNo + ')'"
:value="item.teacherNo"
>
<span>{{ item.commonDeptName ? item.commonDeptName + ' - ' : '' }}{{ item.realName || item.name }}</span>
<span style="color: #999; font-size: 12px; margin-left: 8px;">{{ item.teacherNo }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input
v-model="form.name"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="用户工号" prop="username">
<el-input
v-model="form.username"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="部门" prop="deptId">
<org-selector
v-model:orgList="deptList"
type="dept"
:multiple="false"
@update:orgList="handleDeptChange" />
<el-select
v-model="form.deptId"
placeholder="请选择部门"
filterable
clearable
style="width: 100%"
@change="handleDeptChange"
>
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<el-form-item label="部门名称" prop="deptName">
<el-input
@@ -65,16 +91,15 @@
<script setup lang="ts" name="PurchasingPurchaseManagerForm">
import { reactive, ref, nextTick } from 'vue'
import { getObj, addObj, putObj } from '/@/api/purchase/purchasingPurchaseManager';
import { searchTeachers, getSecondDeptList } from '/@/api/purchase/purchasingrequisition';
import { useMessage } from '/@/hooks/message';
import orgSelector from '/@/components/OrgSelector/index.vue';
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const dataFormRef = ref();
const deptList = ref<any[]>([]);
const userList = ref<any[]>([]);
const deptOptions = ref<any[]>([]);
const userOptions = ref<any[]>([]);
const userLoading = ref(false);
const form = reactive({
id: '',
deptId: '',
@@ -89,46 +114,72 @@ const loading = ref(false);
const dataRules = ref({
userId: [
{ required: true, message: '请选取用户(分管负责人)', trigger: 'change' }
{ required: true, message: '请选择人员', trigger: 'change' }
],
deptId: [
{ required: true, message: '请选择部门', trigger: 'change' }
],
name: [
{ required: true, message: '请先选取用户', trigger: 'blur' }
{ required: true, message: '请先选择人员', trigger: 'blur' }
],
username: [
{ required: true, message: '请先选取用户', trigger: 'blur' }
{ required: true, message: '请先选择人员', trigger: 'blur' }
],
});
// 处理部门选择变化
const handleDeptChange = (list: any[]) => {
if (list && list.length > 0) {
const dept = list[0];
form.deptId = dept.deptId || dept.id || '';
form.deptName = dept.name || dept.deptName || '';
} else {
form.deptId = '';
form.deptName = '';
const loadDeptOptions = async () => {
try {
const res = await getSecondDeptList();
deptOptions.value = res?.data || [];
} catch (_) {
deptOptions.value = [];
}
};
// 处理用户选择变化(选取用户后自动带出姓名、工号)
const handleUserChange = (list: any[]) => {
if (list && list.length > 0) {
const user = list[0];
form.userId = user.userId || user.id || '';
form.username = user.username || user.userName || '';
form.name = user.name || user.realName || '';
} else {
const searchUser = async (query: string) => {
if (!query) {
userOptions.value = [];
return;
}
userLoading.value = true;
try {
const res = await searchTeachers(query);
userOptions.value = res?.data || [];
} catch (_) {
userOptions.value = [];
} finally {
userLoading.value = false;
}
};
const handleDeptChange = (deptId: string) => {
if (!deptId) {
form.deptId = '';
form.deptName = '';
return;
}
const selected = deptOptions.value.find((item: any) => item.deptId === deptId);
if (selected) {
form.deptId = selected.deptId;
form.deptName = selected.deptName;
}
};
const handleUserChange = (teacherNo: string) => {
if (!teacherNo) {
form.userId = '';
form.username = '';
form.name = '';
return;
}
const selected = userOptions.value.find((item: any) => item.teacherNo === teacherNo);
if (selected) {
form.userId = selected.teacherNo;
form.username = selected.teacherNo;
form.name = selected.realName || selected.name;
}
};
// 打开弹窗
const openDialog = async (id?: string) => {
visible.value = true;
form.id = '';
@@ -138,13 +189,13 @@ const openDialog = async (id?: string) => {
form.username = '';
form.name = '';
form.remark = '';
deptList.value = [];
userList.value = [];
userOptions.value = [];
await loadDeptOptions();
nextTick(() => {
dataFormRef.value?.resetFields();
if (id) {
// 编辑时,先获取详情数据
loading.value = true;
getObj(id).then((res: any) => {
if (res.data && res.data.length > 0) {
@@ -158,26 +209,8 @@ const openDialog = async (id?: string) => {
name: data.name || '',
remark: data.remark || '',
});
// 设置部门列表用于回显
if (data.deptId) {
deptList.value = [{
deptId: data.deptId,
name: data.deptName,
id: data.deptId,
type: 'dept',
}];
}
// 设置用户列表用于回显
if (data.userId) {
userList.value = [{
userId: data.userId,
username: data.username,
name: data.name,
id: data.userId,
userName: data.username,
realName: data.name,
type: 'user',
}];
if (form.userId) {
userOptions.value = [{ teacherNo: form.userId, realName: form.name, name: form.name }];
}
}
loading.value = false;
@@ -189,9 +222,7 @@ const openDialog = async (id?: string) => {
});
};
// 提交
const onSubmit = async () => {
// 立即设置 loading防止重复点击
if (loading.value) return;
loading.value = true;
@@ -218,11 +249,10 @@ const onSubmit = async () => {
}
};
// 暴露变量
defineExpose({
openDialog,
});
</script>
<style scoped>
</style>
</style>

View File

@@ -11,23 +11,40 @@
:rules="dataRules"
label-width="100px"
v-loading="loading">
<el-form-item label="用户" prop="userId">
<org-selector
v-model:orgList="userList"
type="user"
:multiple="false"
@update:orgList="handleUserChange" />
<el-form-item label="选择人员" prop="userId">
<el-select
v-model="dataForm.userId"
placeholder="请输入姓名或工号搜索"
filterable
remote
clearable
reserve-keyword
:remote-method="searchUser"
:loading="userLoading"
style="width: 100%"
@change="handleUserChange"
>
<el-option
v-for="item in userOptions"
:key="item.teacherNo"
:label="(item.commonDeptName ? item.commonDeptName + ' - ' : '') + (item.realName || item.name) + ' (' + item.teacherNo + ')'"
:value="item.teacherNo"
>
<span>{{ item.commonDeptName ? item.commonDeptName + ' - ' : '' }}{{ item.realName || item.name }}</span>
<span style="color: #999; font-size: 12px; margin-left: 8px;">{{ item.teacherNo }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input
v-model="dataForm.name"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="用户工号" prop="username">
<el-input
v-model="dataForm.username"
placeholder="选择用户后自动填充"
placeholder="选择人员后自动填充"
readonly />
</el-form-item>
<el-form-item label="备注" prop="remark">
@@ -51,15 +68,14 @@
<script setup lang="ts" name="PurchasingSchoolLeaderForm">
import { reactive, ref, nextTick } from 'vue'
import { getObj, addObj, editObj } from '/@/api/purchase/purchasingschoolleader';
import { searchTeachers } from '/@/api/purchase/purchasingrequisition';
import { useMessage } from '/@/hooks/message';
import orgSelector from '/@/components/OrgSelector/index.vue';
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);
// 定义变量内容
const formRef = ref();
const userList = ref<any[]>([]);
const userOptions = ref<any[]>([]);
const userLoading = ref(false);
const dataForm = reactive({
id: '',
userId: '',
@@ -72,7 +88,7 @@ const loading = ref(false);
const dataRules = ref({
userId: [
{ required: true, message: '请选择用户', trigger: 'change' }
{ required: true, message: '请选择人员', trigger: 'change' }
],
name: [
{ required: true, message: '姓名不能为空', trigger: 'blur' }
@@ -82,21 +98,37 @@ const dataRules = ref({
],
});
// 处理用户选择变化
const handleUserChange = (list: any[]) => {
if (list && list.length > 0) {
const user = list[0];
dataForm.userId = user.userId || user.id || '';
dataForm.username = user.username || user.userName || '';
dataForm.name = user.name || user.realName || '';
} else {
dataForm.userId = '';
dataForm.username = '';
dataForm.name = '';
const searchUser = async (query: string) => {
if (!query) {
userOptions.value = [];
return;
}
userLoading.value = true;
try {
const res = await searchTeachers(query);
userOptions.value = res?.data || [];
} catch (_) {
userOptions.value = [];
} finally {
userLoading.value = false;
}
};
const handleUserChange = (teacherNo: string) => {
if (!teacherNo) {
dataForm.userId = '';
dataForm.username = '';
dataForm.name = '';
return;
}
const selected = userOptions.value.find((item: any) => item.teacherNo === teacherNo);
if (selected) {
dataForm.userId = selected.teacherNo;
dataForm.username = selected.teacherNo;
dataForm.name = selected.realName || selected.name;
}
};
// 打开弹窗
const openDialog = async (type: string, rowData?: any) => {
visible.value = true;
dataForm.id = '';
@@ -104,12 +136,11 @@ const openDialog = async (type: string, rowData?: any) => {
dataForm.username = '';
dataForm.name = '';
dataForm.remark = '';
userList.value = [];
userOptions.value = [];
nextTick(() => {
formRef.value?.resetFields();
if (type === 'edit' && rowData?.id) {
// 编辑时,先获取详情数据
loading.value = true;
getObj(rowData.id).then((res: any) => {
if (res.data) {
@@ -120,16 +151,8 @@ const openDialog = async (type: string, rowData?: any) => {
name: res.data.name || '',
remark: res.data.remark || '',
});
// 设置用户列表用于回显
if (res.data.userId) {
userList.value = [{
userId: res.data.userId,
username: res.data.username,
name: res.data.name,
id: res.data.userId,
userName: res.data.username,
realName: res.data.name,
}];
if (dataForm.userId) {
userOptions.value = [{ teacherNo: dataForm.userId, realName: dataForm.name, name: dataForm.name }];
}
}
loading.value = false;
@@ -141,9 +164,7 @@ const openDialog = async (type: string, rowData?: any) => {
});
};
// 提交
const onSubmit = async () => {
// 立即设置 loading防止重复点击
if (loading.value) return;
loading.value = true;
@@ -170,12 +191,10 @@ const onSubmit = async () => {
}
};
// 暴露变量
defineExpose({
openDialog,
});
</script>
<style scoped>
</style>
</style>