Przeglądaj źródła

营销费用明细

xiaohaizhao 11 miesięcy temu
rodzic
commit
fb8101e72a

+ 2 - 1
app.json

@@ -199,7 +199,8 @@
                 "AnalysisOfUninvoicedShipments/detail",
                 "dataOverview/OverviewAndDetails/Client",
                 "dataOverview/OverviewAndDetails/project",
-                "dataOverview/OverviewAndDetails/Costs"
+                "dataOverview/OverviewAndDetails/Costs",
+                "dataOverview/Costs/SPMEDetail"
             ]
         }
     ],

+ 79 - 0
salesPanel/dataOverview/Costs/SPMEDetail.js

@@ -0,0 +1,79 @@
+const _Http = getApp().globalData.http,
+    currency = require("../../../utils/currency"),
+    CNY = (value, symbol = "¥", precision = 2) => currency(value, {
+        symbol,
+        precision
+    }).format();
+Page({
+    data: {
+        searchShow: false,
+        searchValue: "",
+        typeShow: false,
+        tradefieldShow: false
+    },
+    onLoad(options) {
+        getApp().globalData.Language.getLanguagePackage(this, '营销费用明细')
+        this.setData({
+            content: Object.assign(options, {
+                "where": {
+                    "condition": "",
+                    "begdate": "",
+                    "enddate": ""
+                },
+                "pageNumber": 1,
+                "pageSize": 10
+            })
+        })
+        this.getList()
+    },
+    changeSearchShow() {
+        this.setData({
+            searchShow: !this.data.searchShow
+        })
+        this.selectComponent('#ListBox').automaticSetHei();
+    },
+    getList(init = false) {
+        _Http.init(this.data.content, init).then(content => {
+            _Http.basic({
+                "id": 2024062611202602,
+                content
+            }).then(res => {
+                console.log("明细列表", res)
+                this.selectComponent('#ListBox').automaticSetHei();
+                this.selectComponent('#ListBox').RefreshToComplete();
+                if (res.code != '1') return wx.showToast({
+                    title: res.data,
+                    icon: "none"
+                })
+                res.data = res.data.map(v => {
+                    v.amount = CNY(v.amount)
+                    return v
+                })
+                this.setData({
+                    list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data),
+                    "content.pageNumber": res.pageNumber + 1,
+                    "content.pageSize": res.pageSize,
+                    "content.pageTotal": res.pageTotal,
+                    "total": res.total,
+                })
+                this.onCancel()
+            })
+        })
+    },
+    onSearch() {
+        this.data.content.where.condition = this.data.searchValue;
+        this.getList(true);
+    },
+    onChange(event) {
+        this.setData({
+            searchValue: event.detail
+        })
+    },
+    onClear() {
+        this.setData({
+            searchValue: "",
+            "content.where.condition": ""
+        })
+        this.getList(true);
+    }
+})

+ 4 - 0
salesPanel/dataOverview/Costs/SPMEDetail.json

@@ -0,0 +1,4 @@
+{
+    "usingComponents": {},
+    "navigationBarTitleText": "营销费用明细"
+}

+ 57 - 0
salesPanel/dataOverview/Costs/SPMEDetail.scss

@@ -0,0 +1,57 @@
+.tab-box {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	height: 90rpx;
+	background-color: #fff;
+	padding-left: 20rpx;
+
+	.left1 {
+		line-height: 40rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 700;
+		font-size: 28rpx;
+		color: #333333;
+
+		.amount1 {
+			color: #F56C6C;
+		}
+	}
+
+	.right {
+		display: flex;
+		align-items: center;
+		height: 90rpx;
+		flex-shrink: 0;
+
+		.filtrate-box {
+			display: flex;
+			height: 100%;
+			align-items: center;
+			padding: 0 20rpx;
+
+			font-family: PingFang SC, PingFang SC;
+			font-size: 28rpx;
+			color: #666666;
+
+			.iconfont {
+				margin-right: 6rpx;
+				color: #999999;
+			}
+
+		}
+
+		.search-box {
+			display: flex;
+			height: 100%;
+			align-items: center;
+			padding: 0 30rpx;
+
+			.iconfont {
+				font-size: 40rpx;
+			}
+		}
+	}
+}
+
+@import "../OverviewAndDetails/Costs.scss";

+ 42 - 0
salesPanel/dataOverview/Costs/SPMEDetail.wxml

@@ -0,0 +1,42 @@
+<view class='tab-box'>
+	<view class="left1">
+		{{language['营销费用']||'营销费用'}}:<text class="amount1">{{content.amount}}</text>
+	</view>
+	<view class="right">
+		<view class="search-box" hover-class="navigator-hover" bindtap="changeSearchShow">
+			<text class="iconfont icon-a-sousuolansousuo" />
+		</view>
+	</view>
+</view>
+<view wx-if="{{searchShow}}">
+	<van-transition show="{{ searchShow }}" name='fade' duration='300'>
+		<view>
+			<van-search focus="{{focus}}" value="{{searchValue}}" placeholder="{{language['请输入关键字']||'请输入关键字'}}" bind:search="onSearch" bind:clear="onClear" bind:change="onChange" />
+		</view>
+	</van-transition>
+</view>
+<view style="height: 20rpx;" />
+<Yl_ListBox id='ListBox' bind:getlist='getList'>
+	<view class="global-card item" wx:for="{{list}}" wx:key="sa_salesfeesid">
+		<view class="title">
+			<text class="line-1">{{item.billno || " --"}}</text>
+		</view>
+		<view class="systemapp">{{language[item.systemapp]||item.systemapp}}</view>
+		<view class="row">
+			<view class="col">{{language['负责人']||'负责人'}}:{{language[item.salesname]||item.salesname ||' --'}}</view>
+			<view class="col">{{language['部门']||'部门'}}:{{language[item.depname]||item.depname ||' --'}}</view>
+		</view>
+		<view class="row">{{language['客户名称']||'客户名称'}}:{{item.enterprisename ||' --'}}</view>
+		<view class="row">{{language['项目名称']||'项目名称'}}:{{item.projectname ||' --'}}</view>
+		<view class="row">{{language['联系人']||'联系人'}}:{{item.names ||' --'}}</view>
+		<view class="row">{{language['费用类型']||'费用类型'}}:<text class="amount">{{item.amount}}</text></view>
+		<view class="row">{{language['营销费用(元)']||'营销费用(元)'}}:{{language[item.feestypefullname]||item.feestypefullname ||' --'}}</view>
+		<view class="row">{{language['跟进类型']||'跟进类型'}}:{{language[item.type]||item.type ||' --'}}</view>
+		<view class="row">{{language['跟进内容']||'跟进内容'}}:{{item.content ||' --'}}</view>
+		<view class="row">{{language['跟进时间']||'跟进时间'}}:{{item.createdate ||' --'}}</view>
+	</view>
+	<My_empty wx:if="{{list.length==0}}" />
+</Yl_ListBox>
+
+<van-action-sheet show="{{  typeShow }}" actions="{{ types }}" bind:select='onSelect' bind:cancel='onCancel' bind:click-overlay='onCancel' cancel-text="{{language['取消']||'取消'}}" />
+<van-action-sheet show="{{  tradefieldShow }}" actions="{{ tradefields }}" bind:select='onSelect1' bind:cancel='onCancel' bind:click-overlay='onCancel' cancel-text="{{language['取消']||'取消'}}" />

+ 199 - 0
salesPanel/dataOverview/Costs/SPmarketingExpenses.js

@@ -0,0 +1,199 @@
+const _Http = getApp().globalData.http,
+    currency = require("../../../utils/currency"),
+    CNY = (value, symbol = "¥", precision = 2) => currency(value, {
+        symbol,
+        precision
+    }).format();
+
+Component({
+    options: {
+        addGlobalClass: true
+    },
+    lifetimes: {
+        attached: function () {
+            getApp().globalData.Language.getLanguagePackage(this)
+        }
+    },
+    data: {
+        dateTypes: ["本年", "本季", "本月"],
+        "content": {
+            pageNumber: 1,
+            pageTotal: 1,
+            dataid: wx.getStorageSync('userMsg').userid,
+            username: wx.getStorageSync('userMsg').name,
+            dateType: "本年",
+            type: 0,
+            where: {
+                begdate: "",
+                enddate: "",
+                isleave: "1",
+            }
+        },
+    },
+    methods: {
+        async getList(init = false) {
+            if (init.detail != undefined) init = init.detail;
+            let content = this.data.content
+            const {
+                dataid,
+                type,
+                username,
+                isleave
+            } = getCurrentPages()[getCurrentPages().length - 1].data;
+            if (content.dataid != dataid || content.type != type || isleave != isleave) init = true
+            content.dataid = dataid;
+            content.type = type;
+            content.username = username;
+            content.where.isleave = isleave;
+            if (init) {
+                content.pageNumber = 1;
+                content.pageTotal = 1;
+                content.where.customerstype = "";
+            }
+            if (content.pageNumber > content.pageTotal) return;
+            _Http.basic({
+                "id": 2024062610330602,
+                content
+            }).then(res => {
+                this.selectComponent('#ListBox').RefreshToComplete();
+                console.log('业务员排行列表', res)
+                if (res.code != '1') return wx.showToast({
+                    title: res.data,
+                    icon: "none"
+                })
+                res.data = res.data.map(v => {
+                    const colors = ['#F56C6C', '#EF8E51', '#FFC148', '#999999'];
+                    v.color = colors[v.rowindex - 1] || colors[3];
+                    v.amount = CNY(v.amount)
+                    return v
+                })
+                this.setData({
+                    list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data),
+                    "content.pageNumber": res.pageNumber + 1,
+                    "content.pageSize": res.pageSize,
+                })
+                this.selectComponent("#TimeRange").onCancel()
+            })
+        },
+        initChart(data, total) {
+            const getMapText = getApp().globalData.Language.getMapText;
+            let countDown = null,
+                that = this;
+
+            function changeUnwriteoffamounttype(index) {
+                if (countDown) return;
+                countDown = setTimeout(() => {
+                    clearTimeout(countDown)
+                    countDown = null;
+                    if (data[index].key != that.data.content.where.customerstype) that.setData({
+                        "content.where.customerstype": data[index].key || "",
+                        "content.pageNumber": 1,
+                    });
+                    that.getList()
+
+                }, 200)
+            };
+
+
+            let option = {
+                tooltip: {
+                    trigger: 'item',
+                    confine: true, // Ensure tooltip stays within chart boundaries
+                    formatter: function (params) {
+                        changeUnwriteoffamounttype(params.dataIndex)
+                        return `${getMapText(params.name)}: ${params.value} (${params.percent}%)`;
+                    },
+                },
+                legend: {
+                    type: 'scroll', // Enable scrollable legend
+                    bottom: '5%', // Moved legend to the bottom
+                    left: 'center',
+                    pageIconColor: '#333', // Customize page icon color
+                    pageTextStyle: {
+                        color: '#333' // Customize page text style
+                    }
+                },
+                series: [{
+                    type: 'pie',
+                    radius: ['40%', '70%'],
+                    center: ['50%', '42%'], // Adjusted to align with the new legend position
+                    endAngle: 360,
+                    data: data.map(v => {
+                        return {
+                            name: getMapText(v.key),
+                            value: (v.ratio).toFixed(2),
+                        }
+                    }),
+                    label: {
+                        normal: {
+                            show: true,
+                            position: 'outside',
+                            formatter: '{b}: {c} ({d}%)',
+                            textStyle: {
+                                fontSize: 12,
+                                color: '#333'
+                            }
+                        },
+                        emphasis: {
+                            show: true,
+                            textStyle: {
+                                fontSize: 14,
+                                fontWeight: 'bold'
+                            }
+                        },
+                        rich: {
+                            total: {
+                                fontSize: 20,
+                                fontWeight: 'bold',
+                                color: '#333'
+                            },
+                            desc: {
+                                fontSize: 12,
+                                color: '#999'
+                            }
+                        }
+                    },
+                    labelLine: {
+                        normal: {
+                            show: true,
+                            length: 10,
+                            length2: 10
+                        }
+                    }
+                }]
+            };
+            option.graphic = {
+                type: 'text',
+                left: 'center',
+                top: '35%', // Adjusted to align with the new series position
+                style: {
+                    text: `${getMapText('客户总数')}\n\n${total}`,
+                    textAlign: 'center',
+                    fill: '#333',
+                    fontSize: 16,
+                    fontWeight: 'bold'
+                }
+            };
+            this.chartComponent = this.selectComponent('#mychart');
+            this.chartComponent.init((canvas, width, height, dpr) => {
+                const chart = echarts.init(canvas, null, {
+                    width,
+                    height,
+                    devicePixelRatio: dpr
+                });
+                chart.setOption(option);
+                return chart;
+            });
+        },
+        changeDate({
+            detail
+        }) {
+            this.setData({
+                "content.dateType": detail.dateType,
+                "content.where.begdate": detail.begdate || "",
+                "content.where.enddate": detail.enddate || ""
+            })
+            this.getList(true)
+        }
+    }
+})

+ 4 - 0
salesPanel/dataOverview/Costs/SPmarketingExpenses.json

@@ -0,0 +1,4 @@
+{
+    "component": true,
+    "usingComponents": {}
+}

+ 48 - 0
salesPanel/dataOverview/Costs/SPmarketingExpenses.scss

@@ -0,0 +1,48 @@
+.item {
+	display: flex;
+	align-items: center;
+	height: 160rpx;
+	background: #FFFFFF;
+	border-radius: 20rpx;
+	border: 2rpx solid #F0F0F0;
+	padding: 0 10rpx 0 0 !important;
+
+	.rowindex {
+		min-width: 48rpx;
+		height: 48rpx;
+		background: #F56C6C;
+		display: inline-block;
+		border-radius: 24rpx;
+		text-align: center;
+		line-height: 48rpx;
+		margin-right: 20rpx;
+		font-family: Microsoft YaHei, Microsoft YaHei;
+		font-size: 28rpx;
+		color: #FFFFFF;
+		padding: 0 6rpx;
+		box-sizing: border-box;
+		margin: 0 40rpx;
+	}
+
+	.name {
+		line-height: 38rpx;
+		font-family: Microsoft YaHei, Microsoft YaHei;
+		font-size: 28rpx;
+		color: #333333;
+	}
+
+	.depname {
+		line-height: 32rpx;
+		font-family: Microsoft YaHei, Microsoft YaHei;
+		font-size: 24rpx;
+		color: #999999;
+		margin-top: 8rpx;
+	}
+
+	.amount {
+		line-height: 38rpx;
+		font-family: Microsoft YaHei, Microsoft YaHei;
+		font-size: 28rpx;
+		color: #F56C6C;
+	}
+}

+ 16 - 0
salesPanel/dataOverview/Costs/SPmarketingExpenses.wxml

@@ -0,0 +1,16 @@
+<timeRange id='TimeRange' dateTypes='{{dateTypes}}' dateType='{{content.dateType}}' bind:onChange='changeDate' />
+<Yl_ListBox id='ListBox' bind:getlist='getList'>
+	<view style="height: 20rpx;"></view>
+	<My_empty wx:if='{{list[0].isEmpty}}' />
+	<block wx:else>
+		<navigator class="global-card item" wx:for="{{list}}" wx:key="hrid" url='/salesPanel/dataOverview/Costs/SPMEDetail?hrid={{item.hrid}}&amount={{item.amount}}&dateType={{content.dateType}}'>
+			<view class="rowindex" style="background-color: {{item.color}};">{{item.rowindex}}</view>
+			<view style="width: 300rpx;">
+				<view class="name line-1">{{ language[item.name] ||item.name }}</view>
+				<view class="depname line-1">{{ language[item.depname] || item.depname }}</view>
+			</view>
+			<view class="amount">{{item.amount}}</view>
+		</navigator>
+		<My_empty wx:if="{{list.length==0}}" />
+	</block>
+</Yl_ListBox>

+ 16 - 1
salesPanel/dataOverview/OverviewAndDetails/Costs.scss

@@ -1,6 +1,21 @@
 @import "./Clue.scss";
 
-.amount{
+.amount {
 	color: #FF3B30;
 	font-size: 24rpx;
+}
+
+.systemapp {
+	position: absolute;
+	top: 20rpx;
+	right: 20rpx;
+
+	line-height: 40rpx;
+	font-family: PingFang SC, PingFang SC;
+	font-size: 24rpx;
+	color: #FFFFFF;
+
+	background: #3874F6;
+	border-radius: 4rpx;
+	padding: 0 10rpx;
 }

+ 1 - 0
salesPanel/dataOverview/OverviewAndDetails/Costs.wxml

@@ -18,6 +18,7 @@
 		<view class="title">
 			<text class="line-1">{{item.billno || " --"}}</text>
 		</view>
+		<view class="systemapp">{{language[item.systemapp]||item.systemapp}}</view>
 		<view class="row">
 			<view class="col">{{language['负责人']||'负责人'}}:{{language[item.salesname]||item.salesname ||' --'}}</view>
 			<view class="col">{{language['部门']||'部门'}}:{{language[item.depname]||item.depname ||' --'}}</view>

+ 3 - 0
salesPanel/dataOverview/list/costs.js

@@ -19,6 +19,9 @@ Component({
         tabsList: [{
             label: "数据概况",
             model: "#DataOverview"
+        }, {
+            label: "业务员营销费用TOP10",
+            model: "#SPmarketingExpenses"
         }],
         init: false
     },

+ 2 - 1
salesPanel/dataOverview/list/costs.json

@@ -1,6 +1,7 @@
 {
     "component": true,
     "usingComponents": {
-        "DataOverview": "../Costs/dataOverview"
+        "DataOverview": "../Costs/dataOverview",
+        "SPmarketingExpenses": "../Costs/SPmarketingExpenses"
     }
 }

+ 1 - 0
salesPanel/dataOverview/list/costs.wxml

@@ -1,3 +1,4 @@
 <Yl_FunTabs id='Yl_FunTabs' safety='{{false}}' list='{{tabsList}}' mode='buts' active='{{tabsActive}}' bind:onChenge="tabsChange">
     <DataOverview slot='数据概况' id='DataOverview' />
+    <SPmarketingExpenses slot='业务员营销费用TOP10' id='SPmarketingExpenses' />
 </Yl_FunTabs>