|
@@ -0,0 +1,158 @@
|
|
|
+<template>
|
|
|
+ <div class="w-full h-full flex flex-col">
|
|
|
+ <div class="flex-1 overflow-y-auto my-3 px-6">
|
|
|
+ <van-steps direction="vertical" :active="stageIndex">
|
|
|
+ <template v-for="item in stageList">
|
|
|
+ <van-step>
|
|
|
+ <div>{{ item.name }} {{ item.plan }}</div>
|
|
|
+ </van-step>
|
|
|
+ </template>
|
|
|
+ </van-steps>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="px-6 flex flex-col pb-4 mt-2" v-if="stageIndex <= stageList.length">
|
|
|
+ <van-button type="primary" class="btn-3" v-if="stageIndex < stageList.length - 1"
|
|
|
+ @click="promotionStage()">推荐下阶段({{
|
|
|
+ stageList[+stageIndex + 1]?.name
|
|
|
+ }})</van-button>
|
|
|
+ <van-button type="success" class="btn-3" @click="completionStage(1)">赢单</van-button>
|
|
|
+ <van-button type="warning" class="btn-3" @click="completionStage(2)">输单</van-button>
|
|
|
+ <van-button type="danger" class="btn-3" @click="completionStage(3)">无效</van-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <van-dialog v-model:show="showDisold" :title="`${transitionalData.title}原因`" show-cancel-button @confirm="stageCompletion()">
|
|
|
+ <van-field v-model="transitionalData.reason" rows="4" autosize type="textarea" :placeholder="`请输入${transitionalData.title}原因`"
|
|
|
+ show-word-limit />
|
|
|
+ </van-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref } from 'vue';
|
|
|
+import { useLifecycle } from '@hooks/useCommon.js';
|
|
|
+import { ACQUISITION_STAGE, GET_BUSINESS_OPPORTUNITY_DETAILS, PROMOTION_STAGE, STAGE_NOTES } from '@hooks/useApi'
|
|
|
+import requests from "@common/requests";
|
|
|
+import useShowToast from '@hooks/useToast'
|
|
|
+import useInfoStore from '@store/useInfoStore'
|
|
|
+import useRouterStore from "@store/useRouterStore.js";
|
|
|
+
|
|
|
+const { toastSuccess, toastFail, toastText, toastLoading } = useShowToast()
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ info: {
|
|
|
+ type: Object,
|
|
|
+ required: true,
|
|
|
+ default: () => ({})
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const infoData = ref({})
|
|
|
+const stageList = ref([])
|
|
|
+const stageIndex = ref(0)
|
|
|
+const stageSetting = ref([])
|
|
|
+const transitionalData = ref({})
|
|
|
+const showDisold = ref(false)
|
|
|
+
|
|
|
+function completionStage(type) {
|
|
|
+ const typeObj = { 1: '赢单', 2: '输单', 3: '无效' }
|
|
|
+ const row = stageSetting.value.find(item => item.name === typeObj[type])
|
|
|
+ transitionalData.value = {
|
|
|
+ id: infoData.value.id,
|
|
|
+ stageId: row.id,
|
|
|
+ stageValue: row.name,
|
|
|
+ title: `${typeObj[type]}`,
|
|
|
+ reason: ''
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type != 1) {
|
|
|
+ showDisold.value = true
|
|
|
+ } else {
|
|
|
+ stageCompletion(false)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function enterReason() {
|
|
|
+ const { id, reason } = transitionalData.value
|
|
|
+ requests.post(PROMOTION_STAGE, {
|
|
|
+ id, reason
|
|
|
+ }).then((res) => {
|
|
|
+ getBusinessOpportunityDetails(id)
|
|
|
+ }).catch((err) => {
|
|
|
+ toastFail(err.msg)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function stageCompletion(flag = true) {
|
|
|
+ const { id, stageId, stageValue } = transitionalData.value
|
|
|
+ requests.post(PROMOTION_STAGE, {
|
|
|
+ id, stageId, stageValue
|
|
|
+ }).then((res) => {
|
|
|
+ toastSuccess('操作成功')
|
|
|
+ if(flag) {
|
|
|
+ enterReason()
|
|
|
+ } else {
|
|
|
+ getBusinessOpportunityDetails(id)
|
|
|
+ }
|
|
|
+ }).catch((err) => {
|
|
|
+ toastFail(err.msg)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function promotionStage() {
|
|
|
+ const item = stageList.value[+stageIndex.value + 1]
|
|
|
+ toastLoading('推进中...', 0)
|
|
|
+ requests.post(PROMOTION_STAGE, {
|
|
|
+ id: infoData.value.id,
|
|
|
+ stageId: item.id,
|
|
|
+ stageValue: item.name
|
|
|
+ }).then((res) => {
|
|
|
+ toastSuccess('推进成功')
|
|
|
+ getBusinessOpportunityDetails(infoData.value.id)
|
|
|
+ }).catch((err) => {
|
|
|
+ toastFail(err.msg)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function acquisitionStage(row) {
|
|
|
+ requests.post(ACQUISITION_STAGE, {}).then((res) => {
|
|
|
+ stageIndex.value = (res.data || []).findIndex(item => item.id === row.stageId)
|
|
|
+ stageList.value = (res.data || []).filter(item => !(['赢单', '输单', '无效'].includes(item.name)))
|
|
|
+ stageSetting.value = (res.data || []).filter(item => (['赢单', '输单', '无效'].includes(item.name)))
|
|
|
+ const val = (stageSetting.value || []).find(item => item.id === row.stageId)
|
|
|
+ if(val.length > 0) {
|
|
|
+ stageList.value.push(val[0])
|
|
|
+ stageIndex.value = stageList.value.length - 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function getBusinessOpportunityDetails(id) {
|
|
|
+ requests.post(GET_BUSINESS_OPPORTUNITY_DETAILS, { id }).then((res) => {
|
|
|
+ infoData.value = res.data || {}
|
|
|
+ acquisitionStage(res.data)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function initializeData() {
|
|
|
+ getBusinessOpportunityDetails(props.info.id)
|
|
|
+}
|
|
|
+
|
|
|
+useLifecycle({
|
|
|
+ load: () => {
|
|
|
+ initializeData()
|
|
|
+ },
|
|
|
+ init: () => {
|
|
|
+ initializeData()
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang='scss' scoped>
|
|
|
+.btn-3 {
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep(.van-steps) {
|
|
|
+ background: none;
|
|
|
+}
|
|
|
+</style>
|