Commit e9d161b2 authored by 罗林杰's avatar 罗林杰

修改招标计划,增加招标计划统计模块

parent 3347e224
......@@ -11,12 +11,25 @@ enum Api {
Itemdelete = '/pro/tenderPlan/details/del',
audit = '/pro/tenderPlan/examine',
selectCount = '/pro/tenderPlan/selectCount',
GetListAll = '/pro/tenderPlan/listAll',
ExportCount = '/pro/export/tenderPlanStatistic',
}
export const getListByPage = (params?: ProjectPageParams) =>
defHttp.post<ListGetResultModel>({ url: Api.GetList, data: params });
/*export const getListTenderPlanGetList = (params?: ProjectPageParams) =>
defHttp.post<ListGetResultModel>({ url: Api.tenderPlanGetList, data: params });*/
export const getListAll = (params?: any) =>
defHttp.post<ProjectModel>({ url: Api.GetListAll, data: params });
export const exportTenderCount = (params?: any) =>
defHttp.post<any>(
{
url: Api.ExportCount,
data: params,
responseType: 'blob',
},
{ errorMessageMode: 'none', isTransformResponse: false },
);
//招标计划列表接口
export const getListTenderPlanGetList = (params) =>
......
......@@ -61,6 +61,16 @@ const biddingPlan: AppRouteModule = {
orderNo: 2,
},
},
{
path: 'biddingPlanData',
name: 'planData',
component: () => import('@/views/biddingPlan/biddingPlanData.vue'),
meta: {
auth: '/www/dist/index.html#/biddingPlan/index',
title: '招标计划统计',
orderNo: 2,
},
},
],
};
......
......@@ -81,22 +81,22 @@ export const searchFormSchema: FormSchema[] = [
},
colProps: { span: 4 },
},
{
field: 'companyName',
label: '',
component: 'Select',
componentProps: {
placeholder: '公司名称',
options: [
{
label: '公司名称',
value: '公司名称',
key: '公司名称',
},
],
},
colProps: { span: 4 },
},
// {
// field: 'companyName',
// label: '',
// component: 'Select',
// componentProps: {
// placeholder: '公司名称',
// options: [
// {
// label: '公司名称',
// value: '公司名称',
// key: '公司名称',
// },
// ],
// },
// colProps: { span: 4 },
// },
// {
// field: 'status',
// label: '状态',
......@@ -119,6 +119,7 @@ export const formSchema: FormSchema[] = [
component: 'Input',
componentProps: {
readonly: true,
disabled: true,
},
colProps: { span: 7, offset: 1 },
},
......@@ -260,5 +261,6 @@ export const formSchema: FormSchema[] = [
showCount: true,
},
colProps: { span: 7, offset: 1 },
},
];
];
\ No newline at end of file
<template>
<div style="margin: 16px">
<PageCard title="招标计划统计">
<BasicForm ref="formElRef" @register="registerForm">
<template #formFooter>
<a-button type="primary" @click="handleSubmit"> 查询</a-button>
<a-button type="primary" @click="exportCount" style="margin-left: 10px"> 导出</a-button>
</template>
</BasicForm>
<Table
:pagination="false"
:dataSource="dataSource"
:columns="columns"
bordered
:loading="loadingRef"
:rowClassName="setRowClassName"
:scroll="{ x: 1300, y: 600 }"
/>
</PageCard>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, watch } from 'vue';
import { Table } from 'ant-design-vue';
import { exportTenderCount, getListAll } from '@/api/project/biddingPlan';
import { BasicForm, FormActionType, useForm } from '@/components/Form';
import { useModal } from '@/components/Modal';
import { searchFormSchema } from './biddingPlan.data';
import PageCard from '@/components/Page/src/PageCard.vue';
import { useRouter } from 'vue-router';
import { downloadByData } from '@/utils/file/download';
const { push } = useRouter();
onMounted(async () => {
getStatisticList();
});
defineOptions({ name: 'MonthlyPlan' });
const [register, { openModal: openModal }] = useModal();
const formElRef = ref<Nullable<FormActionType>>(null);
const [registerForm, { getFieldsValue }] = useForm({
labelWidth: 90,
baseColProps: { span: 24 },
schemas: searchFormSchema,
showActionButtonGroup: false,
});
const params = ref({ tenderYear: '', biddingQuarter: '', companyName: '' });
const loadingRef = ref(false);
function handleSubmit() {
let data = getFieldsValue();
params.value = data;
if (params.value.tenderYear !== undefined && params.value.tenderYear !== null) {
columns[0].title = params.value.tenderYear + '年招标计划';
} else {
columns[0].title = '招标计划';
}
getStatisticList();
}
async function exportCount() {
const data = await exportTenderCount(params.value);
downloadByData(data, '招标计划统计报表' + '.xlsx');
}
function setRowClassName(record) {
if (record.projectName === '总计(万元)') {
return 'rowcolor';
} else if (record.companyName === '合计(万元)') {
return 'rowcolor';
} else {
return;
}
}
async function getStatisticList() {
loadingRef.value = true;
let data = await getListAll(params.value);
// dataSource.value = data;
let propsList = ['companyName', 'projectName'];
propsList.map((item) => {
changeData(data, item);
});
loadingRef.value = false;
}
function changeData(data, field) {
let count = 0; // 当前组中第一个元素的索引
let indexCount = 1; // 下一个需要比较的元素的索引
while (indexCount < data.length) {
const item = data[count]; // 获取当前组的第一个元素
const nextItem = data[indexCount]; // 获取下一个需要比较的元素
if (!item[`${field}rowSpan`]) {
item[`${field}rowSpan`] = 1; // 初始化rowSpan属性为1
}
// 检查companyName和指定字段是否匹配
if (item[field] === nextItem[field] && item.companyName === nextItem.companyName) {
item[`${field}rowSpan`]++; // 增加当前元素的rowSpan值
nextItem[`${field}rowSpan`] = 0; // 标记为已合并
} else {
count = indexCount; // 将当前组的起始位置移动到下一个元素
}
indexCount++;
}
dataSource.value = data; // 更新数据源
}
// 列表
const dataSource = ref([]);
// 表头
const columns = [
{
title: '招标计划',
dataIndex: '',
fixed: 'left',
children: [
{
title: '公司名称',
dataIndex: 'companyName',
fixed: 'left',
width: 180,
customCell: (_, any) => ({
rowSpan: _.companyNamerowSpan,
}),
},
{
title: '项目名称',
dataIndex: 'projectName',
width: 180,
customCell: (_, any) => ({
rowSpan: _.projectNamerowSpan,
}),
},
{
title: '立即投资额(万元)',
dataIndex: 'investmentAmount',
width: 180,
},
{
title: '预计控制价(万元)',
dataIndex: 'controlPrice',
width: 180,
},
{
title: '招标类型',
dataIndex: 'biddingType',
width: 180,
},
{
title: '招标方式',
dataIndex: 'biddingMethod',
width: 180,
},
],
},
];
</script>
<style lang="less" scoped>
::v-deep .ant-table-tbody .ant-table-row {
&.rowcolor .ant-table-cell-fix-left {
background-color: #f5f5f5;
}
}
.action-container {
display: flex;
justify-content: space-between;
}
</style>
......@@ -8,11 +8,14 @@
>
<template #extra>
<!-- <a-button type="primary" danger> 删除 </a-button>-->
<a-button type="primary" v-if="!disabled" @click="handleSubmit"> 提交 </a-button>
<a-button type="primary" v-if="!disabled" :disabled="loadingRef" @click="handleSubmit('0')">
暂存
</a-button>
<a-button type="primary" v-if="!disabled" @click="handleSubmit('1')"> 提交 </a-button>
<a-button type="primary" @click="history" v-if="historyData">历史记录 </a-button>
<a-button type="default" @click="router.back()"> 返回 </a-button>
</template>
<template v-for="(item, index) in tabsFormSchema">
<!-- <template v-for="(item, index) in tabsFormSchema">
<PageCard v-if="item.show" :key="index" :title="item.name">
<template #right>
<a-button
......@@ -25,7 +28,36 @@
</template>
<BasicForm :loading="loading" @register="item.Form[0]" />
</PageCard>
</template>
</template>-->
<!-- page页 -->
<CollapseContainer v-for="(item, index) in tabsFormSchema" :key="index">
<template #title>
<span class="projectName">{{ item.name }}</span>
</template>
<template #action>
<a-button
v-if="!disabled"
type="text"
preIcon="ant-design:delete-outlined"
danger
@click="deleteItem(index)"
>删除项目</a-button
>
</template>
<BasicForm :loading="loading" @register="item.Form[0]" />
<!-- 左上角为项目名 -->
<CollapseContainer
v-for="(content, key) in item.list"
:key="key"
class="subCard"
:title="content.name"
>
<template #title>
<span class="contractName">{{ content.name }}</span>
</template>
<BasicForm :loading="loading" @register="content.form" />
</CollapseContainer>
</CollapseContainer>
<a-button v-if="!disabled" type="dashed" @click="add" preIcon="ei:plus">
从项目库导入
</a-button>
......@@ -45,7 +77,6 @@
import { unref, onMounted, ref, reactive, nextTick } from 'vue';
import projectlibraryModel from '@/components/projectlibraryModel/projectlibraryModel.vue';
import { PageWrapper } from '@/components/Page';
import PageCard from '@/components/Page/src/PageCard.vue';
import projectDrawer from '@/views/project/projectDrawer.vue';
import { BasicForm, useForm, FormProps, UseFormReturnType } from '@/components/Form';
import { formSchema } from './biddingPlan.data';
......@@ -58,6 +89,7 @@
import { router } from '@/router';
import { useRoute } from 'vue-router';
import { isArray } from 'lodash-es';
import CollapseContainer from '@/components/Container/src/collapse/CollapseContainer.vue';
//历史记录是否可查
const historyData = ref(true);
......@@ -90,7 +122,7 @@
} else {
isUpdate.value = true;
tenderId.value = id;
formData.value.tenderld = id;
formData.value.tenderId = id;
disabled.value = route.query.disabled == '0' ? false : true;
if (disabled.value) {
getTitle.value = '查看招标计划';
......@@ -102,7 +134,7 @@
for (let i = 0; i < res.length; i++) {
const source = res[i];
const item = {
name: '序号' + (i + 1),
name: '项目:' + source.projectName,
forceRender: true,
show: true,
Form: useForm(
......@@ -157,7 +189,7 @@
*/
async function handleNew(info: any) {
const item = {
name: '序号' + (tabsFormSchema.length + 1),
name: '项目:' + info.projectName,
show: true,
forceRender: true,
Form: useForm(Object.assign({ schemas: formSchema }, baseFormConfig) as FormProps),
......@@ -168,7 +200,7 @@
proId: info.id,
tenderId: isUpdate.value ? tenderId.value : '',
});
nextTick(() => {
await nextTick(() => {
setFieldsValue({
projectName: info.projectName,
fundingSource: info.fundingSource,
......@@ -197,7 +229,53 @@
console.log(params);
handleNew(params);
}
async function handleSubmit() {
async function handleSubmit(isSubmit) {
for (let i = 0; i < tabsFormSchema.length; i++) {
let formSchema = tabsFormSchema[i].Form[1];
const { updateSchema } = formSchema;
await nextTick(() => {
if (isSubmit == '0') {
updateSchema([
{ field: 'projectName', required: false },
{ field: 'projectInitiator', required: false },
{ field: 'fundingSource', required: false },
{ field: 'investmentAmount', required: false },
{ field: 'biddingType', required: false },
{ field: 'controlPrice', required: false },
{ field: 'plannedPeriod', required: false },
{ field: 'biddingPeriod', required: false },
{ field: 'biddingMethod', required: false },
{ field: 'tenderContent', required: false },
{
field: 'remark',
dynamicRules: ({ values }) => {
return [{ required: false }];
},
},
]);
} else {
updateSchema([
{ field: 'projectName', required: true },
{ field: 'projectInitiator', required: true },
{ field: 'fundingSource', required: true },
{ field: 'investmentAmount', required: true },
{ field: 'biddingType', required: true },
{ field: 'controlPrice', required: true },
{ field: 'plannedPeriod', required: true },
{ field: 'biddingPeriod', required: true },
{ field: 'biddingMethod', required: true },
{ field: 'tenderContent', required: true },
{
field: 'remark',
dynamicRules: ({ values }) => {
return values.fundGap ? [{ required: true, message: '说明必填' }] : [];
},
},
]);
}
});
}
loadingRef.value = true;
try {
for (let i = 0; i < tabsFormSchema.length; i++) {
......@@ -217,6 +295,7 @@
}
}
formData.value.proNumber = formData.value.tenderPlanPro.Length;
formData.value.isSubmit = isSubmit;
let res = isUpdate.value ? await updateItem(unref(formData)) : await addItem(unref(formData));
loadingRef.value = true;
......@@ -243,3 +322,18 @@
console.log('历史记录');
}
</script>
<style scoped>
.subCard {
border: 1px solid #e8eaec;
}
.projectName {
border-left: blue solid 6px;
padding-left: 10px;
font-weight: bold;
}
.contractName {
border-left: red solid 6px;
padding-left: 10px;
font-weight: bold;
}
</style>
......@@ -25,7 +25,7 @@
label: '编辑',
onClick: handleEdit.bind(null, record, 0),
ifShow: (_action) => {
return record.reviewStatus == '0'||record.reviewStatus == null;
return record.reviewStatus == '0' || record.reviewStatus == null;
},
},
{
......@@ -37,7 +37,7 @@
confirm: handleDelete.bind(null, record),
},
ifShow: (_action) => {
return record.reviewStatus == '0'||record.reviewStatus == null;
return record.reviewStatus == '0' || record.reviewStatus == null;
},
},
{
......@@ -49,7 +49,11 @@
confirm: examine.bind(null, record, true),
},
ifShow: (_action) => {
return record.reviewStatus == '0'||record.reviewStatus == null;
return (
(record.reviewStatus === '0' || record.reviewStatus === null) &&
record.isSubmit !== '0' &&
deptId !== '100'
);
},
},
]"
......@@ -71,9 +75,11 @@
//审核相关操作
import { operateType, addItemApi, addItemData } from '@/api/operations/operations';
import { onMounted } from 'vue';
import { onMounted, ref } from 'vue';
import { getDepartmentList } from '@/api/project/settlementManage';
import {useUserStore} from "@/store/modules/user";
const deptId = ref('');
const { createMessage } = useMessage();
const { error } = createMessage;
const { push } = useRouter();
......@@ -98,6 +104,7 @@
},
});
onMounted(async () => {
deptId.value = useUserStore().userInfo.deptId;
const data = await getDepartmentList();
searchFormSchema[2].componentProps.options = data;
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment