xiaohaizhao vor 10 Monaten
Ursprung
Commit
e8c8a2fe24

+ 4 - 4
app.json

@@ -192,7 +192,8 @@
                 "index/index",
                 "panel/detail",
                 "customerBlance/detail",
-                "customerBlance/Pipeline"
+                "customerBlance/Pipeline",
+                "salesHourglass/index"
             ]
         }
     ],
@@ -244,8 +245,6 @@
         "van-checkbox": "@vant/weapp/checkbox/index",
         "van-checkbox-group": "@vant/weapp/checkbox-group/index",
         "van-transition": "@vant/weapp/transition/index",
-        "shrink": "/components/shrink/shrink",
-        "timeRange": "/components/timeRange/timeRange",
         "viewDate": "/components/viewDate/index",
         "filtrate": "/components/filtrate/filtrate"
     },
@@ -254,7 +253,8 @@
         "color": "#000000",
         "selectedColor": "#000000",
         "backgroundColor": "#000000",
-        "list": [{
+        "list": [
+            {
                 "pagePath": "pages/tabbar/home/index"
             },
             {

+ 16 - 2
project.private.config.json

@@ -9,12 +9,26 @@
     "condition": {
         "miniprogram": {
             "list": [
+                {
+                    "name": "销售漏斗",
+                    "pathName": "salesPanel/salesHourglass/index",
+                    "query": "",
+                    "scene": null,
+                    "launchMode": "default"
+                },
+                {
+                    "name": "packageA/salesHourglass/index",
+                    "pathName": "packageA/salesHourglass/index",
+                    "query": "",
+                    "launchMode": "default",
+                    "scene": null
+                },
                 {
                     "name": "portrayal/details/project",
                     "pathName": "portrayal/details/project",
                     "query": "id=8286",
-                    "scene": null,
-                    "launchMode": "default"
+                    "launchMode": "default",
+                    "scene": null
                 },
                 {
                     "name": "portrayal/details/client",

+ 446 - 0
salesPanel/salesHourglass/index.js

@@ -0,0 +1,446 @@
+const _Http = getApp().globalData.http,
+    currency = require("../../utils/currency"),
+    CNY = (value, symbol = "", precision = 2) => currency(value, {
+        symbol,
+        precision
+    }).format(),
+    conversion = n => {
+        const integer = (n + '').split(".")[0] + '',
+            length = integer.length,
+            regexp = /(?:\.0*|(\.\d+?)0+)$/
+        if (length <= 4) {
+            const index = 4 - length;
+            return { //元
+                show: CNY(n, "¥", index).replace(regexp, '$1'),
+                value: CNY(n, '¥')
+            }
+        } else if (length <= 8) {
+            return { //万-千万
+
+                show: CNY(currency(n).divide(wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).replace(regexp, '$1') + getApp().globalData.Language.getMapText('万元'),
+                value: CNY(n)
+            }
+        } else {
+            return { //亿
+                show: CNY(currency(n).divide(100000000)).replace(regexp, '$1') + getApp().globalData.Language.getMapText('亿'),
+                value: CNY(n)
+            }
+        }
+    };
+import * as echarts from '../ec-canvas/echarts';
+
+Page({
+    data: {
+        onRenderChart: () => {},
+        onRenderBarChart: () => {},
+        showFiltrate: false,
+        pageMsg: {
+            pageNumber: 1,
+            pageSize: 20,
+            pageTotal: 1,
+            total: 0,
+            signdate_due: ""
+        },
+        "where": {
+            "begindate": "",
+            "enddate": "",
+            "departmentid": ""
+        },
+        username: wx.getStorageSync('userMsg').name,
+        content: {
+            nocache: true,
+            dataid: wx.getStorageSync('userMsg').userid,
+            type: 0,
+            dateType: 0,
+            where: {
+                begdate: "",
+                enddate: "",
+                tradefield: "",
+                isleave: 1,
+                unfinish: 1
+            }
+        },
+        showComingYear: true,
+        filtratelist: [{
+            label: "时间筛选",
+            showName: "name", //显示字段
+            valueKey: "dateType", //返回Key
+            selectKey: "id",
+            value: "id", //选中值
+            index: 0,
+            default: 0,
+            interrupt: true,
+            relevance: "dateRange",
+            list: [{
+                name: "全部",
+                id: 0,
+                queryMonths: -1
+            }, {
+                name: "近一年",
+                id: 1,
+                queryMonths: 12
+            }, {
+                name: "近九个月",
+                id: 2,
+                queryMonths: 9
+            }, {
+                name: "近六个月",
+                id: 3,
+                queryMonths: 6
+            }, {
+                name: "近三个月",
+                id: 4,
+                queryMonths: 3
+            }]
+        }],
+        firstTwelveMonths: {
+            dealaccuracyrate: '0%',
+            totaldealamount: 0,
+            totaldeviationamount: 0,
+            totalsignamount_due: 0
+        },
+        projectPhases: [],
+        stagename: ['全部'],
+        showStagename: [],
+        projectPhasesShow: false
+    },
+    onLoad(options) {
+        _Http.basic({
+            "id": 20221223141802,
+            "content": {
+                "pageNumber": 1,
+                "pageSize": 9999,
+                "where": {
+                    "condition": ""
+                }
+            }
+        }, false).then(res => {
+            console.log("获取领域", res)
+            let filtratelist = this.data.filtratelist
+            if (res.code == '1') {
+                filtratelist.splice(filtratelist.length - 2, 0, {
+                    label: "领域",
+                    index: null,
+                    showName: "tradefield", //显示字段
+                    valueKey: "tradefield", //返回Key
+                    selectKey: "tradefield", //传参 代表选着字段 不传参返回整个选择对象
+                    value: "", //选中值
+                    list: res.data
+                })
+                this.setData({
+                    filtratelist
+                })
+            }
+        })
+        getApp().globalData.Language.getLanguagePackage(this, '销售漏斗');
+        _Http.basic({
+            "id": 20221128143604,
+            "content": {
+                "pageNumber": 1,
+                "pageSize": 99,
+                "where": {
+                    "condition": "",
+                    "allprojecttype": "",
+                    "projecttype": ""
+                }
+            }
+        }).then(res => {
+            if (res.code == 1) {
+                let list = res.data;
+                list.unshift({
+                    stagename: '全部'
+                })
+                this.setData({
+                    projectPhases: [{
+                        label: "项目阶段",
+                        index: [0],
+                        type: "checkbox",
+                        interrupt: true,
+                        showName: "stagename", //显示字段
+                        valueKey: "stagename", //返回Key
+                        selectKey: "stagename", //传参 代表选着字段 不传参返回整个选择对象
+                        value: ['全部'], //选中值
+                        list
+                    }],
+                    showStagename: [getApp().globalData.Language.getMapText('全部')]
+                })
+            }
+        })
+        this.setData({
+            isHY: ['HY', "YOSTEST1"].includes(wx.getStorageSync('userMsg').siteid)
+        })
+        this.setComingYear()
+
+        this.setChartData();
+        let organization = this.selectComponent("#organization")
+        organization.setData({
+            isleave: 1
+        })
+        organization.initDepAndUser()
+    },
+ 
+    interrupt({
+        detail
+    }) {
+        if (detail.data.label == "时间筛选") this.selectComponent("#Yl_Filtrate1").queryMonths(detail.item.queryMonths)
+    },
+    openFiltrate() {
+        this.setData({
+            showFiltrate: true
+        })
+    },
+    handleFilter({
+        detail
+    }) {
+        console.log(detail)
+        if (detail.name == "close") return;
+        if (detail.name == 'reset') {
+            this.selectComponent("#organization").setData({
+                isleave: 1
+            })
+            this.selectComponent("#organization").initDepAndUser()
+            this.setData({
+                'content.dataid': wx.getStorageSync('userMsg').userid,
+                'content.type': 0,
+                'content.where.isleave': 1,
+                'content.where.tradefield': "",
+                'content.where.unfinish': 1,
+            })
+        } else {
+            let active = this.selectComponent("#organization").data.result,
+                isleave = this.selectComponent("#organization").data.isleave;
+            let type = active.userid ? 0 : 1,
+                dataid = type == 0 ? active.userid : active.departmentid
+            console.log(isleave)
+            this.setData({
+                'content.dataid': dataid,
+                'content.type': type,
+                'content.where.tradefield': detail.tradefield,
+                'content.where.isleave': isleave || 1,
+                'content.where.unfinish': detail.unfinish || 0,
+            })
+        }
+        this.data.content.where.begdate = detail.startdate;
+        this.data.content.where.enddate = detail.enddate;
+        if (detail.startdate && detail.enddate) {
+            this.data.content.dateType = 0;
+        } else {
+            this.data.content.dateType = detail.dateType && detail.dateType != 'id' ? dateType : 0
+        }
+        this.setChartData();
+        this.setComingYear();
+    },
+    setChartData() {
+        this.setData({
+            statistics: []
+        })
+        _Http.basic({
+            "id": 20230630151504,
+            "content": this.data.content
+        }).then(res => {
+            console.log("漏斗数据", res)
+            if (res.code != '1') return wx.showToast({
+                title: res.msg,
+                icon: "none"
+            })
+            if (res.data.length) res.data.pop();
+            let full = Math.max(...res.data.map(v => v.wide));
+            let statistics = res.data.map((v, i) => {
+                v.action = getApp().globalData.Language.getMapText(v.stagename)
+                v.zhl = i == 0 ? '' : getApp().globalData.Language.getMapText('转换率') + `:${(v.zhl * 100).toFixed(2)}%`
+                v.percent = v.wide / full;
+                v.totalinvestment = conversion(v.totalinvestment).value
+                v.budgetary = conversion(v.budgetary).value
+                v.signamount_due = conversion(v.signamount_due).value
+                if (i == 0) {
+                    v.totaldealamount = CNY(v.totaldealamount, '¥')
+                    v.totalsignamount_due = CNY(v.totalsignamount_due, '¥')
+                }
+                return v
+            })
+            this.setData({
+                statistics,
+                full
+            });
+        })
+    },
+    setComingYear() {
+        this.setData({
+            showComingYear: false
+        })
+        let pageMsg = this.data.pageMsg;
+        let content = Object.assign(JSON.parse(JSON.stringify(this.data.content)), this.data.pageMsg)
+        pageMsg.signdate_due = '';
+        content.pageNumber = 1;
+        content.stagename = this.data.stagename[0] == '全部' ? [] : this.data.stagename;
+        _Http.basic({
+            "id": 20241028162104,
+            content
+        }).then(res => {
+            console.log("前12个月总数据", res)
+            this.setData({
+                showComingYear: true
+            })
+            if (res.code != '1') return wx.showToast({
+                title: res.msg,
+                icon: "none"
+            })
+            let comingYear = [];
+            if (res.data[0].extradata.array) {
+                const array = res.data[0].extradata.array;
+                comingYear = array.map(v => {
+                    return {
+                        name: getApp().globalData.Language.getMapText('预计签约金额'),
+                        value: (v.signamount_due / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(0) - 0,
+                        date: v.signdate_due
+                    }
+                }).concat(array.map(v => {
+                    return {
+                        name: getApp().globalData.Language.getMapText('预计成交金额'),
+                        value: (v.dealamount_due / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(0) - 0,
+                        date: v.signdate_due
+                    }
+                }))
+            }
+            try {
+                if (res.data[0].extradata) {
+                    let data = res.data[0].extradata
+                    this.setData({
+                        firstTwelveMonths: {
+                            "dealTotalCount": data.dealTotalCount, //成交项目数
+                            "failTotalCount": data.failTotalCount, //失败项目数
+                            "dealRate": (data.dealRate * 100).toFixed(2) + '%', //项目成交率
+                            "positiveCount": data.positiveCount, //预计成交正偏差项目数合计
+                            "positiveOffsetAmount": CNY(((data.positiveOffsetAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //预计成交正偏差金额合计
+                            "negativeCount": data.negativeCount, //预计成交负偏差项目数合计
+                            "negativeOffsetAmount": CNY(((data.negativeOffsetAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //预计成交负偏差金额合计
+                            "offsetCount": data.offsetCount, //预计成交准确项目数
+                            "rightRate": (data.rightRate * 100).toFixed(2) + '%', //预测额成交准确率
+                            "dealAmount": CNY(((data.dealAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //项目成交金额合计
+                            "signAmount": CNY(((data.signAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //预计签约金额合计
+                            "sumdealamount_due": CNY(((data.sumdealamount_due || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), '¥'), //预计项目成交金额合计
+                            "sumsignamount_due": CNY(((data.sumsignamount_due || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), '¥'), //预计预计签约金额合计
+                        },
+                    })
+                }
+            } catch (error) {}
+            res.data = res.data.map(v => {
+                v.progress = v.stage / v.totalstage * 100;
+                v.signamount_due = CNY(v.signamount_due, "¥")
+                v.dealamount = CNY(v.dealamount, "¥")
+                return v
+            })
+            pageMsg.pageNumber = res.pageNumber + 1
+            pageMsg.pageSize = res.pageSize
+            pageMsg.pageTotal = res.pageTotal
+            pageMsg.total = res.total
+            pageMsg.sumsignamount_due = CNY(res.data[0].extradata.sumsignamount_due / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000), "¥")
+            pageMsg.sumdealamount_due = CNY(res.data[0].extradata.sumdealamount_due / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000), "¥")
+            this.setData({
+                comingYear,
+                onRenderBarChart: res.data.length == 0 ? () => {} : () => {
+                    return this.renderBarChart();
+                },
+                pageMsg,
+                list: res.data
+            })
+        })
+    },
+    changeSigndate_due(e) {
+        console.log(e)
+        this.setData({
+            "pageMsg.signdate_due": e[0].origin.date,
+            "pageMsg.sumsignamount_due": CNY(e[0].origin.value / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000), "¥"),
+            "pageMsg.sumdealamount_due": CNY(e[1].origin.value / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000), "¥"),
+        })
+        this.getList(true)
+    },
+    getList(init = false) {
+        if (!this.data.isHY) return;
+        let pageMsg = this.data.pageMsg;
+        if (init) {
+            pageMsg.pageNumber = 1;
+            pageMsg.pageTotal = 1;
+        }
+        if (pageMsg.pageNumber > pageMsg.pageTotal) return;
+        let content = Object.assign(JSON.parse(JSON.stringify(this.data.content)), pageMsg)
+        content.stagename = this.data.stagename[0] == '全部' ? [] : this.data.stagename;
+        _Http.basic({
+            "id": 20241028162104,
+            content
+        }).then(res => {
+            console.log("获取前12月列表", res)
+            this.setData({
+                list: res.data
+            })
+            pageMsg.pageNumber = res.pageNumber + 1
+            pageMsg.pageSize = res.pageSize
+            pageMsg.pageTotal = res.pageTotal
+            pageMsg.total = res.total
+
+            res.data = res.data.map(v => {
+                v.progress = v.stage / v.totalstage * 100;
+                v.signamount_due = CNY(v.signamount_due, "¥")
+                v.dealamount = CNY(v.dealamount, "¥")
+                return v
+            })
+            this.setData({
+                list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data),
+                pageMsg
+            })
+        })
+    },
+    onReachBottom() {
+        this.getList();
+    },
+    openProjectPhases() {
+        this.setData({
+            projectPhasesShow: true
+        })
+    },
+    phasesInterrupt({
+        detail
+    }) {
+        if (detail.item.stagename == '全部') {
+            detail.list[0].index = [0];
+            detail.list[0].value = ['全部'];
+        } else {
+            if (detail.list[0].index.length) {
+                detail.list[0].index = detail.list[0].index.filter(v => v);
+                detail.list[0].value = detail.list[0].index.filter(v => v != '全部');
+            } else {
+                detail.list[0].index = [0];
+                detail.list[0].value = ['全部'];
+            }
+        }
+        this.setData({
+            projectPhases: detail.list
+        })
+    },
+    phasesHandleFilter({
+        detail
+    }) {
+        if (detail.name != "confirm") return;
+        let stagename = ['全部']
+        try {
+            if (detail.stagename[0] != 0) {
+                stagename = detail.stagename.map(v => this.data.projectPhases[0].list[v].stagename)
+            }
+        } catch (error) {
+
+        }
+        this.setData({
+            stagename,
+            showStagename: stagename.map(v => getApp().globalData.Language.getMapText(v))
+        })
+        this.setComingYear()
+    },
+    renderChart() {
+        console.log("renderChart")
+
+    },
+    renderBarChart() {
+        console.log("renderBarChart")
+
+    }
+})

+ 6 - 0
salesPanel/salesHourglass/index.json

@@ -0,0 +1,6 @@
+{
+    "usingComponents": {
+        "ec-canvas": "../ec-canvas/ec-canvas"
+    },
+    "navigationBarTitleText": "销售漏斗"
+}

+ 276 - 0
salesPanel/salesHourglass/index.scss

@@ -0,0 +1,276 @@
+.head {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 30rpx;
+	box-sizing: border-box;
+	height: 90rpx;
+	background: #FFFFFF;
+
+	.label {
+		font-size: 28rpx;
+		font-weight: bold;
+		color: #333333;
+	}
+
+	.filter {
+		font-size: 28rpx;
+		font-family: PingFang SC-Regular, PingFang SC;
+		color: #666666;
+		text-align: right;
+		line-height: 60rpx;
+	}
+}
+
+.analysis {
+	background-color: #fff;
+	padding: 20rpx 30rpx;
+	padding-bottom: 0;
+	width: 100vw;
+	box-sizing: border-box;
+	margin-top: 20rpx;
+
+	.title {
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 600;
+		font-size: 30rpx;
+		color: #333333;
+		line-height: 42rpx;
+	}
+
+	.title1 {
+		font-family: PingFang SC, PingFang SC;
+		font-size: 28rpx;
+		color: #171A1D;
+		line-height: 40rpx;
+	}
+
+	.box {
+		display: flex;
+		width: 690rpx;
+		background: #F6F6F6;
+		padding: 16rpx 20rpx;
+		border-radius: 8rpx 8rpx 8rpx 8rpx;
+		box-sizing: border-box;
+		margin-top: 20rpx;
+		flex-direction: column;
+
+		.row {
+			display: flex;
+			justify-content: space-between;
+			line-height: 34rpx;
+			margin-bottom: 16rpx;
+
+			.label {
+				line-height: 34rpx;
+				font-size: 24rpx;
+				color: #666666;
+			}
+
+			.value {
+				line-height: 34rpx;
+				font-size: 24rpx;
+				color: #009966;
+
+				.count {
+					margin-right: 40rpx;
+				}
+			}
+		}
+
+		.row:last-child {
+			margin-bottom: 0;
+		}
+	}
+}
+
+.item {
+	background-color: #fff;
+	padding: 20rpx 30rpx;
+	box-sizing: border-box;
+	border-bottom: 1px solid #ddd;
+
+	.label {
+		height: 42rpx;
+		line-height: 42rpx;
+		font-family: PingFang SC-Medium, PingFang SC;
+		font-weight: 600;
+		color: #333333;
+	}
+
+	.row {
+		display: flex;
+		justify-content: space-between;
+		font-size: 24rpx;
+		line-height: 34rpx;
+		font-family: PingFang SC-Regular, PingFang SC;
+		color: #666666;
+		margin-top: 10rpx;
+
+		view {
+			width: 330rpx;
+		}
+	}
+}
+
+.row-amount {
+	line-height: 40rpx;
+	padding: 20rpx 30rpx;
+	font-size: 26rpx;
+}
+
+.hy-project {
+	padding: 20rpx 30rpx;
+
+	.top-title {
+		line-height: 42rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-size: 30rpx;
+		color: #333333;
+		font-weight: 700;
+	}
+
+	.amount-row {
+		display: flex;
+		justify-content: space-between;
+		line-height: 34rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-size: 24rpx;
+		color: #666666;
+		padding: 20rpx 0;
+	}
+
+	.project-item {
+		display: flex;
+		align-items: center;
+		background-color: #fff;
+		width: 690rpx;
+		border-radius: 8rpx;
+		margin: 0 auto 20rpx;
+
+		.chart {
+			margin: 0 30rpx;
+			width: 100rpx;
+			flex-shrink: 0;
+
+			.circle {
+				width: 100rpx;
+				height: 100rpx;
+				position: relative;
+				border-radius: 50%;
+				box-shadow: inset 0 0 0 8rpx var(--assist);
+
+				.ab {
+					position: absolute;
+					left: 0;
+					right: 0;
+					top: 0;
+					bottom: 0;
+					margin: auto;
+				}
+
+				&_left {
+					border: 8rpx solid #ccc;
+					border-radius: 50%;
+					clip: rect(0, 50rpx, 100rpx, 0);
+				}
+
+				&_right {
+					border: 8rpx solid #ccc;
+					border-radius: 50%;
+					clip: rect(0, 100rpx, 100rpx, 50rpx);
+				}
+
+				&_text {
+					height: 100%;
+					display: flex;
+					flex-direction: column;
+					justify-content: center;
+					align-items: center;
+					font-size: 16rpx;
+					font-family: PingFang SC-Regular, PingFang SC;
+					color: #666666;
+
+					.value {
+						margin-top: -6rpx;
+					}
+
+					.name {
+						margin-top: 6rpx;
+					}
+				}
+			}
+		}
+
+		.main {
+			position: relative;
+			box-sizing: border-box;
+			padding: 20rpx 0;
+			overflow: hidden;
+
+			.label {
+				display: flex;
+				height: 42rpx;
+
+				.title {
+					flex: 1;
+					width: 0;
+					font-size: 30rpx;
+					font-family: PingFang SC-Regular, PingFang SC;
+					color: #333333;
+					margin-right: 20rpx;
+				}
+
+				.state {
+					flex-shrink: 0;
+					width: 132rpx;
+					height: 40rpx;
+					line-height: 40rpx;
+					border-radius: 20rpx 0px 0px 20rpx;
+					font-size: 24rpx;
+					font-family: PingFang SC-Regular, PingFang SC;
+					color: #FFFFFF;
+					text-align: center;
+				}
+
+			}
+
+			.tag-box {
+				display: flex;
+				align-items: center;
+				width: 100%;
+
+				.datatag,
+				.systemtag {
+					flex-shrink: 0;
+					margin-top: 10rpx;
+					background: #3874f6;
+					color: #ffffff;
+					margin-right: 10rpx;
+					display: flex;
+					align-items: center;
+					height: 40rpx;
+					font-size: 20rpx;
+					padding: 0 10rpx;
+					border-radius: 20rpx;
+					font-family: PingFang SC-Regular, PingFang SC;
+				}
+
+				.datatag {
+					background: #FA8C16;
+				}
+			}
+
+			.replenish {
+				display: flex;
+				min-height: 34rpx;
+				font-size: 24rpx;
+				font-family: PingFang SC-Regular, PingFang SC;
+				color: #333333;
+				margin-top: 10rpx;
+				word-break: break-all;
+				white-space: pre-wrap;
+			}
+		}
+	}
+}

+ 200 - 0
salesPanel/salesHourglass/index.wxml

@@ -0,0 +1,200 @@
+<view class="head" hover-class="navigator-hover" bindtap="openFiltrate">
+	<view class="filter">
+		<text class="iconfont icon-shaixuan" />
+		{{language[username]||username}}_{{language[content.where.unfinish==1?'在职':content.where.unfinish?'离职':'全部']||content.where.unfinish==1?'在职':content.where.unfinish?'离职':'全部'}}
+	</view>
+
+	<view class="filter">
+		<text class="iconfont icon-lingyu" />
+		{{language[content.where.tradefield||'领域']||content.where.tradefield||'领域'}}
+	</view>
+</view>
+
+<Yl_ListBox id='ListBox' pullDown='{{false}}'>
+	漏斗图1位置
+	<view class="analysis">
+		<view class="title">
+			{{language['项目预计成交统计']||'项目预计成交统计'}}
+		</view>
+		<view class="title1" style="margin-top: 20rpx;">
+			{{language['前12个月成交项目指标']||'前12个月成交项目指标'}}
+		</view>
+		<view class="box">
+			<view class="row">
+				<view class="label">{{language['成交项目数']||'成交项目数'}}:</view>
+				<view class="value">{{firstTwelveMonths.dealTotalCount}}</view>
+			</view>
+			<view class="row">
+				<view class="label">{{language['失败项目数']||'失败项目数'}}:</view>
+				<view class="value">{{firstTwelveMonths.failTotalCount}}</view>
+			</view>
+			<view class="row">
+				<view class="label">{{language['项目成交率']||'项目成交率'}}:</view>
+				<view class="value">{{firstTwelveMonths.dealRate}}</view>
+			</view>
+		</view>
+
+		<view class="box">
+			<view class="row">
+				<view class="label">{{language['预计成交正偏差']||'预计成交正偏差'}}:</view>
+				<view class="value">
+					<text class="count">{{firstTwelveMonths.positiveCount}}{{language['个']||'个'}}</text>
+					{{firstTwelveMonths.positiveOffsetAmount}}{{language['万']||'万'}}
+				</view>
+			</view>
+			<view class="row">
+				<view class="label">{{language['预计成交负偏差']||'预计成交负偏差'}}:</view>
+				<view class="value">
+					<text class="count">{{firstTwelveMonths.negativeCount}}{{language['个']||'个'}}</text>
+					{{firstTwelveMonths.negativeOffsetAmount}}{{language['万']||'万'}}
+				</view>
+			</view>
+			<view class="row">
+				<view class="label">{{language['预计成交准确率']||'预计成交准确率'}}:</view>
+				<view class="value">
+					{{firstTwelveMonths.rightRate}}
+				</view>
+			</view>
+		</view>
+
+		<view class="box">
+			<view class="row">
+				<view class="label">{{language['项目成交金额合计']||'项目成交金额合计'}}:</view>
+				<view class="value">{{firstTwelveMonths.dealAmount}}{{language['万']||'万'}}</view>
+			</view>
+			<view class="row">
+				<view class="label">{{language['预计签约金额合计']||'预计签约金额合计'}}:</view>
+				<view class="value">{{firstTwelveMonths.signAmount}}{{language['万']||'万'}}</view>
+			</view>
+		</view>
+		<view style="height: 20rpx;" />
+	</view>
+	<view class="analysis">
+		<block wx:if="{{comingYear.length}}">
+			<view class="title1">
+				{{language['未来12月预计签约金额/预计成交金额分析']||'未来12月预计签约金额/预计成交金额分析'}}({{language['单位']||'单位'}}:{{language['万']||'万'}})
+			</view>
+
+			<navigator url="#" wx:if="{{projectPhases.length}}" class="title1" style="margin-top: 20rpx;display: flex;" bind:tap="openProjectPhases">
+				{{language['项目阶段']||'项目阶段'}}:
+				<view style="color: #3874F6;">{{showStagename}}
+					<van-icon name="arrow-down" />
+				</view>
+			</navigator>
+		</block>
+		<view style="height: 20rpx;"></view>
+	</view>
+	图2位置
+	<!-- <view wx:if="{{comingYear.length && showComingYear}}" class="bar-chart-box">
+	<f2 onRender="{{onRenderBarChart}}" />
+</view> -->
+	<view class="hy-project" wx:if="{{isHY}}">
+		<view class="top-title">{{ pageMsg.signdate_due ?pageMsg.signdate_due+(language['月']||'月'):'全部'}}_{{language['预计成交项目']||'预计成交项目'}}({{list[0].sa_projectid?pageMsg.total:0}})</view>
+		<view class="amount-row">
+			<view>{{language['预计签约金额']||'预计签约金额'}}:{{pageMsg.sumsignamount_due }}{{language['万元']||'万元'}}</view>
+			<view>{{language['预计成交金额']||'预计成交金额'}}:{{pageMsg.sumdealamount_due }}{{language['万元']||'万元'}}</view>
+		</view>
+		<block wx:if="{{list[0].sa_projectid}}">
+			<navigator url="/packageA/project/detail?id={{item.sa_projectid}}" class="project-item" wx:for="{{list}}" wx:key="sa_projectid">
+				<view class="chart">
+					<view class="circle">
+						<view class="circle_left ab" style="{{render.leftRate(item.progress)}}" />
+						<view class="circle_right ab" style="{{render.rightRate(item.progress)}}" />
+						<view class="circle_text">
+							<text class="value">{{item.stage+'/'+item.totalstage}}</text>
+							<text class="name">{{language['进展']||'阶段进度'}}</text>
+						</view>
+					</view>
+				</view>
+				<view class="main">
+					<view class="label">
+						<view class="title line-1">{{item.projectname}}</view>
+						<view class="state" style="background-color: {{item.status == '跟进中' ? '#3874f6' : sColors[item.status]}};">{{language[item.status]||item.status}}</view>
+					</view>
+					<view class="tag-box">
+						<view class="systemtag" wx:for="{{item.tag_sys}}" style="background-color: {{sColors[item]}};" wx:key="item">{{language[item]||item}}</view>
+						<view class="datatag" wx:for="{{item.tag}}" style="background-color: {{sColors[item]}};" wx:key="item">{{language[item]||item}}</view>
+					</view>
+					<view class="replenish">
+						<text style="color: #999;">{{language['项目编号']||'项目编号'}}:</text>
+						<text>{{item.projectnum}}</text>
+					</view>
+					<view class="replenish">
+						<text style="color: #666; flex-shrink: 0;">{{language['项目地址']||'项目地址'}}:</text>
+						<text style="width: 480rpx;">{{item.province?item.province+item.city+item.county+item.address:'--'}}</text>
+					</view>
+					<view class="replenish">
+						<text style="color: #999;">{{language['预计签约金额']||'预计签约金额'}}:</text>
+						<text style="color: #3874F6;">{{item.signamount_due}}</text>
+					</view>
+					<view class="replenish">
+						<text style="color: #999;">{{language['项目成交金额']||'项目成交金额'}}:</text>
+						<text style="color: #FF3B30;">{{item.dealamount}}</text>
+					</view>
+					<view class="replenish">
+						<text style="color: #999;">{{language['项目类型']||'项目类型'}}:</text>
+						<text>{{language[item.projecttype_remarks]||item.projecttype_remarks}}</text>
+					</view>
+					<view class="replenish">
+						<text style="color: #999;">{{language['负责人']||'负责人'}}:</text>
+						<text>{{item.reportby||'--'}}</text>
+					</view>
+				</view>
+			</navigator>
+		</block>
+
+		<wxs module="render">
+			module.exports = {
+				rightRate: function (rate) {
+					if (rate - 0 < 50) {
+						return 'transform: rotate(' + 3.6 * (rate - 0) + 'deg);';
+					} else {
+						return 'transform: rotate(0);border-color: var(--assist);';
+					}
+				},
+				leftRate: function (rate) {
+					if (rate - 0 >= 50) {
+						return 'transform: rotate(' + 3.6 * (rate - 50) + 'deg);';
+					}
+				}
+			}
+		</wxs>
+	</view>
+	<block wx:else>
+		<view class="row-amount">
+			<view>
+				{{language['项目总计']||'项目总计'}}:{{statistics.length ? statistics[0].sequence1 : 0}}
+			</view>
+			<view>
+				{{language['预计签约金额']||'预计签约金额'}}:{{statistics.length ? statistics[0].totalsignamount_due : 0}}{{language['万元']||'万元'}}
+			</view>
+			<view>
+				{{language['项目成交金额']||'项目成交金额'}}:{{statistics.length ? statistics[0].totaldealamount : 0}}{{language['万元']||'万元'}}
+			</view>
+		</view>
+		<view class="item" wx:for="{{statistics}}" wx:key="stagename">
+			<view class="label">{{language[item.stagename]||item.stagename}}</view>
+			<view class="row">
+				<view>
+					{{language['项目总数']||'项目总数'}}:{{item.sequence1}}
+				</view>
+				<view>
+					{{language['当前项目数']||'当前项目数'}}:{{item.projectqty}}
+				</view>
+			</view>
+			<view class="row">
+				<view>
+					{{language['预计签约金额']||'预计签约金额'}}:{{item.signamount_due}}{{language['万元']||'万元'}}
+				</view>
+				<view>
+					{{language['项目成交金额']||'项目成交金额'}}:{{item.dealamount}}{{language['万元']||'万元'}}
+				</view>
+			</view>
+		</view>
+	</block>
+</Yl_ListBox>
+
+<Yl_Filtrate1 id="Yl_Filtrate1" show='{{showFiltrate}}' dateRange list="{{filtratelist}}" dateRangeName="{{language['创建日期']||'创建日期'}}" bindhandle="handleFilter" bindinterrupt='interrupt'>
+	<organization slot='head' defaultIsleave='1' dimissionF id='organization' />
+</Yl_Filtrate1>
+<Yl_Filtrate1 show='{{projectPhasesShow}}' isReset='{{false}}' list="{{projectPhases}}" bindinterrupt='phasesInterrupt' bindhandle="phasesHandleFilter" />

+ 1 - 1
utils/work/apps.js

@@ -28,7 +28,7 @@ function getapps() {
 		icon: "work-zuoyekanban"
 	}, {
 		name: "销售漏斗",
-		path: "/packageA/salesHourglass/index",
+		path: "/salesPanel/salesHourglass/index",
 		icon: "work-xiaoshouloudou"
 	}, {
 		name: "360°画像",