|
@@ -0,0 +1,408 @@
|
|
|
+<template>
|
|
|
+ <section class="project-details">
|
|
|
+ <header class="project-details-header pd-lr">
|
|
|
+ <div class="filter-list line-1">
|
|
|
+ <SubscribeClassListCascader
|
|
|
+ class="filter-item"
|
|
|
+ :options="subscribeClassList"
|
|
|
+ v-model="filters.subscribe"
|
|
|
+ @change="onFilterChange"
|
|
|
+ ref="subscribeKey" />
|
|
|
+ <AreaCityCascader
|
|
|
+ class="filter-item"
|
|
|
+ v-model="filters.area"
|
|
|
+ @change="onFilterChange"
|
|
|
+ :showAreaMap="subscribeAreaMap"
|
|
|
+ ref="areaCity" />
|
|
|
+ <BuyerClassCascader
|
|
|
+ class="filter-item"
|
|
|
+ v-model="filters.buyerClass"
|
|
|
+ @change="onFilterChange"
|
|
|
+ :showOptions="subscribeBuyerClass"
|
|
|
+ ref="buyerClass" />
|
|
|
+ <IndustryCascader
|
|
|
+ class="filter-item"
|
|
|
+ @change="onFilterChange"
|
|
|
+ v-model="filters.industry"
|
|
|
+ ref="industry" />
|
|
|
+ </div>
|
|
|
+ <div class="filter-list line-2">
|
|
|
+ <div class="filter-item">
|
|
|
+ <span class="filter-item-label">中标单位:</span>
|
|
|
+ <AssociationInput
|
|
|
+ class="filter-item-input"
|
|
|
+ v-model.trim="filters.winner"
|
|
|
+ placeholder="请输入中标单位名称"
|
|
|
+ type="ent" />
|
|
|
+ </div>
|
|
|
+ <div class="filter-item">
|
|
|
+ <span class="filter-item-label">采购单位:</span>
|
|
|
+ <AssociationInput
|
|
|
+ class="filter-item-input"
|
|
|
+ v-model.trim="filters.buyerName"
|
|
|
+ placeholder="请输入采购单位名称"
|
|
|
+ type="buyer" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </header>
|
|
|
+ <main class="project-details-main">
|
|
|
+ <div class="project-details-actions">
|
|
|
+ <div class="project-details-actions-left">
|
|
|
+ <template v-if="searchTotal > 0">共 <span class="highlight-text">{{ listState.total }}</span> 个项目</template>
|
|
|
+ </div>
|
|
|
+ <div class="project-details-actions-right no-select">
|
|
|
+ <el-radio-group class="sort-group" v-model="filters.sort" size="small">
|
|
|
+ <el-radio-button
|
|
|
+ v-for="item in conf.sortList"
|
|
|
+ :label="item.value"
|
|
|
+ :key="item.value"
|
|
|
+ >{{ item.name }}</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="project-details-list" v-loading="listState.loading">
|
|
|
+ <ProjectItem
|
|
|
+ class="project-details-item pd-lr"
|
|
|
+ v-for="project in listState.list"
|
|
|
+ :buyer="project.buyer"
|
|
|
+ :title="project.name"
|
|
|
+ :budget="project.budget"
|
|
|
+ :bidAmount="project.bidAmount"
|
|
|
+ :tagList="project.tagList"
|
|
|
+ :winners="project.winners"
|
|
|
+ @clickTitle="toProjectDetail(project)"
|
|
|
+ :key="project.id">
|
|
|
+ <template #hd-right>
|
|
|
+ 本{{reportTypeText}}项目更新时间:{{ project.lastTime ? dateFormatter(project.lastTime * 1000, 'yyyy-MM-dd') : '-' }}
|
|
|
+ </template>
|
|
|
+ </ProjectItem>
|
|
|
+ <Empty v-show="listState.list.length === 0 && listState.loaded">暂无数据</Empty>
|
|
|
+ </div>
|
|
|
+ </main>
|
|
|
+ <div class="project-details-footer">
|
|
|
+ <div class="pagination-container pd-lr" v-show="listState.total > 0">
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ popper-class="pagination-custom-select"
|
|
|
+ layout="prev, pager, next, sizes, jumper"
|
|
|
+ :page-size="listState.pageSize"
|
|
|
+ :current-page="listState.pageNum"
|
|
|
+ @current-change="onCurrentChange"
|
|
|
+ :total="searchTotal"
|
|
|
+ :page-sizes="[5, 10, 50, 100]"
|
|
|
+ :show-confirm-btn="true"
|
|
|
+ @size-change="onSizeChange"
|
|
|
+ ></el-pagination>
|
|
|
+ <div class="bottom-tip-text" v-show="listState.total > 5000">为您展示前{{ conf.listShowMaxCount }}条,可细化筛选条件查看更多信息</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { Input, RadioGroup, RadioButton, Table, TableColumn, Pagination } from 'element-ui'
|
|
|
+import SubscribeClassListCascader from '@/components/selector-cascader/SubscribeClassListCascader.vue'
|
|
|
+import AreaCityCascader from '@/components/selector-cascader/AreaCityCascader.vue'
|
|
|
+import BuyerClassCascader from '@/components/selector-cascader/BuyerClassCascader.vue'
|
|
|
+import IndustryCascader from '@/components/selector-cascader/IndustryCascader.vue'
|
|
|
+import AssociationInput from '@/views/reportData/components/AssociationInput.vue'
|
|
|
+import ProjectItem from '@/components/article-item/ProjectItem.vue'
|
|
|
+import Empty from '@/components/common/Empty'
|
|
|
+import { getWeekMonthReportProjectList } from '@/api/modules'
|
|
|
+import { formatMoney } from '@/utils/'
|
|
|
+import { debounce } from 'lodash'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'ProjectDetails',
|
|
|
+ components: {
|
|
|
+ [Input.name]: Input,
|
|
|
+ [RadioGroup.name]: RadioGroup,
|
|
|
+ [RadioButton.name]: RadioButton,
|
|
|
+ [Table.name]: Table,
|
|
|
+ [TableColumn.name]: TableColumn,
|
|
|
+ [Pagination.name]: Pagination,
|
|
|
+ SubscribeClassListCascader,
|
|
|
+ AreaCityCascader,
|
|
|
+ BuyerClassCascader,
|
|
|
+ IndustryCascader,
|
|
|
+ AssociationInput,
|
|
|
+ ProjectItem,
|
|
|
+ Empty
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ start: {
|
|
|
+ type: Number,
|
|
|
+ default: 0,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ end: {
|
|
|
+ type: Number,
|
|
|
+ default: 0,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ reportType: {
|
|
|
+ type: String,
|
|
|
+ default: 'week',
|
|
|
+ validator (value) {
|
|
|
+ return ['week', 'month'].includes(value)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ subscribeClassList: {
|
|
|
+ type: Array,
|
|
|
+ default () {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ subscribeBuyerClass: {
|
|
|
+ type: Array,
|
|
|
+ default () {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ subscribeAreaMap: {
|
|
|
+ type: Object,
|
|
|
+ default () {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ conf: {
|
|
|
+ sortList: [
|
|
|
+ {
|
|
|
+ name: '项目更新时间由晚到早',
|
|
|
+ value: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '项目金额由大到小',
|
|
|
+ value: 1
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ listShowMaxCount: 5000
|
|
|
+ },
|
|
|
+ filters: {
|
|
|
+ subscribe: [],
|
|
|
+ area: {},
|
|
|
+ buyerClass: [],
|
|
|
+ industry: {},
|
|
|
+ winner: '',
|
|
|
+ sort: 0,
|
|
|
+ buyerName: ''
|
|
|
+ },
|
|
|
+ listState: {
|
|
|
+ loaded: false,
|
|
|
+ loading: false,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ total: 0,
|
|
|
+ list: []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ reportTypeText () {
|
|
|
+ const map = {
|
|
|
+ week: '周',
|
|
|
+ month: '月'
|
|
|
+ }
|
|
|
+ return map[this.reportType]
|
|
|
+ },
|
|
|
+ searchTotal () {
|
|
|
+ const { total } = this.listState
|
|
|
+ const { listShowMaxCount } = this.conf
|
|
|
+ return total > listShowMaxCount ? listShowMaxCount : total
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ 'filters.winner': function () {
|
|
|
+ this.onFilterChange()
|
|
|
+ },
|
|
|
+ 'filters.buyerName': function () {
|
|
|
+ this.onFilterChange()
|
|
|
+ },
|
|
|
+ 'filters.sort': function () {
|
|
|
+ this.onFilterChange()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ this.doSearch()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onFilterChange: debounce(function () {
|
|
|
+ this.doSearch()
|
|
|
+ }, 500),
|
|
|
+ resetListState () {
|
|
|
+ const r = this.$options.data().listState
|
|
|
+ delete r.list
|
|
|
+ Object.assign(this.listState, r)
|
|
|
+ },
|
|
|
+ doSearch () {
|
|
|
+ this.resetListState()
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ onSizeChange (p) {
|
|
|
+ this.listState.pageSize = p
|
|
|
+ this.doSearch()
|
|
|
+ },
|
|
|
+ onCurrentChange (p) {
|
|
|
+ this.listState.pageNum = p
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ getFilters () {
|
|
|
+ const { subscribe, area, buyerClass, industry, winner, buyerName, sort } = this.filters
|
|
|
+ const subscribeList = subscribe.map(item => item.s_item)
|
|
|
+ let industryArr = []
|
|
|
+ for (const key in industry) {
|
|
|
+ industryArr = industryArr.concat(industry[key])
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ items: subscribeList,
|
|
|
+ sort,
|
|
|
+ area,
|
|
|
+ buyerClass,
|
|
|
+ industry: industryArr,
|
|
|
+ buyer: buyerName,
|
|
|
+ winner
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async getList () {
|
|
|
+ const filters = this.getFilters()
|
|
|
+ const params = {
|
|
|
+ pageNum: this.listState.pageNum,
|
|
|
+ pageSize: this.listState.pageSize,
|
|
|
+ start: this.start,
|
|
|
+ end: this.end,
|
|
|
+ ...filters
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ this.listState.loading = true
|
|
|
+ // const { listShowMaxCount } = this.conf
|
|
|
+ const { data, error_code: code } = await getWeekMonthReportProjectList(params)
|
|
|
+ if (code === 0 && data && Array.isArray(data.list)) {
|
|
|
+ this.listState.list = data.list.map(item => {
|
|
|
+ // 整理标签
|
|
|
+ item.tagList = [
|
|
|
+ {
|
|
|
+ value: item.area === '其它' ? '' : item.area
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: item?.bidStatus === '其它' ? '' : item?.bidStatus
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: item?.buyerClass === '其它' ? '' : item?.buyerClass
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // 有中标金额取中标金额,没有取预算,预算没有置空
|
|
|
+ value: formatMoney(item?.bidAmount || item?.budget)
|
|
|
+ }
|
|
|
+ ].filter(v => v.value)
|
|
|
+ // 整理中标企业
|
|
|
+ if (Array.isArray(item.winner)) {
|
|
|
+ const winners = item.winner.map((w, index) => {
|
|
|
+ let id = null
|
|
|
+ if (Array.isArray(item.winnerId)) {
|
|
|
+ id = item.winnerId[index]
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ name: w,
|
|
|
+ id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ item.winners = winners.filter(w => w.name)
|
|
|
+ }
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ this.listState.total = data.total
|
|
|
+ } else {
|
|
|
+ this.listState.list = []
|
|
|
+ this.listState.total = 0
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ this.listState.loading = false
|
|
|
+ this.listState.loaded = true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ toProjectDetail (item) {
|
|
|
+ if (item.id) {
|
|
|
+ window.open(`/swordfish/page_big_pc/pro_follow_detail?sid=${item.id}`)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.pd-lr {
|
|
|
+ padding-left: 40px;
|
|
|
+ padding-right: 40px;
|
|
|
+}
|
|
|
+.project-details {
|
|
|
+ padding: 32px 0;
|
|
|
+ background-color: #fff;
|
|
|
+ &-header {
|
|
|
+ margin-bottom: 46px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.project-details-actions {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 0 40px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+.project-details-list {
|
|
|
+ min-height: 420px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-list {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .filter-item-label {
|
|
|
+ margin-right: 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+ &.line-1 {
|
|
|
+ .filter-item {
|
|
|
+ &:not(:last-of-type) {
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &.line-2 {
|
|
|
+ margin-top: 16px;
|
|
|
+ .filter-item {
|
|
|
+ &:not(:last-of-type) {
|
|
|
+ margin-right: 32px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.project-details-footer {
|
|
|
+ text-align: right;
|
|
|
+ .bottom-tip-text {
|
|
|
+ margin-top: 8px;
|
|
|
+ padding: 0 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 18px;
|
|
|
+ color: #9B9CA3;
|
|
|
+ }
|
|
|
+}
|
|
|
+.sort-group {
|
|
|
+ ::v-deep {
|
|
|
+ .el-radio-button__inner {
|
|
|
+ padding: 8px 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ width: 160px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+::v-deep {
|
|
|
+ .el-radio-button__inner {
|
|
|
+ color: #1d1d1d;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|