商机增加转移商机

This commit is contained in:
yyy 2025-03-11 09:41:24 +08:00
parent 90ba9dadd5
commit 0dcc3ce983
6 changed files with 179 additions and 151 deletions

View File

@ -55,4 +55,10 @@ export function getStoreProductInfo(data) {
return api.get(`/product/store-product/info/${data.id}`, data, { return api.get(`/product/store-product/info/${data.id}`, data, {
login: false login: false
}) })
}
export function transferBusiness(data) {
return api.post('/crm/business/transfer', data, {
login: false
})
} }

View File

@ -29,8 +29,8 @@
<view v-else-if="!item.isLastLevel&&!item.isShowChild" class="switch-off" <view v-else-if="!item.isLastLevel&&!item.isShowChild" class="switch-off"
:style="{'border-top-color':switchColor}"> :style="{'border-top-color':switchColor}">
</view> </view>
<view v-else class="item-last-dot" :style="{'border-top-color':switchColor}"> <!-- <view v-else class="item-last-dot" :style="{'border-top-color':switchColor}">
</view> </view> -->
</view> </view>
<view class="uni-flex-item" @tap.stop="_onItemSelect(item, index)"> <view class="uni-flex-item" @tap.stop="_onItemSelect(item, index)">
<view class="item-name"> {{item.name+(item.childCount?"("+item.childCount+")":'')}} <view class="item-name"> {{item.name+(item.childCount?"("+item.childCount+")":'')}}
@ -443,8 +443,8 @@
} }
.tree-view { .tree-view {
padding: 20rpx 20rpx 20rpx 0;
flex: 1; flex: 1;
padding: 20rpx;
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
@ -509,8 +509,10 @@
.item-icon { .item-icon {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: flex-end;
width: 40rpx; width: 80rpx;
height: 60rpx;
padding-right: 18rpx;
} }
.item-label { .item-label {

View File

@ -1,16 +1,13 @@
<template> <template>
<view class="slot-content"> <view class="slot-content">
<uv-popup mode="bottom" border-radius="38" ref="showRef" > <uv-popup mode="bottom" border-radius="38" ref="showRef">
<view class="popup-title"> <view class="popup-title">
<view class="" style="width: 45px;"> <text class="">选择目标员工</text>
</view> <view class="close" @click="selectShowClose3">
<text class="">选择目标员工</text> <uv-icon name="close" color="#909399" size="22"></uv-icon>
<view class="" @click="selectShowClose3" style="width: 45px;">
<uv-icon name="close" color="#909399" size="30"></uv-icon>
</view> </view>
</view> </view>
<uv-search margin="30rpx 20rpx" shape="square" v-model="adminkeyword" :show-action="false" :clearabled="true" placeholder="输入名称搜索" @change="adminSearch"></uv-search> <scroll-view scroll-y style="height: 760rpx;width: 100%;">
<scroll-view scroll-y style="height: 760rpx;width: 100%;" @scrolltolower="adminBottom">
<view class="list"> <view class="list">
<block v-if="userList.length > 0"> <block v-if="userList.length > 0">
<view class="mb-4"> <view class="mb-4">
@ -21,17 +18,17 @@
</view> </view>
</view> </view>
</view> </view>
<uv-loadmore :status="adminStatus" ></uv-loadmore> <uv-loadmore :status="adminStatus"></uv-loadmore>
</block> </block>
<uv-empty text="暂无数据" v-else margin-top="50" mode="list"></uv-empty> <uv-empty text="暂无数据" v-else margin-top="50" mode="list"></uv-empty>
</view> </view>
</scroll-view> </scroll-view>
<view class="bottom_btn flex justify-end"> <view class="bottom_btn">
<view> <view>
<uv-button customStyle="padding:0 80rpx;" @click="selectShowClose3">取消</uv-button> <uv-button customStyle="padding:0 80rpx;" @click="selectShowClose3">取消</uv-button>
</view> </view>
<view style="margin-left: 20rpx;"> <view style="margin-left: 20rpx;">
<uv-button color="#09b4f1" customStyle="padding:0 80rpx;" @click="onCliskDivert" >转移</uv-button> <uv-button color="#09b4f1" customStyle="padding:0 80rpx;" @click="onCliskDivert">转移</uv-button>
</view> </view>
</view> </view>
</uv-popup> </uv-popup>
@ -39,138 +36,128 @@
</template> </template>
<script setup> <script setup>
import { import {
ref, ref,
unref, unref,
computed, computed,
defineEmits defineEmits
} from 'vue' } from 'vue'
import { onLoad,onShow ,onReady} from '@dcloudio/uni-app' import {
import { onLoad,
getSimpleUserList onShow,
} from '@/api/user' onReady
const lastAdmin = ref(false) } from '@dcloudio/uni-app'
const adminStatus = ref('nomore') import {
const adminkeyword = ref('') getAllUserList
const pageSize = ref(10) } from '@/api/user'
const page = ref(1) const lastAdmin = ref(false)
const userList = ref([]) const adminStatus = ref('nomore')
const adminId = ref(0) const pageSize = ref(10)
const page = ref(1)
const userList = ref([])
const adminId = ref(0)
onShow(()=>{ onShow(() => {
getUserList() getUserList()
})
const showRef = ref()
const doopen = () => {
showRef.value.open()
}
const selectShowClose3 = () => {
unref(showRef).close()
}
defineExpose({ doopen,selectShowClose3 })
const emit = defineEmits(['doTrans'])
const onCliskDivert = () => {
if(adminId.value == 0){
uni.showToast({
title: '请先选择目标员工',
icon: 'none',
duration: 2000
})
return
}
emit('doTrans',adminId.value)
}
const oncompany = (val) => {
adminId.value = val.id
}
const adminSearch = () => {
lastAdmin.value = false
getUserList()
}
const getUserList = async(isNextPage,pages) => {
await getSimpleUserList({
pageNo: page.value,
pageSize: pageSize.value,
username:adminkeyword.value,
}).then(res => {
if(res) {
//
if (res.list.length < 10) {
adminStatus.value = 'nomore'
}
//
if(res.list.length == 0) {
lastAdmin.value = true
}
//
if(isNextPage) {
userList.value = userList.value.concat(res.list)
return
}
userList.value = res.list
}
}) })
}
// const showRef = ref()
const adminBottom = () => { const doopen = () => {
// if(this.lastAdmin || this.adminStatus == 'loading') return ; showRef.value.open()
// this.adminStatus = 'loading' }
// setTimeout(() => {
// if(this.lastAdmin) return ;
// this.onSelectpage(true,++this.adminPage)
// if(this.companyList.length >= 10) this.adminStatus = 'loadmore';
// else this.adminStatus = 'loading';
// }, 1200)
}
const selectShowClose3 = () => {
unref(showRef).close()
}
defineExpose({
doopen,
selectShowClose3
})
const emit = defineEmits(['doTrans'])
const onCliskDivert = () => {
if (adminId.value == 0) {
uni.showToast({
title: '请先选择目标员工',
icon: 'none',
duration: 2000
})
return
}
emit('doTrans', adminId.value)
}
const oncompany = (val) => {
adminId.value = val.id
}
const getUserList = () => {
getAllUserList({
roleCodes: 'sale'
}).then(res => {
userList.value = res
})
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.slot-content { .slot-content {
.search { .search {
padding: 30rpx 25rpx; padding: 30rpx 25rpx;
} }
.popup-title {
display: flex; .popup-title {
align-items: center; display: flex;
justify-content: space-between; align-items: center;
position: relative; justify-content: center;
font-size: 35rpx; position: relative;
font-weight: 600; font-size: 35rpx;
text-align: center; font-weight: 600;
height: 50px; text-align: center;
padding-right: 25rpx; height: 50px;
}
.list { .close {
padding-bottom: 45rpx; position: absolute;
.item { right: 20rpx;
padding: 0 25rpx;
justify-content: space-between;
height: 55px;
.title {
flex: 1;
font-size: 28rpx;
font-weight: 600;
}
.check-icon {
text-align: center;
width: 100rpx;
} }
} }
.list {
padding-bottom: 45rpx;
.item {
padding: 0 25rpx;
justify-content: space-between;
height: 80rpx;
.title {
flex: 1;
font-size: 28rpx;
font-weight: 600;
}
.check-icon {
text-align: center;
width: 100rpx;
}
}
}
.bottom_btn {
background-color: #fff;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 140rpx;
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 26rpx;
box-sizing: border-box;
}
} }
.bottom_btn { </style>
text-align: right;
padding: 28rpx 10rpx 28rpx;
}
}
</style>

View File

@ -109,6 +109,9 @@
<uv-button type="success" text="跟进" customStyle="padding:0 50rpx;" @click="onAdd">跟进</uv-button> <uv-button type="success" text="跟进" customStyle="padding:0 50rpx;" @click="onAdd">跟进</uv-button>
</view> </view>
</view> </view>
<ba-tree-picker ref="treePickerRef" :multiple='true' @select-change="userSelectChange" title="选择员工"
:localdata="userTreeList" valueKey="userId" textKey="nickname" childrenKey="items" confirmColor="#09b4f1" />
</view> </view>
</template> </template>
@ -128,17 +131,21 @@
getCustomer, getCustomer,
getCustomerDoOpen, getCustomerDoOpen,
getRecordPage, getRecordPage,
delCustomer delCustomer,
getUserTreeList
} from '@/api/customer' } from '@/api/customer'
import { import {
getBusiness, getBusiness,
getBusinessProductListByBusinessId, getBusinessProductListByBusinessId,
delBusiness delBusiness,
transferBusiness
} from '@/api/business' } from '@/api/business'
import { import {
formatDateTime, formatDateTime,
prePage prePage
} from '@/utils/util' } from '@/utils/util'
import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue"
const title = ref('商机详情') const title = ref('商机详情')
const businessId = ref(0) const businessId = ref(0)
const business = ref({ const business = ref({
@ -160,13 +167,16 @@
icon: 'edit-pen', icon: 'edit-pen',
show: true, show: true,
}, },
{
text: '转移商机',
icon: 'reload',
show: true,
},
{ {
text: '删除商机', text: '删除商机',
icon: 'trash', icon: 'trash',
show: true, show: true,
} }
]) ])
const recordList = ref([]) const recordList = ref([])
const productList = ref([]) const productList = ref([])
@ -199,12 +209,32 @@
}) })
onLoad((e) => { onLoad((e) => {
console.log('e:', e)
businessId.value = e.id businessId.value = e.id
console.log('businessId.value:', businessId.value)
getData() getData()
getUserList()
}) })
//
const userTreeList = ref([])
const getUserList = () => {
getUserTreeList().then(res => {
userTreeList.value = res
})
}
const treePickerRef = ref()
const userSelectChange = async (userIds) => {
let data = await transferBusiness({
businessIds: [businessId.value],
ownerAdminIds: userIds
})
moreShowClose()
uni.showToast({
title: '操作成功',
icon: 'success',
duration: 2000
})
}
onShow(() => { onShow(() => {
getData() getData()
switch (current.value) { switch (current.value) {
@ -266,6 +296,10 @@
url: '/pages/components/pages/business/add?id=' + business.value.id + '&type=edit' url: '/pages/components/pages/business/add?id=' + business.value.id + '&type=edit'
}); });
break; break;
case "转移商机":
moreShowClose()
treePickerRef.value._show()
break;
case "删除商机": case "删除商机":
unref(moreShowRef).close() unref(moreShowRef).close()
uni.showModal({ uni.showModal({

View File

@ -84,7 +84,7 @@
const oldScrollTop = ref(0) const oldScrollTop = ref(0)
const scrollTop = ref(-1) const scrollTop = ref(-1)
const dataList = ref([]) const dataList = ref([])
const relation = ref(true) const relation = ref('my')
const list = ref( const list = ref(
[{ [{
name: '我的回款', name: '我的回款',

View File

@ -287,7 +287,7 @@
}, },
{ {
text: '转移客户', text: '转移客户',
icon: 'share', icon: 'reload',
show: true, show: true,
}, },
{ {
@ -404,7 +404,6 @@
}) })
const purchaseTotalFormat = computed(() => { const purchaseTotalFormat = computed(() => {
console.log('')
if (customer.value.purchaseTotal) { if (customer.value.purchaseTotal) {
let num; let num;
if (customer.value.purchaseTotal > 9999) { if (customer.value.purchaseTotal > 9999) {