Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
web-project
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
紫光云
web-project
Commits
8c8efd1e
Commit
8c8efd1e
authored
Mar 20, 2025
by
高滢
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(招标计划): 填报统计
parent
a51ef495
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1191 additions
and
50 deletions
+1191
-50
yearTenderMan.ts
src/api/project/yearTenderMan.ts
+20
-4
yearTenderPlan.ts
src/api/project/yearTenderPlan.ts
+46
-0
biddingPlan.ts
src/router/routes/modules/biddingPlan.ts
+38
-5
edit.vue
src/views/tendeYearManage/edit.vue
+1
-1
index.vue
src/views/tendeYearManage/index.vue
+5
-1
statistics.vue
src/views/tendeYearManage/statistics.vue
+16
-39
data.ts
src/views/tenderYearPlan/data.ts
+216
-0
edit.vue
src/views/tenderYearPlan/edit.vue
+348
-0
index.vue
src/views/tenderYearPlan/index.vue
+318
-0
statistics.vue
src/views/tenderYearPlan/statistics.vue
+183
-0
No files found.
src/api/project/yearTenderMan.ts
View file @
8c8efd1e
...
...
@@ -10,14 +10,26 @@ enum Api {
SelectCount
=
'/pro/tenderYearManage/selectCount'
,
GetListAll
=
'/pro/tenderYearManage/statistics'
,
Export
=
'/pro/tenderYearManage/export'
,
Import
=
'/pro/tenderYearManage/import'
,
}
export
const
selectPageList
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
GetPageList
,
data
:
params
});
export
const
addProject
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
AddProject
,
data
:
params
});
export
const
addProject
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
AddProject
,
data
:
params
,
headers
:
{
'Content-Type'
:
'application/json;charset=UTF-8'
,
},
});
export
const
updateProject
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
UpdateProject
,
data
:
params
});
defHttp
.
post
({
url
:
Api
.
UpdateProject
,
data
:
params
,
headers
:
{
'Content-Type'
:
'application/json;charset=UTF-8'
,
},
});
export
const
deleteProject
=
(
params
?:
any
)
=>
defHttp
.
get
({
url
:
Api
.
DeleteProject
,
data
:
params
});
...
...
@@ -27,4 +39,8 @@ export const handelExamine = (params?: any) => defHttp.get({ url: Api.Audit, dat
export
const
getCount
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
SelectCount
,
data
:
params
});
export
const
selectListAll
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
GetListAll
,
data
:
params
});
export
const
exportTender
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
Export
,
data
:
params
});
export
const
exportTender
=
(
params
?:
any
)
=>
defHttp
.
post
(
{
url
:
Api
.
Export
,
data
:
params
,
responseType
:
'blob'
},
{
errorMessageMode
:
'none'
,
isTransformResponse
:
false
},
);
src/api/project/yearTenderPlan.ts
0 → 100644
View file @
8c8efd1e
import
{
defHttp
}
from
'@/utils/http/axios'
;
enum
Api
{
GetPageList
=
'/pro/tenderYearPlan/page'
,
AddProject
=
'/pro/tenderYearPlan/add'
,
UpdateProject
=
'/pro/tenderYearPlan/edit'
,
DeleteProject
=
'/pro/tenderYearPlan/del'
,
ProjectDetail
=
'/pro/tenderYearPlan/details'
,
Audit
=
'/pro/tenderYearPlan/examine'
,
SelectCount
=
'/pro/tenderYearPlan/count'
,
GetListAll
=
'/pro/tenderYearPlan/statistics'
,
Export
=
'/pro/tenderYearPlan/export'
,
}
export
const
selectPageList
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
GetPageList
,
data
:
params
});
export
const
addProject
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
AddProject
,
data
:
params
,
headers
:
{
'Content-Type'
:
'application/json;charset=UTF-8'
,
},
});
export
const
updateProject
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
UpdateProject
,
data
:
params
,
headers
:
{
'Content-Type'
:
'application/json;charset=UTF-8'
,
},
});
export
const
deleteProject
=
(
params
?:
any
)
=>
defHttp
.
get
({
url
:
Api
.
DeleteProject
,
data
:
params
});
export
const
selectDetail
=
(
params
?:
any
)
=>
defHttp
.
get
({
url
:
Api
.
ProjectDetail
,
data
:
params
});
export
const
handelExamine
=
(
params
?:
any
)
=>
defHttp
.
get
({
url
:
Api
.
Audit
,
data
:
params
});
export
const
getCount
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
SelectCount
,
data
:
params
});
export
const
selectListAll
=
(
params
?:
any
)
=>
defHttp
.
post
({
url
:
Api
.
GetListAll
,
data
:
params
});
export
const
exportTender
=
(
params
?:
any
)
=>
defHttp
.
post
(
{
url
:
Api
.
Export
,
data
:
params
,
responseType
:
'blob'
},
{
errorMessageMode
:
'none'
,
isTransformResponse
:
false
},
);
src/router/routes/modules/biddingPlan.ts
View file @
8c8efd1e
...
...
@@ -94,6 +94,16 @@ const biddingPlan: AppRouteModule = {
orderNo
:
5
,
},
},
{
path
:
'tendeYearManage'
,
name
:
'TendeYearManage'
,
component
:
()
=>
import
(
'@/views/tendeYearManage/index.vue'
),
meta
:
{
auth
:
'/www/dist/index.html#/biddingManagement/index'
,
title
:
'年度招标管理填报'
,
orderNo
:
5
,
},
},
{
path
:
'tendeYearManageSta'
,
name
:
'TendeYearManageSta'
,
...
...
@@ -105,13 +115,36 @@ const biddingPlan: AppRouteModule = {
},
},
{
path
:
'tendeYear
Manage
'
,
name
:
'TendeYear
Manage
'
,
component
:
()
=>
import
(
'@/views/tende
YearManage/index
.vue'
),
path
:
'tendeYear
PlanEdit
'
,
name
:
'TendeYear
PlanEdit
'
,
component
:
()
=>
import
(
'@/views/tende
rYearPlan/edit
.vue'
),
meta
:
{
hideTab
:
true
,
hideMenu
:
true
,
hideBreadcrumb
:
true
,
auth
:
'/www/dist/index.html#/biddingManagement/index'
,
title
:
'年度招标管理填报'
,
orderNo
:
5
,
title
:
'年度招标计划填报'
,
orderNo
:
6
,
},
},
{
path
:
'tendeYearPlan'
,
name
:
'TendeYearPlan'
,
component
:
()
=>
import
(
'@/views/tenderYearPlan/index.vue'
),
meta
:
{
auth
:
'/www/dist/index.html#/biddingManagement/index'
,
title
:
'年度招标计划填报'
,
orderNo
:
7
,
},
},
{
path
:
'tendeYearPlanSta'
,
name
:
'TendeYearMPlanSta'
,
component
:
()
=>
import
(
'@/views/tenderYearPlan/statistics.vue'
),
meta
:
{
auth
:
'/www/dist/index.html#/biddingManagement/index'
,
title
:
'年度招标计划统计'
,
orderNo
:
7
,
},
},
],
...
...
src/views/tendeYearManage/edit.vue
View file @
8c8efd1e
...
...
@@ -46,7 +46,7 @@
accept=
".xlsx,.xls"
:on-success=
"uploadFile"
>
<a-button
v-if=
"!disabled"
type=
"dashed"
@
click=
"excelAdd"
class=
"ml-2"
preIcon=
"ei:plus"
>
<a-button
v-if=
"!disabled"
type=
"dashed"
class=
"ml-2"
preIcon=
"ei:plus"
>
Excel导入
</a-button>
</Upload>
...
...
src/views/tendeYearManage/index.vue
View file @
8c8efd1e
...
...
@@ -157,7 +157,7 @@
import
{
useUserStore
}
from
'@/store/modules/user'
;
import
PageCard
from
'@/components/Page/src/PageCard.vue'
;
import
CycleModel
from
'@/views/monthlyPlan/cycleModel/cycleModel.vue'
;
import
FillDetailsModel
from
'@/views/
biddingManagement
/fillDetailsModel/fillDetailsModel.vue'
;
import
FillDetailsModel
from
'@/views/
monthlyPlan
/fillDetailsModel/fillDetailsModel.vue'
;
import
{
Divider
,
Row
,
Col
}
from
'ant-design-vue'
;
import
{
getMothCycel
,
SetEditStatus
}
from
"@/api/project/monthlyPlan"
;
...
...
@@ -243,11 +243,15 @@
function
selectCycle
()
{
openCycleModel
(
true
,
{
data
:
mothCycle
.
value
,
type
:
'year'
,
id
:
11
,
});
}
function
getFillDetails
()
{
openFillDetailModel
(
true
,
{
data
:
mothCycle
.
value
,
url
:
'/pro/monthEngineer/businessComDetails'
,
module
:
'TenderMan'
,
});
}
function
handleCreate
()
{
...
...
src/views/tendeYearManage/statistics.vue
View file @
8c8efd1e
...
...
@@ -106,54 +106,31 @@
loadingRef
.
value
=
true
;
let
data
=
await
selectListAll
(
params
.
value
);
let
propsList
=
[
'companyName'
,
'projectName'
];
let
propsList
=
[
'companyName'
];
propsList
.
map
((
item
)
=>
{
changeData
(
data
,
item
);
});
loadingRef
.
value
=
false
;
}
function
changeData
(
data
,
field
)
{
if
(
field
==
'companyName'
)
{
let
count
=
0
;
//重复项的第一项
let
indexCount
=
1
;
//下一项
while
(
indexCount
<
data
.
length
)
{
let
item
=
data
.
slice
(
count
,
count
+
1
)[
0
];
//获取没有比较的第一个对象
if
(
!
item
[
`
${
field
}
rowSpan`
])
{
item
[
`
${
field
}
rowSpan`
]
=
1
;
//初始化为1
}
if
(
item
[
field
]
===
data
[
indexCount
][
field
])
{
//第一个对象与后面的对象相比,有相同项就累加,并且后面相同项设置为0
item
[
`
${
field
}
rowSpan`
]
++
;
data
[
indexCount
][
`
${
field
}
rowSpan`
]
=
0
;
}
else
{
count
=
indexCount
;
}
indexCount
++
;
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
}
}
if
(
field
==
'proName'
)
{
let
count
=
0
;
//重复项的第一项
let
indexCount
=
1
;
//下一项
while
(
indexCount
<
data
.
length
)
{
let
item
=
data
.
slice
(
count
,
count
+
1
)[
0
];
//获取没有比较的第一个对象
if
(
!
item
[
`
${
field
}
rowSpan`
])
{
item
[
`
${
field
}
rowSpan`
]
=
1
;
//初始化为1
}
if
(
item
[
field
]
===
data
[
indexCount
][
field
]
&&
item
[
'companyName'
]
===
data
[
indexCount
][
'companyName'
]
)
{
//第一个对象与后面的对象相比,有相同项就累加,并且后面相同项设置为0
item
[
`
${
field
}
rowSpan`
]
++
;
data
[
indexCount
][
`
${
field
}
rowSpan`
]
=
0
;
}
else
{
count
=
indexCount
;
}
indexCount
++
;
// 检查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
;
dataSource
.
value
=
data
;
// 更新数据源
}
// 列表
...
...
src/views/tenderYearPlan/data.ts
0 → 100644
View file @
8c8efd1e
import
{
BasicColumn
,
FormSchema
}
from
'@/components/Table'
;
import
{
useUserStore
}
from
'@/store/modules/user'
;
const
deptId
=
useUserStore
().
userInfo
.
deptParentId
;
//主模块-招标计划列表页
export
const
columns
:
BasicColumn
[]
=
[
{
title
:
'序号'
,
dataIndex
:
'serialNumber'
,
width
:
100
,
},
{
title
:
'填报周期'
,
dataIndex
:
'tenderYear'
,
width
:
200
,
},
{
title
:
'项目数量'
,
dataIndex
:
'proNumber'
,
width
:
180
,
},
{
title
:
'公司名称'
,
dataIndex
:
'companyName'
,
width
:
180
,
},
{
title
:
'最新更新人'
,
dataIndex
:
'updateBy'
,
width
:
180
,
},
{
title
:
'审核状态'
,
dataIndex
:
'reviewStatus'
,
ifShow
:
deptId
!=
'100'
,
width
:
140
,
},
{
title
:
'审核人'
,
dataIndex
:
'revieweUser'
,
width
:
180
,
},
{
title
:
'审核时间'
,
dataIndex
:
'reviewTime'
,
width
:
180
,
},
];
export
const
searchFormSchema
:
FormSchema
[]
=
[
{
field
:
'tenderYear'
,
label
:
''
,
component
:
'DatePicker'
,
componentProps
:
{
placeholder
:
'年份'
,
picker
:
'year'
,
valueFormat
:
'YYYY'
,
format
:
'YYYY'
,
style
:
{
width
:
'100%'
,
},
},
colProps
:
{
span
:
4
},
},
{
field
:
'companyId'
,
label
:
''
,
component
:
'Select'
,
componentProps
:
{
placeholder
:
'公司名称'
,
options
:
[
{
label
:
'公司名称'
,
value
:
'公司名称'
,
},
],
},
colProps
:
{
span
:
4
},
},
];
export
const
formSchema
:
FormSchema
[]
=
[
{
field
:
'proName'
,
label
:
'项目名称'
,
required
:
true
,
component
:
'Input'
,
componentProps
:
{
readonly
:
true
,
disabled
:
true
,
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
field
:
'fundingSource'
,
label
:
'资金来源'
,
required
:
true
,
component
:
'Input'
,
componentProps
:
{
readonly
:
true
,
disabled
:
true
,
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
field
:
'projectInitiator'
,
label
:
'立项主体'
,
required
:
true
,
component
:
'Input'
,
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
field
:
'investmentAmount'
,
label
:
'立项投资额'
,
required
:
true
,
component
:
'InputNumber'
,
componentProps
:
{
addonAfter
:
'万元'
,
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
field
:
'biddingType'
,
label
:
'招标类型(施工、监理、设计、图审等)'
,
required
:
true
,
component
:
'Input'
,
colProps
:
{
span
:
7
,
offset
:
1
},
labelWidth
:
400
,
},
{
field
:
'controlPrice'
,
label
:
'预计控制价'
,
required
:
true
,
component
:
'InputNumber'
,
componentProps
:
{
addonAfter
:
'万元'
,
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
field
:
'plannedPeriod'
,
label
:
'计划工期'
,
required
:
true
,
component
:
'RangePicker'
,
colProps
:
{
span
:
7
,
offset
:
1
},
componentProps
:
{
valueFormat
:
'YYYY/MM/DD'
,
format
:
'YYYY/MM/DD'
,
},
},
{
field
:
'biddingPeriod'
,
label
:
'计划招标周期'
,
required
:
true
,
component
:
'RangePicker'
,
colProps
:
{
span
:
7
,
offset
:
1
},
componentProps
:
{
valueFormat
:
'YYYY/MM/DD'
,
format
:
'YYYY/MM/DD'
,
},
},
{
field
:
'biddingMethod'
,
label
:
'招标方式'
,
required
:
true
,
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'建委招标'
,
value
:
'建委招标'
,
},
{
label
:
'平台招标'
,
value
:
'平台招标'
,
},
{
label
:
'邀标比选'
,
value
:
'邀标比选'
,
},
{
label
:
'直接委托'
,
value
:
'直接委托'
,
},
{
label
:
'评定分离'
,
value
:
'评定分离'
,
},
],
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
label
:
'招标内容'
,
field
:
'tenderContent'
,
required
:
true
,
component
:
'InputTextArea'
,
componentProps
:
{
maxlength
:
100
,
showCount
:
true
,
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
{
label
:
'备注'
,
field
:
'remark'
,
// required: true,
component
:
'InputTextArea'
,
componentProps
:
{
maxlength
:
100
,
showCount
:
true
,
},
colProps
:
{
span
:
7
,
offset
:
1
},
},
];
src/views/tenderYearPlan/edit.vue
0 → 100644
View file @
8c8efd1e
<
template
>
<PageWrapper
:title=
"getTitle"
v-loading=
"loadingRef"
loading-tip=
"加载中..."
:contentBackground=
"false"
headerSticky
>
<template
#
extra
>
<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=
"default"
@
click=
"router.back()"
>
返回
</a-button>
</
template
>
<!-- page页 -->
<CollapseContainer
v-for=
"(item, index) in tabsFormSchema"
:key=
"index"
v-show=
"item.show"
>
<
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"
v-show=
"content.show"
>
<
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>
<a-button
v-if=
"!disabled"
type=
"dashed"
@
click=
"handleAdd"
class=
"ml-2"
preIcon=
"ei:plus"
>
新建项目
</a-button>
<Upload
:action=
"uploadAction"
name=
"file"
:multiple=
"false"
methods=
"post"
:file-list=
"fileList"
accept=
".xlsx,.xls"
:on-success=
"uploadFile"
>
<a-button
v-if=
"!disabled"
type=
"dashed"
class=
"ml-2"
preIcon=
"ei:plus"
>
Excel导入
</a-button>
</Upload>
<projectDrawer
v-if=
"!disabled"
@
register=
"registerDrawer"
@
success=
"handleSuccess"
/>
<projectlibraryModel
v-if=
"!disabled"
@
register=
"register"
@
close=
"handleNewData"
/>
</PageWrapper>
</template>
<
script
lang=
"ts"
setup
>
//历史记录
import
{
unref
,
onMounted
,
ref
,
reactive
,
nextTick
}
from
'vue'
;
import
projectlibraryModel
from
'@/components/projectlibraryModel/projectlibraryModel.vue'
;
import
{
PageWrapper
}
from
'@/components/Page'
;
import
projectDrawer
from
'@/views/project/projectDrawer.vue'
;
import
{
BasicForm
,
useForm
,
FormProps
,
UseFormReturnType
}
from
'@/components/Form'
;
import
{
formSchema
}
from
'./data'
;
import
{
deepMerge
}
from
'@/utils'
;
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
{
useDrawer
}
from
'@/components/Drawer'
;
import
{
addProject
,
updateProject
,
selectDetail
}
from
'@/api/project/yearTenderPlan'
;
import
{
editModel
}
from
'@/api/project/model/biddingPlanModel'
;
import
{
useModal
}
from
'@/components/Modal'
;
import
{
router
}
from
'@/router'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
isArray
}
from
'lodash-es'
;
import
CollapseContainer
from
'@/components/Container/src/collapse/CollapseContainer.vue'
;
import
{
Upload
}
from
'ant-design-vue'
;
//历史记录是否可查
const
historyData
=
ref
(
true
);
//页面传递过来了的id
const
routeId
=
ref
(
null
);
const
loadingRef
=
ref
(
false
);
const
[
registerDrawer
,
{
openDrawer
}]
=
useDrawer
();
const
[
register
,
{
openModal
:
openModal
}]
=
useModal
();
const
{
createMessage
}
=
useMessage
();
const
isUpdate
=
ref
(
false
);
const
loading
=
ref
(
false
);
const
formData
=
ref
<
editModel
>
({});
const
tenderId
=
ref
<
any
>
(
''
);
const
disabled
=
ref
(
false
);
const
getTitle
=
ref
(
''
);
const
fileList
=
ref
([]);
const
uploadAction
=
import
.
meta
.
env
.
MODE
===
'development'
?
'http://localhost:5173/api/pro/tenderYearPlan/import'
:
'http://172.72.253.84/pro/tenderYearPlan/import'
;
onMounted
(
async
()
=>
{
loadingRef
.
value
=
true
;
const
route
=
useRoute
();
const
id
=
route
.
query
.
id
;
// 获取名为id的参数
routeId
.
value
=
id
;
if
(
!
id
)
{
historyData
.
value
=
false
;
formData
.
value
.
biddingQuarter
=
route
.
query
.
quarter
;
formData
.
value
.
tenderYear
=
route
.
query
.
year
;
formData
.
value
.
tenderPlanPro
=
[];
isUpdate
.
value
=
false
;
getTitle
.
value
=
'创建年度招标计划'
;
console
.
log
(
formData
);
}
else
{
isUpdate
.
value
=
true
;
tenderId
.
value
=
id
;
formData
.
value
.
tenderId
=
id
;
disabled
.
value
=
route
.
query
.
disabled
==
'0'
?
false
:
true
;
if
(
disabled
.
value
)
{
getTitle
.
value
=
'查看年度招标计划'
;
}
else
{
getTitle
.
value
=
'编辑年度招标计划'
;
}
let
res
=
await
selectDetail
({
id
});
formData
.
value
.
tenderPlanPro
=
[];
for
(
let
i
=
0
;
i
<
res
.
length
;
i
++
)
{
const
source
=
res
[
i
];
const
item
=
{
name
:
'项目:'
+
source
.
projectName
,
forceRender
:
true
,
show
:
true
,
proId
:
source
.
proId
,
Form
:
useForm
(
Object
.
assign
({
schemas
:
formSchema
,
disabled
},
baseFormConfig
)
as
FormProps
,
),
};
source
.
biddingPeriod
=
source
.
biddingPeriod
?
source
.
biddingPeriod
.
split
(
','
)
:
''
;
source
.
plannedPeriod
=
source
.
plannedPeriod
?
source
.
plannedPeriod
.
split
(
','
)
:
''
;
const
{
setFieldsValue
}
=
item
.
Form
[
1
];
tabsFormSchema
.
push
(
item
);
formData
.
value
.
tenderPlanPro
.
push
({
id
:
source
.
id
,
proId
:
source
.
proId
,
tenderId
:
source
.
tenderId
,
});
nextTick
(()
=>
{
setFieldsValue
({
...
source
,
});
});
}
}
loadingRef
.
value
=
false
;
});
type
TabsFormType
=
{
name
:
string
;
show
?:
boolean
;
forceRender
?:
boolean
;
Form
:
UseFormReturnType
;
proId
:
string
;
};
const
baseFormConfig
:
Partial
<
FormProps
>
=
{
showActionButtonGroup
:
false
,
labelWidth
:
100
,
layout
:
'vertical'
,
};
let
tabsFormSchema
=
reactive
<
TabsFormType
[]
>
([]);
async
function
add
()
{
openModal
();
}
async
function
handleNewData
(
info
:
any
)
{
if
(
info
)
{
info
.
map
((
i
)
=>
{
handleNew
(
i
);
});
}
}
/***
*
*/
async
function
handleNew
(
info
:
any
)
{
const
item
=
{
name
:
'项目:'
+
info
.
projectName
,
show
:
true
,
forceRender
:
true
,
proId
:
info
.
id
,
Form
:
useForm
(
Object
.
assign
({
schemas
:
formSchema
},
baseFormConfig
)
as
FormProps
),
};
const
{
setFieldsValue
}
=
item
.
Form
[
1
];
tabsFormSchema
.
push
(
item
);
await
nextTick
(()
=>
{
setFieldsValue
({
projectName
:
info
.
projectName
,
fundingSource
:
info
.
fundingSource
,
investmentAmount
:
info
.
projectInvestment
,
proId
:
info
.
id
,
});
});
}
async
function
deleteItem
(
index
:
any
)
{
tabsFormSchema
[
index
].
show
=
false
;
loadingRef
.
value
=
false
;
}
async
function
handleAdd
()
{
openDrawer
(
true
,
{
isUpdate
:
false
,
});
}
async
function
handleSuccess
(
params
:
any
)
{
console
.
log
(
params
);
handleNew
(
params
);
}
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
},
]);
}
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
},
]);
}
});
}
loadingRef
.
value
=
true
;
formData
.
value
.
tenderPlanPro
=
[];
try
{
let
engineerConListIndex
=
0
;
for
(
let
i
=
0
;
i
<
tabsFormSchema
.
length
;
i
++
)
{
let
item
=
tabsFormSchema
[
i
];
if
(
item
.
show
)
{
const
{
validate
,
getFieldsValue
}
=
item
.
Form
[
1
];
await
validate
();
let
res
=
getFieldsValue
();
res
.
biddingPeriod
=
isArray
(
res
.
biddingPeriod
)
?
res
.
biddingPeriod
.
join
(
','
)
:
res
.
biddingPeriod
;
res
.
plannedPeriod
=
isArray
(
res
.
plannedPeriod
)
?
res
.
plannedPeriod
.
join
(
','
)
:
res
.
plannedPeriod
;
console
.
log
(
'deepMerge(formData.value.tenderPlanPro[i], res)'
,
deepMerge
(
formData
.
value
.
tenderPlanPro
[
i
],
res
),
);
let
obj
=
{
proId
:
item
.
proId
,
};
obj
=
deepMerge
(
obj
,
res
);
formData
.
value
.
tenderPlanPro
.
push
(
obj
);
engineerConListIndex
=
engineerConListIndex
+
1
;
}
}
formData
.
value
.
proNumber
=
formData
.
value
.
tenderPlanPro
.
Length
;
formData
.
value
.
isSubmit
=
isSubmit
;
isUpdate
.
value
?
await
updateProject
(
unref
(
formData
))
:
await
addProject
(
unref
(
formData
));
loadingRef
.
value
=
true
;
if
(
isSubmit
===
'1'
)
{
createMessage
.
success
(
'提交成功!'
);
}
else
if
(
isSubmit
===
'0'
)
{
createMessage
.
success
(
'暂存成功!'
);
}
// router.back();
}
catch
(
e
)
{
// 验证失败或出错,切换到对应标签页
createMessage
.
error
(
'请将项目'
+
e
.
values
.
projectName
+
'信息填写完整!'
);
console
.
log
(
e
);
}
finally
{
loadingRef
.
value
=
false
;
}
}
async
function
uploadFile
(
response
)
{
loadingRef
.
value
=
true
;
if
(
response
.
code
==
1
)
{
response
.
data
.
map
((
info
)
=>
{
const
item
=
{
name
:
'项目:'
+
info
.
proName
,
forceRender
:
true
,
show
:
true
,
Form
:
useForm
(
Object
.
assign
({
schemas
:
formSchema
},
baseFormConfig
)
as
FormProps
),
proId
:
info
.
id
?
info
.
id
:
''
,
};
const
{
setFieldsValue
}
=
item
.
Form
[
1
];
tabsFormSchema
.
push
(
item
);
nextTick
(()
=>
{
setFieldsValue
({
...
info
,
plannedPeriod
:
[
info
.
plannedPeriodStart
,
info
.
plannedPeriodEnd
],
biddingPeriod
:
[
info
.
biddingPeriodStart
,
info
.
biddingPeriodEnd
],
});
});
});
createMessage
.
success
(
'导入成功'
);
loadingRef
.
value
=
false
;
}
else
{
createMessage
.
error
(
'导入失败,请稍后重试'
);
loadingRef
.
value
=
false
;
return
;
}
}
</
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
>
src/views/tenderYearPlan/index.vue
0 → 100644
View file @
8c8efd1e
<
template
>
<div>
<div
v-if=
"deptId == 100 || deptId == 0"
style=
"margin: 16px"
>
<PageCard
title=
"数据填报周期"
>
<Row>
<Col
:span=
"20"
>
<div
class=
"cycleFrame"
>
<div
class=
"card"
>
<div
class=
"cycleIcon"
>
<img
src=
"@/assets/icons/tianbaoriqi.png"
/>
</div>
<div
class=
"characte"
>
<div
class=
"top"
>
填报周期
</div>
<div
@
click=
"selectCycle"
class=
"bottom"
style=
"color: #0d84ff; text-decoration: underline; cursor: pointer"
>
{{
mothCycle
.
fillCycle
}}
</div>
</div>
</div>
<Divider
type=
"vertical"
style=
"height: 36px; border-color: rgba(22,106,203,0.30)"
dashed
/>
<div
class=
"card"
>
<div
class=
"cycleIcon"
>
<img
src=
"@/assets/icons/shenyutianshu.png"
/>
</div>
<div
class=
"characte"
>
<div
class=
"top"
>
剩余天数
</div>
<div
class=
"bottom"
style=
"color:#DFAA21 "
>
{{
daysReturn
()
+
'天'
}}
</div>
</div>
</div>
<Divider
type=
"vertical"
style=
"height: 36px; border-color: rgba(22,106,203,0.30)"
dashed
/>
<div
class=
"card"
>
<div
class=
"cycleIcon"
>
<img
src=
"@/assets/icons/weiwancheng.png"
/>
</div>
<div
class=
"characte"
>
<div
class=
"top"
>
企业未完成
</div>
<div
class=
"bottom"
style=
"color:#DB4343"
>
{{
mothCycle
.
noNum
+
'家'
}}
</div>
</div>
</div>
<Divider
type=
"vertical"
style=
"height: 36px; border-color: rgba(22,106,203,0.30)"
dashed
/>
<div
class=
"card"
>
<div
class=
"cycleIcon"
>
<img
src=
"@/assets/icons/yiwancheng.png"
/>
</div>
<div
class=
"characte"
>
<div
class=
"top"
>
企业已完成
</div>
<div
class=
"bottom"
style=
"color:#16CB28"
>
{{
mothCycle
.
deptNum
-
mothCycle
.
noNum
+
'家'
}}
</div>
</div>
</div>
</div>
</Col>
<Col
:span=
"4"
>
<a-button
class=
"btn"
@
click=
"getFillDetails"
>
查看填报详情
</a-button>
<a-button
class=
"btn"
type=
"primary"
@
click=
"returnEdit"
>
{{
mothCycle
.
isEdit
===
'1'
?
'开启本轮填报'
:
'结束本轮填报'
}}
</a-button>
</Col>
</Row>
</PageCard>
</div>
<BasicTable
@
register=
"registerTable"
:title=
"'招标计划填报'"
>
<template
#
toolbar
>
<a-button
type=
"primary"
preIcon=
"mdi:plus"
@
click=
"handleCreate"
>
新增招标计划
</a-button>
</
template
>
<
template
#
bodyCell=
"{ column, record, index }"
>
<template
v-if=
"column.key === 'reviewStatus'"
>
<Tag
color=
"warning"
v-if=
"record.reviewStatus === '0'"
>
未审核
</Tag>
</
template
>
<
template
v-if=
"column.key === 'reviewStatus'"
>
<Tag
color=
"success"
v-if=
"record.reviewStatus === '1'"
>
已审核
</Tag>
</
template
>
<
template
v-if=
"column.key === 'serialNumber'"
>
{{
index
+
1
}}
</
template
>
<
template
v-if=
"column.key === 'tenderYear'"
>
{{
record
.
tenderYear
+
'年'
+
record
.
biddingQuarter
}}
</
template
>
<
template
v-if=
"column.key === 'action'"
>
<TableAction
:actions=
"[
{
label: '详情',
onClick: handleEdit.bind(null, record, 1),
},
{
label: '修改',
onClick: handleEdit.bind(null, record, 0),
ifShow: (_action) => {
return record.isEdit === '0';
},
},
{
label: '删除',
color: 'error',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null, record),
},
ifShow: (_action) => {
return record.isEdit === '0';
},
},
{
label: '上报',
color: 'success',
popConfirm: {
title: '是否确认上报',
placement: 'left',
confirm: examine.bind(null, record, true),
},
ifShow: (_action) => {
return (record.reviewStatus === '0' || record.reviewStatus === null)
&&
isExamine === true
&&
record.isSubmit == '1';
},
},
]"
/>
</
template
>
</template>
</BasicTable>
<yearModal
@
register=
"register"
@
close=
"handleNew"
/>
<CycleModel
@
register=
"registerCycleModel"
:user-data=
"mothCycle"
@
get-cycle=
"getSetCycle"
/>
<FillDetailsModel
@
register=
"registerFillDetail"
></FillDetailsModel>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
BasicTable
,
useTable
,
TableAction
}
from
'@/components/Table'
;
import
{
selectPageList
,
deleteProject
,
handelExamine
,
getCount
}
from
'@/api/project/yearTenderPlan'
;
import
{
useModal
}
from
'@/components/Modal'
;
import
yearModal
from
'@/components/yearModal.vue'
;
import
{
columns
,
searchFormSchema
}
from
'./data'
;
import
{
useRouter
}
from
'vue-router'
;
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
{
Tag
}
from
"ant-design-vue"
;
//审核相关操作
import
{
operateType
,
addItemApi
,
addItemData
}
from
'@/api/operations/operations'
;
import
{
onMounted
,
ref
}
from
'vue'
;
import
{
useUserStore
}
from
"@/store/modules/user"
;
import
PageCard
from
'@/components/Page/src/PageCard.vue'
;
import
CycleModel
from
'@/views/monthlyPlan/cycleModel/cycleModel.vue'
;
import
FillDetailsModel
from
'@/views/monthlyPlan/fillDetailsModel/fillDetailsModel.vue'
;
import
{
Divider
,
Row
,
Col
}
from
'ant-design-vue'
import
{
getDepartmentList
}
from
'@/api/project/settlementManage'
;
import
{
getMothCycel
,
SetEditStatus
}
from
"@/api/project/monthlyPlan"
;
const
{
createMessage
}
=
useMessage
();
const
{
error
}
=
createMessage
;
const
{
push
}
=
useRouter
();
const
[
registerFillDetail
,
{
openModal
:
openFillDetailModel
}]
=
useModal
();
const
[
registerCycleModel
,
{
openModal
:
openCycleModel
}]
=
useModal
();
const
[
register
,
{
openModal
:
openModal
,
closeModal
:
closeModal
}]
=
useModal
();
const
[
registerTable
,
{
reload
}]
=
useTable
({
api
:
selectPageList
,
columns
,
formConfig
:
{
labelWidth
:
120
,
schemas
:
searchFormSchema
,
},
useSearchForm
:
true
,
showTableSetting
:
false
,
bordered
:
true
,
showIndexColumn
:
false
,
actionColumn
:
{
width
:
220
,
title
:
'操作'
,
dataIndex
:
'action'
,
// slots: { customRender: 'action' },
fixed
:
undefined
,
},
});
const
isExamine
=
ref
<
boolean
>
(
false
);
const
deptId
=
ref
(
100
);
const
mothCycle
=
ref
({
fillCycle
:
'2024-09'
,
isEdit
:
'0'
,
deptNum
:
12
,
noNum
:
6
,
});
onMounted
(
async
()
=>
{
deptId
.
value
=
useUserStore
().
userInfo
.
deptParentId
;
let
roles
=
useUserStore
().
userInfo
.
roles
;
roles
.
forEach
((
item
)
=>
{
if
(
item
.
role_key
===
'approver'
)
{
isExamine
.
value
=
true
;
}
});
const
data
=
await
getDepartmentList
();
searchFormSchema
[
1
].
componentProps
.
options
=
data
;
getSetCycle
()
});
async
function
getSetCycle
()
{
const
cycle
=
await
getMothCycel
({
id
:
'12'
,
module
:
'TenderPlan'
});
mothCycle
.
value
=
cycle
;
}
function
returnEdit
()
{
if
(
mothCycle
.
value
.
isEdit
==
'1'
)
{
mothCycle
.
value
.
isEdit
=
'0'
;
SetEditStatus
(
mothCycle
.
value
);
}
else
{
mothCycle
.
value
.
isEdit
=
'1'
;
SetEditStatus
(
mothCycle
.
value
);
}
reload
();
}
function
daysReturn
()
{
// 获取今天的日期
const
today
=
new
Date
();
// 获取目标年份和月份
let
targetYear
=
Number
.
parseInt
(
mothCycle
.
value
.
fillCycle
);
let
targetMonth
=
12
;
// 创建目标日期(2024年9月30日)
const
targetDate
=
new
Date
(
targetYear
,
targetMonth
,
0
);
// 0表示上一个月的最后一天,即9月30日
// 计算时间差(毫秒)
const
timeDifference
=
targetDate
-
today
;
// 计算天数差(天数 = 毫秒差 / 每天的毫秒数)
const
daysUntilTarget
=
Math
.
max
(
0
,
Math
.
ceil
(
timeDifference
/
(
1000
*
60
*
60
*
24
)));
return
daysUntilTarget
;
}
function
selectCycle
()
{
openCycleModel
(
true
,
{
data
:
mothCycle
.
value
,
});
}
function
getFillDetails
(){
openFillDetailModel
(
true
,{
data
:
mothCycle
.
value
,
url
:
'/pro/monthEngineer/businessComDetails'
,
module
:
'TenderPlan'
,
})
}
function
handleCreate
()
{
openModal
(
true
,
{
data
:
[
'year'
,
'quarter'
],
});
}
function
handleEdit
(
record
:
Recordable
,
disabled
:
number
)
{
push
({
path
:
'/biddingPlan/tendeYearPlanEdit'
,
query
:
{
id
:
record
.
id
,
disabled
:
String
(
disabled
),
},
});
}
function
handleDelete
(
record
:
Recordable
)
{
deleteProject
({
id
:
record
.
id
});
reload
();
}
async
function
handleNew
(
e
)
{
let
res
=
await
getCount
(
e
);
if
(
res
==
true
)
{
closeModal
();
push
({
path
:
'/biddingPlan/tendeYearPlanEdit'
,
query
:
e
,
});
}
else
{
error
(
'该周期已填报'
);
}
}
async
function
examine
(
record
:
Recordable
,
disabled
:
boolean
)
{
const
id
=
record
.
id
;
const
res
=
await
handelExamine
({
id
});
addItemData
.
operateType
=
operateType
.
audit
;
addItemData
.
businessId
=
record
.
id
;
addItemData
.
businessType
=
'招标计划'
;
const
showDatem
=
await
addItemApi
(
addItemData
);
console
.
log
(
showDatem
,
'记录添加成功'
);
console
.
log
(
res
);
reload
();
}
</
script
>
<
style
scoped
>
.btn
{
margin-right
:
10px
;
margin-top
:
8px
;
}
.cycleFrame
{
border
:
1px
solid
rgba
(
22
,
106
,
203
,
0.10
);
border-radius
:
6px
;
padding
:
20px
50px
;
margin-right
:
20px
;
display
:
flex
;
justify-content
:
space-between
;
.card{
display
:
flex
;
.cycleIcon{
margin-right
:
10px
;
}
.characte
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-around
;
.top{
}
.bottom
{}
}
}
}
</
style
>
src/views/tenderYearPlan/statistics.vue
0 → 100644
View file @
8c8efd1e
<
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
}
from
'vue'
;
import
{
Table
}
from
'ant-design-vue'
;
import
{
exportTender
,
selectListAll
}
from
'@/api/project/yearTenderPlan'
;
import
{
BasicForm
,
FormActionType
,
useForm
}
from
'@/components/Form'
;
import
PageCard
from
'@/components/Page/src/PageCard.vue'
;
import
{
downloadByData
}
from
'@/utils/file/download'
;
import
moment
from
'moment'
;
import
{
getDepartmentList
}
from
'@/api/project/settlementManage'
;
const
seach
=
ref
([
{
field
:
'tenderYear'
,
label
:
''
,
component
:
'DatePicker'
,
componentProps
:
{
placeholder
:
'年份'
,
picker
:
'year'
,
defaultValue
:
moment
().
format
(
'YYYY'
),
valueFormat
:
'YYYY'
,
format
:
'YYYY'
,
style
:
{
width
:
'100%'
,
},
},
colProps
:
{
span
:
4
},
},
{
field
:
'companyId'
,
label
:
''
,
component
:
'Select'
,
componentProps
:
{
placeholder
:
'公司名称'
,
options
:
[
{
label
:
'公司名称'
,
value
:
'公司名称'
,
},
],
},
colProps
:
{
span
:
4
},
},
]);
const
formElRef
=
ref
<
Nullable
<
FormActionType
>>
(
null
);
const
[
registerForm
,
{
getFieldsValue
}]
=
useForm
({
labelWidth
:
90
,
baseColProps
:
{
span
:
24
},
schemas
:
seach
,
showActionButtonGroup
:
false
,
});
const
params
=
ref
({
tenderYear
:
''
,
companyName
:
''
});
const
loadingRef
=
ref
(
false
);
onMounted
(
async
()
=>
{
// 设置当前年份
params
.
value
.
tenderYear
=
moment
().
format
(
'YYYY'
);
const
data
=
await
getDepartmentList
();
seach
.
value
[
1
].
componentProps
.
options
=
data
;
getStatisticList
();
});
function
handleSubmit
()
{
let
data
=
getFieldsValue
();
params
.
value
=
data
;
getStatisticList
();
}
async
function
exportCount
()
{
const
data
=
await
exportTender
(
params
.
value
);
downloadByData
(
data
,
'年度招标计划统计报表'
+
'.xls'
);
}
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
selectListAll
(
params
.
value
);
let
propsList
=
[
'companyName'
];
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
:
'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
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment