项目周报界面更改

dev
lh 3 months ago
parent 5e0576c8a8
commit df06825b26

@ -8,7 +8,7 @@
"type": "module",
"scripts": {
"dev": "set NODE_OPTIONS=--no-experimental-strip-types && vite serve --mode development",
"dev": "vite serve --mode development",
"build:prod": "vite build --mode production",
"build:dev": "vite build --mode development",
"preview": "vite preview",

@ -86,15 +86,3 @@ export function getErpProjectInfoList(query) {
params: query
});
}
/**
* id
* @param query
* @returns {*}
*/
export const listProjectInfoByDept = (query?: ProjectInfoQuery): AxiosPromise<ProjectInfoVO[]> => {
return request({
url: '/oa/erp/projectInfo/listByDept',
method: 'get',
params: query
});
};

@ -104,6 +104,13 @@ export interface ProjectInfoVO {
*/
activeFlag: string;
deptName?: string;
managerName?: string;
chargeName?: string;
deputyName?: string;
}
export interface ProjectInfoForm extends BaseEntity {
@ -227,10 +234,16 @@ export interface ProjectInfoForm extends BaseEntity {
*/
bizExt?: any;
deptName?: string;
managerName?: string;
chargeName?: string;
deputyName?: string;
}
export interface ProjectInfoQuery extends PageQuery {
/**
* 1 2
*/
@ -330,7 +343,12 @@ export interface ProjectInfoQuery extends PageQuery {
*
*/
params?: any;
deptName?: string;
managerName?: string;
chargeName?: string;
deputyName?: string;
}

@ -15,6 +15,19 @@ export const listProjectReport = (query?: ProjectReportQuery): AxiosPromise<Proj
params: query
});
};
/**
* ID
* @param query
* @returns {*}
*/
export const listProjectReportByDept = (query?: ProjectReportQuery): AxiosPromise<ProjectReportVO[]> => {
return request({
url: '/oa/erp/projectReport/listByDept',
method: 'get',
params: query
});
};
/**
*

@ -1,4 +1,4 @@
export interface ProjectReportVO {
export interface ProjectReportVO extends extraInfo {
/**
* ID
*/
@ -67,10 +67,9 @@ export interface ProjectReportVO {
/**
*
*/
projectCode: string;
}
export interface ProjectReportForm extends BaseEntity {
export interface ProjectReportForm extends BaseEntity, extraInfo {
/**
* ID
*/
@ -142,7 +141,7 @@ export interface ProjectReportForm extends BaseEntity {
projectCode?: string;
}
export interface ProjectReportQuery extends PageQuery {
export interface ProjectReportQuery extends PageQuery, extraInfo {
/**
* ID
*/
@ -208,3 +207,13 @@ export interface ProjectReportQuery extends PageQuery {
*/
params?: any;
}
export interface extraInfo {
deptName?: string;
managerName?: string;
chargeName?: string;
deputyName?: string;
}

@ -24,21 +24,9 @@
</transition>
<el-card shadow="hover">
<template v-if="prop.multiple" #header>
<el-tag
v-for="material in selectMaterialList"
:key="material.materialId"
closable
style="margin: 2px"
@close="handleCloseTag(material)"
>
{{ material.saleMaterialName }}
</el-tag>
</template>
<vxe-table
ref="tableRef"
height="400px"
height="300px"
border
show-overflow
:data="projectInfoList"
@ -49,13 +37,13 @@
@checkbox-change="handleCheckboxChange"
>
<vxe-column type="checkbox" width="50" align="center" />
<!-- <vxe-column key="relationMaterialId" title="关联物料ID" align="center" field="relationMaterialId" />-->
<vxe-column key="projectCode" title="项目编码" align="center" field="projectCode" width="120" />
<vxe-column key="projectName" title="项目名称" align="center" field="projectName" width="120" />
<vxe-column key="managerId" title="项目经理" align="center" field="managerId" width="120" />
<vxe-column key="deptId" title="部门ID" align="center" field="deptId" width="120" />
<vxe-column key="chargeId" title="部门负责人" align="center" field="chargeId" width="120" />
<vxe-column key="business_direction" title="业务方向" align="center" field="business_direction" width="120" />
<vxe-column key="managerName" title="项目经理" align="center" field="managerName" width="120" />
<vxe-column key="deptName" title="部门ID" align="center" field="deptName" width="120" />
<vxe-column key="chargeName" title="部门负责人" align="center" field="chargeName" width="120" />
<vxe-column key="deputyName" title="分管副总" align="center" field="deputyName" width="120" />
<!-- <vxe-column key="business_direction" title="业务方向" align="center" field="business_direction" width="120" /> -->
<!-- <vxe-column key="customerName" title="客户名称" align="center" field="customerName" width="120" />
<vxe-column key="saleMaterialName" title="销售物料名称" align="center" field="saleMaterialName" width="120" /> -->
<!-- <vxe-column key="purchasePrice" title="采购单价(元)" align="center" field="purchasePrice" width="120" />-->
@ -91,7 +79,7 @@
import { VxeTableInstance } from 'vxe-table';
import useDialog from '@/hooks/useDialog';
import { ProjectInfoVO, ProjectInfoQuery, ProjectInfoForm } from '@/api/oa/erp/projectInfo/types';
import { listProjectInfoByDept, listProjectInfo, getProjectInfo, delProjectInfo, addProjectInfo, updateProjectInfo } from '@/api/oa/erp/projectInfo';
import { listProjectInfo } from '@/api/oa/erp/projectInfo';
interface PropType {
modelValue?: ProjectInfoVO[] | ProjectInfoVO | undefined;
@ -107,17 +95,17 @@ const prop = withDefaults(defineProps<PropType>(), {
const emit = defineEmits(['update:modelValue', 'confirmCallBack']);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { active_flag } = toRefs<any>(proxy?.useDict('active_flag'));
const materialInfoList = ref<RelationMaterialVO[]>([]);
const projectInfoList = ref<ProjectInfoVO[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const selectMaterialList = ref<RelationMaterialVO[]>([]);
//
const projectInfoList = ref<ProjectInfoVO[]>([]);
//
const selectProjectList = ref<ProjectInfoVO[]>([]);
const queryFormRef = ref<ElFormInstance>();
const tableRef = ref<VxeTableInstance<RelationMaterialVO>>();
const tableRef = ref<VxeTableInstance<ProjectInfoVO>>();
const projectSelectDialog = useDialog({
title: '项目选择'
@ -172,50 +160,11 @@ const projectSelectData = reactive<PageData<ProjectInfoForm, ProjectInfoQuery>>(
activeFlag: undefined,
params: {}
},
rules: {
contractFlag: [{ required: true, message: '有无合同不能为空', trigger: 'change' }],
projectCode: [{ required: true, message: '项目编号不能为空', trigger: 'blur' }],
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
businessDirection: [{ required: true, message: '业务方向不能为空', trigger: 'change' }],
projectCategory: [{ required: true, message: '项目类别不能为空', trigger: 'change' }]
}
rules: {}
});
const { queryParams, form, rules } = toRefs(projectSelectData);
const defaultSelectMaterialIds = computed(() => computedIds(prop.data));
const confirm = () => {
emit('update:modelValue', selectMaterialList.value);
emit('confirmCallBack', selectMaterialList.value);
projectSelectDialog.closeDialog();
};
const computedIds = (data) => {
if (data === '' || data === null || data === undefined) {
return [];
}
if (data instanceof Array) {
return data.map((item) => String(item));
} else if (typeof data === 'string') {
return data.split(',');
} else if (typeof data === 'number') {
return [String(data)];
} else {
console.warn('<MaterialSelect> The data type of data should be array or string or number, but I received other');
return [];
}
};
/** 根据部门id查询项目信息 */
const getList = async () => {
loading.value = true;
const res = await listProjectInfoByDept(queryParams.value);
projectInfoList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
@ -229,81 +178,78 @@ const resetQuery = (refresh = true) => {
refresh && handleQuery();
};
const pageList = async () => {
await getList();
const materials = materialInfoList.value.filter((item) => {
return selectMaterialList.value.some((material) => material.relationMaterialId === item.relationMaterialId);
});
await tableRef.value.setCheckboxRow(materials, true);
};
//
const handleCheckboxChange = (checked) => {
//
if (!prop.multiple && checked.checked) {
tableRef.value.setCheckboxRow(selectMaterialList.value, false);
selectMaterialList.value = [];
tableRef.value.setCheckboxRow(selectProjectList.value, false);
selectProjectList.value = [];
}
const row = checked.row;
if (checked.checked) {
selectMaterialList.value.push(row);
selectProjectList.value.push(row);
} else {
selectMaterialList.value = selectMaterialList.value.filter((item) => {
return item.relationMaterialId !== row.relationMaterialId;
selectProjectList.value = selectProjectList.value.filter((item) => {
return item.projectId !== row.projectId;
});
}
};
const handleCheckboxAll = (checked) => {
const rows = materialInfoList.value;
const rows = projectInfoList.value;
if (checked.checked) {
rows.forEach((row) => {
if (!selectMaterialList.value.some((item) => item.relationMaterialId === row.relationMaterialId)) {
selectMaterialList.value.push(row);
if (!selectProjectList.value.some((item) => item.projectId === row.projectId)) {
selectProjectList.value.push(row);
}
});
} else {
selectMaterialList.value = selectMaterialList.value.filter((item) => {
return !rows.some((row) => row.relationMaterialId === item.relationMaterialId);
selectProjectList.value = selectProjectList.value.filter((item) => {
return !rows.some((row) => row.projectId === item.projectId);
});
}
};
const handleCloseTag = (material: RelationMaterialVO) => {
const relationMaterialId = material.relationMaterialId;
// 使splice
const index = selectMaterialList.value.findIndex((item) => item.relationMaterialId === relationMaterialId);
const rows = selectMaterialList.value[index];
tableRef.value?.setCheckboxRow(rows, false);
selectMaterialList.value.splice(index, 1);
};
const initSelectMaterial = async () => {
if (defaultSelectMaterialIds.value.length > 0) {
//
const materials = materialInfoList.value.filter((item) => {
return defaultSelectMaterialIds.value.includes(String(item.relationMaterialId));
});
selectMaterialList.value = materials;
await nextTick(() => {
tableRef.value.setCheckboxRow(materials, true);
});
}
//
const pageList = async () => {
await getList();
const projectInfo = projectInfoList.value.filter((item) => {
return selectProjectList.value.some((projectInfo) => projectInfo.projectId === item.projectId);
});
await tableRef.value.setCheckboxRow(projectInfo, true);
};
const close = () => {
emit('confirmCallBack', []);
projectSelectDialog.closeDialog();
};
//
const confirm = () => {
emit('update:modelValue', selectProjectList.value);
emit('confirmCallBack', selectProjectList.value);
projectSelectDialog.closeDialog();
};
/** 查询项目信息 */
const getList = async () => {
loading.value = true;
const res = await listProjectInfo(queryParams.value);
projectInfoList.value = res.rows;
total.value = res.total;
loading.value = false;
};
watch(
() => projectSelectDialog.visible.value,
async (newValue: boolean) => {
if (newValue) {
await getList(); //
await initSelectMaterial();
} else {
tableRef.value.clearCheckboxReserve();
tableRef.value.clearCheckboxRow();
resetQuery(false);
selectMaterialList.value = [];
selectProjectList.value = [];
}
}
);

@ -102,7 +102,7 @@ export const constantRoutes: RouteRecordRaw[] = [
{
path: 'contractInfo/edit',
component: () => import('@/views/oa/erp/contractInfo/edit.vue'),
name: 'ContractInfoEdit',
name: 'ContractInfoEdit'
},
{
path: 'erpProjectPlan/edit/:projectPlanId',
@ -123,18 +123,18 @@ export const constantRoutes: RouteRecordRaw[] = [
name: 'ErpProjectPlanGantt',
meta: { title: '项目计划甘特图', activeMenu: '/oa/erp/erpProjectPlan' }
},
{
path: 'erpProjectChange/edit',
component: () => import('@/views/oa/erp/erpProjectChange/edit.vue'),
name: 'ErpProjectChangeEdit',
meta: { title: '项目变更', activeMenu: '/oa/erp/erpProjectPlan' }
},
{
path: 'erpProjectChange/edit/:projectChangeId',
component: () => import('@/views/oa/erp/erpProjectChange/edit.vue'),
name: 'ErpProjectChangeEditById',
meta: { title: '项目变更编辑', activeMenu: '/oa/erp/erpProjectPlan' }
}
{
path: 'erpProjectChange/edit',
component: () => import('@/views/oa/erp/erpProjectChange/edit.vue'),
name: 'ErpProjectChangeEdit',
meta: { title: '项目变更', activeMenu: '/oa/erp/erpProjectPlan' }
},
{
path: 'erpProjectChange/edit/:projectChangeId',
component: () => import('@/views/oa/erp/erpProjectChange/edit.vue'),
name: 'ErpProjectChangeEditById',
meta: { title: '项目变更编辑', activeMenu: '/oa/erp/erpProjectPlan' }
}
]
},
{
@ -153,7 +153,7 @@ export const constantRoutes: RouteRecordRaw[] = [
component: () => import('@/views/oa/crm/crmQuoteInfo/edit.vue'),
name: 'crmQuoteInfoView',
meta: { title: '报价单查看', activeMenu: '/oa/crm/crmQuoteInfo' }
},
}
]
},
{
@ -168,14 +168,11 @@ export const constantRoutes: RouteRecordRaw[] = [
meta: { title: '项目预算申请', activeMenu: '/erp/budgetInfo' }
}
]
},
}
];
// 动态路由,基于用户权限动态去加载
export const dynamicRoutes: RouteRecordRaw[] = [
];
export const dynamicRoutes: RouteRecordRaw[] = [];
/**
*

@ -82,7 +82,7 @@ const options = ref({
//
const renderTemplate = (str, data) => {
return str.replace(/#\{(.*?)\}/g, (_, path) => {
let arr = path.split('.');
const arr = path.split('.');
if (arr.length > 0) {
arr[0] = `#{${arr[0]}}`;
}
@ -96,7 +96,7 @@ const rowRenderTemplate = (str, index) => {
return templateData[`^{${path}}`][index] || ' ';
});
res = res.replace(/#\{(.*?)\}/g, (_, path) => {
let arr = path.split('.');
const arr = path.split('.');
if (arr.length > 0) {
arr[0] = `#{${arr[0]}}`;
}
@ -143,12 +143,12 @@ const fillRowData = (e, index) => {
//
const tableTemplate = (table) => {
let data = JSON.parse(JSON.stringify(table));
let arr = [];
const data = JSON.parse(JSON.stringify(table));
const arr = [];
data.forEach((item) => {
let [bol, length] = hasCaretPattern(JSON.parse(JSON.stringify(item.content)));
const [bol, length] = hasCaretPattern(JSON.parse(JSON.stringify(item.content)));
if (bol) {
let obj = JSON.parse(JSON.stringify(item));
const obj = JSON.parse(JSON.stringify(item));
Array(length)
.fill(0)
.forEach((_, index) => {
@ -212,8 +212,8 @@ onMounted(async () => {
getPrintTemplate(route.query.templateId).then((e) => {
template.value = e.data;
const editor = editorRef.value;
let docData = JSON.parse(e.data.templateData || '{}');
let data = fillData(docData);
const docData = JSON.parse(e.data.templateData || '{}');
const data = fillData(docData);
// console.log(data);
// console.log(JSON.parse(e.data.templateData || '{}'));
// editor.setContent(JSON.parse(e.data.templateData || '{}'));

@ -0,0 +1,851 @@
<template>
<div class="p-2">
<el-card shadow="never">
<!-- 审批按钮组件 -->
<approvalButton
@submitForm="submitForm"
@approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="form.projectId"
:status="form.flowStatus"
:pageType="routeParams.type"
:mode="false"
/>
<el-form
ref="contractInfoFormRef"
:model="form"
:loading="buttonLoading"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
:rules="rules"
label-width="120px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="form.projectCode" placeholder="请输入项目编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="里程碑计划" prop="milestonePlan">
<el-input v-model="form.milestonePlan" placeholder="请输入里程碑计划" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目经理" prop="managerName">
<el-input v-model="form.managerName" placeholder="请输入项目经理" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门负责人" prop="chargeName">
<el-input v-model="form.chargeName" placeholder="请输入部门负责人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分管副总" prop="deputyName">
<el-input v-model="form.deputyName" placeholder="请输入分管副总" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="附件" prop="ossId">
<el-button type="primary" plain icon="Upload" @click="handleFile"></el-button>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="form.projectId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="项目经理ID" prop="managerId">
<el-input v-model="form.managerId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="部门ID" prop="deptId">
<el-input v-model="form.deptId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="部门负责人ID" prop="chargeId">
<el-input v-model="form.chargeId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="分管副总ID" prop="deputyId">
<el-input v-model="form.deputyId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="附件ID" prop="ossId">
<el-input v-model="form.ossId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="激活标识" prop="activeFlag">
<el-input v-model="form.activeFlag" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="周报说明" prop="informationNote">
<el-input v-model="form.informationNote" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 合同物料管理区域 -->
<el-card shadow="never" style="margin-top: 20px">
<template #header>
<div style="text-align: left; font-weight: bold; font-size: 18px">合同物料管理</div>
</template>
<!-- 合同物料表格 -->
<div style="margin-bottom: 16px">
<el-button type="primary" icon="Plus" v-if="routeParams.type !== 'view' && routeParams.type != 'approval'" @click="handleAddMaterial"
>新增物料
</el-button>
</div>
<el-table :data="contractMaterialList" v-loading="buttonLoading" border>
<el-table-column label="产品名称" align="center" prop="productName" min-width="120" />
<el-table-column label="规格描述" align="center" prop="specificationDescription" min-width="120" />
<el-table-column label="物料编号" align="center" prop="materialCode" width="120" />
<el-table-column label="物料名称" align="center" prop="materialName" width="120" />
<el-table-column label="销售物料名称" align="center" prop="saleMaterialName" width="120" />
<el-table-column label="数量" align="center" prop="amount" width="80">
<template #default="scope">
{{ scope.row.amount ? Number(scope.row.amount).toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="unitName" width="60" />
<el-table-column label="未税单价" align="center" prop="beforePrice" width="100">
<template #default="scope">
{{ scope.row.beforePrice ? Number(scope.row.beforePrice).toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="税率(%)" align="center" prop="taxRate" width="80">
<template #default="scope">
{{ scope.row.taxRate ? Number(scope.row.taxRate).toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="含税单价" align="center" prop="includingPrice" width="100">
<template #default="scope">
{{ scope.row.includingPrice ? Number(scope.row.includingPrice).toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="小计" align="center" prop="subtotal" width="80">
<template #default="scope">
{{ scope.row.subtotal ? Number(scope.row.subtotal).toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="100" />
<el-table-column label="操作" align="center" fixed="right" width="150" v-if="routeParams.type !== 'view' && routeParams.type != 'approval'">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleEditMaterial(scope.row)"></el-button>
<el-button link type="danger" icon="Delete" @click="handleDeleteMaterial(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 合同物料编辑对话框 -->
<el-dialog :title="materialDialog.title" v-model="materialDialog.visible" width="800px" append-to-body>
<el-form ref="materialFormRef" :model="materialForm" :rules="materialRules" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="计划标识" prop="planFlag">
<el-radio-group v-model="materialForm.planFlag">
<el-radio v-for="dict in plan_flag" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料名称" prop="materialName" v-if="materialForm.planFlag === '1'">
<el-input v-model="materialForm.materialName" placeholder="计划内请点击右侧图标检索物料">
<template #suffix>
<el-icon style="cursor: pointer" @click="openSaleMaterialSelect">
<Search />
</el-icon>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料编号" prop="materialCode" v-if="materialForm.planFlag === '1'">
<el-input v-model="materialForm.materialCode" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称" prop="customerName" v-if="materialForm.planFlag === '1'">
<el-input v-model="materialForm.customerName" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="产品名称" prop="productName">
<el-input v-model="materialForm.productName" placeholder="请输入产品名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规格描述" prop="specificationDescription">
<el-input v-model="materialForm.specificationDescription" placeholder="请输入规格描述" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数量" prop="amount">
<el-input-number
v-model="materialForm.amount"
placeholder="请输入数量"
style="width: 100%"
@change="calculateSubtotal"
:precision="2"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料单位" prop="unitId">
<el-select v-model="materialForm.unitId" placeholder="请选择物料单位">
<el-option v-for="item in unitInfoList" :key="item.unitId" :label="item.unitName" :value="item.unitId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="税率(%)" prop="taxRate">
<el-select
v-model="materialForm.taxRate"
placeholder="请选择或输入税率"
style="width: 100%"
@change="calculateBeforePrice"
filterable
allow-create
default-first-option
>
<el-option label="6" :value="6"></el-option>
<el-option label="13" :value="13"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="未税单价" prop="beforePrice">
<el-input-number
v-model="materialForm.beforePrice"
placeholder="自动计算"
style="width: 100%"
:precision="2"
:controls="false"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="含税单价" prop="includingPrice">
<el-input-number
v-model="materialForm.includingPrice"
placeholder="请输入含税单价"
style="width: 100%"
:precision="2"
@change="calculateBeforePrice"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="小计" prop="subtotal">
<el-input-number
v-model="materialForm.subtotal"
placeholder="自动计算"
style="width: 100%"
readonly
:precision="2"
:controls="false"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="materialForm.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitMaterialForm"> </el-button>
<el-button @click="cancelMaterial"> </el-button>
</div>
</template>
</el-dialog>
<!-- 销售物料选择 -->
<SaleMaterialSelect ref="saleMaterialSelectRef" :multiple="false" @confirm-call-back="saleMaterialSelectCallBack"></SaleMaterialSelect>
<!-- 添加或修改OSS对象存储对话框 -->
<el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" append-to-body>
<el-form ref="ossFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="文件名">
<fileUpload v-if="type === 0" v-model="ossFileModel" />
<imageUpload v-if="type === 1" v-model="ossFileModel" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitOss"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<!-- 提交审批组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<!-- 审批记录 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="ContractInfoEdit" lang="ts">
import { addContractInfo, contractSubmitAndFlowStart, getContractInfo, updateContractInfo } from '@/api/oa/erp/contractInfo';
import { ContractInfoForm } from '@/api/oa/erp/contractInfo/types';
import { ContractMaterialVO, ContractMaterialForm } from '@/api/oa/erp/contractMaterial/types';
import { getBaseUnitInfoList } from '@/api/oa/base/unitInfo';
import { getRuleGenerateCode } from '@/api/system/codeRule';
import { startWorkFlow } from '@/api/workflow/task';
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
import SaleMaterialSelect from '@/components/SaleMaterialSelect/index.vue';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import ApprovalButton from '@/components/Process/approvalButton.vue';
import { ref } from 'vue';
import { allListDept, listDept } from '@/api/system/dept';
import { getCrmCustomerInfoList } from '@/api/oa/crm/customerInfo';
import { getBasePrintTemplateList } from '@/api/oa/base/printTemplate';
import { CodeRuleEnum, FlowCodeEnum } from '@/enums/OAEnum';
import { getInfo } from '@/api/login';
import { ProjectReportVO, ProjectReportQuery, ProjectReportForm } from '@/api/oa/erp/projectReport/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
//
const routeParams = ref<Record<string, any>>({});
const { contract_category, business_direction, contract_flag, contract_type, contract_status, plan_flag } = toRefs<any>(
proxy?.useDict('contract_category', 'business_direction', 'contract_flag', 'contract_type', 'contract_status', 'plan_flag')
);
const buttonLoading = ref(false);
const contractInfoFormRef = ref<ElFormInstance>();
//
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//
const submitFormData = ref<StartProcessBo>({
businessId: '',
flowCode: 'OAC',
variables: {},
bizExt: {}
});
//
const taskVariables = ref<Record<string, any>>({});
const flowInstanceBizExtBo = ref<Record<string, any>>({});
const type = ref(0);
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
// OSS v-model form
const ossFileModel = ref<string | string[] | undefined>(undefined);
//
const isCodeGenerated = ref(false);
//
const materialFormRef = ref<ElFormInstance>();
//
const contractMaterialList = computed(() => {
return (form.value as any).contractMaterialList || [];
});
/** 查询打印模板下拉框结构 */
const printTemplateList = ref([]);
const getPrintTemplateListSelect = async () => {
const res = await getBasePrintTemplateList(null);
printTemplateList.value = res.data;
};
/** 查询单位信息下拉框结构 */
const unitInfoList = ref([]);
const getUnitInfoListSelect = async () => {
const res = await getBaseUnitInfoList(null);
unitInfoList.value = res.data;
};
/** 查询部门信息下拉框结构 */
const deptInfoList = ref([]);
const getDeptInfoListSelect = async () => {
const params = { deptCategory: '03' } as any;
const res = await allListDept(params);
deptInfoList.value = res.data;
};
/** 查询客户信息下拉框结构 */
const customerInfoList = ref([]);
const getCustomerInfoListSelect = async () => {
const res = await getCrmCustomerInfoList(null);
customerInfoList.value = res.data;
};
//
const materialDialog = reactive({
visible: false,
title: ''
});
//
const initMaterialFormData: ContractMaterialForm = {
contractMaterialId: undefined,
planFlag: '2',
contractId: undefined,
productName: undefined,
specificationDescription: undefined,
materialId: undefined,
relationMaterialId: undefined,
amount: undefined,
unitId: undefined,
beforePrice: undefined,
taxRate: undefined,
includingPrice: undefined,
subtotal: undefined,
remark: undefined,
activeFlag: '1'
};
const materialForm = ref<ContractMaterialForm>({ ...initMaterialFormData });
//
const materialRules = {
productName: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
amount: [{ required: true, message: '数量不能为空', trigger: 'blur' }],
taxRate: [{ required: true, message: '税率不能为空', trigger: 'blur' }]
};
const initFormData: ProjectReportForm = {
reportId: undefined,
projectId: undefined,
projectName: undefined,
projectCode: undefined,
milestonePlan: undefined,
managerId: undefined,
deptId: undefined,
chargeId: undefined,
deputyId: undefined,
informationNote: undefined,
sortOrder: undefined,
ossId: undefined,
remark: undefined,
activeFlag: undefined,
deptName: undefined,
managerName: undefined,
chargeName: undefined,
deputyName: undefined
};
const data = reactive<{ form: ProjectReportForm; rules: any }>({
form: { ...initFormData },
rules: {
contractId: [{ required: true, message: '合同ID不能为空', trigger: 'blur' }]
}
});
const { form, rules } = toRefs(data);
// // contractFlag
// watch(
// () => form.value.contractFlag,
// (newVal) => {
// if (newVal === '2') {
// // ""
// form.value.contractCode = undefined;
// isCodeGenerated.value = false;
// }
// }
// );
const saleMaterialSelectRef = ref<InstanceType<typeof SaleMaterialSelect>>();
//
const openSaleMaterialSelect = () => {
saleMaterialSelectRef.value.open();
};
//
const saleMaterialSelectCallBack = (data: any) => {
const materialList = data;
if (materialList.length > 0) {
materialForm.value.materialId = materialList[0].materialId;
materialForm.value.materialCode = materialList[0].materialCode;
materialForm.value.materialName = materialList[0].materialName;
materialForm.value.productName = materialList[0].saleMaterialName;
materialForm.value.relationMaterialId = materialList[0].relationMaterialId;
materialForm.value.customerName = materialList[0].customerName;
}
};
/** 取消按钮 */
function cancel() {
dialog.visible = false;
}
/** 文件按钮操作 */
const handleFile = () => {
type.value = 0;
dialog.visible = true;
dialog.title = '上传合同附件';
//
ossFileModel.value = form.value.ossId as any;
};
/** 提交按钮 */
const submitForm = (status: string, mode: boolean) => {
try {
contractInfoFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
// 稿
if (status != 'draft') {
//
form.value.flowCode = FlowCodeEnum.CONTRACT_CODE;
//
form.value.variables = {
contractName: form.value.contractName,
totalPrice: form.value.totalPrice,
contractCode: form.value.contractCode
};
//
form.value.bizExt = {
businessTitle: '合同审批',
businessCode: form.value.contractCode
};
form.value.contractStatus = '2';
form.value.flowStatus = 'waiting';
const res = await contractSubmitAndFlowStart(form.value).finally(() => (buttonLoading.value = false));
form.value = res.data;
buttonLoading.value = false;
proxy?.$modal.msgSuccess('操作成功');
proxy?.$tab.closePage();
router.go(-1);
} else {
if (status === 'draft') {
form.value.contractStatus = '1';
form.value.flowStatus = 'draft';
}
if (form.value.contractId) {
await updateContractInfo(form.value).finally(() => (buttonLoading.value = false));
} else {
await addContractInfo(form.value).finally(() => (buttonLoading.value = false));
}
buttonLoading.value = false;
proxy?.$modal.msgSuccess('暂存成功');
proxy?.$tab.closePage();
router.go(-1);
}
}
});
} finally {
buttonLoading.value = false;
}
};
//
const handleStartWorkFlow = async (data: ContractInfoForm) => {
try {
submitFormData.value.flowCode = 'OAC';
submitFormData.value.businessId = data.contractId;
//
taskVariables.value = {
contractId: data.contractId,
contractName: data.contractName,
totalPrice: data.totalPrice,
contractCode: data.contractCode
};
//
flowInstanceBizExtBo.value = {
businessTitle: '合同审批',
businessCode: data.contractCode
};
submitFormData.value.variables = taskVariables.value;
submitFormData.value.bizExt = flowInstanceBizExtBo.value;
const resp = await startWorkFlow(submitFormData.value);
if (submitVerifyRef.value) {
buttonLoading.value = false;
await submitVerifyRef.value.openDialog(resp.data.taskId);
}
} finally {
buttonLoading.value = false;
router.go(-1);
}
};
// v-model ossId
const submitOss = () => {
// ossId
form.value.ossId = ossFileModel.value as any;
dialog.visible = false;
proxy?.$modal.msgSuccess('附件已更新');
};
// contractId
const handleAddMaterial = () => {
resetMaterialForm();
materialForm.value.contractId = form.value.contractId;
materialDialog.visible = true;
materialDialog.title = '新增合同物料';
};
//
const handleEditMaterial = (row: ContractMaterialVO) => {
resetMaterialForm();
materialForm.value = { ...row };
materialDialog.visible = true;
materialDialog.title = '编辑合同物料';
};
//
const handleDeleteMaterial = async (row: ContractMaterialVO) => {
await proxy?.$modal.confirm('是否确认删除该合同物料?');
try {
// contractMaterialList
if (!(form.value as any).contractMaterialList) {
(form.value as any).contractMaterialList = [];
}
//
const index = (form.value as any).contractMaterialList.findIndex((item: any) => item.contractMaterialId === row.contractMaterialId);
if (index !== -1) {
(form.value as any).contractMaterialList.splice(index, 1);
}
//
calculateTotalPrice();
proxy?.$modal.msgSuccess('删除成功');
} catch (error) {
console.error('删除合同物料失败:', error);
}
};
//
const resetMaterialForm = () => {
materialForm.value = { ...initMaterialFormData };
materialFormRef.value?.resetFields();
};
//
const cancelMaterial = () => {
resetMaterialForm();
materialDialog.visible = false;
};
//
const calculateBeforePrice = () => {
const tax = Number(materialForm.value.taxRate);
const including = Number(materialForm.value.includingPrice);
if (!isNaN(tax) && !isNaN(including)) {
const divisor = 1 + tax / 100;
if (divisor > 0) {
materialForm.value.beforePrice = Number((including / divisor).toFixed(2));
}
}
//
calculateSubtotal();
};
// ×
const calculateSubtotal = () => {
const amount = Number(materialForm.value.amount);
const including = Number(materialForm.value.includingPrice);
if (!isNaN(amount) && !isNaN(including)) {
materialForm.value.subtotal = Number((amount * including).toFixed(2));
}
//
calculateTotalPrice();
};
//
const calculateTotalPrice = () => {
const materialList = (form.value as any).contractMaterialList || [];
const total = materialList.reduce((sum: number, material: any) => {
const subtotal = Number(material.subtotal) || 0;
return sum + subtotal;
}, 0);
form.value.totalPrice = Number(total.toFixed(2));
};
// -
const submitMaterialForm = () => {
materialFormRef.value?.validate((valid: boolean) => {
if (valid) {
// contractMaterialList
if (!(form.value as any).contractMaterialList) {
(form.value as any).contractMaterialList = [];
}
if (materialForm.value.contractMaterialId) {
//
const index = (form.value as any).contractMaterialList.findIndex(
(item: any) => item.contractMaterialId === materialForm.value.contractMaterialId
);
if (index !== -1) {
(form.value as any).contractMaterialList[index] = { ...materialForm.value };
}
} else {
//
const newMaterial = {
...materialForm.value,
contractMaterialId: Date.now() // ID
};
(form.value as any).contractMaterialList.push(newMaterial);
}
//
calculateTotalPrice();
proxy?.$modal.msgSuccess('操作成功');
materialDialog.visible = false;
}
});
};
//
const loadSelectOptions = () => {
getUnitInfoListSelect();
getDeptInfoListSelect();
getCustomerInfoListSelect();
getPrintTemplateListSelect();
};
onMounted(async () => {
nextTick(async () => {
// //
// routeParams.value = route.query;
// loadSelectOptions();
// const id = routeParams.value.id as string | number;
// if (id && (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval')) {
// proxy?.$modal.loading('...');
// const res = await getContractInfo(id);
// Object.assign(form.value, res.data);
// proxy?.$modal.closeLoading();
// //
// if (form.value.contractCode) {
// isCodeGenerated.value = true;
// } else if (form.value.contractFlag === '1') {
// //
// isCodeGenerated.value = false;
// }
// } else {
// // ID
// try {
// const userInfoRes = await getInfo();
// if (userInfoRes.data?.user?.deptId && !form.value.contractDeptId) {
// form.value.contractDeptId = userInfoRes.data.user.deptId;
// }
// } catch (error) {
// console.error(':', error);
// }
// //
// if (form.value.contractCode) {
// isCodeGenerated.value = true;
// } else if (form.value.contractFlag === '1') {
// //
// isCodeGenerated.value = false;
// }
// }
//
routeParams.value = route.query;
loadSelectOptions();
//
if (routeParams.value.type === 'add') {
//
if (routeParams.value.projectId) {
form.value.projectId = routeParams.value.projectId;
form.value.projectName = routeParams.value.projectName;
form.value.projectCode = routeParams.value.projectCode;
form.value.managerId = routeParams.value.managerId;
form.value.managerName = routeParams.value.managerName;
form.value.deptId = routeParams.value.deptId;
form.value.deptName = routeParams.value.deptName;
form.value.chargeId = routeParams.value.chargeId;
form.value.chargeName = routeParams.value.chargeName;
form.value.deputyId = routeParams.value.deputyId;
form.value.deputyName = routeParams.value.deputyName;
}
}
//
if (routeParams.value.type === 'update' || routeParams.value.type === 'approval') {
const id = routeParams.value.id;
if (id) {
proxy?.$modal.loading('正在加载数据,请稍后...');
const res = await getContractInfo(id);
Object.assign(form.value, res.data);
proxy?.$modal.closeLoading();
}
}
});
});
//
const handleApprovalRecord = () => {
approvalRecordRef.value.init(form.value.contractId);
};
//
const submitCallback = async () => {
await proxy.$tab.closePage(proxy.$route);
router.go(-1);
};
//
const approvalVerifyOpen = async () => {
await submitVerifyRef.value.openDialog(routeParams.value.taskId);
};
// ossId
//
watch(
() => form.value.ossId,
(val) => {
if (!dialog.visible) {
ossFileModel.value = val as any;
}
}
);
</script>

@ -18,31 +18,81 @@
</el-col>
<el-col :span="12">
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="queryParams.projectCode" placeholder="请输入项目编号" clearable @keyup.enter="handleQuery" />
<el-input v-model="queryParams.projectCode" placeholder="请输入项目编号" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="项目经理" prop="managerId">
<el-input v-model="queryParams.managerId" placeholder="请输入项目经理" clearable @keyup.enter="handleQuery" />
<el-form-item label="项目经理" prop="managerName">
<el-input v-model="queryParams.managerName" placeholder="请输入项目经理" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="当前里程碑" prop="milestonePlan">
<el-input v-model="queryParams.milestonePlan" placeholder="请输入当前里程碑" clearable @keyup.enter="handleQuery" />
<el-input v-model="queryParams.milestonePlan" placeholder="请输入当前里程碑" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="部门ID" prop="deptId">
<el-input v-model="queryParams.deptId" placeholder="请输入部门ID" clearable @keyup.enter="handleQuery" />
<el-form-item label="部门名称" prop="deptName">
<el-input v-model="queryParams.deptName" placeholder="请输入部门名称" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门负责人" prop="chargeId">
<el-input v-model="queryParams.chargeId" placeholder="请输入部门负责人" clearable @keyup.enter="handleQuery" />
<el-form-item label="部门负责人" prop="chargeName">
<el-input v-model="queryParams.chargeName" placeholder="请输入部门负责人" clearable />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="queryParams.projectId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="项目经理ID" prop="managerId">
<el-input v-model="queryParams.managerId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="部门ID" prop="deptId">
<el-input v-model="queryParams.deptId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="部门负责人ID" prop="chargeId">
<el-input v-model="queryParams.chargeId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="分管副总ID" prop="deputyId">
<el-input v-model="queryParams.deputyId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="分管副总" prop="deputyName">
<el-input v-model="queryParams.deputyName" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="附件ID" prop="ossId">
<el-input v-model="queryParams.ossId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="queryParams.sortOrder" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="激活标识" prop="activeFlag">
<el-input v-model="queryParams.activeFlag" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="周报说明" prop="informationNote">
<el-input v-model="queryParams.informationNote" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
</el-row>
@ -65,65 +115,49 @@
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['oa:projectReportDetail:add']"></el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['oa/erp:projectReport:add']"></el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['oa:projectReportDetail:edit']"
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['oa/erp:projectReport:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['oa:projectReportDetail:remove']"
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['oa/erp:projectReport:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['oa:projectReportDetail:export']"></el-button>
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['oa/erp:projectReport:export']"></el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="projectReportDetailList" @selection-change="handleSelectionChange">
<!-- 项目周报信息表格展示 -->
<el-table v-loading="loading" border :data="projectReportList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目周报明细ID" align="center" prop="reportDetailId" v-if="columns[0].visible" />
<el-table-column label="项目周报ID" align="center" prop="reportId" v-if="columns[1].visible" />
<el-table-column label="项目周报ID" align="center" prop="reportId" v-if="columns[0].visible" />
<el-table-column label="项目ID" align="center" prop="projectId" v-if="columns[2].visible" />
<el-table-column label="填写日期" align="center" prop="fillTime" width="180" v-if="columns[3].visible">
<template #default="scope">
<span>{{ parseTime(scope.row.fillTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="所在的工作周" align="center" prop="currentWorkWeek" v-if="columns[4].visible" />
<el-table-column label="所属里程碑" align="center" prop="milestonePlan" v-if="columns[5].visible" />
<el-table-column label="二级进度阶段" align="center" prop="secondaryPhase" v-if="columns[6].visible" />
<el-table-column label="本周完成工作" align="center" prop="tasksCompleted" v-if="columns[7].visible" />
<el-table-column label="下周计划" align="center" prop="nextPlan" v-if="columns[8].visible" />
<el-table-column label="风险及解决措施" align="center" prop="riskResolution" v-if="columns[9].visible" />
<el-table-column label="计划完成率" align="center" prop="plannedCompletionRate" v-if="columns[10].visible" />
<el-table-column label="周报情况说明" align="center" prop="informationNote" v-if="columns[11].visible" />
<el-table-column label="项目状态" align="center" prop="scheduleStatus" v-if="columns[12].visible" />
<el-table-column label="周报状态(1暂存 2审批中 3可用)" align="center" prop="projectReportStatus" v-if="columns[13].visible" />
<el-table-column label="流程状态" align="center" prop="flowStatus" v-if="columns[14].visible" />
<el-table-column label="排序号" align="center" prop="sortOrder" v-if="columns[15].visible" />
<el-table-column label="项目阶段(预留)" align="center" prop="projectPhases" v-if="columns[16].visible" />
<el-table-column label="合同ID(预留)" align="center" prop="contractId" v-if="columns[17].visible" />
<el-table-column label="附件ID" align="center" prop="ossId" v-if="columns[18].visible" />
<el-table-column label="备注" align="center" prop="remark" v-if="columns[19].visible" />
<el-table-column label="激活标识" align="center" prop="activeFlag" v-if="columns[20].visible" />
<el-table-column label="项目名称" align="center" prop="projectName" v-if="columns[3].visible" />
<el-table-column label="项目编码" align="center" prop="projectCode" v-if="columns[20].visible" />
<el-table-column label="当前里程碑" align="center" prop="milestonePlan" v-if="columns[4].visible" />
<el-table-column label="项目经理" align="center" prop="managerName" v-if="columns[5].visible" />
<el-table-column label="部门ID" align="center" prop="deptName" v-if="columns[6].visible" />
<el-table-column label="部门负责人" align="center" prop="chargeName" v-if="columns[7].visible" />
<el-table-column label="分管副总" align="center" prop="deputyName" v-if="columns[8].visible" />
<el-table-column label="周报情况说明" align="center" prop="informationNote" v-if="columns[9].visible" />
<el-table-column label="排序号" align="center" prop="sortOrder" v-if="columns[10].visible" />
<el-table-column label="附件ID" align="center" prop="ossId" v-if="columns[11].visible" />
<el-table-column label="备注" align="center" prop="remark" v-if="columns[12].visible" />
<el-table-column label="激活标识" align="center" prop="activeFlag" v-if="columns[13].visible" />
<!-- <el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[20].visible" /> -->
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['oa:projectReportDetail:edit']"></el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['oa:projectReport:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['oa:projectReportDetail:remove']"
></el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['oa:projectReport:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
@ -131,61 +165,39 @@
<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>
<el-form ref="projectReportDetailFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="项目周报ID" prop="reportId">
<el-input v-model="form.reportId" placeholder="请输入项目周报ID" />
<el-form ref="projectReportFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="form.projectId" placeholder="请输入项目ID" />
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="form.projectCode" placeholder="请输入项目编号" />
</el-form-item>
<el-form-item label="填写日期" prop="fillTime">
<el-date-picker clearable v-model="form.fillTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择填写日期">
</el-date-picker>
<el-form-item label="当前里程碑" prop="milestonePlan">
<el-input v-model="form.milestonePlan" placeholder="请输入当前里程碑" />
</el-form-item>
<el-form-item label="所在的工作周" prop="currentWorkWeek">
<el-input v-model="form.currentWorkWeek" placeholder="请输入所在的工作周" />
<el-form-item label="项目经理" prop="managerId">
<el-input v-model="form.managerId" placeholder="请输入项目经理" />
</el-form-item>
<el-form-item label="所属里程碑" prop="milestonePlan">
<el-input v-model="form.milestonePlan" placeholder="请输入所属里程碑" />
<el-form-item label="部门ID" prop="deptId">
<el-input v-model="form.deptId" placeholder="请输入部门ID" />
</el-form-item>
<el-form-item label="二级进度阶段" prop="secondaryPhase">
<el-input v-model="form.secondaryPhase" placeholder="请输入二级进度阶段" />
<el-form-item label="部门负责人" prop="chargeId">
<el-input v-model="form.chargeId" placeholder="请输入部门负责人" />
</el-form-item>
<el-form-item label="本周完成工作" prop="tasksCompleted">
<el-input v-model="form.tasksCompleted" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="下周计划" prop="nextPlan">
<el-input v-model="form.nextPlan" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="风险及解决措施" prop="riskResolution">
<el-input v-model="form.riskResolution" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="计划完成率" prop="plannedCompletionRate">
<el-input v-model="form.plannedCompletionRate" placeholder="请输入计划完成率" />
<el-form-item label="分管副总" prop="deputyId">
<el-input v-model="form.deputyId" placeholder="请输入分管副总" />
</el-form-item>
<el-form-item label="周报情况说明" prop="informationNote">
<el-input v-model="form.informationNote" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请输入排序号" />
</el-form-item>
<el-form-item label="项目阶段(预留)" prop="projectPhases">
<el-input v-model="form.projectPhases" placeholder="请输入项目阶段(预留)" />
</el-form-item>
<el-form-item label="合同ID(预留)" prop="contractId">
<el-input v-model="form.contractId" placeholder="请输入合同ID(预留)" />
</el-form-item>
<el-form-item label="附件ID" prop="ossId">
<el-input v-model="form.ossId" placeholder="请输入附件ID" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="激活标识" prop="activeFlag">
<el-input v-model="form.activeFlag" placeholder="请输入激活标识" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
@ -198,76 +210,57 @@
</template>
<script setup name="ProjectReport" lang="ts">
import { listProjectReport, getProjectReport, delProjectReport, addProjectReport, updateProjectReport } from '@/api/oa/erp/projectReport';
import { ProjectReportVO, ProjectReportQuery, ProjectReportForm } from '@/api/oa/erp/projectReport/types';
import {
listProjectReportDetail,
getProjectReportDetail,
delProjectReportDetail,
addProjectReportDetail,
updateProjectReportDetail
} from '@/api/oa/erp/projectReportDetail/index';
import { ProjectReportDetailVO, ProjectReportDetailQuery, ProjectReportDetailForm } from '@/api/oa/erp/projectReportDetail/types';
import { listProjectReport, getProjectReport, delProjectReport, addProjectReport, updateProjectReport } from '@/api/oa/erp/projectReport';
import ProjectSelect from '@/components/ProjectSelect/index.vue';
//
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
//
const openProjectSelect = () => {
projectSelectRef.value.open();
};
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const projectReportList = ref<ProjectReportVO[]>([]);
const projectReportDetailList = ref<ProjectReportDetailVO[]>([]);
const route = useRoute();
const router = useRouter();
const buttonLoading = ref(false);
const loading = ref(true);
const loading = ref(false);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
//
const queryFormRef = ref<ElFormInstance>();
const projectReportDetailFormRef = ref<ElFormInstance>();
//
const projectReportFormRef = ref<ElFormInstance>();
//
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
//
const columns = ref<FieldOption[]>([
{ key: 0, label: `项目周报明细ID`, visible: true },
{ key: 1, label: `项目周报ID`, visible: true },
{ key: 2, label: `项目ID`, visible: true },
{ key: 3, label: `填写日期`, visible: true },
{ key: 4, label: `所在的工作周`, visible: true },
{ key: 5, label: `所属里程碑`, visible: true },
{ key: 6, label: `二级进度阶段`, visible: true },
{ key: 7, label: `本周完成工作`, visible: true },
{ key: 8, label: `下周计划`, visible: true },
{ key: 9, label: `风险及解决措施`, visible: true },
{ key: 10, label: `计划完成率`, visible: true },
{ key: 11, label: `周报情况说明`, visible: true },
{ key: 12, label: `项目状态`, visible: true },
{ key: 13, label: `周报状态(1暂存 2审批中 3可用)`, visible: true },
{ key: 14, label: `流程状态`, visible: true },
{ key: 15, label: `排序号`, visible: true },
{ key: 16, label: `项目阶段(预留)`, visible: true },
{ key: 17, label: `合同ID(预留)`, visible: true },
{ key: 18, label: `附件ID`, visible: true },
{ key: 19, label: `备注`, visible: true },
{ key: 20, label: `激活标识`, visible: true },
{ key: 21, label: `删除标志`, visible: true },
{ key: 22, label: `创建部门`, visible: true },
{ key: 23, label: `创建时间`, visible: true },
{ key: 24, label: `创建人`, visible: true },
{ key: 25, label: `更新人`, visible: true },
{ key: 26, label: `更新时间`, visible: true }
{ key: 0, label: `项目周报ID`, visible: false },
{ key: 1, label: `租户编号`, visible: false },
{ key: 2, label: `项目ID`, visible: false },
{ key: 3, label: `项目名称`, visible: true },
{ key: 4, label: `当前里程碑`, visible: true },
{ key: 5, label: `项目经理`, visible: true },
{ key: 6, label: `部门ID`, visible: true },
{ key: 7, label: `部门负责人`, visible: true },
{ key: 8, label: `分管副总`, visible: true },
{ key: 9, label: `周报情况说明`, visible: true },
{ key: 10, label: `排序号`, visible: true },
{ key: 11, label: `附件ID`, visible: true },
{ key: 12, label: `备注`, visible: true },
{ key: 13, label: `激活标识`, visible: true },
{ key: 14, label: `删除标志`, visible: true },
{ key: 15, label: `创建部门`, visible: true },
{ key: 16, label: `创建人`, visible: true },
{ key: 17, label: `创建时间`, visible: true },
{ key: 18, label: `更新人`, visible: true },
{ key: 19, label: `更新时间`, visible: true },
{ key: 20, label: `项目编码`, visible: true }
]);
const initFormData: ProjectReportForm = {
reportId: undefined,
projectId: undefined,
@ -282,7 +275,11 @@ const initFormData: ProjectReportForm = {
sortOrder: undefined,
ossId: undefined,
remark: undefined,
activeFlag: undefined
activeFlag: undefined,
deptName: undefined,
managerName: undefined,
chargeName: undefined,
deputyName: undefined
};
const data = reactive<PageData<ProjectReportForm, ProjectReportQuery>>({
form: { ...initFormData },
@ -301,51 +298,23 @@ const data = reactive<PageData<ProjectReportForm, ProjectReportQuery>>({
sortOrder: undefined,
ossId: undefined,
activeFlag: undefined,
deptName: undefined,
managerName: undefined,
chargeName: undefined,
deputyName: undefined,
params: {}
},
rules: {
reportId: [{ required: true, message: '项目周报ID不能为空', trigger: 'blur' }]
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询项目周报信息列表 */
const getList = async () => {
loading.value = true;
const res = await listProjectReport(queryParams.value);
projectReportList.value = res.rows;
total.value = res.total;
loading.value = false;
//
const openProjectSelect = () => {
projectSelectRef.value.open();
};
//
const projectInfoSelectCallBack = (data: any) => {
const projectInfoList = data;
console.log(projectInfoList);
if (projectInfoList.length > 0) {
queryParams.value.projectId = projectInfoList[0].projectId;
queryParams.value.projectName = projectInfoList[0].projectName;
queryParams.value.projectCode = projectInfoList[0].projectCode;
queryParams.value.managerId = projectInfoList[0].managerId;
queryParams.value.milestonePlan = projectInfoList[0].milestonePlan;
queryParams.value.deptId = projectInfoList[0].deptId;
queryParams.value.chargeId = projectInfoList[0].chargeId;
} else {
}
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
projectReportDetailFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
@ -357,6 +326,54 @@ const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 根据部门查询项目周报信息列表 */
const getList = async () => {
loading.value = true;
const res = await listProjectReport(queryParams.value);
projectReportList.value = res.rows;
total.value = res.total;
loading.value = false;
};
//
const projectInfoSelectCallBack = (data: any) => {
if (data.length > 0) {
setFromProjectInfo(data);
getList();
} else {
queryFormRef.value?.resetFields();
proxy?.$modal.msgWarning('请选择项目信息');
getList();
}
};
//
const setFromProjectInfo = (data: any) => {
const projectInfoList = data;
queryParams.value.projectId = projectInfoList[0].projectId;
queryParams.value.projectName = projectInfoList[0].projectName;
queryParams.value.projectCode = projectInfoList[0].projectCode;
queryParams.value.managerId = projectInfoList[0].managerId;
queryParams.value.milestonePlan = projectInfoList[0].milestonePlan;
queryParams.value.deptId = projectInfoList[0].deptId;
queryParams.value.chargeId = projectInfoList[0].chargeId;
queryParams.value.deputyId = projectInfoList[0].deputyId;
queryParams.value.managerName = projectInfoList[0].managerName;
queryParams.value.deptName = projectInfoList[0].deptName;
queryParams.value.chargeName = projectInfoList[0].chargeName;
queryParams.value.deputyName = projectInfoList[0].deputyName;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 所有表单重置 */
const reset = () => {
form.value = { ...initFormData };
projectReportFormRef.value?.resetFields();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: ProjectReportVO[]) => {
@ -368,8 +385,26 @@ const handleSelectionChange = (selection: ProjectReportVO[]) => {
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加项目周报信息';
proxy.$tab.closePage(route);
//
const routeParams = {
type: 'add',
projectId: queryParams.value.projectId,
projectName: queryParams.value.projectName,
projectCode: queryParams.value.projectCode,
managerId: queryParams.value.managerId,
managerName: queryParams.value.managerName,
deptId: queryParams.value.deptId,
deptName: queryParams.value.deptName,
chargeId: queryParams.value.chargeId,
chargeName: queryParams.value.chargeName,
deputyId: queryParams.value.deputyId,
deputyName: queryParams.value.deputyName
};
router.push({
path: '/project/projectReport/edit',
query: routeParams
});
};
/** 修改按钮操作 */
@ -384,7 +419,7 @@ const handleUpdate = async (row?: ProjectReportVO) => {
/** 提交按钮 */
const submitForm = () => {
projectReportDetailFormRef.value?.validate(async (valid: boolean) => {
projectReportFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.reportId) {

Loading…
Cancel
Save