123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759 |
- <template>
- <el-card class="info-list-card progress_list_card">
- <div slot="header" class="flex-r-c">
- <span class="card-title"
- >关注项目列表<span class="title-tips"
- >(可关注 {{ projectAllNum }} 个项目,已关注
- <span style="color: #2cb7ca"> {{ projectNum }} </span> 个)</span
- ></span
- >
- <div
- class="flex-c-c right follow-manager"
- v-if="listState.list.length && !biMode"
- >
- <el-button @click="goManage" class="unfollow-btn" type="plain"
- >批量取消关注30天无更新的项目</el-button
- >
- </div>
- </div>
- <Tips tipText="解锁关注更多项目" v-if="!biMode"></Tips>
- <div class="info-list" v-loading="listState.loading">
- <!-- 工作桌面1.0 删除项目进度悬浮窗 -->
- <!-- <PoverTimeLine
- v-for="(item, index) in listState.list"
- :key="index"
- :stepList="item.stepList"
- @show="thisAnnouncement(item)">
- <template v-slot:content>
- <article-item
- :class="{ item_class: item.i_apppushunread !== 0 && item.i_apppushunread, visited: item.visited }"
- :index="(listState.pageSize * (listState.pageNum - 1)) + index + 1"
- :article="sortItemInfo(item)"
- @onClick="toDetail(item, index)"
- :projectData="projectInfoList">
- <span slot="right-time">{{ dateFromNow(item.l_lastpushtime * 1000) }}</span>
- </article-item>
- </template>
- </PoverTimeLine> -->
- <article-item
- v-for="(item, index) in listState.list"
- :key="index"
- :class="{
- item_class: item.i_apppushunread !== 0 && item.i_apppushunread,
- visited: item.visited
- }"
- :index="listState.pageSize * (listState.pageNum - 1) + index + 1"
- :article="sortItemInfo(item)"
- @onClick="toDetail(item, index)"
- :projectData="projectInfoList"
- >
- <span slot="right-time">{{ calcTime(item) }}</span>
- <!-- bi下显示添加按钮,不显示收藏标签 -->
- <button
- class="bi-report-inject-button"
- :disabled="item.added"
- v-if="biMode"
- @click="biAddProject(item)"
- slot="right-action"
- >
- {{ item.added ? '已添加' : '添加' }}
- </button>
- <template #right-handle-container>
- <span
- class="join-bid"
- @click.prevent.stop="joinBidHandle(item)"
- v-if="!biMode && item.joinBid !== undefined"
- >
- <i
- class="j-self-icon"
- :class="
- item.joinBid ? 'icon-canbiao-img-active' : 'icon-canbiao-img'
- "
- ></i>
- {{ item.joinBid ? '终止参标' : '参标' }}
- </span>
- </template>
- </article-item>
- <empty v-show="showEmpty && !nullProjectTips" images="jy-back.png">
- <div class="flex-c-c center">
- <span>暂无项目进度信息,前往招标搜索关注项目</span>
- <button class="null_tips_btn" @click="jumpPage" v-if="!biMode">
- 添加关注项目
- </button>
- </div>
- </empty>
- <empty v-show="nullProjectTips && showEmpty" images="jy-back.png">
- <div class="flex-c-c center">
- <span>暂无匹配数据</span>
- </div>
- </empty>
- </div>
- <div class="el-pagination-container" v-if="listState.total > 0">
- <el-pagination
- popper-class="pagination-custom-select"
- background
- layout="prev, pager, next, sizes, jumper"
- :current-page="listState.pageNum"
- :page-size="listState.pageSize"
- :total="listState.total"
- @current-change="onPageChange"
- :page-sizes="[5, 10, 50, 100]"
- :show-confirm-btn="true"
- @size-change="onSizeChange"
- >
- </el-pagination>
- </div>
- <!-- 参标更新状态弹窗 -->
- <BidrenewalDialog ref="BidrenewalDialog"></BidrenewalDialog>
- </el-card>
- </template>
- <script>
- import { Pagination, Card, Button } from 'element-ui'
- import Tips from '@/components/common/Tips.vue'
- import Empty from '@/components/common/Empty.vue'
- import ArticleItem from '@/components/article-item/ArticleItem.vue'
- import BidrenewalDialog from '@/views/BidrenewalDialog/index.vue'
- import {
- dateFromNow,
- dateFormatter,
- replaceKeyword,
- scrollTargetView
- } from '@/utils/'
- import {
- getFollowProjectList,
- setFollowRemove30Day,
- showAnnouncement,
- getBiAddedProjects,
- addBiProject,
- joinBidAction
- } from '@/api/modules/'
- import { mixinVisited } from '@/utils/mixins/visited'
- import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
- // import PoverTimeLine from '@/components/time-line/PoverTimeLine.vue'
- export default {
- name: 'project-list',
- mixins: [mixinVisited],
- components: {
- [Pagination.name]: Pagination,
- [Card.name]: Card,
- [Button.name]: Button,
- ArticleItem,
- Tips,
- // PoverTimeLine,
- Empty,
- BidrenewalDialog
- },
- props: {
- biMode: {
- type: Boolean,
- default: false
- },
- showMore: {
- type: Boolean,
- default: false
- },
- filters: {
- type: Object,
- default() {
- return {
- area: '',
- time: ''
- }
- }
- },
- projectNum: {
- type: Number,
- default: 0
- },
- projectAllNum: {
- type: Number,
- default: 10
- },
- dataList: {
- type: Array,
- default: function () {
- return []
- }
- },
- areaItem: {
- type: String,
- default: '全国'
- },
- nullProjectTips: {
- type: Boolean,
- default: false
- }
- },
- computed: {
- showEmpty() {
- return this.listState.list.length === 0 && this.listState.loaded
- },
- getFilters() {
- return this.filters
- }
- },
- data() {
- return {
- bi: {
- loading: false,
- addedIds: [] // bi已添加项目列表
- },
- isAllFirst: false,
- listState: {
- loaded: true, // 是否已经搜索过
- loading: false,
- pageNum: 1, // 当前页
- pageSize: 10, // 每页多少条数据
- total: 0, // 一共多少条数据
- list: [] // 查询请求返回的数据
- },
- thisDataList: [],
- activeArea: '',
- projectInfoList: [] // 鼠标悬浮项目详细公告
- }
- },
- created() {
- // this.doQuery()
- this.listState.loading = true
- this.listState.loaded = false
- setTimeout(() => {
- this.listState.loading = false
- this.listState.loaded = true
- }, 500)
- if (this.biMode) {
- this.getBiAddedProjects()
- }
- },
- watch: {
- dataList(data) {
- this.thisDataList = data
- this.listState.total = this.thisDataList.length
- if (this.listState.total <= this.listState.pageSize) {
- this.listState.pageNum = 1
- }
- let thisList = []
- const start = this.listState.pageSize * (this.listState.pageNum - 1)
- const end = this.listState.pageSize * this.listState.pageNum
- thisList = this.thisDataList.slice(start, end)
- this.listState.list = thisList.map((item) => {
- const visited = this.pathVisited(
- this.createPathItem('/pro_follow_detail/*', `id=${item.sid}`)
- )
- return {
- ...item,
- visited
- }
- })
- },
- areaItem(name) {
- this.activeArea = name
- this.listState.pageNum = 1
- let thisList = []
- const start = this.listState.pageSize * (this.listState.pageNum - 1)
- const end = this.listState.pageSize * this.listState.pageNum
- thisList = this.thisDataList.slice(start, end)
- this.listState.list = thisList.map((item) => {
- const visited = this.pathVisited(
- this.createPathItem('/pro_follow_detail/*', `id=${item.sid}`)
- )
- return {
- ...item,
- visited
- }
- })
- }
- },
- methods: {
- dateFromNow,
- goManage() {
- setFollowRemove30Day()
- .then((res) => {
- if (res && res.error_code === 0) {
- if (res.data && res.data.flag === 'success') {
- this.$emit('showTips', {
- message:
- res.data.removeNum > 0
- ? '已批量取消关注30天无更新的项目'
- : '暂无30天无更新的数据可删除'
- })
- this.$emit('reloadArea')
- }
- }
- this.$emit('reloadData')
- // this.doQuery()
- })
- .catch(() => {
- // this.doQuery()
- this.$emit('reloadData')
- })
- },
- // 恢复数据至第一次请求的状态(页码等)
- resetListState() {
- const state = {
- loaded: false,
- loading: false,
- pageNum: 1,
- pageSize: 10,
- total: 0,
- list: []
- }
- Object.assign(this.listState, state)
- },
- doQuery(filters) {
- this.resetListState()
- this.getList(filters)
- },
- async getList(filters) {
- const query = {
- pageNum: this.listState.pageNum - 1,
- pageSize: this.listState.pageSize
- }
- if (filters && Object.keys(filters).length > 0) {
- Object.keys(filters).forEach((v) => {
- if (typeof filters[v] !== 'undefined') {
- query[v] = filters[v]
- }
- })
- }
- this.listState.loading = true
- this.listState.loaded = false
- // 判断是否无筛选条件
- this.isAllFirst = false
- if (query.pagenum === 1 && query.area === '' && query.time === '') {
- this.isAllFirst = true
- }
- const res = await getFollowProjectList(query)
- this.listState.loading = false
- this.listState.loaded = true
- if (res.error_code === 0) {
- this.listState.total = res.data.total
- if (res.data && Array.isArray(res.data.List)) {
- res.data.List.forEach((item) => {
- const visited = this.pathVisited(
- this.createPathItem('/pro_follow_detail/*', `id=${item.sid}`)
- )
- this.$set(item, 'visited', visited)
- })
- }
- this.listState.list = res.data.List || []
- } else {
- this.listState.total = 0
- this.listState.list = []
- }
- this.checkAddedState()
- },
- toDetail(item) {
- const { sid, fid } = item
- item.visited = true
- item.i_apppushunread = 0
- this.pathVisiting(
- this.createPathItem('/pro_follow_detail/*', `id=${sid}`)
- )
- // const link = this.$router.resolve({
- // path: '/pro_follow_detail',
- // query: {
- // sid,
- // fid
- // }
- // })
- // window.open(link.href)
- const link = `/swordfish/page_big_pc/pro_follow_detail?sid=${sid}&fid=${fid}`
- window.open(link)
- },
- sortItemInfo(item) {
- return {
- ...item,
- type: item.status // 类型
- }
- },
- calcTime(item) {
- const minDay = +new Date('2000/01/01')
- if (item.l_lastpushtime * 1000 <= minDay) {
- return dateFromNow(item.l_createtime * 1000)
- } else {
- return dateFromNow(item.l_lastpushtime * 1000)
- }
- },
- onPageChange(p) {
- scrollTargetView('.info-list')
- this.listState.pageNum = p
- let thisList = []
- const start = this.listState.pageSize * (this.listState.pageNum - 1)
- const end = this.listState.pageSize * this.listState.pageNum
- thisList = this.thisDataList.slice(start, end)
- this.listState.list = thisList
- },
- onSizeChange(size) {
- this.listState.pageNum = 1
- this.listState.pageSize = size
- let thisList = []
- const start = this.listState.pageSize * (this.listState.pageNum - 1)
- const end = this.listState.pageSize * this.listState.pageNum
- thisList = this.thisDataList.slice(start, end)
- this.listState.list = thisList
- },
- async getBiAddedProjects() {
- const { data, error_code: code } = await getBiAddedProjects()
- if (code === 0 && Array.isArray(data)) {
- this.bi.addedIds = data
- this.checkAddedState()
- }
- },
- checkAddedState: function () {
- const addedIds = this.bi.addedIds || []
- if (!$.isArray(addedIds)) return
- if (addedIds.length === 0) return
- this.listState.list.forEach((item) => {
- const added = addedIds.indexOf(item.sid) !== -1
- this.$set(item, 'added', added)
- })
- },
- // 单个添加
- biAddProject(item) {
- if (item.added) return
- const id = item.sid
- if (!id) return
- this.biBatchAddRequest([id])
- },
- async biBatchAddRequest(ids) {
- if (this.bi.loading) return
- this.bi.loading = true
- const params = {
- info_id: ids.join(','),
- source: 3
- }
- const {
- data,
- error_code: code,
- error_msg: msg
- } = await addBiProject(params)
- this.bi.loading = false
- if (code === 0 && data) {
- if (data.status === 1) {
- this.$toast('添加成功')
- }
- this.getBiAddedProjects()
- } else {
- if (msg) {
- this.$toast(msg)
- }
- }
- },
- // 鼠标悬浮展示项目公告
- thisAnnouncement(itemA) {
- if (!itemA.stepList) {
- const data = {
- sid: itemA.sid
- }
- showAnnouncement(data).then((res) => {
- const thisTag = []
- if (res.data.projectInfo.list) {
- const list = res.data.projectInfo.list.reverse()
- list.forEach((item) => {
- // item.s_id = item.s_eid
- item.time = dateFormatter(item.l_publishtime * 1000, 'yyyy-MM-dd')
- if (item.s_subtype || item.s_toptype) {
- item.tags = [item.s_subtype || item.s_toptype]
- } else {
- item.tags = thisTag
- }
- item.content = replaceKeyword(
- item.s_title,
- itemA.title,
- `<span class="highlight-text">${itemA.title}</span>`
- )
- })
- this.$set(itemA, 'stepList', list)
- } else {
- this.$set(itemA, 'stepList', [])
- }
- })
- }
- },
- jumpPage() {
- const url = '/jylab/supsearch/index.html?publishtime=thisyear'
- tryCallHooks({
- fn: () => {
- this.$BRACE.methods.open({
- route: {
- link: url,
- appType: 'iframe'
- }
- })
- },
- spareFn: () => {
- window.open(url)
- }
- })
- },
- // 参标
- async joinBidHandle(item) {
- if (item.joinBid) {
- this.$toast('如需终止参标,需要在详情页进行操作。')
- return
- }
- const params = {
- bidIds: item.sid
- }
- try {
- const {
- error_code: code,
- error_msg: msg,
- data
- } = await joinBidAction('in', params)
- if (code === 0 && data) {
- // this.$toast('已参标,请前往我的参标项目列表查看。')
- // 拉起参标更新弹窗
- this.$refs.BidrenewalDialog.passVisible = true
- this.$refs.BidrenewalDialog.setid(item.sid)
- this.$refs.BidrenewalDialog.refreshData()
- this.$emit('joinBidBack', item)
- } else if (code === -1) {
- this.$toast(msg || '操作错误,请稍后重试')
- }
- } catch (e) {
- console.warn(e)
- this.$toast('操作错误,请稍后重试')
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- @include diy-icon('edit', 20, 20);
- // card样式重置
- ::v-deep {
- .el-card__header {
- margin: 0 40px;
- border-bottom: none;
- padding-left: 0;
- padding-right: 0;
- padding-bottom: 16px;
- padding-top: 20px;
- }
- .el-card__body {
- padding: 0 40px 20px 40px;
- }
- .get-more {
- display: flex;
- .el-icon-arrow-right {
- margin-left: 4px;
- order: 2;
- }
- }
- .article-item:hover {
- background: #f5f6f7;
- box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.05) inset;
- }
- .article-item:hover .a-i-left {
- color: #2cb7ca;
- }
- .article-item .tags span {
- background: #f5f5fb !important;
- border: 1px solid #ececec !important;
- font-size: 12px;
- font-weight: 400;
- text-align: center;
- color: #686868;
- }
- .el-icon-jy-time {
- display: none;
- }
- .item_class .a-i-left {
- max-width: min-content;
- display: flex;
- justify-content: flex-start;
- align-items: center;
- }
- .item_class .a-i-left::after {
- content: '';
- display: block;
- width: 8px;
- height: 8px;
- background: #ff3a20;
- border-radius: 50%;
- margin-left: 5px;
- }
- }
- .follow-manager {
- font-size: 12px;
- line-height: 20px;
- color: #aaaaaa;
- &-button {
- border: 1px solid #e0e0e0;
- box-sizing: border-box;
- border-radius: 6px;
- font-size: 13px;
- line-height: 20px;
- color: #1d1d1d;
- padding: 4px 12px;
- box-sizing: border-box;
- & + span {
- margin-top: 4px;
- }
- }
- }
- .sub-manager {
- display: flex;
- align-items: center;
- padding: 8px 16px;
- font-size: 14px;
- line-height: 24px;
- color: #1d1d1d;
- border-color: #e0e0e0;
- &.el-button:focus,
- &.el-button:hover {
- color: inherit;
- background-color: inherit;
- }
- }
- .info-list-card {
- .card-title {
- font-size: 18px;
- color: #1d1d1d;
- font-weight: 700;
- display: block;
- line-height: 34px;
- .title-tips {
- font-size: 14px;
- color: #666666;
- font-weight: 400;
- }
- }
- .sub-manager {
- float: right;
- }
- .info-list {
- min-height: 300px;
- border-top: 1px solid transparent;
- position: relative;
- }
- .add-key-button {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-top: 32px;
- padding: 8px 16px;
- color: #f7f9fa;
- border-radius: 6px;
- background-color: #2abed1;
- cursor: pointer;
- .icon-chahao {
- margin-right: 4px;
- transform: rotate(-45deg);
- }
- .button-text {
- margin-left: 4px;
- white-space: nowrap;
- }
- }
- .icon-chahao {
- position: relative;
- display: inline-block;
- width: 14px;
- height: 14px;
- &:before,
- &:after {
- position: absolute;
- content: '' !important;
- background-color: #fff;
- top: 50%;
- left: 50%;
- width: 14px;
- height: 2px;
- border-radius: 2px;
- }
- &:before {
- transform: translate(-50%, -50%) rotate(45deg);
- }
- &:after {
- transform: translate(-50%, -50%) rotate(-45deg);
- }
- }
- .el-pagination-container.center {
- .el-pagination {
- left: 50%;
- right: unset;
- transform: translateX(-50%);
- }
- }
- }
- .unfollow-btn {
- padding: 9px 16px;
- border: 1px solid #2cb7ca;
- border-radius: 6px;
- font-size: 14px;
- font-weight: 400;
- text-align: center;
- color: #2cb7ca;
- line-height: 14px;
- }
- .unfollow-btn:hover {
- background: rgba(44, 183, 202, 0.1);
- }
- .flex-r-c {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding-top: 10px;
- }
- .null_tips_btn {
- padding: 7px 24px;
- background: #2cb7ca;
- border-radius: 6px;
- font-size: 14px;
- color: #fff;
- }
- .bi-report-inject-button {
- display: inline-block;
- margin-left: 16px;
- border: 1px solid #2cb7ca;
- color: #2cb7ca;
- background-color: #fff;
- padding: 0 6px;
- height: 22px;
- line-height: 22px;
- border-radius: 4px;
- font-size: 14px;
- text-align: center;
- cursor: pointer;
- box-sizing: content-box;
- min-width: 42px;
- }
- /* .bi-report-inject-button[disabled] {
- opacity: 0.6;
- cursor: not-allowed;
- } */
- .j-self-icon {
- display: inline-block;
- width: 20px;
- height: 20px;
- background-position: center;
- vertical-align: top;
- }
- .join-bid {
- display: inline-block;
- cursor: pointer;
- font-size: 14px;
- line-height: 22px;
- color: #1d1d1d;
- .icon-canbiao-img {
- background: url(~@/assets/images/icon/canbiao.png) no-repeat center;
- background-size: contain;
- }
- .icon-canbiao-img-active {
- background: url(~@/assets/images/icon/canbiao-active.png) no-repeat center;
- background-size: contain;
- }
- }
- </style>
|