合并
This commit is contained in:
@ -69,7 +69,8 @@
|
|||||||
"vue-types": "5.1.3",
|
"vue-types": "5.1.3",
|
||||||
"vue3-print-nb": "^0.1.4",
|
"vue3-print-nb": "^0.1.4",
|
||||||
"vue3-scroll-seamless": "^1.0.6",
|
"vue3-scroll-seamless": "^1.0.6",
|
||||||
"vxe-table": "4.5.22"
|
"vxe-table": "4.5.22",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "9.15.0",
|
"@eslint/js": "9.15.0",
|
||||||
|
Binary file not shown.
@ -24,3 +24,11 @@ export const exportWord = (params) => {
|
|||||||
method: 'post'
|
method: 'post'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// 导出模版
|
||||||
|
export const exportExcel = (params) => {
|
||||||
|
return request({
|
||||||
|
url: '/design/collect/exportExcel',
|
||||||
|
method: 'post',
|
||||||
|
params: params
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -127,6 +127,17 @@ export const majorList = (params) => {
|
|||||||
params: params
|
params: params
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 获取人员列表
|
||||||
|
* @param query
|
||||||
|
*/
|
||||||
|
export const copyUserList = (params) => {
|
||||||
|
return request({
|
||||||
|
url: '/design/volumeCatalog/copyUserList',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
});
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 获取二维码信息
|
* 获取二维码信息
|
||||||
* @param query
|
* @param query
|
||||||
|
@ -75,3 +75,11 @@ export const inventoryList = (id: any) => {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//获取材料表信息
|
||||||
|
export const getMaterialInfo = (id: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/materials/materials/listByFormCode/' + id,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -195,3 +195,35 @@ export const changeProject = (id: string | number) => {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 打卡规则
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const attendanceRuleEdit = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/project/attendanceRule',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 打卡规则
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const attendanceRuleAdd = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/project/attendanceRule',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取规则
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const byProjectIdDetail = (id) => {
|
||||||
|
return request({
|
||||||
|
url: '/project/attendanceRule/byProjectId/' + id,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -71,7 +71,7 @@ export function getRoleList(deptId?: number | string): AxiosPromise<any[]> {
|
|||||||
url: '/system/role/listNoPage',
|
url: '/system/role/listNoPage',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: {
|
params: {
|
||||||
deptId
|
deptId,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ import { ProjectTeamVO } from '@/api/project/projectTeam/types';
|
|||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
export const getProjectTeam = async () => {
|
export const getProjectTeam = async () => {
|
||||||
const isPermission = useUserStore().permissions.some((item) => item == 'project:team:list');
|
const isPermission = useUserStore().permissions.some((item) => item == 'project:team:list');
|
||||||
console.log(useUserStore().permissions);
|
|
||||||
|
|
||||||
if (!isPermission && useUserStore().permissions[0] != '*:*:*') return;
|
if (!isPermission && useUserStore().permissions[0] != '*:*:*') return;
|
||||||
|
|
||||||
const { id } = $cache.local.getJSON('selectedProject');
|
const { id } = $cache.local.getJSON('selectedProject');
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<el-form :model="queryForm" :inline="true">
|
<el-form :model="queryForm" :inline="true">
|
||||||
<el-form-item label="版本号" prop="versions">
|
<el-form-item label="版本号" prop="versions">
|
||||||
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
|
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
|
||||||
<el-option v-for="item in options" :key="item.id" :label="item.versions" :value="item.id" />
|
<el-option v-for="item in options" :key="item.id" :label="item.versions" :value="item.versions" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="表名" prop="sheet">
|
<el-form-item label="表名" prop="sheet">
|
||||||
@ -166,7 +166,8 @@ const getTableData = async () => {
|
|||||||
const params = {
|
const params = {
|
||||||
projectId: currentProject.value?.id,
|
projectId: currentProject.value?.id,
|
||||||
sheet: queryForm.value.sheet,
|
sheet: queryForm.value.sheet,
|
||||||
versions: queryForm.value.versions
|
versions: queryForm.value.versions,
|
||||||
|
type: '1'
|
||||||
};
|
};
|
||||||
const res = await getTreeLimit(params);
|
const res = await getTreeLimit(params);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
@ -210,7 +210,8 @@ const getListTable = async () => {
|
|||||||
const res = await getTreeLimit({
|
const res = await getTreeLimit({
|
||||||
projectId: currentProject.value?.id,
|
projectId: currentProject.value?.id,
|
||||||
versions: form.value.versions,
|
versions: form.value.versions,
|
||||||
sheet: form.value.sheet
|
sheet: form.value.sheet,
|
||||||
|
type: '0'
|
||||||
});
|
});
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
tableData.value = res.data;
|
tableData.value = res.data;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<el-form :model="queryForm" :inline="true">
|
<el-form :model="queryForm" :inline="true">
|
||||||
<el-form-item label="版本号" prop="versions">
|
<el-form-item label="版本号" prop="versions">
|
||||||
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
|
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
|
||||||
<el-option v-for="item in options" :key="item.id" :label="item.versions" :value="item.id" />
|
<el-option v-for="item in options" :key="item.id" :label="item.versions" :value="item.versions" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="表名" prop="sheet">
|
<el-form-item label="表名" prop="sheet">
|
||||||
@ -184,7 +184,8 @@ const getTableData = async () => {
|
|||||||
const params = {
|
const params = {
|
||||||
projectId: currentProject.value?.id,
|
projectId: currentProject.value?.id,
|
||||||
sheet: queryForm.value.sheet,
|
sheet: queryForm.value.sheet,
|
||||||
versions: queryForm.value.versions
|
versions: queryForm.value.versions,
|
||||||
|
type: '0'
|
||||||
};
|
};
|
||||||
const res = await getTreeLimit(params);
|
const res = await getTreeLimit(params);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@ -288,7 +289,7 @@ const handleExport = () => {
|
|||||||
projectId: currentProject.value?.id,
|
projectId: currentProject.value?.id,
|
||||||
sheet: queryForm.value.sheet
|
sheet: queryForm.value.sheet
|
||||||
},
|
},
|
||||||
`限价一览表${queryForm.value.sheet}.xlsx`
|
`投标成本核算${queryForm.value.sheet}.xlsx`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
// 审核
|
// 审核
|
||||||
|
@ -138,9 +138,14 @@
|
|||||||
<el-table-column prop="useQuantity" label="剩余量" align="center">
|
<el-table-column prop="useQuantity" label="剩余量" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{
|
{{
|
||||||
(scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) == 0
|
(scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) ==
|
||||||
|
0
|
||||||
? ''
|
? ''
|
||||||
: (scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
: (scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -149,12 +154,16 @@
|
|||||||
<el-table-column prop="price" label="总价" align="center">
|
<el-table-column prop="price" label="总价" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{
|
{{
|
||||||
((scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)) *
|
((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
|
||||||
Number(scope.row.unitPrice) ==
|
Number(scope.row.unitPrice) ==
|
||||||
0
|
0
|
||||||
? ''
|
? ''
|
||||||
: (
|
: (
|
||||||
((scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)) *
|
((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
|
||||||
Number(scope.row.unitPrice)
|
Number(scope.row.unitPrice)
|
||||||
).toFixed(2)
|
).toFixed(2)
|
||||||
}}
|
}}
|
||||||
@ -328,18 +337,10 @@ const getVersionNums = async () => {
|
|||||||
getSheetName();
|
getSheetName();
|
||||||
} else {
|
} else {
|
||||||
treeForm.value.versions = '';
|
treeForm.value.versions = '';
|
||||||
ElMessage({
|
|
||||||
message: '获取版本号失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
ElMessage({
|
|
||||||
message: '获取版本号失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//获取表名
|
//获取表名
|
||||||
@ -356,19 +357,11 @@ const getSheetName = async () => {
|
|||||||
treeForm.value.sheet = res.data[0];
|
treeForm.value.sheet = res.data[0];
|
||||||
} else {
|
} else {
|
||||||
treeForm.value.sheet = '';
|
treeForm.value.sheet = '';
|
||||||
ElMessage({
|
|
||||||
message: '获取表名失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
getTreeList();
|
getTreeList();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
ElMessage({
|
|
||||||
message: '获取表名失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleSelection = (selection: any) => {
|
const handleSelection = (selection: any) => {
|
||||||
|
@ -124,7 +124,7 @@ const loading = ref(false);
|
|||||||
const options = ref<any[]>([]);
|
const options = ref<any[]>([]);
|
||||||
const sheets = ref<any[]>([]);
|
const sheets = ref<any[]>([]);
|
||||||
const tableData = ref<any[]>([]);
|
const tableData = ref<any[]>([]);
|
||||||
const isExpandAll = ref(false);
|
const isExpandAll = ref(true);
|
||||||
const reviewStatus = ref('');
|
const reviewStatus = ref('');
|
||||||
const versionObj: any = ref({});
|
const versionObj: any = ref({});
|
||||||
const versionMap = new Map();
|
const versionMap = new Map();
|
||||||
@ -150,18 +150,10 @@ const getVersionNums = async () => {
|
|||||||
getSheetName();
|
getSheetName();
|
||||||
} else {
|
} else {
|
||||||
queryForm.value.versions = '';
|
queryForm.value.versions = '';
|
||||||
ElMessage({
|
|
||||||
message: '获取版本号失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
ElMessage({
|
|
||||||
message: '获取版本号失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//选择版本号
|
//选择版本号
|
||||||
@ -193,19 +185,11 @@ const getSheetName = async () => {
|
|||||||
queryForm.value.sheet = res.data[0];
|
queryForm.value.sheet = res.data[0];
|
||||||
} else {
|
} else {
|
||||||
queryForm.value.sheet = '';
|
queryForm.value.sheet = '';
|
||||||
ElMessage({
|
|
||||||
message: '获取表名失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
getTableData();
|
getTableData();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
ElMessage({
|
|
||||||
message: '获取表名失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//获取表格
|
//获取表格
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
>
|
>
|
||||||
<el-row :gutter="8" class="items-top">
|
<el-row :gutter="8" class="items-top">
|
||||||
<!-- 1. 专业选择(核心:统一所有角色的专业来源) -->
|
<!-- 1. 专业选择(核心:统一所有角色的专业来源) -->
|
||||||
<el-col :span="3" class="mb-4 sm:mb-0 pl-4" style="margin-top:8px;">
|
<el-col :span="3" class="mb-4 sm:mb-0 pl-4" style="margin-top: 8px">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:prop="`designers.${configIndex}.userMajor`"
|
:prop="`designers.${configIndex}.userMajor`"
|
||||||
:rules="[
|
:rules="[
|
||||||
@ -76,7 +76,8 @@
|
|||||||
label-width="60px"
|
label-width="60px"
|
||||||
label="专业"
|
label="专业"
|
||||||
>
|
>
|
||||||
<el-select filterable
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="form.designers[configIndex].userMajor"
|
v-model="form.designers[configIndex].userMajor"
|
||||||
placeholder="请选择专业"
|
placeholder="请选择专业"
|
||||||
class="w-full transition-all duration-300 border-gray-300"
|
class="w-full transition-all duration-300 border-gray-300"
|
||||||
@ -109,7 +110,8 @@
|
|||||||
label="设计"
|
label="设计"
|
||||||
label-width="50px"
|
label-width="50px"
|
||||||
>
|
>
|
||||||
<el-select filterable
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="person.userId"
|
v-model="person.userId"
|
||||||
placeholder="选择人员"
|
placeholder="选择人员"
|
||||||
class="w-full transition-all duration-300 border-gray-300"
|
class="w-full transition-all duration-300 border-gray-300"
|
||||||
@ -165,7 +167,8 @@
|
|||||||
label="校审"
|
label="校审"
|
||||||
label-width="50px"
|
label-width="50px"
|
||||||
>
|
>
|
||||||
<el-select filterable
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="person.userId"
|
v-model="person.userId"
|
||||||
placeholder="选择人员"
|
placeholder="选择人员"
|
||||||
class="w-full transition-all duration-300 border-gray-300"
|
class="w-full transition-all duration-300 border-gray-300"
|
||||||
@ -221,7 +224,8 @@
|
|||||||
label="审定"
|
label="审定"
|
||||||
label-width="50px"
|
label-width="50px"
|
||||||
>
|
>
|
||||||
<el-select filterable
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="person.userId"
|
v-model="person.userId"
|
||||||
placeholder="选择人员"
|
placeholder="选择人员"
|
||||||
class="w-full transition-all duration-300 border-gray-300"
|
class="w-full transition-all duration-300 border-gray-300"
|
||||||
@ -277,7 +281,8 @@
|
|||||||
label="审核"
|
label="审核"
|
||||||
label-width="50px"
|
label-width="50px"
|
||||||
>
|
>
|
||||||
<el-select filterable
|
<el-select
|
||||||
|
filterable
|
||||||
v-model="person.userId"
|
v-model="person.userId"
|
||||||
placeholder="选择人员"
|
placeholder="选择人员"
|
||||||
class="w-full transition-all duration-300 border-gray-300"
|
class="w-full transition-all duration-300 border-gray-300"
|
||||||
@ -318,7 +323,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 操作列 -->
|
<!-- 操作列 -->
|
||||||
<el-col :span="2" class="text-right pr-4">
|
<el-col :span="2" class="pr-4 mt-2 text-right">
|
||||||
<el-button
|
<el-button
|
||||||
type="text"
|
type="text"
|
||||||
class="text-red-500 hover:text-red-700 transition-colors"
|
class="text-red-500 hover:text-red-700 transition-colors"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<el-card v-if="index < 3" shadow="always">
|
<el-card v-if="index < 3" shadow="always">
|
||||||
<el-form :model="state.queryForm" :inline="true">
|
<el-form :model="state.queryForm" :inline="true">
|
||||||
<el-form-item label="版本号" prop="versions">
|
<el-form-item label="版本号" prop="versions">
|
||||||
<el-select v-model="state.queryForm.versions" placeholder="选择版本号">
|
<el-select v-model="state.queryForm.versions" placeholder="选择版本号" @change="handleChangeVersion">
|
||||||
<el-option v-for="item in state.options" :key="item.versions" :label="item.versions" :value="item.versions" />
|
<el-option v-for="item in state.options" :key="item.versions" :label="item.versions" :value="item.versions" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="openTable(index)">{{ isExpandAll ? '一键收起' : '一键展开' }}</el-button>
|
<el-button type="primary" @click="openTable(index)">{{ isExpandAll ? '一键收起' : '一键展开' }}</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" @click="downloadTemplate(1)">下载模板</el-button>
|
<el-button type="success" @click="downloadTemplate(1)">下载模板</el-button>
|
||||||
@ -62,15 +62,10 @@
|
|||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="state.versionsData.status == 'draft'">
|
<el-form-item v-if="state.versionsData.status == 'draft'">
|
||||||
<el-button type="primary" con="edit" @click="clickApprovalSheet()">审核</el-button>
|
<el-button type="primary" con="edit" @click="clickApprovalSheet()">审核</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="state.versionsData.status == 'waiting' || state.versionsData.status == 'finish'">
|
<el-form-item v-if="state.versionsData.status == 'waiting' || state.versionsData.status == 'finish'">
|
||||||
<el-button
|
<el-button icon="view" @click="lookApprovalFlow()" type="warning">查看流程</el-button>
|
||||||
icon="view"
|
|
||||||
@click="lookApprovalFlow()"
|
|
||||||
type="warning"
|
|
||||||
>查看流程</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -171,6 +166,7 @@ const handleTabChange = (tab) => {
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getVersionNums();
|
await getVersionNums();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取版本号
|
// 获取版本号
|
||||||
async function getVersionNums(isSheet = true) {
|
async function getVersionNums(isSheet = true) {
|
||||||
try {
|
try {
|
||||||
@ -247,10 +243,10 @@ async function handleSheetName() {
|
|||||||
|
|
||||||
// 获取列表
|
// 获取列表
|
||||||
async function handleQueryList(isSheet = true) {
|
async function handleQueryList(isSheet = true) {
|
||||||
if (isSheet && !state.queryForm.sheet) {
|
// if (isSheet && !state.queryForm) {
|
||||||
console.warn('表名不存在,无法获取列表数据');
|
// console.warn('表名不存在,无法获取列表数据');
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
state.loading.list = true;
|
state.loading.list = true;
|
||||||
@ -308,12 +304,12 @@ function handleChange(sheet) {
|
|||||||
function handleChangeVersion(versions) {
|
function handleChangeVersion(versions) {
|
||||||
state.queryForm.versions = versions;
|
state.queryForm.versions = versions;
|
||||||
state.versionsData = state.options.find((e) => e.versions == versions);
|
state.versionsData = state.options.find((e) => e.versions == versions);
|
||||||
console.log('state.versionsData', state.versionsData);
|
// console.log('state.versionsData', state.versionsData);
|
||||||
state.sheets = [];
|
state.sheets = [];
|
||||||
handleQueryList();
|
handleQueryList();
|
||||||
}
|
}
|
||||||
// 在 openTable 方法中通过索引获取对应的表格实例
|
// 在 openTable 方法中通过索引获取对应的表格实例
|
||||||
function openTable( index) {
|
function openTable(index) {
|
||||||
isExpandAll.value = !isExpandAll.value;
|
isExpandAll.value = !isExpandAll.value;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 通过索引获取当前标签页的表格实例
|
// 通过索引获取当前标签页的表格实例
|
||||||
@ -358,12 +354,12 @@ function lookApprovalFlow(row) {
|
|||||||
const downloadTemplate = (type) => {
|
const downloadTemplate = (type) => {
|
||||||
// 导出模版文件
|
// 导出模版文件
|
||||||
try {
|
try {
|
||||||
let linkurl = '';
|
let linkurl = '';
|
||||||
let name = '';
|
let name = '';
|
||||||
if (type==1) {
|
if (type == 1) {
|
||||||
linkurl = '/billOfQuantities.xlsx';
|
linkurl = '/billOfQuantities.xlsx';
|
||||||
name = '工程量清单模板.xlsx';
|
name = '工程量清单模板.xlsx';
|
||||||
}else{
|
} else {
|
||||||
linkurl = '/materialsEquipment.xlsx';
|
linkurl = '/materialsEquipment.xlsx';
|
||||||
name = '物资设备清单模板.xlsx';
|
name = '物资设备清单模板.xlsx';
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
<el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden">
|
<el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden">
|
||||||
<div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100">
|
<div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100">
|
||||||
<h3 class="text-lg font-semibold text-gray-800">投标工程清单</h3>
|
<h3 class="text-lg font-semibold text-gray-800">招标工程清单</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-6">
|
<div class="p-6">
|
||||||
<el-form
|
<el-form
|
||||||
|
@ -49,7 +49,32 @@
|
|||||||
<!-- 资料文件区域 -->
|
<!-- 资料文件区域 -->
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<div class="flex items-center justify-between mb-5">
|
<div class="flex items-center justify-between mb-5">
|
||||||
<h3 class="text-lg font-semibold text-blue-700">资料文件清单</h3>
|
<div style="display: flex; align-items: center">
|
||||||
|
<h3 class="text-lg font-semibold text-blue-700" style="margin-right: 20px">资料文件清单</h3>
|
||||||
|
<el-upload
|
||||||
|
class="upload-excel"
|
||||||
|
action="#"
|
||||||
|
v-if="!form.id || form.status == 'draft'"
|
||||||
|
ref="uploadRef"
|
||||||
|
:auto-upload="false"
|
||||||
|
:on-change="importTemplate"
|
||||||
|
:show-file-list="false"
|
||||||
|
:accept="'.xlsx,.xls'"
|
||||||
|
:limit="1"
|
||||||
|
>
|
||||||
|
<el-button type="primary" icon="Upload">导入文件</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<el-button
|
||||||
|
v-if="!form.id || form.status == 'draft'"
|
||||||
|
type="primary"
|
||||||
|
style="margin-left: 20px"
|
||||||
|
icon="Download"
|
||||||
|
@click="exportTemplate"
|
||||||
|
class="transition-all hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
导出模版
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
<el-button type="primary" size="small" @click="addDocumentItem" v-if="!disabledAll" icon="Plus" class="transition-all hover:bg-blue-600">
|
<el-button type="primary" size="small" @click="addDocumentItem" v-if="!disabledAll" icon="Plus" class="transition-all hover:bg-blue-600">
|
||||||
添加资料
|
添加资料
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -180,11 +205,11 @@ import { ref, reactive, computed, onMounted, onUnmounted, watch, getCurrentInsta
|
|||||||
import { useUserStoreHook } from '@/store/modules/user';
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
import { ElMessage, ElLoading, FormRules } from 'element-plus';
|
import { ElMessage, ElLoading, FormRules } from 'element-plus';
|
||||||
import { systemUserList } from '@/api/design/appointment';
|
import { systemUserList } from '@/api/design/appointment';
|
||||||
import { collectBatch, byProjectId, exportWord } from '@/api/design/received';
|
import { collectBatch, byProjectId, exportWord, exportExcel } from '@/api/design/received';
|
||||||
import { getUser } from '@/api/system/user';
|
import { getUser } from '@/api/system/user';
|
||||||
import type { ComponentInternalInstance, ElFormInstance } from 'element-plus';
|
import type { ComponentInternalInstance, ElFormInstance } from 'element-plus';
|
||||||
import { getInfo } from '@/api/login';
|
import { getInfo } from '@/api/login';
|
||||||
|
import * as XLSX from 'xlsx';
|
||||||
// 全局实例与状态管理
|
// 全局实例与状态管理
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const userStore = useUserStoreHook();
|
const userStore = useUserStoreHook();
|
||||||
@ -200,7 +225,7 @@ const documentsFormRef = ref<ElFormInstance>();
|
|||||||
const userList = ref<any[]>([]);
|
const userList = ref<any[]>([]);
|
||||||
const userMap = new Map<string, string>(); // 存储用户ID与昵称映射
|
const userMap = new Map<string, string>(); // 存储用户ID与昵称映射
|
||||||
const disabledAll = ref(false); // 表单是否全部禁用
|
const disabledAll = ref(false); // 表单是否全部禁用
|
||||||
|
const uploadRef = ref<any>();
|
||||||
// 表单核心数据
|
// 表单核心数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
projectId: currentProject.value?.id,
|
projectId: currentProject.value?.id,
|
||||||
@ -445,7 +470,66 @@ const onLoad = async () => {
|
|||||||
console.error('文件导出错误:', error);
|
console.error('文件导出错误:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const exportTemplate = async () => {
|
||||||
|
// 导出模版
|
||||||
|
proxy?.download(
|
||||||
|
'design/collect/exportExcel',
|
||||||
|
{
|
||||||
|
deptId: userStore.deptId
|
||||||
|
},
|
||||||
|
`收资清单表格.xlsx`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const importTemplate = async (files, fileList) => {
|
||||||
|
// 导入表格数据
|
||||||
|
const file = fileList[0].raw; // 获取原始文件对象
|
||||||
|
const reader = new FileReader();
|
||||||
|
let obj = {
|
||||||
|
id: '编码',
|
||||||
|
name: '人员',
|
||||||
|
fliename: '目录名',
|
||||||
|
remark: '备注'
|
||||||
|
};
|
||||||
|
reader.onload = (e) => {
|
||||||
|
try {
|
||||||
|
// 读取文件内容
|
||||||
|
const data = new Uint8Array(e.target.result);
|
||||||
|
// 解析Excel
|
||||||
|
const workbook = XLSX.read(data, { type: 'array' });
|
||||||
|
|
||||||
|
// 获取第一个工作表名称
|
||||||
|
const firstSheetName = workbook.SheetNames[0];
|
||||||
|
// 获取第一个工作表内容
|
||||||
|
const worksheet = workbook.Sheets[firstSheetName];
|
||||||
|
|
||||||
|
// 转换为JSON格式
|
||||||
|
const jsonData = XLSX.utils.sheet_to_json(worksheet);
|
||||||
|
|
||||||
|
if (jsonData.length === 0) {
|
||||||
|
ElMessage.info('Excel文件中没有数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let arr = [];
|
||||||
|
// 判断form.documents 是否对象
|
||||||
|
jsonData.forEach((item, index) => {
|
||||||
|
if (item[obj.id]) {
|
||||||
|
arr.push({
|
||||||
|
id: Date.now() + index,
|
||||||
|
catalogueName: item[obj.fliename],
|
||||||
|
remark: item[obj.remark],
|
||||||
|
userId: item[obj.id]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
form.documents = arr;
|
||||||
|
uploadRef.value.clearFiles();
|
||||||
|
console.log(arr);
|
||||||
|
} catch (err) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 以ArrayBuffer方式读取文件
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
};
|
||||||
/** 页面挂载初始化 */
|
/** 页面挂载初始化 */
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 先获取当前用户信息,再获取部门用户列表,最后回显表单数据
|
// 先获取当前用户信息,再获取部门用户列表,最后回显表单数据
|
||||||
|
@ -153,6 +153,11 @@
|
|||||||
<el-form-item v-if="uploadForm.type == '3'" label="蓝图" prop="fileIds">
|
<el-form-item v-if="uploadForm.type == '3'" label="蓝图" prop="fileIds">
|
||||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.fileIds"></file-upload>
|
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.fileIds"></file-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item v-if="uploadForm.type == '3'" label="抄送人">
|
||||||
|
<el-select multiple filterable clearable v-model="form.userIds" placeholder="请选择抄送人">
|
||||||
|
<el-option :value="item.userId" v-for="item in userCoryList" :key="item.userId" :label="item.nickName + '-' + item.phonenumber" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item v-if="uploadForm.type == '1'" label="过程图纸" prop="cancellationIds">
|
<el-form-item v-if="uploadForm.type == '1'" label="过程图纸" prop="cancellationIds">
|
||||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.cancellationIds"></file-upload>
|
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.cancellationIds"></file-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -255,7 +260,8 @@ import {
|
|||||||
uploadVolumeFile,
|
uploadVolumeFile,
|
||||||
majorList,
|
majorList,
|
||||||
getVolumeCatafileList,
|
getVolumeCatafileList,
|
||||||
volumeFileList
|
volumeFileList,
|
||||||
|
copyUserList
|
||||||
} from '@/api/design/volumeCatalog';
|
} from '@/api/design/volumeCatalog';
|
||||||
import { VolumeCatalogVO } from '@/api/design/volumeCatalog/types';
|
import { VolumeCatalogVO } from '@/api/design/volumeCatalog/types';
|
||||||
import { useUserStoreHook } from '@/store/modules/user';
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
@ -281,6 +287,7 @@ const uploadOpinionVisible = ref(false);
|
|||||||
const design = ref('');
|
const design = ref('');
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const dialogHistory = ref(false);
|
const dialogHistory = ref(false);
|
||||||
|
const userCoryList = ref([]);
|
||||||
const opinion = ref('');
|
const opinion = ref('');
|
||||||
const updateRow = ref({
|
const updateRow = ref({
|
||||||
opinion: []
|
opinion: []
|
||||||
@ -416,7 +423,13 @@ const cancel = () => {
|
|||||||
reset();
|
reset();
|
||||||
dialog.visible = false;
|
dialog.visible = false;
|
||||||
};
|
};
|
||||||
|
// 获取人员列表
|
||||||
|
const getDesignUserList = async () => {
|
||||||
|
const res = await copyUserList({ projectId: currentProject.value?.id, userType: 2 });
|
||||||
|
if (res.code === 200) {
|
||||||
|
userCoryList.value = res.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
/** 表单重置 */
|
/** 表单重置 */
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
form.value = { ...initFormData };
|
form.value = { ...initFormData };
|
||||||
@ -546,7 +559,7 @@ const onSubmit = async () => {
|
|||||||
type: uploadForm.type
|
type: uploadForm.type
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
await uploadVolumeFile(obj);
|
await uploadVolumeFile({ ...obj, userIds: form.value.userIds });
|
||||||
proxy?.$modal.msgSuccess('文件上传成功');
|
proxy?.$modal.msgSuccess('文件上传成功');
|
||||||
uploadVisible.value = false;
|
uploadVisible.value = false;
|
||||||
await getList();
|
await getList();
|
||||||
@ -656,6 +669,7 @@ const handleAuditInfo = (row) => {
|
|||||||
// 审核图纸
|
// 审核图纸
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
getDesignUserList();
|
||||||
getSpecialtyList();
|
getSpecialtyList();
|
||||||
getList();
|
getList();
|
||||||
});
|
});
|
||||||
@ -666,6 +680,7 @@ const listeningProject = watch(
|
|||||||
(nid, oid) => {
|
(nid, oid) => {
|
||||||
queryParams.value.projectId = nid;
|
queryParams.value.projectId = nid;
|
||||||
form.value.projectId = nid;
|
form.value.projectId = nid;
|
||||||
|
getDesignUserList();
|
||||||
getSpecialtyList();
|
getSpecialtyList();
|
||||||
getList();
|
getList();
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
<el-table v-loading="loading" :data="formalitiesAreConsolidatedList" @selection-change="handleSelectionChange" row-key="id" default-expand-all>
|
<el-table v-loading="loading" :data="formalitiesAreConsolidatedList" @selection-change="handleSelectionChange" row-key="id" default-expand-all>
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<!-- <el-table-column label="手续办理清单模板父级" align="center" prop="formalitiesPname" /> -->
|
<!-- <el-table-column label="手续办理清单模板父级" align="center" prop="formalitiesPname" /> -->
|
||||||
<el-table-column label="手续办理清单" align="center" prop="formalitiesName" />
|
<el-table-column label="手续办理清单" align="left" prop="formalitiesName" />
|
||||||
<el-table-column label="计划开始时间" align="center" prop="planTheStartTime" width="180">
|
<el-table-column label="计划开始时间" align="center" prop="planTheStartTime" width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>{{ parseTime(scope.row.planTheStartTime, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.planTheStartTime, '{y}-{m}-{d}') }}</span>
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
: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="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="auto">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="auto">
|
||||||
<el-form-item label="材料名称" prop="materialsName">
|
<el-form-item label="材料名称" prop="materialsName">
|
||||||
<el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable
|
<el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable @keyup.enter="handleQuery" />
|
||||||
@keyup.enter="handleQuery" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="材料提供商" prop="companyId">
|
<el-form-item label="材料提供商" prop="companyId">
|
||||||
<el-select v-model="queryParams.companyId" clearable placeholder="全部">
|
<el-select v-model="queryParams.companyId" clearable placeholder="全部">
|
||||||
@ -27,22 +25,20 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['materials:materials:add']"> 新增
|
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['materials:materials:add']"> 新增 </el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['materials:materials:edit']"
|
||||||
|
>修改
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
|
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['materials:materials:remove']"
|
||||||
v-hasPermi="['materials:materials:edit']">修改
|
>删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['materials:materials:export']">导出 </el-button>
|
||||||
v-hasPermi="['materials:materials:remove']">删除
|
|
||||||
</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button type="warning" plain icon="Download" @click="handleExport"
|
|
||||||
v-hasPermi="['materials:materials:export']">导出 </el-button>
|
|
||||||
</el-col>
|
</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>
|
||||||
@ -72,25 +68,28 @@
|
|||||||
<el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="320">
|
<el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="320">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-space>
|
<el-space>
|
||||||
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)"
|
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)" v-hasPermi="['materials:materials:query']">
|
||||||
v-hasPermi="['materials:materials:query']">
|
|
||||||
详情
|
详情
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)"
|
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materials:edit']"> 修改 </el-button>
|
||||||
v-hasPermi="['materials:materials:edit']"> 修改 </el-button>
|
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['materials:materials:remove']">
|
||||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)"
|
|
||||||
v-hasPermi="['materials:materials:remove']">
|
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-hasPermi="['materials:materialsInventory:edit']" link type="primary" icon="Plus"
|
<el-button
|
||||||
@click="handleAddMaterialsInventory(scope.row)"> 出入库 </el-button>
|
v-hasPermi="['materials:materialsInventory:edit']"
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
icon="Plus"
|
||||||
|
@click="handleAddMaterialsInventory(scope.row)"
|
||||||
|
>
|
||||||
|
出入库
|
||||||
|
</el-button>
|
||||||
</el-space>
|
</el-space>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 添加或修改材料名称对话框 -->
|
<!-- 添加或修改材料名称对话框 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||||
@ -121,12 +120,17 @@
|
|||||||
<el-form-item label="材料文件" prop="fileOssIdMap">
|
<el-form-item label="材料文件" prop="fileOssIdMap">
|
||||||
<div :key="item.value" v-for="item in materials_file_type">
|
<div :key="item.value" v-for="item in materials_file_type">
|
||||||
<h3>{{ item.label }}</h3>
|
<h3>{{ item.label }}</h3>
|
||||||
<file-upload v-model="ossIdMap[item.value]" :limit="1" :file-size="50" :file-type="['pdf']"
|
<file-upload
|
||||||
|
v-model="ossIdMap[item.value]"
|
||||||
|
:limit="1"
|
||||||
|
:file-size="50"
|
||||||
|
:file-type="['pdf']"
|
||||||
@update:model-value="
|
@update:model-value="
|
||||||
(args) => {
|
(args) => {
|
||||||
handleOssUpdate(args, item.value);
|
handleOssUpdate(args, item.value);
|
||||||
}
|
}
|
||||||
" />
|
"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -137,8 +141,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<materials-inventory-add-dialog :materials-id="currentMaterialsId" :project-id="currentProject.id" ref="dialogRef"
|
<materials-inventory-add-dialog :materials-id="currentMaterialsId" :project-id="currentProject.id" ref="dialogRef" @submit="getList" />
|
||||||
@submit="getList" />
|
|
||||||
<el-dialog title="材料详情" v-model="showDetailDrawer" width="700px">
|
<el-dialog title="材料详情" v-model="showDetailDrawer" width="700px">
|
||||||
<materials-detail-drawer :materials-id="currentMaterialsId" />
|
<materials-detail-drawer :materials-id="currentMaterialsId" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
@ -73,7 +73,10 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="表单编号" prop="formCode">
|
<el-form-item label="表单编号" prop="formCode">
|
||||||
<el-input v-model="form.formCode" placeholder="请输入表单编号" />
|
<!-- <el-input v-model="form.formCode" placeholder="请输入表单编号" /> -->
|
||||||
|
<el-select v-model="form.formCode" placeholder="请选择表单编号" @change="(value) => formCodeChange(value)">
|
||||||
|
<el-option v-for="item in options" :key="item.formCode" :label="item.formCode" :value="item.formCode" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@ -123,11 +126,11 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="名称"
|
label="名称"
|
||||||
:prop="`itemList.${index}.name`"
|
:prop="`itemList.${index}.materialsId`"
|
||||||
:rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]"
|
:rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]"
|
||||||
>
|
>
|
||||||
<el-select v-model="item.inventoryId" placeholder="请选择名称" @change="(value) => getNameChange(value, index, item)">
|
<el-select v-model="item.materialsId" placeholder="请选择名称" @change="(value) => getNameChange(value, index, item)">
|
||||||
<el-option v-for="opt in optionsName" :key="opt.id" :label="opt.materialsName" :value="opt.id" />
|
<el-option v-for="opt in optionsName" :key="opt.id" :label="`${opt.materialsName}_${opt.createTime}`" :value="opt.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -168,13 +171,9 @@
|
|||||||
</el-col> -->
|
</el-col> -->
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="领取" :prop="`itemList.${index}.issuedQuantity`">
|
<el-form-item label="领取" :prop="`itemList.${index}.issuedQuantity`">
|
||||||
<el-input
|
<el-select v-model="item.issuedQuantity" placeholder="请选择数量">
|
||||||
v-model.number="item.issuedQuantity"
|
<el-option v-for="opt in item.outList" :key="opt.id" :label="opt.number" :value="opt.number" />
|
||||||
disabled
|
</el-select>
|
||||||
placeholder="请输入领取数量"
|
|
||||||
@input="handleIssuedChange(index)"
|
|
||||||
@blur="handleIssuedChange(index)"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="12">
|
<!-- <el-col :span="12">
|
||||||
@ -247,7 +246,8 @@ import {
|
|||||||
addMaterialIssue,
|
addMaterialIssue,
|
||||||
updateMaterialIssue,
|
updateMaterialIssue,
|
||||||
inventoryList,
|
inventoryList,
|
||||||
getMaterialName
|
getMaterialName,
|
||||||
|
getMaterialInfo
|
||||||
} from '@/api/materials/materialIssue';
|
} from '@/api/materials/materialIssue';
|
||||||
|
|
||||||
import { MaterialIssueVO, MaterialIssueQuery, MaterialIssueForm } from '@/api/materials/materialIssue/types';
|
import { MaterialIssueVO, MaterialIssueQuery, MaterialIssueForm } from '@/api/materials/materialIssue/types';
|
||||||
@ -307,6 +307,7 @@ const getInitFormData = () => {
|
|||||||
itemList: [
|
itemList: [
|
||||||
{
|
{
|
||||||
id: undefined,
|
id: undefined,
|
||||||
|
|
||||||
specification: undefined,
|
specification: undefined,
|
||||||
unit: undefined,
|
unit: undefined,
|
||||||
stockQuantity: undefined,
|
stockQuantity: undefined,
|
||||||
@ -314,7 +315,8 @@ const getInitFormData = () => {
|
|||||||
remainingQuantity: undefined,
|
remainingQuantity: undefined,
|
||||||
name: undefined, // 数量验收的名称
|
name: undefined, // 数量验收的名称
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
materialsId: undefined
|
materialsId: undefined,
|
||||||
|
outList: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -365,7 +367,7 @@ const computeMaterialName = () => {
|
|||||||
.map((item) => item.name.trim())
|
.map((item) => item.name.trim())
|
||||||
.filter((name, index, self) => self.indexOf(name) === index); // 去重(如需保留重复则删除这行)
|
.filter((name, index, self) => self.indexOf(name) === index); // 去重(如需保留重复则删除这行)
|
||||||
|
|
||||||
form.value.materialName = validNames.join(',');
|
// form.value.materialName = validNames.join(',');
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 查询物料领料单列表 */
|
/** 查询物料领料单列表 */
|
||||||
@ -404,6 +406,7 @@ const getNameChange = (value, index, item) => {
|
|||||||
item.unit = selected.weightId;
|
item.unit = selected.weightId;
|
||||||
item.issuedQuantity = selected.number;
|
item.issuedQuantity = selected.number;
|
||||||
item.stockQuantity = Number(selected.inventoryNumber) || 0;
|
item.stockQuantity = Number(selected.inventoryNumber) || 0;
|
||||||
|
item.outList = selected.outList || [];
|
||||||
// calculateRemaining(index); // 计算剩余数量
|
// calculateRemaining(index); // 计算剩余数量
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -529,8 +532,27 @@ const handleAdd = () => {
|
|||||||
dialog.title = '添加物料领料单';
|
dialog.title = '添加物料领料单';
|
||||||
// 新增时初始计算材料名称
|
// 新增时初始计算材料名称
|
||||||
computeMaterialName();
|
computeMaterialName();
|
||||||
|
getFormData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const options = ref([]);
|
||||||
|
//新增获取表单数据
|
||||||
|
const getFormData = async () => {
|
||||||
|
const res = await getMaterialInfo(currentProject.value.id);
|
||||||
|
if (res.code == 200) {
|
||||||
|
options.value = res.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const formCodeChange = (value) => {
|
||||||
|
console.log(value);
|
||||||
|
const selected = options.value.find((opt) => opt.formCode === value);
|
||||||
|
if (selected) {
|
||||||
|
form.value.materialName = selected.materialName;
|
||||||
|
form.value.orderingUnit = selected.orderingUnit;
|
||||||
|
form.value.supplierUnit = selected.supplierUnit;
|
||||||
|
optionsName.value = selected.materials;
|
||||||
|
}
|
||||||
|
};
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
const handleUpdate = async (row?: MaterialIssueVO) => {
|
const handleUpdate = async (row?: MaterialIssueVO) => {
|
||||||
reset();
|
reset();
|
||||||
@ -597,6 +619,7 @@ const submitForm = () => {
|
|||||||
remainingQuantity: Number(item.remainingQuantity)
|
remainingQuantity: Number(item.remainingQuantity)
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
console.log('提交数据:', submitData);
|
||||||
|
|
||||||
if (form.value.id) {
|
if (form.value.id) {
|
||||||
await updateMaterialIssue(submitData);
|
await updateMaterialIssue(submitData);
|
||||||
@ -638,10 +661,13 @@ const addItem = () => {
|
|||||||
// 删除数量验收条目
|
// 删除数量验收条目
|
||||||
const removeItem = (index: number) => {
|
const removeItem = (index: number) => {
|
||||||
if (form.value.itemList.length > 1) {
|
if (form.value.itemList.length > 1) {
|
||||||
|
console.log(111111);
|
||||||
|
console.log(itemWatchStopFns.value[index]);
|
||||||
|
|
||||||
// 停止该条目的监听
|
// 停止该条目的监听
|
||||||
if (itemWatchStopFns.value[index]) {
|
// if (itemWatchStopFns.value[index]) {
|
||||||
itemWatchStopFns.value[index]();
|
// itemWatchStopFns.value[index]();
|
||||||
}
|
// }
|
||||||
form.value.itemList.splice(index, 1);
|
form.value.itemList.splice(index, 1);
|
||||||
itemWatchStopFns.value.splice(index, 1);
|
itemWatchStopFns.value.splice(index, 1);
|
||||||
// 删除后重新计算材料名称
|
// 删除后重新计算材料名称
|
||||||
@ -682,7 +708,7 @@ watch(
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
getName();
|
// getName();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听项目id刷新数据
|
// 监听项目id刷新数据
|
||||||
@ -692,7 +718,7 @@ const listeningProject = watch(
|
|||||||
queryParams.value.projectId = nid;
|
queryParams.value.projectId = nid;
|
||||||
form.value.projectId = nid;
|
form.value.projectId = nid;
|
||||||
getList();
|
getList();
|
||||||
getName();
|
// getName();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="2">领料单位</th>
|
<th colspan="2">领料单位</th>
|
||||||
<td class="th-bg" colspan="2">{{ formData.placeholder }}</td>
|
<td class="th-bg" colspan="2">{{ formData.issueUnit }}</td>
|
||||||
<th colspan="2">保管单位</th>
|
<th colspan="2">保管单位</th>
|
||||||
<td class="th-bg" colspan="2">{{ formData.storageUnit }}</td>
|
<td class="th-bg" colspan="2">{{ formData.storageUnit }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
>一键全部保存</el-button
|
>一键全部保存</el-button
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="toggleExpandAll">{{ isExpandAll ? '一键收起' : '一键展开' }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<right-toolbar @queryTable="getMasterDataList"></right-toolbar>
|
<right-toolbar @queryTable="getMasterDataList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -38,6 +41,7 @@
|
|||||||
<el-table
|
<el-table
|
||||||
:data="state.tableData"
|
:data="state.tableData"
|
||||||
v-loading="state.loading.list"
|
v-loading="state.loading.list"
|
||||||
|
ref="tableRef"
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%; margin-bottom: 20px; height: calc(100vh - 230px)"
|
style="width: 100%; margin-bottom: 20px; height: calc(100vh - 230px)"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
@ -264,6 +268,17 @@ const formRules = reactive({
|
|||||||
],
|
],
|
||||||
compileDate: [{ required: true, message: '请选择编制日期', trigger: 'change' }]
|
compileDate: [{ required: true, message: '请选择编制日期', trigger: 'change' }]
|
||||||
});
|
});
|
||||||
|
// 展开状态
|
||||||
|
const isExpandAll = ref(false);
|
||||||
|
const tableRef = ref(null);
|
||||||
|
// 切换展开状态
|
||||||
|
const toggleExpandAll = () => {
|
||||||
|
isExpandAll.value = !isExpandAll.value;
|
||||||
|
console.log(isExpandAll.value);
|
||||||
|
state.tableData.forEach((row) => {
|
||||||
|
tableRef.value.toggleRowExpansion(row, isExpandAll.value);
|
||||||
|
});
|
||||||
|
};
|
||||||
// 获取主表数据
|
// 获取主表数据
|
||||||
async function getMasterDataList() {
|
async function getMasterDataList() {
|
||||||
try {
|
try {
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
<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>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="monthPlanList">
|
<el-table v-loading="loading" :data="monthPlanList">
|
||||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||||
<el-table-column label="计划月份" align="center" prop="planMonth" />
|
<el-table-column label="计划月份" align="center" prop="planMonth" />
|
||||||
@ -82,7 +81,7 @@
|
|||||||
<el-form-item label="计划产值(元)" prop="planValue">
|
<el-form-item label="计划产值(元)" prop="planValue">
|
||||||
<el-input v-model="form.planValue" placeholder="请输入计划产值" type="number" />
|
<el-input v-model="form.planValue" placeholder="请输入计划产值" type="number" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="计划月份(元)" prop="planMonth">
|
<el-form-item label="计划月份" prop="planMonth">
|
||||||
<el-date-picker v-model="form.planMonth" type="month" value-format="YYYY-MM" placeholder="请选择计划月份" />
|
<el-date-picker v-model="form.planMonth" type="month" value-format="YYYY-MM" placeholder="请选择计划月份" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产值类型" prop="valueType">
|
<el-form-item label="产值类型" prop="valueType">
|
||||||
|
@ -175,7 +175,7 @@ const getInfo = () => {
|
|||||||
form.value = res.data as any;
|
form.value = res.data as any;
|
||||||
|
|
||||||
console.log('🚀 ~ getInfo ~ form.value:', form.value[0].projectId);
|
console.log('🚀 ~ getInfo ~ form.value:', form.value[0].projectId);
|
||||||
|
form.value[0].mid = form.value[0].id;
|
||||||
form.value[0].id = form.value[0].projectId + '_' + form.value[0].planMonth;
|
form.value[0].id = form.value[0].projectId + '_' + form.value[0].planMonth;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
buttonLoading.value = false;
|
buttonLoading.value = false;
|
||||||
@ -231,13 +231,15 @@ const approvalVerifyOpen = async () => {
|
|||||||
// 图纸上传成功之后 开始提交
|
// 图纸上传成功之后 开始提交
|
||||||
const submit = async (status, data) => {
|
const submit = async (status, data) => {
|
||||||
form.value = data;
|
form.value = data;
|
||||||
|
console.log(form.value);
|
||||||
|
|
||||||
if (status === 'draft') {
|
if (status === 'draft') {
|
||||||
buttonLoading.value = false;
|
buttonLoading.value = false;
|
||||||
proxy?.$modal.msgSuccess('暂存成功');
|
proxy?.$modal.msgSuccess('暂存成功');
|
||||||
proxy.$tab.closePage(proxy.$route);
|
proxy.$tab.closePage(proxy.$route);
|
||||||
proxy.$router.go(-1);
|
proxy.$router.go(-1);
|
||||||
} else {
|
} else {
|
||||||
const res = await isSubmit(data[1]?.id);
|
const res = await isSubmit(data[0]?.mid);
|
||||||
|
|
||||||
if (!res.data) {
|
if (!res.data) {
|
||||||
proxy?.$modal.msgError('三种计划产值必须填写');
|
proxy?.$modal.msgError('三种计划产值必须填写');
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 地块表单弹窗 -->
|
<!-- 地块表单弹窗 -->
|
||||||
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
<el-dialog draggable :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||||
<el-form ref="landBlockFormRef" :model="form" :rules="rules" label-width="100px">
|
<el-form ref="landBlockFormRef" :model="form" :rules="rules" label-width="100px">
|
||||||
@ -107,20 +108,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 关联方阵弹窗(核心修改区域) -->
|
|
||||||
|
<!-- 关联方阵弹窗(核心修复区域) -->
|
||||||
<el-dialog draggable :title="dialogMatrix.title" v-model="dialogMatrix.visible" width="900px" append-to-body>
|
<el-dialog draggable :title="dialogMatrix.title" v-model="dialogMatrix.visible" width="900px" append-to-body>
|
||||||
<el-button type="primary" plain icon="Plus" @click="addUnitBoItem" style="margin-bottom: 15px">添加</el-button>
|
<el-button type="primary" plain icon="Plus" @click="addUnitBoItem" style="margin-bottom: 15px">添加</el-button>
|
||||||
<!-- 方阵表单:绑定unitBoList的索引,实现动态校验 -->
|
<!-- 修复1:表单模型绑定formM(根模型),确保嵌套字段校验生效 -->
|
||||||
<el-form ref="landBlockFormMatrixRef" :model="formM" label-width="100px">
|
<el-form ref="landBlockFormMatrixRef" :model="formM" label-width="100px">
|
||||||
<el-row v-for="(item, i) of unitBoList" :key="i" class="mb-4">
|
<!-- 修复2:循环formM.unitBoList(而非独立ref),保证数据双向绑定 -->
|
||||||
<!-- 方阵选择:必填校验 -->
|
<el-row v-for="(item, i) of formM.unitBoList" :key="i" class="mb-4">
|
||||||
|
<!-- 方阵选择:修复校验规则(移除min:2,改为min:1,适配单层级选择) -->
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="方阵"
|
label="方阵"
|
||||||
:prop="`unitBoList[${i}].unitProjectId`"
|
:prop="`unitBoList[${i}].unitProjectId`"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true, message: '请选择方阵', trigger: 'change' },
|
{ required: true, message: '请选择方阵', trigger: 'change' },
|
||||||
{ type: 'array', min: 2, message: '请选择完整的方阵层级', trigger: 'change' }
|
{ type: 'array', min: 1, message: '请选择完整的方阵', trigger: 'change' }
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<el-cascader
|
<el-cascader
|
||||||
@ -133,7 +136,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- 所属工区:必填校验 -->
|
<!-- 所属工区:保留原有规则 -->
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="所属工区"
|
label="所属工区"
|
||||||
@ -143,7 +146,7 @@
|
|||||||
<el-input v-model="item.unitProjectArea" placeholder="请输入所属工区" />
|
<el-input v-model="item.unitProjectArea" placeholder="请输入所属工区" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- 方阵状态:必填校验 -->
|
<!-- 方阵状态:保留原有规则 -->
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="方阵状态"
|
label="方阵状态"
|
||||||
@ -153,8 +156,15 @@
|
|||||||
<el-input v-model="item.unitProjectStatus" placeholder="请输入方阵状态" />
|
<el-input v-model="item.unitProjectStatus" placeholder="请输入方阵状态" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<!-- 删除按钮:禁用逻辑优化(至少保留1项) -->
|
||||||
<el-col :span="1" style="margin-left: 15px; display: flex; align-items: flex-end">
|
<el-col :span="1" style="margin-left: 15px; display: flex; align-items: flex-end">
|
||||||
<el-button style="margin-bottom: 18px" type="danger" icon="Delete" @click="removeUnitBoItem(i)"></el-button>
|
<el-button
|
||||||
|
style="margin-bottom: 18px"
|
||||||
|
type="danger"
|
||||||
|
icon="Delete"
|
||||||
|
@click="removeUnitBoItem(i)"
|
||||||
|
:disabled="formM.unitBoList.length <= 1"
|
||||||
|
></el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -181,21 +191,35 @@ import {
|
|||||||
} from '@/api/system/landTransfer/landBlock';
|
} from '@/api/system/landTransfer/landBlock';
|
||||||
import { LandBlockVO, LandBlockQuery, LandBlockForm } from '@/api/system/landTransfer/landBlock/types';
|
import { LandBlockVO, LandBlockQuery, LandBlockForm } from '@/api/system/landTransfer/landBlock/types';
|
||||||
import { useUserStoreHook } from '@/store/modules/user';
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
import { getCurrentInstance, ComponentInternalInstance, onMounted, onUnmounted, watch } from 'vue';
|
import { getCurrentInstance, ComponentInternalInstance, onMounted, onUnmounted, watch, reactive, ref, toRefs, computed } from 'vue';
|
||||||
import { ElFormInstance, ElMessage } from 'element-plus';
|
import { ElFormInstance } from 'element-plus';
|
||||||
|
|
||||||
// 类型定义补充(避免any)
|
// 类型定义补充
|
||||||
interface DialogOption {
|
interface DialogOption {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 方阵级联选择器选项类型
|
||||||
|
interface FangzhenOption {
|
||||||
|
matrixId: string | number;
|
||||||
|
name: string;
|
||||||
|
children?: FangzhenOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方阵表单项类型
|
||||||
interface UnitBoItem {
|
interface UnitBoItem {
|
||||||
unitProjectArea: string;
|
unitProjectArea: string;
|
||||||
unitProjectStatus: string;
|
unitProjectStatus: string;
|
||||||
unitProjectId: (string | number)[]; // 级联选择值(数组)
|
unitProjectId: (string | number)[]; // 级联选择值(数组)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 方阵表单根模型类型(关键:显式声明unitBoList)
|
||||||
|
interface MatrixForm {
|
||||||
|
landId?: string | number; // 关联的地块ID
|
||||||
|
unitBoList: UnitBoItem[]; // 方阵列表
|
||||||
|
}
|
||||||
|
|
||||||
// 基础实例与Store
|
// 基础实例与Store
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const userStore = useUserStoreHook();
|
const userStore = useUserStoreHook();
|
||||||
@ -203,14 +227,17 @@ const currentProject = computed(() => userStore.selectedProject);
|
|||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const landBlockList = ref<LandBlockVO[]>([]);
|
const landBlockList = ref<LandBlockVO[]>([]);
|
||||||
const fangzhenList = ref<any[]>([]); // 方阵列表(实际项目建议定义具体类型)
|
const fangzhenList = ref<FangzhenOption[]>([]);
|
||||||
const buttonLoading = ref(false);
|
const buttonLoading = ref(false);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const showSearch = ref(true);
|
const showSearch = ref(true);
|
||||||
const uploadRef = ref<any>(null); // upload组件ref
|
const uploadRef = ref<any>(null);
|
||||||
|
|
||||||
// 方阵表单数据(核心修改:初始值为空,避免默认填充无效数据)
|
// 方阵表单模型(核心修复:使用reactive并显式声明结构)
|
||||||
const unitBoList = ref<UnitBoItem[]>([{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }]);
|
const formM = reactive<MatrixForm>({
|
||||||
|
landId: undefined,
|
||||||
|
unitBoList: [{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }]
|
||||||
|
});
|
||||||
|
|
||||||
// 表格选择相关
|
// 表格选择相关
|
||||||
const ids = ref<Array<string | number>>([]);
|
const ids = ref<Array<string | number>>([]);
|
||||||
@ -243,7 +270,6 @@ const initFormData: LandBlockForm = {
|
|||||||
// 核心数据(含表单规则)
|
// 核心数据(含表单规则)
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
form: { ...initFormData },
|
form: { ...initFormData },
|
||||||
formM: { landId: undefined }, // 方阵关联表单(仅存地块ID)
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@ -256,7 +282,7 @@ const data = reactive({
|
|||||||
farmerCount: undefined,
|
farmerCount: undefined,
|
||||||
params: {}
|
params: {}
|
||||||
},
|
},
|
||||||
// 地块表单规则(原有规则保留)
|
// 地块表单规则
|
||||||
rules: {
|
rules: {
|
||||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||||
projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }],
|
projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }],
|
||||||
@ -265,7 +291,7 @@ const data = reactive({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { queryParams, form, rules, formM } = toRefs(data);
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
/** 查询地块列表 */
|
/** 查询地块列表 */
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
@ -381,10 +407,10 @@ const getfangzhenList = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
const res = await subMatrix(currentProject.value.id);
|
const res = await subMatrix(currentProject.value.id);
|
||||||
// 处理方阵数据(级联选择需父子结构,此处保留原有逻辑)
|
// 处理方阵数据(级联选择需父子结构)
|
||||||
res.data.forEach((item: any) => {
|
res.data.forEach((item: any) => {
|
||||||
item.children?.forEach((item2: any) => {
|
item.children?.forEach((item2: any) => {
|
||||||
item2.matrixId = `${item2.name}_${item2.matrixId}`; // 拼接名称+ID,便于后续拆分
|
item2.matrixId = `${item2.name}_${item2.matrixId}`;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
fangzhenList.value = res.data;
|
fangzhenList.value = res.data;
|
||||||
@ -395,68 +421,75 @@ const getfangzhenList = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 关联方阵(核心修改:打开弹窗前强制重置表单) */
|
/** 关联方阵 */
|
||||||
const handleView = async (row: LandBlockVO) => {
|
const handleView = async (row: LandBlockVO) => {
|
||||||
if (!row?.id) return proxy?.$modal.msgWarning('请选择有效的地块');
|
if (!row?.id) return proxy?.$modal.msgWarning('请选择有效的地块');
|
||||||
|
|
||||||
// 1. 重置方阵表单(清空历史数据)
|
// 重置方阵表单
|
||||||
resetMatrix();
|
resetMatrix();
|
||||||
// 2. 绑定当前地块ID
|
// 绑定当前地块ID
|
||||||
formM.value.landId = row.id;
|
formM.landId = row.id;
|
||||||
// 3. 打开弹窗
|
// 打开弹窗
|
||||||
dialogMatrix.visible = true;
|
dialogMatrix.visible = true;
|
||||||
|
|
||||||
dialogMatrix.title = `关联方阵(地块:${row.landName || row.landCode})`;
|
dialogMatrix.title = `关联方阵(地块:${row.landName || row.landCode})`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 新增方阵表单项 */
|
/** 新增方阵表单项 */
|
||||||
const addUnitBoItem = () => {
|
const addUnitBoItem = () => {
|
||||||
unitBoList.value.push({
|
formM.unitBoList.push({
|
||||||
unitProjectArea: '',
|
unitProjectArea: '',
|
||||||
unitProjectStatus: '',
|
unitProjectStatus: '',
|
||||||
unitProjectId: [] // 级联选择初始为空数组
|
unitProjectId: []
|
||||||
});
|
});
|
||||||
|
// 重置校验状态
|
||||||
|
landBlockFormMatrixRef.value?.clearValidate();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 删除方阵表单项 */
|
/** 删除方阵表单项 */
|
||||||
const removeUnitBoItem = (index: number) => {
|
const removeUnitBoItem = (index: number) => {
|
||||||
if (unitBoList.value.length <= 1) {
|
if (formM.unitBoList.length <= 1) {
|
||||||
return proxy?.$modal.msgWarning('至少保留一项方阵配置');
|
return proxy?.$modal.msgWarning('至少保留一项方阵配置');
|
||||||
}
|
}
|
||||||
unitBoList.value.splice(index, 1);
|
formM.unitBoList.splice(index, 1);
|
||||||
// 重置表单校验状态(避免删除后残留校验提示)
|
|
||||||
landBlockFormMatrixRef.value?.clearValidate();
|
landBlockFormMatrixRef.value?.clearValidate();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 提交方阵关联表单 */
|
/** 提交方阵关联表单(核心修复:数据处理逻辑) */
|
||||||
const submitFormMatrix = () => {
|
const submitFormMatrix = () => {
|
||||||
landBlockFormMatrixRef.value?.validate(async (valid: boolean) => {
|
landBlockFormMatrixRef.value?.validate(async (valid: boolean) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (!formM.value.landId) return proxy?.$modal.msgWarning('地块ID异常,请重新选择地块');
|
if (!formM.landId) return proxy?.$modal.msgWarning('地块ID异常,请重新选择地块');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 处理方阵数据(拆分名称+ID)
|
// 处理方阵数据(修复ID拆分逻辑)
|
||||||
const unitBoListParams = unitBoList.value.map((item) => {
|
const unitBoListParams = formM.unitBoList.map((item) => {
|
||||||
const [unitProjectName, unitProjectId] = item.unitProjectId[1]?.split('_') || [];
|
// 取级联选择的最后一层值
|
||||||
if (!unitProjectId) throw new Error('方阵ID解析失败,请重新选择方阵');
|
const lastLevelValue = item.unitProjectId[item.unitProjectId.length - 1];
|
||||||
|
if (!lastLevelValue) throw new Error('请选择完整的方阵');
|
||||||
|
|
||||||
|
// 拆分名称和ID
|
||||||
|
const [unitProjectName, unitProjectId] = String(lastLevelValue).split('_');
|
||||||
|
if (!unitProjectId) throw new Error('方阵ID解析失败,请重新选择');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
unitProjectArea: item.unitProjectArea.trim(),
|
unitProjectArea: item.unitProjectArea.trim(),
|
||||||
unitProjectStatus: item.unitProjectStatus.trim(),
|
unitProjectStatus: item.unitProjectStatus.trim(),
|
||||||
unitProjectId: unitProjectId, // 纯ID(后端需要)
|
unitProjectId: unitProjectId,
|
||||||
unitProjectName: unitProjectName // 名称(可选,用于显示)
|
unitProjectName: unitProjectName
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 调用关联接口
|
// 调用关联接口
|
||||||
const res = await LandUnit({
|
const res = await LandUnit({
|
||||||
landId: formM.value.landId,
|
landId: formM.landId,
|
||||||
unitBoList: unitBoListParams
|
unitBoList: unitBoListParams
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
proxy?.$modal.msgSuccess('关联方阵成功');
|
proxy?.$modal.msgSuccess('关联方阵成功');
|
||||||
dialogMatrix.visible = false;
|
dialogMatrix.visible = false;
|
||||||
await getList(); // 刷新地块列表
|
await getList();
|
||||||
} else {
|
} else {
|
||||||
proxy?.$modal.msgError(res.msg || '关联失败');
|
proxy?.$modal.msgError(res.msg || '关联失败');
|
||||||
}
|
}
|
||||||
@ -472,13 +505,10 @@ const cancelMatrix = () => {
|
|||||||
dialogMatrix.visible = false;
|
dialogMatrix.visible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 方阵表单重置(核心修改:清空所有数据+重置校验) */
|
/** 方阵表单重置 */
|
||||||
const resetMatrix = () => {
|
const resetMatrix = () => {
|
||||||
// 1. 清空地块ID
|
formM.landId = undefined;
|
||||||
formM.value.landId = undefined;
|
formM.unitBoList = [{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }];
|
||||||
// 2. 重置方阵列表(仅保留一个空项)
|
|
||||||
unitBoList.value = [{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }];
|
|
||||||
// 3. 重置表单校验状态
|
|
||||||
if (landBlockFormMatrixRef.value) {
|
if (landBlockFormMatrixRef.value) {
|
||||||
landBlockFormMatrixRef.value.resetFields();
|
landBlockFormMatrixRef.value.resetFields();
|
||||||
landBlockFormMatrixRef.value.clearValidate();
|
landBlockFormMatrixRef.value.clearValidate();
|
||||||
@ -491,11 +521,11 @@ const listeningProject = watch(
|
|||||||
(newId) => {
|
(newId) => {
|
||||||
if (newId) {
|
if (newId) {
|
||||||
queryParams.value.projectId = newId;
|
queryParams.value.projectId = newId;
|
||||||
getfangzhenList(); // 刷新方阵列表
|
getfangzhenList();
|
||||||
getList(); // 刷新地块列表
|
getList();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true } // 初始加载时执行一次
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
/** 导入Excel */
|
/** 导入Excel */
|
||||||
@ -524,36 +554,34 @@ const handleImport = (options: { file: File }) => {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 导出模板 */
|
||||||
const exportFile = () => {
|
const exportFile = () => {
|
||||||
// 导出模版文件
|
|
||||||
try {
|
try {
|
||||||
// 创建a标签
|
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
// 设置PDF文件路径 - 相对于public目录
|
|
||||||
link.href = '/dikuai.xlsx';
|
link.href = '/dikuai.xlsx';
|
||||||
// 设置下载后的文件名
|
|
||||||
link.download = '地块信息导入模版.xlsx';
|
link.download = '地块信息导入模版.xlsx';
|
||||||
// 触发点击
|
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click();
|
link.click();
|
||||||
// 清理
|
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('下载失败,请重试');
|
alert('下载失败,请重试');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 下载导入模板 */
|
/** 下载导入模板 */
|
||||||
const downloadTemplate = () => {
|
const downloadTemplate = () => {
|
||||||
try {
|
try {
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = '/landBlock.xlsx'; // 模板路径(需确保public目录下存在该文件)
|
link.href = '/landBlock.xlsx';
|
||||||
link.download = '地块信息导入模板.xlsx'; // 下载后文件名
|
link.download = '地块信息导入模板.xlsx';
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click(); // 触发下载
|
link.click();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
proxy?.$modal.msgError('模板下载失败,请重试');
|
proxy?.$modal.msgError('模板下载失败,请重试');
|
||||||
} finally {
|
} finally {
|
||||||
document.body.removeChild(link); // 清理DOM
|
const link = document.querySelector('a[download="地块信息导入模板.xlsx"]');
|
||||||
|
if (link) document.body.removeChild(link);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,13 +144,16 @@
|
|||||||
</el-table-column> -->
|
</el-table-column> -->
|
||||||
<el-table-column label="备注" align="center" prop="remark" />
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||||
<el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="400">
|
<el-table-column fixed="right" label="操作" align="center" width="500">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-space>
|
<el-space>
|
||||||
|
<el-button link type="primary" icon="Edit" @click="handleCheckRules(scope.row)" v-hasPermi="['project:attendanceRule:byProjectId']"
|
||||||
|
>打卡规则
|
||||||
|
</el-button>
|
||||||
|
<!-- <el-button link type="primary" icon="Edit" @click="handleScope(scope.row)" v-hasPermi="['project:project:edit']">打卡范围 </el-button> -->
|
||||||
<el-button link type="primary" icon="FolderOpened" @click="handleShowUpload(scope.row)" v-hasPermi="['project:project:edit']"
|
<el-button link type="primary" icon="FolderOpened" @click="handleShowUpload(scope.row)" v-hasPermi="['project:project:edit']"
|
||||||
>导入安全协议书
|
>导入安全协议书
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['project:project:edit']">修改 </el-button>
|
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['project:project:edit']">修改 </el-button>
|
||||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['project:project:remove']">删除 </el-button>
|
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['project:project:remove']">删除 </el-button>
|
||||||
<el-button link type="primary" icon="upload" @click="handleUpload(scope.row)" v-hasPermi="['project:project:saveTenderFile']"
|
<el-button link type="primary" icon="upload" @click="handleUpload(scope.row)" v-hasPermi="['project:project:saveTenderFile']"
|
||||||
@ -160,7 +163,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 添加或修改项目对话框 -->
|
<!-- 添加或修改项目对话框 -->
|
||||||
@ -253,78 +255,6 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<div class="block-box">
|
|
||||||
<div class="">打卡设置</div>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12" :offset="0">
|
|
||||||
<el-form-item label="打卡开始时间" prop="playCardStart" label-width="110px">
|
|
||||||
<!-- <el-time-picker value-format="HH:mm" v-model="form.playCardStart" placeholder="请输入打卡开始时间" /> -->
|
|
||||||
<el-time-select
|
|
||||||
v-model="form.playCardStart"
|
|
||||||
style="width: 100%"
|
|
||||||
class="mr-4"
|
|
||||||
placeholder="请输入打卡开始时间"
|
|
||||||
value-format="HH:mm"
|
|
||||||
start="00:00"
|
|
||||||
step="00:15"
|
|
||||||
end="23:59"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12" :offset="0">
|
|
||||||
<el-form-item label="打卡结束时间" prop="playCardEnd" label-width="110px">
|
|
||||||
<!-- <el-time-picker value-format="HH:mm" v-model="form.playCardEnd" placeholder="请输入打卡结束时间" /> -->
|
|
||||||
<el-time-select
|
|
||||||
v-model="form.playCardEnd"
|
|
||||||
style="width: 100%"
|
|
||||||
:min-time="form.playCardStart"
|
|
||||||
class="mr-4"
|
|
||||||
placeholder="请输入打卡结束时间"
|
|
||||||
value-format="HH:mm"
|
|
||||||
start="00:00"
|
|
||||||
step="00:15"
|
|
||||||
end="23:59"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12" :offset="0">
|
|
||||||
<el-form-item label="打卡类型" prop="playCardStart" label-width="110px">
|
|
||||||
<!-- <el-time-picker value-format="HH:mm" v-model="form.playCardStart" placeholder="请输入打卡开始时间" /> -->
|
|
||||||
<el-time-select
|
|
||||||
v-model="form.playCardStart"
|
|
||||||
style="width: 100%"
|
|
||||||
class="mr-4"
|
|
||||||
placeholder="请输入打卡开始时间"
|
|
||||||
value-format="HH:mm"
|
|
||||||
start="00:00"
|
|
||||||
step="00:15"
|
|
||||||
end="23:59"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12" :offset="0">
|
|
||||||
<el-form-item label="工作日" prop="playCardEnd" label-width="110px">
|
|
||||||
<!-- <el-time-picker value-format="HH:mm" v-model="form.playCardEnd" placeholder="请输入打卡结束时间" /> -->
|
|
||||||
<el-time-select
|
|
||||||
v-model="form.playCardEnd"
|
|
||||||
style="width: 100%"
|
|
||||||
:min-time="form.playCardStart"
|
|
||||||
class="mr-4"
|
|
||||||
placeholder="请输入打卡结束时间"
|
|
||||||
value-format="HH:mm"
|
|
||||||
start="00:00"
|
|
||||||
step="00:15"
|
|
||||||
end="23:59"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<!-- <el-col :span="24" :offset="0">
|
|
||||||
<el-form-item label="安全协议书" prop="securityAgreement">
|
|
||||||
<file-upload v-model="form.securityAgreement" :limit="1" :file-type="['pdf']" :file-size="50" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col> -->
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
@ -342,13 +272,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- //选取项目地址弹窗 -->
|
<!-- //选取项目地址弹窗 -->
|
||||||
<el-dialog v-model="amapStatus" :title="form.projectName + '-获取经纬度'" width="80%">
|
<el-dialog draggable v-model="amapStatus" :title="form.projectName + '-获取经纬度'" width="80%">
|
||||||
<amap height="620px" @setLocation="setPoi"></amap>
|
<amap height="620px" @setLocation="setPoi"></amap>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 选取方阵地址 -->
|
<!-- 选取方阵地址 -->
|
||||||
<el-dialog title="设置方阵" v-model="polygonStatus" width="1400px" :close-on-click-modal="false">
|
<el-dialog draggable title="设置方阵" v-model="polygonStatus" width="1400px" :close-on-click-modal="false">
|
||||||
<open-layers-map
|
<open-layers-map
|
||||||
:project-id="projectId"
|
:project-id="projectId"
|
||||||
:design-id="designId"
|
:design-id="designId"
|
||||||
@ -356,7 +285,7 @@
|
|||||||
@close="polygonStatus = false"
|
@close="polygonStatus = false"
|
||||||
></open-layers-map>
|
></open-layers-map>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog title="添加子项目" v-model="childProjectStatus" width="400">
|
<el-dialog draggable title="添加子项目" v-model="childProjectStatus" width="400">
|
||||||
<span>填写子项目名称</span>
|
<span>填写子项目名称</span>
|
||||||
<el-input v-model="childProjectForm.projectName"></el-input>
|
<el-input v-model="childProjectForm.projectName"></el-input>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -366,7 +295,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog title="上传文件" v-model="fileVisble" width="400">
|
<el-dialog draggable title="上传文件" v-model="fileVisble" width="400">
|
||||||
<file-upload v-model="fileForm.tenderFiles" :limit="10" :file-type="['pdf']" :file-size="50" />
|
<file-upload v-model="fileForm.tenderFiles" :limit="10" :file-type="['pdf']" :file-size="50" />
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
@ -375,6 +304,86 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<el-dialog draggable title="打卡规则" v-model="ruleFlag" width="800">
|
||||||
|
<template #footer>
|
||||||
|
<el-form ref="projectFormRef" :model="form" :rules="rules" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12" :offset="0">
|
||||||
|
<el-form-item label="上班时间" prop="clockInTime">
|
||||||
|
<el-time-select
|
||||||
|
v-model="form.clockInTime"
|
||||||
|
style="width: 100%"
|
||||||
|
class="mr-4"
|
||||||
|
placeholder="请输入打卡开始时间"
|
||||||
|
value-format="HH:mm"
|
||||||
|
start="00:00"
|
||||||
|
step="00:15"
|
||||||
|
end="23:59"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" :offset="0">
|
||||||
|
<el-form-item label="下班时间" prop="clockOutTime">
|
||||||
|
<el-time-select
|
||||||
|
v-model="form.clockOutTime"
|
||||||
|
style="width: 100%"
|
||||||
|
:min-time="form.clockInTime"
|
||||||
|
class="mr-4"
|
||||||
|
placeholder="请输入打卡结束时间"
|
||||||
|
value-format="HH:mm"
|
||||||
|
start="00:00"
|
||||||
|
step="00:15"
|
||||||
|
end="23:59"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24" :offset="0">
|
||||||
|
<el-form-item label="打卡类型" prop="type">
|
||||||
|
<el-radio-group v-model="form.type">
|
||||||
|
<el-radio value="1" size="large">无限制</el-radio>
|
||||||
|
<el-radio value="2" size="large">范围内打卡</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="打卡类型" prop="weekday">
|
||||||
|
<el-checkbox-group v-model="form.weekday" size="small">
|
||||||
|
<el-checkbox label="星期一" value="1" />
|
||||||
|
<el-checkbox label="星期二" value="2" />
|
||||||
|
<el-checkbox label="星期三" value="3" />
|
||||||
|
<el-checkbox label="星期四" value="4" />
|
||||||
|
<el-checkbox label="星期五" value="5" />
|
||||||
|
<el-checkbox label="星期六" value="6" />
|
||||||
|
<el-checkbox label="星期日" value="7" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> </el-row
|
||||||
|
></el-form>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="ruleSubmit"> 提交</el-button>
|
||||||
|
<el-button @click="ruleFlag = false">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<el-dialog draggable title="打卡范围" v-model="ScopeFlag" width="600">
|
||||||
|
<div v-for="(item, i) of punchRangeList" :key="i" class="options_item">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1"> <el-color-picker v-model="item.punchColor" show-alpha /></el-col>
|
||||||
|
<el-col :span="12"> <el-input v-model="item.punchName" placeholder="请输入打卡范围名称" class="ml-8" /></el-col>
|
||||||
|
<el-col :span="10" style="text-align: right; margin-top: 5px">
|
||||||
|
<el-button link type="primary" icon="view">预览</el-button>
|
||||||
|
<el-button link type="primary" icon="plus">添加</el-button>
|
||||||
|
<el-button link type="primary" icon="delete">移除</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="scopeSubmit"> 提交</el-button>
|
||||||
|
<el-button @click="ScopeFlag = false">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -382,14 +391,14 @@
|
|||||||
import {
|
import {
|
||||||
addChildProject,
|
addChildProject,
|
||||||
addProject,
|
addProject,
|
||||||
addProjectFacilities,
|
|
||||||
addProjectPilePoint,
|
|
||||||
addProjectSquare,
|
|
||||||
delProject,
|
delProject,
|
||||||
uploadProjectFile,
|
uploadProjectFile,
|
||||||
getProject,
|
getProject,
|
||||||
listProject,
|
listProject,
|
||||||
updateProject
|
updateProject,
|
||||||
|
attendanceRuleAdd,
|
||||||
|
attendanceRuleEdit,
|
||||||
|
byProjectIdDetail
|
||||||
} from '@/api/project/project';
|
} from '@/api/project/project';
|
||||||
import { ProjectForm, ProjectQuery, ProjectVO, childProjectQuery, locationType } from '@/api/project/project/types';
|
import { ProjectForm, ProjectQuery, ProjectVO, childProjectQuery, locationType } from '@/api/project/project/types';
|
||||||
import amap from '@/components/amap/index.vue';
|
import amap from '@/components/amap/index.vue';
|
||||||
@ -413,6 +422,14 @@ const polygonStatus = ref(false);
|
|||||||
const dxfFile = ref(null);
|
const dxfFile = ref(null);
|
||||||
const projectId = ref<string>('');
|
const projectId = ref<string>('');
|
||||||
const designId = ref<string>('');
|
const designId = ref<string>('');
|
||||||
|
const ruleFlag = ref(false);
|
||||||
|
const ScopeFlag = ref(false);
|
||||||
|
const punchRangeList = ref<any>([
|
||||||
|
{
|
||||||
|
punchName: '',
|
||||||
|
punchColor: '#1983ff'
|
||||||
|
}
|
||||||
|
]);
|
||||||
const childProjectForm = reactive<childProjectQuery>({
|
const childProjectForm = reactive<childProjectQuery>({
|
||||||
projectName: '',
|
projectName: '',
|
||||||
pid: '',
|
pid: '',
|
||||||
@ -432,7 +449,7 @@ const fileForm = ref({
|
|||||||
const jsonData = ref(null);
|
const jsonData = ref(null);
|
||||||
const fullscreenLoading = ref(false);
|
const fullscreenLoading = ref(false);
|
||||||
|
|
||||||
const initFormData: ProjectForm = {
|
const initFormData = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
projectName: undefined,
|
projectName: undefined,
|
||||||
shortName: undefined,
|
shortName: undefined,
|
||||||
@ -451,13 +468,15 @@ const initFormData: ProjectForm = {
|
|||||||
lat: undefined,
|
lat: undefined,
|
||||||
plan: undefined,
|
plan: undefined,
|
||||||
onStreamTime: undefined,
|
onStreamTime: undefined,
|
||||||
playCardStart: undefined,
|
clockInTime: undefined,
|
||||||
playCardEnd: undefined,
|
clockOutTime: undefined,
|
||||||
designTotal: undefined,
|
designTotal: undefined,
|
||||||
securityAgreement: undefined,
|
securityAgreement: undefined,
|
||||||
sort: 0,
|
sort: 0,
|
||||||
showHidden: undefined,
|
showHidden: undefined,
|
||||||
isDelete: undefined
|
isDelete: undefined,
|
||||||
|
type: '1',
|
||||||
|
weekday: []
|
||||||
};
|
};
|
||||||
const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
||||||
form: { ...initFormData },
|
form: { ...initFormData },
|
||||||
@ -480,8 +499,6 @@ const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
|||||||
lat: undefined,
|
lat: undefined,
|
||||||
plan: undefined,
|
plan: undefined,
|
||||||
onStreamTime: undefined,
|
onStreamTime: undefined,
|
||||||
playCardStart: undefined,
|
|
||||||
playCardEnd: undefined,
|
|
||||||
designTotal: undefined,
|
designTotal: undefined,
|
||||||
securityAgreement: undefined,
|
securityAgreement: undefined,
|
||||||
sort: undefined,
|
sort: undefined,
|
||||||
@ -490,8 +507,8 @@ const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
|||||||
params: {}
|
params: {}
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
playCardStart: [{ required: true, message: '打卡开始时间不能为空', trigger: 'blur' }],
|
clockInTime: [{ required: true, message: '打卡开始时间不能为空', trigger: 'blur' }],
|
||||||
playCardEnd: [{ required: true, message: '打卡结束时间不能为空', trigger: 'blur' }],
|
clockOutTime: [{ required: true, message: '打卡结束时间不能为空', trigger: 'blur' }],
|
||||||
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
|
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
|
||||||
shortName: [{ required: true, message: '项目简称不能为空', trigger: 'blur' }],
|
shortName: [{ required: true, message: '项目简称不能为空', trigger: 'blur' }],
|
||||||
principalPhone: [{ required: true, message: '负责人电话不能为空', trigger: 'blur' }],
|
principalPhone: [{ required: true, message: '负责人电话不能为空', trigger: 'blur' }],
|
||||||
@ -692,7 +709,48 @@ const handleSetChild = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleScope = (row) => {
|
||||||
|
// 打卡范围
|
||||||
|
ScopeFlag.value = true;
|
||||||
|
projectId.value = row.id;
|
||||||
|
};
|
||||||
|
const scopeSubmit = () => {
|
||||||
|
// 提交打卡范围
|
||||||
|
};
|
||||||
|
// 添加规则
|
||||||
|
const handleCheckRules = async (row?: ProjectVO) => {
|
||||||
|
reset();
|
||||||
|
const _id = row?.id || ids.value[0];
|
||||||
|
const res = await byProjectIdDetail(_id);
|
||||||
|
if (res.data) {
|
||||||
|
res.data.weekday = res.data.weekday.split(',');
|
||||||
|
Object.assign(form.value, res.data);
|
||||||
|
}
|
||||||
|
projectId.value = row.id;
|
||||||
|
ruleFlag.value = true;
|
||||||
|
};
|
||||||
|
const ruleSubmit = async () => {
|
||||||
|
console.log(form.value);
|
||||||
|
projectFormRef.value?.validate(async (valid: boolean) => {
|
||||||
|
if (valid) {
|
||||||
|
let obj = {
|
||||||
|
weekday: form.value.weekday.join(','),
|
||||||
|
projectId: projectId.value,
|
||||||
|
id: projectId.value,
|
||||||
|
clockInTime: form.value.clockInTime,
|
||||||
|
clockOutTime: form.value.clockOutTime,
|
||||||
|
type: form.value.type
|
||||||
|
};
|
||||||
|
if (form.value.id) {
|
||||||
|
await attendanceRuleEdit(obj);
|
||||||
|
} else {
|
||||||
|
await attendanceRuleAdd(obj);
|
||||||
|
}
|
||||||
|
ruleFlag.value = false;
|
||||||
|
await getList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
const handleExport = () => {
|
const handleExport = () => {
|
||||||
proxy?.download(
|
proxy?.download(
|
||||||
|
258
src/views/system/user/comm/editInfo.vue
Normal file
258
src/views/system/user/comm/editInfo.vue
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-2 editInfo">
|
||||||
|
<el-form label-position="top" ref="userFormRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="用户昵称" prop="nickName">
|
||||||
|
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2"></el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="归属部门" prop="deptId">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="form.deptId"
|
||||||
|
:data="enabledDeptOptions"
|
||||||
|
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||||
|
value-key="id"
|
||||||
|
placeholder="请选择归属部门"
|
||||||
|
check-strictly
|
||||||
|
@change="handleDeptChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="手机号码" prop="phonenumber">
|
||||||
|
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
|
||||||
|
</el-form-item> </el-col
|
||||||
|
><el-col :span="2"></el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
|
||||||
|
<el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" />
|
||||||
|
</el-form-item> </el-col
|
||||||
|
><el-col :span="2"></el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
|
||||||
|
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="用户性别">
|
||||||
|
<el-select v-model="form.sex" placeholder="请选择">
|
||||||
|
<el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item> </el-col
|
||||||
|
><el-col :span="2"></el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="岗位">
|
||||||
|
<el-select v-model="form.postIds" multiple placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in postOptions"
|
||||||
|
:key="item.postId"
|
||||||
|
:label="item.postName"
|
||||||
|
:value="item.postId"
|
||||||
|
:disabled="item.status == '1'"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item> </el-col
|
||||||
|
><el-col :span="2"></el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-radio-group v-model="form.status">
|
||||||
|
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<!-- <div class="box_submit">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel()">取 消</el-button>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="Profile" lang="ts">
|
||||||
|
import api from '@/api/system/user';
|
||||||
|
import { listProject } from '@/api/project/project';
|
||||||
|
import { getProjectByDeptId, getRoleList, optionselect } from '@/api/system/post';
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
|
||||||
|
const enabledDeptOptions = ref([]);
|
||||||
|
const deptOptions = ref([]);
|
||||||
|
const projectOptions = ref<any[]>([]);
|
||||||
|
const postOptions = ref([]);
|
||||||
|
const roleOptions = ref([]);
|
||||||
|
const userFormRef = ref<ElFormInstance>();
|
||||||
|
const initFormData = {
|
||||||
|
userId: undefined,
|
||||||
|
deptId: undefined,
|
||||||
|
userName: '',
|
||||||
|
nickName: undefined,
|
||||||
|
password: '',
|
||||||
|
phonenumber: undefined,
|
||||||
|
email: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
projectRoles: [
|
||||||
|
{
|
||||||
|
projectId: '',
|
||||||
|
roleIds: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status: '0',
|
||||||
|
remark: '',
|
||||||
|
postIds: [],
|
||||||
|
filePath: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const initData = {
|
||||||
|
form: { ...initFormData },
|
||||||
|
rules: {
|
||||||
|
userName: [
|
||||||
|
{ required: true, message: '用户名称不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
min: 2,
|
||||||
|
max: 20,
|
||||||
|
message: '用户名称长度必须介于 2 和 20 之间',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
|
||||||
|
password: [
|
||||||
|
{ required: true, message: '用户密码不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
min: 5,
|
||||||
|
max: 20,
|
||||||
|
message: '用户密码长度必须介于 5 和 20 之间',
|
||||||
|
trigger: 'blur'
|
||||||
|
},
|
||||||
|
{ pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符:< > " \' \\ |', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{
|
||||||
|
type: 'email',
|
||||||
|
message: '请输入正确的邮箱地址',
|
||||||
|
trigger: ['blur', 'change']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
phonenumber: [
|
||||||
|
{ required: true, message: '请输入手机号码', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||||
|
message: '请输入正确的手机号码',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const data = reactive(initData);
|
||||||
|
const { form, rules } = toRefs(data);
|
||||||
|
/** 查询部门下拉树结构 */
|
||||||
|
const getDeptTree = async () => {
|
||||||
|
const res = await api.deptTreeSelect({ isShow: '1' });
|
||||||
|
deptOptions.value = res.data;
|
||||||
|
enabledDeptOptions.value = filterDisabledDept(res.data);
|
||||||
|
const projectList = await listProject();
|
||||||
|
projectOptions.value = projectList.rows;
|
||||||
|
};
|
||||||
|
/** 过滤禁用的部门 */
|
||||||
|
const filterDisabledDept = (deptList) => {
|
||||||
|
return deptList.filter((dept) => {
|
||||||
|
if (dept.disabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dept.children && dept.children.length) {
|
||||||
|
dept.children = filterDisabledDept(dept.children);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async function handleDeptChange(value: number | string) {
|
||||||
|
proxy?.$emit('setDeptId', value);
|
||||||
|
const response = await optionselect(value);
|
||||||
|
const roleList = await getRoleList(value);
|
||||||
|
roleOptions.value = roleList.data;
|
||||||
|
postOptions.value = response.data;
|
||||||
|
form.value.postIds = [];
|
||||||
|
form.value.projectRoles = [
|
||||||
|
{
|
||||||
|
projectId: '',
|
||||||
|
roleIds: []
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitForm = () => {
|
||||||
|
userFormRef.value?.validate(async (valid: boolean) => {
|
||||||
|
if (valid) {
|
||||||
|
form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
|
||||||
|
proxy?.$modal.msgSuccess('操作成功');
|
||||||
|
proxy?.$emit('submit', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancel = () => {
|
||||||
|
proxy?.$emit('close', false);
|
||||||
|
};
|
||||||
|
/** 重置操作表单 */
|
||||||
|
const reset = () => {
|
||||||
|
form.value = { ...initFormData };
|
||||||
|
form.value.projectRoles = [
|
||||||
|
{
|
||||||
|
projectId: '',
|
||||||
|
roleIds: []
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
userFormRef.value?.resetFields();
|
||||||
|
};
|
||||||
|
// 打开弹框调用参数
|
||||||
|
const open = async (row?: any) => {
|
||||||
|
reset();
|
||||||
|
if (row) {
|
||||||
|
// 编辑
|
||||||
|
const { data } = await api.getUser(row.userId);
|
||||||
|
Object.assign(form.value, data.user);
|
||||||
|
postOptions.value = data.posts;
|
||||||
|
roleOptions.value = data.roles;
|
||||||
|
form.value.postIds = data.postIds;
|
||||||
|
form.value.projectRoles = data.projectRoles;
|
||||||
|
form.value.password = '';
|
||||||
|
const roleList = await getRoleList(form.value.deptId);
|
||||||
|
roleOptions.value = roleList.data;
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
const { data } = await api.getUser();
|
||||||
|
postOptions.value = data.posts;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getInfoForm = () => {
|
||||||
|
return form.value;
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getDeptTree();
|
||||||
|
});
|
||||||
|
defineExpose({ open, getInfoForm });
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.editInfo {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
.box_submit {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
477
src/views/system/user/comm/roleInfo.vue
Normal file
477
src/views/system/user/comm/roleInfo.vue
Normal file
@ -0,0 +1,477 @@
|
|||||||
|
<template>
|
||||||
|
<div class="roleInfo">
|
||||||
|
<div class="title_detail">
|
||||||
|
<span>当前选定角色信息预览</span>
|
||||||
|
<div style="margin-top: 10px">
|
||||||
|
<el-table :data="roleList" border height="150">
|
||||||
|
<el-table-column label="所属部门" align="center" prop="deptName" />
|
||||||
|
<el-table-column label="关联项目" align="center" prop="projectName" />
|
||||||
|
<el-table-column label="web端担任角色" align="center" prop="webRoles" />
|
||||||
|
<el-table-column label="APP端担任角色" align="center" prop="appRoles" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="title_detail" style="margin-top: 20px">
|
||||||
|
<span>选择或修改当前角色信息</span>
|
||||||
|
<div style="margin-top: 10px" class="box_detail">
|
||||||
|
<!-- 项目列表选择区 -->
|
||||||
|
<div class="project_list">
|
||||||
|
<span>关联项目模块</span>
|
||||||
|
<div class="project-items">
|
||||||
|
<div
|
||||||
|
v-for="item in projectOptions"
|
||||||
|
:key="item.id"
|
||||||
|
class="project-item"
|
||||||
|
:class="{ 'project-item-selected': isProjectSelected(item.id) }"
|
||||||
|
@click="toggleProjectSelection(item)"
|
||||||
|
>
|
||||||
|
<div class="project-item-content">
|
||||||
|
<el-checkbox v-model="item.checked" :value="item.id" class="project-checkbox" @change="handleProjectCheck(item, $event)" />
|
||||||
|
<span class="project-name">{{ item.projectName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 角色分配区 -->
|
||||||
|
<div class="post_list">
|
||||||
|
<span>关联项目角色分配</span>
|
||||||
|
<div v-if="selectedProjects.length === 0" class="no-selection">请从左侧选择项目进行角色分配</div>
|
||||||
|
<div v-for="(project, index) in selectedProjects" :key="project.id" class="project-role-container">
|
||||||
|
<div class="project-header">
|
||||||
|
<span class="project-title">{{ project.projectName }}</span>
|
||||||
|
<el-button type="text" class="remove-project" @click="removeProject(project.id)"> 移除 </el-button>
|
||||||
|
</div>
|
||||||
|
<div class="role-assignment">
|
||||||
|
<div class="role-group">
|
||||||
|
<label class="role-label">web端角色:</label>
|
||||||
|
<el-checkbox-group v-model="project.webRoles" @change="updateRoleList">
|
||||||
|
<el-checkbox v-for="role in allRoles" :key="role.roleId" :value="role.roleId">
|
||||||
|
{{ role.roleName }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
<div class="role-group">
|
||||||
|
<label class="role-label">APP端角色:</label>
|
||||||
|
<el-checkbox-group v-model="project.appRoles" @change="updateRoleList">
|
||||||
|
<el-checkbox v-for="role in AppRoles" :key="role.roleId" :value="role.roleId">
|
||||||
|
{{ role.roleName }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_submit">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel()">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="RoleProjectManagement" lang="ts">
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance, ComponentInternalInstance, defineExpose, watch } from 'vue';
|
||||||
|
import { ElFormInstance } from 'element-plus';
|
||||||
|
import api from '@/api/system/user';
|
||||||
|
import { listProject } from '@/api/project/project';
|
||||||
|
import { getRoleList } from '@/api/system/post';
|
||||||
|
|
||||||
|
// 类型定义
|
||||||
|
interface Project {
|
||||||
|
id: number | string;
|
||||||
|
projectName: string;
|
||||||
|
checked: boolean;
|
||||||
|
webRoles: string[];
|
||||||
|
appRoles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Role {
|
||||||
|
roleId: number | string;
|
||||||
|
roleName: string;
|
||||||
|
roleSort?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RoleInfo {
|
||||||
|
userNick: string;
|
||||||
|
deptName: string;
|
||||||
|
postName: string;
|
||||||
|
projectName: string;
|
||||||
|
webRoles: string;
|
||||||
|
appRoles: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件实例
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const projectOptions = ref<Project[]>([]);
|
||||||
|
const selectedProjects = ref<Project[]>([]);
|
||||||
|
const allRoles = ref<Role[]>([]); // web端角色
|
||||||
|
const AppRoles = ref<Role[]>([]); // APP端角色
|
||||||
|
const roleList = ref<RoleInfo[]>([]);
|
||||||
|
// 表单初始数据
|
||||||
|
const initFormData = {
|
||||||
|
userId: undefined,
|
||||||
|
deptId: undefined,
|
||||||
|
userName: '',
|
||||||
|
nickName: undefined,
|
||||||
|
password: '',
|
||||||
|
phonenumber: undefined,
|
||||||
|
email: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
projectRoles: [] as Array<{ projectId: number | string; webRoles: string[]; appRoles: string[] }>,
|
||||||
|
status: '0',
|
||||||
|
remark: '',
|
||||||
|
postIds: [],
|
||||||
|
filePath: undefined,
|
||||||
|
deptName: '' // 新增部门名称字段
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
form: { ...initFormData }
|
||||||
|
});
|
||||||
|
const deptName = ref('');
|
||||||
|
const { form } = toRefs(data);
|
||||||
|
|
||||||
|
// 核心方法:更新预览列表
|
||||||
|
const updateRoleList = () => {
|
||||||
|
if (selectedProjects.value.length === 0) {
|
||||||
|
roleList.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
roleList.value = selectedProjects.value.map((project) => {
|
||||||
|
// 处理web端角色名称
|
||||||
|
var webRoleNames = project.webRoles
|
||||||
|
.map((roleId) => {
|
||||||
|
const role = allRoles.value.find((r) => r.roleId === roleId);
|
||||||
|
return role ? role.roleName : '';
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
// 处理APP端角色名称
|
||||||
|
var appRoleNames = project.appRoles
|
||||||
|
.map((roleId) => {
|
||||||
|
const role = AppRoles.value.find((r) => r.roleId === roleId);
|
||||||
|
return role ? role.roleName : '';
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
webRoleNames = [...new Set(webRoleNames)];
|
||||||
|
appRoleNames = [...new Set(appRoleNames)];
|
||||||
|
return {
|
||||||
|
deptName: deptName.value,
|
||||||
|
projectName: project.projectName,
|
||||||
|
webRoles: webRoleNames.length > 0 ? webRoleNames.join(',') : '无',
|
||||||
|
appRoles: appRoleNames.length > 0 ? appRoleNames.join(',') : '无'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听已选项目变化,自动更新预览列表
|
||||||
|
watch(
|
||||||
|
selectedProjects,
|
||||||
|
() => {
|
||||||
|
updateRoleList();
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 检查项目是否被选中
|
||||||
|
const isProjectSelected = (projectId: number | string) => {
|
||||||
|
return selectedProjects.value.some((p) => p.id === projectId);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换项目选择状态
|
||||||
|
const toggleProjectSelection = (project: Project) => {
|
||||||
|
// handleProjectCheck(project, !project.checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理项目勾选状态变化
|
||||||
|
const handleProjectCheck = (project: Project, checked: boolean) => {
|
||||||
|
// project.checked = checked;
|
||||||
|
const index = selectedProjects.value.findIndex((p) => p.id === project.id);
|
||||||
|
|
||||||
|
if (checked && index === -1) {
|
||||||
|
// 添加选中的项目
|
||||||
|
selectedProjects.value.push({
|
||||||
|
...project,
|
||||||
|
webRoles: [],
|
||||||
|
appRoles: []
|
||||||
|
});
|
||||||
|
} else if (!checked && index !== -1) {
|
||||||
|
// 移除取消选中的项目
|
||||||
|
selectedProjects.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 移除项目
|
||||||
|
const removeProject = (projectId: number | string) => {
|
||||||
|
// 更新选中项目列表
|
||||||
|
selectedProjects.value = selectedProjects.value.filter((p) => p.id !== projectId);
|
||||||
|
|
||||||
|
// 更新项目选项的勾选状态
|
||||||
|
const project = projectOptions.value.find((p) => p.id === projectId);
|
||||||
|
if (project) {
|
||||||
|
project.checked = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 整理项目角色数据
|
||||||
|
form.value.projectRoles = selectedProjects.value.map((project) => ({
|
||||||
|
projectId: project.id,
|
||||||
|
roleIds: [...new Set(project.webRoles), ...new Set(project.appRoles)]
|
||||||
|
}));
|
||||||
|
// 提交数据
|
||||||
|
try {
|
||||||
|
if (form.value.userId) {
|
||||||
|
await api.updateUser(form.value);
|
||||||
|
} else {
|
||||||
|
await api.addUser(form.value);
|
||||||
|
}
|
||||||
|
proxy?.$modal.msgSuccess('操作成功');
|
||||||
|
proxy?.$emit('submit', form.value);
|
||||||
|
cancel();
|
||||||
|
} catch (error) {
|
||||||
|
proxy?.$modal.msgError('操作失败,请重试');
|
||||||
|
console.error('提交失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消操作
|
||||||
|
const cancel = () => {
|
||||||
|
resetForm();
|
||||||
|
proxy?.$emit('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
const resetForm = () => {
|
||||||
|
data.form = { ...initFormData };
|
||||||
|
projectOptions.value.forEach((p) => (p.checked = false));
|
||||||
|
selectedProjects.value = [];
|
||||||
|
roleList.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
const initData = async () => {
|
||||||
|
try {
|
||||||
|
// 获取项目列表
|
||||||
|
const projectRes = await listProject();
|
||||||
|
projectOptions.value = projectRes.rows.map((item: any) => ({
|
||||||
|
id: item.id,
|
||||||
|
projectName: item.projectName,
|
||||||
|
checked: false
|
||||||
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
proxy?.$modal.msgError('数据加载失败');
|
||||||
|
console.error('初始化数据失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 打开弹窗时调用
|
||||||
|
const open = async (row?: any, deptId?: any) => {
|
||||||
|
resetForm();
|
||||||
|
await initData();
|
||||||
|
deptName.value = row.deptName;
|
||||||
|
console.log(row);
|
||||||
|
if (row) {
|
||||||
|
try {
|
||||||
|
if (!row.createTime) {
|
||||||
|
form.value = { ...row };
|
||||||
|
// 获取角色列表
|
||||||
|
if (form.value.deptId) {
|
||||||
|
deptId = form.value.deptId;
|
||||||
|
}
|
||||||
|
const roleRes = await getRoleList(deptId);
|
||||||
|
allRoles.value = roleRes.data.filter((item: Role) => item.roleSort === 1);
|
||||||
|
AppRoles.value = roleRes.data.filter((item: Role) => item.roleSort !== 1);
|
||||||
|
} else {
|
||||||
|
const { data } = await api.getUser(row.userId);
|
||||||
|
Object.assign(form.value, data.user);
|
||||||
|
// 获取角色列表
|
||||||
|
if (form.value.deptId) {
|
||||||
|
deptId = form.value.deptId;
|
||||||
|
}
|
||||||
|
const roleRes = await getRoleList(deptId);
|
||||||
|
// 区分web端和app端角色
|
||||||
|
allRoles.value = roleRes.data.filter((item: Role) => item.roleSort === 1);
|
||||||
|
AppRoles.value = roleRes.data.filter((item: Role) => item.roleSort !== 1);
|
||||||
|
// 加载项目角色数据
|
||||||
|
if (data.projectRoles && data.projectRoles.length) {
|
||||||
|
data.projectRoles.forEach((pr: any) => {
|
||||||
|
const project = projectOptions.value.find((p) => p.id === pr.projectId);
|
||||||
|
if (project) {
|
||||||
|
project.checked = true;
|
||||||
|
selectedProjects.value.push({
|
||||||
|
...project,
|
||||||
|
webRoles: pr.roleIds || [],
|
||||||
|
appRoles: pr.roleIds || []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
proxy?.$modal.msgError('加载用户数据失败');
|
||||||
|
console.error('加载用户数据失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({ open });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.roleInfo {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.title_detail {
|
||||||
|
> span {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
display: inline-block;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
border-bottom: 2px solid #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_detail {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
height: 350px;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow-y: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project_list {
|
||||||
|
width: 320px;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.project-items {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-item {
|
||||||
|
padding: 10px 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-color: #e4e7ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-item-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-checkbox {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-name {
|
||||||
|
flex: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-item-selected {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
border-color: #c6e2ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post_list {
|
||||||
|
flex: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.no-selection {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-role-container {
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
|
||||||
|
.project-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.project-title {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-project {
|
||||||
|
color: #f56c6c;
|
||||||
|
padding: 0 5px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #e4393c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.role-assignment {
|
||||||
|
.role-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.role-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 110px;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-checkbox-group {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
|
||||||
|
.el-checkbox {
|
||||||
|
margin-right: 15px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.box_submit {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 0px;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
788
src/views/system/user/index copy.vue
Normal file
788
src/views/system/user/index copy.vue
Normal file
@ -0,0 +1,788 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-2">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<!-- 部门树 -->
|
||||||
|
<el-col :lg="4" :xs="24" style="">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
|
||||||
|
<el-tree
|
||||||
|
ref="deptTreeRef"
|
||||||
|
class="mt-2"
|
||||||
|
node-key="id"
|
||||||
|
:data="deptOptions"
|
||||||
|
:props="{ label: 'label', children: 'children' }"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :lg="20" :xs="24">
|
||||||
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
|
<div v-show="showSearch" class="mb-[10px]">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
|
<el-form-item label="用户名称" prop="userName">
|
||||||
|
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号码" prop="phonenumber">
|
||||||
|
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select v-model="queryParams.status" placeholder="用户状态" clearable>
|
||||||
|
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" style="width: 308px">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery" @v-has-permi="['system:user:query']">搜索</el-button>
|
||||||
|
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<template #header>
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button v-has-permi="['system:user:add']" type="primary" plain icon="Plus" @click="handleAdd()"> 新增 </el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button v-has-permi="['system:user:edit']" type="success" plain :disabled="single" icon="Edit" @click="handleUpdate()">
|
||||||
|
修改
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button v-has-permi="['system:user:remove']" type="danger" plain :disabled="multiple" icon="Delete" @click="handleDelete()">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-dropdown class="mt-[1px]">
|
||||||
|
<el-button plain type="info">
|
||||||
|
更多
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-has-permi="['system:user:import']" icon="Top" @click="handleImport">导入数据 </el-dropdown-item>
|
||||||
|
<el-dropdown-item v-has-permi="['system:user:export']" icon="Download" @click="handleExport"> 导出数据 </el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar v-model:show-search="showSearch" :columns="columns" :search="true" @query-table="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
<el-table-column v-if="columns[0].visible" key="userId" label="用户编号" align="center" prop="userId" />
|
||||||
|
<el-table-column v-if="columns[1].visible" key="userName" label="用户名称" align="center" prop="userName" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column v-if="columns[2].visible" key="nickName" label="用户昵称" align="center" prop="nickName" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column v-if="columns[3].visible" key="deptName" label="部门" align="center" prop="deptName" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column v-if="columns[4].visible" key="phonenumber" label="手机号码" align="center" prop="phonenumber" width="120" />
|
||||||
|
<el-table-column v-if="columns[5].visible" key="status" label="状态" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column v-if="columns[6].visible" label="创建时间" align="center" prop="createTime" width="160">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.createTime }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="操作" fixed="right" width="230" class-name="small-padding fixed-width">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip v-if="scope.row.userId !== 1" content="修改" placement="top">
|
||||||
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip v-if="scope.row.userId !== 1" content="删除" placement="top">
|
||||||
|
<el-button v-hasPermi="['system:user:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
|
||||||
|
<el-tooltip v-if="scope.row.userId !== 1" content="重置密码" placement="top">
|
||||||
|
<el-button v-hasPermi="['system:user:resetPwd']" link type="primary" icon="Key" @click="handleResetPwd(scope.row)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
|
||||||
|
<el-tooltip v-if="scope.row.userId !== 1" content="分配角色" placement="top">
|
||||||
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip v-if="scope.row.userId !== 1" content="编辑关联项目" placement="top">
|
||||||
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit" @click="handleUpdateProject(scope.row)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip v-if="scope.row.userId !== 1" content="上传证书目录" placement="top">
|
||||||
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Upload" @click="handleUploadCert(scope.row)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-dialog v-model="shuttleVisible" title="编辑关联项目" width="auto" destroy-on-close>
|
||||||
|
<shuttle-frame :userId="selectedUserId" @close="shuttleVisible = false" />
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
v-model:page="queryParams.pageNum"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
:total="total"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 添加或修改用户配置对话框 -->
|
||||||
|
<el-dialog draggable ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body @close="closeDialog">
|
||||||
|
<el-form ref="userFormRef" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="用户昵称" prop="nickName">
|
||||||
|
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="归属部门" prop="deptId">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="form.deptId"
|
||||||
|
:data="enabledDeptOptions"
|
||||||
|
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||||
|
value-key="id"
|
||||||
|
placeholder="请选择归属部门"
|
||||||
|
check-strictly
|
||||||
|
@change="handleDeptChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="手机号码" prop="phonenumber">
|
||||||
|
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
|
||||||
|
<el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
|
||||||
|
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="用户性别">
|
||||||
|
<el-select v-model="form.sex" placeholder="请选择">
|
||||||
|
<el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="岗位">
|
||||||
|
<el-select v-model="form.postIds" multiple placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in postOptions"
|
||||||
|
:key="item.postId"
|
||||||
|
:label="item.postName"
|
||||||
|
:value="item.postId"
|
||||||
|
:disabled="item.status == '1'"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-row :gutter="20" v-for="(item, index) in form.projectRoles">
|
||||||
|
<el-col :span="11" :offset="0">
|
||||||
|
<el-form-item label="项目列表">
|
||||||
|
<el-select v-model="item.projectId" placeholder="请选择">
|
||||||
|
<el-option v-for="dict in projectOptions" :key="dict.id" :label="dict.shortName" :value="dict.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="11" :offset="0">
|
||||||
|
<el-form-item label="角色">
|
||||||
|
<el-select v-model="item.roleIds" filterable multiple placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in roleOptions"
|
||||||
|
:key="item.roleId"
|
||||||
|
:label="item.roleName"
|
||||||
|
:value="item.roleId"
|
||||||
|
:disabled="item.status == '1'"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1" :offset="0">
|
||||||
|
<el-button type="primary" circle icon="Plus" @click="handleAddProject" v-if="index == 0"></el-button>
|
||||||
|
<el-button type="danger" circle icon="Delete" @click="delProject(index)" v-else></el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-radio-group v-model="form.status">
|
||||||
|
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel()">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 用户导入对话框 -->
|
||||||
|
<el-dialog draggable v-model="upload.open" :title="upload.title" width="400px" append-to-body>
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
:limit="1"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
:headers="upload.headers"
|
||||||
|
:action="upload.url + '?updateSupport=' + upload.updateSupport"
|
||||||
|
:disabled="upload.isUploading"
|
||||||
|
:on-progress="handleFileUploadProgress"
|
||||||
|
:on-success="handleFileSuccess"
|
||||||
|
:auto-upload="false"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<el-icon class="el-icon--upload">
|
||||||
|
<i-ep-upload-filled />
|
||||||
|
</el-icon>
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="text-center el-upload__tip">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="upload.updateSupport" />
|
||||||
|
是否更新已经存在的用户数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||||
|
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板 </el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||||||
|
<el-button @click="upload.open = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="上传证书目录" v-model="certDialog" width="30%" destroy-on-close>
|
||||||
|
<!-- <File-upload v-model="fileUpload" :limit="5"></File-upload> -->
|
||||||
|
<ImageUpload v-model="fileUpload" :limit="5"></ImageUpload>
|
||||||
|
<template #footer>
|
||||||
|
<span>
|
||||||
|
<el-button @click="certDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="uploadCert">确定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="User" lang="ts">
|
||||||
|
import api, { uploadCertList } from '@/api/system/user';
|
||||||
|
import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
|
||||||
|
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
||||||
|
import { RoleVO } from '@/api/system/role/types';
|
||||||
|
import { PostVO } from '@/api/system/post/types';
|
||||||
|
import { globalHeaders } from '@/utils/request';
|
||||||
|
import { to } from 'await-to-js';
|
||||||
|
import { getProjectByDeptId, getRoleList, optionselect } from '@/api/system/post';
|
||||||
|
import ShuttleFrame from '../../project/projectRelevancy/component/ShuttleFrame.vue';
|
||||||
|
import { listProject } from '@/api/project/project';
|
||||||
|
import editInfo from './comm/editInfo.vue';
|
||||||
|
const router = useRouter();
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
|
||||||
|
const userList = ref<UserVO[]>();
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref<Array<number | string>>([]);
|
||||||
|
const single = ref(true);
|
||||||
|
const multiple = ref(true);
|
||||||
|
const total = ref(0);
|
||||||
|
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
|
||||||
|
const deptName = ref('');
|
||||||
|
const deptOptions = ref<DeptTreeVO[]>([]);
|
||||||
|
const enabledDeptOptions = ref<DeptTreeVO[]>([]);
|
||||||
|
const initPassword = ref<string>('');
|
||||||
|
const postOptions = ref<PostVO[]>([]);
|
||||||
|
const roleOptions = ref<RoleVO[]>([]);
|
||||||
|
const projectOptions = ref<any[]>([]);
|
||||||
|
|
||||||
|
/*** 用户导入参数 */
|
||||||
|
const upload = reactive<ImportOption>({
|
||||||
|
// 是否显示弹出层(用户导入)
|
||||||
|
open: false,
|
||||||
|
// 弹出层标题(用户导入)
|
||||||
|
title: '',
|
||||||
|
// 是否禁用上传
|
||||||
|
isUploading: false,
|
||||||
|
// 是否更新已经存在的用户数据
|
||||||
|
updateSupport: 0,
|
||||||
|
// 设置上传的请求头部
|
||||||
|
headers: globalHeaders(),
|
||||||
|
// 上传的地址
|
||||||
|
url: import.meta.env.VITE_APP_BASE_API + '/system/user/importData'
|
||||||
|
});
|
||||||
|
// 列显隐信息
|
||||||
|
const columns = ref<FieldOption[]>([
|
||||||
|
{ key: 0, label: `用户编号`, visible: false, children: [] },
|
||||||
|
{ key: 1, label: `用户名称`, visible: true, children: [] },
|
||||||
|
{ key: 2, label: `用户昵称`, visible: true, children: [] },
|
||||||
|
{ key: 3, label: `部门`, visible: true, children: [] },
|
||||||
|
{ key: 4, label: `手机号码`, visible: true, children: [] },
|
||||||
|
{ key: 5, label: `状态`, visible: true, children: [] },
|
||||||
|
{ key: 6, label: `创建时间`, visible: true, children: [] }
|
||||||
|
]);
|
||||||
|
|
||||||
|
const deptTreeRef = ref<ElTreeInstance>();
|
||||||
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
|
const userFormRef = ref<ElFormInstance>();
|
||||||
|
const uploadRef = ref<ElUploadInstance>();
|
||||||
|
const formDialogRef = ref<ElDialogInstance>();
|
||||||
|
|
||||||
|
const dialog = reactive<DialogOption>({
|
||||||
|
visible: false,
|
||||||
|
title: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const initFormData: UserForm = {
|
||||||
|
userId: undefined,
|
||||||
|
deptId: undefined,
|
||||||
|
userName: '',
|
||||||
|
nickName: undefined,
|
||||||
|
password: '',
|
||||||
|
phonenumber: undefined,
|
||||||
|
email: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
projectRoles: [
|
||||||
|
{
|
||||||
|
projectId: '',
|
||||||
|
roleIds: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status: '0',
|
||||||
|
remark: '',
|
||||||
|
postIds: [],
|
||||||
|
filePath: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const initData: PageData<UserForm, UserQuery> = {
|
||||||
|
form: { ...initFormData },
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
userName: '',
|
||||||
|
phonenumber: '',
|
||||||
|
status: '',
|
||||||
|
deptId: '',
|
||||||
|
roleId: ''
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
userName: [
|
||||||
|
{ required: true, message: '用户名称不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
min: 2,
|
||||||
|
max: 20,
|
||||||
|
message: '用户名称长度必须介于 2 和 20 之间',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
|
||||||
|
password: [
|
||||||
|
{ required: true, message: '用户密码不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
min: 5,
|
||||||
|
max: 20,
|
||||||
|
message: '用户密码长度必须介于 5 和 20 之间',
|
||||||
|
trigger: 'blur'
|
||||||
|
},
|
||||||
|
{ pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符:< > " \' \\ |', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{
|
||||||
|
type: 'email',
|
||||||
|
message: '请输入正确的邮箱地址',
|
||||||
|
trigger: ['blur', 'change']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
phonenumber: [
|
||||||
|
{ required: true, message: '请输入手机号码', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||||
|
message: '请输入正确的手机号码',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const data = reactive<PageData<UserForm, UserQuery>>(initData);
|
||||||
|
|
||||||
|
const { queryParams, form, rules } = toRefs<PageData<UserForm, UserQuery>>(data);
|
||||||
|
|
||||||
|
/** 通过条件过滤节点 */
|
||||||
|
const filterNode = (value: string, data: any) => {
|
||||||
|
if (!value) return true;
|
||||||
|
return data.label.indexOf(value) !== -1;
|
||||||
|
};
|
||||||
|
/** 根据名称筛选部门树 */
|
||||||
|
watchEffect(
|
||||||
|
() => {
|
||||||
|
deptTreeRef.value?.filter(deptName.value);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/** 查询用户列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await api.listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||||
|
loading.value = false;
|
||||||
|
userList.value = res.rows;
|
||||||
|
total.value = res.total;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 查询部门下拉树结构 */
|
||||||
|
const getDeptTree = async () => {
|
||||||
|
const res = await api.deptTreeSelect({ isShow: '1' });
|
||||||
|
deptOptions.value = res.data;
|
||||||
|
enabledDeptOptions.value = filterDisabledDept(res.data);
|
||||||
|
const projectList = await listProject();
|
||||||
|
projectOptions.value = projectList.rows;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 过滤禁用的部门 */
|
||||||
|
const filterDisabledDept = (deptList: DeptTreeVO[]) => {
|
||||||
|
return deptList.filter((dept) => {
|
||||||
|
if (dept.disabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dept.children && dept.children.length) {
|
||||||
|
dept.children = filterDisabledDept(dept.children);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 节点单击事件 */
|
||||||
|
const handleNodeClick = (data: DeptVO) => {
|
||||||
|
queryParams.value.deptId = data.id;
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 部门选择变化 */
|
||||||
|
const handleAddProject = () => {
|
||||||
|
form.value.projectRoles.push({
|
||||||
|
projectId: '',
|
||||||
|
roleIds: []
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 删除项目 */
|
||||||
|
const delProject = (index: number) => {
|
||||||
|
form.value.projectRoles.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
dateRange.value = ['', ''];
|
||||||
|
queryFormRef.value?.resetFields();
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
queryParams.value.deptId = undefined;
|
||||||
|
deptTreeRef.value?.setCurrentKey(undefined);
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (row?: UserVO) => {
|
||||||
|
const userIds = row?.userId || ids.value;
|
||||||
|
const [err] = await to(proxy?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?') as any);
|
||||||
|
if (!err) {
|
||||||
|
await api.delUser(userIds);
|
||||||
|
await getList();
|
||||||
|
proxy?.$modal.msgSuccess('删除成功');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 用户状态修改 */
|
||||||
|
const handleStatusChange = async (row: UserVO) => {
|
||||||
|
let text = row.status === '0' ? '启用' : '停用';
|
||||||
|
try {
|
||||||
|
await proxy?.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?');
|
||||||
|
await api.changeUserStatus(row.userId, row.status);
|
||||||
|
proxy?.$modal.msgSuccess(text + '成功');
|
||||||
|
} catch (err) {
|
||||||
|
row.status = row.status === '0' ? '1' : '0';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/** 跳转角色分配 */
|
||||||
|
const handleAuthRole = (row: UserVO) => {
|
||||||
|
const userId = row.userId;
|
||||||
|
router.push('/system/user-auth/role/' + userId);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 重置密码按钮操作 */
|
||||||
|
const handleResetPwd = async (row: UserVO) => {
|
||||||
|
const [err, res] = await to(
|
||||||
|
ElMessageBox.prompt('请输入"' + row.userName + '"的新密码', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
closeOnClickModal: false,
|
||||||
|
inputPattern: /^.{5,20}$/,
|
||||||
|
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
|
||||||
|
inputValidator: (value) => {
|
||||||
|
if (/<|>|"|'|\||\\/.test(value)) {
|
||||||
|
return '不能包含非法字符:< > " \' \\ |';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (!err && res) {
|
||||||
|
await api.resetUserPwd(row.userId, res.value);
|
||||||
|
proxy?.$modal.msgSuccess('修改成功,新密码是:' + res.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 选择条数 */
|
||||||
|
const handleSelectionChange = (selection: UserVO[]) => {
|
||||||
|
ids.value = selection.map((item) => item.userId);
|
||||||
|
single.value = selection.length != 1;
|
||||||
|
multiple.value = !selection.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 导入按钮操作 */
|
||||||
|
const handleImport = () => {
|
||||||
|
upload.title = '用户导入';
|
||||||
|
upload.open = true;
|
||||||
|
};
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = () => {
|
||||||
|
proxy?.download(
|
||||||
|
'system/user/export',
|
||||||
|
{
|
||||||
|
...queryParams.value
|
||||||
|
},
|
||||||
|
`user_${new Date().getTime()}.xlsx`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = () => {
|
||||||
|
proxy?.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**文件上传中处理 */
|
||||||
|
const handleFileUploadProgress = () => {
|
||||||
|
upload.isUploading = true;
|
||||||
|
};
|
||||||
|
/** 文件上传成功处理 */
|
||||||
|
const handleFileSuccess = (response: any, file: UploadFile) => {
|
||||||
|
upload.open = false;
|
||||||
|
upload.isUploading = false;
|
||||||
|
uploadRef.value?.handleRemove(file);
|
||||||
|
ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
|
||||||
|
dangerouslyUseHTMLString: true
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交上传文件 */
|
||||||
|
function submitFileForm() {
|
||||||
|
uploadRef.value?.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置操作表单 */
|
||||||
|
const reset = () => {
|
||||||
|
form.value = { ...initFormData };
|
||||||
|
form.value.projectRoles = [
|
||||||
|
{
|
||||||
|
projectId: '',
|
||||||
|
roleIds: []
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
userFormRef.value?.resetFields();
|
||||||
|
};
|
||||||
|
/** 取消按钮 */
|
||||||
|
const cancel = () => {
|
||||||
|
dialog.visible = false;
|
||||||
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
const handleAdd = async () => {
|
||||||
|
reset();
|
||||||
|
const { data } = await api.getUser();
|
||||||
|
dialog.visible = true;
|
||||||
|
dialog.title = '新增用户';
|
||||||
|
postOptions.value = data.posts;
|
||||||
|
form.value.password = initPassword.value.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
const handleUpdate = async (row?: UserForm) => {
|
||||||
|
reset();
|
||||||
|
const userId = row?.userId || ids.value[0];
|
||||||
|
const { data } = await api.getUser(userId);
|
||||||
|
dialog.visible = true;
|
||||||
|
dialog.title = '修改用户';
|
||||||
|
Object.assign(form.value, data.user);
|
||||||
|
postOptions.value = data.posts;
|
||||||
|
roleOptions.value = data.roles;
|
||||||
|
form.value.postIds = data.postIds;
|
||||||
|
form.value.projectRoles = data.projectRoles;
|
||||||
|
form.value.password = '';
|
||||||
|
const roleList = await getRoleList(form.value.deptId);
|
||||||
|
|
||||||
|
roleOptions.value = roleList.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const validate = () => {
|
||||||
|
for (let i = 0; i < form.value.projectRoles.length; i++) {
|
||||||
|
const item = form.value.projectRoles[i];
|
||||||
|
if (!item.projectId || item.projectId.length === 0) {
|
||||||
|
proxy?.$modal.msgError(`第 ${i + 1} 行“项目列表”未填写`);
|
||||||
|
return false; // 阻止提交
|
||||||
|
}
|
||||||
|
if (!item.roleIds || item.roleIds.length === 0) {
|
||||||
|
proxy?.$modal.msgError(`第 ${i + 1} 行“角色”未填写`);
|
||||||
|
return false; // 阻止提交
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交按钮 */
|
||||||
|
const submitForm = () => {
|
||||||
|
const isValid = validate();
|
||||||
|
if (!isValid) return;
|
||||||
|
userFormRef.value?.validate(async (valid: boolean) => {
|
||||||
|
if (valid) {
|
||||||
|
form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
|
||||||
|
proxy?.$modal.msgSuccess('操作成功');
|
||||||
|
dialog.visible = false;
|
||||||
|
await getList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭用户弹窗
|
||||||
|
*/
|
||||||
|
const closeDialog = () => {
|
||||||
|
dialog.visible = false;
|
||||||
|
resetForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单
|
||||||
|
*/
|
||||||
|
const resetForm = () => {
|
||||||
|
userFormRef.value?.resetFields();
|
||||||
|
userFormRef.value?.clearValidate();
|
||||||
|
|
||||||
|
form.value.id = undefined;
|
||||||
|
form.value.status = '1';
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getDeptTree(); // 初始化部门数据
|
||||||
|
getList(); // 初始化列表数据
|
||||||
|
proxy?.getConfigKey('sys.user.initPassword').then((response) => {
|
||||||
|
initPassword.value = response.data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handleDeptChange(value: number | string) {
|
||||||
|
const response = await optionselect(value);
|
||||||
|
const roleList = await getRoleList(value);
|
||||||
|
|
||||||
|
roleOptions.value = roleList.data;
|
||||||
|
postOptions.value = response.data;
|
||||||
|
form.value.postIds = [];
|
||||||
|
form.value.projectRoles = [
|
||||||
|
{
|
||||||
|
projectId: [],
|
||||||
|
roleIds: []
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const shuttleVisible = ref(false);
|
||||||
|
const selectedUserId = ref<number>();
|
||||||
|
const handleUpdateProject = (row) => {
|
||||||
|
if (row) {
|
||||||
|
selectedUserId.value = row.userId;
|
||||||
|
shuttleVisible.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const certDialog = ref(false);
|
||||||
|
const certId = ref<string | number>(undefined);
|
||||||
|
const fileUpload = ref<string>();
|
||||||
|
//上传证书
|
||||||
|
const handleUploadCert = (row: UserVO) => {
|
||||||
|
certId.value = row.userId;
|
||||||
|
fileUpload.value = row.filePath;
|
||||||
|
certDialog.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadCert = async () => {
|
||||||
|
if (!fileUpload.value) {
|
||||||
|
proxy?.$modal.msgError('请上传证书目录');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let res = await uploadCertList({
|
||||||
|
userId: certId.value,
|
||||||
|
fileId: fileUpload.value
|
||||||
|
});
|
||||||
|
console.log(res);
|
||||||
|
|
||||||
|
certDialog.value = false;
|
||||||
|
proxy?.$modal.msgSuccess('上传证书目录成功');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
@ -5,14 +5,22 @@
|
|||||||
<el-col :lg="4" :xs="24" style="">
|
<el-col :lg="4" :xs="24" style="">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover">
|
||||||
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
|
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
|
||||||
<el-tree ref="deptTreeRef" class="mt-2" node-key="id" :data="deptOptions"
|
<el-tree
|
||||||
:props="{ label: 'label', children: 'children' }" :expand-on-click-node="false"
|
ref="deptTreeRef"
|
||||||
:filter-node-method="filterNode" highlight-current default-expand-all @node-click="handleNodeClick" />
|
class="mt-2"
|
||||||
|
node-key="id"
|
||||||
|
:data="deptOptions"
|
||||||
|
:props="{ label: 'label', children: 'children' }"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :lg="20" :xs="24">
|
<el-col :lg="20" :xs="24">
|
||||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
: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="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
@ -20,24 +28,27 @@
|
|||||||
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机号码" prop="phonenumber">
|
<el-form-item label="手机号码" prop="phonenumber">
|
||||||
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable
|
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery" />
|
||||||
@keyup.enter="handleQuery" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-select v-model="queryParams.status" placeholder="用户状态" clearable>
|
<el-select v-model="queryParams.status" placeholder="用户状态" clearable>
|
||||||
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label"
|
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||||
:value="dict.value" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建时间" style="width: 308px">
|
<el-form-item label="创建时间" style="width: 308px">
|
||||||
<el-date-picker v-model="dateRange" value-format="YYYY-MM-DD HH:mm:ss" type="daterange"
|
<el-date-picker
|
||||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
|
v-model="dateRange"
|
||||||
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"></el-date-picker>
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="handleQuery"
|
<el-button type="primary" icon="Search" @click="handleQuery" @v-has-permi="['system:user:query']">搜索</el-button>
|
||||||
@v-has-permi="['system:user:query']">搜索</el-button>
|
|
||||||
|
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -50,18 +61,15 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button v-has-permi="['system:user:add']" type="primary" plain icon="Plus" @click="handleAdd()"> 新增
|
<el-button v-has-permi="['system:user:add']" type="primary" plain icon="Plus" @click="handleAdd()"> 新增 </el-button>
|
||||||
</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button v-has-permi="['system:user:edit']" type="success" plain :disabled="single" icon="Edit"
|
<el-button v-has-permi="['system:user:edit']" type="success" plain :disabled="single" icon="Edit" @click="handleUpdate()">
|
||||||
@click="handleUpdate()">
|
|
||||||
修改
|
修改
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button v-has-permi="['system:user:remove']" type="danger" plain :disabled="multiple" icon="Delete"
|
<el-button v-has-permi="['system:user:remove']" type="danger" plain :disabled="multiple" icon="Delete" @click="handleDelete()">
|
||||||
@click="handleDelete()">
|
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -76,34 +84,26 @@
|
|||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>
|
<el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>
|
||||||
<el-dropdown-item v-has-permi="['system:user:import']" icon="Top" @click="handleImport">导入数据
|
<el-dropdown-item v-has-permi="['system:user:import']" icon="Top" @click="handleImport">导入数据 </el-dropdown-item>
|
||||||
</el-dropdown-item>
|
<el-dropdown-item v-has-permi="['system:user:export']" icon="Download" @click="handleExport"> 导出数据 </el-dropdown-item>
|
||||||
<el-dropdown-item v-has-permi="['system:user:export']" icon="Download" @click="handleExport"> 导出数据
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar v-model:show-search="showSearch" :columns="columns" :search="true"
|
<right-toolbar v-model:show-search="showSearch" :columns="columns" :search="true" @query-table="getList"></right-toolbar>
|
||||||
@query-table="getList"></right-toolbar>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
<el-table-column v-if="columns[0].visible" key="userId" label="用户编号" align="center" prop="userId" />
|
<el-table-column v-if="columns[0].visible" key="userId" label="用户编号" align="center" prop="userId" />
|
||||||
<el-table-column v-if="columns[1].visible" key="userName" label="用户名称" align="center" prop="userName"
|
<el-table-column v-if="columns[1].visible" key="userName" label="用户名称" align="center" prop="userName" :show-overflow-tooltip="true" />
|
||||||
:show-overflow-tooltip="true" />
|
<el-table-column v-if="columns[2].visible" key="nickName" label="用户昵称" align="center" prop="nickName" :show-overflow-tooltip="true" />
|
||||||
<el-table-column v-if="columns[2].visible" key="nickName" label="用户昵称" align="center" prop="nickName"
|
<el-table-column v-if="columns[3].visible" key="deptName" label="部门" align="center" prop="deptName" :show-overflow-tooltip="true" />
|
||||||
:show-overflow-tooltip="true" />
|
<el-table-column v-if="columns[4].visible" key="phonenumber" label="手机号码" align="center" prop="phonenumber" width="120" />
|
||||||
<el-table-column v-if="columns[3].visible" key="deptName" label="部门" align="center" prop="deptName"
|
|
||||||
:show-overflow-tooltip="true" />
|
|
||||||
<el-table-column v-if="columns[4].visible" key="phonenumber" label="手机号码" align="center" prop="phonenumber"
|
|
||||||
width="120" />
|
|
||||||
<el-table-column v-if="columns[5].visible" key="status" label="状态" align="center">
|
<el-table-column v-if="columns[5].visible" key="status" label="状态" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1"
|
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||||
@change="handleStatusChange(scope.row)"></el-switch>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@ -116,30 +116,24 @@
|
|||||||
<el-table-column label="操作" fixed="right" width="230" class-name="small-padding fixed-width">
|
<el-table-column label="操作" fixed="right" width="230" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip v-if="scope.row.userId !== 1" content="修改" placement="top">
|
<el-tooltip v-if="scope.row.userId !== 1" content="修改" placement="top">
|
||||||
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit"
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||||
@click="handleUpdate(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="scope.row.userId !== 1" content="删除" placement="top">
|
<el-tooltip v-if="scope.row.userId !== 1" content="删除" placement="top">
|
||||||
<el-button v-hasPermi="['system:user:remove']" link type="primary" icon="Delete"
|
<el-button v-hasPermi="['system:user:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||||
@click="handleDelete(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip v-if="scope.row.userId !== 1" content="重置密码" placement="top">
|
<el-tooltip v-if="scope.row.userId !== 1" content="重置密码" placement="top">
|
||||||
<el-button v-hasPermi="['system:user:resetPwd']" link type="primary" icon="Key"
|
<el-button v-hasPermi="['system:user:resetPwd']" link type="primary" icon="Key" @click="handleResetPwd(scope.row)"></el-button>
|
||||||
@click="handleResetPwd(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip v-if="scope.row.userId !== 1" content="分配角色" placement="top">
|
<el-tooltip v-if="scope.row.userId !== 1" content="分配角色" placement="top">
|
||||||
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="CircleCheck"
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)"></el-button>
|
||||||
@click="handleAuthRole(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="scope.row.userId !== 1" content="编辑关联项目" placement="top">
|
<el-tooltip v-if="scope.row.userId !== 1" content="编辑关联项目" placement="top">
|
||||||
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit"
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit" @click="handleUpdateProject(scope.row)"></el-button>
|
||||||
@click="handleUpdateProject(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="scope.row.userId !== 1" content="上传证书目录" placement="top">
|
<el-tooltip v-if="scope.row.userId !== 1" content="上传证书目录" placement="top">
|
||||||
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Upload"
|
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Upload" @click="handleUploadCert(scope.row)"></el-button>
|
||||||
@click="handleUploadCert(scope.row)"></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -148,117 +142,47 @@
|
|||||||
<shuttle-frame :userId="selectedUserId" @close="shuttleVisible = false" />
|
<shuttle-frame :userId="selectedUserId" @close="shuttleVisible = false" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
<pagination
|
||||||
:total="total" @pagination="getList" />
|
v-show="total > 0"
|
||||||
|
v-model:page="queryParams.pageNum"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
:total="total"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 添加或修改用户配置对话框 -->
|
<!-- 添加或修改用户配置对话框 -->
|
||||||
<el-dialog ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body
|
<el-dialog draggable ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="1300px" append-to-body @close="closeDialog">
|
||||||
@close="closeDialog">
|
<div class="boxDetial">
|
||||||
<el-form ref="userFormRef" :model="form" :rules="rules" label-width="80px">
|
<div class="tab_info">
|
||||||
<el-row>
|
<span @click="onTab(1)" :class="{ active: type == 1 }">基本资料</span>
|
||||||
<el-col :span="12">
|
<span @click="onTab(2)" :class="{ active: type == 2 }">角色信息</span>
|
||||||
<el-form-item label="用户昵称" prop="nickName">
|
|
||||||
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="归属部门" prop="deptId">
|
|
||||||
<el-tree-select v-model="form.deptId" :data="enabledDeptOptions"
|
|
||||||
:props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="请选择归属部门"
|
|
||||||
check-strictly @change="handleDeptChange" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="手机号码" prop="phonenumber">
|
|
||||||
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="邮箱" prop="email">
|
|
||||||
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
|
|
||||||
<el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
|
|
||||||
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="用户性别">
|
|
||||||
<el-select v-model="form.sex" placeholder="请选择">
|
|
||||||
<el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label"
|
|
||||||
:value="dict.value"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="岗位">
|
|
||||||
<el-select v-model="form.postIds" multiple placeholder="请选择">
|
|
||||||
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId"
|
|
||||||
:disabled="item.status == '1'"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-row :gutter="20" v-for="(item, index) in form.projectRoles">
|
|
||||||
<el-col :span="11" :offset="0">
|
|
||||||
<el-form-item label="项目列表">
|
|
||||||
<el-select v-model="item.projectId" placeholder="请选择">
|
|
||||||
<el-option v-for="dict in projectOptions" :key="dict.id" :label="dict.shortName"
|
|
||||||
:value="dict.id"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="11" :offset="0">
|
|
||||||
<el-form-item label="角色">
|
|
||||||
<el-select v-model="item.roleIds" filterable multiple placeholder="请选择">
|
|
||||||
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName"
|
|
||||||
:value="item.roleId" :disabled="item.status == '1'"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1" :offset="0">
|
|
||||||
<el-button type="primary" circle icon="Plus" @click="handleAddProject" v-if="index == 0"></el-button>
|
|
||||||
<el-button type="danger" circle icon="Delete" @click="delProject(index)" v-else></el-button>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="状态">
|
|
||||||
<el-radio-group v-model="form.status">
|
|
||||||
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="备注">
|
|
||||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
<el-button @click="cancel()">取 消</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div class="tab_content" v-show="type == 1">
|
||||||
|
<editInfo ref="editInfoRef" @close="dialog.visible = false" @submit="getList" @setDeptId="setDeptId"></editInfo>
|
||||||
|
</div>
|
||||||
|
<div class="tab_content" v-show="type == 2">
|
||||||
|
<roleInfo ref="roleInfoRef" @close="dialog.visible = false" @submit="getList"></roleInfo>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 用户导入对话框 -->
|
<!-- 用户导入对话框 -->
|
||||||
<el-dialog draggable v-model="upload.open" :title="upload.title" width="400px" append-to-body>
|
<el-dialog draggable v-model="upload.open" :title="upload.title" width="400px" append-to-body>
|
||||||
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
|
<el-upload
|
||||||
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
|
ref="uploadRef"
|
||||||
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
|
:limit="1"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
:headers="upload.headers"
|
||||||
|
:action="upload.url + '?updateSupport=' + upload.updateSupport"
|
||||||
|
:disabled="upload.isUploading"
|
||||||
|
:on-progress="handleFileUploadProgress"
|
||||||
|
:on-success="handleFileSuccess"
|
||||||
|
:auto-upload="false"
|
||||||
|
drag
|
||||||
|
>
|
||||||
<el-icon class="el-icon--upload">
|
<el-icon class="el-icon--upload">
|
||||||
<i-ep-upload-filled />
|
<i-ep-upload-filled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -270,8 +194,7 @@
|
|||||||
是否更新已经存在的用户数据
|
是否更新已经存在的用户数据
|
||||||
</div>
|
</div>
|
||||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||||
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
|
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板 </el-link>
|
||||||
@click="importTemplate">下载模板 </el-link>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
@ -307,7 +230,8 @@ import { to } from 'await-to-js';
|
|||||||
import { getProjectByDeptId, getRoleList, optionselect } from '@/api/system/post';
|
import { getProjectByDeptId, getRoleList, optionselect } from '@/api/system/post';
|
||||||
import ShuttleFrame from '../../project/projectRelevancy/component/ShuttleFrame.vue';
|
import ShuttleFrame from '../../project/projectRelevancy/component/ShuttleFrame.vue';
|
||||||
import { listProject } from '@/api/project/project';
|
import { listProject } from '@/api/project/project';
|
||||||
|
import editInfo from './comm/editInfo.vue';
|
||||||
|
import roleInfo from './comm/roleInfo.vue';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
|
const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
|
||||||
@ -326,7 +250,8 @@ const initPassword = ref<string>('');
|
|||||||
const postOptions = ref<PostVO[]>([]);
|
const postOptions = ref<PostVO[]>([]);
|
||||||
const roleOptions = ref<RoleVO[]>([]);
|
const roleOptions = ref<RoleVO[]>([]);
|
||||||
const projectOptions = ref<any[]>([]);
|
const projectOptions = ref<any[]>([]);
|
||||||
|
const editInfoRef = ref<InstanceType<typeof editInfo> | null>(null);
|
||||||
|
const roleInfoRef = ref<InstanceType<typeof roleInfo> | null>(null);
|
||||||
/*** 用户导入参数 */
|
/*** 用户导入参数 */
|
||||||
const upload = reactive<ImportOption>({
|
const upload = reactive<ImportOption>({
|
||||||
// 是否显示弹出层(用户导入)
|
// 是否显示弹出层(用户导入)
|
||||||
@ -358,7 +283,8 @@ const queryFormRef = ref<ElFormInstance>();
|
|||||||
const userFormRef = ref<ElFormInstance>();
|
const userFormRef = ref<ElFormInstance>();
|
||||||
const uploadRef = ref<ElUploadInstance>();
|
const uploadRef = ref<ElUploadInstance>();
|
||||||
const formDialogRef = ref<ElDialogInstance>();
|
const formDialogRef = ref<ElDialogInstance>();
|
||||||
|
const deptIdRole = ref<number>();
|
||||||
|
const type = ref(1);
|
||||||
const dialog = reactive<DialogOption>({
|
const dialog = reactive<DialogOption>({
|
||||||
visible: false,
|
visible: false,
|
||||||
title: ''
|
title: ''
|
||||||
@ -452,7 +378,9 @@ watchEffect(
|
|||||||
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
|
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
const setDeptId = (deptId: number) => {
|
||||||
|
deptIdRole.value = deptId;
|
||||||
|
};
|
||||||
/** 查询用户列表 */
|
/** 查询用户列表 */
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@ -637,8 +565,12 @@ const cancel = () => {
|
|||||||
const handleAdd = async () => {
|
const handleAdd = async () => {
|
||||||
reset();
|
reset();
|
||||||
const { data } = await api.getUser();
|
const { data } = await api.getUser();
|
||||||
|
type.value = 1;
|
||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
dialog.title = '新增用户';
|
dialog.title = '新增用户';
|
||||||
|
nextTick(() => {
|
||||||
|
editInfoRef.value?.open();
|
||||||
|
});
|
||||||
postOptions.value = data.posts;
|
postOptions.value = data.posts;
|
||||||
form.value.password = initPassword.value.toString();
|
form.value.password = initPassword.value.toString();
|
||||||
};
|
};
|
||||||
@ -646,19 +578,13 @@ const handleAdd = async () => {
|
|||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
const handleUpdate = async (row?: UserForm) => {
|
const handleUpdate = async (row?: UserForm) => {
|
||||||
reset();
|
reset();
|
||||||
const userId = row?.userId || ids.value[0];
|
|
||||||
const { data } = await api.getUser(userId);
|
|
||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
dialog.title = '修改用户';
|
dialog.title = '修改用户';
|
||||||
Object.assign(form.value, data.user);
|
type.value = 1;
|
||||||
postOptions.value = data.posts;
|
form.value = row;
|
||||||
roleOptions.value = data.roles;
|
nextTick(() => {
|
||||||
form.value.postIds = data.postIds;
|
editInfoRef.value?.open(row);
|
||||||
form.value.projectRoles = data.projectRoles;
|
});
|
||||||
form.value.password = '';
|
|
||||||
const roleList = await getRoleList(form.value.deptId);
|
|
||||||
|
|
||||||
roleOptions.value = roleList.data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
@ -764,6 +690,46 @@ const uploadCert = async () => {
|
|||||||
certDialog.value = false;
|
certDialog.value = false;
|
||||||
proxy?.$modal.msgSuccess('上传证书目录成功');
|
proxy?.$modal.msgSuccess('上传证书目录成功');
|
||||||
};
|
};
|
||||||
|
const onTab = (val) => {
|
||||||
|
type.value = val;
|
||||||
|
if (val == 2) {
|
||||||
|
let obj = editInfoRef.value?.getInfoForm();
|
||||||
|
form.value = obj;
|
||||||
|
nextTick(() => {
|
||||||
|
roleInfoRef.value?.open(form.value, deptIdRole.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.boxDetial {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 680px;
|
||||||
|
.tab_info {
|
||||||
|
height: 100%;
|
||||||
|
width: 200px;
|
||||||
|
background: #f0f2f5;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 18px;
|
||||||
|
> span {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tab_content {
|
||||||
|
height: 100%;
|
||||||
|
width: calc(100% - 200px);
|
||||||
|
padding: 20px 10px;
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<el-option v-for="item in options" :key="item.versions" :label="item.versions" :value="item.versions" />
|
<el-option v-for="item in options" :key="item.versions" :label="item.versions" :value="item.versions" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="表名" prop="sheet">
|
<el-form-item label="表名" prop="sheet" v-if="activeTab != '3'">
|
||||||
<el-select v-model="queryForm.sheet" placeholder="选择表名" @change="changeSheet">
|
<el-select v-model="queryForm.sheet" placeholder="选择表名" @change="changeSheet">
|
||||||
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -139,7 +139,7 @@ const sheets = ref([]);
|
|||||||
const options = ref([]);
|
const options = ref([]);
|
||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const isExpandAll = ref(false);
|
const isExpandAll = ref(true);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const versionMap = new Map();
|
const versionMap = new Map();
|
||||||
|
|
||||||
|
@ -191,9 +191,14 @@
|
|||||||
<el-table-column prop="useQuantity" label="剩余量" align="center">
|
<el-table-column prop="useQuantity" label="剩余量" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{
|
{{
|
||||||
(scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) == 0
|
(scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) ==
|
||||||
|
0
|
||||||
? ''
|
? ''
|
||||||
: (scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
: (scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -219,12 +224,16 @@
|
|||||||
<el-table-column prop="price" label="总价" align="center">
|
<el-table-column prop="price" label="总价" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{
|
{{
|
||||||
((scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)) *
|
((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
|
||||||
Number(scope.row.unitPrice) ==
|
Number(scope.row.unitPrice) ==
|
||||||
0
|
0
|
||||||
? ''
|
? ''
|
||||||
: (
|
: (
|
||||||
((scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0)) *
|
((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||||
|
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||||
|
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
|
||||||
Number(scope.row.unitPrice)
|
Number(scope.row.unitPrice)
|
||||||
).toFixed(2)
|
).toFixed(2)
|
||||||
}}
|
}}
|
||||||
@ -459,19 +468,11 @@ const getSheetName = async () => {
|
|||||||
treeForm.value.sheet = res.data[0];
|
treeForm.value.sheet = res.data[0];
|
||||||
} else {
|
} else {
|
||||||
treeForm.value.sheet = '';
|
treeForm.value.sheet = '';
|
||||||
ElMessage({
|
|
||||||
message: '获取表名失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
getTreeList();
|
getTreeList();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
ElMessage({
|
|
||||||
message: '获取表名失败',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleSelection = (selection: any) => {
|
const handleSelection = (selection: any) => {
|
||||||
|
@ -234,17 +234,17 @@
|
|||||||
<!-- 第十一行:注册人员数量(仅劳务类型显示) -->
|
<!-- 第十一行:注册人员数量(仅劳务类型显示) -->
|
||||||
<el-row :gutter="20" class="mb-4" v-if="form.supplierType === '劳务'">
|
<el-row :gutter="20" class="mb-4" v-if="form.supplierType === '劳务'">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="一建建造师" prop="build1">
|
<el-form-item label="一建建造师" prop="firstBuildingNumber">
|
||||||
<el-input v-model="form.build1" placeholder="请输入一建建造师数量" clearable />
|
<el-input v-model="form.firstBuildingNumber" placeholder="请输入一建建造师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="二建建造师" prop="build2">
|
<el-form-item label="二建建造师" prop="secondBuildingNumber">
|
||||||
<el-input v-model="form.build2" placeholder="请输入二建建造师数量" clearable />
|
<el-input v-model="form.secondBuildingNumber" placeholder="请输入二建建造师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="注册造价工程师" prop="build3">
|
<el-form-item label="注册造价工程师" prop="registeredEngineerNumber">
|
||||||
<el-input v-model="form.build3" placeholder="请输入注册造价工程师数量" clearable />
|
<el-input v-model="form.registeredEngineerNumber" placeholder="请输入注册造价工程师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="其他(分别写)" prop="build4">
|
<el-form-item label="其他(分别写)" prop="otherBuildingNumber">
|
||||||
<el-input v-model="form.build4" placeholder="请输入其他人员数量" clearable />
|
<el-input v-model="form.otherBuildingNumber" placeholder="请输入其他人员数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@ -254,17 +254,17 @@
|
|||||||
<!-- 第十二行:职称人员数量(仅劳务类型显示) -->
|
<!-- 第十二行:职称人员数量(仅劳务类型显示) -->
|
||||||
<el-row :gutter="20" class="mb-4" v-if="form.supplierType === '劳务'">
|
<el-row :gutter="20" class="mb-4" v-if="form.supplierType === '劳务'">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="高级工程师人数" prop="personnelNumber1">
|
<el-form-item label="高级工程师人数" prop="seniorEngineerNumber">
|
||||||
<el-input v-model="form.personnelNumber1" placeholder="请输高级工程师数量" clearable />
|
<el-input v-model="form.seniorEngineerNumber" placeholder="请输高级工程师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="工程师数量" prop="personnelNumber2">
|
<el-form-item label="工程师数量" prop="engineerNumber">
|
||||||
<el-input v-model="form.personnelNumber2" placeholder="请输入工程师数量" clearable />
|
<el-input v-model="form.engineerNumber" placeholder="请输入工程师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="助理工程师数量" prop="personnelNumber3">
|
<el-form-item label="助理工程师数量" prop="assistantEngineerNumber">
|
||||||
<el-input v-model="form.personnelNumber3" placeholder="请输入助理工程师数量" clearable />
|
<el-input v-model="form.assistantEngineerNumber" placeholder="请输入助理工程师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="其他人员数量" prop="personnelNumber4">
|
<el-form-item label="其他人员数量" prop="otherPersonnelNumber">
|
||||||
<el-input v-model="form.personnelNumber4" placeholder="请输入其他人员数量" clearable />
|
<el-input v-model="form.otherPersonnelNumber" placeholder="请输入其他人员数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@ -285,8 +285,8 @@
|
|||||||
:data="form"
|
:data="form"
|
||||||
uploadUrl="/supplierInput/supplierInput"
|
uploadUrl="/supplierInput/supplierInput"
|
||||||
:limit="1"
|
:limit="1"
|
||||||
:onUploadSuccess="handleUploadSuccess"
|
@handleChange="handleFileChange"
|
||||||
@handleChange="change"
|
@handleRemove="handleFileRemove"
|
||||||
showFileList
|
showFileList
|
||||||
>
|
>
|
||||||
<div><el-button type="primary">上传文件</el-button><br /></div>
|
<div><el-button type="primary">上传文件</el-button><br /></div>
|
||||||
@ -309,7 +309,7 @@
|
|||||||
<script setup name="SupplierInput" lang="ts">
|
<script setup name="SupplierInput" lang="ts">
|
||||||
import { ComponentInternalInstance, getCurrentInstance, onMounted, ref, reactive, toRefs, computed } from 'vue';
|
import { ComponentInternalInstance, getCurrentInstance, onMounted, ref, reactive, toRefs, computed } from 'vue';
|
||||||
import { ElFormInstance } from 'element-plus';
|
import { ElFormInstance } from 'element-plus';
|
||||||
import { listSupplierInput, getSupplierInput, delSupplierInput } from '@/api/supplierInput/supplierInput/index';
|
import { listSupplierInput, getSupplierInput, delSupplierInput, updateSupplierInput } from '@/api/supplierInput/supplierInput/index';
|
||||||
import { SupplierInputVO, SupplierInputQuery, SupplierInputForm, PageData, DialogOption } from '@/api/supplierInput/supplierInput/types';
|
import { SupplierInputVO, SupplierInputQuery, SupplierInputForm, PageData, DialogOption } from '@/api/supplierInput/supplierInput/types';
|
||||||
import Pagination from '@/components/Pagination/index.vue';
|
import Pagination from '@/components/Pagination/index.vue';
|
||||||
import RightToolbar from '@/components/RightToolbar/index.vue';
|
import RightToolbar from '@/components/RightToolbar/index.vue';
|
||||||
@ -369,14 +369,14 @@ const initFormData: any = {
|
|||||||
inputFile: undefined,
|
inputFile: undefined,
|
||||||
// state: '0', // 新增默认待审核
|
// state: '0', // 新增默认待审核
|
||||||
// 新增:用于表单输入的单独字段
|
// 新增:用于表单输入的单独字段
|
||||||
build1: undefined, // 一建建造师
|
firstBuildingNumber: undefined, // 一建建造师
|
||||||
build2: undefined, // 二建建造师
|
secondBuildingNumber: undefined, // 二建建造师
|
||||||
build3: undefined, // 注册造价工程师
|
registeredEngineerNumber: undefined, // 注册造价工程师
|
||||||
build4: undefined, // 其他注册人员
|
otherBuildingNumber: undefined, // 其他注册人员
|
||||||
personnelNumber1: undefined, // 高级工程师
|
seniorEngineerNumber: undefined, // 高级工程师
|
||||||
personnelNumber2: undefined, // 工程师
|
engineerNumber: undefined, // 工程师
|
||||||
personnelNumber3: undefined, // 助理工程师
|
assistantEngineerNumber: undefined, // 助理工程师
|
||||||
personnelNumber4: undefined // 其他职称人员
|
otherPersonnelNumber: undefined // 其他职称人员
|
||||||
};
|
};
|
||||||
// 核心数据(表单+查询参数)
|
// 核心数据(表单+查询参数)
|
||||||
const data = reactive<PageData<SupplierInputForm, SupplierInputQuery>>({
|
const data = reactive<PageData<SupplierInputForm, SupplierInputQuery>>({
|
||||||
@ -411,14 +411,14 @@ const rules = computed(() => {
|
|||||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
id: [{ required: true, message: 'ID不能为空', trigger: 'blur' }],
|
id: [{ required: true, message: 'ID不能为空', trigger: 'blur' }],
|
||||||
build1: [{ required: true, message: '请输入一建建造师数量', trigger: 'change' }],
|
firstBuildingNumber: [{ required: true, message: '请输入一建建造师数量', trigger: 'change' }],
|
||||||
build2: [{ required: true, message: '请输入二建建造师数量', trigger: 'change' }],
|
secondBuildingNumber: [{ required: true, message: '请输入二建建造师数量', trigger: 'change' }],
|
||||||
build3: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'change' }],
|
registeredEngineerNumber: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'change' }],
|
||||||
build4: [{ required: true, message: '请输入其他数量', trigger: 'change' }],
|
otherBuildingNumber: [{ required: true, message: '请输入其他数量', trigger: 'change' }],
|
||||||
personnelNumber1: [{ required: true, message: '请输入高级工程师数量', trigger: 'change' }],
|
seniorEngineerNumber: [{ required: true, message: '请输入高级工程师数量', trigger: 'change' }],
|
||||||
personnelNumber2: [{ required: true, message: '请输入工程师数量', trigger: 'change' }],
|
engineerNumber: [{ required: true, message: '请输入工程师数量', trigger: 'change' }],
|
||||||
personnelNumber3: [{ required: true, message: '请输入助理工程师数量', trigger: 'change' }],
|
assistantEngineerNumber: [{ required: true, message: '请输入助理工程师数量', trigger: 'change' }],
|
||||||
personnelNumber4: [{ required: true, message: '请输入其他数量', trigger: 'change' }]
|
otherPersonnelNumber: [{ required: true, message: '请输入其他数量', trigger: 'change' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
// 仅当类型为"劳务"时,添加安全生产许可证+人员数量校验
|
// 仅当类型为"劳务"时,添加安全生产许可证+人员数量校验
|
||||||
@ -430,15 +430,15 @@ const rules = computed(() => {
|
|||||||
safeCodeData: [{ required: true, message: '请选择安全生产许可证发证日期', trigger: 'change' }],
|
safeCodeData: [{ required: true, message: '请选择安全生产许可证发证日期', trigger: 'change' }],
|
||||||
safeCertificateValidity: [{ required: true, message: '请选择安全生产许可证有效期', trigger: 'change' }],
|
safeCertificateValidity: [{ required: true, message: '请选择安全生产许可证有效期', trigger: 'change' }],
|
||||||
// 注册人员数量校验
|
// 注册人员数量校验
|
||||||
build1: [{ required: true, message: '请输入一建建造师数量', trigger: 'blur' }],
|
firstBuildingNumber: [{ required: true, message: '请输入一建建造师数量', trigger: 'blur' }],
|
||||||
build2: [{ required: true, message: '请输入二建建造师数量', trigger: 'blur' }],
|
secondBuildingNumber: [{ required: true, message: '请输入二建建造师数量', trigger: 'blur' }],
|
||||||
build3: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'blur' }],
|
registeredEngineerNumber: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'blur' }],
|
||||||
build4: [{ required: true, message: '请输入其他注册人员数量', trigger: 'blur' }],
|
otherBuildingNumber: [{ required: true, message: '请输入其他注册人员数量', trigger: 'blur' }],
|
||||||
// 职称人员数量校验
|
// 职称人员数量校验
|
||||||
personnelNumber1: [{ required: true, message: '请输入高级工程师数量', trigger: 'blur' }],
|
seniorEngineerNumber: [{ required: true, message: '请输入高级工程师数量', trigger: 'blur' }],
|
||||||
personnelNumber2: [{ required: true, message: '请输入工程师数量', trigger: 'blur' }],
|
engineerNumber: [{ required: true, message: '请输入工程师数量', trigger: 'blur' }],
|
||||||
personnelNumber3: [{ required: true, message: '请输入助理工程师数量', trigger: 'blur' }],
|
assistantEngineerNumber: [{ required: true, message: '请输入助理工程师数量', trigger: 'blur' }],
|
||||||
personnelNumber4: [{ required: true, message: '请输入其他职称人员数量', trigger: 'blur' }]
|
otherPersonnelNumber: [{ required: true, message: '请输入其他职称人员数量', trigger: 'blur' }]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,22 +455,26 @@ const handleTypeChange = () => {
|
|||||||
form.value.registeredNumber = undefined;
|
form.value.registeredNumber = undefined;
|
||||||
form.value.personnelNumber = undefined;
|
form.value.personnelNumber = undefined;
|
||||||
// 清空表单单独字段
|
// 清空表单单独字段
|
||||||
form.value.build1 = form.value.build2 = form.value.build3 = form.value.build4 = undefined;
|
form.value.firstBuildingNumber =
|
||||||
form.value.personnelNumber1 = form.value.personnelNumber2 = form.value.personnelNumber3 = form.value.personnelNumber4 = undefined;
|
form.value.secondBuildingNumber =
|
||||||
|
form.value.registeredEngineerNumber =
|
||||||
|
form.value.otherBuildingNumber =
|
||||||
|
undefined;
|
||||||
|
form.value.seniorEngineerNumber = form.value.engineerNumber = form.value.assistantEngineerNumber = form.value.otherPersonnelNumber = undefined;
|
||||||
}
|
}
|
||||||
// 重置隐藏字段的校验状态,避免错误提示残留
|
// 重置隐藏字段的校验状态,避免错误提示残留
|
||||||
supplierInputFormRef.value?.clearValidate([
|
supplierInputFormRef.value?.clearValidate([
|
||||||
'safeCode',
|
'safeCode',
|
||||||
'safeCodeData',
|
'safeCodeData',
|
||||||
'safeCertificateValidity',
|
'safeCertificateValidity',
|
||||||
'build1',
|
'firstBuildingNumber',
|
||||||
'build2',
|
'secondBuildingNumber',
|
||||||
'build3',
|
'registeredEngineerNumber',
|
||||||
'build4',
|
'otherBuildingNumber',
|
||||||
'personnelNumber1',
|
'seniorEngineerNumber',
|
||||||
'personnelNumber2',
|
'engineerNumber',
|
||||||
'personnelNumber3',
|
'assistantEngineerNumber',
|
||||||
'personnelNumber4'
|
'otherPersonnelNumber'
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -517,18 +521,18 @@ const resetQuery = () => {
|
|||||||
const splitBackEndStrToForm = (resData: any) => {
|
const splitBackEndStrToForm = (resData: any) => {
|
||||||
if (resData.registeredNumber) {
|
if (resData.registeredNumber) {
|
||||||
const registeredArr = resData.registeredNumber.split(',');
|
const registeredArr = resData.registeredNumber.split(',');
|
||||||
form.value.build1 = registeredArr[0] || undefined; // 一建建造师
|
form.value.firstBuildingNumber = registeredArr[0] || undefined; // 一建建造师
|
||||||
form.value.build2 = registeredArr[1] || undefined; // 二建建造师
|
form.value.secondBuildingNumber = registeredArr[1] || undefined; // 二建建造师
|
||||||
form.value.build3 = registeredArr[2] || undefined; // 注册造价工程师
|
form.value.registeredEngineerNumber = registeredArr[2] || undefined; // 注册造价工程师
|
||||||
form.value.build4 = registeredArr[3] || undefined; // 其他注册人员
|
form.value.otherBuildingNumber = registeredArr[3] || undefined; // 其他注册人员
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resData.personnelNumber) {
|
if (resData.personnelNumber) {
|
||||||
const personnelArr = resData.personnelNumber.split(',');
|
const personnelArr = resData.personnelNumber.split(',');
|
||||||
form.value.personnelNumber1 = personnelArr[0] || undefined; // 高级工程师
|
form.value.seniorEngineerNumber = personnelArr[0] || undefined; // 高级工程师
|
||||||
form.value.personnelNumber2 = personnelArr[1] || undefined; // 工程师
|
form.value.engineerNumber = personnelArr[1] || undefined; // 工程师
|
||||||
form.value.personnelNumber3 = personnelArr[2] || undefined; // 助理工程师
|
form.value.assistantEngineerNumber = personnelArr[2] || undefined; // 助理工程师
|
||||||
form.value.personnelNumber4 = personnelArr[3] || undefined; // 其他职称人员
|
form.value.otherPersonnelNumber = personnelArr[3] || undefined; // 其他职称人员
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/** 审核过程按钮操作 */
|
/** 审核过程按钮操作 */
|
||||||
@ -572,6 +576,7 @@ const handleAdd = () => {
|
|||||||
dialog.title = '添加供应商入库';
|
dialog.title = '添加供应商入库';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const editFileId = ref('');
|
||||||
const handleUpdate = async (row?: SupplierInputVO) => {
|
const handleUpdate = async (row?: SupplierInputVO) => {
|
||||||
reset();
|
reset();
|
||||||
const _id = row?.id || ids.value[0];
|
const _id = row?.id || ids.value[0];
|
||||||
@ -579,7 +584,8 @@ const handleUpdate = async (row?: SupplierInputVO) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await getSupplierInput(_id);
|
const res = await getSupplierInput(_id);
|
||||||
const resData = res.data || {};
|
const resData: any = res.data || {};
|
||||||
|
editFileId.value = resData.fileId;
|
||||||
// 1. 基础字段回显
|
// 1. 基础字段回显
|
||||||
form.value = { ...form.value, ...resData, inputFile: '' };
|
form.value = { ...form.value, ...resData, inputFile: '' };
|
||||||
// 2. 核心修复:拆分后端拼接字符串到表单单独字段
|
// 2. 核心修复:拆分后端拼接字符串到表单单独字段
|
||||||
@ -594,32 +600,61 @@ const handleUpdate = async (row?: SupplierInputVO) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fileStatus = ref(false);
|
||||||
|
const updateFileStatus = ref(true);
|
||||||
|
const isUpdateFile = ref(false); //记录是否在修改页面时是否有新上传的文件
|
||||||
|
const handleFileChange = (file, fileList) => {
|
||||||
|
if (form.value.id) {
|
||||||
|
updateFileStatus.value = true;
|
||||||
|
isUpdateFile.value = true; //记录是否在修改页面时是否有新上传的文件
|
||||||
|
}
|
||||||
|
fileStatus.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileRemove = (file, fileList) => {
|
||||||
|
if (form.value.id) {
|
||||||
|
updateFileStatus.value = false;
|
||||||
|
isUpdateFile.value = false; //记录是否在修改页面时是否有新上传的文件
|
||||||
|
}
|
||||||
|
|
||||||
|
fileStatus.value = false;
|
||||||
|
};
|
||||||
/** 提交表单 */
|
/** 提交表单 */
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
supplierInputFormRef.value?.validate(async (valid: boolean) => {
|
supplierInputFormRef.value?.validate(async (valid: boolean) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (form.value.supplierType === '劳务') {
|
if (form.value.supplierType === '劳务') {
|
||||||
form.value.registeredNumber = [form.value.build1, form.value.build2, form.value.build3, form.value.build4].join(',');
|
form.value.registeredNumber = [
|
||||||
|
form.value.firstBuildingNumber,
|
||||||
|
form.value.secondBuildingNumber,
|
||||||
|
form.value.registeredEngineerNumber,
|
||||||
|
form.value.otherBuildingNumber
|
||||||
|
].join(',');
|
||||||
form.value.personnelNumber = [
|
form.value.personnelNumber = [
|
||||||
form.value.personnelNumber1,
|
form.value.seniorEngineerNumber,
|
||||||
form.value.personnelNumber2,
|
form.value.engineerNumber,
|
||||||
form.value.personnelNumber3,
|
form.value.assistantEngineerNumber,
|
||||||
form.value.personnelNumber4
|
form.value.otherPersonnelNumber
|
||||||
].join(',');
|
].join(',');
|
||||||
}
|
}
|
||||||
buttonLoading.value = true;
|
buttonLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (fileUploadRef.value) {
|
if (fileUploadRef.value) {
|
||||||
await fileUploadRef.value.submitUpload().then((res) => {
|
if (form.value.fileId === editFileId.value && !isUpdateFile.value) {
|
||||||
console.log(res);
|
console.log(1111111111);
|
||||||
if (res == 'noFile') {
|
|
||||||
proxy?.$modal.msgError('请上传文件');
|
editFormData();
|
||||||
return;
|
} else {
|
||||||
}
|
fileUploadRef.value.submitUpload().then((res) => {
|
||||||
proxy?.$modal.msgSuccess('操作成功');
|
if (res == 'noFile') {
|
||||||
dialog.visible = false;
|
proxy?.$modal.msgError('请上传文件');
|
||||||
getList();
|
return;
|
||||||
});
|
}
|
||||||
|
proxy?.$modal.msgSuccess('操作成功');
|
||||||
|
dialog.visible = false;
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
proxy?.$modal.msgError('提交失败,请重试');
|
proxy?.$modal.msgError('提交失败,请重试');
|
||||||
@ -628,7 +663,14 @@ const submitForm = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const editFormData = async () => {
|
||||||
|
const res = await updateSupplierInput(form.value);
|
||||||
|
if ((res.code = 200)) {
|
||||||
|
proxy?.$modal.msgSuccess('操作成功');
|
||||||
|
dialog.visible = false;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
};
|
||||||
/** 删除操作 */
|
/** 删除操作 */
|
||||||
const handleDelete = async (row?: SupplierInputVO) => {
|
const handleDelete = async (row?: SupplierInputVO) => {
|
||||||
const _ids = row?.id || ids.value;
|
const _ids = row?.id || ids.value;
|
||||||
|
@ -122,41 +122,41 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="mb-4" v-if="form.supplierType === '劳务'">
|
<el-row class="mb-4" v-if="form.supplierType === '劳务'">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="一建建造师" prop="build1">
|
<el-form-item label="一建建造师" prop="firstBuildingNumber">
|
||||||
<el-input v-model="form.build1" placeholder="请输入一建建造师数量" clearable />
|
<el-input v-model="form.firstBuildingNumber" placeholder="请输入一建建造师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="二建建造师" prop="build2">
|
<el-form-item label="二建建造师" prop="secondBuildingNumber">
|
||||||
<el-input v-model="form.build2" placeholder="请输入二建建造师数量" clearable />
|
<el-input v-model="form.secondBuildingNumber" placeholder="请输入二建建造师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="其他(分别写)" prop="build4">
|
<el-form-item label="其他(分别写)" prop="otherBuildingNumber">
|
||||||
<el-input v-model="form.build3" placeholder="请输入其他人员数量" clearable />
|
<el-input v-model="form.otherBuildingNumber" placeholder="请输入其他人员数量" clearable />
|
||||||
</el-form-item> </el-col
|
</el-form-item> </el-col
|
||||||
><el-col :span="12">
|
><el-col :span="12">
|
||||||
<el-form-item label="注册造价工程师" prop="build3">
|
<el-form-item label="注册造价工程师" prop="registeredEngineerNumber">
|
||||||
<el-input v-model="form.build4" placeholder="请输入注册造价工程师数量" clearable />
|
<el-input v-model="form.registeredEngineerNumber" placeholder="请输入注册造价工程师数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="24" class="mb-4" v-if="form.supplierType === '劳务'">
|
<el-row :gutter="24" class="mb-4" v-if="form.supplierType === '劳务'">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="高级工程师人数" prop="personnelNumber1">
|
<el-form-item label="高级工程师人数" prop="seniorEngineerNumber">
|
||||||
<el-input v-model="form.personnelNumber1" placeholder="请输高级工程师数量" clearable />
|
<el-input v-model="form.seniorEngineerNumber" placeholder="请输高级工程师数量" clearable />
|
||||||
</el-form-item> </el-col
|
</el-form-item> </el-col
|
||||||
><el-col :span="12">
|
><el-col :span="12">
|
||||||
<el-form-item label="工程师数量" prop="personnelNumber2">
|
<el-form-item label="工程师数量" prop="engineerNumber">
|
||||||
<el-input v-model="form.personnelNumber2" placeholder="请输入工程师数量" clearable />
|
<el-input v-model="form.engineerNumber" placeholder="请输入工程师数量" clearable />
|
||||||
</el-form-item> </el-col
|
</el-form-item> </el-col
|
||||||
><el-col :span="12">
|
><el-col :span="12">
|
||||||
<el-form-item label="助理工程师数量" prop="personnelNumber3">
|
<el-form-item label="助理工程师数量" prop="assistantEngineerNumber">
|
||||||
<el-input v-model="form.personnelNumber3" placeholder="请输入助理工程师数量" clearable />
|
<el-input v-model="form.assistantEngineerNumber" placeholder="请输入助理工程师数量" clearable />
|
||||||
</el-form-item> </el-col
|
</el-form-item> </el-col
|
||||||
><el-col :span="12">
|
><el-col :span="12">
|
||||||
<el-form-item label="其他人员数量" prop="personnelNumber4">
|
<el-form-item label="其他人员数量" prop="otherPersonnelNumber">
|
||||||
<el-input v-model="form.personnelNumber4" placeholder="请输入其他人员数量" clearable />
|
<el-input v-model="form.otherPersonnelNumber" placeholder="请输入其他人员数量" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -270,14 +270,14 @@ const initFormData = {
|
|||||||
inputFile: undefined,
|
inputFile: undefined,
|
||||||
state: '0', // 新增默认待审核
|
state: '0', // 新增默认待审核
|
||||||
// 新增:用于表单输入的单独字段
|
// 新增:用于表单输入的单独字段
|
||||||
build1: undefined, // 一建建造师
|
firstBuildingNumber: undefined, // 一建建造师
|
||||||
build2: undefined, // 二建建造师
|
secondBuildingNumber: undefined, // 二建建造师
|
||||||
build3: undefined, // 注册造价工程师
|
registeredEngineerNumber: undefined, // 注册造价工程师
|
||||||
build4: undefined, // 其他注册人员
|
otherBuildingNumber: undefined, // 其他注册人员
|
||||||
personnelNumber1: undefined, // 高级工程师
|
seniorEngineerNumber: undefined, // 高级工程师
|
||||||
personnelNumber2: undefined, // 工程师
|
engineerNumber: undefined, // 工程师
|
||||||
personnelNumber3: undefined, // 助理工程师
|
assistantEngineerNumber: undefined, // 助理工程师
|
||||||
personnelNumber4: undefined // 其他职称人员
|
otherPersonnelNumber: undefined
|
||||||
};
|
};
|
||||||
const data = reactive<PageData<LeaveForm, LeaveQuery>>({
|
const data = reactive<PageData<LeaveForm, LeaveQuery>>({
|
||||||
form: { ...initFormData },
|
form: { ...initFormData },
|
||||||
@ -332,17 +332,27 @@ const getInfo = () => {
|
|||||||
buttonLoading.value = false;
|
buttonLoading.value = false;
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
const res = await getSupplierInput(routeParams.value.id);
|
const res = await getSupplierInput(routeParams.value.id);
|
||||||
|
console.log(res, '------------------res');
|
||||||
|
|
||||||
Object.assign(form.value, res.data);
|
Object.assign(form.value, res.data);
|
||||||
form.value.registeredNumber = form.value.registeredNumber?.split(',');
|
// form.value.firstBuildingNumber=res.data.firstBuildingNumber, // 一建建造师
|
||||||
form.value.build1 = form.value.registeredNumber[0] || '';
|
// secondBuildingNumber: undefined, // 二建建造师
|
||||||
form.value.build2 = form.value.registeredNumber[1] || '';
|
// registeredEngineerNumber: undefined, // 注册造价工程师
|
||||||
form.value.build3 = form.value.registeredNumber[2] || '';
|
// otherBuildingNumber: undefined, // 其他注册人员
|
||||||
form.value.build4 = form.value.registeredNumber[3] || '';
|
// seniorEngineerNumber: undefined, // 高级工程师
|
||||||
form.value.personnelNumber = form.value.personnelNumber?.split(',');
|
// engineerNumber: undefined, // 工程师
|
||||||
form.value.personnelNumber1 = form.value.personnelNumber[0] || '';
|
// assistantEngineerNumber: undefined, // 助理工程师
|
||||||
form.value.personnelNumber2 = form.value.personnelNumber[1] || '';
|
// otherPersonnelNumber: undefined
|
||||||
form.value.personnelNumber3 = form.value.personnelNumber[2] || '';
|
// form.value.registeredNumber = form.value.registeredNumber?.split(',');
|
||||||
form.value.personnelNumber4 = form.value.personnelNumber[3] || '';
|
// form.value.build1 = form.value.registeredNumber[0] || '';
|
||||||
|
// form.value.build2 = form.value.registeredNumber[1] || '';
|
||||||
|
// form.value.build3 = form.value.registeredNumber[2] || '';
|
||||||
|
// form.value.build4 = form.value.registeredNumber[3] || '';
|
||||||
|
// form.value.personnelNumber = form.value.personnelNumber?.split(',');
|
||||||
|
// form.value.personnelNumber1 = form.value.personnelNumber[0] || '';
|
||||||
|
// form.value.personnelNumber2 = form.value.personnelNumber[1] || '';
|
||||||
|
// form.value.personnelNumber3 = form.value.personnelNumber[2] || '';
|
||||||
|
// form.value.personnelNumber4 = form.value.personnelNumber[3] || '';
|
||||||
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
buttonLoading.value = false;
|
buttonLoading.value = false;
|
||||||
|
230
vite.config.ts.timestamp-1756887630311-9edbd99a3287f.mjs
Normal file
230
vite.config.ts.timestamp-1756887630311-9edbd99a3287f.mjs
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user