494 lines
11 KiB
Vue
494 lines
11 KiB
Vue
<template>
|
|
<uv-navbar leftIcon="" :safeAreaInsetTop="true" :fixed="false" bgColor="#09b4f1">
|
|
<template v-slot:center>
|
|
<view class="slot-wrap">
|
|
<uv-search placeholder="请输入搜索客户名称" v-model="keyword" bgColor="#ffffff" :showAction="false"
|
|
:customStyle="customStyle" @focus="onSearch"></uv-search>
|
|
</view>
|
|
</template>
|
|
</uv-navbar>
|
|
|
|
<view class="container">
|
|
<view class="top" style="background-color: #09b4f1;">
|
|
<view class="statusBar" :is-back="false" style="height: 30rpx;"></view>
|
|
</view>
|
|
<!-- 待办 -->
|
|
<view class="notice">
|
|
<uv-grid :col="4" :border="false">
|
|
<uv-grid-item v-for="(item,index) in toolIcons" :key="index" @click="gopage(item.url)">
|
|
<uv-icon :name="item.icon" :size="30"></uv-icon>
|
|
<text class="p-1 font-size-sm">{{item.name}}</text>
|
|
</uv-grid-item>
|
|
</uv-grid>
|
|
</view>
|
|
<!-- 工具项 -->
|
|
<view class="region mt-3">
|
|
<view class="title flex">
|
|
<text>常用功能</text>
|
|
</view>
|
|
<uv-grid :col="4" :border="false" @click="onGrid">
|
|
<uv-grid-item v-for="(item, index) in toolIcons2" :key="index" :customStyle="customStyle2"
|
|
@click="item.name == '客户' ? gopage2(item.url) : gopage(item.url)">
|
|
<uv-icon :name="item.icon" :size="30"></uv-icon>
|
|
<text class="p-1 font-size-sm">{{ item.name }}</text>
|
|
</uv-grid-item>
|
|
</uv-grid>
|
|
</view>
|
|
|
|
<view class="region mt-3" style="margin-top: 20rpx;">
|
|
<view class="title flex">
|
|
<text>数据简报</text>
|
|
</view>
|
|
<uv-grid :col="3" :border="false" @click="onGrid">
|
|
<uv-grid-item v-for="(item, index) in toolIcons3" :key="index" :customStyle="customStyle2">
|
|
<text class="p-1 font-size-sm">{{ item.name }}</text>
|
|
<text class="p-1 font-size-sm">{{ item.count }}</text>
|
|
</uv-grid-item>
|
|
</uv-grid>
|
|
</view>
|
|
<view class="region mt-3" style="margin-top: 20rpx;">
|
|
<view class="title flex">
|
|
<text>业绩目标</text>
|
|
<view class="flex align-center">
|
|
<uv-switch v-model="isContract" size="18" inactiveColor="#5ac725" @change="changeChart"></uv-switch>
|
|
<view class="ml-1">
|
|
<uv-text size="14" text="合同" color="#3c9cff" v-if="isContract"></uv-text>
|
|
<uv-text size="14" text="回款" type="success" v-else></uv-text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<uv-row>
|
|
<uv-col span="8">
|
|
<qiun-data-charts type="gauge" :opts="opts" :chartData="chartData" />
|
|
</uv-col>
|
|
<uv-col span="4">
|
|
<view class="mb-4">
|
|
<view class="text-color-assist font-size-medium mb-2">目标金额</view>
|
|
<view>¥{{isContract ? chartCountData.contractMoney : chartCountData.receivablesMoney}}</view>
|
|
</view>
|
|
<view>
|
|
<view class="text-color-assist font-size-medium mb-2">完成金额</view>
|
|
<view>¥{{isContract ? chartCountData.contractSuccessMoney : chartCountData.receivablesSuccessMoney}}</view>
|
|
</view>
|
|
</uv-col>
|
|
</uv-row>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {
|
|
ref,
|
|
computed
|
|
} from 'vue'
|
|
import {
|
|
onLoad,
|
|
onShow
|
|
} from '@dcloudio/uni-app'
|
|
import {
|
|
useMainStore
|
|
} from '@/store/store'
|
|
import {
|
|
storeToRefs
|
|
} from 'pinia'
|
|
import {
|
|
indexCount,
|
|
indexChartCount
|
|
} from '@/api/index'
|
|
const main = useMainStore()
|
|
const statusBarHeight = ref(0)
|
|
const rightSafeArea = ref(0)
|
|
statusBarHeight.value = uni.getSystemInfoSync().statusBarHeight
|
|
|
|
const windowInfo = uni.getWindowInfo()
|
|
const {
|
|
left
|
|
} = uni.getMenuButtonBoundingClientRect()
|
|
rightSafeArea.value = windowInfo.windowWidth - left + 'px'
|
|
const customStyle = computed(() => {
|
|
return {
|
|
//width:'100%'
|
|
// paddingLeft:'20rpx',
|
|
paddingRight: rightSafeArea.value
|
|
}
|
|
})
|
|
const customStyle2 = computed(() => {
|
|
return {
|
|
paddingBottom: '40rpx',
|
|
// paddingRight:'180rpx'
|
|
}
|
|
})
|
|
const toolIcons = ref([{
|
|
name: '公海客户',
|
|
icon: '/static/images/index002.png',
|
|
url: '/pages/components/pages/customer/open',
|
|
},
|
|
{
|
|
name: '线索',
|
|
icon: '/static/images/index003.png',
|
|
url: '/pages/components/pages/clues/index',
|
|
},
|
|
{
|
|
name: '跟进记录',
|
|
icon: '/static/images/index004.png',
|
|
url: '/pages/components/pages/record/index',
|
|
},
|
|
{
|
|
name: '合同',
|
|
icon: '/static/images/index006.png',
|
|
url: '/pages/components/pages/contract/index',
|
|
}
|
|
])
|
|
|
|
const toolIcons2 = ref([{
|
|
name: '客户',
|
|
icon: '/static/images/1.png',
|
|
url: '/pages/customer/index',
|
|
},
|
|
{
|
|
name: '商机',
|
|
icon: '/static/images/2.png',
|
|
url: '/pages/components/pages/business/index',
|
|
},
|
|
{
|
|
name: '线索池',
|
|
icon: '/static/images/3.png',
|
|
url: '/pages/components/pages/clues/open',
|
|
},
|
|
{
|
|
name: '联系人',
|
|
icon: '/static/images/4.png',
|
|
url: '/pages/components/pages/contacts/index',
|
|
},
|
|
{
|
|
name: '回款',
|
|
icon: '/static/images/5.png',
|
|
url: '/pages/components/pages/receivables/index',
|
|
},
|
|
{
|
|
name: '查重',
|
|
icon: '/static/images/6.png',
|
|
url: '/pages/components/pages/customer/repeat',
|
|
},
|
|
{
|
|
name: '发票',
|
|
icon: '/static/images/7.png',
|
|
url: '/pages/components/pages/invoice/index',
|
|
},
|
|
{
|
|
name: '产品',
|
|
icon: '/static/images/8.png',
|
|
url: '/pages/components/pages/product/index',
|
|
},
|
|
])
|
|
|
|
const countData = ref({})
|
|
|
|
const toolIcons3 = ref([{
|
|
name: '新增商机',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '新增线索',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '新增客户',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '新增跟进',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '新增合同',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '合同金额',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '回款金额',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '新增联系人',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '客户成交量',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '客户未成交量',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '商机成交量',
|
|
count: 0,
|
|
},
|
|
{
|
|
name: '商机未成交量',
|
|
count: 0,
|
|
}
|
|
])
|
|
|
|
|
|
const chartData = ref({
|
|
categories: [{
|
|
"value": 0.2,
|
|
"color": "#1890ff"
|
|
}, {
|
|
"value": 0.8,
|
|
"color": "#2fc25b"
|
|
}, {
|
|
"value": 1,
|
|
"color": "#f04864"
|
|
}],
|
|
series: [{
|
|
name: "完成率",
|
|
data: 0.2
|
|
}]
|
|
})
|
|
|
|
const opts = ref({
|
|
color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
|
|
padding: undefined,
|
|
title: {
|
|
name: "完成率",
|
|
fontSize: 25,
|
|
color: "#2fc25b",
|
|
offsetY: 0
|
|
},
|
|
subtitle: {
|
|
name: "200%",
|
|
fontSize: 15,
|
|
color: "#1890ff",
|
|
offsetY: 0
|
|
},
|
|
extra: {
|
|
gauge: {
|
|
type: "progress",
|
|
width: 15,
|
|
labelColor: "#666666",
|
|
startAngle: 0.75,
|
|
endAngle: 0.25,
|
|
startNumber: 0,
|
|
endNumber: 100,
|
|
labelFormat: "",
|
|
splitLine: {
|
|
fixRadius: -10,
|
|
splitNumber: 10,
|
|
width: 15,
|
|
color: "#FFFFFF",
|
|
childNumber: 5,
|
|
childWidth: 12
|
|
},
|
|
pointer: {
|
|
width: 24,
|
|
color: "auto"
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
const isContract = ref(true)
|
|
const chartCountData = ref({})
|
|
|
|
onShow(() => {
|
|
getData()
|
|
getChart()
|
|
})
|
|
|
|
const getChart = async () => {
|
|
let data = await indexChartCount({
|
|
type: 2,
|
|
year: 2024,
|
|
month: 0
|
|
})
|
|
chartCountData.value = data
|
|
let resData = data.contractPer
|
|
chartData.value.series[0].data = resData > 100 ? 1 : resData / 100
|
|
opts.value.subtitle.name = resData + "%"
|
|
}
|
|
|
|
const changeChart = () => {
|
|
let resData = isContract.value ? chartCountData.value.contractPer : chartCountData.value.receivablesPer
|
|
chartData.value.series[0].data = resData > 100 ? 1 : resData / 100
|
|
opts.value.subtitle.name = resData + "%"
|
|
}
|
|
|
|
const getData = async () => {
|
|
let data = await indexCount()
|
|
let brieCount = data.brieCountVO
|
|
toolIcons3.value[0].count = brieCount.count01
|
|
toolIcons3.value[1].count = brieCount.count02
|
|
toolIcons3.value[2].count = brieCount.count03
|
|
toolIcons3.value[3].count = brieCount.count04
|
|
toolIcons3.value[4].count = brieCount.count05
|
|
toolIcons3.value[5].count = brieCount.count06
|
|
toolIcons3.value[6].count = brieCount.count07
|
|
toolIcons3.value[7].count = brieCount.count08
|
|
toolIcons3.value[8].count = brieCount.count09
|
|
toolIcons3.value[9].count = brieCount.count10
|
|
toolIcons3.value[10].count = brieCount.count11
|
|
toolIcons3.value[11].count = brieCount.count12
|
|
main.SET_INDEX_COUNT(data)
|
|
let count = brieCount.count13 + data.contractCheckCount + data.invoiceCheckCount + data.receivablesCheckCount +
|
|
data.followBusinessCount + data.followCluesCount + data.followCustomerCount
|
|
//let str = count > 0 ? count + '' : ''
|
|
if (count > 0) {
|
|
uni.setTabBarBadge({
|
|
index: 2,
|
|
text: count + ''
|
|
})
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
const onSearch = () => {
|
|
gopage2('/pages/customer/index')
|
|
}
|
|
|
|
const gopage = (url) => {
|
|
uni.navigateTo({
|
|
url
|
|
})
|
|
}
|
|
|
|
const gopage2 = (url) => {
|
|
uni.switchTab({
|
|
url
|
|
})
|
|
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
background-color: #F7F7F7 !important;
|
|
padding-bottom: 50px;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.top {
|
|
height: 110rpx;
|
|
/* #ifdef H5 */
|
|
height: 360rpx;
|
|
/* #endif */
|
|
color: #fff;
|
|
}
|
|
|
|
.notice {
|
|
margin: -50px 8px 10px 8px;
|
|
left: 0;
|
|
right: 0;
|
|
background-color: #fff;
|
|
border-radius: 10px;
|
|
padding: 15px 0px;
|
|
|
|
.title {
|
|
padding: 20rpx;
|
|
font-size: 30rpx;
|
|
font-weight: 500;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
|
|
.region {
|
|
background-color: #fff;
|
|
border-radius: 12px;
|
|
margin: 0 10px;
|
|
padding: 8px 5px;
|
|
|
|
.title {
|
|
padding: 28rpx 20rpx;
|
|
font-size: 30rpx;
|
|
font-weight: 500;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.plus {
|
|
background-color: #FFF0ED;
|
|
border-radius: 10rpx;
|
|
padding: 15rpx;
|
|
}
|
|
|
|
.nape {
|
|
width: 48%;
|
|
border-radius: 8px;
|
|
background-color: #FBFBFB;
|
|
padding: 30rpx 20rpx 30rpx 35rpx;
|
|
margin-bottom: 15rpx;
|
|
|
|
&:nth-child(2n+1) {
|
|
margin-right: 4%;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item-padding {
|
|
padding: 45rpx 0;
|
|
}
|
|
|
|
.gray {
|
|
color: #BFBFBF;
|
|
}
|
|
|
|
.slot-wrap {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 30rpx;
|
|
flex: 1
|
|
}
|
|
|
|
.statusBar {
|
|
position: relative;
|
|
}
|
|
|
|
.arrow-icon {
|
|
position: absolute;
|
|
bottom: 16px;
|
|
left: 10px;
|
|
}
|
|
|
|
.charts-box {
|
|
.charts {
|
|
width: 100%;
|
|
height: 300px;
|
|
}
|
|
|
|
.introduce {
|
|
justify-content: space-between;
|
|
padding: 45rpx 12px;
|
|
|
|
.text {
|
|
font-size: 30rpx;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.screen {
|
|
font-size: 30rpx;
|
|
font-weight: 500;
|
|
background-color: #fff;
|
|
padding: 10rpx 32rpx;
|
|
border-radius: 60rpx;
|
|
}
|
|
}
|
|
|
|
.target {
|
|
margin-top: -60rpx;
|
|
justify-content: space-around;
|
|
|
|
.text {
|
|
background-color: #D7D7D7;
|
|
font-size: 25rpx;
|
|
padding: 10rpx 20rpx;
|
|
border-radius: 20rpx;
|
|
}
|
|
}
|
|
}
|
|
</style> |