合并
This commit is contained in:
@ -69,7 +69,8 @@
|
||||
"vue-types": "5.1.3",
|
||||
"vue3-print-nb": "^0.1.4",
|
||||
"vue3-scroll-seamless": "^1.0.6",
|
||||
"vxe-table": "4.5.22"
|
||||
"vxe-table": "4.5.22",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.15.0",
|
||||
|
Binary file not shown.
@ -24,3 +24,11 @@ export const exportWord = (params) => {
|
||||
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
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取人员列表
|
||||
* @param query
|
||||
*/
|
||||
export const copyUserList = (params) => {
|
||||
return request({
|
||||
url: '/design/volumeCatalog/copyUserList',
|
||||
method: 'get',
|
||||
params: params
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取二维码信息
|
||||
* @param query
|
||||
|
@ -75,3 +75,11 @@ export const inventoryList = (id: any) => {
|
||||
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'
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 打卡规则
|
||||
* @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',
|
||||
method: 'get',
|
||||
params: {
|
||||
deptId
|
||||
deptId,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import { ProjectTeamVO } from '@/api/project/projectTeam/types';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
export const getProjectTeam = async () => {
|
||||
const isPermission = useUserStore().permissions.some((item) => item == 'project:team:list');
|
||||
console.log(useUserStore().permissions);
|
||||
|
||||
if (!isPermission && useUserStore().permissions[0] != '*:*:*') return;
|
||||
|
||||
const { id } = $cache.local.getJSON('selectedProject');
|
||||
|
@ -5,7 +5,7 @@
|
||||
<el-form :model="queryForm" :inline="true">
|
||||
<el-form-item label="版本号" prop="versions">
|
||||
<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-form-item>
|
||||
<el-form-item label="表名" prop="sheet">
|
||||
@ -166,7 +166,8 @@ const getTableData = async () => {
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
sheet: queryForm.value.sheet,
|
||||
versions: queryForm.value.versions
|
||||
versions: queryForm.value.versions,
|
||||
type: '1'
|
||||
};
|
||||
const res = await getTreeLimit(params);
|
||||
loading.value = false;
|
||||
|
@ -210,7 +210,8 @@ const getListTable = async () => {
|
||||
const res = await getTreeLimit({
|
||||
projectId: currentProject.value?.id,
|
||||
versions: form.value.versions,
|
||||
sheet: form.value.sheet
|
||||
sheet: form.value.sheet,
|
||||
type: '0'
|
||||
});
|
||||
if (res.code == 200) {
|
||||
tableData.value = res.data;
|
||||
|
@ -5,7 +5,7 @@
|
||||
<el-form :model="queryForm" :inline="true">
|
||||
<el-form-item label="版本号" prop="versions">
|
||||
<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-form-item>
|
||||
<el-form-item label="表名" prop="sheet">
|
||||
@ -184,7 +184,8 @@ const getTableData = async () => {
|
||||
const params = {
|
||||
projectId: currentProject.value?.id,
|
||||
sheet: queryForm.value.sheet,
|
||||
versions: queryForm.value.versions
|
||||
versions: queryForm.value.versions,
|
||||
type: '0'
|
||||
};
|
||||
const res = await getTreeLimit(params);
|
||||
loading.value = false;
|
||||
@ -288,7 +289,7 @@ const handleExport = () => {
|
||||
projectId: currentProject.value?.id,
|
||||
sheet: queryForm.value.sheet
|
||||
},
|
||||
`限价一览表${queryForm.value.sheet}.xlsx`
|
||||
`投标成本核算${queryForm.value.sheet}.xlsx`
|
||||
);
|
||||
};
|
||||
// 审核
|
||||
|
@ -138,9 +138,14 @@
|
||||
<el-table-column prop="useQuantity" label="剩余量" align="center">
|
||||
<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>
|
||||
</el-table-column>
|
||||
@ -149,12 +154,16 @@
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<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) ==
|
||||
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)
|
||||
).toFixed(2)
|
||||
}}
|
||||
@ -328,18 +337,10 @@ const getVersionNums = async () => {
|
||||
getSheetName();
|
||||
} else {
|
||||
treeForm.value.versions = '';
|
||||
ElMessage({
|
||||
message: '获取版本号失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取版本号失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
};
|
||||
//获取表名
|
||||
@ -356,19 +357,11 @@ const getSheetName = async () => {
|
||||
treeForm.value.sheet = res.data[0];
|
||||
} else {
|
||||
treeForm.value.sheet = '';
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
getTreeList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleSelection = (selection: any) => {
|
||||
|
@ -124,7 +124,7 @@ const loading = ref(false);
|
||||
const options = ref<any[]>([]);
|
||||
const sheets = ref<any[]>([]);
|
||||
const tableData = ref<any[]>([]);
|
||||
const isExpandAll = ref(false);
|
||||
const isExpandAll = ref(true);
|
||||
const reviewStatus = ref('');
|
||||
const versionObj: any = ref({});
|
||||
const versionMap = new Map();
|
||||
@ -150,18 +150,10 @@ const getVersionNums = async () => {
|
||||
getSheetName();
|
||||
} else {
|
||||
queryForm.value.versions = '';
|
||||
ElMessage({
|
||||
message: '获取版本号失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取版本号失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
};
|
||||
//选择版本号
|
||||
@ -193,19 +185,11 @@ const getSheetName = async () => {
|
||||
queryForm.value.sheet = res.data[0];
|
||||
} else {
|
||||
queryForm.value.sheet = '';
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
getTableData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
};
|
||||
//获取表格
|
||||
|
@ -65,7 +65,7 @@
|
||||
>
|
||||
<el-row :gutter="8" class="items-top">
|
||||
<!-- 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
|
||||
:prop="`designers.${configIndex}.userMajor`"
|
||||
:rules="[
|
||||
@ -76,7 +76,8 @@
|
||||
label-width="60px"
|
||||
label="专业"
|
||||
>
|
||||
<el-select filterable
|
||||
<el-select
|
||||
filterable
|
||||
v-model="form.designers[configIndex].userMajor"
|
||||
placeholder="请选择专业"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@ -109,7 +110,8 @@
|
||||
label="设计"
|
||||
label-width="50px"
|
||||
>
|
||||
<el-select filterable
|
||||
<el-select
|
||||
filterable
|
||||
v-model="person.userId"
|
||||
placeholder="选择人员"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@ -165,7 +167,8 @@
|
||||
label="校审"
|
||||
label-width="50px"
|
||||
>
|
||||
<el-select filterable
|
||||
<el-select
|
||||
filterable
|
||||
v-model="person.userId"
|
||||
placeholder="选择人员"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@ -221,7 +224,8 @@
|
||||
label="审定"
|
||||
label-width="50px"
|
||||
>
|
||||
<el-select filterable
|
||||
<el-select
|
||||
filterable
|
||||
v-model="person.userId"
|
||||
placeholder="选择人员"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@ -277,7 +281,8 @@
|
||||
label="审核"
|
||||
label-width="50px"
|
||||
>
|
||||
<el-select filterable
|
||||
<el-select
|
||||
filterable
|
||||
v-model="person.userId"
|
||||
placeholder="选择人员"
|
||||
class="w-full transition-all duration-300 border-gray-300"
|
||||
@ -318,7 +323,7 @@
|
||||
</el-col>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<el-col :span="2" class="text-right pr-4">
|
||||
<el-col :span="2" class="pr-4 mt-2 text-right">
|
||||
<el-button
|
||||
type="text"
|
||||
class="text-red-500 hover:text-red-700 transition-colors"
|
||||
|
@ -6,7 +6,7 @@
|
||||
<el-card v-if="index < 3" shadow="always">
|
||||
<el-form :model="state.queryForm" :inline="true">
|
||||
<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-select>
|
||||
</el-form-item>
|
||||
@ -16,7 +16,7 @@
|
||||
</el-select>
|
||||
</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-button type="success" @click="downloadTemplate(1)">下载模板</el-button>
|
||||
@ -62,15 +62,10 @@
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<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 v-if="state.versionsData.status == 'waiting' || state.versionsData.status == 'finish'">
|
||||
<el-button
|
||||
icon="view"
|
||||
@click="lookApprovalFlow()"
|
||||
type="warning"
|
||||
>查看流程</el-button
|
||||
>
|
||||
<el-button icon="view" @click="lookApprovalFlow()" type="warning">查看流程</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
@ -171,6 +166,7 @@ const handleTabChange = (tab) => {
|
||||
onMounted(async () => {
|
||||
await getVersionNums();
|
||||
});
|
||||
|
||||
// 获取版本号
|
||||
async function getVersionNums(isSheet = true) {
|
||||
try {
|
||||
@ -247,10 +243,10 @@ async function handleSheetName() {
|
||||
|
||||
// 获取列表
|
||||
async function handleQueryList(isSheet = true) {
|
||||
if (isSheet && !state.queryForm.sheet) {
|
||||
console.warn('表名不存在,无法获取列表数据');
|
||||
return;
|
||||
}
|
||||
// if (isSheet && !state.queryForm) {
|
||||
// console.warn('表名不存在,无法获取列表数据');
|
||||
// return;
|
||||
// }
|
||||
|
||||
try {
|
||||
state.loading.list = true;
|
||||
@ -308,12 +304,12 @@ function handleChange(sheet) {
|
||||
function handleChangeVersion(versions) {
|
||||
state.queryForm.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 = [];
|
||||
handleQueryList();
|
||||
}
|
||||
// 在 openTable 方法中通过索引获取对应的表格实例
|
||||
function openTable( index) {
|
||||
function openTable(index) {
|
||||
isExpandAll.value = !isExpandAll.value;
|
||||
nextTick(() => {
|
||||
// 通过索引获取当前标签页的表格实例
|
||||
@ -358,12 +354,12 @@ function lookApprovalFlow(row) {
|
||||
const downloadTemplate = (type) => {
|
||||
// 导出模版文件
|
||||
try {
|
||||
let linkurl = '';
|
||||
let linkurl = '';
|
||||
let name = '';
|
||||
if (type==1) {
|
||||
if (type == 1) {
|
||||
linkurl = '/billOfQuantities.xlsx';
|
||||
name = '工程量清单模板.xlsx';
|
||||
}else{
|
||||
} else {
|
||||
linkurl = '/materialsEquipment.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">
|
||||
<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 class="p-6">
|
||||
<el-form
|
||||
|
@ -49,7 +49,32 @@
|
||||
<!-- 资料文件区域 -->
|
||||
<div class="mb-8">
|
||||
<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>
|
||||
@ -180,11 +205,11 @@ import { ref, reactive, computed, onMounted, onUnmounted, watch, getCurrentInsta
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { ElMessage, ElLoading, FormRules } from 'element-plus';
|
||||
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 type { ComponentInternalInstance, ElFormInstance } from 'element-plus';
|
||||
import { getInfo } from '@/api/login';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
// 全局实例与状态管理
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const userStore = useUserStoreHook();
|
||||
@ -200,7 +225,7 @@ const documentsFormRef = ref<ElFormInstance>();
|
||||
const userList = ref<any[]>([]);
|
||||
const userMap = new Map<string, string>(); // 存储用户ID与昵称映射
|
||||
const disabledAll = ref(false); // 表单是否全部禁用
|
||||
|
||||
const uploadRef = ref<any>();
|
||||
// 表单核心数据
|
||||
const form = reactive({
|
||||
projectId: currentProject.value?.id,
|
||||
@ -445,7 +470,66 @@ const onLoad = async () => {
|
||||
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(() => {
|
||||
// 先获取当前用户信息,再获取部门用户列表,最后回显表单数据
|
||||
|
@ -153,6 +153,11 @@
|
||||
<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>
|
||||
</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">
|
||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.cancellationIds"></file-upload>
|
||||
</el-form-item>
|
||||
@ -255,7 +260,8 @@ import {
|
||||
uploadVolumeFile,
|
||||
majorList,
|
||||
getVolumeCatafileList,
|
||||
volumeFileList
|
||||
volumeFileList,
|
||||
copyUserList
|
||||
} from '@/api/design/volumeCatalog';
|
||||
import { VolumeCatalogVO } from '@/api/design/volumeCatalog/types';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
@ -281,6 +287,7 @@ const uploadOpinionVisible = ref(false);
|
||||
const design = ref('');
|
||||
const total = ref(0);
|
||||
const dialogHistory = ref(false);
|
||||
const userCoryList = ref([]);
|
||||
const opinion = ref('');
|
||||
const updateRow = ref({
|
||||
opinion: []
|
||||
@ -416,7 +423,13 @@ const cancel = () => {
|
||||
reset();
|
||||
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 = () => {
|
||||
form.value = { ...initFormData };
|
||||
@ -546,7 +559,7 @@ const onSubmit = async () => {
|
||||
type: uploadForm.type
|
||||
};
|
||||
try {
|
||||
await uploadVolumeFile(obj);
|
||||
await uploadVolumeFile({ ...obj, userIds: form.value.userIds });
|
||||
proxy?.$modal.msgSuccess('文件上传成功');
|
||||
uploadVisible.value = false;
|
||||
await getList();
|
||||
@ -656,6 +669,7 @@ const handleAuditInfo = (row) => {
|
||||
// 审核图纸
|
||||
};
|
||||
onMounted(() => {
|
||||
getDesignUserList();
|
||||
getSpecialtyList();
|
||||
getList();
|
||||
});
|
||||
@ -666,6 +680,7 @@ const listeningProject = watch(
|
||||
(nid, oid) => {
|
||||
queryParams.value.projectId = nid;
|
||||
form.value.projectId = nid;
|
||||
getDesignUserList();
|
||||
getSpecialtyList();
|
||||
getList();
|
||||
}
|
||||
|
@ -81,7 +81,7 @@
|
||||
<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 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">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.planTheStartTime, '{y}-{m}-{d}') }}</span>
|
||||
|
@ -1,13 +1,11 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="auto">
|
||||
<el-form-item label="材料名称" prop="materialsName">
|
||||
<el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable
|
||||
@keyup.enter="handleQuery" />
|
||||
<el-input v-model="queryParams.materialsName" placeholder="请输入材料名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="材料提供商" prop="companyId">
|
||||
<el-select v-model="queryParams.companyId" clearable placeholder="全部">
|
||||
@ -27,22 +25,20 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<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-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
|
||||
v-hasPermi="['materials:materials:edit']">修改
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['materials:materials:remove']"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
||||
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-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['materials:materials:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@ -72,25 +68,28 @@
|
||||
<el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="320">
|
||||
<template #default="scope">
|
||||
<el-space>
|
||||
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)"
|
||||
v-hasPermi="['materials:materials:query']">
|
||||
<el-button link type="primary" icon="View" @click="handleShowDrawer(scope.row)" v-hasPermi="['materials:materials:query']">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)"
|
||||
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="success" icon="Edit" @click="handleUpdate(scope.row)" 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>
|
||||
<el-button v-hasPermi="['materials:materialsInventory:edit']" link type="primary" icon="Plus"
|
||||
@click="handleAddMaterialsInventory(scope.row)"> 出入库 </el-button>
|
||||
<el-button
|
||||
v-hasPermi="['materials:materialsInventory:edit']"
|
||||
link
|
||||
type="primary"
|
||||
icon="Plus"
|
||||
@click="handleAddMaterialsInventory(scope.row)"
|
||||
>
|
||||
出入库
|
||||
</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</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-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
@ -121,12 +120,17 @@
|
||||
<el-form-item label="材料文件" prop="fileOssIdMap">
|
||||
<div :key="item.value" v-for="item in materials_file_type">
|
||||
<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="
|
||||
(args) => {
|
||||
handleOssUpdate(args, item.value);
|
||||
}
|
||||
" />
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -137,8 +141,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<materials-inventory-add-dialog :materials-id="currentMaterialsId" :project-id="currentProject.id" ref="dialogRef"
|
||||
@submit="getList" />
|
||||
<materials-inventory-add-dialog :materials-id="currentMaterialsId" :project-id="currentProject.id" ref="dialogRef" @submit="getList" />
|
||||
<el-dialog title="材料详情" v-model="showDetailDrawer" width="700px">
|
||||
<materials-detail-drawer :materials-id="currentMaterialsId" />
|
||||
</el-dialog>
|
||||
|
@ -73,7 +73,10 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<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-col>
|
||||
<el-col :span="12">
|
||||
@ -123,11 +126,11 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
label="名称"
|
||||
:prop="`itemList.${index}.name`"
|
||||
:prop="`itemList.${index}.materialsId`"
|
||||
:rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]"
|
||||
>
|
||||
<el-select v-model="item.inventoryId" placeholder="请选择名称" @change="(value) => getNameChange(value, index, item)">
|
||||
<el-option v-for="opt in optionsName" :key="opt.id" :label="opt.materialsName" :value="opt.id" />
|
||||
<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}_${opt.createTime}`" :value="opt.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -168,13 +171,9 @@
|
||||
</el-col> -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="领取" :prop="`itemList.${index}.issuedQuantity`">
|
||||
<el-input
|
||||
v-model.number="item.issuedQuantity"
|
||||
disabled
|
||||
placeholder="请输入领取数量"
|
||||
@input="handleIssuedChange(index)"
|
||||
@blur="handleIssuedChange(index)"
|
||||
/>
|
||||
<el-select v-model="item.issuedQuantity" placeholder="请选择数量">
|
||||
<el-option v-for="opt in item.outList" :key="opt.id" :label="opt.number" :value="opt.number" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="12">
|
||||
@ -247,7 +246,8 @@ import {
|
||||
addMaterialIssue,
|
||||
updateMaterialIssue,
|
||||
inventoryList,
|
||||
getMaterialName
|
||||
getMaterialName,
|
||||
getMaterialInfo
|
||||
} from '@/api/materials/materialIssue';
|
||||
|
||||
import { MaterialIssueVO, MaterialIssueQuery, MaterialIssueForm } from '@/api/materials/materialIssue/types';
|
||||
@ -307,6 +307,7 @@ const getInitFormData = () => {
|
||||
itemList: [
|
||||
{
|
||||
id: undefined,
|
||||
|
||||
specification: undefined,
|
||||
unit: undefined,
|
||||
stockQuantity: undefined,
|
||||
@ -314,7 +315,8 @@ const getInitFormData = () => {
|
||||
remainingQuantity: undefined,
|
||||
name: undefined, // 数量验收的名称
|
||||
remark: undefined,
|
||||
materialsId: undefined
|
||||
materialsId: undefined,
|
||||
outList: []
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -365,7 +367,7 @@ const computeMaterialName = () => {
|
||||
.map((item) => item.name.trim())
|
||||
.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.issuedQuantity = selected.number;
|
||||
item.stockQuantity = Number(selected.inventoryNumber) || 0;
|
||||
item.outList = selected.outList || [];
|
||||
// calculateRemaining(index); // 计算剩余数量
|
||||
}
|
||||
};
|
||||
@ -529,8 +532,27 @@ const handleAdd = () => {
|
||||
dialog.title = '添加物料领料单';
|
||||
// 新增时初始计算材料名称
|
||||
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) => {
|
||||
reset();
|
||||
@ -597,6 +619,7 @@ const submitForm = () => {
|
||||
remainingQuantity: Number(item.remainingQuantity)
|
||||
}))
|
||||
};
|
||||
console.log('提交数据:', submitData);
|
||||
|
||||
if (form.value.id) {
|
||||
await updateMaterialIssue(submitData);
|
||||
@ -638,10 +661,13 @@ const addItem = () => {
|
||||
// 删除数量验收条目
|
||||
const removeItem = (index: number) => {
|
||||
if (form.value.itemList.length > 1) {
|
||||
console.log(111111);
|
||||
console.log(itemWatchStopFns.value[index]);
|
||||
|
||||
// 停止该条目的监听
|
||||
if (itemWatchStopFns.value[index]) {
|
||||
itemWatchStopFns.value[index]();
|
||||
}
|
||||
// if (itemWatchStopFns.value[index]) {
|
||||
// itemWatchStopFns.value[index]();
|
||||
// }
|
||||
form.value.itemList.splice(index, 1);
|
||||
itemWatchStopFns.value.splice(index, 1);
|
||||
// 删除后重新计算材料名称
|
||||
@ -682,7 +708,7 @@ watch(
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getName();
|
||||
// getName();
|
||||
});
|
||||
|
||||
// 监听项目id刷新数据
|
||||
@ -692,7 +718,7 @@ const listeningProject = watch(
|
||||
queryParams.value.projectId = nid;
|
||||
form.value.projectId = nid;
|
||||
getList();
|
||||
getName();
|
||||
// getName();
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<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>
|
||||
<td class="th-bg" colspan="2">{{ formData.storageUnit }}</td>
|
||||
</tr>
|
||||
|
@ -30,6 +30,9 @@
|
||||
>一键全部保存</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="toggleExpandAll">{{ isExpandAll ? '一键收起' : '一键展开' }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<right-toolbar @queryTable="getMasterDataList"></right-toolbar>
|
||||
</el-row>
|
||||
@ -38,6 +41,7 @@
|
||||
<el-table
|
||||
:data="state.tableData"
|
||||
v-loading="state.loading.list"
|
||||
ref="tableRef"
|
||||
stripe
|
||||
style="width: 100%; margin-bottom: 20px; height: calc(100vh - 230px)"
|
||||
row-key="id"
|
||||
@ -264,6 +268,17 @@ const formRules = reactive({
|
||||
],
|
||||
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() {
|
||||
try {
|
||||
|
@ -36,7 +36,6 @@
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="monthPlanList">
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column label="计划月份" align="center" prop="planMonth" />
|
||||
@ -82,7 +81,7 @@
|
||||
<el-form-item label="计划产值(元)" prop="planValue">
|
||||
<el-input v-model="form.planValue" placeholder="请输入计划产值" type="number" />
|
||||
</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-form-item>
|
||||
<el-form-item label="产值类型" prop="valueType">
|
||||
|
@ -175,7 +175,7 @@ const getInfo = () => {
|
||||
form.value = res.data as any;
|
||||
|
||||
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;
|
||||
loading.value = false;
|
||||
buttonLoading.value = false;
|
||||
@ -231,13 +231,15 @@ const approvalVerifyOpen = async () => {
|
||||
// 图纸上传成功之后 开始提交
|
||||
const submit = async (status, data) => {
|
||||
form.value = data;
|
||||
console.log(form.value);
|
||||
|
||||
if (status === 'draft') {
|
||||
buttonLoading.value = false;
|
||||
proxy?.$modal.msgSuccess('暂存成功');
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.go(-1);
|
||||
} else {
|
||||
const res = await isSubmit(data[1]?.id);
|
||||
const res = await isSubmit(data[0]?.mid);
|
||||
|
||||
if (!res.data) {
|
||||
proxy?.$modal.msgError('三种计划产值必须填写');
|
||||
|
@ -78,6 +78,7 @@
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 地块表单弹窗 -->
|
||||
<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">
|
||||
@ -107,20 +108,22 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 关联方阵弹窗(核心修改区域) -->
|
||||
|
||||
<!-- 关联方阵弹窗(核心修复区域) -->
|
||||
<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>
|
||||
<!-- 方阵表单:绑定unitBoList的索引,实现动态校验 -->
|
||||
<!-- 修复1:表单模型绑定formM(根模型),确保嵌套字段校验生效 -->
|
||||
<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-form-item
|
||||
label="方阵"
|
||||
:prop="`unitBoList[${i}].unitProjectId`"
|
||||
:rules="[
|
||||
{ required: true, message: '请选择方阵', trigger: 'change' },
|
||||
{ type: 'array', min: 2, message: '请选择完整的方阵层级', trigger: 'change' }
|
||||
{ type: 'array', min: 1, message: '请选择完整的方阵', trigger: 'change' }
|
||||
]"
|
||||
>
|
||||
<el-cascader
|
||||
@ -133,7 +136,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 所属工区:必填校验 -->
|
||||
<!-- 所属工区:保留原有规则 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item
|
||||
label="所属工区"
|
||||
@ -143,7 +146,7 @@
|
||||
<el-input v-model="item.unitProjectArea" placeholder="请输入所属工区" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 方阵状态:必填校验 -->
|
||||
<!-- 方阵状态:保留原有规则 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item
|
||||
label="方阵状态"
|
||||
@ -153,8 +156,15 @@
|
||||
<el-input v-model="item.unitProjectStatus" placeholder="请输入方阵状态" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 删除按钮:禁用逻辑优化(至少保留1项) -->
|
||||
<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-row>
|
||||
</el-form>
|
||||
@ -181,21 +191,35 @@ import {
|
||||
} from '@/api/system/landTransfer/landBlock';
|
||||
import { LandBlockVO, LandBlockQuery, LandBlockForm } from '@/api/system/landTransfer/landBlock/types';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { getCurrentInstance, ComponentInternalInstance, onMounted, onUnmounted, watch } from 'vue';
|
||||
import { ElFormInstance, ElMessage } from 'element-plus';
|
||||
import { getCurrentInstance, ComponentInternalInstance, onMounted, onUnmounted, watch, reactive, ref, toRefs, computed } from 'vue';
|
||||
import { ElFormInstance } from 'element-plus';
|
||||
|
||||
// 类型定义补充(避免any)
|
||||
// 类型定义补充
|
||||
interface DialogOption {
|
||||
visible: boolean;
|
||||
title: string;
|
||||
}
|
||||
|
||||
// 方阵级联选择器选项类型
|
||||
interface FangzhenOption {
|
||||
matrixId: string | number;
|
||||
name: string;
|
||||
children?: FangzhenOption[];
|
||||
}
|
||||
|
||||
// 方阵表单项类型
|
||||
interface UnitBoItem {
|
||||
unitProjectArea: string;
|
||||
unitProjectStatus: string;
|
||||
unitProjectId: (string | number)[]; // 级联选择值(数组)
|
||||
}
|
||||
|
||||
// 方阵表单根模型类型(关键:显式声明unitBoList)
|
||||
interface MatrixForm {
|
||||
landId?: string | number; // 关联的地块ID
|
||||
unitBoList: UnitBoItem[]; // 方阵列表
|
||||
}
|
||||
|
||||
// 基础实例与Store
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const userStore = useUserStoreHook();
|
||||
@ -203,14 +227,17 @@ const currentProject = computed(() => userStore.selectedProject);
|
||||
|
||||
// 响应式数据
|
||||
const landBlockList = ref<LandBlockVO[]>([]);
|
||||
const fangzhenList = ref<any[]>([]); // 方阵列表(实际项目建议定义具体类型)
|
||||
const fangzhenList = ref<FangzhenOption[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const uploadRef = ref<any>(null); // upload组件ref
|
||||
const uploadRef = ref<any>(null);
|
||||
|
||||
// 方阵表单数据(核心修改:初始值为空,避免默认填充无效数据)
|
||||
const unitBoList = ref<UnitBoItem[]>([{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }]);
|
||||
// 方阵表单模型(核心修复:使用reactive并显式声明结构)
|
||||
const formM = reactive<MatrixForm>({
|
||||
landId: undefined,
|
||||
unitBoList: [{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }]
|
||||
});
|
||||
|
||||
// 表格选择相关
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
@ -243,7 +270,6 @@ const initFormData: LandBlockForm = {
|
||||
// 核心数据(含表单规则)
|
||||
const data = reactive({
|
||||
form: { ...initFormData },
|
||||
formM: { landId: undefined }, // 方阵关联表单(仅存地块ID)
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
@ -256,7 +282,7 @@ const data = reactive({
|
||||
farmerCount: undefined,
|
||||
params: {}
|
||||
},
|
||||
// 地块表单规则(原有规则保留)
|
||||
// 地块表单规则
|
||||
rules: {
|
||||
id: [{ 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 () => {
|
||||
@ -381,10 +407,10 @@ const getfangzhenList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await subMatrix(currentProject.value.id);
|
||||
// 处理方阵数据(级联选择需父子结构,此处保留原有逻辑)
|
||||
// 处理方阵数据(级联选择需父子结构)
|
||||
res.data.forEach((item: any) => {
|
||||
item.children?.forEach((item2: any) => {
|
||||
item2.matrixId = `${item2.name}_${item2.matrixId}`; // 拼接名称+ID,便于后续拆分
|
||||
item2.matrixId = `${item2.name}_${item2.matrixId}`;
|
||||
});
|
||||
});
|
||||
fangzhenList.value = res.data;
|
||||
@ -395,68 +421,75 @@ const getfangzhenList = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 关联方阵(核心修改:打开弹窗前强制重置表单) */
|
||||
/** 关联方阵 */
|
||||
const handleView = async (row: LandBlockVO) => {
|
||||
if (!row?.id) return proxy?.$modal.msgWarning('请选择有效的地块');
|
||||
|
||||
// 1. 重置方阵表单(清空历史数据)
|
||||
// 重置方阵表单
|
||||
resetMatrix();
|
||||
// 2. 绑定当前地块ID
|
||||
formM.value.landId = row.id;
|
||||
// 3. 打开弹窗
|
||||
// 绑定当前地块ID
|
||||
formM.landId = row.id;
|
||||
// 打开弹窗
|
||||
dialogMatrix.visible = true;
|
||||
|
||||
dialogMatrix.title = `关联方阵(地块:${row.landName || row.landCode})`;
|
||||
};
|
||||
|
||||
/** 新增方阵表单项 */
|
||||
const addUnitBoItem = () => {
|
||||
unitBoList.value.push({
|
||||
formM.unitBoList.push({
|
||||
unitProjectArea: '',
|
||||
unitProjectStatus: '',
|
||||
unitProjectId: [] // 级联选择初始为空数组
|
||||
unitProjectId: []
|
||||
});
|
||||
// 重置校验状态
|
||||
landBlockFormMatrixRef.value?.clearValidate();
|
||||
};
|
||||
|
||||
/** 删除方阵表单项 */
|
||||
const removeUnitBoItem = (index: number) => {
|
||||
if (unitBoList.value.length <= 1) {
|
||||
if (formM.unitBoList.length <= 1) {
|
||||
return proxy?.$modal.msgWarning('至少保留一项方阵配置');
|
||||
}
|
||||
unitBoList.value.splice(index, 1);
|
||||
// 重置表单校验状态(避免删除后残留校验提示)
|
||||
formM.unitBoList.splice(index, 1);
|
||||
landBlockFormMatrixRef.value?.clearValidate();
|
||||
};
|
||||
|
||||
/** 提交方阵关联表单 */
|
||||
/** 提交方阵关联表单(核心修复:数据处理逻辑) */
|
||||
const submitFormMatrix = () => {
|
||||
landBlockFormMatrixRef.value?.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
if (!formM.value.landId) return proxy?.$modal.msgWarning('地块ID异常,请重新选择地块');
|
||||
if (!formM.landId) return proxy?.$modal.msgWarning('地块ID异常,请重新选择地块');
|
||||
|
||||
try {
|
||||
// 处理方阵数据(拆分名称+ID)
|
||||
const unitBoListParams = unitBoList.value.map((item) => {
|
||||
const [unitProjectName, unitProjectId] = item.unitProjectId[1]?.split('_') || [];
|
||||
if (!unitProjectId) throw new Error('方阵ID解析失败,请重新选择方阵');
|
||||
// 处理方阵数据(修复ID拆分逻辑)
|
||||
const unitBoListParams = formM.unitBoList.map((item) => {
|
||||
// 取级联选择的最后一层值
|
||||
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 {
|
||||
unitProjectArea: item.unitProjectArea.trim(),
|
||||
unitProjectStatus: item.unitProjectStatus.trim(),
|
||||
unitProjectId: unitProjectId, // 纯ID(后端需要)
|
||||
unitProjectName: unitProjectName // 名称(可选,用于显示)
|
||||
unitProjectId: unitProjectId,
|
||||
unitProjectName: unitProjectName
|
||||
};
|
||||
});
|
||||
|
||||
// 调用关联接口
|
||||
const res = await LandUnit({
|
||||
landId: formM.value.landId,
|
||||
landId: formM.landId,
|
||||
unitBoList: unitBoListParams
|
||||
});
|
||||
|
||||
if (res.code === 200) {
|
||||
proxy?.$modal.msgSuccess('关联方阵成功');
|
||||
dialogMatrix.visible = false;
|
||||
await getList(); // 刷新地块列表
|
||||
await getList();
|
||||
} else {
|
||||
proxy?.$modal.msgError(res.msg || '关联失败');
|
||||
}
|
||||
@ -472,13 +505,10 @@ const cancelMatrix = () => {
|
||||
dialogMatrix.visible = false;
|
||||
};
|
||||
|
||||
/** 方阵表单重置(核心修改:清空所有数据+重置校验) */
|
||||
/** 方阵表单重置 */
|
||||
const resetMatrix = () => {
|
||||
// 1. 清空地块ID
|
||||
formM.value.landId = undefined;
|
||||
// 2. 重置方阵列表(仅保留一个空项)
|
||||
unitBoList.value = [{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }];
|
||||
// 3. 重置表单校验状态
|
||||
formM.landId = undefined;
|
||||
formM.unitBoList = [{ unitProjectArea: '', unitProjectStatus: '', unitProjectId: [] }];
|
||||
if (landBlockFormMatrixRef.value) {
|
||||
landBlockFormMatrixRef.value.resetFields();
|
||||
landBlockFormMatrixRef.value.clearValidate();
|
||||
@ -491,11 +521,11 @@ const listeningProject = watch(
|
||||
(newId) => {
|
||||
if (newId) {
|
||||
queryParams.value.projectId = newId;
|
||||
getfangzhenList(); // 刷新方阵列表
|
||||
getList(); // 刷新地块列表
|
||||
getfangzhenList();
|
||||
getList();
|
||||
}
|
||||
},
|
||||
{ immediate: true } // 初始加载时执行一次
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
/** 导入Excel */
|
||||
@ -524,36 +554,34 @@ const handleImport = (options: { file: File }) => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
/** 导出模板 */
|
||||
const exportFile = () => {
|
||||
// 导出模版文件
|
||||
try {
|
||||
// 创建a标签
|
||||
const link = document.createElement('a');
|
||||
// 设置PDF文件路径 - 相对于public目录
|
||||
link.href = '/dikuai.xlsx';
|
||||
// 设置下载后的文件名
|
||||
link.download = '地块信息导入模版.xlsx';
|
||||
// 触发点击
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
// 清理
|
||||
document.body.removeChild(link);
|
||||
} catch (error) {
|
||||
alert('下载失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
/** 下载导入模板 */
|
||||
const downloadTemplate = () => {
|
||||
try {
|
||||
const link = document.createElement('a');
|
||||
link.href = '/landBlock.xlsx'; // 模板路径(需确保public目录下存在该文件)
|
||||
link.download = '地块信息导入模板.xlsx'; // 下载后文件名
|
||||
link.href = '/landBlock.xlsx';
|
||||
link.download = '地块信息导入模板.xlsx';
|
||||
document.body.appendChild(link);
|
||||
link.click(); // 触发下载
|
||||
link.click();
|
||||
} catch (err) {
|
||||
proxy?.$modal.msgError('模板下载失败,请重试');
|
||||
} 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 label="备注" align="center" prop="remark" />
|
||||
<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">
|
||||
<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>
|
||||
|
||||
<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="primary" icon="upload" @click="handleUpload(scope.row)" v-hasPermi="['project:project:saveTenderFile']"
|
||||
@ -160,7 +163,6 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改项目对话框 -->
|
||||
@ -253,78 +255,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</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>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@ -342,13 +272,12 @@
|
||||
</div>
|
||||
</template>
|
||||
</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>
|
||||
</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
|
||||
:project-id="projectId"
|
||||
:design-id="designId"
|
||||
@ -356,7 +285,7 @@
|
||||
@close="polygonStatus = false"
|
||||
></open-layers-map>
|
||||
</el-dialog>
|
||||
<el-dialog title="添加子项目" v-model="childProjectStatus" width="400">
|
||||
<el-dialog draggable title="添加子项目" v-model="childProjectStatus" width="400">
|
||||
<span>填写子项目名称</span>
|
||||
<el-input v-model="childProjectForm.projectName"></el-input>
|
||||
<template #footer>
|
||||
@ -366,7 +295,7 @@
|
||||
</span>
|
||||
</template>
|
||||
</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" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@ -375,6 +304,86 @@
|
||||
</div>
|
||||
</template>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
@ -382,14 +391,14 @@
|
||||
import {
|
||||
addChildProject,
|
||||
addProject,
|
||||
addProjectFacilities,
|
||||
addProjectPilePoint,
|
||||
addProjectSquare,
|
||||
delProject,
|
||||
uploadProjectFile,
|
||||
getProject,
|
||||
listProject,
|
||||
updateProject
|
||||
updateProject,
|
||||
attendanceRuleAdd,
|
||||
attendanceRuleEdit,
|
||||
byProjectIdDetail
|
||||
} from '@/api/project/project';
|
||||
import { ProjectForm, ProjectQuery, ProjectVO, childProjectQuery, locationType } from '@/api/project/project/types';
|
||||
import amap from '@/components/amap/index.vue';
|
||||
@ -413,6 +422,14 @@ const polygonStatus = ref(false);
|
||||
const dxfFile = ref(null);
|
||||
const projectId = 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>({
|
||||
projectName: '',
|
||||
pid: '',
|
||||
@ -432,7 +449,7 @@ const fileForm = ref({
|
||||
const jsonData = ref(null);
|
||||
const fullscreenLoading = ref(false);
|
||||
|
||||
const initFormData: ProjectForm = {
|
||||
const initFormData = {
|
||||
id: undefined,
|
||||
projectName: undefined,
|
||||
shortName: undefined,
|
||||
@ -451,13 +468,15 @@ const initFormData: ProjectForm = {
|
||||
lat: undefined,
|
||||
plan: undefined,
|
||||
onStreamTime: undefined,
|
||||
playCardStart: undefined,
|
||||
playCardEnd: undefined,
|
||||
clockInTime: undefined,
|
||||
clockOutTime: undefined,
|
||||
designTotal: undefined,
|
||||
securityAgreement: undefined,
|
||||
sort: 0,
|
||||
showHidden: undefined,
|
||||
isDelete: undefined
|
||||
isDelete: undefined,
|
||||
type: '1',
|
||||
weekday: []
|
||||
};
|
||||
const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
||||
form: { ...initFormData },
|
||||
@ -480,8 +499,6 @@ const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
||||
lat: undefined,
|
||||
plan: undefined,
|
||||
onStreamTime: undefined,
|
||||
playCardStart: undefined,
|
||||
playCardEnd: undefined,
|
||||
designTotal: undefined,
|
||||
securityAgreement: undefined,
|
||||
sort: undefined,
|
||||
@ -490,8 +507,8 @@ const data = reactive<PageData<ProjectForm, ProjectQuery>>({
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
playCardStart: [{ required: true, message: '打卡开始时间不能为空', trigger: 'blur' }],
|
||||
playCardEnd: [{ required: true, message: '打卡结束时间不能为空', trigger: 'blur' }],
|
||||
clockInTime: [{ required: true, message: '打卡开始时间不能为空', trigger: 'blur' }],
|
||||
clockOutTime: [{ required: true, message: '打卡结束时间不能为空', trigger: 'blur' }],
|
||||
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
|
||||
shortName: [{ 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 = () => {
|
||||
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-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-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">
|
||||
<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">
|
||||
@ -20,24 +28,27 @@
|
||||
<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-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-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-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 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>
|
||||
@ -50,18 +61,15 @@
|
||||
<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-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 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 v-has-permi="['system:user:remove']" type="danger" plain :disabled="multiple" icon="Delete" @click="handleDelete()">
|
||||
删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
@ -76,34 +84,26 @@
|
||||
<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-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>
|
||||
<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[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>
|
||||
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
@ -116,30 +116,24 @@
|
||||
<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-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-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-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-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-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-button v-hasPermi="['system:user:edit']" link type="primary" icon="Upload" @click="handleUploadCert(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -148,117 +142,47 @@
|
||||
<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" />
|
||||
<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 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>
|
||||
<el-dialog draggable ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="1300px" append-to-body @close="closeDialog">
|
||||
<div class="boxDetial">
|
||||
<div class="tab_info">
|
||||
<span @click="onTab(1)" :class="{ active: type == 1 }">基本资料</span>
|
||||
<span @click="onTab(2)" :class="{ active: type == 2 }">角色信息</span>
|
||||
</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 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-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>
|
||||
@ -270,8 +194,7 @@
|
||||
是否更新已经存在的用户数据
|
||||
</div>
|
||||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||||
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
|
||||
@click="importTemplate">下载模板 </el-link>
|
||||
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板 </el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
@ -307,7 +230,8 @@ 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';
|
||||
import roleInfo from './comm/roleInfo.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'));
|
||||
@ -326,7 +250,8 @@ const initPassword = ref<string>('');
|
||||
const postOptions = ref<PostVO[]>([]);
|
||||
const roleOptions = ref<RoleVO[]>([]);
|
||||
const projectOptions = ref<any[]>([]);
|
||||
|
||||
const editInfoRef = ref<InstanceType<typeof editInfo> | null>(null);
|
||||
const roleInfoRef = ref<InstanceType<typeof roleInfo> | null>(null);
|
||||
/*** 用户导入参数 */
|
||||
const upload = reactive<ImportOption>({
|
||||
// 是否显示弹出层(用户导入)
|
||||
@ -358,7 +283,8 @@ const queryFormRef = ref<ElFormInstance>();
|
||||
const userFormRef = ref<ElFormInstance>();
|
||||
const uploadRef = ref<ElUploadInstance>();
|
||||
const formDialogRef = ref<ElDialogInstance>();
|
||||
|
||||
const deptIdRole = ref<number>();
|
||||
const type = ref(1);
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
@ -452,7 +378,9 @@ watchEffect(
|
||||
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
|
||||
}
|
||||
);
|
||||
|
||||
const setDeptId = (deptId: number) => {
|
||||
deptIdRole.value = deptId;
|
||||
};
|
||||
/** 查询用户列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
@ -637,8 +565,12 @@ const cancel = () => {
|
||||
const handleAdd = async () => {
|
||||
reset();
|
||||
const { data } = await api.getUser();
|
||||
type.value = 1;
|
||||
dialog.visible = true;
|
||||
dialog.title = '新增用户';
|
||||
nextTick(() => {
|
||||
editInfoRef.value?.open();
|
||||
});
|
||||
postOptions.value = data.posts;
|
||||
form.value.password = initPassword.value.toString();
|
||||
};
|
||||
@ -646,19 +578,13 @@ const handleAdd = async () => {
|
||||
/** 修改按钮操作 */
|
||||
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;
|
||||
type.value = 1;
|
||||
form.value = row;
|
||||
nextTick(() => {
|
||||
editInfoRef.value?.open(row);
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
@ -764,6 +690,46 @@ const uploadCert = async () => {
|
||||
certDialog.value = false;
|
||||
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>
|
||||
|
||||
<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-select>
|
||||
</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-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
@ -139,7 +139,7 @@ const sheets = ref([]);
|
||||
const options = ref([]);
|
||||
const tableData = ref([]);
|
||||
const tableRef = ref();
|
||||
const isExpandAll = ref(false);
|
||||
const isExpandAll = ref(true);
|
||||
const loading = ref(false);
|
||||
const versionMap = new Map();
|
||||
|
||||
|
@ -191,9 +191,14 @@
|
||||
<el-table-column prop="useQuantity" label="剩余量" align="center">
|
||||
<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>
|
||||
</el-table-column>
|
||||
@ -219,12 +224,16 @@
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<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) ==
|
||||
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)
|
||||
).toFixed(2)
|
||||
}}
|
||||
@ -459,19 +468,11 @@ const getSheetName = async () => {
|
||||
treeForm.value.sheet = res.data[0];
|
||||
} else {
|
||||
treeForm.value.sheet = '';
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
getTreeList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
ElMessage({
|
||||
message: '获取表名失败',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleSelection = (selection: any) => {
|
||||
|
@ -234,17 +234,17 @@
|
||||
<!-- 第十一行:注册人员数量(仅劳务类型显示) -->
|
||||
<el-row :gutter="20" class="mb-4" v-if="form.supplierType === '劳务'">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="一建建造师" prop="build1">
|
||||
<el-input v-model="form.build1" placeholder="请输入一建建造师数量" clearable />
|
||||
<el-form-item label="一建建造师" prop="firstBuildingNumber">
|
||||
<el-input v-model="form.firstBuildingNumber" placeholder="请输入一建建造师数量" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="二建建造师" prop="build2">
|
||||
<el-input v-model="form.build2" placeholder="请输入二建建造师数量" clearable />
|
||||
<el-form-item label="二建建造师" prop="secondBuildingNumber">
|
||||
<el-input v-model="form.secondBuildingNumber" placeholder="请输入二建建造师数量" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="注册造价工程师" prop="build3">
|
||||
<el-input v-model="form.build3" placeholder="请输入注册造价工程师数量" clearable />
|
||||
<el-form-item label="注册造价工程师" prop="registeredEngineerNumber">
|
||||
<el-input v-model="form.registeredEngineerNumber" placeholder="请输入注册造价工程师数量" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="其他(分别写)" prop="build4">
|
||||
<el-input v-model="form.build4" placeholder="请输入其他人员数量" clearable />
|
||||
<el-form-item label="其他(分别写)" prop="otherBuildingNumber">
|
||||
<el-input v-model="form.otherBuildingNumber" placeholder="请输入其他人员数量" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@ -254,17 +254,17 @@
|
||||
<!-- 第十二行:职称人员数量(仅劳务类型显示) -->
|
||||
<el-row :gutter="20" class="mb-4" v-if="form.supplierType === '劳务'">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="高级工程师人数" prop="personnelNumber1">
|
||||
<el-input v-model="form.personnelNumber1" placeholder="请输高级工程师数量" clearable />
|
||||
<el-form-item label="高级工程师人数" prop="seniorEngineerNumber">
|
||||
<el-input v-model="form.seniorEngineerNumber" placeholder="请输高级工程师数量" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="工程师数量" prop="personnelNumber2">
|
||||
<el-input v-model="form.personnelNumber2" placeholder="请输入工程师数量" clearable />
|
||||
<el-form-item label="工程师数量" prop="engineerNumber">
|
||||
<el-input v-model="form.engineerNumber" placeholder="请输入工程师数量" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="助理工程师数量" prop="personnelNumber3">
|
||||
<el-input v-model="form.personnelNumber3" placeholder="请输入助理工程师数量" clearable />
|
||||
<el-form-item label="助理工程师数量" prop="assistantEngineerNumber">
|
||||
<el-input v-model="form.assistantEngineerNumber" placeholder="请输入助理工程师数量" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="其他人员数量" prop="personnelNumber4">
|
||||
<el-input v-model="form.personnelNumber4" placeholder="请输入其他人员数量" clearable />
|
||||
<el-form-item label="其他人员数量" prop="otherPersonnelNumber">
|
||||
<el-input v-model="form.otherPersonnelNumber" placeholder="请输入其他人员数量" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@ -285,8 +285,8 @@
|
||||
:data="form"
|
||||
uploadUrl="/supplierInput/supplierInput"
|
||||
:limit="1"
|
||||
:onUploadSuccess="handleUploadSuccess"
|
||||
@handleChange="change"
|
||||
@handleChange="handleFileChange"
|
||||
@handleRemove="handleFileRemove"
|
||||
showFileList
|
||||
>
|
||||
<div><el-button type="primary">上传文件</el-button><br /></div>
|
||||
@ -309,7 +309,7 @@
|
||||
<script setup name="SupplierInput" lang="ts">
|
||||
import { ComponentInternalInstance, getCurrentInstance, onMounted, ref, reactive, toRefs, computed } from 'vue';
|
||||
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 Pagination from '@/components/Pagination/index.vue';
|
||||
import RightToolbar from '@/components/RightToolbar/index.vue';
|
||||
@ -369,14 +369,14 @@ const initFormData: any = {
|
||||
inputFile: undefined,
|
||||
// state: '0', // 新增默认待审核
|
||||
// 新增:用于表单输入的单独字段
|
||||
build1: undefined, // 一建建造师
|
||||
build2: undefined, // 二建建造师
|
||||
build3: undefined, // 注册造价工程师
|
||||
build4: undefined, // 其他注册人员
|
||||
personnelNumber1: undefined, // 高级工程师
|
||||
personnelNumber2: undefined, // 工程师
|
||||
personnelNumber3: undefined, // 助理工程师
|
||||
personnelNumber4: undefined // 其他职称人员
|
||||
firstBuildingNumber: undefined, // 一建建造师
|
||||
secondBuildingNumber: undefined, // 二建建造师
|
||||
registeredEngineerNumber: undefined, // 注册造价工程师
|
||||
otherBuildingNumber: undefined, // 其他注册人员
|
||||
seniorEngineerNumber: undefined, // 高级工程师
|
||||
engineerNumber: undefined, // 工程师
|
||||
assistantEngineerNumber: undefined, // 助理工程师
|
||||
otherPersonnelNumber: undefined // 其他职称人员
|
||||
};
|
||||
// 核心数据(表单+查询参数)
|
||||
const data = reactive<PageData<SupplierInputForm, SupplierInputQuery>>({
|
||||
@ -411,14 +411,14 @@ const rules = computed(() => {
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
||||
],
|
||||
id: [{ required: true, message: 'ID不能为空', trigger: 'blur' }],
|
||||
build1: [{ required: true, message: '请输入一建建造师数量', trigger: 'change' }],
|
||||
build2: [{ required: true, message: '请输入二建建造师数量', trigger: 'change' }],
|
||||
build3: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'change' }],
|
||||
build4: [{ required: true, message: '请输入其他数量', trigger: 'change' }],
|
||||
personnelNumber1: [{ required: true, message: '请输入高级工程师数量', trigger: 'change' }],
|
||||
personnelNumber2: [{ required: true, message: '请输入工程师数量', trigger: 'change' }],
|
||||
personnelNumber3: [{ required: true, message: '请输入助理工程师数量', trigger: 'change' }],
|
||||
personnelNumber4: [{ required: true, message: '请输入其他数量', trigger: 'change' }]
|
||||
firstBuildingNumber: [{ required: true, message: '请输入一建建造师数量', trigger: 'change' }],
|
||||
secondBuildingNumber: [{ required: true, message: '请输入二建建造师数量', trigger: 'change' }],
|
||||
registeredEngineerNumber: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'change' }],
|
||||
otherBuildingNumber: [{ required: true, message: '请输入其他数量', trigger: 'change' }],
|
||||
seniorEngineerNumber: [{ required: true, message: '请输入高级工程师数量', trigger: 'change' }],
|
||||
engineerNumber: [{ required: true, message: '请输入工程师数量', trigger: 'change' }],
|
||||
assistantEngineerNumber: [{ required: true, message: '请输入助理工程师数量', trigger: 'change' }],
|
||||
otherPersonnelNumber: [{ required: true, message: '请输入其他数量', trigger: 'change' }]
|
||||
};
|
||||
|
||||
// 仅当类型为"劳务"时,添加安全生产许可证+人员数量校验
|
||||
@ -430,15 +430,15 @@ const rules = computed(() => {
|
||||
safeCodeData: [{ required: true, message: '请选择安全生产许可证发证日期', trigger: 'change' }],
|
||||
safeCertificateValidity: [{ required: true, message: '请选择安全生产许可证有效期', trigger: 'change' }],
|
||||
// 注册人员数量校验
|
||||
build1: [{ required: true, message: '请输入一建建造师数量', trigger: 'blur' }],
|
||||
build2: [{ required: true, message: '请输入二建建造师数量', trigger: 'blur' }],
|
||||
build3: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'blur' }],
|
||||
build4: [{ required: true, message: '请输入其他注册人员数量', trigger: 'blur' }],
|
||||
firstBuildingNumber: [{ required: true, message: '请输入一建建造师数量', trigger: 'blur' }],
|
||||
secondBuildingNumber: [{ required: true, message: '请输入二建建造师数量', trigger: 'blur' }],
|
||||
registeredEngineerNumber: [{ required: true, message: '请输入注册造价工程师数量', trigger: 'blur' }],
|
||||
otherBuildingNumber: [{ required: true, message: '请输入其他注册人员数量', trigger: 'blur' }],
|
||||
// 职称人员数量校验
|
||||
personnelNumber1: [{ required: true, message: '请输入高级工程师数量', trigger: 'blur' }],
|
||||
personnelNumber2: [{ required: true, message: '请输入工程师数量', trigger: 'blur' }],
|
||||
personnelNumber3: [{ required: true, message: '请输入助理工程师数量', trigger: 'blur' }],
|
||||
personnelNumber4: [{ required: true, message: '请输入其他职称人员数量', trigger: 'blur' }]
|
||||
seniorEngineerNumber: [{ required: true, message: '请输入高级工程师数量', trigger: 'blur' }],
|
||||
engineerNumber: [{ required: true, message: '请输入工程师数量', trigger: 'blur' }],
|
||||
assistantEngineerNumber: [{ required: true, message: '请输入助理工程师数量', trigger: 'blur' }],
|
||||
otherPersonnelNumber: [{ required: true, message: '请输入其他职称人员数量', trigger: 'blur' }]
|
||||
};
|
||||
}
|
||||
|
||||
@ -455,22 +455,26 @@ const handleTypeChange = () => {
|
||||
form.value.registeredNumber = undefined;
|
||||
form.value.personnelNumber = undefined;
|
||||
// 清空表单单独字段
|
||||
form.value.build1 = form.value.build2 = form.value.build3 = form.value.build4 = undefined;
|
||||
form.value.personnelNumber1 = form.value.personnelNumber2 = form.value.personnelNumber3 = form.value.personnelNumber4 = undefined;
|
||||
form.value.firstBuildingNumber =
|
||||
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([
|
||||
'safeCode',
|
||||
'safeCodeData',
|
||||
'safeCertificateValidity',
|
||||
'build1',
|
||||
'build2',
|
||||
'build3',
|
||||
'build4',
|
||||
'personnelNumber1',
|
||||
'personnelNumber2',
|
||||
'personnelNumber3',
|
||||
'personnelNumber4'
|
||||
'firstBuildingNumber',
|
||||
'secondBuildingNumber',
|
||||
'registeredEngineerNumber',
|
||||
'otherBuildingNumber',
|
||||
'seniorEngineerNumber',
|
||||
'engineerNumber',
|
||||
'assistantEngineerNumber',
|
||||
'otherPersonnelNumber'
|
||||
]);
|
||||
};
|
||||
|
||||
@ -517,18 +521,18 @@ const resetQuery = () => {
|
||||
const splitBackEndStrToForm = (resData: any) => {
|
||||
if (resData.registeredNumber) {
|
||||
const registeredArr = resData.registeredNumber.split(',');
|
||||
form.value.build1 = registeredArr[0] || undefined; // 一建建造师
|
||||
form.value.build2 = registeredArr[1] || undefined; // 二建建造师
|
||||
form.value.build3 = registeredArr[2] || undefined; // 注册造价工程师
|
||||
form.value.build4 = registeredArr[3] || undefined; // 其他注册人员
|
||||
form.value.firstBuildingNumber = registeredArr[0] || undefined; // 一建建造师
|
||||
form.value.secondBuildingNumber = registeredArr[1] || undefined; // 二建建造师
|
||||
form.value.registeredEngineerNumber = registeredArr[2] || undefined; // 注册造价工程师
|
||||
form.value.otherBuildingNumber = registeredArr[3] || undefined; // 其他注册人员
|
||||
}
|
||||
|
||||
if (resData.personnelNumber) {
|
||||
const personnelArr = resData.personnelNumber.split(',');
|
||||
form.value.personnelNumber1 = personnelArr[0] || undefined; // 高级工程师
|
||||
form.value.personnelNumber2 = personnelArr[1] || undefined; // 工程师
|
||||
form.value.personnelNumber3 = personnelArr[2] || undefined; // 助理工程师
|
||||
form.value.personnelNumber4 = personnelArr[3] || undefined; // 其他职称人员
|
||||
form.value.seniorEngineerNumber = personnelArr[0] || undefined; // 高级工程师
|
||||
form.value.engineerNumber = personnelArr[1] || undefined; // 工程师
|
||||
form.value.assistantEngineerNumber = personnelArr[2] || undefined; // 助理工程师
|
||||
form.value.otherPersonnelNumber = personnelArr[3] || undefined; // 其他职称人员
|
||||
}
|
||||
};
|
||||
/** 审核过程按钮操作 */
|
||||
@ -572,6 +576,7 @@ const handleAdd = () => {
|
||||
dialog.title = '添加供应商入库';
|
||||
};
|
||||
|
||||
const editFileId = ref('');
|
||||
const handleUpdate = async (row?: SupplierInputVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
@ -579,7 +584,8 @@ const handleUpdate = async (row?: SupplierInputVO) => {
|
||||
|
||||
try {
|
||||
const res = await getSupplierInput(_id);
|
||||
const resData = res.data || {};
|
||||
const resData: any = res.data || {};
|
||||
editFileId.value = resData.fileId;
|
||||
// 1. 基础字段回显
|
||||
form.value = { ...form.value, ...resData, inputFile: '' };
|
||||
// 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 = () => {
|
||||
supplierInputFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
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.personnelNumber1,
|
||||
form.value.personnelNumber2,
|
||||
form.value.personnelNumber3,
|
||||
form.value.personnelNumber4
|
||||
form.value.seniorEngineerNumber,
|
||||
form.value.engineerNumber,
|
||||
form.value.assistantEngineerNumber,
|
||||
form.value.otherPersonnelNumber
|
||||
].join(',');
|
||||
}
|
||||
buttonLoading.value = true;
|
||||
try {
|
||||
if (fileUploadRef.value) {
|
||||
await fileUploadRef.value.submitUpload().then((res) => {
|
||||
console.log(res);
|
||||
if (res == 'noFile') {
|
||||
proxy?.$modal.msgError('请上传文件');
|
||||
return;
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
});
|
||||
if (form.value.fileId === editFileId.value && !isUpdateFile.value) {
|
||||
console.log(1111111111);
|
||||
|
||||
editFormData();
|
||||
} else {
|
||||
fileUploadRef.value.submitUpload().then((res) => {
|
||||
if (res == 'noFile') {
|
||||
proxy?.$modal.msgError('请上传文件');
|
||||
return;
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
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 _ids = row?.id || ids.value;
|
||||
|
@ -122,41 +122,41 @@
|
||||
</el-row>
|
||||
<el-row class="mb-4" v-if="form.supplierType === '劳务'">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="一建建造师" prop="build1">
|
||||
<el-input v-model="form.build1" placeholder="请输入一建建造师数量" clearable />
|
||||
<el-form-item label="一建建造师" prop="firstBuildingNumber">
|
||||
<el-input v-model="form.firstBuildingNumber" placeholder="请输入一建建造师数量" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="二建建造师" prop="build2">
|
||||
<el-input v-model="form.build2" placeholder="请输入二建建造师数量" clearable />
|
||||
<el-form-item label="二建建造师" prop="secondBuildingNumber">
|
||||
<el-input v-model="form.secondBuildingNumber" placeholder="请输入二建建造师数量" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="其他(分别写)" prop="build4">
|
||||
<el-input v-model="form.build3" placeholder="请输入其他人员数量" clearable />
|
||||
<el-form-item label="其他(分别写)" prop="otherBuildingNumber">
|
||||
<el-input v-model="form.otherBuildingNumber" placeholder="请输入其他人员数量" clearable />
|
||||
</el-form-item> </el-col
|
||||
><el-col :span="12">
|
||||
<el-form-item label="注册造价工程师" prop="build3">
|
||||
<el-input v-model="form.build4" placeholder="请输入注册造价工程师数量" clearable />
|
||||
<el-form-item label="注册造价工程师" prop="registeredEngineerNumber">
|
||||
<el-input v-model="form.registeredEngineerNumber" placeholder="请输入注册造价工程师数量" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" class="mb-4" v-if="form.supplierType === '劳务'">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="高级工程师人数" prop="personnelNumber1">
|
||||
<el-input v-model="form.personnelNumber1" placeholder="请输高级工程师数量" clearable />
|
||||
<el-form-item label="高级工程师人数" prop="seniorEngineerNumber">
|
||||
<el-input v-model="form.seniorEngineerNumber" placeholder="请输高级工程师数量" clearable />
|
||||
</el-form-item> </el-col
|
||||
><el-col :span="12">
|
||||
<el-form-item label="工程师数量" prop="personnelNumber2">
|
||||
<el-input v-model="form.personnelNumber2" placeholder="请输入工程师数量" clearable />
|
||||
<el-form-item label="工程师数量" prop="engineerNumber">
|
||||
<el-input v-model="form.engineerNumber" placeholder="请输入工程师数量" clearable />
|
||||
</el-form-item> </el-col
|
||||
><el-col :span="12">
|
||||
<el-form-item label="助理工程师数量" prop="personnelNumber3">
|
||||
<el-input v-model="form.personnelNumber3" placeholder="请输入助理工程师数量" clearable />
|
||||
<el-form-item label="助理工程师数量" prop="assistantEngineerNumber">
|
||||
<el-input v-model="form.assistantEngineerNumber" placeholder="请输入助理工程师数量" clearable />
|
||||
</el-form-item> </el-col
|
||||
><el-col :span="12">
|
||||
<el-form-item label="其他人员数量" prop="personnelNumber4">
|
||||
<el-input v-model="form.personnelNumber4" placeholder="请输入其他人员数量" clearable />
|
||||
<el-form-item label="其他人员数量" prop="otherPersonnelNumber">
|
||||
<el-input v-model="form.otherPersonnelNumber" placeholder="请输入其他人员数量" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -270,14 +270,14 @@ const initFormData = {
|
||||
inputFile: undefined,
|
||||
state: '0', // 新增默认待审核
|
||||
// 新增:用于表单输入的单独字段
|
||||
build1: undefined, // 一建建造师
|
||||
build2: undefined, // 二建建造师
|
||||
build3: undefined, // 注册造价工程师
|
||||
build4: undefined, // 其他注册人员
|
||||
personnelNumber1: undefined, // 高级工程师
|
||||
personnelNumber2: undefined, // 工程师
|
||||
personnelNumber3: undefined, // 助理工程师
|
||||
personnelNumber4: undefined // 其他职称人员
|
||||
firstBuildingNumber: undefined, // 一建建造师
|
||||
secondBuildingNumber: undefined, // 二建建造师
|
||||
registeredEngineerNumber: undefined, // 注册造价工程师
|
||||
otherBuildingNumber: undefined, // 其他注册人员
|
||||
seniorEngineerNumber: undefined, // 高级工程师
|
||||
engineerNumber: undefined, // 工程师
|
||||
assistantEngineerNumber: undefined, // 助理工程师
|
||||
otherPersonnelNumber: undefined
|
||||
};
|
||||
const data = reactive<PageData<LeaveForm, LeaveQuery>>({
|
||||
form: { ...initFormData },
|
||||
@ -332,17 +332,27 @@ const getInfo = () => {
|
||||
buttonLoading.value = false;
|
||||
nextTick(async () => {
|
||||
const res = await getSupplierInput(routeParams.value.id);
|
||||
console.log(res, '------------------res');
|
||||
|
||||
Object.assign(form.value, res.data);
|
||||
form.value.registeredNumber = form.value.registeredNumber?.split(',');
|
||||
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] || '';
|
||||
// form.value.firstBuildingNumber=res.data.firstBuildingNumber, // 一建建造师
|
||||
// secondBuildingNumber: undefined, // 二建建造师
|
||||
// registeredEngineerNumber: undefined, // 注册造价工程师
|
||||
// otherBuildingNumber: undefined, // 其他注册人员
|
||||
// seniorEngineerNumber: undefined, // 高级工程师
|
||||
// engineerNumber: undefined, // 工程师
|
||||
// assistantEngineerNumber: undefined, // 助理工程师
|
||||
// otherPersonnelNumber: undefined
|
||||
// form.value.registeredNumber = form.value.registeredNumber?.split(',');
|
||||
// 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;
|
||||
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