This commit is contained in:
2025-08-28 23:32:17 +08:00
parent 2b25709c14
commit ade1177294
16 changed files with 1929 additions and 649 deletions

View File

@ -27,3 +27,11 @@ export const systemUserList = (query) => {
params: query params: query
}); });
}; };
// 查询
export const desUserList = (query) => {
return request({
url: '/design/drawingreviewReceipts/desUser/list',
method: 'get',
params: query
});
};

View File

@ -56,7 +56,7 @@ export const fillOutTheDesignVerificationForm = (data) => {
export const drawingreviewReceipts = (data) => { export const drawingreviewReceipts = (data) => {
return request({ return request({
url: '/design/drawingreviewReceipts', url: '/design/drawingreviewReceipts',
method: 'post', method: 'put',
data data
}); });
}; };
@ -96,3 +96,10 @@ export const drawingreview = (id) => {
method: 'get' method: 'get'
}); });
}; };
// 获取单据
export const getDrawingreviewReceipts = (id) => {
return request({
url: '/design/drawingreviewReceipts/review/' + id,
method: 'get'
});
};

View File

@ -68,3 +68,10 @@ export const getMaterialName = (id: any) => {
method: 'get' method: 'get'
}); });
}; };
//获取出库记录
export const inventoryList = (id: any) => {
return request({
url: '/materials/materialIssue/inventory/list/' + id,
method: 'get'
});
};

View File

@ -185,6 +185,10 @@ const props = defineProps({
taskVariables: { taskVariables: {
type: Object as () => Record<string, any>, type: Object as () => Record<string, any>,
default: () => {} default: () => {}
},
businessId1: {
type: String,
default: ''
} }
}); });
//遮罩层 //遮罩层
@ -336,6 +340,9 @@ const handleCompleteTask = async () => {
} }
if (isDrawing.value) { if (isDrawing.value) {
isShowSubmit.value = true; isShowSubmit.value = true;
nextTick(() => {
detailFormTeRef.value.getInfo(props.businessId1);
});
return; return;
} }
await proxy?.$modal.confirm('是否确认提交?'); await proxy?.$modal.confirm('是否确认提交?');
@ -538,6 +545,9 @@ const handleTermination = async () => {
const handleTerminationTask = async () => { const handleTerminationTask = async () => {
if (isDrawing.value) { if (isDrawing.value) {
isShowTermination.value = true; isShowTermination.value = true;
nextTick(() => {
detailFormTeRef.value.getInfo(props.businessId);
});
return; return;
} }
const params = { const params = {

View File

@ -16,7 +16,7 @@
<template v-if="item.meta" #title> <template v-if="item.meta" #title>
<svg-icon :icon-class="item.meta ? item.meta.icon : ''" /> <svg-icon :icon-class="item.meta ? item.meta.icon : ''" />
<span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span> <span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span>
<span class="bage" v-if="item.meta?.title == '我的任务' && total >= 0">{{ total }}</span> <!-- <span class="bage" v-if="item.meta?.title == '我的任务' && total >= 0">{{ total }}</span> -->
</template> </template>
<sidebar-item <sidebar-item
@ -59,7 +59,6 @@ const total = ref(0);
onMounted(() => { onMounted(() => {
if (onlyOneChild.value.meta?.title == '我的待办' || props.item.meta?.title == '我的任务') { if (onlyOneChild.value.meta?.title == '我的待办' || props.item.meta?.title == '我的任务') {
console.log(44444444); console.log(44444444);
getWaitingList(); getWaitingList();
} }
}); });

View File

@ -0,0 +1,804 @@
<template>
<div class="p-6 bg-gray-50">
<div class="appointment mx-auto bg-white rounded-xl shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md">
<!-- 表单标题区域 -->
<div class="bg-gradient-to-r from-blue-500 to-blue-600 text-white p-6">
<h2 class="text-2xl font-bold flex items-center"><i class="el-icon-user-circle mr-3"></i>人员配置</h2>
<p class="text-blue-100 mt-2 opacity-90">请配置项目相关负责人员信息</p>
<el-button @click="disabledForm = false" class="px-8 py-2.5 transition-all duration-300 font-medium" v-if="disabledForm">
点击编辑
</el-button>
</div>
<!-- 表单内容区域 -->
<el-form ref="leaveFormRef" :model="form" :disabled="disabledForm" :rules="rules" label-width="120px" class="p-6 space-y-6">
<!-- 设计负责人 -->
<div class="fonts">
<el-row>
<el-col :span="8"
><el-form-item label="设计负责人" prop="designLeader" class="mb-4">
<el-select
v-model="form.designLeader"
placeholder="请选择设计负责人"
class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400"
>
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 专业人员配置专业 + 设计人员 + 校审人员 横向排列 -->
<div class="border border-gray-200 rounded-lg p-5 transition-all duration-300 hover:shadow-md bg-gray-50">
<div class="flex justify-between items-center mb-5">
<h3 class="text-lg font-semibold text-gray-700 flex items-center"><i class="el-icon-users mr-2 text-blue-500"></i>专业人员配置</h3>
<div class="flex gap-3">
<!-- 新增专业按钮 -->
<el-button type="primary" size="small" :disabled="disabledForm" @click="addMajor">
<i class="el-icon-plus mr-1"></i>新增专业
</el-button>
</div>
</div>
<!-- 表头 -->
<el-row :gutter="20" class="mb-3 font-medium text-gray-700">
<el-col :span="6" :xs="24" :sm="8">专业</el-col>
<el-col :span="9" :xs="24" :sm="8">设计人员可多选</el-col>
<el-col :span="9" :xs="24" :sm="8">校审人员可多选</el-col>
</el-row>
<!-- 分割线 -->
<el-divider class="my-4" />
<!-- 专业配置行专业+ 设计人员+ 校审人员 横向排列 -->
<div
v-for="(majorConfig, configIndex) in combinedConfigs"
:key="configIndex"
style="background: aliceblue; border-radius: 10px"
class="mb-5 animate-fadeIn"
>
<el-row :gutter="20" class="items-top">
<!-- 左侧专业选择 -->
<el-col :span="6" :xs="24" :sm="8" class="mb-4 sm:mb-0" style="margin-top: 8px">
<el-form-item
:prop="`designers.${configIndex}.userMajor`"
:rules="{ required: true, message: '请选择专业', trigger: 'change' }"
class="mb-0"
label-width="80px"
label="专业"
>
<!-- 专业选择下拉框 -->
<el-select
v-model="form.designers[configIndex].userMajor"
placeholder="请选择专业"
class="w-full transition-all duration-300 border-gray-300"
@change="(val) => handleMajorChange(val, configIndex)"
>
<!-- 临时添加调试显示 -->
<template v-if="des_user_major && des_user_major.length > 0">
<el-option v-for="item in des_user_major" :key="item.value" :label="item.label" :value="item.value" />
</template>
<template v-else>
<el-option label="无专业数据" value="" disabled />
</template>
</el-select>
</el-form-item>
</el-col>
<!-- 中间设计人员 -->
<el-col :span="9" :xs="24" :sm="8" class="mb-4 sm:mb-0">
<div class="pl-0 sm:pl-4 border-l-0 sm:border-l-2 border-blue-200 py-0 sm:py-2">
<!-- 设计人员列表 -->
<div class="space-y-3">
<div v-for="(person, personIndex) in majorConfig.designPersons" :key="personIndex" class="flex items-center">
<el-form-item
:prop="`designers.${configIndex}.persons.${personIndex}.userId`"
:rules="{ required: true, message: '请选择人员', trigger: 'change' }"
class="flex-1 mr-3 mb-0"
label="设计人员"
label-width="80px"
>
<el-select
v-model="person.userId"
placeholder="请选择设计人员"
class="w-full transition-all duration-300 border-gray-300"
@change="() => checkDuplicate(person, 'designers', configIndex, personIndex)"
>
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
</el-select>
</el-form-item>
<div>
<el-button
type="danger"
size="small"
@click="removePerson('designers', configIndex, personIndex)"
class="transition-all duration-300 hover:bg-red-600"
:disabled="majorConfig.designPersons.length <= 1 || disabledForm"
>
<el-icon :size="16">
<Delete />
</el-icon>
</el-button>
<el-button
type="success"
size="small"
@click="addPerson('designers', configIndex)"
class="transition-all duration-300 transform hover:scale-105"
:disabled="!majorConfig.userMajor || disabledForm"
>
<el-icon :size="16">
<Plus />
</el-icon>
</el-button>
</div>
</div>
</div>
<!-- 空状态提示 -->
<div
v-if="majorConfig.designPersons.length == 0"
class="text-gray-500 text-sm py-2 bg-gray-100 rounded-lg border border-dashed border-gray-200 mt-1"
>
暂无设计人员请点击"添加设计人员"
</div>
</div>
</el-col>
<!-- 右侧校审人员 -->
<el-col :span="9" :xs="24" :sm="8">
<div class="pl-0 sm:pl-4 border-l-0 sm:border-l-2 border-green-200 py-0 sm:py-2">
<!-- 校审人员列表 -->
<div class="space-y-3">
<div v-for="(person, personIndex) in majorConfig.reviewPersons" :key="personIndex" class="flex items-center">
<el-form-item
:prop="`reviewers.${configIndex}.persons.${personIndex}.userId`"
:rules="{ required: true, message: '请选择人员', trigger: 'change' }"
class="flex-1 mr-3 mb-0"
label="校审人员"
label-width="80px"
>
<el-select
v-model="person.userId"
placeholder="请选择校审人员"
class="w-full transition-all duration-300 border-gray-300"
@change="() => checkDuplicate(person, 'reviewers', configIndex, personIndex)"
>
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
</el-select>
</el-form-item>
<div>
<el-button
type="danger"
size="small"
@click="removePerson('reviewers', configIndex, personIndex)"
class="transition-all duration-300 hover:bg-red-600"
:disabled="majorConfig.reviewPersons.length <= 1 || disabledForm"
>
<el-icon :size="16">
<Delete />
</el-icon>
</el-button>
<el-button
type="success"
size="small"
@click="addPerson('reviewers', configIndex)"
class="transition-all duration-300 transform hover:scale-105"
:disabled="!majorConfig.userMajor || disabledForm"
>
<el-icon :size="16">
<Plus />
</el-icon>
</el-button>
</div>
</div>
</div>
<!-- 空状态提示 -->
<div
v-if="majorConfig.reviewPersons.length == 0"
class="text-gray-500 text-sm py-2 bg-gray-100 rounded-lg border border-dashed border-gray-200 mt-1"
>
暂无校审人员请点击"添加校审人员"
</div>
</div>
</el-col>
</el-row>
<!-- 删除专业配置行 -->
<el-row class="mt-2">
<el-col :span="24" class="text-right pr-4">
<el-button
type="text"
class="text-red-500 hover:text-red-700 transition-colors"
@click="removeMajor(configIndex)"
:disabled="combinedConfigs.length <= 1 || disabledForm"
>
<i class="el-icon-delete mr-1"></i>删除专业
</el-button>
</el-col>
</el-row>
</div>
</div>
<!-- 提交按钮区域 -->
<div class="flex justify-center space-x-6 mt-8 pt-6 border-t border-gray-100">
<el-button
type="primary"
size="large"
v-hasPermi="['design:user:batch']"
@click="submitForm"
class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium"
:disabled="disabledForm"
>
<i class="el-icon-check mr-2"></i>确认提交
</el-button>
<el-button
size="large"
@click="resetForm"
class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium"
:disabled="disabledForm"
>
<i class="el-icon-refresh mr-2"></i>重置
</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script setup name="PersonnelForm" lang="ts">
import { ref, reactive, computed, onMounted, toRefs, watch, WatchStopHandle } from 'vue';
import { getCurrentInstance } from 'vue';
import type { ComponentInternalInstance } from 'vue';
import { useUserStoreHook } from '@/store/modules/user';
import { ElMessage, ElLoading } from 'element-plus';
import { Delete, Plus } from '@element-plus/icons-vue'; // 修复添加Plus图标导入
import { designUserAdd, designUserList, systemUserList } from '@/api/design/appointment';
// 获取当前实例
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
// 获取用户 store
const userStore = useUserStoreHook();
// 从 store 中获取当前选中的项目
const currentProject = computed(() => userStore.selectedProject);
// 专业字典数据 - 增加默认空数组避免undefined
const { des_user_major = ref([]) } = toRefs<any>(proxy?.useDict('des_user_major') || {});
// 调试:打印专业数据
onMounted(() => {
console.log('专业数据:', des_user_major.value);
});
// 表单数据:保持原有数据结构不变
interface MajorGroup {
userMajor: string | null; // 专业
persons: Array<{ userId: number | null }>; // 该专业下的多个人员
}
const form = reactive({
projectId: currentProject.value?.id,
designLeader: null, // 设计负责人
designers: [] as MajorGroup[], // 设计人员:按专业分组,每组含多个人员
reviewers: [] as MajorGroup[] // 校审人员:按专业分组,每组含多个人员
});
// 组合配置用于视图展示(专业+设计人员+校审人员)
const combinedConfigs = computed(() => {
// 确保designers和reviewers数组长度一致
const maxLength = Math.max(form.designers.length, form.reviewers.length);
while (form.designers.length < maxLength) {
form.designers.push(createEmptyMajorGroup());
}
while (form.reviewers.length < maxLength) {
form.reviewers.push(createEmptyMajorGroup());
}
// 组合数据用于视图展示
return form.designers.map((designerGroup, index) => ({
userMajor: designerGroup.userMajor,
designPersons: designerGroup.persons,
reviewPersons: form.reviewers[index].persons
}));
});
// 表单验证规则
const rules = reactive({
designLeader: [{ required: true, message: '请选择设计负责人', trigger: 'change' }]
});
// 用户列表
const userList = ref([]);
// 表单引用
const leaveFormRef = ref();
const disabledForm = ref(false); //控制提交按钮状态
/** 查询当前部门的所有用户 */
const getDeptAllUser = async (deptId: any) => {
try {
const res = await systemUserList({ deptId });
userList.value = res.rows;
} catch (error) {
ElMessage.error('获取用户列表失败');
}
};
/** 查询当前表单数据并回显 */
const designUser = async () => {
if (!currentProject.value?.id) return;
const loading = ElLoading.service({
lock: true,
text: '加载配置数据中...',
background: 'rgba(255, 255, 255, 0.7)'
});
try {
const res = await designUserList({ projectId: currentProject.value?.id });
// 清空现有数据
form.designLeader = null;
form.designers = [];
form.reviewers = [];
if (res.code == 200 && res.rows && res.rows.length > 0) {
disabledForm.value = true;
// 1. 分类整理数据(按用户类型)
const designLeader = res.rows.find((item) => item.userType == 1);
const designerItems = res.rows.filter((item) => item.userType == 2);
const reviewerItems = res.rows.filter((item) => item.userType == 3);
// 2. 回显设计负责人
if (designLeader) form.designLeader = designLeader.userId;
// 3. 回显设计人员(按专业分组)
form.designers = groupPersonByMajor(designerItems);
// 4. 回显校审人员(按专业分组)
form.reviewers = groupPersonByMajor(reviewerItems);
}
// 补全默认空项至少1个专业分组每组至少1个人员
if (form.designers.length == 0) form.designers.push(createEmptyMajorGroup());
if (form.reviewers.length == 0) form.reviewers.push(createEmptyMajorGroup());
} catch (error) {
ElMessage.error('获取配置数据失败');
// 异常时初始化默认空项
form.designers = [createEmptyMajorGroup()];
form.reviewers = [createEmptyMajorGroup()];
} finally {
loading.close();
}
};
/** 辅助函数创建空的专业分组含1个空人员 */
const createEmptyMajorGroup = (): MajorGroup => ({
userMajor: null,
persons: [{ userId: null }]
});
/** 辅助函数:按专业分组整理人员数据(用于回显) */
const groupPersonByMajor = (items: any[]): MajorGroup[] => {
const groupMap: Record<string, MajorGroup> = {};
items.forEach((item) => {
const major = item.userMajor || '未分类';
// 不存在该专业分组则创建
if (!groupMap[major]) {
groupMap[major] = { userMajor: item.userMajor, persons: [] };
}
// 添加当前人员到专业分组
groupMap[major].persons.push({ userId: item.userId });
});
// 处理空分组确保每组至少1个人员
Object.values(groupMap).forEach((group) => {
if (group.persons.length == 0) group.persons.push({ userId: null });
});
return Object.values(groupMap);
};
/** 新增专业配置行 */
const addMajor = () => {
form.designers.push(createEmptyMajorGroup());
form.reviewers.push(createEmptyMajorGroup());
// 滚动到新增的专业配置行
setTimeout(() => {
const groups = document.querySelectorAll(`[data-v-${proxy?.$options.__scopeId}] .animate-fadeIn`);
if (groups.length > 0) {
groups[groups.length - 1].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}, 100);
};
/** 删除专业配置行 */
const removeMajor = (configIndex: number) => {
if (form.designers.length <= 1) {
ElMessage.warning('至少保留一个专业配置');
return;
}
form.designers.splice(configIndex, 1);
form.reviewers.splice(configIndex, 1);
};
/** 给指定专业配置行添加人员 */
const addPerson = (type: 'designers' | 'reviewers', configIndex: number) => {
form[type][configIndex].persons.push({ userId: null });
// 滚动到新增的人员选择框
setTimeout(() => {
const personSelects = document.querySelectorAll(`[data-v-${proxy?.$options.__scopeId}] .el-select`);
if (personSelects.length > 0) {
personSelects[personSelects.length - 1].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}, 100);
};
/** 从指定专业配置行删除人员 */
const removePerson = (type: 'designers' | 'reviewers', configIndex: number, personIndex: number) => {
const targetGroup = form[type][configIndex];
if (targetGroup.persons.length <= 1) {
ElMessage.warning(`该专业至少保留一个${type == 'designers' ? '设计' : '校审'}人员`);
return;
}
targetGroup.persons.splice(personIndex, 1);
};
/** 专业变更时:清空当前专业下的人员(避免专业与人员不匹配) */
const handleMajorChange = (newMajor: string, configIndex: number) => {
// 直接修改原始数据源,确保响应式生效
form.designers[configIndex].userMajor = newMajor;
form.reviewers[configIndex].userMajor = newMajor;
form.designers[configIndex].persons = [{ userId: null }];
form.reviewers[configIndex].persons = [{ userId: null }];
// ElMessage.info(`已重置「${getMajorLabel(newMajor)}」专业下的人员,请重新选择`);
};
// ========== 核心:重复校验逻辑 ==========
/**
* 校验同一角色内(设计/校审)的「专业+人员」组合唯一性
*/
const checkDuplicate = (current: { userId: number | null }, role: 'designers' | 'reviewers', configIndex: number, personIndex: number) => {
console.log(`校验触发 - 角色: ${role}, 专业索引: ${configIndex}, 人员索引: ${personIndex}, 人员ID: ${current.userId}`);
console.log(form);
const currentGroup = form[role][configIndex];
// 未选专业/人员时不校验
if (!currentGroup.userMajor || !current.userId) return;
// 生成当前「专业+人员」唯一标识
const currentKey = `${currentGroup.userMajor}-${current.userId}`;
let duplicateItem = null;
// 1. 检查当前专业配置行内是否有重复人员
duplicateItem = currentGroup.persons.find((item, idx) => {
return idx !== personIndex && item.userId == current.userId;
});
if (duplicateItem) {
ElMessage.warning(`当前专业下「${getUserName(current.userId)}」已存在,请重新选择`);
current.userId = null;
return;
}
// 2. 检查同一角色内其他专业配置行是否有重复(专业+人员唯一)
form[role].forEach((group, gIdx) => {
if (gIdx == configIndex) return; // 跳过当前配置行
group.persons.forEach((item) => {
if (`${group.userMajor}-${item.userId}` == currentKey) {
duplicateItem = item;
}
});
});
if (duplicateItem) {
ElMessage.warning(`${getMajorLabel(currentGroup.userMajor)}+${getUserName(current.userId)}」组合已存在,请重新选择`);
current.userId = null;
}
};
/** 辅助函数:通过专业值获取专业名称 */
const getMajorLabel = (majorValue: string | null) => {
if (!majorValue || !des_user_major.value) return '';
const major = des_user_major.value.find((item: any) => item.value == majorValue);
return major ? major.label : majorValue;
};
/** 辅助函数通过用户ID获取用户名 */
const getUserName = (userId: number | null) => {
if (!userId || !userList.value.length) return '';
const user = userList.value.find((item: any) => item.userId == userId);
return user ? user.nickName : userId;
};
/** 提交表单(保持原有数据结构) */
const submitForm = async () => {
if (!leaveFormRef.value) return;
try {
// 1. 基础表单验证
await leaveFormRef.value.validate();
// 2. 提交前二次校验:「专业+人员」组合唯一性
let hasDuplicate = false;
const allKeys: string[] = [];
// 收集所有「专业+人员」组合(设计+校审分开校验)
const collectKeys = (roleGroups: MajorGroup[], roleName: string) => {
roleGroups.forEach((group) => {
if (!group.userMajor) return;
group.persons.forEach((person) => {
if (!person.userId) return;
const key = `${group.userMajor}-${person.userId}`;
if (allKeys.includes(key)) {
hasDuplicate = true;
ElMessage.error(`${roleName}中存在重复的「专业+人员」组合,请检查`);
}
allKeys.push(key);
});
});
};
// 校验设计人员
collectKeys(form.designers, '设计人员');
if (hasDuplicate) return;
// 清空临时数组,校验校审人员(不校验设计与校审之间)
allKeys.length = 0;
collectKeys(form.reviewers, '校审人员');
if (hasDuplicate) return;
// 3. 构建提交数据(适配后端原有数据格式)
const submitData = {
projectId: form.projectId,
personnel: [
// 设计负责人
{
userId: form.designLeader,
userType: 'designLeader',
userMajor: null
},
// 设计人员:展开专业分组,每个人员单独作为一条数据
...form.designers.flatMap((group) =>
group.persons.map((person) => ({
userId: person.userId,
userType: 'designer',
userMajor: group.userMajor
}))
),
// 校审人员:展开专业分组,每个人员单独作为一条数据
...form.reviewers.flatMap((group) =>
group.persons.map((person) => ({
userId: person.userId,
userType: 'reviewer',
userMajor: group.userMajor
}))
)
]
};
// 4. 数据处理(保持原有逻辑不变)
const arr = [];
userList.value.forEach((item) => {
submitData.personnel.forEach((item1) => {
if (item1.userId == item.userId) {
let userType = 1;
if (item1.userType == 'designer') userType = 2;
else if (item1.userType == 'reviewer') userType = 3;
arr.push({
userName: item.nickName,
projectId: submitData.projectId,
userId: item1.userId,
userType: userType,
userMajor: item1.userMajor
});
}
});
});
// 5. 提交到后端(保持原有逻辑不变)
const loading = ElLoading.service({ text: '提交中...', background: 'rgba(255,255,255,0.7)' });
const res = await designUserAdd({
list: arr,
projectId: currentProject.value?.id
});
if (res.code == 200) {
disabledForm.value = true;
loading.close();
ElMessage.success('提交成功');
} else {
ElMessage.error(res.msg || '提交失败');
}
} catch (error) {
ElMessage.error('请完善表单信息后再提交');
} finally {
// ElLoading.service().close();
}
};
/** 重置表单(适配新数据结构) */
const resetForm = () => {
if (leaveFormRef.value) {
leaveFormRef.value.resetFields();
// 重置为默认空状态1个专业分组每组1个空人员
form.designers = [createEmptyMajorGroup()];
form.reviewers = [createEmptyMajorGroup()];
ElMessage.info('表单已重置');
}
};
// 监听项目ID刷新数据
const listeningProject: WatchStopHandle = watch(
() => currentProject.value?.id,
() => {
getDeptAllUser(userStore.deptId).then(() => {
designUser();
});
}
);
// 页面生命周期
onUnmounted(() => {
listeningProject();
});
onMounted(() => {
getDeptAllUser(userStore.deptId).then(() => {
designUser();
});
});
</script>
<style lang="scss" scoped>
.appointment {
width: 70vw;
max-width: 1600px;
.el-select__wrapper {
width: 100% !important;
}
.el-button--small {
margin-bottom: 0;
}
.fonts {
.el-form-item--default .el-form-item__label {
font-size: 18px !important;
}
}
}
// 自定义动画
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fadeIn {
animation: fadeIn 0.3s ease-out forwards;
}
// 表单样式优化
::v-deep .el-form {
--el-form-item-margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 0;
&__label {
font-weight: 500;
color: #4e5969;
}
&__content {
padding: 0;
}
}
::v-deep .el-select {
width: 100%;
.el-input__inner {
border-radius: 6px;
transition: all 0.3s ease;
}
&:hover .el-input__inner {
border-color: #66b1ff;
}
&.el-select-focus .el-input__inner {
border-color: #409eff;
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}
}
::v-deep .el-button {
border-radius: 6px;
padding: 8px 16px;
&--primary {
background-color: #409eff;
border-color: #409eff;
&:hover {
background-color: #66b1ff;
border-color: #66b1ff;
}
}
&--success {
background-color: #67c23a;
border-color: #67c23a;
&:hover {
background-color: #85ce61;
border-color: #85ce61;
}
&:disabled {
background-color: #b3e099;
border-color: #b3e099;
}
}
&--danger {
background-color: #f56c6c;
border-color: #f56c6c;
&:hover {
background-color: #f78989;
border-color: #f78989;
}
&:disabled {
background-color: #ffcccc;
border-color: #ffbbbb;
cursor: not-allowed;
}
}
&--text {
color: #f56c6c;
&:hover {
color: #f78989;
background-color: rgba(245, 108, 108, 0.05);
}
}
}
// 响应式网格布局
.grid {
display: grid;
}
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.md\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.gap-4 {
gap: 1rem;
}
// 适配小屏幕小于768px时垂直排列
@media (max-width: 768px) {
.appWidth {
width: 95vw;
}
::v-deep .el-form {
padding: 4px;
}
::v-deep .el-form-item__label {
width: 100px;
}
// 小屏幕下各列上下间距
::v-deep .el-col-xs-24 + .el-col-xs-24 {
margin-top: 12px;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@
<el-table-column label="卷册号" align="center" prop="volumeNo" width="150" /> <el-table-column label="卷册号" align="center" prop="volumeNo" width="150" />
<el-table-column label="流程状态" align="center"> <el-table-column label="流程状态" align="center">
<template #default="scope"> <template #default="scope">
<dict-tag v-if="scope.row.fileId != null" :options="wf_business_status" :value="scope.row.status" /> <dict-tag v-if="scope.row.costEstimation > 0" :options="wf_business_status" :value="scope.row.status" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="变更文件" align="center" width="150"> <el-table-column label="变更文件" align="center" width="150">
@ -64,19 +64,16 @@
<dict-tag :options="design_change_reason_type" :value="scope.row.changeReason ? scope.row.changeReason.split(',') : []" /> <dict-tag :options="design_change_reason_type" :value="scope.row.changeReason ? scope.row.changeReason.split(',') : []" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="图纸状态" align="center">
<template #default="scope">
<dict-tag v-if="scope.row.fileId != null" :options="wf_business_status" :value="scope.row.auditStatus" />
</template>
</el-table-column>
<el-table-column label="变更内容" align="center" prop="changeContent" width="150" /> <el-table-column label="变更内容" align="center" prop="changeContent" width="150" />
<el-table-column label="创建时间" align="center" prop="createTime" width="150" /> <el-table-column label="创建时间" align="center" prop="createTime" width="150" />
<el-table-column label="备注" align="center" prop="remark" width="200" /> <el-table-column label="备注" align="center" prop="remark" width="200" />
<el-table-column label="操作" align="center" fixed="right" width="300"> <el-table-column label="操作" align="center" fixed="right" width="300">
<template #default="scope"> <template #default="scope">
<el-button
type="primary"
link
icon="Upload"
@click="handleAddChange(scope.row)"
v-if="(scope.row.status == 'finish' || scope.row.costEstimation == '0') && scope.row.auditStatus == 'draft'"
>上传</el-button
>
<el-button <el-button
type="success" type="success"
link link
@ -86,8 +83,31 @@
@click="handleViewInfo(scope.row)" @click="handleViewInfo(scope.row)"
>查看</el-button >查看</el-button
> >
<el-button type="success" link icon="View" v-hasPermi="['design:designChange:query']" @click="handleViewDetail(scope.row)" <el-button
>通知单</el-button type="primary"
v-if="scope.row.status == 'draft' && scope.row.costEstimation > 0"
link
icon="plus"
v-hasPermi="['design:designChange:query']"
@click="handleViewUpdate(scope.row)"
>审核通知单</el-button
>
<el-button
v-if="scope.row.status != 'draft'"
type="success"
link
icon="View"
v-hasPermi="['design:designChange:query']"
@click="handleViewDetail(scope.row)"
>查看通知单</el-button
>
<el-button
type="primary"
link
icon="Upload"
@click="handleAddChange(scope.row)"
v-if="(scope.row.status == 'finish' || scope.row.costEstimation == '0') && scope.row.auditStatus == 'draft'"
>上传图纸</el-button
> >
<el-button <el-button
type="warning" type="warning"
@ -210,6 +230,17 @@ const handleAdd = () => {
}); });
}; };
/** 查看详情 */ /** 查看详情 */
const handleViewUpdate = (row) => {
proxy.$tab.closePage(proxy.$route);
proxy.$router.push({
path: `/approval/designChange/indexEdit`,
query: {
id: row.id,
type: 'update'
}
});
};
/** 查看详情 */
const handleViewDetail = (row) => { const handleViewDetail = (row) => {
proxy.$tab.closePage(proxy.$route); proxy.$tab.closePage(proxy.$route);
proxy.$router.push({ proxy.$router.push({

View File

@ -145,7 +145,7 @@
></el-col> ></el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="费用" prop="costEstimation"> <el-form-item label="费用" prop="costEstimation">
<el-input v-model="form.costEstimation" type="number" placeholder="请输入费用" /> </el-form-item <el-input min="0" v-model="form.costEstimation" type="number" placeholder="请输入费用" /> </el-form-item
></el-col> ></el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="变更费用估算表" label-width="110px" prop="costEstimationFile"> <el-form-item label="变更费用估算表" label-width="110px" prop="costEstimationFile">
@ -348,8 +348,11 @@ const getInfo = () => {
loading.value = true; loading.value = true;
buttonLoading.value = false; buttonLoading.value = false;
nextTick(async () => { nextTick(async () => {
const res = await getDesignChange(routeParams.value.id); let id = routeParams.value.id.split('_')[0];
const res = await getDesignChange(id);
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
console.log(form.value);
if (form.value.changeReason.length > 0) { if (form.value.changeReason.length > 0) {
form.value.changeReason = form.value.changeReason.split(','); form.value.changeReason = form.value.changeReason.split(',');
} }
@ -374,24 +377,26 @@ const submitForm = (status1: string) => {
if (form.value.saveFile && form.value.saveFile.length > 0) { if (form.value.saveFile && form.value.saveFile.length > 0) {
saveFile = form.value.saveFile.join(','); saveFile = form.value.saveFile.join(',');
} }
} leaveFormRef.value?.validate(async (valid: boolean) => {
leaveFormRef.value?.validate(async (valid: boolean) => { if (valid) {
if (valid) { buttonLoading.value = true;
buttonLoading.value = true; var res;
var res; res = await addDesignChange({ ...form.value, changeReason, saveFile }).finally(() => (buttonLoading.value = false));
res = await addDesignChange({ ...form.value, changeReason, saveFile }).finally(() => (buttonLoading.value = false)); if (res.code == 200) {
if (res.code == 200) { if (form.value.costEstimation == '0') {
if (form.value.costEstimation == '0') { ElMessage.success('通知成功');
ElMessage.success('通知成功'); goBack();
goBack(); } else {
submit(status.value, res.data);
}
} else { } else {
submit(status.value, res.data); ElMessage.error(res.msg);
} }
} else {
ElMessage.error(res.msg);
} }
} });
}); } else {
submit(status.value, form.value);
}
}; };
const submitFlow = async () => { const submitFlow = async () => {
@ -429,14 +434,15 @@ const submitCallback = async () => {
}; };
//审批 //审批
const approvalVerifyOpen = async () => { const approvalVerifyOpen = async () => {
submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId); // submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId);
// submitVerifyRef.value.openDialog(routeParams.value.taskId); submitVerifyRef.value.openDialog(routeParams.value.taskId);
}; };
// 图纸上传成功之后 开始提交 // 图纸上传成功之后 开始提交
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const submit = async (status, data) => { const submit = async (status, data) => {
form.value = data; form.value = data;
form.value.id = form.value.id + '_audit';
if (status === 'draft') { if (status === 'draft') {
buttonLoading.value = false; buttonLoading.value = false;
proxy?.$modal.msgSuccess('暂存成功'); proxy?.$modal.msgSuccess('暂存成功');

View File

@ -36,7 +36,7 @@
</div> </div>
</el-card> </el-card>
<!-- 提交组件 --> <!-- 提交组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> <submitVerify ref="submitVerifyRef" :businessId1="form.id" :task-variables="taskVariables" @submit-callback="submitCallback" />
<approvalRecord ref="approvalRecordRef"></approvalRecord> <approvalRecord ref="approvalRecordRef"></approvalRecord>
<!-- 流程选择对话框 --> <!-- 流程选择对话框 -->
<el-dialog <el-dialog
@ -253,13 +253,16 @@ const submitCallback = async () => {
}; };
//审批 //审批
const approvalVerifyOpen = async () => { const approvalVerifyOpen = async () => {
submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId); // 判断是否还需要设计验证
// submitVerifyRef.value.openDialog(routeParams.value.taskId); if (form.value.isWindow) {
submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId);
} else {
submitVerifyRef.value.openDialog(routeParams.value.taskId);
}
}; };
// 图纸上传成功之后 开始提交 // 图纸上传成功之后 开始提交
const submit = async (status, data) => { const submit = async (status, data) => {
form.value = data; form.value = data;
form.value.id = routeParams.value.type == 'add' ? form.value.id + '_' : form.value.id.split('_')[0];
form.value.status = data.auditStatus ? data.auditStatus : data.status; form.value.status = data.auditStatus ? data.auditStatus : data.status;
if (status === 'draft') { if (status === 'draft') {
buttonLoading.value = false; buttonLoading.value = false;

View File

@ -11,12 +11,17 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="编号" prop="num"> <el-form-item label="编号" prop="num">
<!-- prop="num" 需与 rules 中键名一致 --> <!-- prop="num" 需与 rules 中键名一致 -->
<el-input v-model="formData.num" placeholder="请输入编号" /> <el-input v-model="formData.num" disabled placeholder="请输入编号" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="专业" prop="professional"> <el-form-item label="专业" prop="professionalName">
<el-input v-model="formData.professional" placeholder="请输入专业" /> <el-input v-model="formData.professionalName" disabled placeholder="请输入专业" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="卷册" prop="volume">
<el-input v-model="formData.volume" disabled placeholder="请输入卷册" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -24,14 +29,8 @@
<el-input v-model="formData.stage" placeholder="请输入设计阶段" /> <el-input v-model="formData.stage" placeholder="请输入设计阶段" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item label="卷册" prop="volume">
<el-input v-model="formData.volume" placeholder="请输入卷册" />
</el-form-item>
</el-col>
</el-row> </el-row>
</div> </div>
<!-- 项目信息区域 --> <!-- 项目信息区域 -->
<div class="form-section"> <div class="form-section">
<div class="section-title"> <div class="section-title">
@ -54,7 +53,6 @@
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
<!-- 人员信息区域 --> <!-- 人员信息区域 -->
<div class="form-section"> <div class="form-section">
<div class="section-title"> <div class="section-title">
@ -65,56 +63,77 @@
<el-row :gutter="20" class="section-content"> <el-row :gutter="20" class="section-content">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="设计人" prop="designer"> <el-form-item label="设计人" prop="designer">
<el-input v-model="formData.designer" placeholder="请输入设计人" /> <el-input disabled v-model="formData.designerName" placeholder="请输入设计人" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"></el-col> <el-col :span="12"></el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="校审人员" prop="proofreading"> <el-form-item label="校审人员" prop="proofreading">
<el-input v-model="formData.proofreading" placeholder="请输入校审人员" /> <el-input disabled v-model="formData.proofreading" placeholder="请输入校审人员" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col :span="12">
<el-form-item label="校审人员ID" prop="proofreadingId">
<el-input v-model="formData.proofreadingId" placeholder="请输入校审人员ID" />
</el-form-item>
</el-col> -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="校审时间" prop="proofreadingDate"> <el-form-item label="校审时间" prop="proofreadingDate">
<el-date-picker v-model="formData.proofreadingDate" type="date" placeholder="选择校审时间" format="YYYY-MM-DD" <el-date-picker
value-format="YYYY-MM-DD" /> v-model="formData.proofreadingDate"
type="date"
disabled
placeholder="选择校审时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="审核人员" prop="audit"> <el-form-item label="审核人员" prop="audit">
<el-input v-model="formData.audit" placeholder="请输入审核人员" /> <el-input disabled v-model="formData.audit" placeholder="请输入审核人员" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col :span="12">
<el-form-item label="审核人员ID" prop="auditId">
<el-input v-model="formData.auditId" placeholder="请输入审核人员ID" />
</el-form-item>
</el-col> -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="审核时间" prop="auditDate"> <el-form-item label="审核时间" prop="auditDate">
<el-date-picker v-model="formData.auditDate" type="date" placeholder="选择审核时间" format="YYYY-MM-DD" <el-date-picker
value-format="YYYY-MM-DD" /> disabled
v-model="formData.auditDate"
type="date"
placeholder="选择审核时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="审定人员" prop="approve">
<el-input disabled v-model="formData.approve" placeholder="请输入审定人员" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="审定时间" prop="approveDate">
<el-date-picker
disabled
v-model="formData.approveDate"
type="date"
placeholder="选择审定时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="执行人员" prop="executor"> <el-form-item label="执行人员" prop="executor">
<el-input v-model="formData.executor" placeholder="请输入执行人员" /> <el-select
v-model="formData.executorId"
@change="changeExecutor"
placeholder="选择执行人员"
class="w-full transition-all duration-300 border-gray-300"
>
<el-option v-for="item in userList" :key="`user-${item.userId}`" :label="item.userName" :value="item.userId" />
</el-select>
<!-- <el-input v-model="formData.executor" placeholder="请输入执行人员" /> -->
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col :span="12">
<el-form-item label="执行人员ID" prop="executorId">
<el-input v-model="formData.executorId" placeholder="请输入执行人员ID" />
</el-form-item>
</el-col> -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="执行时间" prop="executorDate"> <el-form-item label="执行时间" prop="executorDate">
<el-date-picker v-model="formData.executorDate" type="date" placeholder="选择执行时间" format="YYYY-MM-DD" <el-date-picker v-model="formData.executorDate" type="date" placeholder="选择执行时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
value-format="YYYY-MM-DD" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -151,17 +170,20 @@
<script setup name="ExamineForm" lang="ts"> <script setup name="ExamineForm" lang="ts">
import { ref, watch, reactive } from 'vue'; import { ref, watch, reactive } from 'vue';
import { fillOutTheDesignVerificationForm, drawingreviewReceipts } from '@/api/design/drawingreview'; import { fillOutTheDesignVerificationForm, drawingreviewReceipts } from '@/api/design/drawingreview';
import type { FormInstance, FormRules } from 'element-plus'; import { dayjs, type FormInstance, type FormRules } from 'element-plus';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
import { computed } from 'vue'; import { computed } from 'vue';
import { subProjectListAll } from '@/api/design/drawingreview'; import { subProjectListAll, getDrawingreviewReceipts } from '@/api/design/drawingreview';
import { desUserList } from '@/api/design/appointment';
// 获取用户 store // 获取用户 store
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
const userList = ref([]);
const userMap = new Map();
// 从 store 中获取当前选中的项目 // 从 store 中获取当前选中的项目
const currentProject = computed(() => userStore.selectedProject); const currentProject = computed(() => userStore.selectedProject);
console.log(currentProject.value);
const subProjectList = ref([]); const subProjectList = ref([]);
const Drawingreview = ref({});
let subProjectMap = new Map(); let subProjectMap = new Map();
// 定义表单数据类型 // 定义表单数据类型
interface FormData { interface FormData {
@ -193,9 +215,9 @@ const rules: FormRules = {
num: [{ required: true, message: '请输入编号', trigger: 'blur' }], num: [{ required: true, message: '请输入编号', trigger: 'blur' }],
professional: [{ required: true, message: '请输入专业', trigger: 'blur' }] professional: [{ required: true, message: '请输入专业', trigger: 'blur' }]
}; };
const userName = userStore.nickname;
// 表单数据 - 直接在组件内定义不再通过Props接收 // 表单数据 - 直接在组件内定义不再通过Props接收
const formData = reactive<FormData>({ const formData = ref({
num: '', num: '',
professional: '', professional: '',
stage: '', stage: '',
@ -228,8 +250,8 @@ watch(
(newVal) => { (newVal) => {
if (newVal) { if (newVal) {
// 根据实际项目结构调整赋值字段 // 根据实际项目结构调整赋值字段
formData.projectId = newVal.id || ''; formData.value.projectId = newVal.id || '';
formData.projectName = newVal.name || ''; formData.value.projectName = newVal.name || '';
} }
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
@ -259,12 +281,12 @@ const resetFields = () => {
// 获取表单数据 // 获取表单数据
const getFormData = (): FormData => { const getFormData = (): FormData => {
return { ...formData }; return { ...formData.value };
}; };
// 设置表单数据 // 设置表单数据
const setFormData = (data: Partial<FormData>) => { const setFormData = (data: Partial<FormData>) => {
Object.assign(formData, data); Object.assign(formData.value, data);
}; };
// 提交表单 // 提交表单
@ -279,12 +301,10 @@ const submit = async (businessId, cb) => {
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}); });
formData.subprojectName = subProjectMap.get(formData.subprojectId); formData.value.subprojectName = subProjectMap.get(formData.value.subprojectId);
// formData.drawingreviewId = businessId;
console.log(businessId); console.log(businessId);
// businessId 设置 如果有下滑线去掉后面及下划线 formData.value.drawingreviewId = businessId.replace(/_/g, '');
formData.drawingreviewId = businessId.replace(/_/g, ''); const res = await drawingreviewReceipts(formData.value);
const res = await drawingreviewReceipts(formData);
if (res.code === 200) { if (res.code === 200) {
// 提交成功处理逻辑 // 提交成功处理逻辑
console.log('提交成功'); console.log('提交成功');
@ -292,6 +312,52 @@ const submit = async (businessId, cb) => {
// 关闭 // 关闭
ElLoading.service().close(); ElLoading.service().close();
}; };
// 获取单据
const getInfo = async (id) => {
// 获取单据
console.log(id);
await getDeptAllUser();
let res = await getDrawingreviewReceipts(id);
console.log(res);
formData.value = res.data;
console.log(formData);
// 设计人 名称 designerName iddesigner
// 校审人员 名称 proofreading id: proofreadingId 校审时间 proofreadingDate
// 审定人员 名称 approve idapproveId 审定时间 approveDate
// 审核人员 名称 audit idauditId 审核时间 auditDate
// userStore.nickname //用户名
// userStore.userId //用户id
if (formData.value.approve) {
} else if (formData.value.audit) {
// 说明流程在第三步
formData.value.approve = userStore.nickname;
formData.value.approveId = userStore.userId;
formData.value.approveDate = dayjs().format('YYYY-MM-DD');
} else if (formData.value.proofreading) {
// 说明流程在第二步
formData.value.audit = userStore.nickname;
formData.value.auditId = userStore.userId;
formData.value.auditDate = dayjs().format('YYYY-MM-DD');
} else if (formData.value.designerName) {
// 说明流程在第一步
formData.value.proofreading = userStore.nickname;
formData.value.proofreadingId = userStore.userId;
formData.value.proofreadingDate = dayjs().format('YYYY-MM-DD');
}
};
/** 获取当前设计用户 */
const getDeptAllUser = async () => {
const res = await desUserList({ projectId: currentProject.value?.id, userType: '2' });
userList.value = res.data || [];
for (let i = 0; i < userList.value.length; i++) {
userMap.set(userList.value[i].userId, userList.value[i].userName);
}
};
const changeExecutor = (val) => {
formData.value.executor = userMap.get(val);
formData.value.executorDate = dayjs().format('YYYY-MM-DD');
};
onMounted(() => { onMounted(() => {
getSubProject(); getSubProject();
}); });
@ -301,7 +367,8 @@ defineExpose({
resetFields, resetFields,
getFormData, getFormData,
setFormData, setFormData,
submit submit,
getInfo
}); });
</script> </script>

View File

@ -39,7 +39,7 @@
</div> </div>
</el-card> </el-card>
<!-- 提交组件 --> <!-- 提交组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> <submitVerify ref="submitVerifyRef" :businessId1="form.id" :task-variables="taskVariables" @submit-callback="submitCallback" />
<approvalRecord ref="approvalRecordRef"></approvalRecord> <approvalRecord ref="approvalRecordRef"></approvalRecord>
<!-- 流程选择对话框 --> <!-- 流程选择对话框 -->
<el-dialog <el-dialog
@ -202,8 +202,14 @@ const submitCallback = async () => {
}; };
//审批 //审批
const approvalVerifyOpen = async () => { const approvalVerifyOpen = async () => {
// 图纸评审验证 // 图纸评审验证 判断是否需要设计验证
submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId); if (form.value.isWindow) {
console.log(routeParams.value.businessId);
submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId);
} else {
submitVerifyRef.value.openDialog(routeParams.value.taskId);
}
}; };
const submit = async (status, data) => { const submit = async (status, data) => {
form.value = data; form.value = data;

View File

@ -541,7 +541,6 @@ const onSubmit = async () => {
buttonLoading.value = false; buttonLoading.value = false;
} }
}; };
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: VolumeCatalogVO) => { const handleDelete = async (row?: VolumeCatalogVO) => {
const _ids = row?.design || ids.value; const _ids = row?.design || ids.value;

View File

@ -20,16 +20,12 @@
</div> </div>
<div class="p-6"> <div class="p-6">
<div class="grid grid-cols-1 gap-4"> <div class="grid grid-cols-1 gap-4">
<el-form <el-form ref="leaveFormRef" :model="form" :rules="rules" label-width="100px" class="space-y-4">
ref="leaveFormRef"
:disabled="routeParams.type === 'view' || form.auditStatus == 'waiting'"
:model="form"
:rules="rules"
label-width="100px"
class="space-y-4"
>
<el-form-item label="图纸文件" prop="fileId" class="mb-2 md:col-span-2"> <el-form-item label="图纸文件" prop="fileId" class="mb-2 md:col-span-2">
<el-input v-model="form.fileName" disabled placeholder="图纸名称" /> <!-- <el-input v-model="form.fileName" disabled placeholder="图纸名称" /> -->
<el-link :href="form.fileUrl" target="_blank" type="primary" :underline="false">
{{ form.fileName }}
</el-link>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -199,7 +195,7 @@ const submitCallback = async () => {
//审批 //审批
const approvalVerifyOpen = async () => { const approvalVerifyOpen = async () => {
// 图纸评审验证 // 图纸评审验证
submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId); submitVerifyRef.value.openDialog(routeParams.value.taskId);
}; };
const submit = async (status, data) => { const submit = async (status, data) => {
form.value = data; form.value = data;

View File

@ -56,7 +56,7 @@
<el-table-column label="操作" align="center" min-width="150" fixed="right"> <el-table-column label="操作" align="center" min-width="150" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['materials:materialIssue:query']">查看</el-button> <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['materials:materialIssue:query']">查看</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialIssue:edit']">修改</el-button> <!-- <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialIssue:edit']">修改</el-button> -->
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['materials:materialIssue:remove']" <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['materials:materialIssue:remove']"
>删除</el-button >删除</el-button
> >
@ -130,8 +130,8 @@
:prop="`itemList.${index}.name`" :prop="`itemList.${index}.name`"
:rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]"
> >
<el-select v-model="item.name" placeholder="请选择名称" @change="(value) => getNameChange(value, index, item)"> <el-select v-model="item.inventoryId" placeholder="请选择名称" @change="(value) => getNameChange(value, index, item)">
<el-option v-for="opt in optionsName" :key="opt.id" :label="opt.materialsName" :value="opt.materialsName" /> <el-option v-for="opt in optionsName" :key="opt.id" :label="opt.materialsName" :value="opt.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -141,7 +141,7 @@
:prop="`itemList.${index}.specification`" :prop="`itemList.${index}.specification`"
:rules="[{ required: true, message: '规格不能为空', trigger: 'blur' }]" :rules="[{ required: true, message: '规格不能为空', trigger: 'blur' }]"
> >
<el-input v-model="item.specification" placeholder="请输入规格" /> <el-input disabled v-model="item.specification" placeholder="请输入规格" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -150,10 +150,10 @@
:prop="`itemList.${index}.unit`" :prop="`itemList.${index}.unit`"
:rules="[{ required: true, message: '单位不能为空', trigger: 'blur' }]" :rules="[{ required: true, message: '单位不能为空', trigger: 'blur' }]"
> >
<el-input v-model="item.unit" placeholder="请输入单位" /> <el-input disabled v-model="item.unit" placeholder="请输入单位" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <!-- <el-col :span="12">
<el-form-item <el-form-item
label="库存" label="库存"
:prop="`itemList.${index}.stockQuantity`" :prop="`itemList.${index}.stockQuantity`"
@ -169,29 +169,19 @@
@blur="handleStockChange(index)" @blur="handleStockChange(index)"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="领取" :prop="`itemList.${index}.issuedQuantity`">
label="领取"
:prop="`itemList.${index}.issuedQuantity`"
:rules="[
{ required: true, message: '领取数量不能为空', trigger: 'blur' },
{ type: 'number', min: 0, message: '领取数量不能小于0', trigger: ['blur', 'change'] },
{
validator: (rule, value, callback) => validateIssuedQuantity(rule, value, callback, index),
trigger: ['blur', 'change']
}
]"
>
<el-input <el-input
v-model.number="item.issuedQuantity" v-model.number="item.issuedQuantity"
disabled
placeholder="请输入领取数量" placeholder="请输入领取数量"
@input="handleIssuedChange(index)" @input="handleIssuedChange(index)"
@blur="handleIssuedChange(index)" @blur="handleIssuedChange(index)"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <!-- <el-col :span="12">
<el-form-item <el-form-item
label="剩余" label="剩余"
:prop="`itemList.${index}.remainingQuantity`" :prop="`itemList.${index}.remainingQuantity`"
@ -204,7 +194,7 @@
<el-form-item label="备注" :prop="`itemList.${index}.remark`"> <el-form-item label="备注" :prop="`itemList.${index}.remark`">
<el-input v-model="item.remark" placeholder="请输入内容" /> <el-input v-model="item.remark" placeholder="请输入内容" />
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="12" v-if="form.itemList.length > 1"> <el-col :span="12" v-if="form.itemList.length > 1">
<div class="item-actions"> <div class="item-actions">
<el-button type="danger" link @click="removeItem(index)" icon="Delete">删除</el-button> <el-button type="danger" link @click="removeItem(index)" icon="Delete">删除</el-button>
@ -263,6 +253,7 @@ import {
delMaterialIssue, delMaterialIssue,
addMaterialIssue, addMaterialIssue,
updateMaterialIssue, updateMaterialIssue,
inventoryList,
getMaterialName getMaterialName
} from '@/api/materials/materialIssue'; } from '@/api/materials/materialIssue';
@ -399,7 +390,9 @@ const getList = async () => {
// 获取材料名称列表 // 获取材料名称列表
const getName = async () => { const getName = async () => {
try { try {
const res = await getMaterialName(currentProject.value.id); const res = await inventoryList(currentProject.value.id);
console.log(res);
if (res.code == 200) { if (res.code == 200) {
optionsName.value = res.data; optionsName.value = res.data;
} }
@ -410,14 +403,15 @@ const getName = async () => {
// 材料名称选择变化处理修改select的value为名称而非ID // 材料名称选择变化处理修改select的value为名称而非ID
const getNameChange = (value, index, item) => { const getNameChange = (value, index, item) => {
const selected = optionsName.value.find((opt) => opt.materialsName === value); const selected = optionsName.value.find((opt) => opt.id === value);
if (selected) { if (selected) {
item.name = selected.materialsName; // 直接赋值名称 item.name = selected.materialsName; // 直接赋值名称
item.materialsId = selected.id; // 保留ID用于后端 item.materialsId = selected.id; // 保留ID用于后端
item.specification = selected.typeSpecificationName; item.specification = selected.typeSpecificationName;
item.unit = selected.weightId; item.unit = selected.weightId;
item.issuedQuantity = selected.number;
item.stockQuantity = Number(selected.inventoryNumber) || 0; item.stockQuantity = Number(selected.inventoryNumber) || 0;
calculateRemaining(index); // 计算剩余数量 // calculateRemaining(index); // 计算剩余数量
} }
}; };
@ -504,14 +498,14 @@ const watchItemChanges = (index: number) => {
itemWatchStopFns.value[index](); itemWatchStopFns.value[index]();
} }
// 监听库存和领取数量变化 // // 监听库存和领取数量变化
const stop = watch( // const stop = watch(
() => [form.value.itemList[index].stockQuantity, form.value.itemList[index].issuedQuantity], // () => [form.value.itemList[index].stockQuantity, form.value.itemList[index].issuedQuantity],
() => { // () => {
calculateRemaining(index); // calculateRemaining(index);
}, // },
{ immediate: true } // { immediate: true }
); // );
itemWatchStopFns.value[index] = stop; itemWatchStopFns.value[index] = stop;
}; };

View File

@ -1,8 +1,37 @@
<template> <template>
<div class="p-2"> <div class="p-2 detailbox">
<div class="box1">
<div>
<div>
<span>设计面积</span>
<span>{{ detailInfo.designArea }} </span>
</div>
<el-icon :size="50" color="#3176ff">
<Postcard />
</el-icon>
</div>
<div>
<div>
<span>已流转面积</span>
<span>{{ detailInfo.transferAea }} </span>
</div>
<el-icon :size="50" color="#3176ff">
<Postcard />
</el-icon>
</div>
<div>
<div>
<span>租金</span>
<span>{{ detailInfo.landRent / 1000 }} 万元</span>
</div>
<el-icon :size="50" color="#3176ff">
<Postcard />
</el-icon>
</div>
</div>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]"> <div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover"> <el-card shadow="never">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px"> <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px">
<el-form-item label="对应地块" prop="landBlockId"> <el-form-item label="对应地块" prop="landBlockId">
<el-select v-model="queryParams.landBlockId" clearable placeholder="请选择对应地块"> <el-select v-model="queryParams.landBlockId" clearable placeholder="请选择对应地块">
@ -33,21 +62,6 @@
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landTransferLedger:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landTransferLedger:add']">新增</el-button>
</el-col> </el-col>
<el-col :span="6"></el-col> <el-col :span="6"></el-col>
<el-col :span="1.5">
<el-tag size="large" type="primary"
><span style="font-size: 20px">设计面积{{ detailInfo.designArea }} </span></el-tag
>
</el-col>
<el-col :span="1.5">
<el-tag size="large" type="success"
><span style="font-size: 20px">已流转面积{{ detailInfo.transferAea }} </span></el-tag
>
</el-col>
<el-col :span="1.5">
<el-tag size="large" type="warning"
><span style="font-size: 20px">租金{{ detailInfo.landRent / 1000 }} 万元</span></el-tag
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
</template> </template>
@ -562,3 +576,36 @@ onMounted(() => {
Promise.all([getLandBlockList(), getListLand(), getList()]); Promise.all([getLandBlockList(), getListLand(), getList()]);
}); });
</script> </script>
<style lang="scss">
.detailbox {
width: 100%;
.box1 {
width: 100%;
display: flex;
justify-content: center;
margin: 20px 0;
> div {
width: 300px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 15px;
border: 1px solid #e7e7e7;
margin: 0 20px;
border-radius: 6px;
> div {
display: flex;
flex-direction: column;
> span:first-child {
font-size: 16px;
margin-bottom: 10px;
}
> span:last-child {
font-size: 24px;
/* font-weight: bold; */
}
}
}
}
}
</style>