123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- <template>
- <van-popover
- v-model="showPopover"
- v-if="model.canFollow"
- trigger="click"
- :placement="placement"
- :offset="calcOffset"
- >
- <FollowPopoverContentCard
- :used="model.expands?.used"
- :surplus="model.expands?.surplus"
- @toTimeline="toProjectDetail"
- @toMyFollow="toMonitorList"
- @applyMore="applyMoreMonitor"
- @cancelFollow="cancelMonitor"
- />
- <template #reference>
- <TabActionItem
- showText
- :direction="direction"
- class="action-monitor"
- @click.native.stop="changePopoverState"
- >
- <AppIcon
- slot="icon"
- :name="model.follow ? 'yijiankong' : 'jiankong'"
- size="20"
- ></AppIcon>
- <template #text>{{ model.follow ? '已监控' : '监控' }}</template>
- </TabActionItem>
- </template>
- </van-popover>
- </template>
- <script>
- import TabActionItem from '@/views/article/ui/TabActionItem.vue'
- import FollowPopoverContentCard from '@/views/article/ui/FollowPopoverContentCard.vue'
- import { useQuickMonitorModel } from '@/composables/quick-monitor/index'
- import { Popover } from 'vant'
- import { AppIcon } from '@/ui'
- import { reactive, toRefs, toRef } from 'vue'
- import { mapGetters } from 'vuex'
- import { LINKS } from '@/data'
- import { openAppOrWxPage } from '@/utils/'
- import { cloneDeep } from 'lodash'
- const confMap = {
- project: {
- key: '项目',
- pushActiveKey: 2,
- applyMoreSource: 'article_project_more',
- limitSource: 'article_project_limit',
- toPushSettingDialogMessage:
- '您可前往“工作台-商机-项目进度监控”查看项目最新招标/采购进度。',
- successDialogMessage: '监控成功,您可前往“工作台-商机-项目进度监控”查看',
- monitorListLink: LINKS.项目进度监控列表,
- monitorListLinkBusiness: LINKS.商机管理项目进度监控列表
- },
- ent: {
- key: '企业',
- pushActiveKey: 4,
- applyMoreSource: 'article_ent_more',
- limitSource: 'article_ent_limit',
- toPushSettingDialogMessage:
- '您可前往“工作台-商机-企业情报监控”查看项目最新招标/采购进度。',
- successDialogMessage: '监控成功,您可前往“工作台-商机-企业情报监控”查看',
- monitorListLink: LINKS.企业情报监控列表
- },
- client: {
- key: '业主',
- pushActiveKey: 3,
- applyMoreSource: 'article_client_more',
- limitSource: 'article_client_limit',
- freeSource: 'buyer_monitor_freeuser',
- toPushSettingDialogMessage:
- '您可前往“工作台-商机-业主监控”查看项目最新招标/采购进度。',
- successDialogMessage: '监控成功,您可前往“工作台-商机-业主监控”查看',
- monitorListLink: LINKS.业主监控列表
- }
- }
- export default {
- name: 'QuickMonitor',
- components: {
- [Popover.name]: Popover,
- FollowPopoverContentCard,
- TabActionItem,
- AppIcon
- },
- props: {
- id: {
- type: String,
- default: '',
- required: true
- },
- type: {
- type: String,
- default: 'project',
- validator(t) {
- return ['project', 'ent', 'client'].includes(t)
- }
- },
- // 是否使用popover
- popover: {
- type: Boolean,
- default: false
- },
- cache: {
- type: Boolean,
- default: false
- },
- // 默认doFetch请求
- auto: {
- type: Boolean,
- default: false
- },
- direction: {
- type: String,
- default: 'column',
- validator(d) {
- return ['row', 'column'].includes(d)
- }
- },
- placement: {
- type: String,
- default: 'top'
- },
- beforeLeavePage: Function, // 跳转前处理
- beforeAction: Function
- },
- setup(props, { emit }) {
- const useMonitor = useQuickMonitorModel({
- type: props.type,
- cache: props.cache,
- params: {
- id: props.id
- }
- })
- const { model, fid } = toRefs(reactive(useMonitor))
- const { follow } = toRef(model)
- const { doFetch, doChange } = useMonitor
- if (props.auto) {
- doFetch().finally(() => {
- emit('initd', {
- model: cloneDeep(model.value),
- id: props.id,
- fid: fid?.value
- })
- })
- }
- return {
- useMonitor,
- model,
- follow,
- fid,
- doFetch,
- doChange
- }
- },
- data() {
- return {
- showPopover: false
- // model: {
- // canFollow: false,
- // follow: false,
- // expands: {
- // surplus: 0,
- // used: 0
- // }
- // }
- }
- },
- computed: {
- ...mapGetters('user', [
- 'isLogin',
- 'isFree',
- 'isMember',
- 'isBusiness',
- 'isNewBusiness',
- 'isEntService'
- ]),
- isMemberOrBusiness() {
- return this.isMember || this.isBusiness
- },
- conf() {
- const conf = confMap[this.type] || confMap.project
- // 项目监控跳转 - 商机管理跳转单独计算
- if (this.type === 'project' && conf.monitorListLinkBusiness) {
- if (this.isEntService || this.isNewBusiness || this.isBusiness) {
- conf.monitorListLink = conf.monitorListLinkBusiness
- }
- }
- return conf
- },
- calcOffset() {
- if (this.placement === 'top-start') {
- return [5, 10]
- } else if (this.placement === 'top-end') {
- return [-5, 10]
- } else {
- return undefined
- }
- }
- },
- methods: {
- async toProjectDetail() {
- const params = {
- fid: this.fid,
- sid: this.id
- }
- sessionStorage.setItem('bigvip-fid', JSON.stringify(params))
- if (this.beforeLeavePage) {
- await this.beforeLeavePage()
- }
- openAppOrWxPage(LINKS.项目详情页)
- },
- async toMonitorList() {
- if (this.beforeLeavePage) {
- await this.beforeLeavePage()
- }
- openAppOrWxPage(this.conf.monitorListLink)
- this.showPopoverList(false)
- },
- async applyMoreMonitor() {
- if (this.isMemberOrBusiness) {
- // 弹窗提示监控更多项目/企业/业主
- this.concatKfDialog({
- title: `申请监控更多${this.conf.key}`,
- message: `您可联系客服,申请升级产品套餐,监控更多${this.conf.key}`
- })
- } else {
- if (this.beforeLeavePage) {
- await this.beforeLeavePage()
- }
- // 留资页面
- this.$leaveInfo.toLeaveInfoPage({
- source: `${this.$env.platform}_${this.conf.applyMoreSource}`
- })
- }
- this.showPopoverList(false)
- },
- async concatKfDialog({ message, title }) {
- try {
- await this.$dialog.alert({
- title: title || '',
- messageAlign: 'center',
- className: 'j-confirm-dialog',
- confirmButtonText: '联系客服',
- showCancelButton: true,
- cancelButtonText: '我再想想',
- message: message
- })
- // 联系客服
- if (this.beforeLeavePage) {
- await this.beforeLeavePage()
- }
- openAppOrWxPage(LINKS.客服)
- } catch (error) {
- console.log('我再想想', error)
- }
- },
- async cancelMonitorDialog() {
- return await this.$dialog.alert({
- title: '确定不再监控?',
- messageAlign: 'center',
- className: 'j-confirm-dialog',
- confirmButtonText: '我再想想',
- showCancelButton: true,
- cancelButtonText: '确定取消',
- message: `取消监控,将错过${this.conf.key}最新动态推送`
- })
- },
- async cancelMonitor() {
- try {
- await this.cancelMonitorDialog()
- } catch (error) {
- this.doCancelMonitor()
- }
- },
- showPopoverList(f = false) {
- this.showPopover = f
- },
- async changePopoverState() {
- if (this.model.follow) {
- // 已监控
- if (this.popover) {
- this.showPopoverList(!this.showPopover)
- } else {
- // 点击弹窗,二次确认是否取消监控
- this.cancelMonitor()
- }
- } else {
- this.doMonitor()
- }
- },
- async successMonitorAndToPushSettingDialog() {
- try {
- await this.$dialog.alert({
- title: '监控成功',
- messageAlign: 'center',
- className: 'j-confirm-dialog',
- confirmButtonText: '去开启',
- showCancelButton: true,
- cancelButtonText: '暂不开启',
- message: `${this.conf.toPushSettingDialogMessage}为保证您能及时获取新增监控信息推送,请前往开启推送提醒。`
- })
- // 去开启提醒
- this.$router.push({
- path: '/push/pushsetting',
- query: {
- active: this.conf.pushActiveKey
- }
- })
- } catch (error) {
- console.log('暂不开启推送提醒', error)
- }
- },
- // 监控
- /**
- * 监控操作业务流程
- * 0. 前置权益判断
- * 0.1 判断是否非大会员、非商机管理用户
- * > 否,留资弹窗
- * 1. 监控成功
- * 1.1 判断是否开启推送提醒
- * > 是,提醒开启推送提醒 success-monitor
- * > 否,toast 提醒监控成功 success-toast
- * 2. 监控失败
- * 2.1 超出可监控项目个数
- * 2.1.1 判断是否非大会员、非商机管理用户
- * > 是,弹窗提醒 max-monitor
- * > 否,留资弹窗
- * 2.2 其他错误,toast 提醒
- * @return {Promise<void>}
- */
- async doMonitor() {
- if (this.beforeAction) {
- const r = await this.beforeAction()
- if (!r) {
- return
- }
- }
- // 采购单位监控,仅大会员和商机管理可用
- if (this.conf.freeSource) {
- if (this.isFree) {
- if (this.beforeLeavePage) {
- await this.beforeLeavePage()
- }
- return openAppOrWxPage(LINKS.留资, {
- query: {
- source: `${this.$env.platform}_${this.conf.freeSource}`
- }
- })
- }
- }
- const loading = this.$toast.loading()
- // do something...
- try {
- const { success, msg, data } = await this.doChange()
- loading.clear()
- if (success) {
- // 判断是否开启推送提醒
- if (data?.msg_open) {
- // 推送提醒已经开启
- this.$toast(this.conf.successDialogMessage)
- } else {
- // 提醒未开启
- this.successMonitorAndToPushSettingDialog()
- }
- } else {
- // 判断是否超出可监控项目个数
- if (data?.limit_count) {
- if (!this.isFree) {
- const count = data?.limit_count || 0
- this.concatKfDialog({
- title: `监控${this.conf.key}个数已达上限`,
- message: `您最多可监控${count}个${this.conf.key},可联系客服,申请监控更多${this.conf.key}`
- })
- } else {
- // 留资
- if (this.beforeLeavePage) {
- await this.beforeLeavePage()
- }
- return openAppOrWxPage(LINKS.留资, {
- query: {
- source: `${this.$env.platform}_${this.conf.limitSource}`
- }
- })
- }
- }
- // if (msg) {
- // this.$toast(msg)
- // }
- }
- this.syncValue(true)
- } catch (error) {
- // loading.clear()
- console.log(error)
- } finally {
- this.emitChange()
- }
- },
- emitChange() {
- this.$emit('change', {
- model: cloneDeep(this.model),
- id: this.id,
- fid: this.fid
- })
- },
- // 取消监控
- async doCancelMonitor() {
- const loading = this.$toast.loading()
- const { success, msg } = await this.doChange()
- if (success) {
- this.emitChange()
- console.log('取消监控成功')
- } else {
- console.log('取消监控失败', msg)
- }
- loading.clear()
- this.syncValue(false)
- },
- syncValue(v) {
- this.$emit('input', v)
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- ::v-deep {
- .tab-action-item {
- height: 100%;
- }
- .icon-jiankong {
- color: #9b9ca3;
- }
- .icon-yijiankong {
- color: #ff9f40;
- }
- }
- </style>
|