codeMan před 3 roky
rodič
revize
97c1583f40

+ 170 - 0
packageA/saleClue/addClue.js

@@ -0,0 +1,170 @@
+const _Http = getApp().globalData.http,
+    getTime = require("../../utils/getTime");
+
+Page({
+    data: {
+        showAll: false,
+        form: [{
+            label: "客户(企业)",
+            error: false,
+            errMsg: "",
+            type: "label",
+            value: "",
+            placeholder: "客户(企业)",
+            valueName: "enterprisename",
+            checking: "base",
+            required: true
+        }, {
+            label: "联系人",
+            error: false,
+            errMsg: "",
+            type: "label",
+            value: "",
+            placeholder: "联系人",
+            valueName: "name",
+            checking: "base",
+            required: false
+        }, {
+            label: "手机号码",
+            error: false,
+            checking: "phone",
+            errMsg: "",
+            type: "number",
+            value: "",
+            placeholder: "手机号码",
+            valueName: "phonenumber", //绑定的字段名称
+            required: true, //必填
+        }, {
+            label: "省市县",
+            error: false,
+            errMsg: "",
+            type: "region",
+            value: "",
+            placeholder: "省市县",
+            valueName: "province",
+            checking: "base",
+            required: true
+        }, {
+            label: "详细地址",
+            error: false,
+            errMsg: "",
+            type: "label",
+            value: "",
+            placeholder: "详细地址",
+            valueName: "address",
+            checking: "base",
+            required: false
+        }, {
+            label: "来源",
+            error: false,
+            errMsg: "",
+            type: "label",
+            value: "",
+            placeholder: "来源",
+            valueName: "cluesource",
+            checking: "base",
+            required: false
+        }, {
+            label: "备注",
+            error: false,
+            errMsg: "",
+            type: "label",
+            value: "",
+            placeholder: "备注",
+            valueName: "notes",
+            checking: "base",
+            required: false
+        }],
+        "content": {
+            "sat_orderclueid": 0,
+            "enterprisename":"",
+            "name": "",
+            "phonenumber": "",
+            "province": "",
+            "city": "",
+            "county": "",
+            "address": "",
+            "notes": "",
+            "cluesource": "",
+            "sat_orderclueid":0,//活动id,当活动id大于0是默认业务员创建
+            "isprivate":1//0表示公海,1表示私域
+        },
+        disabled: true
+    },
+    onLoad(options) {
+        if (options.sat_orderclueid) {
+            this.data.form.sat_orderclueid = options.sat_orderclueid
+        }
+        if (options.rowData) {
+            // wx.setNavigationBarTitle({
+            //   title: 'title',
+            // })
+            let data = JSON.parse(options.rowData);
+            console.log(data);
+            this.setData({
+                disabled: false,
+                form: this.data.form.map(v => {
+                    if (v.valueName != 'region') {
+                        v.value = data[v.valueName];
+                    } else {
+                        v.value = data.province ? [data.province, data.city, data.county] : []
+                    }
+                    return v
+                }),
+                'form[0].value':data.enterprisename_customer,
+                'content.sat_orderclueid':data.sat_orderclueid
+            })
+        }
+    },
+    submit() {
+        let content = {
+            ...this.data.content,
+            ...this.selectComponent("#Form").submit()
+        };
+        content.sat_orderclueid = this.data.content.sat_orderclueid
+        if (content.province.length > 0) {
+            content.city = content.province[1]
+            content.county = content.province[2]
+            content.province = content.province[0]
+        }
+        
+        _Http.basic({
+            "id":"20221205162402",
+            content
+        }).then(res => {
+            console.log("添加线索", res)
+            wx.showToast({
+                title: res.msg != '成功' ? res.msg : '保存成功',
+                icon: "none"
+            })
+            if (res.msg != '成功') return;
+            setTimeout(() => {
+                wx.navigateBack();
+                getCurrentPages().forEach(v => {
+                    console.log(v,'路径');
+                    if(v.__route__=='packageA/saleClue/detail'){
+                        v.getDetail();
+                    }else if(v.__route__=='packageA/saleClue/index'){
+                        v.getList(true);
+                    }
+                })
+            }, 300)
+        })
+    },
+    // 是否显示全部
+    onChange({
+        detail
+    }) {
+        this.setData({
+            showAll: detail
+        })
+    },
+    /* 表单必填项是否完成 */
+    onConfirm({
+        detail
+    }) {
+        this.setData({
+            disabled: detail
+        })
+    }
+})

+ 4 - 0
packageA/saleClue/addClue.json

@@ -0,0 +1,4 @@
+{
+    "usingComponents": {},
+    "navigationBarTitleText": "添加线索"
+}

+ 23 - 0
packageA/saleClue/addClue.scss

@@ -0,0 +1,23 @@
+.new-footer {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    position: fixed;
+    width: 100vw;
+    height: 130rpx;
+    background: #FFFFFF;
+    box-shadow: 0px -4rpx 16rpx 2rpx rgba(150, 157, 165, 0.16);
+    bottom: 0;
+
+    .new-submit {
+        width: 156rpx;
+        height: 90rpx;
+        background: #3874F6;
+        border-radius: 8rpx;
+        font-size: 28rpx;
+        font-family: PingFang SC-Bold, PingFang SC;
+        font-weight: bold;
+        color: #FFFFFF;
+        margin-right: 30rpx;
+    }
+}

+ 6 - 0
packageA/saleClue/addClue.wxml

@@ -0,0 +1,6 @@
+<Yl_Headline title='基本信息' type='switch' switchLabel='仅显示必填信息' switch='{{showAll}}' bind:callBack='onChange' />
+<Yl_field id='Form' form='{{form}}' showAll='{{!showAll}}' bind:onConfirm='onConfirm' bind:interrupt="interrupt" />
+<view style="height: 100rpx;" />
+<view class="new-footer">
+    <van-button custom-class='new-submit' disabled='{{disabled}}' bindclick='submit'>提交</van-button>
+</view>

+ 81 - 0
packageA/saleClue/change.js

@@ -0,0 +1,81 @@
+const _Http = getApp().globalData.http,
+    getTime = require("../../utils/getTime");
+
+Page({
+    data: {
+        showAll: false,
+        form: [{
+            label: "项目名称",
+            error: false,
+            errMsg: "",
+            type: "label",
+            value: "",
+            placeholder: "项目名称",
+            valueName: "projectname",
+            checking: "base",
+            required: true
+        }, {
+            label: "项目类型",
+            error: false,
+            errMsg: "",
+            type: "option",
+            optionNmae: "projecttype",
+            optionType: "radio", //复选   radio 单选
+            value: "",
+            placeholder: "项目类型",
+            valueName: "projecttype",
+            checking: "base",
+            required: true
+        }],
+        "content": {
+            "projecttype": "",
+            "projectname":"",
+            "sat_orderclueid":""
+        },
+        disabled: true
+    },
+    onLoad(options) {
+        let data = JSON.parse(options.rowData);
+        this.setData({
+            'content.sat_orderclueid':data.sat_orderclueid
+        })
+    },
+    submit() {
+        let content = {
+            ...this.data.content,
+            ...this.selectComponent("#Form").submit()
+        };
+        _Http.basic({
+            "id":"20221124154902",
+            content
+        }).then(res => {
+            console.log("转化", res)
+            wx.showToast({
+                title: res.msg != '成功' ? res.msg : '转化成功',
+                icon: "none"
+            })
+            if (res.msg != '成功') return;
+            setTimeout(() => {
+                wx.redirectTo({
+                    url: `/packageA/project/detail?sa_projectid=${res.data.sa_projectid}`,
+                })
+            }, 300)
+        })
+    },
+    // 是否显示全部
+    onChange({
+        detail
+    }) {
+        this.setData({
+            showAll: detail
+        })
+    },
+    /* 表单必填项是否完成 */
+    onConfirm({
+        detail
+    }) {
+        this.setData({
+            disabled: detail
+        })
+    }
+})

+ 4 - 0
packageA/saleClue/change.json

@@ -0,0 +1,4 @@
+{
+    "usingComponents": {},
+    "navigationBarTitleText": "转化"
+}

+ 23 - 0
packageA/saleClue/change.scss

@@ -0,0 +1,23 @@
+.new-footer {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    position: fixed;
+    width: 100vw;
+    height: 130rpx;
+    background: #FFFFFF;
+    box-shadow: 0px -4rpx 16rpx 2rpx rgba(150, 157, 165, 0.16);
+    bottom: 0;
+
+    .new-submit {
+        width: 156rpx;
+        height: 90rpx;
+        background: #3874F6;
+        border-radius: 8rpx;
+        font-size: 28rpx;
+        font-family: PingFang SC-Bold, PingFang SC;
+        font-weight: bold;
+        color: #FFFFFF;
+        margin-right: 30rpx;
+    }
+}

+ 6 - 0
packageA/saleClue/change.wxml

@@ -0,0 +1,6 @@
+<Yl_Headline title='基本信息' type='switch' switchLabel='仅显示必填信息' switch='{{showAll}}' bind:callBack='onChange' />
+<Yl_field id='Form' form='{{form}}' showAll='{{!showAll}}' bind:onConfirm='onConfirm' bind:interrupt="interrupt" />
+<view style="height: 100rpx;" />
+<view class="new-footer">
+    <van-button custom-class='new-submit' disabled='{{disabled}}' bindclick='submit'>提交</van-button>
+</view>

+ 388 - 0
packageA/saleClue/detail.js

@@ -0,0 +1,388 @@
+const _Http = getApp().globalData.http;
+Page({
+    data: {
+        tabsActive: 0, //tabs 选中项
+        sat_orderclueid: "",
+        detail:'',
+        sheetTitle:'',
+        tabsList: [{
+            label: "详细信息",
+            num: 132
+        }, {
+            label: "跟进记录",
+            num: 132
+        }, {
+            label: "操作",
+            num: 132
+        }, {
+            label: "跟进动态",
+            num: 132
+        }],
+        tabbarList: [{
+            icon: "icon-bianji",
+            label: "编辑"
+        }, {
+            icon: "icon-genjin",
+            label: "跟进"
+        }, {
+            icon: "icon-genjin",
+            label: "无效"
+        }, {
+            icon: "icon-dibu-zhuanhuan",
+            label: "转化"
+        }, {
+            icon: "icon-dibu-zhuanhuan",
+            label: "转移"
+        }, {
+            icon: "icon-dibu-jieshu",
+            label: "作废"
+        }],
+        oldtabbarList: [{
+            icon: "icon-bianji",
+            label: "编辑"
+        }, {
+            icon: "icon-genjin",
+            label: "跟进"
+        }, {
+            icon: "icon-dibu-wuxiao",
+            label: "无效"
+        }, {
+            icon: "icon-dibu-zhuanhuan",
+            label: "转化"
+        }, {
+            icon: "icon-zhuanyi",
+            label: "更换负责人"
+        }, {
+            icon: "icon-dibu-jieshu",
+            label: "作废"
+        }],
+    },
+    onLoad(options) {
+        this.setData({
+            sat_orderclueid: options.sat_orderclueid
+        });
+        this.getDetail();
+    },
+    getDetail() {
+        console.log(111);
+        _Http.basic({
+            "classname": "saletool.orderclue.web.orderclue",
+            "method": "selectDetail",
+            "version": 1,
+            "content": {
+                "nocache":true,
+                "sat_orderclueid": this.data.sat_orderclueid
+            },
+        }).then(res => {
+            console.log("线索详情", res)
+            if (res.msg != '成功') return wx.showToast({
+                title: res.msg,
+                icon: "none"
+            });
+            console.log(res.data.createBy);
+            this.setData({
+                detail: res.data,
+                briefs: [ {
+                    label: "联系人",
+                    value: res.data.name
+                }, {
+                    label: "手机号",
+                    value: res.data.phonenumber
+                }, {
+                    label: "来源",
+                    value: res.data.cluesource
+                }, {
+                    label:'负责人',
+                    value:res.data.leader ? res.data.leader[0].name : ''
+                  },
+                  {
+                    label:'分配状态',
+                    value:res.data.allocationstatus
+                  },
+                  {
+                    label:'跟进状态',
+                    value:res.data.status
+                  },
+                  {
+                    label:'跟进次数',
+                    value:res.data.followcount||'0'
+                  },
+                  {
+                    label:'转化次数',
+                    value:res.data.changecount
+                  }],
+                list1: [{
+                    label: "联系人",
+                    value: res.data.name
+                }, {
+                    label: "手机号",
+                    value: res.data.phonenumber
+                }, {
+                    label: "来源",
+                    value: res.data.cluesource
+                }, {
+                    label:'负责人',
+                    value:res.data.leader ? res.data.leader[0].name : ''
+                  },
+                  {
+                    label:'分配状态',
+                    value:res.data.allocationstatus
+                  },
+                  {
+                    label:'跟进状态',
+                    value:res.data.status
+                  },
+                  {
+                    label:'跟进次数',
+                    value:res.data.followcount||'0'
+                  },
+                  {
+                    label:'转化次数',
+                    value:res.data.changecount
+                  }],
+                list2: [{
+                    label: "创建人",
+                    value: res.data.createBy
+                }, {
+                    label: "创建时间",
+                    value: res.data.createDate
+                }, {
+                    label: "分配人",
+                    value: res.data.assignedBy
+                }, {
+                    label: "最近跟进人",
+                    value: res.data.followBy
+                }, {
+                    label: "转移人",
+                    value: res.data.changeBy
+                }, {
+                    label: "最近编辑人",
+                    value: res.data.editBy
+                }, {
+                    label: "创建时间",
+                    value: res.data.createDate
+                }, {
+                    label: "分配时间",
+                    value: res.data.assignedDate
+                }, {
+                    label: "最近跟进时间",
+                    value: res.data.followDate
+                }, {
+                    label: "最近转移时间",
+                    value: res.data.changeDate
+                }, {
+                    label: "最近编辑时间",
+                    value: res.data.editDate
+                }],
+                tabsList: this.data.tabsList,
+            });
+            let arr = this.data.oldtabbarList
+            if (res.data.status != '待跟进' && res.data.status != '跟进中') {
+                arr = []
+            }
+            this.setData({
+                tabbarList: arr
+            })
+            this.getTags();
+            this.getGroup();
+            this.partialRenewal();
+        })
+    },
+    /*跟进提交*/
+    endFollow ({
+        detail
+    }) {
+        this.setData({
+            sheetTitle:''
+        })
+        this.getDetail()
+        this.selectComponent('#follow').getFollowDetail()
+    },
+    //tabs 切换
+    tabsChange({
+        detail
+    }) {
+        this.setData({
+            tabsActive: detail
+        });
+        this.partialRenewal();
+    },
+    //更新标签
+    getTags() {
+        this.selectComponent("#Tags").getTags();
+    },
+    //更新团队成员
+    getGroup() {
+        this.selectComponent("#Group").getList();
+    },
+    //局部数据更新 tabs
+    partialRenewal(init = false) {
+        let id = this.data.detail.sat_orderclueid;
+        let model = '';
+        let name = this.data.tabsList[this.data.tabsActive].label;
+        switch (name) {
+            case "跟进记录":
+                model = "#follow"
+                break;
+            case "操作":
+                model = "#Record"
+                break;
+            case "跟进动态":
+                model = "#Trace"
+                break;
+        };
+        if (model) {
+            // 确定好模块ID total = null 是第一次加载 加载数据
+            // init是新增或修改需要清数据
+            let Component = this.selectComponent(model);
+            const {
+                total,
+                pageNumber,
+                pageTotal
+            } = Component.data.content;
+            if (total == null || init) {
+                Component.getList(id, init);
+            } else if (pageNumber <= pageTotal) {
+                Component.getList(id, false);
+            } else {
+                //用来判断 在搜索页面修改,与tabs选项不一致 但是切换到该选项 重置数据
+            }
+        }
+    },
+    onReachBottom() {
+        this.partialRenewal();
+    },
+    //详情按钮回调
+    tabbarOnClick({
+        detail
+    }) {
+        let data = this.data.detail;
+        switch (detail.label) {
+            case "编辑":
+                wx.navigateTo({
+                    url: `/packageA/saleClue/addClue?rowData=${JSON.stringify(this.data.detail)}`,
+                })
+                break;
+            case "作废":
+                wx.showModal({
+                    title: '提示',
+                    content: `是否确认作废该线索?`,
+                    complete: ({
+                        confirm
+                    }) => {
+                        if (confirm) _Http.basic({
+                            "id":20221123193702,
+                            "content": {
+                                "sat_orderclueids": [this.data.detail.sat_orderclueid]
+                            }
+                        }).then(res => {
+                            wx.showToast({
+                                title: res.msg == '成功' ? `已作废该线索` : res.msg,
+                                icon: "none"
+                            });
+                            if (res.msg == '成功') {
+                                wx.navigateBack()
+                                getCurrentPages().forEach(v => {
+                                    if(v.__route__=="packageA/saleClue/index") {
+                                        v.getList(true)
+                                    }
+                                })
+                            }
+                        })
+                    }
+                })
+                break;
+            case "无效":
+                wx.showModal({
+                    title: '提示',
+                    content: `是否设置该线索为"无效"状态,确定后无法撤销!`,
+                    complete: ({
+                        confirm
+                    }) => {
+                        if (confirm) _Http.basic({
+                            "classname": "saletool.orderclue.web.orderclue",
+                            "method": "addFollowUpLog",
+                            "content": {
+                                "sat_orderclueid":this.data.detail.sat_orderclueid,
+                                "content": "",
+                                "followupmode": "",
+                                "logtype": "无效",
+                                "competitor": ""
+                            }
+                        }).then(res => {
+                            wx.showToast({
+                                title: res.msg == '成功' ? `已无效该线索` : res.msg,
+                                icon: "none"
+                            });
+                            if (res.msg == '成功') {
+                                wx.navigateBack()
+                                getCurrentPages().forEach(v => {
+                                    if(v.__route__=="packageA/saleClue/index") {
+                                        v.getList(true)
+                                    }
+                                })
+                            }
+                        })
+                    }
+                })
+                break;
+            case "转化":
+                wx.navigateTo({
+                    url: `/packageA/saleClue/change?rowData=${JSON.stringify(this.data.detail)}`,
+                })
+                break;
+            case "跟进":
+                this.selectComponent("#followAction").updateTime();
+                this.setData({
+                    sheetTitle: '跟进'
+                })
+                break;
+            case "更换负责人":
+                wx.navigateTo({
+                    url: `/packageA/group/select?data=${JSON.stringify({
+                             ownertable:"sat_orderclue",
+                             ownerid:data.sat_orderclueid,
+                        })}&radio=true&principal=true`,
+                })
+                break;
+        }
+    },
+    /* 更换负责人 */
+    handelSubmit(arr) {
+        const that = this;
+        wx.showModal({
+            title: '提示',
+            content: '是否确认更换负责人',
+            complete: ({
+                confirm
+            }) => {
+                if (confirm) _Http.basic({
+                    "id": 20220930103701,
+                    "content": {
+                        ownertable: "sat_orderclue",
+                        ownerid: that.data.detail.sat_orderclueid,
+                        userid: arr[0]
+                    }
+                }).then(res => {
+                    console.log("更换负责人", res)
+                    if (res.msg != '成功') return wx.showToast({
+                        title: res.data,
+                        icon: "none"
+                    });
+                    wx.showToast({
+                        title: '更换成功!',
+                        icon: "none"
+                    });
+                    setTimeout(() => {
+                        that.getDetail();
+                        wx.navigateBack();
+                        /*  getCurrentPages().forEach(v => {
+                             if (['packageA/project/index'].includes(v.__route__)) v.getList(true)
+                         }) */
+                    }, 300)
+                })
+            }
+        })
+    },
+    onShareAppMessage() {}
+})

+ 11 - 0
packageA/saleClue/detail.json

@@ -0,0 +1,11 @@
+{
+    "usingComponents": {
+        "Preview": "../setclient/modules/preview/index",
+        "Trace": "../setclient/modules/trace/index",
+        "Record":"/packageA/public/record/index",
+        "Follow":"./modules/follow/follow",
+        "Popup": "../../pages/threadedTree/modules/popup/index",
+        "followAction":"./modules/followAction/followAction"
+    },
+    "navigationBarTitleText": "线索详情"
+}

+ 15 - 0
packageA/saleClue/detail.scss

@@ -0,0 +1,15 @@
+.header {
+    background-color: #fff;
+    padding: 20rpx 30rpx 0rpx;
+    box-sizing: border-box;
+    margin-bottom: -16rpx;
+
+    .title {
+        height: 40rpx;
+        font-size: 28rpx;
+        font-family: PingFang SC-Bold, PingFang SC;
+        font-weight: bold;
+        color: #333333;
+        margin-bottom: 16rpx;
+    }
+}

+ 25 - 0
packageA/saleClue/detail.wxml

@@ -0,0 +1,25 @@
+<view class="header">
+    <view class="title">{{detail.enterprisename_customer}}</view>
+    <Yl-tags id="Tags" add ownertable='sat_orderclue' ownerid='{{detail.sat_orderclueid}}' />
+</view>
+<!-- 简介 -->
+<Yl_Detail list="{{briefs}}">
+    <Yl-group slot='bottom' id='Group' add ownertable='sat_orderclue' ownerid='{{detail.sat_orderclueid}}' />
+</Yl_Detail>
+<view style="height: 20rpx;" />
+<Yl_FunTabs list='{{tabsList}}' active='{{tabsActive}}' bind:onChenge="tabsChange">
+    <Preview slot='详细信息' list1='{{list1}}' list2='{{list2}}' />
+    <Follow slot='跟进记录' rowData="{{detail}}" id='follow'/>
+    <Record slot='操作' id="Record" ownertable='sat_orderclue' ownerid='{{detail.sat_orderclueid}}' />
+    <Trace slot='跟进动态' id='Trace' ownertable='sat_orderclue' ownerid='{{detail.sat_orderclueid}}' />
+    <view style="height: 140rpx;" />
+</Yl_FunTabs>
+
+<Popup sheetTitle='{{sheetTitle}}'>
+    <view>
+        <followAction id='followAction' sat_orderclueid='{{sat_orderclueid}}' bind:endChange='endFollow' />
+    </view>
+</Popup>
+
+<!-- 底部 -->
+<Yl_Tabbar list='{{tabbarList}}' bind:callback="tabbarOnClick" />

+ 278 - 0
packageA/saleClue/index.js

@@ -0,0 +1,278 @@
+const _Http = getApp().globalData.http,
+    getHeight = require("../../utils/getRheRemainingHeight");
+Page({
+
+    /**
+     * 页面的初始数据
+     */
+    data: {
+        navList: [{
+            label: "全部",
+            icon: "icon-webxialaxuanxiangjiantou",
+            color: "",
+            width: "",
+            id: "1"
+        },{
+            label: "排序",
+            icon: "icon-shengxu",
+            color: "",
+            width: "",
+            id: "sort"
+        }, {
+            label: "筛选",
+            icon: "icon-shaixuan",
+            color: "",
+            width: "",
+            id: "2"
+        }],
+        classShow: false,
+        classActions: [],
+        content: {
+            "isAll":0,
+            "nocache": true,
+            "version": 1,
+            "pageNumber": 1,
+            "pageSize": 20,
+            "where": {
+                "condition": "",
+            },
+            "sort": []
+        },
+        filter: {
+            show: false,
+            status: ['新建', '发布', '结束'], //状态项
+            statusActive: "",
+            startdate: "",
+            enddate: ""
+        }
+    },
+    onLoad(options) {
+        this.getList()
+        this.getTypeList()
+        this.getClueArea()
+    },
+    /* 获取列表 */
+    getList(init = false, data) {
+        if (init.detail != undefined) init = init.detail;
+        let content = this.data.content;
+        if (init) content.pageNumber = 1;
+        if (content.pageNumber > content.pageTotal) return;
+        if (data) {
+            content.where.status = data.statusActive;
+        }
+        _Http.basic({
+            "id": 20221101094502,
+            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.progress = v.stage / v.totalstage * 100;
+                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();
+            this.getTags();
+        })
+    },
+    /* 获取线索范围 */
+    getTypeList () {
+        _Http.basic({
+            "classname": "sysmanage.develop.optiontype.optiontype",
+            "method": "optiontypeselect",
+            "content": {
+                "typename":'dataarea'
+            }
+        }).then(res => {
+            console.log("状态列表", res)
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            })
+            let classActions = res.data.map(item => {
+                return {
+                    name:item.value,
+                    index:item.remarks
+                }
+            })
+            this.setData({
+                classActions: classActions
+            });
+            console.log(this.data.classActions);
+            this.setListHeight();
+        })
+    },
+    /* 获取线索状态 */
+    getClueArea () {
+        _Http.basic({
+            "classname": "sysmanage.develop.optiontype.optiontype",
+            "method": "optiontypeselect",
+            "content": {
+                "typename":'clueprivate'
+            }
+        }).then(res => {
+            console.log("线索范围", res)
+            if (res.msg != '成功') return wx.showToast({
+                title: res.data,
+                icon: "none"
+            })
+            let status = res.data.map(item => {
+                return item.value
+            })
+            this.setData({
+                'filter.status': status
+            });
+            console.log(this.data.filter.type);
+            this.setListHeight();
+        })
+    },
+    /* 处理搜索 */
+    onSearch({
+        detail
+    }) {
+        this.setData({
+            "content.where.condition": detail
+        });
+        this.getList(true);
+    },
+    /* 获取列表标签 */
+    getTags() {
+        let list = this.data.list,
+            ownerids = list.map(v => v.sat_orderclueid);
+        _Http.basic({
+            "id": 20221018102001,
+            "content": {
+                nocache: true,
+                "ownertable": "sat_orderclue",
+                ownerids
+            }
+        }).then(res => {
+            console.log("标签", res)
+            for (let key in res.data) {
+                let index = list.findIndex(v => v.sat_orderclueid == key);
+                list[index].tags = res.data[key]
+            };
+            this.setData({
+                list
+            })
+        })
+    },
+    /* 去添加 */
+    openType() {
+        wx.navigateTo({
+          url: '/packageA/saleClue/addClue',
+        })
+    },
+    /* 选择添加报价形式 */
+    typeSelect({
+        detail
+    }) {
+        wx.navigateTo({
+            url: detail.name == '项目报价' ? '/packageA/offers/addProjectOffer' : '/packageA/offers/addSetclientOffer',
+        });
+        this.typeCancel();
+    },
+    onReady() {
+        this.setListHeight();
+    },
+    setListHeight() {
+        getHeight.getHeight('.total', this).then(res => {
+            if (this.data.listHeight != res)
+                this.setData({
+                    listHeight: res
+                })
+        });
+    },
+    /* 顶部条件导航回调 */
+    navClick({
+        detail
+    }) {
+        switch (detail.id) {
+            case '1':
+                this.setData({
+                    classShow: true
+                })
+                break;
+            case '2':
+                this.setData({
+                    'filter.show': true
+                })
+                break;
+        }
+    },
+    classClose() {
+        this.setData({
+            classShow: false
+        })
+    },
+    classSelect({
+        detail
+    }) {
+        if (this.data.content.type == detail.index) return this.classClose();
+        this.setData({
+            "content.type": detail.index,
+            'navList[0].label': detail.name
+        })
+        this.classClose();
+        this.getList(true)
+    },
+    /* 筛选状态选择 */
+    selectStatus(e) {
+        const {
+            item
+        } = e.currentTarget.dataset;
+        this.setData({
+            "filter.statusActive": this.data.filter.statusActive == item ? "" : item
+        })
+    },
+    /* 筛选状态选择 */
+    typeStatus(e) {
+        const {
+            item
+        } = e.currentTarget.dataset;
+        this.setData({
+            "filter.typeActive": this.data.filter.typeActive == item ? "" : item
+        })
+    },
+    /* 处理筛选 */
+    handleFilter({
+        detail
+    }) {
+        const data = this.data.filter;
+        switch (detail) {
+            case 'confirm':
+                this.setData({
+                    'filter.show': false
+                });
+                this.getList(true, data);
+                break;
+            case 'reset':
+                this.setData({
+                    'filter.statusActive': "",
+                    'filter.typeActive': "",
+                    'filter.startdate': "",
+                    'filter.enddate': "",
+                });
+                this.getList(true, this.data.filter)
+                break;
+            case 'close':
+                this.setData({
+                    'filter.show': false
+                });
+                break;
+        }
+    },
+    onShareAppMessage() {
+
+    }
+})

+ 6 - 0
packageA/saleClue/index.json

@@ -0,0 +1,6 @@
+{
+    "usingComponents": {
+        "list":"./modules/list/list"
+    },
+    "navigationBarTitleText": "销售线索"
+}

+ 16 - 0
packageA/saleClue/index.scss

@@ -0,0 +1,16 @@
+@import "../../components/Yl_filtrate/groud.scss";
+
+page {
+    height: 100vh;
+    overflow: hidden;
+}
+
+.total {
+    height: 64rpx;
+    line-height: 64rpx;
+    font-size: 24rpx;
+    font-family: PingFang SC-Regular, PingFang SC;
+    color: #666666;
+    background: #F4F5F7;
+    padding-left: 30rpx;
+}

+ 23 - 0
packageA/saleClue/index.wxml

@@ -0,0 +1,23 @@
+<Yl_nav search list='{{navList}}' sort='{{content.sort}}' bind:onClick='navClick' bindonSearch="onSearch" />
+<!-- 显示类型 -->
+<van-action-sheet show="{{ classShow }}" actions="{{ classActions }}" cancel-text="取消" bind:cancel="classClose" bind:select="classSelect" />
+<view class="total">共{{content.total}}个</view>
+
+<My_listBox id='ListBox' height="{{listHeight}}" bind:getlist='getList'>
+    <list list='{{list}}' />
+    <view style="height: 80rpx;" />
+</My_listBox>
+<!-- 筛选条件 -->
+<Yl_filtrate show="{{filter.show}}" bind:handle="handleFilter">
+    <view class="groud">
+        <view class="label">
+            线索状态
+        </view>
+        <view class="content">
+            <van-button custom-class='but {{filter.statusActive==item?"active":""}}' wx:for="{{filter.status}}" wx:key="item" bindtap="selectStatus" data-item="{{item}}">{{item}}</van-button>
+        </view>
+    </view>
+</Yl_filtrate>
+
+<!-- 浮动按钮 -->
+<Yl_FloatingButton bindtap="openType" />

+ 121 - 0
packageA/saleClue/modules/follow/follow.js

@@ -0,0 +1,121 @@
+const _Http = getApp().globalData.http
+Component({
+    /**
+     * 组件的属性列表
+     */
+    properties: {
+        rowData: Object
+    },
+    options: {
+        addGlobalClass:true
+    },
+
+    /**
+     * 组件的初始数据
+     */
+    data: {
+        isdesc:1,
+        showWhere:'所有日期',
+        followList:[],
+        timeRangeShow:false,
+        whereType: {
+            value: "start",
+            list: {
+                "start": "",
+                "end": ""
+            }
+        },
+        where:{}
+    },
+    ready () {
+        setTimeout(() =>{
+            this.getFollowDetail()
+        },1000)
+    },
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        getFollowDetail () {
+            _Http.basic({
+                "classname": "webmanage.saletool.orderclue.publicclue.PublicClue",
+                "method": "getFollowList",
+                "content": {
+                    "nocache":true,
+                    "sat_orderclueid": this.properties.rowData.sat_orderclueid,
+                    "isdesc": this.data.isdesc,
+                    "where":this.data.where
+                }
+            }).then(res => {
+                console.log(res,'跟进');
+                this.setData({
+                    followList:res.data
+                })
+            })
+        },
+        openSelectDate () {
+
+        },
+        changeIsdesc () {
+            this.setData({
+                isdesc: this.data.isdesc == 1 ? 0 : 1
+            });
+            this.getFollowDetail()
+        },
+        /* 打开选择时间 */
+        openSelectDate() {
+            this.setData({
+                timeRangeShow: true
+            })
+        },
+        /* 确定时间范围 */
+        determineScope() {
+            const {
+                list
+            } = this.data.whereType;
+            this.setData({
+                "where": list,
+                showWhere: list.start + '~' + list.end,
+                timeRangeShow: false
+            });
+            this.getFollowDetail();
+        },
+        /* 得到选择时间 */
+        getDate({
+            detail
+        }) {
+            let obj = this.data.whereType;
+            obj.list[obj.value] = detail;
+            this.setData({
+                whereType: obj
+            })
+        },
+        /* 选择日期类型 */
+        selectDateType(e) {
+            const {
+                name
+            } = e.target.dataset;
+            this.setData({
+                "whereType.value": name
+            })
+        },
+        /* 查看所有日期 */
+        toSeeAll() {
+            this.setData({
+                showWhere: "所有日期"
+            })
+            this.timeRangeClose();
+            this.getFollowDetail();
+        },
+        /* 关闭时间范围选择 */
+        timeRangeClose() {
+            this.setData({
+                timeRangeShow: false,
+                "where": {
+                    "start": "",
+                    "end": ""
+                }
+            })
+        },
+    }
+})

+ 6 - 0
packageA/saleClue/modules/follow/follow.json

@@ -0,0 +1,6 @@
+{
+    "component": true,
+    "usingComponents": {
+        "My_datePicker": "/components/My_datePicker/index"
+    }
+}

+ 67 - 0
packageA/saleClue/modules/follow/follow.scss

@@ -0,0 +1,67 @@
+@import "../../../../pages/submission/wxss/detePicker.scss";
+.filtrate {
+    display: flex;
+    justify-content: space-between;
+    width: 100vw;
+    height: 90rpx;
+    padding: 0 30rpx;
+    box-sizing: border-box;
+    margin-bottom: -20rpx;
+
+    .date {
+        display: flex;
+        align-items: center;
+        font-size: 28rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #333333;
+    }
+
+    .sort {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 90rpx;
+        width: 90rpx;
+    }
+}
+
+.box {
+    width: 100vw;
+    padding: 20rpx 30rpx;
+    background-color: #ffffff;
+    box-sizing: border-box;
+    margin-top: 20rpx;
+    word-break: break-all;
+    white-space: pre-wrap;
+
+    .time {
+        height: 34rpx;
+        font-size: 24rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #666666;
+    }
+
+    .content {
+        font-size: 28rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #999999;
+        margin-top: 20rpx;
+
+        text {
+            color: #333333;
+        }
+    }
+
+    .explain {
+        background: #F5F5F5;
+        border-radius: 16rpx;
+        padding: 20rpx 30rpx;
+        font-size: 28rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #333333;
+        margin-top: 20rpx;
+
+    }
+
+
+}

+ 33 - 0
packageA/saleClue/modules/follow/follow.wxml

@@ -0,0 +1,33 @@
+<view class="filtrate">
+    <view class="date" bindtap="openSelectDate">{{showWhere}}
+        <van-icon style="margin-left: 8rpx;" name="arrow-down" />
+    </view>
+    <view class="sort" bindtap="changeIsdesc">
+        <text class="iconfont {{ isdesc==1?'icon-jiangxu':'icon-shengxu1' }}" />
+    </view>
+</view>
+<navigator url="#" class="box" wx:for="{{followList}}">
+    <view class="time">{{item.createdate}}</view>
+    <view class="content">由经销商端<text style="color: var(--warning);"> {{item.createby}} </text>开始跟进<block wx:if="{{item.followupmode}}">,跟进方式:<text>{{item.followupmode}}</text></block><block wx:if="{{item.logtype}}">,跟进结果:<text>{{item.logtype}}</text></block><block wx:if="{{item.content}}">,跟进内容:</block></view>
+    <view class="explain" wx:if="{{item.content}}">{{item.content}}</view>
+</navigator>
+<My_empty wx:if="{{followList.length==0}}" />
+<view style="height: 140rpx;" />
+
+<van-action-sheet show="{{ timeRangeShow }}" bind:close='timeRangeClose'>
+    <view class="detePickerHeader">
+        <text catchtap="toSeeAll">所有日期</text>
+        <view class="type" catchtap="selectDateType">
+            <view class="option {{whereType.value=='start'?'active-op':''}}" data-name="start">
+                <view data-name="start">开始</view>
+                <view data-name="start" class="time">{{whereType.list.start||'开始时间'}}</view>
+            </view>
+            <view class="option {{whereType.value=='end'?'active-op':''}}" data-name="end">
+                <view data-name="end">结束</view>
+                <view data-name="end" class="time">{{whereType.list.end||'结束时间'}}</view>
+            </view>
+        </view>
+        <text catchtap="determineScope">确定</text>
+    </view>
+    <My_datePicker bind:getDate='getDate' />
+</van-action-sheet>

+ 143 - 0
packageA/saleClue/modules/followAction/followAction.js

@@ -0,0 +1,143 @@
+const deleteMark = require("../../../../utils/deleteMark"),
+    getTime = require("../../../../utils/getTime"),
+    _Http = getApp().globalData.http;
+Component({
+    /**
+     * 组件的属性列表
+     */
+    properties: {
+        endChange: Function,
+        sat_orderclueid: Number
+    },
+
+    /**
+     * 组件的初始数据
+     */
+    data: {
+        actionShow: false,
+        time: "",
+        actions: [{
+            name: '电话沟通',
+        }, {
+            name: '当面沟通',
+        }, {
+            name: '微信沟通',
+        }],
+        "content": {
+            "content": "",
+            "followupmode": "",
+            "logtype": "",
+            "competitor": ""
+        },
+        disabled: true,
+        loading: false
+    },
+    ready () {
+        this.getFollowType()
+    },
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        submit() {
+            if (this.data.disabled || this.data.loading) return;
+            let content = this.data.content;
+            content.sat_orderclueid = this.data.sat_orderclueid;
+            this.setData({
+                loading: true
+            })
+            _Http.basic({
+                "classname": "saletool.orderclue.web.orderclue",
+                "method": "addFollowUpLog",
+                content
+            }).then(res => {
+                console.log(res)
+                this.setData({
+                    loading: false
+                })
+                if (res.msg != '成功') return wx.showToast({
+                    title: res.msg,
+                    icon: "none"
+                });
+                wx.showToast({
+                    title: '保存成功!',
+                })
+                setTimeout(() => {
+                    this.setData({
+                        content: {
+                            "content": "",
+                            "followupmode": "",
+                            "logtype": "",
+                            "competitor": ""
+                        }
+                    })
+                    this.triggerEvent("endChange");
+                }, 300);
+            })
+        },
+        /* 获取跟进方式 */
+        async getFollowType () {
+            let res = await _Http.basic({
+                "classname": "sysmanage.develop.optiontype.optiontype",
+                "method": "optiontypeselect",
+                "content": {
+                    "typename":'followupmode'
+                }
+            })
+            let Arr = res.data.map(item => {
+                return {
+                    name:item.value
+                }
+            })
+            this.setData({
+                actions: Arr
+            })
+        },
+        /* 打开选择跟进方式 */
+        selectWay() {
+            this.setData({
+                actionShow: !this.data.actionShow
+            })
+        },
+        /* 选择方式 */
+        onSelect(e) {
+            this.setData({
+                "content.followupmode": e.detail.name
+            })
+            this.isDisabled();
+        },
+        /* 选择结果 */
+        changeType(e) {
+            if (e.target.dataset.name) this.setData({
+                'content.logtype': e.target.dataset.name
+            })
+            this.isDisabled();
+        },
+        /* 输入框输入内容 */
+        inputChange(e) {
+            let text = e.type == 'input' ? e.detail.value : e.detail;
+            text = deleteMark.queryStr(text);
+
+            const {
+                label
+            } = e.currentTarget.dataset;
+
+            this.setData({
+                ["content." + label]: text
+            })
+            this.isDisabled();
+        },
+        isDisabled() {
+            let data = this.data.content,
+                disabled = (data.followupmode != '' && data.content != '' && data.logtype != '') ? false : true;
+            this.setData({
+                disabled
+            })
+        },
+        updateTime() {
+            this.setData({
+                time: getTime.formatTime(new Date(), "-")
+            })
+        }
+    }
+})

+ 4 - 0
packageA/saleClue/modules/followAction/followAction.json

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

+ 41 - 0
packageA/saleClue/modules/followAction/followAction.scss

@@ -0,0 +1,41 @@
+@import "../../../../pages/threadedTree/modules/insert/insert.scss";
+@import "../../../../pages/threadedTree/modules/insert/insert.scss";
+
+@import "../../../../pages/threadedTree/details/modules/handOver/index.scss";
+
+.results {
+    display: flex;
+    justify-content: space-between;
+    padding: 0 30rpx;
+    width: 100vw;
+    box-sizing: border-box;
+    margin-top: 20rpx;
+
+    >view {
+        width: 220rpx;
+        height: 90rpx;
+        text-align: center;
+        line-height: 90rpx;
+        background: #FFFFFF;
+        border-radius: 16rpx;
+        border: 1px solid #CCCCCC;
+        font-size: 28rpx;
+        font-family: PingFang SC-Regular, PingFang SC;
+        color: #666666;
+    }
+
+    .op {
+        border-color: #3874F6;
+        background: #3874F6;
+        color: #FFFFFF;
+    }
+}
+
+.time {
+    height: 40rpx;
+    font-size: 28rpx;
+    font-family: PingFang SC-Regular, PingFang SC;
+    color: #333333;
+    padding-left: 30rpx;
+    margin-top: 20rpx;
+}

+ 65 - 0
packageA/saleClue/modules/followAction/followAction.wxml

@@ -0,0 +1,65 @@
+<view class="box">
+    <view class="label"><text>*</text>跟进时间:</view>
+    <view class="time">{{time}}</view>
+    <view class="label"><text>*</text>本次跟进方式:</view>
+    <view class="selector" bindtap="selectWay">
+        <view>{{content.followupmode?content.followupmode:'请选择'}}</view>
+        <van-icon name="arrow-down" />
+    </view>
+
+    <view class="label"><text>*</text>本次跟进结果:</view>
+    <view class="results" bindtap="changeType">
+        <view class="{{content.logtype=='继续跟进'?'op':''}}" data-name="继续跟进">继续跟进</view>
+        <view class="{{content.logtype=='预约到店'?'op':''}}" data-name="预约到店">预约到店</view>
+        <view class="{{content.logtype=='互加微信'?'op':''}}" data-name="互加微信">互加微信</view>
+    </view>
+    <view class="label"><text>*</text>本次跟进内容</view>
+    <textarea value='{{content.content}}' class="textarea selector" data-label="content" bind:input="inputChange" placeholder="请描述跟进情况及内容" />
+</view>
+
+
+<view style="height: 140rpx;" />
+<view class="footer-but">
+    <van-button custom-class='button' disabled='{{disabled}}' bindtap="submit" loading='{{loading}}' loading-text="保存中...">确定</van-button>
+</view>
+
+<van-action-sheet show="{{ actionShow }}" actions="{{ actions }}" cancel-text="取消" bind:close="selectWay" bind:cancel='selectWay' bind:select="onSelect" />
+
+<wxs module="text">
+    module.exports.type = function (str) {
+        var text = '';
+        switch (str) {
+            case "跟进":
+                text = '本次跟进内容:'
+                break;
+            case "成交":
+                text = '添加备注:'
+                break;
+            case "丢单":
+                text = '丢单原因:'
+                break;
+            case "无效":
+                text = '无效原因:'
+                break;
+        }
+        return text
+    }
+    module.exports.typeNote = function (str) {
+        var text = '';
+        switch (str) {
+            case "跟进":
+                text = '请描述跟进情况及内容'
+                break;
+            case "成交":
+                text = '请填写备注'
+                break;
+            case "丢单":
+                text = '请填写丢单原因'
+                break;
+            case "无效":
+                text = '请填写无效原因'
+                break;
+        }
+        return text
+    }
+</wxs>

+ 29 - 0
packageA/saleClue/modules/list/list.js

@@ -0,0 +1,29 @@
+// packageA/activity/modules/list/index.js
+Component({
+    /**
+     * 组件的属性列表
+     */
+    properties: {
+        list:Array
+    },
+
+    /**
+     * 组件的初始数据
+     */
+    data: {
+
+    },
+
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        distribution ({
+            currentTarget
+        }) {
+            wx.navigateTo({
+              url: `/packageA/publicClue/distribution?data=${JSON.stringify(currentTarget.dataset.item)}`,
+            })
+        }
+    }
+})

+ 4 - 0
packageA/saleClue/modules/list/list.json

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

+ 58 - 0
packageA/saleClue/modules/list/list.scss

@@ -0,0 +1,58 @@
+.offer-list {
+    width: 100%;
+    padding: 20rpx 30rpx;
+    box-sizing: border-box;
+    background-color: #fff;
+    border-bottom: 1rpx solid #ddd;
+    font-family: PingFang SC-Regular, PingFang SC;
+    position: relative;
+    .action {
+        position: absolute;
+        right: 0;
+        bottom: 30rpx;
+    }
+    .title {
+        position: relative;
+        display: flex;
+        height: 42rpx;
+        align-items: center;
+
+        >text {
+            display: inline-block;
+            width: 80%;
+            font-size: 30rpx;
+            color: #333333;
+        }
+
+        .status {
+            position: absolute;
+            right: -30rpx;
+            width: 132rpx;
+            height: 40rpx;
+            border-radius: 20rpx 0px 0px 20rpx;
+            box-sizing: border-box;
+            padding-left: 30rpx;
+            line-height: 40rpx;
+            font-size: 24rpx;
+            font-family: PingFang SC-Regular, PingFang SC;
+            color: #FFFFFF;
+        }
+    }
+
+    .exp {
+        height: 34rpx;
+        font-size: 24rpx;
+        color: #666;
+        margin-top: 8rpx;
+
+        text {
+            color: #333333;
+        }
+    }
+}
+
+.line-1 {
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}

+ 29 - 0
packageA/saleClue/modules/list/list.wxml

@@ -0,0 +1,29 @@
+    <!--packageA/activity/modules/list/index.wxml-->
+    <navigator class="offer-list" url="/packageA/saleClue/detail?sat_orderclueid={{item.sat_orderclueid}}" wx:for="{{list}}" wx:key="item.sat_orderclueid">
+    <view class="title">
+        <text class="line-1">{{item.enterprisename_customer}}</text>
+        <view class="status" style="background-color: {{backColor.getColor(item.status)}};">{{item.status}}</view>
+    </view>
+    <view class="exp line-1">省市县:{{item.province?item.province+item.city+item.county:"暂无"}}</view>
+    <view class="exp line-1">联系人:<text>{{item.name}}</text></view>
+    <view class="exp line-1">手机号:<text>{{item.phonenumber || '--'}}</text></view>
+    <view class="exp line-1">来源:<text>{{item.cluesource ? item.cluesource : '--'}}</text></view>
+</navigator>
+
+<My_empty wx:if="{{list.length == 0}}" />
+
+<wxs module="backColor">
+    module.exports.getColor = function(status) {
+        var color = null;
+        if (status == '待跟进') {
+            color = '#FA8C16';
+        } else if (status == '跟进中') {
+            color = '#52C41A';
+        } else if (status == '已转化') {
+            color = '#F60909';
+        } else {
+            color = '#BBBBBB';
+        };
+        return color
+    }
+</wxs>