中扬CRM客户关系管理系统
#
Junjie
2023-08-31 2f4b656c91d9410d3b0ba46d45ae6f5b900a9e76
#
5个文件已修改
226 ■■■■■ 已修改文件
src/main/java/com/zy/crm/manager/controller/ContractController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/crm/manager/entity/Contract.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ContractMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/contract/contract.js 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/contract/contract.html 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/crm/manager/controller/ContractController.java
@@ -83,7 +83,9 @@
    @RequestMapping(value = "/contract/add/auth")
    @ManagerAuth
    public R add(Contract contract) {
        contract.setCreateBy(getUserId());
        contract.setUserId(getUserId());
        //创建人员部门
        contract.setDeptId(getDeptId());
        contract.setCreateTime(new Date());
        contractService.insert(contract);
        return R.ok();
src/main/java/com/zy/crm/manager/entity/Contract.java
@@ -93,8 +93,8 @@
     * 创建人员
     */
    @ApiModelProperty(value= "创建人员")
    @TableField("create_by")
    private Long createBy;
    @TableField("user_id")
    private Long userId;
    /**
     * 更新人员
@@ -178,9 +178,16 @@
    @ApiModelProperty(value= "合同编号")
    private String serial;
    /**
     * 部门ID
     */
    @ApiModelProperty(value= "创建人员")
    @TableField("dept_id")
    private Long deptId;
    public Contract() {}
    public Contract(Long id, String customer, String address, String company, String companyAddress, String taxNum, String bank, String bankNum, Date createTime, Date updateTime, Long createBy, Long updateBy, String filepath, String city, String shippingAddress, String shippingName, String shippingPhone, Double price, String email, String name, Integer status, String memo, String boss, String serial) {
    public Contract(Long id, String customer, String address, String company, String companyAddress, String taxNum, String bank, String bankNum, Date createTime, Date updateTime, Long userId, Long updateBy, String filepath, String city, String shippingAddress, String shippingName, String shippingPhone, Double price, String email, String name, Integer status, String memo, String boss, String serial, Long deptId) {
        this.id = id;
        this.customer = customer;
        this.address = address;
@@ -191,7 +198,7 @@
        this.bankNum = bankNum;
        this.createTime = createTime;
        this.updateTime = updateTime;
        this.createBy = createBy;
        this.userId = userId;
        this.updateBy = updateBy;
        this.filepath = filepath;
        this.city = city;
@@ -205,6 +212,7 @@
        this.memo = memo;
        this.boss = boss;
        this.serial = serial;
        this.deptId = deptId;
    }
    //    Contract contract = new Contract(
@@ -243,9 +251,9 @@
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public String getCreateBy$() {
    public String getUserId$() {
        UserService userService = SpringUtils.getBean(UserService.class);
        User user = userService.selectById(this.createBy);
        User user = userService.selectById(this.userId);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getNickname());
        }
src/main/resources/mapper/ContractMapper.xml
@@ -14,7 +14,7 @@
        <result column="bank_num" property="bankNum" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="create_by" property="createBy" />
        <result column="user_id" property="userId" />
        <result column="update_by" property="updateBy" />
        <result column="filepath" property="filepath" />
        <result column="city" property="city" />
@@ -28,6 +28,7 @@
        <result column="memo" property="memo" />
        <result column="boss" property="boss" />
        <result column="serial" property="serial" />
        <result column="dept_id" property="deptId" />
    </resultMap>
src/main/webapp/static/js/contract/contract.js
@@ -1,19 +1,77 @@
var pageCurr;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).use(['table','laydate', 'form', 'admin'], function(){
}).use(['table', 'laydate', 'form', 'admin', 'tree', 'dropdown'], function () {
    var table = layui.table;
    var $ = layui.jquery;
    var layer = layui.layer;
    var layDate = layui.laydate;
    var form = layui.form;
    var admin = layui.admin;
    var dropdown = layui.dropdown;
    var tree = layui.tree;
    $('#organization').html(localStorage.getItem('nickname') + ' <i class="layui-icon">&#xe61a;</i>');
    // 部门人员 筛选
    dropdown.render({
        elem: '#organization'
        , content: ['<div id="organizationTree" style="height: calc(100vh - 525px);border: none"></div>'].join('')
        , style: 'width: 370px; height: 350px; padding: 0 15px; box-shadow: 1px 1px 30px rgb(0 0 0 / 12%);overflow: scroll;'
        , ready: function () {
            loadTree();
        }
    });
    // 树形图
    var organizationTree;
    window.loadTree = function (condition) {
        var loadIndex = layer.load(2);
        $.ajax({
            url: baseUrl + "/dept/user/tree/auth",
            headers: {'token': localStorage.getItem('token')},
            data: {
                'condition': condition
            },
            method: 'POST',
            success: function (res) {
                layer.close(loadIndex);
                if (res.code === 200) {
                    organizationTree = tree.render({
                        elem: '#organizationTree',
                        id: 'organizationTree',
                        onlyIconControl: true,
                        data: res.data,
                        click: function (obj) {
                            treeCond = {
                                key: obj.data.key,
                                val: obj.data.id
                            }
                            $('#organization').html(obj.data.title + ' <i class="layui-icon">&#xe61a;</i>');
                            $('#organizationTree').find('.ew-tree-click').removeClass('ew-tree-click');
                            $(obj.elem).children('.layui-tree-entry').addClass('ew-tree-click');
                            clearFormVal($('#search-box'));
                            tableIns.reload({
                                where: {[obj.data.key]: obj.data.id},
                                page: {curr: 1}
                            });
                        }
                    });
                    treeData = res.data;
                } else if (res.code === 403) {
                    top.location.href = baseUrl + "/";
                } else {
                    layer.msg(res.msg)
                }
            }
        })
    }
    // 数据渲染
    tableIns = table.render({
        elem: '#contract',
        headers: {token: localStorage.getItem('token')},
        url: baseUrl+'/contract/list/auth',
        url: baseUrl + '/contract/list/auth',
        page: true,
        limit: 15,
        limits: [15, 30, 50, 100, 200, 500],
@@ -23,18 +81,18 @@
        cols: [[
            {type: 'checkbox'}
            // ,{field: 'id', align: 'center',title: '#ID'}
            ,{field: 'serial', align: 'center',title: '合同编号'}
            ,{field: 'name', align: 'center',title: '合同名称'}
            ,{field: 'customer', align: 'center',title: '甲方'}
            ,{field: 'company', align: 'center',title: '公司名称'}
            ,{field: 'status$', align: 'center',title: '状态'}
            ,{field: 'createBy$', align: 'center',title: '添加人员'}
            ,{field: 'createTime$', align: 'center',title: '添加时间'}
            ,{field: 'updateBy$', align: 'center',title: '修改人员'}
            ,{field: 'updateTime$', align: 'center',title: '修改时间'}
            ,{field: 'memo', align: 'center',title: '备注'}
            , {field: 'serial', align: 'center', title: '合同编号'}
            , {field: 'name', align: 'center', title: '合同名称'}
            , {field: 'customer', align: 'center', title: '甲方'}
            , {field: 'company', align: 'center', title: '公司名称'}
            , {field: 'status$', align: 'center', title: '状态'}
            , {field: 'userId$', align: 'center', title: '添加人员'}
            , {field: 'createTime$', align: 'center', title: '添加时间'}
            , {field: 'updateBy$', align: 'center', title: '修改人员'}
            , {field: 'updateTime$', align: 'center', title: '修改时间'}
            , {field: 'memo', align: 'center', title: '备注'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:400}
            , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 400}
        ]],
        request: {
            pageName: 'curr',
@@ -51,11 +109,11 @@
        response: {
            statusCode: 200
        },
        done: function(res, curr, count) {
        done: function (res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl+"/";
                top.location.href = baseUrl + "/";
            }
            pageCurr=curr;
            pageCurr = curr;
            limit();
        }
    });
@@ -63,7 +121,7 @@
    // 监听排序事件
    table.on('sort(contract)', function (obj) {
        var searchData = {};
        $.each($('#search-box [name]').serializeArray(), function() {
        $.each($('#search-box [name]').serializeArray(), function () {
            searchData[this.name] = this.value;
        });
        searchData['orderByField'] = obj.field;
@@ -77,23 +135,23 @@
    // 监听头工具栏事件
    table.on('toolbar(contract)', function (obj) {
        var checkStatus = table.checkStatus(obj.config.id).data;
        switch(obj.event) {
        switch (obj.event) {
            case 'addData':
                showEditModel();
                break;
            case 'deleteData':
               if (checkStatus.length === 0) {
                   layer.msg('请选择要删除的数据', {icon: 2});
                   return;
               }
               del(checkStatus.map(function (d) {
                   return d.id;
               }));
               break;
                if (checkStatus.length === 0) {
                    layer.msg('请选择要删除的数据', {icon: 2});
                    return;
                }
                del(checkStatus.map(function (d) {
                    return d.id;
                }));
                break;
            case 'exportData':
                admin.confirm('确定导出Excel吗', {shadeClose: true}, function(){
                    var titles=[];
                    var fields=[];
                admin.confirm('确定导出Excel吗', {shadeClose: true}, function () {
                    var titles = [];
                    var fields = [];
                    obj.config.cols[0].map(function (col) {
                        if (col.type === 'normal' && col.hide === false && col.toolbar == null) {
                            titles.push(col.title);
@@ -101,7 +159,7 @@
                        }
                    });
                    var exportData = {};
                    $.each($('#search-box [name]').serializeArray(), function() {
                    $.each($('#search-box [name]').serializeArray(), function () {
                        exportData[this.name] = this.value;
                    });
                    var param = {
@@ -109,18 +167,18 @@
                        'fields': fields
                    };
                    $.ajax({
                        url: baseUrl+"/contract/export/auth",
                        url: baseUrl + "/contract/export/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: JSON.stringify(param),
                        dataType:'json',
                        contentType:'application/json;charset=UTF-8',
                        dataType: 'json',
                        contentType: 'application/json;charset=UTF-8',
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll();
                            if (res.code === 200) {
                                table.exportFile(titles,res.data,'xls');
                                table.exportFile(titles, res.data, 'xls');
                            } else if (res.code === 403) {
                                top.location.href = baseUrl+"/";
                                top.location.href = baseUrl + "/";
                            } else {
                                layer.msg(res.msg, {icon: 2})
                            }
@@ -132,7 +190,7 @@
    });
    // 监听行工具事件
    table.on('tool(contract)', function(obj){
    table.on('tool(contract)', function (obj) {
        var data = obj.data;
        switch (obj.event) {
            case 'edit':
@@ -173,19 +231,19 @@
                form.on('submit(editSubmit)', function (data) {
                    var loadIndex = layer.load(2);
                    $.ajax({
                        url: baseUrl+"/contract/"+(mData?'update':'add')+"/auth",
                        url: baseUrl + "/contract/" + (mData ? 'update' : 'add') + "/auth",
                        headers: {'token': localStorage.getItem('token')},
                        data: data.field,
                        method: 'POST',
                        success: function (res) {
                            layer.close(loadIndex);
                            if (res.code === 200){
                            if (res.code === 200) {
                                layer.close(dIndex);
                                layer.msg(res.msg, {icon: 1});
                                tableReload();
                            } else if (res.code === 403){
                                top.location.href = baseUrl+"/";
                            }else {
                            } else if (res.code === 403) {
                                top.location.href = baseUrl + "/";
                            } else {
                                layer.msg(res.msg, {icon: 2});
                            }
                        }
@@ -232,7 +290,7 @@
                            a.click();
                            // 清理临时资源
                            setTimeout(function() {
                            setTimeout(function () {
                                window.URL.revokeObjectURL(url);
                                document.body.removeChild(a);
                            }, 100);
@@ -255,10 +313,10 @@
            type: 2,
            title: '合同明细',
            maxmin: true,
            area: [top.detailWidth,top.detailHeight],
            area: [top.detailWidth, top.detailHeight],
            shadeClose: false,
            content: '../contractSales/contractSales.html?contractId=' + mData.id,
            success: function(layero, index){
            success: function (layero, index) {
            }
        });
    }
@@ -266,24 +324,24 @@
    //上传合同
    function upload(data) {
        if (data.filepath == '' || data.filepath == null) {
            layer.confirm('是否上传合同?', function(){
            layer.confirm('是否上传合同?', function () {
                $("#uploadQuote").click()
            });
        }else {
            layer.confirm('已上传合同,是否继续覆盖上传?', function(){
        } else {
            layer.confirm('已上传合同,是否继续覆盖上传?', function () {
                $("#uploadQuote").click()
            });
        }
        $("#uploadQuote").on("change",(evt) => {
        $("#uploadQuote").on("change", (evt) => {
            var files = evt.target.files;
            if(files==null || files.length==0){
            if (files == null || files.length == 0) {
                alert("No files wait for import");
                return;
            }
            let name = files[0].name;
            let suffixArr = name.split("."), suffix = suffixArr[suffixArr.length-1];
            let suffixArr = name.split("."), suffix = suffixArr[suffixArr.length - 1];
            // if(suffix!="xlsx"){
            //     alert("Currently only supports the import of xlsx files");
            //     return;
@@ -301,11 +359,11 @@
                contentType: false,
                success: function (res) {
                    if (res.code == 200) {
                        layer.msg('上传成功',{time:1000},() => {
                        layer.msg('上传成功', {time: 1000}, () => {
                            parent.location.reload()
                        })
                    }else{
                        layer.msg(res.msg,{time:1000},() => {
                    } else {
                        layer.msg(res.msg, {time: 1000}, () => {
                            parent.location.reload()
                        })
                    }
@@ -317,7 +375,7 @@
    //下载合同
    function download(data) {
        $.ajax({
            url: baseUrl+"/contract/download/auth",
            url: baseUrl + "/contract/download/auth",
            headers: {'token': localStorage.getItem('token')},
            data: data,
            method: 'GET',
@@ -341,7 +399,7 @@
                a.click();
                // 清理临时资源
                setTimeout(function() {
                setTimeout(function () {
                    window.URL.revokeObjectURL(url);
                    document.body.removeChild(a);
                }, 100);
@@ -358,17 +416,17 @@
            layer.close(i);
            var loadIndex = layer.load(2);
            $.ajax({
                url: baseUrl+"/contract/delete/auth",
                url: baseUrl + "/contract/delete/auth",
                headers: {'token': localStorage.getItem('token')},
                data: {ids: ids},
                method: 'POST',
                success: function (res) {
                    layer.close(loadIndex);
                    if (res.code === 200){
                    if (res.code === 200) {
                        layer.msg(res.msg, {icon: 1});
                        tableReload();
                    } else if (res.code === 403){
                        top.location.href = baseUrl+"/";
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg, {icon: 2});
                    }
@@ -395,22 +453,23 @@
        setTimeout(function () {
            layDate.render({
                elem: '.layui-laydate-range'
                ,type: 'datetime'
                ,range: true
                , type: 'datetime'
                , range: true
            });
            layDate.render({
                elem: '#createTime\\$',
                type: 'datetime',
                value: data!==undefined?data['createTime\\$']:null
                value: data !== undefined ? data['createTime\\$'] : null
            });
            layDate.render({
                elem: '#updateTime\\$',
                type: 'datetime',
                value: data!==undefined?data['updateTime\\$']:null
                value: data !== undefined ? data['updateTime\\$'] : null
            });
        }, 300);
    }
    layDateRender();
});
src/main/webapp/views/contract/contract.html
@@ -15,14 +15,24 @@
<div class="layui-fluid">
    <div class="layui-card">
        <div class="layui-card-body">
            <div class="layui-form toolbar" id="search-box">
            <div id="search-box" class="layui-form toolbar" style="display: flex;justify-content: space-between;align-items: center;">
                <div class="nav-box" style="display: flex;align-items: center;">
                    <div class="nav-box-item">
                        <i class="layui-icon" style="color: #1890ff;font-weight: bold">&#xe613;</i>
                    </div>
                    <div class="nav-box-item">
                        <button id="organization" style="border: none;padding-right: 35px;" class="layui-btn layui-btn-primary icon-btn">
                            未知
                        </button>
                    </div>
                </div>
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <div class="layui-input-inline">
                            <input class="layui-input" type="text" name="serial" placeholder="合同编号" autocomplete="off">
                        </div>
                    </div>
                     <div class="layui-inline" style="width: 300px">
                    <div class="layui-inline" style="width: 300px">
                        <div class="layui-input-inline">
                            <input class="layui-input layui-laydate-range" name="create_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px">
                        </div>