Browse Source

项目成交预测

xiaohaizhao 2 years ago
parent
commit
517f18374d
31 changed files with 1544 additions and 1 deletions
  1. 5 1
      app.json
  2. 89 0
      packageA/finishforecast/admin.js
  3. 6 0
      packageA/finishforecast/admin.json
  4. 4 0
      packageA/finishforecast/admin.scss
  5. 7 0
      packageA/finishforecast/admin.wxml
  6. 230 0
      packageA/finishforecast/detail.js
  7. 8 0
      packageA/finishforecast/detail.json
  8. 20 0
      packageA/finishforecast/detail.scss
  9. 18 0
      packageA/finishforecast/detail.wxml
  10. 89 0
      packageA/finishforecast/index.js
  11. 6 0
      packageA/finishforecast/index.json
  12. 4 0
      packageA/finishforecast/index.scss
  13. 7 0
      packageA/finishforecast/index.wxml
  14. 11 0
      packageA/finishforecast/modules/getColor.wxs
  15. 11 0
      packageA/finishforecast/modules/list/index.js
  16. 4 0
      packageA/finishforecast/modules/list/index.json
  17. 38 0
      packageA/finishforecast/modules/list/index.scss
  18. 25 0
      packageA/finishforecast/modules/list/index.wxml
  19. 241 0
      packageA/finishforecast/modules/project/index.js
  20. 6 0
      packageA/finishforecast/modules/project/index.json
  21. 61 0
      packageA/finishforecast/modules/project/index.scss
  22. 32 0
      packageA/finishforecast/modules/project/index.wxml
  23. 117 0
      packageA/finishforecast/modules/project/list/index.js
  24. 4 0
      packageA/finishforecast/modules/project/list/index.json
  25. 132 0
      packageA/finishforecast/modules/project/list/index.scss
  26. 50 0
      packageA/finishforecast/modules/project/list/index.wxml
  27. 150 0
      packageA/select/project/select2.js
  28. 4 0
      packageA/select/project/select2.json
  29. 102 0
      packageA/select/project/select2.scss
  30. 55 0
      packageA/select/project/select2.wxml
  31. 8 0
      pages/tabbar/home/index.js

+ 5 - 1
app.json

@@ -133,7 +133,11 @@
                 "report/detail",
                 "achievement/index",
                 "project/webview",
-                "salesHourglass/index"
+                "salesHourglass/index",
+                "finishforecast/index",
+                "finishforecast/detail",
+                "finishforecast/admin",
+                "select/project/select2"
             ]
         }
     ],

+ 89 - 0
packageA/finishforecast/admin.js

@@ -0,0 +1,89 @@
+let _Http = getApp().globalData.http,
+    currency = require("../../utils/currency"),
+    CNY = value => currency(value, {
+        symbol: "¥",
+        precision: 2
+    }).format();
+
+Page({
+    data: {
+        content: {
+            baseonproject: 1, //1项目预测,0出货开票预测
+            pageNumber: 1,
+            pageTotal: 1,
+            pagesize: 20,
+            sort: [],
+            where: {
+                condition: ""
+            }
+        },
+        navList: [{
+            label: "排序",
+            icon: "icon-jiangxu1",
+            color: "",
+            width: "",
+            id: "sort"
+        }, {
+            label: "筛选",
+            icon: "icon-shaixuan",
+            color: "",
+            width: "",
+            id: "2"
+        }]
+    },
+    onLoad(options) {
+        this.getList();
+    },
+    /* 获取列表 */
+    getList(init = false) {
+        if (init.detail != undefined) init = init.detail;
+        let content = this.data.content;
+        if (init) content.pageNumber = 1;
+        if (content.pageNumber > content.pageTotal) return;
+
+        _Http.basic({
+            "id": 20230706092304,
+            content
+        }).then(res => {
+            console.log("项目成交预测", res)
+            this.selectComponent('#ListBox').RefreshToComplete();
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            })
+            res.data = res.data.map(v => {
+                v.showAmount = CNY(v.projectamount)
+                return v
+            })
+            this.setData({
+                'content.pageNumber': res.pageNumber + 1,
+                'content.pageTotal': res.pageTotal,
+                'content.total': res.total,
+                'content.sort': res.sort,
+                list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data)
+            });
+            this.setListHeight();
+        })
+    },
+    /* 处理搜索 */
+    onSearch({
+        detail
+    }) {
+        this.setData({
+            "content.where.condition": detail
+        });
+        this.getList(true);
+    },
+    onReady() {
+        this.setListHeight();
+    },
+    setListHeight() {
+        this.selectComponent("#ListBox").setHeight(".head", this);
+    },
+    /* 顶部条件导航回调 */
+    navClick({
+        detail
+    }) {
+        console.log(detail)
+    },
+})

+ 6 - 0
packageA/finishforecast/admin.json

@@ -0,0 +1,6 @@
+{
+    "usingComponents": {
+        "List": "./modules/list"
+    },
+    "navigationBarTitleText": "项目成交预测管理"
+}

+ 4 - 0
packageA/finishforecast/admin.scss

@@ -0,0 +1,4 @@
+page {
+    height: 100vh;
+    overflow: hidden;
+}

+ 7 - 0
packageA/finishforecast/admin.wxml

@@ -0,0 +1,7 @@
+<Yl_nav search list='{{navList}}' sort='{{content.sort}}' bind:onClick='navClick' bindonSearch="onSearch" />
+<view class="head" />
+<Yl_ListBox id='ListBox' bind:getlist='getList'>
+	<view style="height: 20rpx;" />
+	<List list='{{list}}' admin />
+	<view style="height: 80rpx;" />
+</Yl_ListBox>

+ 230 - 0
packageA/finishforecast/detail.js

@@ -0,0 +1,230 @@
+let _Http = getApp().globalData.http,
+    currency = require("../../utils/currency"),
+    CNY = value => currency(value, {
+        symbol: "¥",
+        precision: 2
+    }).format();
+
+Page({
+    data: {
+        admin: false,
+        tabsActive: 0,
+        tabsList: [{
+            label: "项目产品清单",
+            icon: "icon-tabchanpin",
+            model: "#Project"
+        }, {
+            label: "附件",
+            icon: "icon-tabfujian1",
+            model: "#Files"
+        }, {
+            label: "操作记录",
+            icon: "icon-tabcaozuojilu1",
+            model: "#Record"
+        }],
+        tabbarList: [{
+            icon: "icon-guanlian-bianji",
+            label: "添加项目"
+        }, {
+            icon: "icon-guanlian-fuzhi",
+            label: "移除项目"
+        }],
+    },
+    onLoad(options) {
+        this.setData({
+            admin: options.admin ? options.admin == 'true' : false,
+            sa_salesforecastbillid: options.id
+        })
+        this.getDetail();
+        this.getTags();
+        this.partialRenewal();
+    },
+    getDetail() {
+        _Http.basic({
+            "id": 20230705144704,
+            "content": {
+                "sa_salesforecastbillid": this.data.sa_salesforecastbillid
+            }
+        }).then(res => {
+            console.log("预测详情", res)
+            res.data.projectamount = CNY(res.data.projectamount)
+            this.setData({
+                detail: res.data
+            })
+        })
+    },
+    tabbarOnClick({
+        detail
+    }) {
+        switch (detail.label) {
+            case "添加项目":
+                this.toAddProject();
+                break;
+            case "移除项目":
+                wx.navigateTo({
+                    url: `/packageA/select/project/select2?params=${JSON.stringify({
+                        "id": "20230705144904",
+                        "content": {
+                            nocache: true,
+                            sa_salesforecastbillid:this.data.sa_salesforecastbillid,
+                            pageSize: 20,
+                            "where":{
+                                "condition":""
+                            }
+                        }
+                        })}&radio=true`,
+                })
+                getApp().globalData.handleSelect = this.deteleProject.bind(this);
+                break;
+        }
+    },
+    //tabs 切换
+    tabsChange({
+        detail
+    }) {
+        this.setData({
+            tabsActive: detail
+        });
+        this.partialRenewal();
+    },
+    toAddProject() {
+        wx.navigateTo({
+            url: `/packageA/select/project/select2?params=${JSON.stringify({
+                    "id": 20230705145604,
+                    "content": {
+                        nocache:true,
+                        sa_salesforecastbillid:this.data.sa_salesforecastbillid,
+                        "where":{
+                            "condition":""
+                        }
+                    }
+            })}`,
+        });
+        getApp().globalData.handleSelect = this.addProject.bind(this);
+    },
+    /* 添加项目 */
+    addProject({
+        list
+    }) {
+        let that = this;
+        wx.showModal({
+            title: '提示',
+            content: `是否确认添加${list.length}个项目`,
+            complete: ({
+                confirm
+            }) => {
+                if (confirm) _Http.basic({
+                    id: 20230705145104,
+                    content: {
+                        sa_salesforecastbillid: that.data.sa_salesforecastbillid,
+                        "ownertable": "sa_project",
+                        salesforecastproject: list.map(v => {
+                            return {
+                                ownerid: v.sa_projectid,
+                                ownertable: "sa_project",
+                                discountrate: v.discountrate,
+                                sa_salesforecastprojectid: 0
+                            }
+                        })
+                    }
+                }).then(res => {
+                    console.log("添加项目", res)
+                    wx.showToast({
+                        title: res.msg == '成功' ? '添加成功' : res.msg,
+                        icon: "none"
+                    });
+                    if (res.msg == '成功') {
+                        that.setData({
+                            tabsActive: that.data.tabsList.findIndex(v => v.label == '项目产品清单')
+                        });
+                        setTimeout(() => {
+                            wx.navigateBack();
+                            setTimeout(() => {
+                                that.selectComponent('#Project').getList(that.data.sa_salesforecastbillid, false);
+                            }, 300)
+                        }, 300)
+                    }
+                })
+            }
+        })
+    },
+    /* 删除项目 */
+    deteleProject({
+        item
+    }) {
+        let that = this;
+        wx.showModal({
+            title: '提示',
+            content: `是否确认移除“${item.projectname}”`,
+            complete: ({
+                confirm
+            }) => {
+                if (confirm) _Http.basic({
+                    "id": 20230705145304,
+                    "content": {
+                        "sa_salesforecastbillid": that.data.sa_salesforecastbillid,
+                        "sa_salesforecastprojectids": [item.sa_salesforecastprojectid]
+                    }
+                }).then(res => {
+                    console.log("移除项目", res)
+                    if (res.msg != '成功') return wx.showToast({
+                        title: res.msg,
+                        icon: "none"
+                    });
+                    that.selectComponent("#Project").getList(that.data.sa_salesforecastbillid);
+                    setTimeout(() => {
+                        wx.showToast({
+                            title: `已移除“${item.projectname}”`,
+                            icon: "none"
+                        })
+                        let page = getCurrentPages().find(v => v.__route__ == 'packageA/select/project/select2');
+                        if (page) page.deteleItem(item.sa_projectid);
+                        that.getDetail();
+                    }, 500)
+                })
+            }
+        })
+    },
+    //更新标签
+    getTags() {
+        this.selectComponent("#Tags").getTags();
+    },
+    //局部数据更新 tabs
+    partialRenewal(init = false) {
+        let model = this.data.tabsList[this.data.tabsActive].model;
+        if (model) {
+            let Component = this.selectComponent(model),
+                {
+                    total,
+                    pageNumber,
+                    pageTotal
+                } = Component.data.content,
+                id = this.data.sa_salesforecastbillid;
+            if (total == null || init) {
+                Component.getList(id, init);
+            } else if (pageNumber <= pageTotal) {
+                Component.getList(id, false);
+            }
+        }
+    },
+    onReachBottom() {
+        this.partialRenewal();
+    },
+    onUnload() {
+        const page = getCurrentPages().find(v => v.__route__ == 'packageA/finishforecast/index' || v.__route__ == 'packageA/finishforecast/admin');
+        if (!page) return;
+        let content = JSON.parse(JSON.stringify(page.data.content));
+        content.pageSize = (content.pageNumber - 1) * content.pageSize;
+        content.pageNumber = 1;
+        _Http.basic({
+            id: '20230706092304',
+            content
+        }).then(res => {
+            console.log("更新预测", res);
+            if (res.msg == '成功') page.setData({
+                list: res.data,
+                "content.total": res.total
+            })
+        })
+    }
+})

+ 8 - 0
packageA/finishforecast/detail.json

@@ -0,0 +1,8 @@
+{
+    "usingComponents": {
+        "Project": "./modules/project/index",
+        "Record": "/packageA/public/record/index",
+        "Files": "/packageA/public/files/index"
+    },
+    "navigationBarTitleText": "预测填报"
+}

+ 20 - 0
packageA/finishforecast/detail.scss

@@ -0,0 +1,20 @@
+.header {
+    box-sizing: border-box;
+    padding: 20rpx 30rpx;
+    background-color: #fff;
+
+    .title {
+        line-height: 40rpx;
+        font-size: 28rpx;
+        color: #000000;
+        font-weight: 600;
+        margin-bottom: 10rpx;
+    }
+
+    .row {
+        line-height: 34rpx;
+        font-size: 24rpx;
+        color: #333333;
+        margin-top: 8rpx;
+    }
+}

+ 18 - 0
packageA/finishforecast/detail.wxml

@@ -0,0 +1,18 @@
+<view class="header">
+    <view class="title">{{detail.title}}</view>
+    <Yl-tags id="Tags" add ownertable='sa_salesforecastbill' ownerid='{{sa_salesforecastbillid}}' />
+    <view class="row">单号:{{detail.billnum}}</view>
+    <view class="row">预测人:{{detail.name}}</view>
+    <view class="row">预测时间:{{detail.periodstart}} 至 {{detail.periodend}}</view>
+    <view class="row">预测金额:<text style="color: #F60909;">{{detail.projectamount}}</text></view>
+    <view class="row">状态:<text style="color:{{backColor.getColor(detail.status)}};">{{detail.status}}</text></view>
+</view>
+<view style="height: 20rpx;" />
+<Yl_FunTabs list='{{tabsList}}' active='{{tabsActive}}' bind:onChenge="tabsChange">
+    <Project slot='项目产品清单' id='Project' disabled="{{detail.status=='进行中' || detail.status=='未开始'}}" catchtoAdd="toAddProject" />
+    <Record slot='操作记录' id="Record" ownertable='sa_salesforecastbill' ownerid='{{sa_salesforecastbillid}}' />
+    <Files slot='附件' id="Files" ownertable='sa_salesforecastbill' ownerid='{{sa_salesforecastbillid}}' />
+    <view style="height: 140rpx;" />
+</Yl_FunTabs>
+<Yl_Tabbar wx:if="{{detail.status=='进行中'|| detail.status=='未开始'}}" list='{{tabbarList}}' bind:callback="tabbarOnClick" />
+<wxs src="./modules/getColor.wxs" module="backColor" />

+ 89 - 0
packageA/finishforecast/index.js

@@ -0,0 +1,89 @@
+let _Http = getApp().globalData.http,
+    currency = require("../../utils/currency"),
+    CNY = value => currency(value, {
+        symbol: "¥",
+        precision: 2
+    }).format();
+
+Page({
+    data: {
+        content: {
+            baseonproject: 1, //1项目预测,0出货开票预测
+            pageNumber: 1,
+            pageTotal: 1,
+            pagesize: 20,
+            sort: [],
+            where: {
+                condition: ""
+            }
+        },
+        navList: [{
+            label: "排序",
+            icon: "icon-jiangxu1",
+            color: "",
+            width: "",
+            id: "sort"
+        }, {
+            label: "筛选",
+            icon: "icon-shaixuan",
+            color: "",
+            width: "",
+            id: "2"
+        }]
+    },
+    onLoad(options) {
+        this.getList();
+    },
+    /* 获取列表 */
+    getList(init = false) {
+        if (init.detail != undefined) init = init.detail;
+        let content = this.data.content;
+        if (init) content.pageNumber = 1;
+        if (content.pageNumber > content.pageTotal) return;
+
+        _Http.basic({
+            "id": 20230706092304,
+            content
+        }).then(res => {
+            console.log("项目成交预测", res)
+            this.selectComponent('#ListBox').RefreshToComplete();
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            })
+            res.data = res.data.map(v => {
+                v.showAmount = CNY(v.projectamount)
+                return v
+            })
+            this.setData({
+                'content.pageNumber': res.pageNumber + 1,
+                'content.pageTotal': res.pageTotal,
+                'content.total': res.total,
+                'content.sort': res.sort,
+                list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data)
+            });
+            this.setListHeight();
+        })
+    },
+    /* 处理搜索 */
+    onSearch({
+        detail
+    }) {
+        this.setData({
+            "content.where.condition": detail
+        });
+        this.getList(true);
+    },
+    onReady() {
+        this.setListHeight();
+    },
+    setListHeight() {
+        this.selectComponent("#ListBox").setHeight(".head", this);
+    },
+    /* 顶部条件导航回调 */
+    navClick({
+        detail
+    }) {
+        console.log(detail)
+    },
+})

+ 6 - 0
packageA/finishforecast/index.json

@@ -0,0 +1,6 @@
+{
+    "usingComponents": {
+        "List": "./modules/list"
+    },
+    "navigationBarTitleText": "项目成交预测"
+}

+ 4 - 0
packageA/finishforecast/index.scss

@@ -0,0 +1,4 @@
+page {
+    height: 100vh;
+    overflow: hidden;
+}

+ 7 - 0
packageA/finishforecast/index.wxml

@@ -0,0 +1,7 @@
+<Yl_nav search list='{{navList}}' sort='{{content.sort}}' bind:onClick='navClick' bindonSearch="onSearch" />
+<view class="head" />
+<Yl_ListBox id='ListBox' bind:getlist='getList'>
+    <view style="height: 20rpx;" />
+    <List list='{{list}}' />
+    <view style="height: 80rpx;" />
+</Yl_ListBox>

+ 11 - 0
packageA/finishforecast/modules/getColor.wxs

@@ -0,0 +1,11 @@
+module.exports.getColor = function (status) {
+    var color = null;
+    if (status == '未开始') {
+        color = 'var(--warning)';
+    } else if (status == '进行中') {
+        color = '#5AB73F';
+    } else if (status == '已截止') {
+        color = '#BBBBBB';
+    };
+    return color
+}

+ 11 - 0
packageA/finishforecast/modules/list/index.js

@@ -0,0 +1,11 @@
+Component({
+	properties: {
+		list: {
+			type: Array
+		},
+		admin: {
+			type: Boolean,
+			value: false
+		}
+	},
+})

+ 4 - 0
packageA/finishforecast/modules/list/index.json

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

+ 38 - 0
packageA/finishforecast/modules/list/index.scss

@@ -0,0 +1,38 @@
+.box {
+    width: 100vw;
+    background-color: #fff;
+    padding: 20rpx 30rpx;
+    box-sizing: border-box;
+    border-bottom: 1px solid #ddd;
+    .title {
+        position: relative;
+        height: 44rpx;
+        line-height: 44rpx;
+        font-size: 28rpx;
+        font-family: PingFang SC-Bold, PingFang SC;
+        font-weight: bold;
+        color: #333333;
+
+        .status {
+            position: absolute;
+            right: -30rpx;
+            top: 4rpx;
+            font-weight: normal;
+            width: 132rpx;
+            height: 40rpx;
+            line-height: 40rpx;
+            text-align: center;
+            background: #5AB73F;
+            border-radius: 20rpx 0rpx 0rpx 20rpx;
+            font-size: 24rpx;
+            color: #FFFFFF;
+        }
+    }
+
+    .row {
+        line-height: 34rpx;
+        font-size: 24rpx;
+        color: #333333;
+        margin-top: 8rpx;
+    }
+}

+ 25 - 0
packageA/finishforecast/modules/list/index.wxml

@@ -0,0 +1,25 @@
+<navigator url="/packageA/finishforecast/detail?id={{item.sa_salesforecastbillid}}&admin={{admin}}" class="box" wx:for="{{list}}" wx:key="sa_salesforecastbillid">
+    <view class="title">
+        {{item.title}}
+        <view class="status" style="background-color:{{backColor.getColor(item.status)}};">
+            {{item.status}}
+        </view>
+    </view>
+    <block wx:if="{{!admin}}">
+        <view class="row">
+            单号:{{item.billnum}}
+        </view>
+        <view class="row">
+            预测人:{{item.name}}
+        </view>
+    </block>
+    <view class="row">
+        预测时间:{{item.periodstart}} 至 {{item.periodend}}
+    </view>
+    <view class="row">
+        预测金额:<text style="color: #FF3B30;" wx:if="{{item.projectamount}}">{{item.showAmount}}</text><text wx:else> --</text>
+    </view>
+</navigator>
+
+<My_empty wx:if="{{!list.length}}" />
+<wxs src="../getColor.wxs" module="backColor" />

+ 241 - 0
packageA/finishforecast/modules/project/index.js

@@ -0,0 +1,241 @@
+const _Http = getApp().globalData.http,
+    currency = require("../../../../utils/currency"),
+    file = require("../../../../utils/matchingFeilType"),
+    CNY = value => currency(value, {
+        symbol: "¥",
+        precision: 2
+    }).format();
+Component({
+    properties: {
+        disabled: {
+            type: Boolean
+        },
+        toAdd: {
+            type: Function
+        }
+    },
+    options: {
+        addGlobalClass: true
+    },
+    data: {
+        sa_salesforecastbillid: 0,
+        list: [],
+        sa_projectid: 0,
+        "content": {
+            "nocache": true,
+            pageSize: 9999,
+            "total": null,
+            "where": {
+                "condition": ""
+            }
+        },
+        project: null
+    },
+    methods: {
+        getList(id, init, update = false) {
+            let content = this.data.content;
+            content.sa_salesforecastbillid = id;
+            content.where.condition = update ? this.data.project.projectnum : "";
+            _Http.basic({
+                "id": 20230705144904,
+                content
+            }).then(res => {
+                console.log("预测项目列表", res)
+                if (res.msg != '成功') return wx.showToast({
+                    title: res.data,
+                    icon: "none"
+                })
+                res.data = res.data.map(v => {
+                    v.zk = currency(v.discountrate).multiply(100).value;
+                    v.shouAmount = CNY(v.sumprojectamount)
+                    return v
+                });
+                if (update) {
+                    const index = this.data.list.findIndex(v => v.projectnum == this.data.project.projectnum);
+                    if (index != -1) {
+                        this.setData({
+                            [`list[${index}]`]: res.data[0],
+                            project: res.data[0]
+                        });
+                        this.getProduct();
+                    }
+                } else {
+                    content.total = res.total;
+                    this.setData({
+                        list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data),
+                        content
+                    });
+                    if (res.data.length) {
+                        this.setData({
+                            sa_projectid: res.data[0].sa_projectid,
+                            project: res.data[0]
+                        });
+                        this.getProduct();
+                    } else {
+                        this.setData({
+                            sa_projectid: 0,
+                            project: null
+                        })
+                    }
+                }
+                this.setData({
+                    sa_salesforecastbillid: id
+                })
+            })
+        },
+        onChange({
+            detail
+        }) {
+            this.setData({
+                sa_projectid: detail.name,
+                project: this.data.list[detail.index]
+            });
+            this.getProduct();
+        },
+        addProject() {
+            this.triggerEvent("toAdd")
+        },
+        /* 折扣失焦 */
+        onBlur(e) {
+            let zk = e.detail.value,
+                project = JSON.parse(JSON.stringify(this.data.project));
+            if (zk > 100) {
+                zk = 100
+            } else if (zk < 0.01) {
+                zk = project.zk;
+                wx.showToast({
+                    title: '折扣过小',
+                    icon: "none"
+                })
+            }
+            if (zk == project.zk) return;
+            project.zk = currency(zk).multiply(1).value;
+            project.discountrate = currency(zk, {
+                precision: 4
+            }).divide(100).value;
+            _Http.basic({
+                id: 20230705145104,
+                content: {
+                    sa_salesforecastbillid: this.data.sa_salesforecastbillid,
+                    "ownertable": "sa_project",
+                    salesforecastproject: [{
+                        ownerid: project.sa_projectid,
+                        ownertable: "sa_project",
+                        discountrate: project.discountrate,
+                        sa_salesforecastprojectid: project.sa_salesforecastprojectid
+                    }]
+                }
+            }).then(res => {
+                console.log("修改项目折扣", res)
+                wx.showToast({
+                    title: res.msg == '成功' ? '折扣修改成功' : res.msg,
+                    icon: "none"
+                })
+                if (res.msg == '成功') this.updateAmount();
+            })
+        },
+        getProduct() {
+            _Http.basic({
+                "id": 20230705145004,
+                "content": {
+                    nocache: true,
+                    "sa_salesforecastprojectid": this.data.project.sa_salesforecastprojectid,
+                    pageSize: 9999,
+                    "where": {
+                        "condition": ""
+                    }
+                }
+            }).then(res => {
+                if (res.msg != '成功') return wx.showToast({
+                    title: res.data,
+                    icon: "none"
+                })
+                console.log("产品", res)
+                this.setData({
+                    productList: res.data.map(value => {
+                        if (value.attinfos.length != 0) {
+                            value.attinfos = file.fileList(value.attinfos)
+                            let image = value.attinfos.find(v => v.fileType == "image");
+                            value.cover = image ? image.cover : "";
+                        }
+                        value.className = value.itemclass.length == 0 ? "暂无类目" : value.itemclass.map(v => v.itemclassname);
+                        value.brandName = value.brand.length == 0 ? "暂无品牌" : value.brand.map(v => v.brandname);
+                        value.showMP = CNY(value.marketprice)
+                        value.showOrderamount = CNY(value.orderamount)
+                        return value
+                    })
+                })
+            })
+        },
+        toAddProduct() {
+            let project = this.data.project;
+            wx.navigateTo({
+                url: `/packageA/select/product/select?params=${JSON.stringify({
+                "accesstoken": "1ede5d2594d778a5e652b5a267c90308",
+                "id": 20230705145704,
+                "content": {
+                    "pageNumber": 1,
+                    "pageSize": 20,
+                    "sa_salesforecastbillid":project.sa_salesforecastbillid,
+                    "sa_salesforecastprojectid":project.sa_salesforecastprojectid,
+                    "sa_projectid":project.sa_projectid,
+                    "where": {
+                        "condition": ""
+                    }
+                }
+            })}`,
+            });
+            getApp().globalData.handleSelect = this.handleAdd.bind(this);
+        },
+        handleAdd({
+            list
+        }) {
+            let that = this,
+                project = this.data.project;
+                console.log(list)
+            wx.showModal({
+                title: '提示',
+                content: `是否确认添加${list.length}件产品`,
+                complete: (res) => {
+                    if (res.confirm) _Http.basic({
+                        "id": 20230705145204,
+                        "content": {
+                            "sa_salesforecastbillid": project.sa_salesforecastbillid,
+                            "sa_salesforecastprojectid": project.sa_salesforecastprojectid,
+                            "salesforecast": list.map(v => {
+                                return {
+                                    "itemid": v.itemid,
+                                    "orderqty": v.qty,
+                                    "orderamount": v.qty * v.price,
+                                    "price": v.price,
+                                    "sa_salesforecastid": 0
+                                }
+                            })
+                        }
+                    }).then(res => {
+                        console.log("添加产品", res)
+                        if (res.msg != '成功') return wx.showToast({
+                            title: res.data,
+                            icon: "none"
+                        });
+                        that.updateAmount()
+                        wx.showToast({
+                            title: '添加成功',
+                            icon: "none",
+                            mask: true
+                        });
+                        setTimeout(() => {
+                            wx.navigateBack()
+                        }, 300)
+                    })
+                }
+            })
+        },
+        /* 更新金额 */
+        updateAmount() {
+            const page = getCurrentPages().find(v => v.__route__ == 'packageA/finishforecast/detail');
+            if (page) page.getDetail();
+            this.getList(this.data.sa_salesforecastbillid, true, true)
+        },
+    }
+})

+ 6 - 0
packageA/finishforecast/modules/project/index.json

@@ -0,0 +1,6 @@
+{
+    "component": true,
+    "usingComponents": {
+        "Product": "./list/index"
+    }
+}

+ 61 - 0
packageA/finishforecast/modules/project/index.scss

@@ -0,0 +1,61 @@
+.head {
+    display: flex;
+    align-items: center;
+    width: 100vw;
+    height: 120rpx;
+    padding: 0 20rpx 0 30rpx;
+    box-sizing: border-box;
+
+    .count {
+        font-size: 28rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #333333;
+        font-weight: 600;
+    }
+
+    .expand {
+        flex: 1;
+        display: flex;
+        justify-content: flex-end;
+
+        .but {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            width: 80rpx;
+            height: 80rpx;
+            background: #FFFFFF;
+            border-radius: 8rpx;
+            border: 2rpx solid #CCCCCC;
+            margin-left: 20rpx;
+            color: #666666;
+        }
+    }
+}
+
+.discount {
+    display: flex;
+    align-items: center;
+    height: 58rpx;
+    width: 100%;
+    font-size: 24rpx;
+    font-family: PingFang SC-Regular, PingFang SC;
+    margin-top: -20rpx;
+
+    .label {
+        color: #666666;
+    }
+
+    .input {
+        width: 140rpx;
+        height: 58rpx;
+        background: #FFFFFF;
+        border-radius: 4rpx;
+        border: 1rpx solid #CCCCCC;
+        text-align: center;
+    }
+
+    .price {
+        color: #F60909;
+    }
+}

+ 32 - 0
packageA/finishforecast/modules/project/index.wxml

@@ -0,0 +1,32 @@
+<block wx:if="{{list.length==0}}">
+    <view class="head">
+        <view class="count">去添加项目</view>
+        <view class="expand">
+            <navigator wx:if="{{disabled}}" url="#" class="but" bindtap="addProject">
+                <van-icon name="plus" />
+            </navigator>
+        </view>
+    </view>
+    <My_empty />
+</block>
+
+<van-tabs active="{{sa_projectid}}" wx:elif="{{list.length>1}}" nav-class='tabs' color='#3874F6' title-active-color='#3874F6' bind:change='onChange'>
+    <van-tab title="{{item.projectname}}" wx:for="{{list}}" wx:key="sa_projectid" name='{{item.sa_projectid}}' />
+</van-tabs>
+<block wx:if="{{project}}">
+    <view class="head">
+        <view class="count">{{project.projectname}}</view>
+        <view class="expand">
+            <navigator wx:if="{{disabled}}" url="#" class="but" bindtap="toAddProduct">
+                <van-icon name="plus" />
+            </navigator>
+        </view>
+    </view>
+    <view class="discount">
+        <view class="label" style="margin-left: 30rpx;">折扣(%):</view>
+        <input class="input" type="digit" value="{{project.zk}}" bindblur='onBlur' />
+        <view class="label" style="margin-left: 97rpx;">金额:</view>
+        <view class="price">{{project.shouAmount}}</view>
+    </view>
+    <Product list="{{productList}}" disabled='{{disabled}}' sa_salesforecastprojectid='{{project.sa_salesforecastprojectid}}' catchchangeAmount='updateAmount' />
+</block>

+ 117 - 0
packageA/finishforecast/modules/project/list/index.js

@@ -0,0 +1,117 @@
+const currency = require("../../../../../utils/currency");
+const _Http = getApp().globalData.http;
+
+Component({
+    properties: {
+        list: {
+            type: Array
+        },
+        changeAmount: { //修改产品
+            type: Function
+        },
+        disabled: {
+            type: Boolean
+        },
+        sa_salesforecastprojectid: {
+            type: String
+        }
+    },
+    options: {
+        addGlobalClass: true
+    },
+    methods: {
+        /* 修改产品数量/单价 */
+        onBlur(e) {
+            let {
+                name,
+                index
+            } = e.currentTarget.dataset;
+            let item = this.data.list[index];
+            if (e.detail.value <= 0) {
+                wx.showToast({
+                    title: '非法数值',
+                    icon: "none"
+                });
+            } else {
+                if (item[name] == e.detail.value) return;
+                let v = e.detail.value - 0;
+                //处理起订量和增量
+                if (name == 'orderqty') {
+                    if (v < item.orderminqty) {
+                        wx.showToast({
+                            title: `输入数量小于起订量${item.orderminqty}`,
+                            icon: "none",
+                            mask: true
+                        });
+                        item.orderqty = item.orderminqty;
+                    } else if (item.orderminqty < v) {
+                        var currencyRounding = value => currency(value, {
+                            increment: item.orderaddqty
+                        });
+                        item.orderqty = currency(currencyRounding(currency(v).subtract(item.orderminqty)).format()).add(item.orderminqty).value;
+                        if (item.orderqty != v) wx.showToast({
+                            title: `输入数量不符合增减量规则,已为您取最接近的值`,
+                            icon: "none",
+                            mask: true
+                        })
+                    } else {
+                        item.orderqty = v;
+                    }
+                } else {
+                    item[name] = v;
+                }
+                _Http.basic({
+                    "id": 20230705145204,
+                    "content": {
+                        "sa_salesforecastbillid": item.sa_salesforecastbillid,
+                        "sa_salesforecastprojectid": this.data.sa_salesforecastprojectid,
+                        "salesforecast": [{
+                            "itemid": item.itemid,
+                            "orderqty": item.orderqty,
+                            "orderamount": item.orderqty * item.price,
+                            "price": item.price,
+                            "sa_salesforecastid": item.sa_salesforecastid
+                        }]
+                    }
+                }).then(res => {
+                    console.log("修改产品", res)
+                    this.triggerEvent("changeAmount")
+                })
+            }
+            this.data.list[index] = item;
+            this.setData({
+                list: this.data.list
+            })
+        },
+        deleteProduct(e) {
+            const {
+                item
+            } = e.currentTarget.dataset,
+                that = this;
+            console.log(item)
+            wx.showModal({
+                title: '提示',
+                content: `是否确认删除“${item.itemname}”?`,
+                complete: ({
+                    confirm
+                }) => {
+                    if (confirm) _Http.basic({
+                        "accesstoken": "7cbf3f38611c090666f8de7b9582a6ae",
+                        "id": 20230705145404,
+                        "content": {
+                            "sa_salesforecastbillid": item.sa_salesforecastbillid,
+                            "sa_salesforecastids": [item.sa_salesforecastid]
+                        }
+                    }).then(res => {
+                        console.log("删除项目产品", res)
+                        wx.showToast({
+                            title: res.msg == '成功' ? '删除成功' : res.msg,
+                            icon: "none"
+                        })
+                        if (res.msg == '成功') that.triggerEvent("changeAmount")
+                    })
+                }
+            })
+        },
+    }
+})

+ 4 - 0
packageA/finishforecast/modules/project/list/index.json

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

+ 132 - 0
packageA/finishforecast/modules/project/list/index.scss

@@ -0,0 +1,132 @@
+.product-item {
+    background-color: #fff;
+    box-sizing: border-box;
+    border-bottom: 1rpx solid #DDDDDD;
+    margin-top: 20rpx;
+
+    .product {
+        padding: 20rpx 30rpx;
+        box-sizing: border-box;
+
+        .mian {
+            position: relative;
+            display: flex;
+            width: 100%;
+            box-sizing: border-box;
+
+            .img {
+                flex-shrink: 0;
+                width: 112rpx;
+                height: 112rpx;
+                border-radius: 16rpx;
+                margin-right: 20rpx;
+                overflow: hidden;
+            }
+
+            .dec {
+                flex: 1;
+                width: 0;
+                min-height: 128rpx;
+                height: 100%;
+                font-size: 24rpx;
+                font-family: PingFang SC-Regular, PingFang SC;
+                color: #999999;
+
+                .title {
+                    width: 90%;
+                    height: 40rpx;
+                    font-size: 28rpx;
+                    font-weight: 600;
+                    color: #333333;
+                }
+
+                .subfield {
+                    display: flex;
+                    margin-top: 8rpx;
+                    height: 34rpx;
+                    line-height: 34rpx;
+
+                    text {
+                        display: inline-block;
+                        width: 40%;
+                    }
+
+
+                    .money {
+                        flex: 1;
+                        display: flex;
+                        font-size: 24rpx;
+                        font-family: PingFang SC-Medium, PingFang SC;
+                        color: #666666;
+                        margin-right: 20rpx;
+
+                        text {
+                            font-size: 28rpx;
+                            color: #FF3B30;
+                            font-weight: 600;
+                        }
+                    }
+                }
+            }
+
+            .delete {
+                position: absolute;
+                width: 68rpx;
+                height: 68rpx;
+                line-height: 68rpx;
+                right: -30rpx;
+                top: -20rpx;
+                text-align: center;
+                font-size: 32rpx;
+                color: #999;
+            }
+        }
+    }
+
+
+    .bot {
+        width: 690rpx;
+        border-top: 1rpx solid #ddd;
+        margin: 0 auto;
+        padding-bottom: 20rpx;
+
+        .row {
+            display: flex;
+            width: 100%;
+            margin-top: 20rpx;
+
+            view {
+                display: flex;
+                height: 58rpx;
+                align-items: center;
+
+                .label {
+                    width: 144rpx;
+                    font-size: 24rpx;
+                    font-family: PingFang SC-Regular, PingFang SC;
+                    color: #666666;
+                    text-align-last: justify;
+                }
+            }
+
+            .input {
+                height: 58rpx;
+                background: #FFFFFF;
+                border-radius: 8rpx;
+                border: 1rpx solid #CCCCCC;
+                font-size: 28rpx;
+                font-family: PingFang SC-Regular, PingFang SC;
+                color: #333333;
+                line-height: 44px;
+                text-align: center;
+            }
+        }
+    }
+}
+
+/* 文本行数限制 */
+.line-1 {
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}

+ 50 - 0
packageA/finishforecast/modules/project/list/index.wxml

@@ -0,0 +1,50 @@
+<view class="product-item" wx:for="{{list}}" wx:key="sa_salesforecastid">
+    <navigator class="product" url="#">
+        <view class="mian">
+            <view class="img" data-file="{{item.attinfos}}" catchtap="viewImage">
+                <van-image width="100%" height="100%" src="{{item.cover||''}}" use-loading-slot use-error-slot lazy-load>
+                    <van-loading slot="loading" type="spinner" size="20" vertical />
+                    <text slot="error" style="font-size: 24rpx;">暂无图片</text>
+                </van-image>
+            </view>
+            <view class="dec">
+                <view class="title line-1">
+                    {{item.itemname}}
+                </view>
+                <view class="subfield">
+                    编号:{{item.itemno}}
+                </view>
+                <view class="subfield">
+                    <text class="line-1" style="margin-right: 6rpx;">品牌:{{item.brandName||' --'}}</text>
+                    <text class="line-1">产品类别:{{item.className||' --'}}</text>
+                </view>
+                <view class="subfield">
+                    <text class="line-1" style="margin-right: 6rpx;">规格:{{item.spec||' --'}}</text>
+                    <text class="line-1">型号:{{item.model||' --'}}</text>
+                </view>
+                <view class="subfield">
+                    <text class="line-1" style="margin-right: 6rpx;">牌价:{{item.showMP||' --'}}</text>
+                    <view class="money line-1">
+                        金额:<text>{{item.showOrderamount}}</text>
+                    </view>
+                </view>
+                <view class="delete" wx:if="{{disabled}}" data-item="{{item}}" catchtap="deleteProduct">
+                    <text class="iconfont icon-guanlian-shanchu" />
+                </view>
+            </view>
+        </view>
+    </navigator>
+    <view class="bot">
+        <view class="row">
+            <view style="margin-right: 40rpx;">
+                <view class="label">数量({{item.unitname}}):</view>
+                <input class="input" style="width: 180rpx;" type="digit" disabled="{{!disabled}}" value="{{item.orderqty}}" data-name="orderqty" data-index="{{index}}" bindblur="onBlur" />
+            </view>
+            <view>
+                <view class="label">单价(元):</view>
+                <input class="input" style="width: 180rpx;" type="digit" disabled="{{!disabled}}" value="{{item.price}}" data-name="price" data-index="{{index}}" bindblur="onBlur" />
+            </view>
+        </view>
+    </view>
+</view>
+<My_empty wx:if="{{list.length==0}}" />

+ 150 - 0
packageA/select/project/select2.js

@@ -0,0 +1,150 @@
+const _Http = getApp().globalData.http,
+    currency = require("../../../utils/currency"),
+    CNY = value => currency(value, {
+        symbol: "¥",
+        precision: 2
+    }).format();
+
+Page({
+    data: {
+        params: {}, //请求体
+        result: [], //返回结果
+        radio: false, //是否为单选
+        idname: "sa_projectid", //idkey
+        showName: "projectname", //表单用 显示名称
+    },
+    onLoad(options) {
+        if (options.params) {
+            let params = JSON.parse(options.params);
+            if (!params.content.pageNumber || !params.content.pageTotal) {
+                params.content.pageNumber = 1;
+                params.content.pageTotal = 1;
+            }
+            this.setData({
+                params
+            });
+        }
+        if (options.title) wx.setNavigationBarTitle({
+            title: options.title,
+        })
+        this.setData({
+            radio: options.radio ? true : false,
+            idname: options.idname || this.data.idname,
+            showName: options.showName || this.data.showName,
+        });
+        this.getList()
+    },
+    getList(init = false) {
+        //init 用于初始化分页
+        if (init.detail != undefined) init = init.detail;
+        let params = this.data.params;
+        if (init) params.content.pageNumber = 1;
+        if (params.content.pageNumber > params.content.pageTotal) return;
+        _Http.basic(params).then(res => {
+            console.log("选择项目列表", res)
+            this.selectComponent('#ListBox').RefreshToComplete();
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            })
+            res.data = res.data.map(v => {
+                v.signamount_due = CNY(v.signamount_due);
+                return v
+            })
+            this.setData({
+                'params.content.pageNumber': res.pageNumber + 1,
+                'params.content.pageTotal': res.pageTotal,
+                'params.content.total': res.total,
+                list: res.pageNumber == 1 ? res.data : this.data.list.concat(res.data)
+            })
+        })
+    },
+    /* 获取列表标签 */
+    getTags() {
+        let list = this.data.list,
+            ownerids = list.map(v => v.sa_projectid);
+        _Http.basic({
+            "id": 20221018102001,
+            "content": {
+                nocache: true,
+                "ownertable": "sa_project",
+                ownerids
+            }
+        }).then(res => {
+            console.log("标签", res)
+            for (let key in res.data) {
+                let index = list.findIndex(v => v.sa_projectid == key);
+                list[index].tags = res.data[key]
+            };
+            console.log(list)
+            this.setData({
+                list
+            })
+        })
+    },
+    /* 删除项 */
+    deteleItem(id) {
+        this.setData({
+            list: this.data.list.filter(v => v[this.data.idname] != id),
+            "params.content.total": this.data.params.content.total - 1
+        })
+    },
+    /* 选中 */
+    changeResult(e) {
+        let {
+            id
+        } = e.currentTarget.dataset, result = this.data.result;
+        if (this.data.radio) {
+            result = [id];
+        } else {
+            result.some(v => v == id) ? result = result.filter(v => v != id) : result.push(id)
+        }
+        this.setData({
+            result
+        });
+        if (this.data.radio) this.submit();
+    },
+    /* 提交 */
+    submit() {
+        let result = this.data.result,
+            obj = this.data.radio ? {
+                id: result,
+                item: this.data.list.find(value => value[this.data.idname] == result),
+                value: [this.data.list.find(value => value[this.data.idname] == result)[this.data.showName], result]
+            } : {
+                result,
+                list: result.map(v => this.data.list.find(value => value[this.data.idname] == v)),
+                value: [result.map(v => {
+                    let data = this.data.list.find(value => value[this.data.idname] == v);
+                    return data ? data[this.data.showName] : ""
+                }), result]
+            }
+        getApp().globalData.handleSelect && getApp().globalData.handleSelect(obj)
+    },
+    /* 开始搜索 */
+    startSearch({
+        detail
+    }) {
+        let condition = this.data.content ? this.data.content.where.condition : this.data.params.content.where.condition;
+        if (detail == condition) return;
+        this.setData({
+            'content.where.condition': detail,
+            'params.content.where.condition': detail
+        });
+        this.getList(true);
+    },
+    /* 取消搜索 */
+    onClear() {
+        this.setData({
+            'content.where.condition': "",
+            'params.content.where.condition': ""
+        });
+        this.getList(true);
+    },
+    onReady() {
+        this.selectComponent("#ListBox").setHeight(".div", this);
+    },
+    onUnload() { //回收数据
+        getApp().globalData.handleSelect = null;
+    }
+})

+ 4 - 0
packageA/select/project/select2.json

@@ -0,0 +1,4 @@
+{
+    "usingComponents": {},
+    "navigationBarTitleText": "选择项目"
+}

+ 102 - 0
packageA/select/project/select2.scss

@@ -0,0 +1,102 @@
+page {
+    height: 100vh;
+    overflow: hidden;
+}
+
+.total {
+    height: 60rpx;
+    line-height: 60rpx;
+    font-size: 24rpx;
+    font-family: PingFang SC-Regular, PingFang SC;
+    color: #666666;
+    padding-left: 30rpx;
+}
+
+.setclient-list-item {
+    width: 100vw;
+    background-color: #fff;
+    box-sizing: border-box;
+    padding-left: 30rpx;
+
+    .con {
+        display: flex;
+        align-items: center;
+        width: 100%;
+        border-bottom: 1px solid #EFEFEF;
+        box-sizing: border-box;
+        padding: 10rpx 0;
+        padding-bottom: 14rpx;
+
+        .mian {
+            flex: 1;
+
+            .title {
+                display: flex;
+                height: 44rpx;
+                line-height: 44rpx;
+                width: 100%;
+
+                .projecttype,
+                .tradefield {
+                    height: 44rpx;
+                    line-height: 44rpx;
+                    padding: 0 12rpx;
+                    border-radius: 4rpx;
+                    font-size: 20rpx;
+                    color: #FFFFFF;
+                    margin-right: 10rpx;
+                    flex-shrink: 0;
+                }
+
+                view {
+                    flex: 1;
+                    width: 0;
+                }
+            }
+
+            .row {
+                display: flex;
+                font-size: 24rpx;
+                font-family: PingFang SC-Regular, PingFang SC;
+                color: #666666;
+
+                .left {
+                    width: 350rpx;
+                }
+            }
+        }
+
+
+    }
+}
+
+.footer {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 30rpx;
+    position: fixed;
+    width: 100vw;
+    height: 130rpx;
+    background: #FFFFFF;
+    box-shadow: 0px -4rpx 16rpx 2rpx rgba(150, 157, 165, 0.16);
+    bottom: 0;
+    box-sizing: border-box;
+
+    .count {
+        font-size: 28rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #333333;
+    }
+
+    .but {
+        width: 156rpx;
+        height: 90rpx;
+        background: #3874F6;
+        border-radius: 8rpx;
+        font-size: 28rpx;
+        font-family: PingFang SC-Bold, PingFang SC;
+        font-weight: bold;
+        color: #FFFFFF;
+    }
+}

+ 55 - 0
packageA/select/project/select2.wxml

@@ -0,0 +1,55 @@
+<van-search class="search" value="{{ params.content.where.condition }}" shape="round" placeholder="请输入搜索关键词" bind:search='startSearch' bind:clear='onClear' />
+<view class="div" style="height: 20rpx;" />
+<Yl_ListBox id='ListBox' bind:getlist='getList'>
+    <navigator class="setclient-list-item" url="#" wx:for="{{list}}" wx:key="{{idname}}" data-id="{{item[idname]}}" bindtap="changeResult">
+        <view class="con">
+            <van-checkbox wx:if="{{!radio}}" value="{{ handle.isCheck(item[idname],result) }}" shape="square" icon-size='28rpx' />
+            <view class="mian">
+                <view class="title">
+                    <text class="projecttype" style="background-color: #3874F6;" wx:if="{{item.projecttype}}">{{item.projecttype}}</text>
+                    <text class="tradefield" style="background-color: #5AB73F;" wx:if="{{item.tradefield}}">{{item.tradefield}}</text>
+                    <view class="line-1">
+                        {{item.projectname}}
+                    </view>
+                </view>
+                <view class="row" style="margin-top: 16rpx;">
+                    <view class="left">
+                        业务员:{{item.name||' --'}}
+                    </view>
+                    <view class="right">
+                        项目阶段:{{item.stagename||' --'}}
+                    </view>
+                </view>
+                <view class="row" style="margin-top: 8rpx;">
+                    <view class="left">
+                        预计签约金额:{{item.signamount_due||' --'}}
+                    </view>
+                    <view class="right">
+                        预计签约时间:{{item.signdate_due||' --'}}
+                    </view>
+                </view>
+            </view>
+        </view>
+    </navigator>
+    <view style="height: 150rpx;" />
+    <My_empty wx:if="{{!list.length}}" />
+</Yl_ListBox>
+
+<view style="height: 130rpx;" />
+<block wx:if="{{!radio}}">
+    <view class="footer">
+        <view class="count">
+            已选:{{result.length}}
+        </view>
+        <van-button custom-class='but' disabled='{{result.length==0}}' bind:click="submit">确定</van-button>
+    </view>
+    <wxs module="handle">
+        module.exports = {
+            isCheck: function (id, list) {
+                return list.some(function (v) {
+                    return v == id
+                });
+            },
+        }
+    </wxs>
+</block>

+ 8 - 0
pages/tabbar/home/index.js

@@ -226,6 +226,14 @@ Page({
                     path: "/packageA/salesForecasting/index",
                     icon: "work-xiaochengxu_xiaoshouyuce",
                     objectname: "sa_salesforecastbill"
+                }, {
+                    name: "项目成交预测",
+                    path: "/packageA/finishforecast/index",
+                    icon: "work-xiangmuchengjiaoyuce"
+                }, {
+                    name: "项目成交预测管理",
+                    path: "/packageA/finishforecast/admin",
+                    icon: "work-xiangmuchengjiaoyuceguanli"
                 }];
                 let crm = getApp().globalData.queryPer.query(wx.getStorageSync('userauth'), ['CRM'], ['销售预测', '销售线索', '销售目标', '合同管理', '客户管理', '项目管理']),
                     list = [];