From ced9614599e1bb66e883c0be59b23dd32c5ac3c0 Mon Sep 17 00:00:00 2001 From: 72crm <49100395+72crm@users.noreply.github.com> Date: Fri, 10 May 2019 00:57:56 +0800 Subject: [PATCH] 72crm_update_190509 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【重要提示】将更新包中的SQL文件(/public/sql/update_sql_190508.sql)执行导入,此sql文件只用于本次(版本号:72crm_9.0.1_20190509)升级,请勿重复执行。 新增: 1、 跟进记录增加删除功能 2、 联系人、产品导入导出功能 3、 商业智能“员工客户分析、员工业绩分析、客户画像分析、产品分析、排行榜分析”等29个多维度报表 修复: 1、创建员工选择完角色后,在对应的“角色员工”列表没有员工信息,且在“角色员工”处主动关联员工也无法关联 2、员工和部门管理第一大类(办公室)无法更改,一更改就显示参数错误 3、商机自定义字段后,商机详情商机阶段显示错误,且不能正常推进,只能选择最后一步,且编辑商机时商机组及商机阶段显示为id 4、合同、回款 操作记录没有显示 5、审批流为固定审批流,且指定某一人时,审批人在“待我审批”列表看不到数据 6、客户不选中时导出只能导出20条数据 7、日志编辑失败 8、编辑商机状态组,商机阶段展示为数字ID 9、公告结束时间选择为当天,会创建到已结束里 10、 仪表盘目标金额不显示 11、 普通员工将自己添加的场景设为默认的时候,提示“无权操作” 12、 添加完任务之后,在工作台不显示对应动态 13、 商机列表根据商机状态筛选,搜索不出数据 优化: 1、 新建商机、合同时,“总金额”调整为可编辑,可以根据总金额和产品金额自动计算整单折扣 2、 仪表盘时间筛选优化 3、最高管理员可删除所有日志 4、商机状态筛选中,增加“赢单、输单、无效”三个选项 5、系统中显示的当前版本号V9.0.0升级后可以自动更新 6、在线索列表场景中筛选“已转化线索”,勾选之后,将“转移、转化为客户”的操作按钮隐藏 --- application/admin/common.php | 15 +- application/admin/controller/Base.php | 11 +- application/admin/controller/ExamineFlow.php | 2 +- application/admin/controller/Field.php | 19 +- application/admin/controller/Groups.php | 4 +- application/admin/controller/Index.php | 4 +- application/admin/controller/Install.php | 2 +- application/admin/controller/Record.php | 12 +- application/admin/controller/Scene.php | 2 +- application/admin/controller/Structures.php | 20 +- application/admin/controller/Users.php | 48 +- application/admin/model/Excel.php | 345 +++++++--- application/admin/model/Field.php | 68 +- application/admin/model/Record.php | 26 +- application/admin/model/Rule.php | 3 + application/admin/model/Scene.php | 6 +- application/admin/model/User.php | 17 +- application/bi/controller/Achievement.php | 4 +- application/bi/controller/Business.php | 165 ++++- application/bi/controller/Contract.php | 251 +++++++ application/bi/controller/Customer.php | 635 +++++++++++++++++- application/bi/controller/Product.php | 20 +- application/bi/controller/Ranking.php | 312 +++++++++ application/bi/controller/Receivables.php | 2 +- application/bi/model/ActionRecord.php | 33 + application/bi/model/Business.php | 85 +++ application/bi/model/Contacts.php | 35 + application/bi/model/Contract.php | 78 +++ application/bi/model/Customer.php | 511 ++++++++++++++ application/bi/model/Examine.php | 39 ++ application/bi/model/Product.php | 173 +++++ application/bi/model/Receivables.php | 46 ++ application/bi/model/Record.php | 112 +++ application/common.php | 9 +- application/crm/controller/Business.php | 4 +- application/crm/controller/Contacts.php | 77 ++- application/crm/controller/Contract.php | 4 +- application/crm/controller/Customer.php | 111 +-- application/crm/controller/Index.php | 186 +++-- application/crm/controller/Leads.php | 27 +- application/crm/controller/Message.php | 140 +++- application/crm/controller/Product.php | 72 +- application/crm/controller/Receivables.php | 6 +- .../crm/controller/ReceivablesPlan.php | 56 +- application/crm/controller/Setting.php | 20 +- application/crm/model/Achievement.php | 34 +- application/crm/model/Business.php | 14 +- application/crm/model/BusinessStatus.php | 8 +- application/crm/model/Contacts.php | 17 +- application/crm/model/Contract.php | 34 +- application/crm/model/Customer.php | 21 +- application/crm/model/Leads.php | 6 +- application/crm/model/Message.php | 2 +- application/crm/model/Product.php | 42 +- application/crm/model/Receivables.php | 29 +- application/crm/model/ReceivablesPlan.php | 13 +- application/oa/controller/Announcement.php | 6 +- application/oa/controller/Examine.php | 38 +- application/oa/controller/Index.php | 2 +- application/oa/controller/Log.php | 44 +- application/oa/model/Announcement.php | 10 +- application/oa/model/Examine.php | 18 +- application/oa/model/Log.php | 5 - application/work/model/Task.php | 12 +- config/route_admin.php | 4 + config/route_bi.php | 58 +- config/route_crm.php | 34 +- config/version.php | 4 +- index.html | 2 +- public/sql/5kcrm.sql | 40 +- public/sql/update_sql_190508.sql | 18 + static/css/app.469f55b8.css | 9 + static/css/chunk-05cb.3567a1a0.css | 1 + static/css/chunk-05f7.f4f812f3.css | 1 + static/css/chunk-0648.b5d2bdd4.css | 1 + static/css/chunk-08cf.13f93aaa.css | 1 + static/css/chunk-0976.c1352b2e.css | 1 + static/css/chunk-0bb9.41bb6209.css | 1 + static/css/chunk-0da7.e7176999.css | 1 + static/css/chunk-0e1f.6757841a.css | 1 + static/css/chunk-102d.4b0e6cf9.css | 1 + static/css/chunk-1a16.b83dfb8a.css | 1 + static/css/chunk-2211.c11e4de7.css | 1 + static/css/chunk-2402.6823ea58.css | 1 + static/css/chunk-24d4.3edad277.css | 1 + static/css/chunk-2591.4c19aabc.css | 1 + static/css/chunk-2e0d.b688e241.css | 1 + static/css/chunk-2eb9.1c19503f.css | 1 + static/css/chunk-329a.4c9e9c9b.css | 1 + static/css/chunk-335c.ac60753c.css | 1 + static/css/chunk-36b7.28e0847c.css | 1 + static/css/chunk-378f.593c6b9e.css | 1 + static/css/chunk-382b.1106bba8.css | 1 + static/css/chunk-3a5c.8b175435.css | 1 + static/css/chunk-3b66.ff6715e4.css | 1 + static/css/chunk-3f52.432cf039.css | 1 + static/css/chunk-3f62.afbbf40e.css | 1 + static/css/chunk-4049.186df3ae.css | 1 + static/css/chunk-4772.96026062.css | 1 + static/css/chunk-4880.82f4b4e6.css | 1 + static/css/chunk-4d8d.1ce4420a.css | 1 + static/css/chunk-4f83.c1c6fff1.css | 1 + static/css/chunk-55b8.3977e7fe.css | 1 + static/css/chunk-56ab.c70b33c7.css | 1 + static/css/chunk-57a8.c79cb16a.css | 1 + static/css/chunk-5aa9.a6832355.css | 7 + static/css/chunk-5aba.4a6ac2ea.css | 1 + static/css/chunk-5b33.63a2deef.css | 1 + static/css/chunk-5ba3.2109fa2d.css | 1 + static/css/chunk-5dff.4f615b57.css | 1 + static/css/chunk-60b8.6306b10c.css | 1 + static/css/chunk-6287.e1821d1a.css | 1 + static/css/chunk-64be.ea1c56ad.css | 1 + static/css/chunk-6b2d.895588e1.css | 1 + static/css/chunk-6c3e.8fd5bd6e.css | 1 + static/css/chunk-6fbf.59587c6a.css | 1 + static/css/chunk-7129.3431e103.css | 1 + static/css/chunk-7607.4082389f.css | 1 + static/css/chunk-7cca.441d5fd6.css | 1 + static/css/chunk-891f.aee497cd.css | 1 + static/css/chunk-8ade.ebc82e28.css | 1 + static/css/chunk-9b12.d35dfba6.css | 1 + static/css/chunk-9b32.d75a9695.css | 1 + static/css/chunk-9fbc.01b1cfca.css | 1 + static/css/chunk-a346.61683d2c.css | 1 + static/css/chunk-a699.943fc099.css | 1 + static/css/chunk-a781.b85aa018.css | 1 + static/css/chunk-b143.3a229606.css | 1 + static/css/chunk-b84d.895588e1.css | 1 + static/css/chunk-b84d5.895588e1.css | 1 + static/css/chunk-bfd9.5c4f3820.css | 1 + static/css/chunk-d519.bb5702a8.css | 1 + static/css/chunk-d583.eded0bf4.css | 1 + static/css/chunk-dc2f.769b1a0b.css | 1 + static/css/chunk-de5d.7fb73d56.css | 1 + static/css/chunk-dfcc.fb338eeb.css | 1 + static/css/chunk-e5d2.14affbe4.css | 1 + static/css/chunk-e8cd.90b6a6a2.css | 1 + static/css/chunk-ea7d.6974ae38.css | 1 + static/css/chunk-ecc7.0c084728.css | 1 + static/css/chunk-elementUI.0c492a8b.css | 1 + static/css/chunk-fc7a.043a7fb7.css | 1 + static/fonts/iconfont.01d49e9.ttf | Bin 0 -> 17444 bytes static/fonts/iconfont.1279f4e.woff | Bin 0 -> 11740 bytes static/fonts/iconfont.5aa51d8.eot | Bin 0 -> 17604 bytes static/img/iconfont.5e55d32.svg | 203 ++++++ static/js/MTm3.fa93eb96.js | 1 + static/js/app.d9b983a4.js | 1 + static/js/chunk-05cb.e0848d56.js | 1 + static/js/chunk-05f7.3cc4a331.js | 1 + static/js/chunk-0648.addd0392.js | 1 + static/js/chunk-08cf.33ae9144.js | 1 + static/js/chunk-0976.420e40d9.js | 1 + static/js/chunk-0bb9.76ca225f.js | 1 + static/js/chunk-0da7.85fb99b3.js | 1 + static/js/chunk-0e1f.3f6413be.js | 1 + static/js/chunk-102d.31eca8d1.js | 1 + static/js/chunk-1a16.996c89f6.js | 1 + static/js/chunk-2211.8e0d212e.js | 1 + static/js/chunk-2402.33d2bda3.js | 1 + static/js/chunk-24d4.ebeb5229.js | 1 + static/js/chunk-2591.bc31fe7e.js | 1 + static/js/chunk-2e0d.08b5ea25.js | 1 + static/js/chunk-2eb9.f94d0f39.js | 1 + static/js/chunk-329a.726f67a0.js | 1 + static/js/chunk-335c.ec5323a0.js | 1 + static/js/chunk-36b7.5848de1a.js | 1 + static/js/chunk-378f.1b1c84e7.js | 1 + static/js/chunk-382b.6e1399c8.js | 1 + static/js/chunk-3a5c.1c319e9d.js | 1 + static/js/chunk-3b66.cd700cb1.js | 1 + static/js/chunk-3f52.e64cc652.js | 1 + static/js/chunk-3f62.0a6656de.js | 1 + static/js/chunk-4049.47024060.js | 1 + static/js/chunk-4772.561897ec.js | 1 + static/js/chunk-4880.4c9e43f7.js | 1 + static/js/chunk-4d8d.43520f1b.js | 1 + static/js/chunk-4f83.9ef4dc56.js | 1 + static/js/chunk-55b8.6d0dbafc.js | 1 + static/js/chunk-56ab.eca8a02f.js | 1 + static/js/chunk-57a8.87d47531.js | 1 + static/js/chunk-5965.5130ff8b.js | 14 + static/js/chunk-5aa9.5b5a73b2.js | 1 + static/js/chunk-5aba.8922958e.js | 1 + static/js/chunk-5b33.95f97af2.js | 1 + static/js/chunk-5ba3.1d30d1a4.js | 1 + static/js/chunk-5dff.ab2f13cb.js | 1 + static/js/chunk-60b8.0da396f5.js | 1 + static/js/chunk-6287.520651a5.js | 1 + static/js/chunk-64be.988c44bc.js | 1 + static/js/chunk-6b2d.8264ce5d.js | 1 + static/js/chunk-6c3e.3da21cb4.js | 1 + static/js/chunk-6fbf.be6da6d8.js | 1 + static/js/chunk-7129.8af9eb6a.js | 1 + static/js/chunk-7607.657bae66.js | 1 + static/js/chunk-7ab0.fce11133.js | 8 + static/js/chunk-7cca.6d49ef81.js | 1 + static/js/chunk-891f.3055fc7c.js | 1 + static/js/chunk-8ade.763eed00.js | 1 + static/js/chunk-9b12.f8d90863.js | 1 + static/js/chunk-9b32.1e36da07.js | 1 + static/js/chunk-9fbc.987c5c9f.js | 1 + static/js/chunk-a346.931ad19e.js | 1 + static/js/chunk-a699.dfe6a76d.js | 1 + static/js/chunk-a781.c9aa5cf0.js | 1 + static/js/chunk-b143.9ea8d6ac.js | 1 + static/js/chunk-b84d.299ffae5.js | 1 + static/js/chunk-b84d5.070bbd7e.js | 1 + static/js/chunk-bfd9.bb089aba.js | 1 + static/js/chunk-d1ba.2f751617.js | 45 ++ static/js/chunk-d519.1e69c81d.js | 1 + static/js/chunk-d583.d860ffe8.js | 1 + static/js/chunk-dc2f.784cdecd.js | 1 + static/js/chunk-de5d.9813bcf8.js | 1 + static/js/chunk-dfcc.a44e7c9b.js | 1 + static/js/chunk-e5d2.5d17499b.js | 1 + static/js/chunk-e85d.b1fa9dcc.js | 1 + static/js/chunk-e8cd.7c23c791.js | 1 + static/js/chunk-ea7d.3b9eaac5.js | 1 + static/js/chunk-ecc7.8aa61286.js | 1 + static/js/chunk-elementUI.e8c5c39a.js | 1 + static/js/chunk-fc7a.b783bd94.js | 1 + static/js/chunk-libs.92b6f54d.js | 63 ++ static/js/fnnb.2a9e9de9.js | 1 + update_sql_190508.sql | 18 + ux/package.json | 3 +- ux/src/App.vue | 10 +- .../api/businessIntelligence/achievement.js | 25 + ux/src/api/businessIntelligence/bi.js | 64 -- ux/src/api/businessIntelligence/business.js | 58 ++ ux/src/api/businessIntelligence/customer.js | 141 ++++ .../businessIntelligence/customerPortrayal.js | 20 + ux/src/api/businessIntelligence/product.js | 12 + ux/src/api/businessIntelligence/ranking.js | 113 ++++ ux/src/api/customermanagement/common.js | 22 + ux/src/api/customermanagement/contacts.js | 41 ++ ux/src/api/customermanagement/product.js | 41 ++ ux/src/assets/iconfont/iconfont.css | 24 +- ux/src/assets/iconfont/iconfont.eot | Bin 16900 -> 17604 bytes ux/src/assets/iconfont/iconfont.js | 2 +- ux/src/assets/iconfont/iconfont.svg | 9 + ux/src/assets/iconfont/iconfont.ttf | Bin 16740 -> 17444 bytes ux/src/assets/iconfont/iconfont.woff | Bin 11292 -> 11740 bytes ux/src/assets/iconfont/iconfont.woff2 | Bin 9640 -> 10008 bytes ux/src/components/CreateCom/XhProduct.vue | 126 +++- ux/src/components/timeTypeSelect/index.vue | 178 +++++ ux/src/router/index.js | 4 +- ux/src/router/modules/business.js | 429 ++++++++++-- ux/src/router/modules/manager.js | 4 + ux/src/styles/index.scss | 5 + ux/src/views/OAManagement/journal/index.vue | 20 - .../OAManagement/journal/journalCell.vue | 34 +- ux/src/views/OAManagement/notice/details.vue | 2 +- ux/src/views/OAManagement/notice/index.vue | 8 +- ux/src/views/OAManagement/schedule/index.vue | 6 +- .../SystemManagement/RoleAuthorization.vue | 6 +- .../SystemEmployee/EmployeeDepManagement.vue | 2 +- .../SystemManagement/components/newDialog.vue | 28 +- .../TaskCompleteStatistics.vue | 78 ++- .../achievement/AchievementBackStatistics.vue | 56 ++ .../AchievementCountStatistics.vue | 56 ++ .../AchievementMoneyStatistics.vue | 56 ++ .../AchievementSummaryStatistics.vue | 89 +++ .../business/BusinessTrendStatistics.vue | 252 +++++++ .../business/BusinessWinStatistics.vue | 264 ++++++++ .../business/FunnelStatistics.vue | 159 +++++ .../components/filtrateHandleView.vue | 370 ++++++++++ .../customer/CustomerConversionStatistics.vue | 277 ++++++++ .../customer/CustomerCycleStatistics.vue | 61 ++ .../customer/CustomerPoolStatistics.vue | 251 +++++++ .../customer/CustomerRecordModeStatistics.vue | 221 ++++++ .../customer/CustomerRecordStatistics.vue | 249 +++++++ .../customer/CustomerTotalStatistics.vue | 236 +++++++ .../customer/components/CycleView.vue | 290 ++++++++ .../CustomerAddressStatistics.vue | 154 +++++ .../CustomerPortrayalStatistics.vue | 209 ++++++ .../mixins/achievement.js | 353 ++++++++++ .../views/businessIntelligence/mixins/base.js | 44 ++ .../businessIntelligence/mixins/ranking.js | 101 +++ .../product/ProductCategoryStatistics.vue | 100 +++ .../product/ProductStatistics.vue | 380 +++++++++++ .../ranking/RankingAddContactsStatistics.vue | 104 +++ .../ranking/RankingAddCustomerStatistics.vue | 104 +++ .../ranking/RankingContractStatistics.vue | 102 +++ .../ranking/RankingExamineStatistics.vue | 104 +++ .../ranking/RankingProductStatistics.vue | 104 +++ .../ranking/RankingReceivablesStatistics.vue | 102 +++ .../RankingRecordCustomerStatistics.vue | 104 +++ .../ranking/RankingRecordNunStatistics.vue | 104 +++ .../ranking/RankingSigningStatistics.vue | 104 +++ .../businessIntelligence/styles/detail.scss | 35 + .../business/BusinessDetail.vue | 7 +- .../customermanagement/clue/ClueIndex.vue | 31 - .../components/CRMImport.vue | 75 ++- .../components/CRMListHead.vue | 17 +- .../components/CRMTableHead.vue | 70 +- .../components/RelativeBusiness.vue | 25 +- .../components/followLog/RecordLog.vue | 12 +- .../followLog/components/FollowRecordCell.vue | 42 +- .../components/sceneForm/SceneCreate.vue | 2 +- .../components/sceneForm/SceneList.vue | 25 +- .../contacts/ContactsIndex.vue | 1 + .../contract/ContractDetail.vue | 2 +- .../customer/CustomerIndex.vue | 31 - .../views/customermanagement/mixins/table.js | 63 +- .../product/ProductIndex.vue | 1 + .../customermanagement/seas/SeasIndex.vue | 2 +- .../workbench/components/CustomerDash.vue | 217 ++---- .../workbench/workbench.vue | 57 +- ux/src/views/layout/businessLayout.vue | 21 +- ux/src/views/layout/components/Navbar.vue | 2 +- ux/src/views/layout/components/Sidebar.vue | 40 +- ux/src/views/layout/customerLayout.vue | 3 +- ux/src/views/layout/personCenterLayout.vue | 3 +- ux/src/views/login/index.vue | 2 +- 315 files changed, 11219 insertions(+), 1084 deletions(-) create mode 100644 application/bi/controller/Contract.php create mode 100644 application/bi/controller/Ranking.php create mode 100644 application/bi/model/ActionRecord.php create mode 100644 application/bi/model/Business.php create mode 100644 application/bi/model/Contacts.php create mode 100644 application/bi/model/Contract.php create mode 100644 application/bi/model/Customer.php create mode 100644 application/bi/model/Examine.php create mode 100644 application/bi/model/Product.php create mode 100644 application/bi/model/Receivables.php create mode 100644 application/bi/model/Record.php create mode 100644 public/sql/update_sql_190508.sql create mode 100644 static/css/app.469f55b8.css create mode 100644 static/css/chunk-05cb.3567a1a0.css create mode 100644 static/css/chunk-05f7.f4f812f3.css create mode 100644 static/css/chunk-0648.b5d2bdd4.css create mode 100644 static/css/chunk-08cf.13f93aaa.css create mode 100644 static/css/chunk-0976.c1352b2e.css create mode 100644 static/css/chunk-0bb9.41bb6209.css create mode 100644 static/css/chunk-0da7.e7176999.css create mode 100644 static/css/chunk-0e1f.6757841a.css create mode 100644 static/css/chunk-102d.4b0e6cf9.css create mode 100644 static/css/chunk-1a16.b83dfb8a.css create mode 100644 static/css/chunk-2211.c11e4de7.css create mode 100644 static/css/chunk-2402.6823ea58.css create mode 100644 static/css/chunk-24d4.3edad277.css create mode 100644 static/css/chunk-2591.4c19aabc.css create mode 100644 static/css/chunk-2e0d.b688e241.css create mode 100644 static/css/chunk-2eb9.1c19503f.css create mode 100644 static/css/chunk-329a.4c9e9c9b.css create mode 100644 static/css/chunk-335c.ac60753c.css create mode 100644 static/css/chunk-36b7.28e0847c.css create mode 100644 static/css/chunk-378f.593c6b9e.css create mode 100644 static/css/chunk-382b.1106bba8.css create mode 100644 static/css/chunk-3a5c.8b175435.css create mode 100644 static/css/chunk-3b66.ff6715e4.css create mode 100644 static/css/chunk-3f52.432cf039.css create mode 100644 static/css/chunk-3f62.afbbf40e.css create mode 100644 static/css/chunk-4049.186df3ae.css create mode 100644 static/css/chunk-4772.96026062.css create mode 100644 static/css/chunk-4880.82f4b4e6.css create mode 100644 static/css/chunk-4d8d.1ce4420a.css create mode 100644 static/css/chunk-4f83.c1c6fff1.css create mode 100644 static/css/chunk-55b8.3977e7fe.css create mode 100644 static/css/chunk-56ab.c70b33c7.css create mode 100644 static/css/chunk-57a8.c79cb16a.css create mode 100644 static/css/chunk-5aa9.a6832355.css create mode 100644 static/css/chunk-5aba.4a6ac2ea.css create mode 100644 static/css/chunk-5b33.63a2deef.css create mode 100644 static/css/chunk-5ba3.2109fa2d.css create mode 100644 static/css/chunk-5dff.4f615b57.css create mode 100644 static/css/chunk-60b8.6306b10c.css create mode 100644 static/css/chunk-6287.e1821d1a.css create mode 100644 static/css/chunk-64be.ea1c56ad.css create mode 100644 static/css/chunk-6b2d.895588e1.css create mode 100644 static/css/chunk-6c3e.8fd5bd6e.css create mode 100644 static/css/chunk-6fbf.59587c6a.css create mode 100644 static/css/chunk-7129.3431e103.css create mode 100644 static/css/chunk-7607.4082389f.css create mode 100644 static/css/chunk-7cca.441d5fd6.css create mode 100644 static/css/chunk-891f.aee497cd.css create mode 100644 static/css/chunk-8ade.ebc82e28.css create mode 100644 static/css/chunk-9b12.d35dfba6.css create mode 100644 static/css/chunk-9b32.d75a9695.css create mode 100644 static/css/chunk-9fbc.01b1cfca.css create mode 100644 static/css/chunk-a346.61683d2c.css create mode 100644 static/css/chunk-a699.943fc099.css create mode 100644 static/css/chunk-a781.b85aa018.css create mode 100644 static/css/chunk-b143.3a229606.css create mode 100644 static/css/chunk-b84d.895588e1.css create mode 100644 static/css/chunk-b84d5.895588e1.css create mode 100644 static/css/chunk-bfd9.5c4f3820.css create mode 100644 static/css/chunk-d519.bb5702a8.css create mode 100644 static/css/chunk-d583.eded0bf4.css create mode 100644 static/css/chunk-dc2f.769b1a0b.css create mode 100644 static/css/chunk-de5d.7fb73d56.css create mode 100644 static/css/chunk-dfcc.fb338eeb.css create mode 100644 static/css/chunk-e5d2.14affbe4.css create mode 100644 static/css/chunk-e8cd.90b6a6a2.css create mode 100644 static/css/chunk-ea7d.6974ae38.css create mode 100644 static/css/chunk-ecc7.0c084728.css create mode 100644 static/css/chunk-elementUI.0c492a8b.css create mode 100644 static/css/chunk-fc7a.043a7fb7.css create mode 100644 static/fonts/iconfont.01d49e9.ttf create mode 100644 static/fonts/iconfont.1279f4e.woff create mode 100644 static/fonts/iconfont.5aa51d8.eot create mode 100644 static/img/iconfont.5e55d32.svg create mode 100644 static/js/MTm3.fa93eb96.js create mode 100644 static/js/app.d9b983a4.js create mode 100644 static/js/chunk-05cb.e0848d56.js create mode 100644 static/js/chunk-05f7.3cc4a331.js create mode 100644 static/js/chunk-0648.addd0392.js create mode 100644 static/js/chunk-08cf.33ae9144.js create mode 100644 static/js/chunk-0976.420e40d9.js create mode 100644 static/js/chunk-0bb9.76ca225f.js create mode 100644 static/js/chunk-0da7.85fb99b3.js create mode 100644 static/js/chunk-0e1f.3f6413be.js create mode 100644 static/js/chunk-102d.31eca8d1.js create mode 100644 static/js/chunk-1a16.996c89f6.js create mode 100644 static/js/chunk-2211.8e0d212e.js create mode 100644 static/js/chunk-2402.33d2bda3.js create mode 100644 static/js/chunk-24d4.ebeb5229.js create mode 100644 static/js/chunk-2591.bc31fe7e.js create mode 100644 static/js/chunk-2e0d.08b5ea25.js create mode 100644 static/js/chunk-2eb9.f94d0f39.js create mode 100644 static/js/chunk-329a.726f67a0.js create mode 100644 static/js/chunk-335c.ec5323a0.js create mode 100644 static/js/chunk-36b7.5848de1a.js create mode 100644 static/js/chunk-378f.1b1c84e7.js create mode 100644 static/js/chunk-382b.6e1399c8.js create mode 100644 static/js/chunk-3a5c.1c319e9d.js create mode 100644 static/js/chunk-3b66.cd700cb1.js create mode 100644 static/js/chunk-3f52.e64cc652.js create mode 100644 static/js/chunk-3f62.0a6656de.js create mode 100644 static/js/chunk-4049.47024060.js create mode 100644 static/js/chunk-4772.561897ec.js create mode 100644 static/js/chunk-4880.4c9e43f7.js create mode 100644 static/js/chunk-4d8d.43520f1b.js create mode 100644 static/js/chunk-4f83.9ef4dc56.js create mode 100644 static/js/chunk-55b8.6d0dbafc.js create mode 100644 static/js/chunk-56ab.eca8a02f.js create mode 100644 static/js/chunk-57a8.87d47531.js create mode 100644 static/js/chunk-5965.5130ff8b.js create mode 100644 static/js/chunk-5aa9.5b5a73b2.js create mode 100644 static/js/chunk-5aba.8922958e.js create mode 100644 static/js/chunk-5b33.95f97af2.js create mode 100644 static/js/chunk-5ba3.1d30d1a4.js create mode 100644 static/js/chunk-5dff.ab2f13cb.js create mode 100644 static/js/chunk-60b8.0da396f5.js create mode 100644 static/js/chunk-6287.520651a5.js create mode 100644 static/js/chunk-64be.988c44bc.js create mode 100644 static/js/chunk-6b2d.8264ce5d.js create mode 100644 static/js/chunk-6c3e.3da21cb4.js create mode 100644 static/js/chunk-6fbf.be6da6d8.js create mode 100644 static/js/chunk-7129.8af9eb6a.js create mode 100644 static/js/chunk-7607.657bae66.js create mode 100644 static/js/chunk-7ab0.fce11133.js create mode 100644 static/js/chunk-7cca.6d49ef81.js create mode 100644 static/js/chunk-891f.3055fc7c.js create mode 100644 static/js/chunk-8ade.763eed00.js create mode 100644 static/js/chunk-9b12.f8d90863.js create mode 100644 static/js/chunk-9b32.1e36da07.js create mode 100644 static/js/chunk-9fbc.987c5c9f.js create mode 100644 static/js/chunk-a346.931ad19e.js create mode 100644 static/js/chunk-a699.dfe6a76d.js create mode 100644 static/js/chunk-a781.c9aa5cf0.js create mode 100644 static/js/chunk-b143.9ea8d6ac.js create mode 100644 static/js/chunk-b84d.299ffae5.js create mode 100644 static/js/chunk-b84d5.070bbd7e.js create mode 100644 static/js/chunk-bfd9.bb089aba.js create mode 100644 static/js/chunk-d1ba.2f751617.js create mode 100644 static/js/chunk-d519.1e69c81d.js create mode 100644 static/js/chunk-d583.d860ffe8.js create mode 100644 static/js/chunk-dc2f.784cdecd.js create mode 100644 static/js/chunk-de5d.9813bcf8.js create mode 100644 static/js/chunk-dfcc.a44e7c9b.js create mode 100644 static/js/chunk-e5d2.5d17499b.js create mode 100644 static/js/chunk-e85d.b1fa9dcc.js create mode 100644 static/js/chunk-e8cd.7c23c791.js create mode 100644 static/js/chunk-ea7d.3b9eaac5.js create mode 100644 static/js/chunk-ecc7.8aa61286.js create mode 100644 static/js/chunk-elementUI.e8c5c39a.js create mode 100644 static/js/chunk-fc7a.b783bd94.js create mode 100644 static/js/chunk-libs.92b6f54d.js create mode 100644 static/js/fnnb.2a9e9de9.js create mode 100644 update_sql_190508.sql create mode 100644 ux/src/api/businessIntelligence/achievement.js create mode 100644 ux/src/api/businessIntelligence/business.js create mode 100644 ux/src/api/businessIntelligence/customer.js create mode 100644 ux/src/api/businessIntelligence/customerPortrayal.js create mode 100644 ux/src/api/businessIntelligence/product.js create mode 100644 ux/src/api/businessIntelligence/ranking.js create mode 100644 ux/src/components/timeTypeSelect/index.vue create mode 100644 ux/src/views/businessIntelligence/achievement/AchievementBackStatistics.vue create mode 100644 ux/src/views/businessIntelligence/achievement/AchievementCountStatistics.vue create mode 100644 ux/src/views/businessIntelligence/achievement/AchievementMoneyStatistics.vue create mode 100644 ux/src/views/businessIntelligence/achievement/AchievementSummaryStatistics.vue create mode 100644 ux/src/views/businessIntelligence/business/BusinessTrendStatistics.vue create mode 100644 ux/src/views/businessIntelligence/business/BusinessWinStatistics.vue create mode 100644 ux/src/views/businessIntelligence/business/FunnelStatistics.vue create mode 100644 ux/src/views/businessIntelligence/components/filtrateHandleView.vue create mode 100644 ux/src/views/businessIntelligence/customer/CustomerConversionStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customer/CustomerCycleStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customer/CustomerPoolStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customer/CustomerRecordModeStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customer/CustomerRecordStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customer/CustomerTotalStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customer/components/CycleView.vue create mode 100644 ux/src/views/businessIntelligence/customerPortrayal/CustomerAddressStatistics.vue create mode 100644 ux/src/views/businessIntelligence/customerPortrayal/CustomerPortrayalStatistics.vue create mode 100644 ux/src/views/businessIntelligence/mixins/achievement.js create mode 100644 ux/src/views/businessIntelligence/mixins/base.js create mode 100644 ux/src/views/businessIntelligence/mixins/ranking.js create mode 100644 ux/src/views/businessIntelligence/product/ProductCategoryStatistics.vue create mode 100644 ux/src/views/businessIntelligence/product/ProductStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingAddContactsStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingAddCustomerStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingContractStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingExamineStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingProductStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingReceivablesStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingRecordCustomerStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingRecordNunStatistics.vue create mode 100644 ux/src/views/businessIntelligence/ranking/RankingSigningStatistics.vue diff --git a/application/admin/common.php b/application/admin/common.php index 50e4dcde..19f3c4be 100644 --- a/application/admin/common.php +++ b/application/admin/common.php @@ -47,11 +47,18 @@ function decrypt($str, $key = 'kls8in1e') /** * 部门树形数组 - * @param + * @param type 0 下属数组, 1包含自己 */ -function getSubObj($id, $objList, $separate) { - $array = array(); - foreach ($objList AS $value) { +function getSubObj($id, $objList, $separate, $is_first = 0) { + $array = array(); + foreach ($objList as $key => $value) { + if ($key == 0 && $is_first == 1) { + if ($value['id'] == 1) { + $id = 0; + } else { + $id = $value['pid']; + } + } if ($id == $value['pid']) { $array[] = array('id' => $value['id'], 'name' => $separate.$value['name']); $array = array_merge($array, getSubObj($value['id'], $objList, $separate.'--')); diff --git a/application/admin/controller/Base.php b/application/admin/controller/Base.php index 4f3f8fcb..c1eabf0c 100644 --- a/application/admin/controller/Base.php +++ b/application/admin/controller/Base.php @@ -22,8 +22,8 @@ public function login() $password = $param['password']; $verifyCode = !empty($param['verifyCode'])? $param['verifyCode']: ''; $isRemember = !empty($param['isRemember'])? $param['isRemember']: ''; - $type = $param['type'] ? : ''; - $data = $userModel->login($username, $password, $verifyCode, $isRemember, $type, $authKey); + $is_mobile = $param['is_mobile'] ? : ''; + $data = $userModel->login($username, $password, $verifyCode, $isRemember, $type, $authKey, $is_mobile); Session::set('user_id', $data['userInfo']['id']); if (!$data) { @@ -35,8 +35,13 @@ public function login() //退出登录 public function logout() { + $param = $this->param; $header = Request::instance()->header(); - cache('Auth_'.$header['authkey'], null); + if ($param['mobile'] == 1) { + cache('Auth_'.$header['authkey'].'mobile', null); + } else { + cache('Auth_'.$header['authkey'], null); + } session('null', 'admin'); session('admin','null'); session('user_id','null'); diff --git a/application/admin/controller/ExamineFlow.php b/application/admin/controller/ExamineFlow.php index a2538c0c..a2a7406e 100644 --- a/application/admin/controller/ExamineFlow.php +++ b/application/admin/controller/ExamineFlow.php @@ -35,7 +35,7 @@ public function _initialize() //权限判断 $unAction = ['steplist','userlist','recordlist']; $adminTypes = adminGroupTypes($userInfo['id']); - if (!in_array(4,$adminTypes) && !in_array(1,$adminTypes) && !in_array($a, $unAction)) { + if (!in_array(4,$adminTypes) && !in_array(1,$adminTypes) && !in_array(2,$adminTypes) && !in_array($a, $unAction)) { header('Content-Type:application/json; charset=utf-8'); exit(json_encode(['code'=>102,'error'=>'无权操作'])); } diff --git a/application/admin/controller/Field.php b/application/admin/controller/Field.php index 44d8afd8..ed0220ec 100644 --- a/application/admin/controller/Field.php +++ b/application/admin/controller/Field.php @@ -23,7 +23,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['index','getfield','update','read','config','validates','configindex','columnwidth'] + 'allow'=>['index','getfield','update','read','config','validates','configindex','columnwidth','uniquefield'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -35,7 +35,7 @@ public function _initialize() //权限判断 $unAction = ['getfield','read','config','validates','configindex','columnwidth']; $adminTypes = adminGroupTypes($userInfo['id']); - if (!in_array(6,$adminTypes) && !in_array(1,$adminTypes) && !in_array($a, $unAction)) { + if (!in_array(6,$adminTypes) && !in_array(1,$adminTypes) && !in_array(2,$adminTypes) && !in_array($a, $unAction)) { header('Content-Type:application/json; charset=utf-8'); exit(json_encode(['code'=>102,'error'=>'无权操作'])); } @@ -345,5 +345,18 @@ public function configIndex() return resultArray(['error' => $userFieldModel->getError()]); } return resultArray(['data' => $res]); - } + } + + /** + * 自定义验重字段 + * @param types 分类 + * @param + */ + public function uniqueField() + { + $param = $this->param; + $list = db('admin_field')->where(['types' => $param['types'],'is_unique' => 1])->column('name'); + $list = $list ? implode(',',$list) : '无'; + return resultArray(['data' => $list]); + } } diff --git a/application/admin/controller/Groups.php b/application/admin/controller/Groups.php index d315eb41..67c07ff1 100644 --- a/application/admin/controller/Groups.php +++ b/application/admin/controller/Groups.php @@ -33,7 +33,7 @@ public function _initialize() $userInfo = $this->userInfo; //权限判断 $adminTypes = adminGroupTypes($userInfo['id']); - if (!in_array(3,$adminTypes) && !in_array(1,$adminTypes)) { + if (!in_array(1,$adminTypes) && !in_array(2,$adminTypes) && !in_array(3,$adminTypes)) { header('Content-Type:application/json; charset=utf-8'); exit(json_encode(['code'=>102,'error'=>'无权操作'])); } @@ -174,6 +174,8 @@ public function copy() } $dataInfo = json_decode($dataInfo, true); unset($dataInfo['id']); + $titleCount = db('admin_group')->where(['title' => $dataInfo['title']])->count(); + $dataInfo['title'] = $dataInfo['title'].'('.$titleCount.')'; $data = $groupModel->createData($dataInfo); if (!$data) { return resultArray(['error' => $groupModel->getError()]); diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php index 067dad9e..7230becf 100644 --- a/application/admin/controller/Index.php +++ b/application/admin/controller/Index.php @@ -76,7 +76,7 @@ public function authList() $ruleMap = []; $adminTypes = adminGroupTypes($u_id); if (in_array(1,$adminTypes)) { - $map['status'] = 1; + $ruleMap['status'] = 1; } else { $userModel = new \app\admin\model\User(); $groups = $userModel->get($u_id)->groups; @@ -92,7 +92,7 @@ public function authList() } $newRuleIds = []; // 重新设置ruleIds,除去部分已删除或禁用的权限。 - $rules = Db::name('admin_rule')->where($ruleMap)->select(); + $rules = Db::name('admin_rule')->where($ruleMap)->order('types asc')->select(); foreach ($rules as $k => $v) { $newRuleIds[] = $v['id']; $rules[$k]['name'] = strtolower($v['name']); diff --git a/application/admin/controller/Install.php b/application/admin/controller/Install.php index 95bc1f80..44713938 100644 --- a/application/admin/controller/Install.php +++ b/application/admin/controller/Install.php @@ -318,7 +318,7 @@ private function checkNnv() 'php' => ['PHP版本', '5.6', '5.6.x', PHP_VERSION, 'ok'], ]; session('install_error',''); - if ($items['php'][3] < $items['php'][1]) { + if (substr($items['php'][3],0,3) < $items['php'][1]) { $items['php'][4] = 'no'; session('install_error', true); } diff --git a/application/admin/controller/Record.php b/application/admin/controller/Record.php index 67c5878e..b6618b8a 100644 --- a/application/admin/controller/Record.php +++ b/application/admin/controller/Record.php @@ -102,18 +102,22 @@ public function update() * @param * @return */ - public function delete($id) + public function delete() { $recordModel = model('Record'); $param = $this->param; + $userInfo = $this->userInfo; //权限判断 $dataInfo = $recordModel->getDataById($param['id']); if (!$dataInfo) { return resultArray(['error' => '数据不存在或已删除']); } - - // $resData = $recordModel->delDataById($param['id']); - $resData = $recordModel->signDelById($param['id']); //逻辑删 + //自己(24小时)或者管理员 + $adminTypes = adminGroupTypes($userInfo['id']); + if (!in_array(1,$adminTypes) && ($dataInfo['create_user_id'] !== $userInfo['id'] && ((time()-$dataInfo['create_time']) > 86400))) { + return resultArray(['error' => '超过24小时,不能删除']); + } + $resData = $recordModel->delDataById($param['id']); if (!$resData) { return resultArray(['error' => $recordModel->getError()]); } diff --git a/application/admin/controller/Scene.php b/application/admin/controller/Scene.php index 3209f128..15624732 100644 --- a/application/admin/controller/Scene.php +++ b/application/admin/controller/Scene.php @@ -24,7 +24,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['index','save','read','update','delete','sort','default'] + 'allow'=>['index','save','read','update','delete','sort','defaults'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); diff --git a/application/admin/controller/Structures.php b/application/admin/controller/Structures.php index 05212461..3fe72506 100644 --- a/application/admin/controller/Structures.php +++ b/application/admin/controller/Structures.php @@ -23,7 +23,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['index','read','save','update','delete','deletes','enables','listdialog','subindex'] + 'allow'=>['index','read','save','update','delete','deletes','enables','listdialog','subindex','getsubuserbystructrue'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -34,7 +34,7 @@ public function _initialize() $userInfo = $this->userInfo; //权限判断 - $unAction = ['index','listdialog','subindex']; + $unAction = ['index','listdialog','subindex','getsubuserbystructrue']; $adminTypes = adminGroupTypes($userInfo['id']); if (!in_array(3,$adminTypes) && !in_array(1,$adminTypes) && !in_array(2,$adminTypes) && !in_array($a, $unAction)) { header('Content-Type:application/json; charset=utf-8'); @@ -45,9 +45,13 @@ public function _initialize() //获取权限范围内的部门 public function subIndex() { + $param = $this->param; $userInfo = $this->userInfo; $userModel = model('User'); - $ret = $userModel->getUserByPer(); + $m = $param['m'] ? : ''; + $c = $param['c'] ? : ''; + $a = $param['a'] ? : ''; + $ret = $userModel->getUserByPer($m, $c, $a); $where['au.id'] = ['in',$ret]; $list = Db::name('AdminUser') ->alias('au') @@ -55,8 +59,9 @@ public function subIndex() ->field('ast.*') ->where($where) ->group('structure_id') + ->order('structure_id asc') ->select(); - $result = getSubObj(0, $list,''); + $result = getSubObj(0, $list, '', 1); return resultArray(['data'=>$result]); } @@ -137,12 +142,9 @@ public function update() $structureModel = model('Structure'); $param = $this->param; $dataInfo = $structureModel->getDataByID($param['id']); - if (empty($dataInfo['pid'])) { + if (empty($dataInfo['pid']) || $param['id'] == '1') { unset($param['pid']); } - if (!$param['pid']) { - return resultArray(['error' => '参数错误']); - } $data = $structureModel->updateDataById($param, $param['id']); if (!$data) { return resultArray(['error' => $structureModel->getError()]); @@ -207,7 +209,7 @@ public function listDialog() } } } - $structureList = getSubObj(0, $structureList, ''); + $structureList = getSubObj(0, $structureList, '', 1); return resultArray(['data' => $structureList]); } } diff --git a/application/admin/controller/Users.php b/application/admin/controller/Users.php index a39be724..49f5f183 100644 --- a/application/admin/controller/Users.php +++ b/application/admin/controller/Users.php @@ -103,9 +103,10 @@ public function update() $userModel = model('User'); $param = $this->param; $userInfo = $this->userInfo; + $userData = db('admin_user')->where(['id' => $param['id']])->find(); if (!$param['id']) { //修改个人信息 - $param['user_id'] = $userInfo['id']; + $param['user_id'] = $userData['id']; } else { //权限判断 $adminTypes = adminGroupTypes($userInfo['id']); @@ -114,12 +115,13 @@ public function update() exit(json_encode(['code'=>102,'error'=>'无权操作'])); } } + unset($param['username']); $data = $userModel->updateDataById($param, $param['id']); if (!$data) { return resultArray(['error' => $userModel->getError()]); } - $param['userInfo'] = $userInfo; + $param['userInfo'] = $userData; $resSync = model('Sync')->syncData($param); return resultArray(['data' => '编辑成功']); @@ -157,9 +159,9 @@ public function enables() $ids = $param['id']; } //顶级管理员不能修改 - foreach ($ids as $v) { - if ($v == 1) { - unset($ids[$v]); + foreach ($ids as $k=>$v) { + if ((int)$v == 1 && $param['status'] == '0') { + unset($ids[$k]); } } $data = $userModel->enableDatas($ids, $param['status']); @@ -178,26 +180,26 @@ public function getUserList() { $userModel = model('User'); $param = $this->param; - $by = $param['by']; + $by = $param['by'] ? : ''; if ($param['m'] && $param['c'] && $param['a']) { if ($param['m'] == 'oa' && $param['c'] == 'task') { $belowIds = getSubUserId(true, 1); } $belowIds = $userModel->getUserByPer($param['m'], $param['c'], $param['a']); } else { - // if ($by == 'all') { - // $belowIds = getSubUserId(true, 1); - // } else { - // $userInfo = $this->userInfo; - // $adminIds = $userModel->getAdminId(); - // if (in_array($userInfo['id'],$adminIds)) { - // $belowIds = getSubUserId(true, 1); - // } else { - // //下属id - // $belowIds = getSubUserId(); - // } - // } - $belowIds = getSubUserId(true, 1); + if ($by == 'sub') { + $userInfo = $this->userInfo; + $adminIds = $userModel->getAdminId(); + if (in_array($userInfo['id'],$adminIds)) { + $belowIds = getSubUserId(true, 1); + } else { + //下属id + $belowIds = getSubUserId(); + } + } else { + $belowIds = getSubUserId(true, 1); + } + // $belowIds = getSubUserId(true, 1); } $userList = db('admin_user') ->where(['user.id' => ['in',$belowIds]]) @@ -321,9 +323,9 @@ public function groups() $resData = false; } } - if ($resData == false) { - return resultArray(['error' => '操作失败,请重试']); - } + // if ($resData == false) { + // return resultArray(['error' => '操作失败,请重试']); + // } return resultArray(['data' => '创建成功']); } @@ -356,7 +358,7 @@ public function groupsDel() public function structureUserList() { $structure_list = db('admin_structure')->select(); - $structureList = getSubObj(0, $structure_list, ''); + $structureList = getSubObj(0, $structure_list, '', 1); foreach ($structureList as $k=>$v) { $userList = []; $userList = db('admin_user')->where(['structure_id' => $v['id'],'status' => array('in',['1','3'])])->field('id,realname')->select(); diff --git a/application/admin/model/Excel.php b/application/admin/model/Excel.php index 3ecc10d6..837070c6 100644 --- a/application/admin/model/Excel.php +++ b/application/admin/model/Excel.php @@ -65,6 +65,14 @@ public function excelImportDownload($field_list, $types){ $objActSheet = $objPHPExcel->getActiveSheet(); $objActSheet->setTitle('悟空软件导入模板'.date('Y-m-d',time())); //设置sheet的标题 + //存储Excel数据源到其他工作薄 + $objPHPExcel->createSheet(); + $subObject = $objPHPExcel->getSheet(1); + $subObject->setTitle('data'); + //保护数据源 + $subObject->getProtection()->setSheet(true); + $subObject->protectCells('A1:C1000',time()); + $k = 0; foreach ($field_list as $field) { $objActSheet->getColumnDimension($this->stringFromColumnIndex($k))->setWidth(20); //设置单元格宽度 @@ -76,23 +84,61 @@ public function excelImportDownload($field_list, $types){ $k++; } } else { - if($field['form_type'] == 'select' || $field['form_type'] == 'checkbox' || $field['form_type'] == 'radio'){ - $setting = $field['setting'] ? : []; + if ($field['form_type'] == 'select' || $field['form_type'] == 'checkbox' || $field['form_type'] == 'radio' || $field['form_type'] == 'category') { + //产品类别 + if ($field['form_type'] == 'category' && $field['types'] == 'crm_product') { + $setting = db('crm_product_category')->order('pid asc')->column('name'); + } else { + $setting = $field['setting'] ? : []; + } $select_value = implode(',',$setting); - if ($select_value) { - //数据有效性 start - $objValidation = $objActSheet->getCell($this->stringFromColumnIndex($k).'3')->getDataValidation(); - $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) - -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) - -> setAllowBlank(false) - -> setShowInputMessage(true) - -> setShowErrorMessage(true) - -> setShowDropDown(true) - -> setErrorTitle('输入的值有误') - -> setError('您输入的值不在下拉框列表内.') - -> setPromptTitle('--请选择--') - -> setFormula1('"'.$select_value.'"'); - //数据有效性 end + + //解决下拉框数据来源字串长度过大:将每个来源字串分解到一个空闲的单元格中 + $str_len = strlen($select_value); + $selectList = array(); + if ($str_len >= 255) { + $str_list_arr = explode(',', $select_value); + if ($str_list_arr) { + foreach ($str_list_arr as $i1=>$d) { + $c = $this->stringFromColumnIndex($k).($i1+1); + $subObject->setCellValue($c,$d); + $selectList[$d]=$d; + } + $endcell = $c; + } + for ($c=3; $c<=70; $c++) { + //数据有效性 start + $objValidation = $objActSheet->getCell($this->stringFromColumnIndex($k).$c)->getDataValidation(); + $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) + -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) + -> setAllowBlank(false) + -> setShowInputMessage(true) + -> setShowErrorMessage(true) + -> setShowDropDown(true) + -> setErrorTitle('输入的值有误') + -> setError('您输入的值不在下拉框列表内.') + -> setPromptTitle('--请选择--') + -> setFormula1('data!$'.$this->stringFromColumnIndex($k).'$1:$'.$this->stringFromColumnIndex($k).'$'.count(explode(',',$select_value))); + //数据有效性 end + } + } else { + if ($select_value) { + for ($c=3; $c<=70; $c++) { + //数据有效性 start + $objValidation = $objActSheet->getCell($this->stringFromColumnIndex($k).$c)->getDataValidation(); + $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) + -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) + -> setAllowBlank(false) + -> setShowInputMessage(true) + -> setShowErrorMessage(true) + -> setShowDropDown(true) + -> setErrorTitle('输入的值有误') + -> setError('您输入的值不在下拉框列表内.') + -> setPromptTitle('--请选择--') + -> setFormula1('"'.$select_value.'"'); + //数据有效性 end + } + } } } //检查该字段若必填,加上"*" @@ -114,9 +160,9 @@ public function excelImportDownload($field_list, $types){ $objActSheet->getStyle('A1')->getFont()->getColor()->setARGB('FFFF0000'); $objActSheet->getStyle('A1')->getAlignment()->setWrapText(true); //设置单元格格式范围的字体、字体大小、加粗 - $objActSheet->getStyle('A1:'.$mark_row.'1')->getFont()->setName("微软雅黑")->setSize(13)->getColor()->setARGB('#00000000'); + $objActSheet->getStyle('A1:'.$max_row.'1')->getFont()->setName("微软雅黑")->setSize(13)->getColor()->setARGB('#00000000'); //给单元格填充背景色 - $objActSheet->getStyle('A1:'.$mark_row.'1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('#ff9900'); + $objActSheet->getStyle('A1:'.$max_row.'1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('#ff9900'); switch ($types) { case 'crm_leads' : $types_name = '线索信息'; break; @@ -233,7 +279,7 @@ public function importExcel($file, $param) if ($ext =='xlsx') { $objWriter = new \PHPExcel_Writer_Excel2007($objPHPExcel); - $objRender = \PHPExcel_IOFactory::createReader('excel2007'); + $objRender = \PHPExcel_IOFactory::createReader('Excel2007'); $ExcelObj = $objRender->load($savePath); } else if ($ext =='xls') { $objWriter = new \PHPExcel_Writer_Excel5($objPHPExcel); @@ -259,18 +305,32 @@ public function importExcel($file, $param) //取出文件的内容描述信息,循环取出数据,写入数据库 switch ($types) { case 'crm_leads' : $dataModel = new \app\crm\model\Leads(); $db = 'crm_leads'; $db_id = 'leads_id'; break; - case 'crm_customer' : $dataModel = new \app\crm\model\Customer(); $db = 'crm_customer'; $db_id = 'customer_id'; break; + case 'crm_customer' : $dataModel = new \app\crm\model\Customer(); $db = 'crm_customer'; $db_id = 'customer_id'; $fieldParam['form_type'] = array('not in',['file','form','user','structure']); break; case 'crm_contacts' : $dataModel = new \app\crm\model\Contacts(); $db = 'crm_contacts'; $db_id = 'contacts_id'; break; - } + case 'crm_product' : $dataModel = new \app\crm\model\Product(); $db = 'crm_product'; $db_id = 'product_id'; break; + } + $contactsModel = new \app\crm\model\Contacts(); //自定义字段 $fieldModel = new \app\admin\model\Field(); $fieldParam['types'] = $types; $field_list = $fieldModel->getDataList($fieldParam); $fieldArr = []; + $uniqueField = []; //验重字段 foreach ($field_list as $k=>$v) { $fieldArr[$v['name']]['field'] = $v['field']; $fieldArr[$v['name']]['form_type'] = $v['form_type']; + if ($v['is_unique'] == 1) $uniqueField[] = $v['field']; + } + $field_num = count($field_list); + //客户导入联系人 + if ($types == 'crm_customer') { + $contacts_field_list = $fieldModel->getDataList(['types' => 'crm_contacts','field' => array('neq','customer_id')]); + $contactsFieldArr = []; + foreach ($contacts_field_list as $k=>$v) { + $contactsFieldArr[$v['name']]['field'] = $v['field']; + $contactsFieldArr[$v['name']]['form_type'] = $v['form_type']; + } } $defaultData = []; //默认数据 $defaultData['create_user_id'] = $param['create_user_id']; @@ -279,102 +339,119 @@ public function importExcel($file, $param) $defaultData['update_time'] = time(); if ($types == 'crm_customer') { $defaultData['deal_time'] = time(); + } + //产品类别 + if ($types == 'crm_product') { + $productCategory = db('crm_product_category')->select(); + $productCategoryArr = []; + foreach ($productCategory as $v) { + $productCategoryArr[$v['name']] = $v['category_id']; + } } - $key = 2; + + $keys = 2; $errorMessage = []; - foreach ($sheetContent as $val){ + foreach ($sheetContent as $kk => $val){ $data = ''; + $contactsData = ''; $k = 0; + $contacts_k = $field_num; $resNameIds = ''; - $key++; + $keys++; $name = ''; //客户、线索、联系人等名称 + $contactsName = ''; $data = $defaultData; //导入数据 + $contacts_data = $defaultData; //导入数据 + $resWhere = ''; //验重条件 + $resContacts = false; //联系人是否有数据 + $resInfo = false; //Excel列是否有数据 foreach ($excelHeader as $aa => $header) { if (empty($header)) break; $fieldName = trim(str_replace('*','',$header)); $info = ''; $info = $val[$k]; - if (empty($fieldArr[$fieldName]['field'])) break; - if ($fieldArr[$fieldName]['field'] == 'name') $name = $info; - if ($info) { - if ($fieldArr[$fieldName]['form_type'] == 'address') { - $address = array(); - for ($i=0; $i<4; $i++) { - $address[] = $val[$k]; - $k++; - } - $data[$fieldArr[$fieldName]['field']] = implode(chr(10), $address); - - // 地址信息转地理坐标(仅处理系统初始的地址字段) - if ($fieldArr[$fieldName]['field'] == 'address') { - $address_arr = $address; - if ($address_arr['3']) { - $address_str = implode('', $address_arr); - $ret = get_lng_lat($address_str); - $data['lng'] = $ret['lng'] ?: 0; - $data['lat'] = $ret['lat'] ?: 0; - } - } - } elseif ($fieldArr[$fieldName]['form_type'] == 'date') { - $data[$fieldArr[$fieldName]['field']] = $info ? date('Y-m-d',strtotime($info)) : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'datetime') { - $data[$fieldArr[$fieldName]['field']] = $info ? strtotime($info) : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'customer') { - $data[$fieldArr[$fieldName]['field']] = db('crm_customer')->where(['name' => $info])->value('customer_id') ? : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'contacts') { - $data[$fieldArr[$fieldName]['field']] = db('crm_contacts')->where(['name' => $info])->value('contacts_id') ? : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'business') { - $data[$fieldArr[$fieldName]['field']] = db('crm_business')->where(['name' => $info])->value('business_id') ? : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'category') { - $data[$fieldArr[$fieldName]['field']] = db('crm_product_category')->where(['name' => $info])->value('category_id') ? : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'business_type') { - $data[$fieldArr[$fieldName]['field']] = db('crm_business_type')->where(['name' => $info])->value('type_id') ? : ''; - $k++; - } elseif ($fieldArr[$fieldName]['form_type'] == 'business_status') { - $data[$fieldArr[$fieldName]['field']] = db('crm_business_status')->where(['name' => $info])->value('status_id') ? : ''; - $k++; - } else { - $data[$fieldArr[$fieldName]['field']] = $info ? : ''; - $k++; - } - } else { - $data[$fieldArr[$fieldName]['field']] = ''; - $k++; + if ($info) $resInfo = true; + if ($types == 'crm_product' && $fieldName == '产品类别') { + $data['category_id'] = $productCategoryArr[$info] ? : 0; + $data['category_str'] = $dataModel->getPidStr($productCategoryArr[$info], '', 1); } + //联系人 + if ($types == 'crm_contacts' && $fieldName == '客户名称') { + if (!$info) { + $errorMessage[] = '第'.$keys.'行导入错误,失败原因:客户名称必填'; + continue; + } + $customer_id = ''; + $customer_id = db('crm_customer')->where(['name' => $info])->value('customer_id'); + if (!$customer_id) { + $errorMessage[] = '第'.$keys.'行导入错误,失败原因:客户名称不存在'; + continue; + } + $data['customer_id'] = $customer_id; + } + if ($aa < $field_num) { + if (empty($fieldArr[$fieldName]['field'])) continue; + // if ($fieldArr[$fieldName]['field'] == 'name') $name = $info; + if (in_array($fieldArr[$fieldName]['field'], $uniqueField) && $info) $resWhere .= " `".$fieldArr[$fieldName]['field']."` = '".$info."' OR"; + + $resList = []; + $resList = $this->sheetData($k, $fieldArr, $fieldName, $info); + $resData[] = $resList['data']; + $k = $resList['k']; + } else { + //联系人 + if ($types == 'crm_customer' && $aa == (int)$contacts_k) { + $contactsInfo = ''; + $contactsInfo = $val[$contacts_k]; + if ($contactsInfo) { + $resContacts = true; + } + // if ($contactsFieldArr[$fieldName]['field'] == 'name') $contactsName = $contactsInfo; + $resContactsList = []; + $resContactsList = $this->sheetData($contacts_k, $contactsFieldArr, $fieldName, $contactsInfo); + $resContactsData[] = $resContactsList['data']; + $contacts_k = $resContactsList['k']; + } + } } - if ($name) $resNameIds = db($db)->where(['name' => $name,'owner_user_id' => $param['owner_user_id']])->column($db_id); - if ($resNameIds) { - if ($config == 1) { + $result = $this->changeArr($resData); //二维数组转一维数组 + $data = $result ? array_merge($data,$result) : []; + if ($types == 'crm_customer' && $result) { + $resultContacts = $this->changeArr($resContactsData); + $contactsData = $resultContacts ? array_merge($contacts_data,$resultContacts) : []; //联系人 + } + $resWhere = $resWhere ? substr($resWhere,0,-2) : ''; + $ownerWhere['owner_user_id'] = $param['owner_user_id']; + if ($uniqueField && $resWhere) $resNameIds = db($db)->where($resWhere)->where($ownerWhere)->column($db_id); + if ($resInfo == false) { + continue; + } + if ($resNameIds && $data) { + if ($config == 1 && $resNameIds) { + $data['user_id'] = $param['create_user_id']; //覆盖数据(以名称为查重规则,如存在则覆盖原数据) - if ($resNameIds) { - foreach ($resNameIds as $nid) { - $upRes = $dataModel->updateDataById($data, $nid); - if (!$upRes) { - $errorMessage[] = '第'.$key.'行导入错误,失败原因:数据更新失败'; - continue; - } + foreach ($resNameIds as $nid) { + $upRes = $dataModel->updateDataById($data, $nid); + if (!$upRes) { + $errorMessage[] = '第'.$keys.'行导入错误,失败原因:'.$dataModel->getError(); + continue; } - } + } } } else { if (!$resData = $dataModel->createData($data)) { - $errorMessage[] = '第'.$key.'行导入错误,失败原因:'.$dataModel->getError(); + $errorMessage[] = '第'.$keys.'行导入错误,失败原因:'.$dataModel->getError(); continue; } - // if ($types == 'crm_customer') { - // $contactsModel = new \app\crm\model\Contacts(); - // $contactsData = $data; - // $contactsData['customer_id'] = $resData['customer_id']; - // $resData = $contactsModel->createData($contactsData); - // } + if ($types == 'crm_customer' && $resContacts !== false) { + $contactsData['customer_id'] = $resData['customer_id']; + if (!$resData = $contactsModel->createData($contactsData)) { + $errorMessage[] = '第'.$keys.'行导入错误,失败原因:'.$contactsModel->getError(); + continue; + } + } } - } + } if ($errorMessage) { $this->error = $errorMessage; return false; @@ -386,6 +463,84 @@ public function importExcel($file, $param) } } + /** + * excel数据处理 + * @param $k 需处理数据开始下标 + * @author Michael_xu + * @return + */ + public function sheetData($k = 0, $fieldArr, $fieldName, $info) + { + if ($info) { + if ($fieldArr[$fieldName]['form_type'] == 'address') { + $address = array(); + for ($i=0; $i<4; $i++) { + $address[] = $val[$k]; + $k++; + } + $data[$fieldArr[$fieldName]['field']] = implode(chr(10), $address); + + // 地址信息转地理坐标(仅处理系统初始的地址字段) + if ($fieldArr[$fieldName]['field'] == 'address') { + $address_arr = $address; + if ($address_arr['3']) { + $address_str = implode('', $address_arr); + $ret = get_lng_lat($address_str); + $data['lng'] = $ret['lng'] ?: 0; + $data['lat'] = $ret['lat'] ?: 0; + } + } + } elseif ($fieldArr[$fieldName]['form_type'] == 'date') { + $data[$fieldArr[$fieldName]['field']] = $info ? date('Y-m-d',strtotime($info)) : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'datetime') { + $data[$fieldArr[$fieldName]['field']] = $info ? strtotime($info) : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'customer') { + $data[$fieldArr[$fieldName]['field']] = db('crm_customer')->where(['name' => $info])->value('customer_id') ? : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'contacts') { + $data[$fieldArr[$fieldName]['field']] = db('crm_contacts')->where(['name' => $info])->value('contacts_id') ? : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'business') { + $data[$fieldArr[$fieldName]['field']] = db('crm_business')->where(['name' => $info])->value('business_id') ? : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'category') { + $data[$fieldArr[$fieldName]['field']] = db('crm_product_category')->where(['name' => $info])->value('category_id') ? : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'business_type') { + $data[$fieldArr[$fieldName]['field']] = db('crm_business_type')->where(['name' => $info])->value('type_id') ? : ''; + $k++; + } elseif ($fieldArr[$fieldName]['form_type'] == 'business_status') { + $data[$fieldArr[$fieldName]['field']] = db('crm_business_status')->where(['name' => $info])->value('status_id') ? : ''; + $k++; + } else { + $data[$fieldArr[$fieldName]['field']] = $info ? : ''; + $k++; + } + } else { + $data[$fieldArr[$fieldName]['field']] = ''; + $k++; + } + $res['data'] = $data; + $res['k'] = $k; + return $res; + } + + //二维数组转一维数组 + public function changeArr($arr) + { + $newArr = []; + foreach ($arr as $v) { + if ($v && is_array($v)) { + $newArr = array_merge($newArr,$v); + } else { + continue; + } + } + return $newArr; + } + /** * excel参数配置(备份) * @param diff --git a/application/admin/model/Field.php b/application/admin/model/Field.php index 82476a3f..9fcd9863 100644 --- a/application/admin/model/Field.php +++ b/application/admin/model/Field.php @@ -53,7 +53,7 @@ public function getDataList($param) $this->error = '参数错误'; return false; } - $map['types'] = $types; + $map = $param; if ($types == 'oa_examine') { $map['types_id'] = $param['types_id']; } @@ -496,9 +496,9 @@ public function field($param, $dataInfo = []) if (in_array($param['action'],array('index','view'))) { $map['types'] = array(array('eq',$types),array('eq',''),'or'); } else { - if ($param['types'] == 'crm_customer' && (in_array($param['action'],array('save','update','excel')))) { - $map['field'] = array('not in',['deal_status']); - } + // if ($param['types'] == 'crm_customer' && (in_array($param['action'],array('save','update','excel')))) { + // $map['field'] = array('not in',['deal_status']); + // } $map['types'] = $types; } if ($param['controller'] == 'customer' && $param['action'] == 'pool') { @@ -515,7 +515,7 @@ public function field($param, $dataInfo = []) $field_list = $this->getIndexFieldConfig($types, $param['user_id']); // $order = new \think\db\Expression('field(field_id,'..')'); } else { - $field_list = $this->where($map)->field('field,name,form_type,default_value,is_unique,is_null,input_tips,setting')->order($order)->select(); + $field_list = $this->where($map)->field('field,types,name,form_type,default_value,is_unique,is_null,input_tips,setting')->order($order)->select(); //客户 if (in_array($param['types'],['crm_customer']) && $param['action'] !== 'excel') { $new_field_list[] = [ @@ -554,6 +554,9 @@ public function field($param, $dataInfo = []) $setting = explode(chr(10), $v['setting']); if ($v['form_type'] == 'checkbox') $default_value = $v['default_value'] ? explode(',', $v['default_value']) : []; } + if ($v['field'] == 'order_date') { + $default_value = date('Y-m-d',time()); + } //地图类型 if ($v['form_type'] == 'map_address') { $value = [ @@ -635,7 +638,7 @@ public function field($param, $dataInfo = []) if ($param['action'] == 'read') { $value = $dataInfo[$v['field']] ? db('crm_business_type')->where(['type_id' => $dataInfo[$v['field']]])->value('name') : ''; } else { - $value = $dataInfo[$v['field']] ? : ''; + $value = (int)$dataInfo[$v['field']] ? : ''; } } elseif ($v['form_type'] == 'business_status') { //商机阶段 @@ -643,8 +646,8 @@ public function field($param, $dataInfo = []) $value = $dataInfo[$v['field']] ? db('crm_business_status')->where(['status_id' => $dataInfo[$v['field']]])->value('name') : ''; } else { $businessStatusModel = new \app\crm\model\BusinessStatus(); - $setting = $businessStatusModel->getDataList($dataInfo['type_id']); - $value = $dataInfo[$v['field']] ? : ''; + $setting = $businessStatusModel->getDataList($dataInfo['type_id']); + $value = (int)$dataInfo[$v['field']] ? : ''; } } elseif ($v['form_type'] == 'receivables_plan') { //回款计划期数 @@ -744,7 +747,7 @@ public function fieldSearch($param) ->whereOr('structure_id','') ->select(); foreach ($setting as $key=>$val) { - $setting[$key]['statusList'] = $businessStatusModel->getDataList($val['type_id']); + $setting[$key]['statusList'] = $businessStatusModel->getDataList($val['type_id'], 1); } $setting = $setting ? : []; } @@ -758,9 +761,10 @@ public function fieldSearch($param) * @author Michael_xu * @param */ - public function validateField($types) + public function validateField($types, $types_id = 0) { - $fieldList = $this->where(['types' => ['in',['',$types]],'is_unique' => 1,'form_type' => ['not in',['checkbox','user','structure','file']]])->field('field,name,form_type,is_unique,is_null,max_length')->select(); + $unField = ['update_time','create_time','create_user_id','owner_user_id']; + $fieldList = $this->where(['types' => ['in',['',$types]],'types_id' => $types_id,'field' => ['not in',$unField],'form_type' => ['not in',['checkbox','user','structure','file']]])->field('field,name,form_type,is_unique,is_null,max_length')->select(); $validateArr = []; $rule = []; $message = []; @@ -771,35 +775,39 @@ public function validateField($types) $max_length = $field['max_length'] ? : ''; if ($field['is_null']) { - $rule_value .= 'require|'; - $message[$field['field'].'.require'] = $field['name'].'不能为空'; - } - if ($max_length) { - $rule_value .= 'max:'.$max_length; - $message[$field['field'].'.max'] = $field['name'].'不能超过'.$max_length.'个字符'; - } - if ($field['is_unique']) { - $rule_value .= 'unique:'.$types; - $message[$field['field'].'.unique'] = $field['name'].'已经存在,不能重复添加'; + $rule_value .= 'require'; + $message[$field['field'].'.require'] = $field['name'].'不能为空'; } if ($field['form_type'] == 'number') { + if ($rule_value) $rule_value .= '|'; $rule_value .= 'number'; $message[$field['field'].'.number'] = $field['name'].'必须是数字'; - } - if ($field['form_type'] == 'email') { + } elseif ($field['form_type'] == 'email') { + if ($rule_value) $rule_value .= '|'; $rule_value .= 'email'; $message[$field['field'].'.email'] = $field['name'].'格式错误'; - } - if ($field['form_type'] == 'mobile ') { + } elseif ($field['form_type'] == 'mobile ') { + if ($rule_value) $rule_value .= '|'; $rule_value .= 'regex:^1[3456789][0-9]{9}?$'; $message[$field['field'].'.regex'] = $field['name'].'格式错误'; } - if ($field['form_type'] == 'datetime') { - $rule_value .= 'date'; - $message[$field['field'].'.date'] = $field['name'].'格式错误'; - } - + if ($field['is_unique']) { + if ($rule_value) $rule_value .= '|'; + $rule_value .= 'unique:'.$types; + $message[$field['field'].'.unique'] = $field['name'].'已经存在,不能重复添加'; + } + if ($max_length) { + if ($rule_value) $rule_value .= '|'; + $rule_value .= 'max:'.$max_length; + $message[$field['field'].'.max'] = $field['name'].'不能超过'.$max_length.'个字符'; + } + // if ($field['form_type'] == 'datetime') { + // $rule_value .= 'date'; + // $message[$field['field'].'.date'] = $field['name'].'格式错误'; + // } + if ($rule_value == 'require|') $rule_value = 'require'; if (!empty($rule_value)) $rule[$field['field']] = $rule_value; + } $validateArr['rule'] = $rule ? : []; $validateArr['message'] = $message ? : []; diff --git a/application/admin/model/Record.php b/application/admin/model/Record.php index bd04346e..74849a4d 100644 --- a/application/admin/model/Record.php +++ b/application/admin/model/Record.php @@ -62,6 +62,15 @@ public function getDataList($request, $by = '') $whereOr['types_id'] = $leads_id; } } + //联系人下包含关联的客户的跟进记录 + if ($map['types'] == 'crm_contacts') { + $whereOr = []; + $whereOr['contacts_ids'] = array('like','%,'.$map['types_id'].',%'); + } + if ($map['types'] == 'crm_business') { + $whereOr = []; + $whereOr['business_ids'] = array('like','%,'.$map['types_id'].',%'); + } $list = db('admin_record') ->page($request['page'], $request['limit']) ->order('create_time desc') @@ -377,9 +386,7 @@ public function createData($param) unset($param['file_id']); if ($this->data($param)->allowField(true)->save()) { //下次联系时间 - if ($param['next_time']) { - $this->updateNexttime($param['types'], $param['types_id'], $param['next_time']); - } + $this->updateNexttime($param['types'], $param['types_id'], $param['next_time']); //处理附件关系 if ($fileArr) { @@ -407,15 +414,7 @@ public function createData($param) public function getDataById($id = '') { $map['record_id'] = $id; - $data_view = $this - ->where($map) - ->alias('record') - ->join('__CRM_BUSINESS__ business', 'business.business_id = record.business_id', 'LEFT') - ->join('__CRM_CONTACTS__ contacts', 'contacts.contacts_id = record.contacts_id', 'LEFT'); - - $dataInfo = $data_view - ->field('record.*,business.name as business_name,contacts.name as contacts_name') - ->find(); + $dataInfo = db('admin_record')->where($map)->find(); if (!$dataInfo) { $this->error = '暂无此数据'; return false; @@ -499,8 +498,9 @@ public function updateNexttime($types, $types_id, $next_time) default : break; } $data = []; - $data['next_time'] = $next_time; + if ($next_time) $data['next_time'] = $next_time; $data['update_time'] = time(); + $data['follow'] = '已跟进'; $dbName->where([$dbId => $types_id])->update($data); return true; } diff --git a/application/admin/model/Rule.php b/application/admin/model/Rule.php index dc692738..95448fb2 100644 --- a/application/admin/model/Rule.php +++ b/application/admin/model/Rule.php @@ -34,6 +34,9 @@ public function getDataList($param) $data[$k]['check'] = false; if ($types && !in_array((int)$v['types'], $types)) { unset($data[$k]); + } + if (empty($v['status'])) { + unset($data[$k]); } } $data = array_merge($data); diff --git a/application/admin/model/Scene.php b/application/admin/model/Scene.php index 307ab7fd..e00619ba 100644 --- a/application/admin/model/Scene.php +++ b/application/admin/model/Scene.php @@ -147,11 +147,7 @@ public function getDataById($id = '', $user_id, $types = '') if (is_array($data)) { foreach ($data as $k=>$v) { if ($v['form_type'] == 'business_type') { - $v['value'] = $v['type_id']; - if ($v['status_id']) { - $v['value'] = $v['status_id']; - $data['status_id'] = $v; - } + $data[$k]['value'] = $v['type_id']; } } } diff --git a/application/admin/model/User.php b/application/admin/model/User.php index 847243e4..a0852871 100644 --- a/application/admin/model/User.php +++ b/application/admin/model/User.php @@ -69,6 +69,9 @@ public function getDataList($request) //角色员工 if ($map['group_id']) { $group_user_ids = db('admin_access')->where(['group_id' => $map['group_id']])->column('user_id'); + if ($map['group_id'] == 1 && !$group_user_ids) { + $group_user_ids = ['1']; + } $map['user.id'] = array('in',$group_user_ids); } $exp = new \think\db\Expression('field(user.status,1,2,0)'); @@ -81,7 +84,7 @@ public function getDataList($request) $map['user.structure_id'] = ['in',$new_str_ids]; //$map['structure_id']; } unset($map['structure_id']); - if ($map['status']) { + if ($map['status'] || $map['group_id']) { $map['user.status'] = ($map['status'] !== 'all') ? ($map['status'] ? : ['gt',0]) : ['egt',0]; } else { $map['user.status'] = 0; @@ -362,9 +365,10 @@ public function updateDataById($param, $id) * @param [string] $verifyCode [验证码] * @param Boolean $isRemember [是否记住密码] * @param Boolean $type [是否重复登录] + * @param Boolean $mobile [1手机登录] * @return [type] [description] */ - public function login($username, $password, $verifyCode = '', $isRemember = false, $type = false, $authKey) + public function login($username, $password, $verifyCode = '', $isRemember = false, $type = false, $authKey = '', $mobile = 0) { if (!$username) { $this->error = '帐号不能为空'; @@ -424,11 +428,15 @@ public function login($username, $password, $verifyCode = '', $isRemember = fals // $info['_AUTH_LIST_'] = $dataList['rulesList']; $info['authKey'] = $authKey; //手机登录 - if (!$type) { + if ($mobile == 1) { + cache('Auth_'.$userInfo['authkey'].'mobile', NULL); + cache('Auth_'.$authKey.'mobile', $info, $loginExpire); + } else { cache('Auth_'.$userInfo['authkey'], NULL); + cache('Auth_'.$authKey, $info, $loginExpire); } unset($userInfo['authkey']); - cache('Auth_'.$authKey, $info, $loginExpire); + // 返回信息 $data['authKey'] = $authKey; $data['sessionId'] = $info['sessionId']; @@ -648,7 +656,6 @@ public function getGroupTypeByAction($uid, $m, $c, $a) $mRuleId = db('admin_rule')->where(['name'=>$m,'level'=>1])->value('id'); $cRuleId = db('admin_rule')->where(['name'=>$c,'level'=>2,'pid'=>$mRuleId])->value('id'); $aRuleId = db('admin_rule')->where(['name'=>$a,'level'=>3,'pid'=>$cRuleId])->value('id'); - //获取用户组 $groups = $this->get($uid)->groups; if (!$groups) { diff --git a/application/bi/controller/Achievement.php b/application/bi/controller/Achievement.php index c231e2d5..dcca1e75 100644 --- a/application/bi/controller/Achievement.php +++ b/application/bi/controller/Achievement.php @@ -39,7 +39,7 @@ public function _initialize() */ public function statistics() { - if (!checkPerByAction('bi', 'achievement' , 'read')) { + if (!checkPerByAction('bi', 'achievement', 'read')) { header('Content-Type:application/json; charset=utf-8'); exit(json_encode(['code'=>102,'error'=>'无权操作'])); } @@ -47,5 +47,5 @@ public function statistics() $achievementModel = new \app\crm\model\Achievement(); $list = $achievementModel->getList($param) ? : []; return resultArray(['data'=>$list]); - } + } } diff --git a/application/bi/controller/Business.php b/application/bi/controller/Business.php index 4b2382f4..e01abb12 100644 --- a/application/bi/controller/Business.php +++ b/application/bi/controller/Business.php @@ -23,7 +23,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['funnel'] + 'allow'=>['funnel','businesstrend','trendlist','win'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -61,9 +61,168 @@ public function funnel() $perUserIds = $userModel->getUserByPer('bi', 'business', 'read'); //权限范围内userIds $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 $param['userIds'] = $userIds ? : []; - $param['start_time'] = $param['start_time']; - $param['end_time'] = $param['end_time'] ? $param['end_time']+86399 : time(); + $list = $businessModel->getFunnel($param); return resultArray(['data' => $list]); } + + /** + * 新增商机数与金额趋势分析 + * @return [type] [description] + */ + public function businessTrend() + { + if (!checkPerByAction('bi', 'business' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $businessModel = new \app\bi\model\Business(); + $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'business', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['create_user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + + $item['business_num'] = $businessModel->getDataCount($whereArr); + $item['business_money'] = $businessModel->getDataMoney($whereArr); + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 新增商机数与金额趋势分析 列表 + * @return [type] [description] + */ + public function trendList() + { + if (!checkPerByAction('bi', 'business' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $businessModel = new \app\bi\model\Business(); + $crmBusinessModel = new \app\crm\model\Business(); + $userModel = new \app\admin\model\User(); + $param = $this->param; + if ($param['type']) { + $timeArr = getTimeByType($param['type']); + $param['start_time'] = $timeArr[0]; + $param['end_time'] = $timeArr[1]; + } + $dataList = $businessModel->getDataList($param); + foreach ($dataList as $k => $v) { + $business_info = $crmBusinessModel->getDataById($v['business_id']); + $dataList[$k]['business_name'] = $business_info['name']; + $dataList[$k]['create_time'] = date('Y-m-d',strtotime($business_info['create_time'])); + $dataList[$k]['customer_id'] = $v['customer_id']; + $customer = db('crm_customer')->field('name')->where('customer_id',$v['customer_id'])->find(); + $dataList[$k]['customer_name'] = $customer['name']; + $create_user_id_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : []; + $dataList[$k]['create_user_name'] = $create_user_id_info['realname']; + $owner_user_id_info = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : []; + $dataList[$k]['owner_user_name'] = $owner_user_id_info['realname']; + $dataList[$k]['status_id_info'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段 + $dataList[$k]['type_id_info'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组 + } + return resultArray(['data' => $dataList]); + } + + /** + * 赢单机会转化率趋势分析 + * @author Michael_xu + * @param + * @return + */ + public function win() + { + if (!checkPerByAction('bi', 'business' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $businessModel = new \app\bi\model\Business(); + $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'business', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['create_user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + + $item['business_num'] = $businessModel->getDataCount($whereArr); + $whereArr['is_end'] = 1; + $item['business_end'] = $businessModel->getDataCount($whereArr); + + if($item['business_num']== 0 || $item['business_end'] == 0){ + $item['proportion'] = 0; + }else{ + $item['proportion'] = round(($item['business_end']/$item['business_num']),4)*100; + } + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } } diff --git a/application/bi/controller/Contract.php b/application/bi/controller/Contract.php new file mode 100644 index 00000000..c620ecbf --- /dev/null +++ b/application/bi/controller/Contract.php @@ -0,0 +1,251 @@ +[''], + 'allow'=>['analysis','summary'] + ]; + Hook::listen('check_auth',$action); + $request = Request::instance(); + $a = strtolower($request->action()); + if (!in_array($a, $action['permission'])) { + parent::_initialize(); + } + } + + /** + * 合同数量分析/金额分析/回款金额分析 + * @return [type] [description] + */ + public function analysis() + { + if (!checkPerByAction('bi', 'contract' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $receivablesModel = new \app\bi\model\Receivables(); + $biContractModel = new \app\bi\model\Contract(); + $param = $this->param; + if(empty($param['year'])){ + $year = date('Y'); + }else{ + $year = $param['year']; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $datas = array(); + for ($i=1; $i <= 12; $i++) { + $whereArr = []; + $whereArr['owner_user_id'] = array('in',$userIds); + $item = array(); + $item['type'] = $i.'月'; + //时间段 + $start_time = $year.'-'.$i.'-01'; + $end_time = $year.'-'.($i+1).'-01'; + if($i == 12){ + $start_time = $year.'-'.$i.'-01'; + $end_time = ($year+1).'-01-01'; + } + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + if($param['type'] == 'back'){ + $time = 'return_time'; + }else{ + $time = 'order_date'; + } + $whereArr['check_status'] = array('eq',2); + $whereArr[$time] = $create_time; + //当月 + if($param['type'] == 'count'){ + $item['month'] = $biContractModel->getDataCount($whereArr); + }else if($param['type'] == 'money'){ + $item['month'] = $biContractModel->getDataMoney($whereArr); + }else if($param['type'] == 'back'){ + $item['month'] = $receivablesModel->getDataMoney($whereArr); + } + //上月 + if($i == 1){ + $start_time = ($year-1).'-12-01'; + $end_time = $year.'-01-01'; + }else{ + $start_time = $year.'-'.($i-1).'-01'; + $end_time = $year.'-'.$i.'-01'; + } + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr[$time] = $create_time; + if($param['type'] == 'count'){ + $item['lastMonth'] = $biContractModel->getDataCount($whereArr); + }else if($param['type'] == 'money'){ + $item['lastMonth'] = $biContractModel->getDataMoney($whereArr); + }else if($param['type'] == 'back'){ + $whereArr['return_time'] = $create_time; + $item['lastMonth'] = $receivablesModel->getDataMoney($whereArr); + } + + //去年当月 + $start_time = ($year-1).'-'.$i.'-01'; + $end_time = ($year-1).'-'.($i+1).'-01'; + if($i == 12){ + $start_time = ($year-1).'-'.$i.'-01'; + $end_time = ($year).'-01-01'; + } + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr[$time] = $create_time; + if($param['type'] == 'count'){ + $item['lastYeatMonth'] = $biContractModel->getDataCount($whereArr); + }else if($param['type'] == 'money'){ + $item['lastYeatMonth'] = $biContractModel->getDataMoney($whereArr); + }else if($param['type'] == 'back'){ + $whereArr['return_time'] = $create_time; + $item['lastYeatMonth'] = $receivablesModel->getDataMoney($whereArr); + } + + // //去年上月 + if($i == 1){ + $start_time = ($year-2).'-12-01'; + $end_time = ($year-1).'-01-01'; + }else{ + $start_time = ($year-1).'-'.($i-1).'-01'; + $end_time = ($year-1).'-'.$i.'-01'; + } + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr[$time] = $create_time; + if($param['type'] == 'count'){ + $item['lastYeatLastMonth'] = $biContractModel->getDataCount($whereArr); + }else if($param['type'] == 'money'){ + $item['lastYeatLastMonth'] = $biContractModel->getDataMoney($whereArr); + }else if($param['type'] == 'back'){ + $whereArr['return_time'] = $create_time; + $item['lastYeatLastMonth'] = $receivablesModel->getDataMoney($whereArr); + } + + //环比增长 + if($item['month']==0 || $item['lastMonth']==0){ + $item['chain_ratio'] = 0; + }else{ + $item['chain_ratio'] = round(($item['month']/$item['lastMonth']),4)*100; + } + //同比增长 + if($item['month']==0 || $item['lastYeatMonth']==0){ + $item['year_on_year'] = 0; + }else{ + $item['year_on_year'] = round(($item['month']/$item['lastYeatMonth']),4)*100; + } + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 合同汇总表 + * @return [type] [description] + */ + public function summary() + { + if (!checkPerByAction('bi', 'contract' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $receivablesModel = new \app\bi\model\Receivables(); + $biContractModel = new \app\bi\model\Contract(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('crm', 'contract', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['owner_user_id'] = array('in',$userIds); + $whereArr['check_status'] = array('eq',2); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = $timeArr['year'].'-'.$timeArr['month'].'-'.$day; + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = $timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day; + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $where = array(); + $where = $whereArr; + $where['order_date'] = $create_time; + $item['count'] = $biContractModel->getDataCount($where); + $item['money'] = $biContractModel->getDataMoney($where); + $where_b = array(); + $where_b = $whereArr; + $where_b['return_time'] = $create_time; + $item['back'] = $receivablesModel->getDataMoney($where_b); + $datas['items'][] = $item; + } + if(!empty($param['start_time'])){ + $whereArr['create_time'] = array('between',array($param['start_time'],$param['end_time'])); + }else{ + $create_time = getTimeByType($param['type']); + if ($create_time) { + $whereArr['create_time'] = array('between',array($create_time[0],$create_time[1])); + } + } + $datas['count_zong'] = $biContractModel->getDataCount($whereArr); + $datas['money_zong'] = $biContractModel->getDataMoney($whereArr); + $datas['back_zong'] = $receivablesModel->getDataMoney($whereArr); + $datas['w_back_zong'] = $datas['money_zong']-$datas['back_zong']; + return resultArray(['data' => $datas]); + } +} diff --git a/application/bi/controller/Customer.php b/application/bi/controller/Customer.php index 4617607f..dd2730f8 100644 --- a/application/bi/controller/Customer.php +++ b/application/bi/controller/Customer.php @@ -10,6 +10,7 @@ use app\admin\controller\ApiCommon; use think\Hook; use think\Request; +use think\Db; class Customer extends ApiCommon { @@ -23,7 +24,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['statistics'] + 'allow'=>['statistics','total','recordtimes','recordlist','recordmode','conversion','conversioninfo','pool','poollist','usercycle','productcycle','addresscycle','addressanalyse','portrait'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -31,8 +32,8 @@ public function _initialize() if (!in_array($a, $action['permission'])) { parent::_initialize(); } - } - + } + /** * 员工客户分析 * @author Michael_xu @@ -47,7 +48,633 @@ public function statistics() } $customerModel = new \app\crm\model\Customer(); $param = $this->param; + if ($param['type']) { + $timeArr = getTimeByType($param['type']); + $param['start_time'] = $timeArr[0]; + $param['end_time'] = $timeArr[1]; + } $list = $customerModel->getStatistics($param); return resultArray(['data' => $list]); - } + } + + /** + * 员工客户总量分析 + * @author + * @param + * @return + */ + public function total() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $customerModel = new \app\crm\model\Customer(); + $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['create_user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + $item['customer_num'] = $customerModel->getDataCount($whereArr); + $whereArr['deal_status'] = '已成交'; + $item['deal_customer_num'] = $customerModel->getDataCount($whereArr); + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 员工客户跟进次数分析 + * @author + * @param + * @return + */ + public function recordTimes() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $biCustomerModel = new \app\bi\model\Customer(); + $biRecordModel = new \app\bi\model\Record(); + $userModel = new \app\admin\model\User(); + $param = $this->param; + + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['create_user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + /*跟进次数*/ + $item['dataCount'] = $biRecordModel->getRecordNum($whereArr); + /*跟进客户数*/ + $item['customerCount'] = $biRecordModel->getCustomerNum($whereArr); + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 员工客户跟进次数分析 具体员工列表 + * @author + * @param + * @return + */ + public function recordList() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $biRecordModel = new \app\bi\model\Record(); + $param = $this->param; + if ($param['type']) { + $timeArr = getTimeByType($param['type']); + $param['start_time'] = $timeArr[0]; + $param['end_time'] = $timeArr[1]; + } + $list = $biRecordModel->getDataList($param); + return resultArray(['data' => $list]); + } + + /** + * 员工跟进方式分析 + * @author + * @param + * @return + */ + public function recordMode() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $biCustomerModel = new \app\bi\model\Customer(); + $biRecordModel = new \app\bi\model\Record(); + $param = $this->param; + $whereArr = array(); + $whereArr = $biCustomerModel->getParamByWhere($param,'record'); + $record_categorys = array('打电话','发邮件','发短信','见面拜访','活动'); + $count = $biRecordModel->getRecordNum($whereArr); + + $datas = array(); + foreach ($record_categorys as $key => $value) { + $item = array(); + $whereArr['category'] = $value; + $item['category'] = $value; + $item['recordNum'] = $allCustomer = $biRecordModel->getRecordNum($whereArr); + if(empty($allCustomer) || empty($count)){ + $item['proportion'] = 0; + }else{ + $item['proportion'] = round(($allCustomer/$count),4)*100; + } + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 客户转化率分析 + * @author + * @param + * @return + */ + public function conversion() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $customerModel = new \app\crm\model\Customer(); + $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['create_user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + $item['customer_num'] = $customer_num = $customerModel->getDataCount($whereArr); + $whereArr['deal_status'] = '已成交'; + $item['deal_customer_num'] = $deal_customer_num = $customerModel->getDataCount($whereArr); + if ($customer_num== 0 || $deal_customer_num == 0) { + $item['proportion'] = 0; + } else { + $item['proportion'] = round(($item['deal_customer_num']/$item['customer_num']),4)*100; + } + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 客户转化率分析具体数据 + * @return [type] [description] + */ + public function conversionInfo() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $customerModel = new \app\bi\model\Customer(); + $userModel = new \app\admin\model\User(); + $param = $this->param; + $whereArr = $customerModel->getParamByWhere($param); + $whereArr['deal_status'] = array('eq','已成交'); + $list = $customerModel->getWhereByList($whereArr); + return resultArray(['data' => $list]); + } + + /** + * 公海客户分析 + * @return [type] [description] + */ + public function pool() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $actionRecordModel = new \app\bi\model\ActionRecord(); + $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + + if (empty($param['type']) && empty($param['start_time'])) { + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $whereArr['user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + $whereArr['content'] = '将客户放入公海'; + $item['put_in'] = $actionRecordModel->getDataList($whereArr); + $whereArr['content'] = '领取了客户'; + $item['receive'] = $actionRecordModel->getDataList($whereArr); + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 公海客户分析 具体列表 + * @return [type] [description] + */ + public function poolList() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $param = $this->param; + $userModel = new \app\admin\model\User(); + $actionRecordModel = new \app\bi\model\ActionRecord(); + $customerModel = new \app\crm\model\Customer(); + $structureModel = new \app\admin\model\Structure(); + //员工IDS + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $where['id'] = array('in',$userIds); + $where['type'] = 1; + $userList = db('admin_user')->where($where)->field('id,username,structure_id,realname')->select(); + if ($param['type']) { + $timeArr = getTimeByType($param['type']); + $param['start_time'] = $timeArr[0]; + $param['end_time'] = $timeArr[1]; + } + if ($param['start_time'] && $param['end_time']) { + $create_time = array('between',array($param['start_time'],$param['end_time'])); + } + $whereArr['create_time'] = $create_time; + foreach ($userList as $k=>$v) { + $structure_info = $structureModel->getDataByID($v['structure_id']); + $customer_num = 0; + $whereArr['user_id'] = $v['id']; + $whereArr['content'] = '将客户放入公海'; + $userList[$k]['put_in'] = $actionRecordModel->getDataList($whereArr); + $whereArr['content'] = '领取了客户'; + $userList[$k]['receive'] = $actionRecordModel->getDataList($whereArr); + + $where_c['create_time'] = $create_time; + $where_c['owner_user_id'] = $v['id']; + $customer_num = $customerModel->getDataCount($where_c); + $userList[$k]['customer_num'] = $customer_num; + $userList[$k]['username'] = $structure_info['name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 员工客户成交周期 + * @return [type] [description] + */ + public function userCycle() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $customerModel = new \app\crm\model\Customer(); + $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $company = $biCustomerModel->getParamByCompany($param); + $datas = array(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr['owner_user_id'] = array('in',$userIds); + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + $whereArr['deal_status'] = '已成交'; + $item['customer_num'] = $customerModel->getDataCount($whereArr); + //周期 + $cycle = $biCustomerModel->getWhereByCycle($whereArr); + $item['cycle'] = $cycle ? $cycle : 0; + $item['start_time'] = $start_time; + $item['end_time'] = $end_time; + $datas['items'][] = $item; + } + $where['id'] = array('in',$userIds); + $where['type'] = 1; + $userList = db('admin_user')->where($where)->field('id,username,realname')->select(); + $create_time = []; + if (!empty($param['start_time'])) { + $where_c['create_time'] = array('between',array($param['start_time'],$param['end_time'])); + } else { + $create_time = getTimeByType($param['type']); + if ($create_time) { + $where_c['create_time'] = array('between',array($create_time[0],$create_time[1])); + } + } + foreach ($userList as $k=>$v) { + $customer_num = 0; + $where_c['owner_user_id'] = array('eq',$v['id']); + $where_c['deal_status'] = '已成交'; + $customer_num = $customerModel->getDataCount($where_c); + $customer_cycle = $biCustomerModel->getWhereByCycle($where_c); + $userList[$k]['customer_num'] = $customer_num; + $userList[$k]['cycle'] = $customer_cycle?$customer_cycle:0; + } + $datas['users'] = $userList; + return resultArray(['data' => $datas]); + } + + /** + * 产品成交周期 + * @return [type] [description] + */ + public function productCycle() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $biCustomerModel = new \app\bi\model\Customer(); + $productModel = new \app\bi\model\Product(); + $param = $this->param; + $list = $productModel->getDealByProduct($param); + $datas = array(); + foreach ($list as $key => $value) { + $item = array(); + //周期 + $customer_ids = $productModel->getCycleByProduct($param,$value['product_id']); + $whereArr = array(); + $whereArr['customer_id'] = array('in',$customer_ids); + $cycle = $biCustomerModel->getWhereByCycle($whereArr); + $item['product_name'] = $value['product_name']; + $item['customer_num'] = $value['num']; + $item['cycle'] = $cycle?$cycle:0; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 地区成交周期 + * @return [type] [description] + */ + public function addressCycle() + { + if (!checkPerByAction('bi', 'customer' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $customerModel = new \app\crm\model\Customer(); + $biCustomerModel = new \app\bi\model\Customer(); + $address_arr = array('北京','上海','天津','广东','浙江','海南','福建','湖南','湖北','重庆','辽宁','吉林','黑龙江','河北','河南','山东','陕西','甘肃','青海','新疆','山西','四川','贵州','安徽','江西','江苏','云南','内蒙古','广西','西藏','宁夏', + ); + $param = $this->param; + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $datas = array(); + foreach ($address_arr as $key => $value) { + $item = array(); + $whereArr = array(); + if (!empty($param['start_time'])) { + $start_time = $param['start_time']; + $end_time = $param['end_time']; + $whereArr['create_time'] = array('between',array($param['start_time'],$param['end_time'])); + } else { + $create_time = getTimeByType($param['type']); + $start_time = $create_time[0]; + $end_time = $create_time[1]; + if ($create_time) { + $whereArr['create_time'] = array('between',array($create_time[0],$create_time[1])); + } + } + $whereArr['owner_user_id'] = array('in',$userIds); + $whereArr['address'] = array('like','%'.$value.'%'); + $item['address'] = $value; + $whereArr['deal_status'] = '已成交'; + $item['customer_num'] = $dealCustomer = $customerModel->getDataCount($whereArr); + //周期 + $cycle = $biCustomerModel->getWhereByCycle($whereArr); + $item['cycle'] = $cycle?$cycle:0; + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 客户所在城市分析 + * @author + * @param + * @return + */ + public function addressAnalyse() + { + if (!checkPerByAction('bi', 'portrait' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $customerModel = new \app\crm\model\Customer(); + $userModel = new \app\admin\model\User(); + $address_arr = array('北京','上海','天津','广东','浙江','海南','福建','湖南','湖北','重庆','辽宁','吉林','黑龙江','河北','河南','山东','陕西','甘肃','青海','新疆','山西','四川','贵州','安徽','江西','江苏','云南','内蒙古','广西','西藏','宁夏', + ); + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $datas = array(); + foreach ($address_arr as $key => $value) { + $item = array(); + $whereArr = array(); + $whereArr['address'] = array('like','%'.$value.'%'); + $whereArr['owner_user_id'] = array('in',$userIds); + $item['address'] = $value; + $item['allCustomer'] = $allCustomer = $customerModel->getDataCount($whereArr); + $whereArr['deal_status'] = '已成交'; + $item['dealCustomer'] = $dealCustomer = $customerModel->getDataCount($whereArr); + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } + + /** + * 客户行业/级别/来源分析 + * @author + * @param + * @return + */ + public function portrait() + { + if (!checkPerByAction('bi', 'portrait' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $biCustomerModel = new \app\bi\model\Customer(); + $customerModel = new \app\crm\model\Customer(); + $param = $this->param; + $whereArr = array(); + $whereArr['types'] = array('eq','crm_customer'); + $whereArr['field'] = array('eq',$param['type_analyse']); + $setting = $biCustomerModel->getOptionByField($whereArr); + $setting[] = '未知'; + $datas = array(); + foreach ($setting as $key => $value) { + $item = array(); + $where = array(); + $where = $biCustomerModel->getParamByWhere($param); + if($value != '未知'){ + $where[$param['type_analyse']] = array('eq',$value); + }else{ + $where[$param['type_analyse']] = array('eq',''); + } + $item[$param['type_analyse']] = $value; + $item['allCustomer'] = $customerModel->getDataCount($where); + + $where['deal_status'] = '已成交'; + $item['dealCustomer'] = $customerModel->getDataCount($where); + $datas[] = $item; + } + return resultArray(['data' => $datas]); + } } diff --git a/application/bi/controller/Product.php b/application/bi/controller/Product.php index d5645266..9c0a2202 100644 --- a/application/bi/controller/Product.php +++ b/application/bi/controller/Product.php @@ -23,7 +23,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['statistics'] + 'allow'=>['statistics','productcategory'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -49,5 +49,21 @@ public function statistics() $param = $this->param; $list = $productModel->getStatistics($param); return resultArray(['data' => $list]); - } + } + + /** + * 产品分类销量分析 + * @return [type] [description] + */ + public function productCategory() + { + if (!checkPerByAction('bi', 'product' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $productModel = new \app\bi\model\Product(); + $param = $this->param; + $list = $productModel->getStatistics($param); + return resultArray(['data' => $list]); + } } diff --git a/application/bi/controller/Ranking.php b/application/bi/controller/Ranking.php new file mode 100644 index 00000000..98248434 --- /dev/null +++ b/application/bi/controller/Ranking.php @@ -0,0 +1,312 @@ +[''], + 'allow'=>['contract','receivables','signing','addcustomer','addcontacts','recordnun','recordcustomer','examine','product'] + ]; + Hook::listen('check_auth',$action); + $request = Request::instance(); + $a = strtolower($request->action()); + if (!in_array($a, $action['permission'])) { + parent::_initialize(); + } + } + + /** + * 合同金额排行 + * @author Michael_xu + * @param + * @return + */ + public function contract() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $contractModel = new \app\bi\model\Contract(); + $param = $this->param; + $whereArr = $this->com($param,'contract'); + $whereArr['check_status'] = array('eq',2); + $userList = $contractModel->getSortByMoney($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['owner_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 回款金额排序 + * @return [type] [description] + */ + public function receivables() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $receivablesModel = new \app\bi\model\Receivables(); + $param = $this->param; + $userModel = new \app\admin\model\User(); + //员工IDS + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $userIds = $map_user_ids ? $map_user_ids : []; //数组交集 + $create_time = []; + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + if(!empty($param['start_time'])){ + $whereArr['return_time'] = array('between',array($param['start_time'],$param['end_time'])); + }else{ + $create_time = getTimeByType($param['type']); + if ($create_time) { + $whereArr['return_time'] = array('between',array(date('Y-m-d',$create_time[0]),date('Y-m-d',$create_time[1]))); + } + } + $whereArr['create_user_id'] = array('in',$userIds); + $whereArr['check_status'] = array('eq',2); + $userList = $receivablesModel->getSortByMoney($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['owner_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 签约合同排序 + * @return [type] [description] + */ + public function signing() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $contractModel = new \app\bi\model\Contract(); + $param = $this->param; + $whereArr = $this->com($param,'contract'); + $whereArr['check_status'] = array('eq',2); + $userList = $contractModel->getSortByCount($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['owner_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 新增客户排序 + * @return [type] [description] + */ + public function addCustomer() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $customerModel = new \app\bi\model\Customer(); + $param = $this->param; + $whereArr = $this->com($param,'record'); + $userList = $customerModel->getSortByCount($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['owner_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 新增联系人排序 + * @return [type] [description] + */ + public function addContacts() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $contactsModel = new \app\bi\model\Contacts(); + $param = $this->param; + $whereArr = $this->com($param,'record'); + $userList = $contactsModel->getSortByCount($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['owner_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 跟进次数排行 + * @return [type] [description] + */ + public function recordNun() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $recordModel = new \app\bi\model\Record(); + $param = $this->param; + $whereArr = $this->com($param,'record'); + $userList = $recordModel->getSortByCount($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['create_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 跟进客户数排行 + * @return [type] [description] + */ + public function recordCustomer() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $recordModel = new \app\bi\model\Record(); + $param = $this->param; + $whereArr = $this->com($param,'record'); + $userList = $recordModel->getSortByCustomer($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['create_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 出差次数排行 + * @return [type] [description] + */ + public function examine() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $examineModel = new \app\bi\model\Examine(); + $param = $this->param; + $whereArr = $this->com($param,'record'); + $whereArr['category_id'] = array('eq',3); + $userList = $examineModel->getSortByExamine($whereArr); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['create_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + /** + * 产品销量排行 + * @return [type] [description] + */ + public function product() + { + if (!checkPerByAction('bi', 'ranking' , 'read')) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $userModel = new \app\admin\model\User(); + $productModel = new \app\bi\model\Product(); + $param = $this->param; + $userList = $productModel->getSortByProduct($param); + foreach ($userList as $key => $value) { + $user = $userModel->getDataById($value['owner_user_id']); + $userList[$key]['user_name'] = $user['realname']; + $userList[$key]['structure_name'] = $user['structure_name']; + } + return resultArray(['data' => $userList]); + } + + public function com($param,$type='') + { + $userModel = new \app\admin\model\User(); + //员工IDS + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $userIds = $map_user_ids ? $map_user_ids : []; //数组交集 + $create_time = []; + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + if($type == 'contract'){ + $where_time = 'order_date'; + }else if ($type == 'record') { + $where_time = 'create_time'; + }else{ + $where_time = 'start_time'; + } + //时间戳:新增客户排行 + if(!empty($param['start_time'])){ + $whereArr[$where_time] = array('between',array($param['start_time'],$param['end_time'])); + }else{ + $create_time = getTimeByType($param['type']); + if ($create_time) { + if($type == 'contract'){ + $whereArr[$where_time] = array('between',array(date('Y-m-d',$create_time[0]),date('Y-m-d',$create_time[1]))); + }else{ + $whereArr[$where_time] = array('between',array($create_time[0],$create_time[1])); + } + } + } + $whereArr['create_user_id'] = array('in',$userIds); + return $whereArr; + } +} \ No newline at end of file diff --git a/application/bi/controller/Receivables.php b/application/bi/controller/Receivables.php index de5310cf..501490fd 100644 --- a/application/bi/controller/Receivables.php +++ b/application/bi/controller/Receivables.php @@ -97,5 +97,5 @@ public function statistics() $chartParam['userIds'] = $userIds ? : []; $chartList = $receivablesModel->getStatistics($chartParam); //柱状图 return resultArray(['data' => $chartList]); - } + } } diff --git a/application/bi/model/ActionRecord.php b/application/bi/model/ActionRecord.php new file mode 100644 index 00000000..b9c47c6f --- /dev/null +++ b/application/bi/model/ActionRecord.php @@ -0,0 +1,33 @@ +where($request)->count(); + return $dataCount; + } +} \ No newline at end of file diff --git a/application/bi/model/Business.php b/application/bi/model/Business.php new file mode 100644 index 00000000..a73e4d09 --- /dev/null +++ b/application/bi/model/Business.php @@ -0,0 +1,85 @@ +where($whereArr)->where($where)->count('business_id'); + $count = $dataCount ? : 0; + return $count; + } + /** + * [getDataMoney 商机金额] + * @author Michael_xu + * @param [string] $map [查询条件] + * @param [number] $page [当前页数] + * @param [number] $limit [每页数量] + * @return [array] [description] + */ + function getDataMoney($whereArr) + { + $where = []; + $money = $this->where($whereArr)->where($where)->sum('money'); + return $money; + } + /** + * 获取商机list + * @return [type] [description] + */ + function getDataList($request) + { + $userModel = new \app\admin\model\User(); + $request = $this->fmtRequest( $request ); + $map = $request['map'] ? : []; + //员工IDS + $map_user_ids = []; + if ($map['user_id']) { + $map_user_ids = array($map['user_id']); + } else { + if ($map['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($map['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $where['owner_user_id'] = array('in',$userIds); + + $start_time = $map['start_time']; + $end_time = $map['end_time']; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $where['create_time'] = $create_time; + $dataList = db('crm_business')->field('business_id,customer_id,money,type_id,status_id,deal_date,create_user_id,owner_user_id')->where($where)->select(); + return $dataList; + } +} \ No newline at end of file diff --git a/application/bi/model/Contacts.php b/application/bi/model/Contacts.php new file mode 100644 index 00000000..a002e755 --- /dev/null +++ b/application/bi/model/Contacts.php @@ -0,0 +1,35 @@ +group('owner_user_id')->field('owner_user_id,count(contacts_id) as count')->where($whereArr)->select(); + return $count; + } +} \ No newline at end of file diff --git a/application/bi/model/Contract.php b/application/bi/model/Contract.php new file mode 100644 index 00000000..c42ca882 --- /dev/null +++ b/application/bi/model/Contract.php @@ -0,0 +1,78 @@ +'待审核','1'=>'审核中','2'=>'审核通过','3'=>'已拒绝','4'=>'已撤回']; + + /** + * [getDataList 合同金额] + * @author Michael_xu + * @param [string] $map [查询条件] + * @param [number] $page [当前页数] + * @param [number] $limit [每页数量] + * @return [array] [description] + */ + function getWhereByMoney($whereArr) + { + $money = db('crm_contract')->where($whereArr)->sum('money'); + return $money; + } + /** + * [getSortByMoney 根据合同金额排序] + * @param [type] $whereArr [description] + * @return [type] [description] + */ + function getSortByMoney($whereArr) + { + $money = db('crm_contract')->group('owner_user_id')->field('owner_user_id,sum(money) as money')->where($whereArr)->select(); + return $money; + } + /** + * [getDataList 根据合同签约数排序] + * @author Michael_xu + * @param [string] $map [查询条件] + * @param [number] $page [当前页数] + * @param [number] $limit [每页数量] + * @return [array] [description] + */ + function getSortByCount($whereArr) + { + $money = db('crm_contract')->group('owner_user_id')->field('owner_user_id,count(contract_id) as count')->where($whereArr)->select(); + return $money; + } + /** + * 获取合同数量 + * @return [type] [description] + */ + function getDataCount($whereArr){ + $count = db('crm_contract')->where($whereArr)->count('contract_id'); + return $count; + } + /** + * 获取合同金额 + * @return [type] [description] + */ + function getDataMoney($whereArr){ + $money = db('crm_contract')->where($whereArr)->sum('money'); + return $money; + } +} \ No newline at end of file diff --git a/application/bi/model/Customer.php b/application/bi/model/Customer.php new file mode 100644 index 00000000..9685a2a7 --- /dev/null +++ b/application/bi/model/Customer.php @@ -0,0 +1,511 @@ + 'timestamp', + ]; + /** + * 获取转化客户信息 + * @param [type] $whereArr [description] + * @return [type] [description] + */ + function getWhereByList($whereArr) + { + $userModel = new \app\admin\model\User(); + $receivables = new \app\bi\model\Receivables(); + + $list = db('crm_customer')->field('customer_id,name,owner_user_id,create_user_id,industry,source,create_time')->where($whereArr)->select(); + foreach ($list as $key => $value) { + $where_c = array(); + $where_c['customer_id'] = array('eq',$value['customer_id']); + $contract = db('crm_contract')->field('contract_id,name,money,create_time,order_date')->order('contract_id asc')->limit(1)->where($where_c)->find(); + $list[$key]['create_time'] = date('Y-m-d',$value['create_time']); + $list[$key]['contract_name'] = $contract['name']; + $list[$key]['contract_money'] = $contract['money']; + $list[$key]['order_time'] = $contract['order_date']; + $owner_user = $userModel->getDataById($value['owner_user_id']); + $list[$key]['owner_realname'] = $owner_user['realname']; + $create_user = $userModel->getDataById($value['create_user_id']); + $list[$key]['create_realname'] = $create_user['realname']; + $where_c['contract_id'] = array('eq',$contract['contract_id']); + $r_money = $receivables->getDataMoney($where_c); + $list[$key]['r_money'] = $r_money; + } + return $list; + } + /** + * 根据条件获取开始、结束时间 + * @param [type] $type [description] + * @param [type] $year [description] + * @param [type] $i [description] + * @return [type] [description] + */ + function getStartAndEnd($param,$year,$i) + { + $timeArr = array(); + switch($param['type']) { + case 'year'://本年度 + $timeArr['month'] = $i; + $timeArr['next_month'] = $i+1; + if($timeArr['next_month'] != 13){ + $timeArr['year'] = $year; + $timeArr['next_year'] = $year; + }else{ + $timeArr['year'] = $year; + $timeArr['next_year'] = $year+1; + $timeArr['next_month'] = 1; + } + $timeArr['type'] = $year.'-'.$i; + break; + case 'lastYear'://上年度 + $timeArr['month'] = $i; + $timeArr['next_month'] = $i+1; + if($timeArr['next_month'] != 13){ + $timeArr['year'] = $year; + $timeArr['next_year'] = $year; + }else{ + $timeArr['year'] = $year; + $timeArr['next_year'] = $year+1; + $timeArr['next_month'] = 1; + } + $timeArr['type'] = $year.'-'.$i; + break; + case 'quarter'://本季度 + $season = ceil(date('n')/3); + $dates = mktime(0,0,0,($season-1)*3+1,1,date('Y')); + $month = date('m',$dates); + $timeArr['year'] = $year; + $timeArr['month'] = $month+$i-1; + if($month != 10){ + $timeArr['next_year'] = $year; + $timeArr['next_month'] = $month+$i; + $timeArr['type'] = $year.'-'.($month+$i-1); + }else{ + if($month+$i <= 12){ + $timeArr['next_year'] = $year; + $timeArr['next_month'] = $month+$i; + $timeArr['type'] = $year.$month+$i; + }else{ + $timeArr['next_year'] = $year+1; + $timeArr['next_month'] = 1; + $timeArr['type'] = ($year+1).'-'.'01'; + } + } + break; + case 'lastQuarter'://上季度 + $season = ceil(date('n')/3); + $dates = mktime(0,0,0,($season-1)*3+1,1,date('Y')); + $month = date('m',$dates); + if($month > 3){ + $timeArr['year'] = $year; + $month = $month-3; + $timeArr['month'] = $month+$i-1; + $timeArr['next_year'] = $year; + $timeArr['next_month'] = $month+$i; + $timeArr['type'] = $year.'-'.($month+$i-1); + }else{ + $month = 10; + $timeArr['year'] = $year-1; + $timeArr['month'] = $month+$i-1; + if($month+$i <= 12){ + $timeArr['next_year'] = $year-1; + $timeArr['next_month'] = $month+$i; + }else{ + $timeArr['next_year'] = $year; + $timeArr['next_month'] = 1; + } + $timeArr['type'] = $year.'-'.$month+$i-1; + } + + break; + case 'month'://本月 + $timeArr['year'] = $year; + $timeArr['month'] = date('m'); + $timeArr['next_year'] = $year; + $timeArr['day'] = $i; + if($i != date("t")){ + $timeArr['next_month'] = date('m'); + $timeArr['next_day'] = $i+1; + }else{ + $timeArr['next_month'] = date('m')+1; + $timeArr['next_day'] = 1; + } + // if($i != date("t")){ + // $timeArr['day'] = $i; + // $timeArr['next_day'] = $i+1; + // $timeArr['month'] = date('m'); + // $timeArr['next_month'] = date('m'); + // }else{ + // $timeArr['day'] = $i; + // $timeArr['next_day'] = 1; + // $timeArr['month'] = date('m'); + // if(date('m') != 12){ + // $timeArr['next_month'] = date('m')+1; + // }else{ + // $timeArr['next_month'] = 1; + // $timeArr['next_year'] = $year+1; + // } + // } + $timeArr['type'] = $year.'-'.date('m').'-'.$i; + break; + case 'lastMonth'://上月 + $timeArr['year'] = $year; + $month = date('m');//当前月 + if($month != 1){ + $month = $month-1;//上月 + $days = date('t', strtotime(date('Y').'-'.$month.'-1'));//上月天数 + $timeArr['next_year'] = $year; + if($i != $days){ + $timeArr['day'] = $i; + $timeArr['next_day'] = $i+1; + $timeArr['month'] = $month; + $timeArr['next_month'] = $month; + }else{ + $timeArr['day'] = $i; + $timeArr['next_day'] = 1; + $timeArr['month'] = $month; + if($month != 12){ + $timeArr['next_month'] = $month+1; + }else{ + $timeArr['next_month'] = 1; + $timeArr['next_year'] = $year; + } + } + }else{ + $month = 12; + $timeArr['year'] = $year-1; + $timeArr['next_year'] = $year; + } + $timeArr['type'] = $year.'-'.$month.'-'.$i; + break; + case 'week'://本周 + date_default_timezone_set('PRC'); + $week = date("Y-m-d",strtotime("this week")); + $day = strtotime($week)+($i-1)*(60*60*24); + $lastDay = strtotime($week)+$i*(60*60*24); + $timeArr['day'] = date("d",$day); + $timeArr['next_day'] = date("d",$lastDay); + $timeArr['month'] = date("m",$day); + $timeArr['next_month'] = date("m",$lastDay); + $timeArr['year'] = date("y",$day); + $timeArr['next_year'] = date("y",$lastDay); + $timeArr['type'] = $year.'-'.date("m",$day).'-'.date("d",$day); + break; + case 'lastWeek'://上周 + date_default_timezone_set('PRC'); + $week = date("Y-m-d",strtotime("this week")); + $day = strtotime($week)+($i-8)*(60*60*24); + $lastDay = strtotime($week)+($i-7)*(60*60*24); + $timeArr['day'] = date("d",$day); + $timeArr['next_day'] = date("d",$lastDay); + $timeArr['month'] = date("m",$day); + $timeArr['next_month'] = date("m",$lastDay); + $timeArr['year'] = date("y",$day); + $timeArr['next_year'] = date("y",$lastDay); + $timeArr['type'] = $year.'-'.date("m",$day).'-'.date("d",$day); + break; + case 'today'://今天 + $today = time(); + $yesterday = time()+60*60*24; + $timeArr['day'] = date("d",$today); + $timeArr['next_day'] = date("d",$yesterday); + $timeArr['month'] = date("m",$today); + $timeArr['next_month'] = date("m",$yesterday); + $timeArr['year'] = date("y",$today); + $timeArr['next_year'] = date("y",$yesterday); + $timeArr['type'] = $year.'-'.date("m",$today).'-'.date("d",$today); + break; + case 'yesterday'://昨天 + $today = time()-60*60*24; + $yesterday = time(); + $timeArr['day'] = date("d",$today); + $timeArr['next_day'] = date("d",$yesterday); + $timeArr['month'] = date("m",$today); + $timeArr['next_month'] = date("m",$yesterday); + $timeArr['year'] = date("y",$today); + $timeArr['next_year'] = date("y",$yesterday); + $timeArr['type'] = $year.'-'.date("m",$today).'-'.date("d",$today); + break; + case 'month_k'://跨月 + $start_time_y = date('y',strtotime($param['start_time'])); + $timeArr['year'] = $start_time_y; + $timeArr['next_year'] = $start_time_y; + $m = date('m',strtotime($start_time)); + if($i > 1){ + $timeArr['month'] = $m+$i-1; + $timeArr['next_month'] = $m+$i; + $timeArr['type'] = '20'.$start_time_y.'-'.($m+$i-1); + }else{ + $timeArr['month'] = $m; + $timeArr['next_month'] = $m+1; + $timeArr['type'] = '20'.$start_time_y.'-'.$m; + } + break; + case 'year_k'://跨年 + $start_time = $param['start_time']; + $end_time = $param['end_time']; + + $start_y = date('y',strtotime($start_time)); + $start_m = date('m',strtotime($start_time)); + $start_d = date('d',strtotime($start_time)); + + $monthNum = $this->getMonthNum(strtotime($start_time),strtotime($end_time)); + $y = ceil(($start_m+$i-1)/12); + if(($start_m+$i-1)/12 <= $y){ + if($i == 1){ + $timeArr['day'] = $start_d; + $timeArr['end_d'] = 1; + } + $timeArr['year'] = $start_y+$y-1; + if($start_m+$i-1 < 12){ + $timeArr['month'] = $start_m+$i-1; + $timeArr['next_year'] = $start_y+$y-1; + $timeArr['next_month'] = $start_m+$i; + $timeArr['type'] = '20'.($start_y+$y-1).'-'.($start_m+$i-1); + }else{ + if(($start_m+$i-1)/12 == $y){ + $timeArr['month'] = 12; + $timeArr['next_year'] = $start_y+$y; + $timeArr['next_month'] = 1; + $timeArr['type'] = '20'.($start_y+$y-1).'-12'; + }else{ + $timeArr['month'] = ($start_m+$i-1)-12*($y-1); + $timeArr['next_year'] = $start_y+$y-1; + if ($monthNum+1 != $i) { + $timeArr['next_month'] = ($start_m+$i)-12*($y-1); + }else{ + $end_d = date('d',$param['end_time']); + $timeArr['next_day'] = $end_d; + $timeArr['next_month'] = ($start_m+$i-1)-12*($y-1); + } + $timeArr['type'] = '20'.($start_y+$y-1).'-'.(($start_m+$i-1)-12*($y-1)); + } + } + } + break; + default ://自定义时间 + $start_time = strtotime($param['start_time']); + $end_time = strtotime($param['end_time']); + + $start_time_y = date('y',$start_time); + $start_time_m = date('m',$start_time); + $end_time_y = date('y',$end_time); + $end_time_m = date('m',$end_time); + if($end_time_y-$start_time_y == 0){//不跨年 + if($end_time_m-$start_time_m > 0){ + $param['type']='month_k'; + $timeArr = $this->getStartAndEnd($param,$year,$i); + }else{//不跨月 + $param['type']='month'; + $timeArr = $this->getStartAndEnd($param,$year,$i); + } + }else{//跨年 + $start_time = date('Y-m-d',$start_time); + $end_time = date('Y-m-d',$end_time); + $monthNum = $this->getMonthNum($start_time,$end_time); + $param['type']='year_k'; + $timeArr = $this->getStartAndEnd($param,$year,$i); + } + break; + } + return $timeArr; + } + + /** + * 根据条件获取单位 + * @return [type] [description] + */ + function getParamByCompany($param) + { + $company['year'] = date('Y'); + $company['month'] = date('m'); + switch($param['type']) { + case 'year'://本年度 + $company['j'] = 12; + break; + case 'lastYear'://上年度 + $company['j'] = 12; + $company['year'] = date('Y')-1; + break; + case 'quarter'://本季度 + $company['j'] = 3; + break; + case 'lastQuarter'://上季度 + $company['j'] = 3; + break; + case 'month'://本月 + $company['j'] = date("t"); + break; + case 'lastMonth'://上月 + if(date('m') == 1){ + $m = 12; + }else{ + $m = date('m')-1; + } + $days = date('t', strtotime(date('Y').'-'.$m.'-1')); + $company['j'] = $days; + break; + case 'week'://本周 + $company['j'] = 7; + break; + case 'lastWeek'://上周 + $company['j'] = 7; + break; + case 'today'://今天 + $company['j'] = 1; + break; + case 'yesterday'://昨天 + $company['j'] = 1; + break; + default ://自定义时间 + $start_time = strtotime($param['start_time']); + $end_time = strtotime($param['end_time']); + $company['start_time_y'] = $start_time_y = date('y',$start_time); + $start_time_m = date('m',$start_time); + $end_time_y = date('y',$end_time); + $end_time_m = date('m',$end_time); + if($end_time_y-$start_time_y == 0){//不跨年 + if($end_time_m-$start_time_m > 0){//跨月 + $company['type']='month_k'; + $company['time_unit'] = '月'; + $company['j'] = $end_time_m-$start_time_m+1; + }else{//不跨月 + $company['type']='month'; + $company['j'] = date("t"); + } + }else{//跨年 + $start_time = date('Y-m-d',$start_time); + $end_time = date('Y-m-d',$end_time); + $monthNum = $this->getMonthNum($start_time,$end_time); + $company['type']='year_k'; + $company['j'] = $monthNum+1; + } + break; + } + return $company; + } + function getMonthNum($start_m, $end_m){ + $date1 = explode('-',$start_m); + $date2 = explode('-',$end_m); + if($date1[1]<$date2[1]){ //判断月份大小,进行相应加或减 + $month_number= abs($date1[0] - $date2[0]) * 12 + abs($date1[1] - $date2[1]); + }else{ + $month_number= abs($date1[0] - $date2[0]) * 12 - abs($date1[1] - $date2[1]); + } + return $month_number; + } + /** + * 根据数据获取查询条件 + * @param [type] $param [description] + * @return [type] [description] + */ + function getParamByWhere($param,$type='') + { + $userModel = new \app\admin\model\User(); + $whereArr = array(); + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + //时间戳:客户跟进分析 、客户转化率分析 + if(!empty($param['start_time'])){ + $whereArr['create_time'] = array('between',array($param['start_time'],$param['end_time'])); + // $whereArr['create_time'] = array('between',array(date('Y-m-d',$param['start_time']),date('Y-m-d',$param['end_time']))); + }else{ + $create_time = getTimeByType($param['type']); + if ($create_time) { + $whereArr['create_time'] = array('between',array($create_time[0],$create_time[1])); + } + } + + $map_user_ids = []; + if ($param['user_id']) { + $map_user_ids = array($param['user_id']); + } else { + if ($param['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + if($type && $type == 'record'){ + $whereArr['create_user_id'] = array('in',$userIds); + }else{ + $whereArr['owner_user_id'] = array('in',$userIds); + } + return $whereArr; + } + /** + * 根据自定义字段获取 下拉框数据 + */ + function getOptionByField($whereArr) + { + $setting = db('admin_field')->where($whereArr)->field('setting')->find(); + return explode(chr(10),$setting['setting']); + } + /** + * 根据新增客户数排序 + * @param [type] $whereArr [description] + * @return [type] [description] + */ + function getSortByCount($whereArr) + { + $count = db('crm_customer')->group('owner_user_id')->field('owner_user_id,count(customer_id) as count')->where($whereArr)->select(); + return $count; + } + /** + * 获取成交周期 + * @return [type] [description] + */ + function getWhereByCycle($whereArr) + { + $customer_ids = db('crm_customer')->field('customer_id')->where($whereArr)->select(); + //首次成交 + if(!empty($customer_ids)){ + $cycle_num = 0; + $customer_num = 0; + foreach ($customer_ids as $key => $value) { + $where = array(); + $where['customer_id'] = array('eq',$value['customer_id']); + $create_time = db('crm_customer')->field('create_time')->where($where)->find(); + $where['check_status'] = array('eq',2); + $order_date = db('crm_contract')->where($where)->order('order_date asc')->field('order_date')->find(); + $cycle_time = ceil((strtotime($order_date['order_date'])-$create_time['create_time'])/86400); + if($cycle_time < 0){ + $cycle_num = $cycle_num+0; + $customer_num = $customer_num+0; + }else{ + $cycle_num += $cycle_time; + $customer_num ++; + } + } + if($cycle_num==0 || $customer_num==0){ + $cycle = 0; + }else{ + $cycle = ceil($cycle_num/$customer_num); + } + + } + return $cycle; + } +} \ No newline at end of file diff --git a/application/bi/model/Examine.php b/application/bi/model/Examine.php new file mode 100644 index 00000000..d0632e32 --- /dev/null +++ b/application/bi/model/Examine.php @@ -0,0 +1,39 @@ +'待审核','1'=>'审核中','2'=>'审核通过','3'=>'已拒绝','4'=>'已撤回']; + /** + * [getDataList 出差] + * @author Michael_xu + * @param [string] $map [查询条件] + * @param [number] $page [当前页数] + * @param [number] $limit [每页数量] + * @return + */ + public function getSortByExamine($whereArr) + { + $count = db('oa_examine')->group('create_user_id')->field('create_user_id,count(examine_id) as count')->where($whereArr)->select(); + return $count; + } +} \ No newline at end of file diff --git a/application/bi/model/Product.php b/application/bi/model/Product.php new file mode 100644 index 00000000..c9b0607d --- /dev/null +++ b/application/bi/model/Product.php @@ -0,0 +1,173 @@ +getWhere($request); + $join = [ + ['__CRM_CONTRACT__ contract', 'contract.contract_id = a.contract_id', 'LEFT'], + ['__ADMIN_USER__ user', 'user.id = contract.owner_user_id', 'LEFT'], + ['__CRM_PRODUCT__ product', 'product.product_id = a.product_id', 'LEFT'], + ['__CRM_PRODUCT_CATEGORY__ product_category', 'product_category.category_id = product.category_id', 'LEFT'], + ]; + + $list = db('crm_contract_product') + ->alias('a') + ->where($where) + ->join($join) + ->group('a.product_id') + ->field('a.product_id,sum(a.num) as num,product.name as product_name,product_category.name as category_id_info,product_category.category_id') + ->select(); + return $list; + } + /** + * 产品成交客户数 + * @param [type] $request [description] + * @return [type] [description] + */ + function getDealByProduct($request) + { + $where = $this->getWhere($request); + $where['customer.deal_status'] = '已成交'; + $join = [ + ['__CRM_CONTRACT__ contract', 'contract.contract_id = a.contract_id', 'LEFT'], + ['__ADMIN_USER__ user', 'user.id = contract.owner_user_id', 'LEFT'], + ['__CRM_PRODUCT__ product', 'product.product_id = a.product_id', 'LEFT'], + ['__CRM_PRODUCT_CATEGORY__ product_category', 'product_category.category_id = product.category_id', 'LEFT'], + ['__CRM_CUSTOMER__ customer', 'customer.customer_id = contract.customer_id', 'LEFT'], + ]; + + $list = db('crm_contract_product') + ->alias('a') + ->where($where) + ->join($join) + ->group('a.product_id') + ->field('a.product_id,count(customer.customer_id) as num,product.name as product_name,product_category.name as category_id_info,product_category.category_id') + ->select(); + return $list; + } + /** + * 产品成交周期 + * @param [type] $request [description] + * @return [type] [description] + */ + function getCycleByProduct($request,$product_id) + { + $where = $this->getWhere($request); + $where['customer.deal_status'] = '已成交'; + $where['a.product_id'] = $product_id; + $join = [ + ['__CRM_CONTRACT__ contract', 'contract.contract_id = a.contract_id', 'LEFT'], + ['__ADMIN_USER__ user', 'user.id = contract.owner_user_id', 'LEFT'], + ['__CRM_PRODUCT__ product', 'product.product_id = a.product_id', 'LEFT'], + ['__CRM_PRODUCT_CATEGORY__ product_category', 'product_category.category_id = product.category_id', 'LEFT'], + ['__CRM_CUSTOMER__ customer', 'customer.customer_id = contract.customer_id', 'LEFT'], + ]; + + $list = db('crm_contract_product') + ->alias('a') + ->where($where) + ->join($join) + ->order('order_date') + ->group('customer.customer_id') + ->field('customer.customer_id') + ->select(); + $customer_ids = array(); + foreach ($list as $key => $value) { + $customer_ids[] = $value['customer_id']; + } + return $customer_ids; + } + /** + * 产品销量排行 + * @param [type] $whereArr [description] + * @return [type] [description] + */ + function getSortByProduct($request) + { + $where = $this->getWhere($request); + + $join = [ + ['__CRM_CONTRACT__ contract', 'contract.contract_id = a.contract_id', 'LEFT'], + ['__ADMIN_USER__ user', 'user.id = contract.owner_user_id', 'LEFT'], + ['__CRM_PRODUCT__ product', 'product.product_id = a.product_id', 'LEFT'], + ['__CRM_PRODUCT_CATEGORY__ product_category', 'product_category.category_id = product.category_id', 'LEFT'], + ]; + + $list = db('crm_contract_product') + ->alias('a') + ->where($where) + ->join($join) + ->group('contract.owner_user_id') + ->field('sum(a.num) as num,contract.owner_user_id') + ->select(); + return $list; + } + /** + * 获取条件 + * @param [type] $request [description] + * @return [type] [description] + */ + function getWhere($request) + { + $userModel = new \app\admin\model\User(); + $where = []; + //时间段 + if(empty($request['type']) && empty($request['start_time'])){ + $request['type'] = 'month'; + } + if(!empty($request['start_time'])){ + $where['contract.order_date'] = array('between',array($request['start_time'],$request['end_time'])); + }else{ + $create_time = getTimeByType($request['type']); + if ($create_time) { + $where['contract.create_time'] = array('between',array($create_time[0],$create_time[1])); + } + } + if(!empty($request['category_id'])){ + $where['product_category.category_id'] = array('eq',$request['category_id']); + } + $where['contract.check_status'] = array('eq',2); + //员工IDS + $map_user_ids = []; + if ($request['user_id']) { + $map_user_ids = [$request['user_id']]; + } else { + if ($request['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($request['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'product', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $where['contract.owner_user_id'] = array('in',$userIds); + return $where; + } +} \ No newline at end of file diff --git a/application/bi/model/Receivables.php b/application/bi/model/Receivables.php new file mode 100644 index 00000000..b8270c87 --- /dev/null +++ b/application/bi/model/Receivables.php @@ -0,0 +1,46 @@ +'待审核','1'=>'审核中','2'=>'审核通过','3'=>'已拒绝','4'=>'已撤回']; + /** + * [getDataList 根据回款金额排序] + * @author Michael_xu + * @param [string] $map [查询条件] + * @param [number] $page [当前页数] + * @param [number] $limit [每页数量] + * @return [array] [description] + */ + function getSortByMoney($whereArr) + { + $money = db('crm_receivables')->group('owner_user_id')->field('owner_user_id,sum(money) as money')->where($whereArr)->select(); + return $money; + } + /** + * 获取回款金额 + * @return [type] [description] + */ + function getDataMoney($whereArr){ + $money = db('crm_receivables')->where($whereArr)->sum('money'); + return $money; + } +} \ No newline at end of file diff --git a/application/bi/model/Record.php b/application/bi/model/Record.php new file mode 100644 index 00000000..dc833160 --- /dev/null +++ b/application/bi/model/Record.php @@ -0,0 +1,112 @@ +getSubUserByStr($request['structure_id'], 2); + } + } + $perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds + $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 + $where['id'] = array('in',$userIds); + $where['type'] = 1; + $userList = db('admin_user')->where($where)->field('id,username,realname')->select(); + foreach ($userList as $k=>$v) { + $whereArr = []; + $customer_num = 0; //跟进客户数 + $record_num = 0; //跟进次数 + $whereArr['create_user_id'] = $v['id']; + + $start_time = $request['start_time']; + $end_time = $request['end_time']; + + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + $userList[$k]['customer_num'] = $customer_num = $this->getCustomerNum($whereArr); + $userList[$k]['record_num'] = $record_num = $this->getRecordNum($whereArr); + } + return $userList ? : []; + } + /** + * 根据条件获取跟进客户数 + * @param [type] $type [description] + * @param [type] $year [description] + * @param [type] $i [description] + * @return [type] [description] + */ + function getCustomerNum($whereArr){ + $dataCount = db('admin_record')->where($whereArr)->group('types_id')->count(); + return $dataCount; + } + /** + * [根据条件获取跟进次数] + * @author Michael_xu + * @param + * @return + */ + function getRecordNum($whereArr){ + $dataCount = db('admin_record')->where($whereArr)->count(); + return $dataCount; + } + /** + * 跟进次数排行 + * @param [type] $whereArr [description] + * @return [type] [description] + */ + function getSortByCount($whereArr) + { + $count = db('admin_record')->group('create_user_id')->field('create_user_id,count(record_id) as count')->where($whereArr)->select(); + return $count; + } + /** + * 跟进客户排行 + * @param [type] $whereArr [description] + * @return [type] [description] + */ + function getSortByCustomer($whereArr) + { + $list = db('admin_record')->group('create_user_id')->field('create_user_id')->where($whereArr)->select(); + foreach ($list as $key => $value) { + $where = array(); + $where['create_user_id'] = array('eq',$value['create_user_id']); + $list[$key]['count'] = count(db('admin_record')->group('types_id')->field('count(types_id) as count')->where($where)->select()); + } + return $list; + } +} \ No newline at end of file diff --git a/application/common.php b/application/common.php index 47a31695..ea343649 100644 --- a/application/common.php +++ b/application/common.php @@ -189,6 +189,9 @@ function where_arr($array = [], $m = '', $c = '', $a = '') } elseif (!empty($v['value'])) { if (in_array($k, $check_field_arr)) { $where[$c.$k] = field($v['value'], 'contains'); + } elseif (($c == 'business' || $c == 'business.') && $k == 'type_id') { + $where[$c.'type_id'] = field($v['type_id'], 'eq'); + $where[$c.'status_id'] = field($v['status_id'], 'eq'); } else { $where[$c.$k] = field($v['value'], $v['condition']); } @@ -586,10 +589,12 @@ function updateActionLog($user_id, $types, $action_id, $oldData = [], $newData = $structureModel = new \app\admin\model\Structure(); $field_arr = $fieldModel->getField(['types' => $types,'unFormType' => ['file','form']]); //获取字段属性 $newFieldArr = array(); + $unField = ['update_time','create_time']; //定义过滤字段 foreach ($field_arr as $k=>$v) { - $newFieldArr[$v['field']] = $v; + if (!in_array($v['field'],$unField)) { + $newFieldArr[$v['field']] = $v; + } } - $unField = ['update_time']; //定义过滤字段 $message = []; $un_form_type = ['file','form']; foreach ($differentData as $k=>$v) { diff --git a/application/crm/controller/Business.php b/application/crm/controller/Business.php index 56c86311..3bf02491 100644 --- a/application/crm/controller/Business.php +++ b/application/crm/controller/Business.php @@ -299,8 +299,8 @@ public function product() $dataList[$k]['category_id_info'] = $category_name ? : ''; } $list['list'] = $dataList ? : []; - $list['total_price'] = $contractInfo['total_price'] ? : '0.00'; - $list['discount_rate'] = $contractInfo['discount_rate'] ? : '0.00'; + $list['total_price'] = $businessInfo['total_price'] ? : '0.00'; + $list['discount_rate'] = $businessInfo['discount_rate'] ? : '0.00'; return resultArray(['data' => $list]); } diff --git a/application/crm/controller/Contacts.php b/application/crm/controller/Contacts.php index 8a74f33a..52f0aadb 100644 --- a/application/crm/controller/Contacts.php +++ b/application/crm/controller/Contacts.php @@ -22,7 +22,7 @@ class Contacts extends ApiCommon public function _initialize() { $action = [ - 'permission'=>[''], + 'permission'=>['exceldownload'], 'allow'=>[''] ]; Hook::listen('check_auth',$action); @@ -122,7 +122,7 @@ public function update() } /** - * 删除联系人(逻辑删) + * 删除联系人 * @author Michael_xu * @param * @return @@ -229,5 +229,76 @@ public function transfer() } else { return resultArray(['error' => $errorMessage]); } - } + } + + /** + * 联系人导入模板 + * @author Michael_xu + * @param + * @return + */ + public function excelDownload() + { + $param = $this->param; + $userInfo = $this->userInfo; + $excelModel = new \app\admin\model\Excel(); + + // 导出的字段列表 + $fieldModel = new \app\admin\model\Field(); + $fieldParam['types'] = 'crm_contacts'; + $fieldParam['action'] = 'excel'; + $field_list = $fieldModel->field($fieldParam); + $res = $excelModel->excelImportDownload($field_list, 'crm_contacts'); + } + + /** + * 联系人导出 + * @author Michael_xu + * @param + * @return + */ + public function excelExport() + { + $param = $this->param; + $userInfo = $this->userInfo; + $param['user_id'] = $userInfo['id']; + if ($param['contacts_id']) { + $param['contacts_id'] = ['condition' => 'in','value' => $param['contacts_id'],'form_type' => 'text','name' => '']; + $param['is_excel'] = 1; + } + + $excelModel = new \app\admin\model\Excel(); + // 导出的字段列表 + $fieldModel = new \app\admin\model\Field(); + $field_list = $fieldModel->getIndexFieldList('crm_contacts', $userInfo['id']); + // 文件名 + $file_name = '5kcrm_contacts_'.date('Ymd'); + $param['pageType'] = 'all'; + $excelModel->exportCsv($file_name, $field_list, function($page) use ($param){ + $list = model('Contacts')->getDataList($param); + return $list; + }); + } + + /** + * 联系人数据导入 + * @author Michael_xu + * @param + * @return + */ + public function excelImport() + { + $param = $this->param; + $userInfo = $this->userInfo; + $excelModel = new \app\admin\model\Excel(); + $param['types'] = 'crm_contacts'; + $param['create_user_id'] = $userInfo['id']; + $param['owner_user_id'] = $param['owner_user_id'] ? : $userInfo['id']; + $file = request()->file('file'); + $res = $excelModel->importExcel($file, $param); + if (!$res) { + return resultArray(['error'=>$excelModel->getError()]); + } + return resultArray(['data'=>'导入成功']); + } } diff --git a/application/crm/controller/Contract.php b/application/crm/controller/Contract.php index 93095171..bc69e3cb 100644 --- a/application/crm/controller/Contract.php +++ b/application/crm/controller/Contract.php @@ -88,7 +88,7 @@ public function save() if (!$check_user_id) { return resultArray(['error' => '无可用审批人,请联系管理员']); } - $param['check_user_id'] = $check_user_id; + $param['check_user_id'] = is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id; //流程审批人 // $flow_user_id = $examineFlowModel->getUserByFlow($examineFlowData['flow_id'], $param['create_user_id']); // $param['flow_user_id'] = $flow_user_id ? arrayToString($flow_user_id) : ''; @@ -184,7 +184,7 @@ public function update() if (!$check_user_id) { return resultArray(['error' => '无可用审批人,请联系管理员']); } - $param['check_user_id'] = $check_user_id; + $param['check_user_id'] = is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id; $param['check_status'] = 0; //流程审批人 diff --git a/application/crm/controller/Customer.php b/application/crm/controller/Customer.php index b1777433..19685a2a 100644 --- a/application/crm/controller/Customer.php +++ b/application/crm/controller/Customer.php @@ -80,9 +80,6 @@ public function save() $userInfo = $this->userInfo; $param['create_user_id'] = $userInfo['id']; $param['owner_user_id'] = $userInfo['id']; - $param['deal_status'] = '未成交'; - $param['deal_time'] = time(); - if ($res = $customerModel->createData($param)) { return resultArray(['data' => $res]); } else { @@ -128,7 +125,7 @@ public function read() * @return */ public function update() - { + { $customerModel = model('Customer'); $param = $this->param; $userInfo = $this->userInfo; @@ -598,9 +595,9 @@ public function excelDownload() $fieldParam['action'] = 'excel'; $customer_field_list = $fieldModel->field($fieldParam); $contactsParam['types'] = 'crm_contacts'; - // $contacts_field_list = $fieldModel->getDataList($contactsParam); - $contacts_field_list = []; - + $contactsParam['field'] = array('neq','customer_id'); + $contacts_field_list = $fieldModel->getDataList($contactsParam); + // $contacts_field_list = []; //实例化主文件 vendor("phpexcel.PHPExcel"); vendor("phpexcel.PHPExcel.Writer.Excel5"); @@ -622,7 +619,7 @@ public function excelDownload() $objProps->setCategory("5kcrm"); $objPHPExcel->setActiveSheetIndex(0); $objActSheet = $objPHPExcel->getActiveSheet(); - $objActSheet->setTitle('悟空软件导入模板'.date('Y-m-d',time())); + $objActSheet->setTitle('悟空软件客户导入模板'.date('Y-m-d',time())); //填充边框 $styleArray = [ @@ -651,19 +648,21 @@ public function excelDownload() $setting = $field['setting'] ? : []; $select_value = implode(',',$setting); if ($select_value) { - //数据有效性 start - $objValidation = $objActSheet->getCell($excelModel->stringFromColumnIndex($k).'3')->getDataValidation(); //这一句为要设置数据有效性的单元格 - $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) - -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) - -> setAllowBlank(false) - -> setShowInputMessage(true) - -> setShowErrorMessage(true) - -> setShowDropDown(true) - -> setErrorTitle('输入的值有误') - -> setError('您输入的值不在下拉框列表内.') - -> setPromptTitle('--请选择--') - -> setFormula1('"'.$select_value.'"'); - //数据有效性 end + for ($c=3; $c<=70; $c++) { + //数据有效性 start + $objValidation = $objActSheet->getCell($excelModel->stringFromColumnIndex($k).$c)->getDataValidation(); //这一句为要设置数据有效性的单元格 + $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) + -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) + -> setAllowBlank(false) + -> setShowInputMessage(true) + -> setShowErrorMessage(true) + -> setShowDropDown(true) + -> setErrorTitle('输入的值有误') + -> setError('您输入的值不在下拉框列表内.') + -> setPromptTitle('--请选择--') + -> setFormula1('"'.$select_value.'"'); + //数据有效性 end + } } } //检查该字段若必填,加上"*" @@ -692,19 +691,23 @@ public function excelDownload() if ($field['form_type'] == 'select' || $field['form_type'] == 'checkbox' || $field['form_type'] == 'radio') { $setting = $field['setting'] ? : []; $select_value = implode(',',$setting); - //数据有效性 start - $objValidation = $objActSheet->getCell($excelModel->stringFromColumnIndex($k).'3')->getDataValidation(); //这一句为要设置数据有效性的单元格 - $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) - -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) - -> setAllowBlank(false) - -> setShowInputMessage(true) - -> setShowErrorMessage(true) - -> setShowDropDown(true) - -> setErrorTitle('输入的值有误') - -> setError('您输入的值不在下拉框列表内.') - -> setPromptTitle('--请选择--') - -> setFormula1('"'.$select_value.'"'); - //数据有效性 end + if ($select_value) { + for ($c=3; $c<=70; $c++) { + //数据有效性 start + $objValidation = $objActSheet->getCell($excelModel->stringFromColumnIndex($k).'3')->getDataValidation(); //这一句为要设置数据有效性的单元格 + $objValidation -> setType(\PHPExcel_Cell_DataValidation::TYPE_LIST) + -> setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION) + -> setAllowBlank(false) + -> setShowInputMessage(true) + -> setShowErrorMessage(true) + -> setShowDropDown(true) + -> setErrorTitle('输入的值有误') + -> setError('您输入的值不在下拉框列表内.') + -> setPromptTitle('--请选择--') + -> setFormula1('"'.$select_value.'"'); + //数据有效性 end + } + } } //检查该字段若必填,加上"*" $field['name'] = sign_required($field['is_null'], $field['name']); @@ -718,24 +721,27 @@ public function excelDownload() $mark_contacts = $excelModel->stringFromColumnIndex($k-1); $objActSheet->mergeCells('A1:'.$max_customer_column.'1'); - // $objActSheet->mergeCells($mark_customer.'1:'.$mark_contacts.'1'); + $objActSheet->mergeCells($mark_customer.'1:'.$mark_contacts.'1'); $objActSheet->getStyle('A1:'.$mark_customer.'1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); //水平居中 $objActSheet->getStyle('A1:'.$mark_customer.'1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); //垂直居中 $objActSheet->getRowDimension(1)->setRowHeight(28); //设置行高 $objActSheet->getStyle('A1')->getFont()->getColor()->setARGB('FFFF0000'); $objActSheet->getStyle('A1')->getAlignment()->setWrapText(true); //设置单元格格式范围的字体、字体大小、加粗 - $objActSheet->getStyle('A1:'.$mark_contacts.'1')->getFont()->setName("微软雅黑")->setSize(13)->getColor()->setARGB('#00000000'); + $objActSheet->getStyle('A1:'.$mark_contacts.'1')->getFont()->setName("微软雅黑")->setSize(13)->getColor()->setARGB('#000000'); //给单元格填充背景色 - $objActSheet->getStyle('A1:'.$mark_contacts.'1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('#ff9900'); + $objActSheet->getStyle('A1:'.$max_customer_column.'1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('#ff9900'); + $objActSheet->getStyle($mark_customer.'1:'.$mark_contacts.'1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('#FFEBCD'); $objActSheet->getStyle($contacts_start_mark)->getAlignment()->setWrapText(true); $content = '客户信息(*代表必填项)'; $objActSheet->setCellValue('A1', $content); - // $objActSheet->setCellValue($mark_customer.'1', '联系人信息(*代表必填项)'); + $objActSheet->getStyle('A1:'.$max_customer_column.'1')->getBorders()->getAllBorders()->setBorderStyle(\PHPExcel_Style_Border::BORDER_THIN); + $objActSheet->getStyle('A1')->getBorders()->getRight()->getColor()->setARGB('#000000'); + $objActSheet->setCellValue($mark_customer.'1', '联系人信息(*代表必填项)'); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); ob_end_clean(); header("Content-Type: application/vnd.ms-excel;"); - header("Content-Disposition:attachment;filename=5kcrm_customer.xls"); + header("Content-Disposition:attachment;filename=客户信息导入模板".date('Y-m-d',time()).".xls"); header("Pragma:no-cache"); header("Expires:0"); $objWriter->save('php://output'); @@ -754,8 +760,8 @@ public function excelImport() $excelModel = new \app\admin\model\Excel(); $param['create_user_id'] = $userInfo['id']; $param['owner_user_id'] = $param['owner_user_id'] ? : 0; - $param['deal_time'] = time(); - $param['deal_status'] = '未成交'; + // $param['deal_time'] = time(); + // $param['deal_status'] = '未成交'; $param['types'] = 'crm_customer'; $file = request()->file('file'); $res = $excelModel->importExcel($file, $param); @@ -763,5 +769,26 @@ public function excelImport() return resultArray(['error'=>$excelModel->getError()]); } return resultArray(['data'=>'导入成功']); - } + } + + /** + * 客户标记为已跟进 + * @author Michael_xu + * @param + * @return + */ + public function setFollow(){ + $param = $this->param; + $customerIds = $param['id'] ? : []; + if (!$customerIds || !is_array($customerIds)) { + return resultArray(['error'=>'参数错误']); + } + $data['follow'] = '已跟进'; + $data['update_time'] = time(); + $res = db('crm_customer')->where(['customer_id' => ['in',$customerIds]])->update($data); + if (!$res) { + return resultArray(['error'=>'操作失败,请重试']); + } + return resultArray(['data'=>'跟进成功']); + } } \ No newline at end of file diff --git a/application/crm/controller/Index.php b/application/crm/controller/Index.php index d41ee70d..ca8170a2 100644 --- a/application/crm/controller/Index.php +++ b/application/crm/controller/Index.php @@ -13,7 +13,7 @@ class Index extends ApiCommon { - /** + /** * 用于判断权限 * @permission 无限制 * @allow 登录用户可访问 @@ -64,22 +64,36 @@ public function index() $map_user_ids = []; if ($param['user_id']) { $map_user_ids = $param['user_id']; - } elseif ($param['structure_id']) { - $map_structure_user_ids = $userModel->getSubUserByStr($param['structure_id']); + } + if ($param['structure_id']) { + $map_structure_user_ids = []; + foreach ($param['structure_id'] as $v) { + $map_structure_user_ids = $userModel->getSubUserByStr($v,2); + if (!in_array($v,$map_structure_user_ids) && $map_structure_user_ids) { + $map_structure_user_ids = array_merge($map_structure_user_ids,$map_structure_user_ids); + } + } if ($map_user_ids && $map_structure_user_ids) { $map_user_ids = array_merge($map_user_ids,$map_structure_user_ids); } elseif ($map_structure_user_ids) { $map_user_ids = $map_structure_user_ids; } } else { - $map_user_ids = [$userInfo['id']]; + // $map_user_ids = [$userInfo['id']]; + $map_user_ids = getSubUserId(true); } $perUserIds = getSubUserId(); //权限范围内userIds $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : $perUserIds; //数组交集 $where['owner_user_id'] = array('in',$userIds); - - $between_time = getTimeByType($param['type']); - $where['create_time'] = array('between',$between_time); + if (!empty($param['type'])) { + $between_time = getTimeByType($param['type']); + $where['create_time'] = array('between',$between_time); + } else { + //自定义时间 + if (!empty($param['start_time'])) { + $where['create_time'] = array('between',array($param['start_time'],$param['end_time'])); + } + } $customerNum = 0; //录入客户 $contactsNum = 0; //新增联系人 $businessNum = 0; //新增商机 @@ -111,7 +125,7 @@ public function index() $data['recordNum'] = $recordNum; $data['receivablesNum'] = $receivablesNum; $data['businessStatusNum'] = $businessStatusNum; - return resultArray(['data' => $data]); + return resultArray(['data' => $data]); } /** @@ -132,27 +146,41 @@ public function achievementData() $map_user_ids = []; if ($param['user_id']) { $map_user_ids = $param['user_id']; - } elseif ($param['structure_id']) { - $map_structure_user_ids = $userModel->getSubUserByStr($param['structure_id']); + } + if ($param['structure_id']) { + $map_structure_user_ids = []; + foreach ($param['structure_id'] as $v) { + $map_structure_user_ids = $userModel->getSubUserByStr($v,2); + if (!in_array($v,$map_structure_user_ids) && $map_structure_user_ids) { + $map_structure_user_ids = array_merge($map_structure_user_ids,$map_structure_user_ids); + } + } if ($map_user_ids && $map_structure_user_ids) { $map_user_ids = array_merge($map_user_ids,$map_structure_user_ids); } elseif ($map_structure_user_ids) { $map_user_ids = $map_structure_user_ids; } } else { - $map_user_ids = [$userInfo['id']]; + // $map_user_ids = [$userInfo['id']]; + $map_user_ids = getSubUserId(true); } $status = $param['status'] ? : 1; //1合同目标2回款目标 $perUserIds = getSubUserId(); //权限范围内userIds $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : array($userInfo['id']); //数组交集 $where['owner_user_id'] = array('in',$userIds); - - $start_time = $param['start_time'] ? : strtotime(date('Y-01-01',time())); - $end_time = $param['end_time'] ? strtotime(date('Y-m-01', $param['end_time']) . ' +1 month -1 day') : strtotime(date('Y-m-01', time()) . ' +1 month -1 day'); - $between_time = array($start_time,$end_time); - $where['create_time'] = array('between',$between_time); - + if (!empty($param['type'])) { + $between_time = getTimeByType($param['type']); + $start_time = $between_time[0]; + $end_time = $between_time[1]; + $where['create_time'] = array('between',$between_time); + } else { + //自定义时间 + $start_time = $param['start_time'] ? : strtotime(date('Y-01-01',time())); + $end_time = $param['end_time'] ? strtotime(date('Y-m-01', $param['end_time']) . ' +1 month -1 day') : strtotime(date('Y-m-01', time()) . ' +1 month -1 day'); + $between_time = array($start_time,$end_time); + $where['create_time'] = array('between',$between_time); + } //合同金额 $where_contract = $where; $where_contract['check_status'] = 2; //审核通过 @@ -169,10 +197,12 @@ public function achievementData() //获取时间段包含年份 $year = getYearByTime($start_time, $end_time); $where_achievement['year'] = array('in',$year); - $where_achievement_str = '(( `obj_id` IN ('.implode(',',$user_id).') AND `type` = 3 ) OR ( `obj_id` IN ('.implode(',',$structure_id).') AND `type` = 2 ) )'; - // p($where_achievement); + if(empty($param['user_id']) && empty($param['structure_id'])){ + $where_achievement_str = '( `obj_id` IN ('.implode(',',$map_user_ids).') AND `type` = 3 )'; + }else{ + $where_achievement_str = '(( `obj_id` IN ('.implode(',',$user_id).') AND `type` = 3 ) OR ( `obj_id` IN ('.implode(',',$structure_id).') AND `type` = 2 ) )'; + } $achievement = db('crm_achievement')->where($where_achievement)->where($where_achievement_str)->select(); - // p( db('crm_achievement')->getLastSql() ); $achievementMoney = 0.00; //获取需要查询的月份 $month = getmonthByTime($start_time, $end_time); @@ -212,60 +242,109 @@ public function funnel() $userModel = new \app\admin\model\User(); $param = $this->param; $userInfo = $this->userInfo; - + //员工IDS $map_user_ids = []; if ($param['user_id']) { $map_user_ids = $param['user_id']; - } elseif ($param['structure_id']) { - $map_structure_user_ids = $userModel->getSubUserByStr($param['structure_id']); + } + if ($param['structure_id']) { + $map_structure_user_ids = []; + foreach ($param['structure_id'] as $v) { + $map_structure_user_ids = $userModel->getSubUserByStr($v,2); + if (!in_array($v,$map_structure_user_ids) && $map_structure_user_ids) { + $map_structure_user_ids = array_merge($map_structure_user_ids,$map_structure_user_ids); + } + } if ($map_user_ids && $map_structure_user_ids) { $map_user_ids = array_merge($map_user_ids,$map_structure_user_ids); } elseif ($map_structure_user_ids) { $map_user_ids = $map_structure_user_ids; } } else { - $map_user_ids = [$userInfo['id']]; + // $map_user_ids = [$userInfo['id']]; + $map_user_ids = getSubUserId(true); } unset($param['user_id']); unset($param['structure_id']); $perUserIds = getSubUserId(); //权限范围内userIds $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : array($userInfo['id']); //数组交集 $param['userIds'] = $userIds ? : []; - $param['end_time'] = $param['end_time']+3600*24; + $param['end_time'] = $param['end_time']?$param['end_time']+3600*24:''; $list = $businessModel->getFunnel($param); return resultArray(['data' => $list]); - } + } - //销售趋势 + /** + * 销售趋势 + * @return [type] [description] + */ public function saletrend() { $receivablesModel = new \app\crm\model\Receivables(); $userModel = new \app\admin\model\User(); + $biCustomerModel = new \app\bi\model\Customer(); + $param = $this->param; $userInfo = $this->userInfo; - + //员工IDS $map_user_ids = []; if ($param['user_id']) { $map_user_ids = $param['user_id']; - } elseif ($param['structure_id']) { - $map_structure_user_ids = $userModel->getSubUserByStr($param['structure_id']); + } + if ($param['structure_id']) { + $map_structure_user_ids = []; + foreach ($param['structure_id'] as $v) { + $map_structure_user_ids = $userModel->getSubUserByStr($v,2); + if (!in_array($v,$map_structure_user_ids) && $map_structure_user_ids) { + $map_structure_user_ids = array_merge($map_structure_user_ids,$map_structure_user_ids); + } + } if ($map_user_ids && $map_structure_user_ids) { $map_user_ids = array_merge($map_user_ids,$map_structure_user_ids); } elseif ($map_structure_user_ids) { $map_user_ids = $map_structure_user_ids; } } else { - $map_user_ids = [$userInfo['id']]; + // $map_user_ids = [$userInfo['id']]; + $map_user_ids = getSubUserId(true); } - $perUserIds = getSubUserId(); //权限范围内userIds $userIds = $map_user_ids ? array_intersect($map_user_ids, $perUserIds) : array($userInfo['id']); //数组交集 - $year = $param['year']; - $chartParam['year'] = $year; - $chartParam['userIds'] = $userIds ? : []; - $chartList = $receivablesModel->getStatistics($chartParam); //柱状图 - return resultArray(['data' => $chartList]); + if(empty($param['type']) && empty($param['start_time'])){ + $param['type'] = 'month'; + } + $company = $biCustomerModel->getParamByCompany($param); + $list = array(); + $totlaContractMoney = '0.00'; + $totlaReceivablesMoney = '0.00'; + $biContractModel = new \app\bi\model\Contract(); + $receivablesModel = new \app\bi\model\Receivables(); + for ($i=1; $i <= $company['j']; $i++) { + $whereArr = []; + $item = array(); + //时间段 + $timeArr = $biCustomerModel->getStartAndEnd($param,$company['year'],$i); + $item['type'] = $timeArr['type']; + $day = $timeArr['day']?$timeArr['day']:'1'; + $start_time = strtotime($timeArr['year'].'-'.$timeArr['month'].'-'.$day); + $next_day = $timeArr['next_day']?$timeArr['next_day']:'1'; + $end_time = strtotime($timeArr['next_year'].'-'.$timeArr['next_month'].'-'.$next_day); + $create_time = []; + if ($start_time && $end_time) { + $create_time = array('between',array($start_time,$end_time)); + } + $whereArr['create_time'] = $create_time; + $whereArr['check_status'] = array('eq',2); + $whereArr['owner_user_id'] = array('in',$userIds); + $totlaContractMoney += $item['contractMoney'] = $biContractModel->getDataMoney($whereArr); + $totlaReceivablesMoney += $item['receivablesMoney'] = $receivablesModel->getDataMoney($whereArr); + $list[] = $item; + } + $datas['list'] = $list; + $datas['totlaContractMoney'] = $totlaContractMoney ? : '0.00'; + $datas['totlaReceivablesMoney'] = $totlaReceivablesMoney ? : '0.00'; + return resultArray(['data' => $datas]); } /** @@ -328,5 +407,36 @@ public function noFollowUp() $where['next_time'] = array('between',array(strtotime(date('Y-m-d',time())),strtotime(date('Y-m-d',time()))+86399+(86400*(int)$param['day']))); $customerList = db('crm_customer')->where($where)->select(); return resultArray(['data' => $customerList]); - } + } + + /** + * 客户名称、联系人姓名、联系人手机号查询 + * @author Michael_xu + * @param + * @return + */ + public function search() + { + $param = $this->param; + $search = $param['search'] ? : ''; + $page = $param['page'] ? : 1; + $limit = $param['limit'] ? : 15; + $types = $param['types'] ? : ''; + if (!$search) return resultArray(['error' => '查询条件不能为空']); + if ($types == 'crm_customer' || !$types) { + $customerList = db('crm_customer')->where(['name' => ['like','%'.$search.'%']])->field('name,owner_user_id')->page($page, $limit)->select(); + $customerCount = db('crm_customer')->where(['name' => ['like','%'.$search.'%']])->count(); + } + + if ($types == 'crm_contacts' || !$types) { + $contactsList = db('crm_contacts')->where(['name' => ['like','%'.$search.'%']])->whereOr('mobile','like','%'.$search.'%')->field('name,owner_user_id')->page($page, $limit)->select(); + $customerCount = db('crm_contacts')->where(['name' => ['like','%'.$search.'%']])->whereOr('mobile','like','%'.$search.'%')->count(); + } + $data = []; + $data['customerList'] = $customerList ? : []; + $data['customerCount'] = $customerCount ? : 0; + $data['contactsList'] = $contactsList ? : []; + $data['customerCount'] = $customerCount ? : 0; + return resultArray(['data' => $data]); + } } \ No newline at end of file diff --git a/application/crm/controller/Leads.php b/application/crm/controller/Leads.php index 96b98138..3407cd30 100644 --- a/application/crm/controller/Leads.php +++ b/application/crm/controller/Leads.php @@ -220,6 +220,10 @@ public function transform() $data = $leadsInfo ? : []; $data['create_user_id'] = $userInfo['id']; $data['owner_user_id'] = $userInfo['id']; + $data['deal_status'] = '未成交'; + $data['deal_time'] = time(); + $data['create_time'] = time(); + $data['update_time'] = time(); //权限判断 if (!$leadsInfo) { $errorMessage[] = 'id:为'.$leads_id.'的线索转化失败,错误原因:数据不存在;'; @@ -377,5 +381,26 @@ public function excelImport() return resultArray(['error'=>$excelModel->getError()]); } return resultArray(['data'=>'导入成功']); - } + } + + /** + * 线索标记为已跟进 + * @author Michael_xu + * @param + * @return + */ + public function setFollow(){ + $param = $this->param; + $leadsIds = $param['id'] ? : []; + if (!$leadsIds || !is_array($leadsIds)) { + return resultArray(['error'=>'参数错误']); + } + $data['follow'] = '已跟进'; + $data['update_time'] = time(); + $res = db('crm_leads')->where(['leads_id' => ['in',$leadsIds]])->update($data); + if (!$res) { + return resultArray(['error'=>'操作失败,请重试']); + } + return resultArray(['data'=>'跟进成功']); + } } diff --git a/application/crm/controller/Message.php b/application/crm/controller/Message.php index 3a4e31e7..155d27d0 100644 --- a/application/crm/controller/Message.php +++ b/application/crm/controller/Message.php @@ -43,7 +43,8 @@ public function index() $messageModel = model('Message'); $param = $this->param; $userInfo = $this->userInfo; - $param['user_id'] = $userInfo['id']; + $param['user_id'] = $userInfo['id']; + $param['module_name'] = 'crm'; $data = $messageModel->getDataList($param); return resultArray(['data' => $data]); } @@ -94,5 +95,140 @@ public function unCheckExamine() $where['check_status'] = 0; $list = $examineModel->getDataList($where); return resultArray(['data' => $list]); - } + } + + /** + * 消息数 + * @author Michael_xu + * @return + */ + public function num() + { + $param = $this->param; + $userInfo = $this->userInfo; + + $sysNum = $unCheckContractNum = $unCheckReceivablesNum = $unCheckExamineNum = 0; + $sysNum = db('admin_message')->where(['from_user_id' => 0,'to_user_id' => $userInfo['id'],'read_time' => ''])->count(); + // $unCheckContractNum = + return resultArray(['data' => $data]); + } + + /** + * 今日需联系客户 + * @author Michael_xu + * @return + */ + public function todayCustomer() + { + $customerModel = model('Customer'); + $todayTime = getTimeByType('today'); + $where = []; + $where['customer.next_time'] = ['between',$todayTime]; + $data = $customerModel->getDataList($where); + return resultArray(['data' => $data]); + } + + /** + * 待跟进线索 + * @author Michael_xu + * @return + */ + public function followLeads() + { + $leadsModel = model('Leads'); + $where = []; + $where['leads.follow'] = ['neq','已跟进']; + $data = $leadsModel->getDataList($where); + return resultArray(['data' => $data]); + } + + /** + * 待跟进客户 + * @author Michael_xu + * @return + */ + public function followCustomer() + { + $customerModel = model('Customer'); + $where = []; + $where['customer.follow'] = ['neq','已跟进']; + $data = $customerModel->getDataList($where); + return resultArray(['data' => $data]); + } + + /** + * 待审核合同 + * @author Michael_xu + * @return + */ + public function checkContract() + { + $userInfo = $this->userInfo; + $contractModel = model('Contract'); + $where = []; + $where['contract.check_status'] = ['lt','2']; + $where['contract.check_user_id'] = ['like',','.$userInfo['id'].',']; + $data = $contractModel->getDataList($where); + return resultArray(['data' => $data]); + } + + /** + * 待审核回款 + * @author Michael_xu + * @return + */ + public function checkReceivables() + { + $userInfo = $this->userInfo; + $receivablesModel = model('Receivables'); + $where = []; + $where['receivables.check_status'] = ['lt','2']; + $where['receivables.check_user_id'] = ['like',','.$userInfo['id'].',']; + $data = $receivablesModel->getDataList($where); + return resultArray(['data' => $data]); + } + + /** + * 待回款(回款计划) + * @author Michael_xu + * @return + */ + public function remindReceivablesPlan() + { + $param = $this->param; + $userInfo = $this->userInfo; + $receivablesPlanModel = model('ReceivablesPlan'); + $status = $param['status'] ? : '待回款'; + $where = []; + $where['user_id'] = $userInfo['id']; + switch ($status) { + case '待回款' : $where['receivables_id'] = 0; $where['remind_date'] = array('elt',date('Y-m-d',time())); $where['return_date'] = array('egt',date('Y-m-d',time())) break; + case '已回款' : $where['receivables_id'] = array('gt',0); break; + case '已逾期' : $where['receivables_id'] = 0; $where['return_date'] = array('lt',date('Y-m-d',time())); break; + } + $data = $receivablesPlanModel->getDataList($where); + return resultArray(['data' => $data]); + } + + /** + * 即将到期合同 + * @author Michael_xu + * @return + */ + public function endContract() + { + $param = $this->param; + $contractModel = model('Contract'); + $configModel = new \app\crm\model\ConfigData(); + $configInfo = $configModel->getData(); + $status = $param['status'] ? : '待回款'; + $expireDay = $configInfo['contract_day'] ? : '7'; + $where = []; + switch ($status) { + case '即将到期' : $where['end_time'] = array('between',array(date('Y-m-d',time()-86400*$expireDay),date('Y-m-d',time()))); break; + case '已到期' : $where['end_time'] = array('lt',date('Y-m-d',time())); break; + } + $data = $contractModel->getDataList($where); + return resultArray(['data' => $data]); + } } \ No newline at end of file diff --git a/application/crm/controller/Product.php b/application/crm/controller/Product.php index f85884b7..f5501cda 100644 --- a/application/crm/controller/Product.php +++ b/application/crm/controller/Product.php @@ -22,7 +22,7 @@ class Product extends ApiCommon public function _initialize() { $action = [ - 'permission'=>[''], + 'permission'=>['exceldownload'], 'allow'=>[''] ]; Hook::listen('check_auth',$action); @@ -133,4 +133,74 @@ public function status() } return resultArray(['data' => $data['status'].'成功']); } + + /** + * 产品导入模板 + * @author Michael_xu + * @param + * @return + */ + public function excelDownload() + { + $param = $this->param; + $userInfo = $this->userInfo; + $excelModel = new \app\admin\model\Excel(); + + // 导出的字段列表 + $fieldModel = new \app\admin\model\Field(); + $fieldParam['types'] = 'crm_product'; + $fieldParam['action'] = 'excel'; + $field_list = $fieldModel->field($fieldParam); + $res = $excelModel->excelImportDownload($field_list, 'crm_product'); + } + + /** + * 产品导出 + * @author Michael_xu + * @param + * @return + */ + public function excelExport() + { + $param = $this->param; + $userInfo = $this->userInfo; + $param['user_id'] = $userInfo['id']; + if ($param['product_id']) { + $param['product_id'] = ['condition' => 'in','value' => $param['product_id'],'form_type' => 'text','name' => '']; + } + + $excelModel = new \app\admin\model\Excel(); + // 导出的字段列表 + $fieldModel = new \app\admin\model\Field(); + $field_list = $fieldModel->getIndexFieldList('crm_product', $userInfo['id']); + // 文件名 + $file_name = '5kcrm_product_'.date('Ymd'); + $param['pageType'] = 'all'; + $excelModel->exportCsv($file_name, $field_list, function($page) use ($param){ + $list = model('Product')->getDataList($param); + return $list; + }); + } + + /** + * 产品数据导入 + * @author Michael_xu + * @param + * @return + */ + public function excelImport() + { + $param = $this->param; + $userInfo = $this->userInfo; + $excelModel = new \app\admin\model\Excel(); + $param['types'] = 'crm_product'; + $param['create_user_id'] = $userInfo['id']; + $param['owner_user_id'] = $param['owner_user_id'] ? : $userInfo['id']; + $file = request()->file('file'); + $res = $excelModel->importExcel($file, $param); + if (!$res) { + return resultArray(['error'=>$excelModel->getError()]); + } + return resultArray(['data'=>'导入成功']); + } } diff --git a/application/crm/controller/Receivables.php b/application/crm/controller/Receivables.php index 27e69ad5..b368afb7 100644 --- a/application/crm/controller/Receivables.php +++ b/application/crm/controller/Receivables.php @@ -87,7 +87,7 @@ public function save() if (!$check_user_id) { return resultArray(['error' => '无可用审批人,请联系管理员']); } - $param['check_user_id'] = $check_user_id; + $param['check_user_id'] = is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id; //流程审批人 // $flow_user_id = $examineFlowModel->getUserByFlow($examineFlowData['flow_id'], $param['owner_user_id']); // $param['flow_user_id'] = $flow_user_id ? arrayToString($flow_user_id) : ''; @@ -137,7 +137,7 @@ public function update() $userModel = new \app\admin\model\User(); $param = $this->param; $userInfo = $this->userInfo; - + $param['user_id'] = $userInfo['id']; //判断权限 $dataInfo = $receivablesModel->getDataById($param['id']); $auth_user_ids = $userModel->getUserByPer('crm', 'receivables', 'update'); @@ -177,7 +177,7 @@ public function update() if (!$check_user_id) { return resultArray(['error' => '无可用审批人,请联系管理员']); } - $param['check_user_id'] = $check_user_id; + $param['check_user_id'] = is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id; $param['check_status'] = 0; //流程审批人 diff --git a/application/crm/controller/ReceivablesPlan.php b/application/crm/controller/ReceivablesPlan.php index bc5838a7..e66af141 100644 --- a/application/crm/controller/ReceivablesPlan.php +++ b/application/crm/controller/ReceivablesPlan.php @@ -23,7 +23,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['index','save','read','update'] + 'allow'=>['index','save','read','update','delete'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -96,14 +96,66 @@ public function read() public function update() { $receivablesPlanModel = model('ReceivablesPlan'); + $userModel = new \app\admin\model\User(); $param = $this->param; $userInfo = $this->userInfo; + $plan_id = $param['id']; + $dataInfo = db('crm_receivables_plan')->where(['plan_id' => $plan_id])->find(); + //根据合同权限判断 + $contractData = db('crm_contract')->where(['contract_id' => $dataInfo['contract_id']])->find(); + $auth_user_ids = $userModel->getUserByPer('crm', 'contract', 'update'); + //读写权限 + $rwPre = $userModel->rwPre($userInfo['id'], $contractData['ro_user_id'], $contractData['rw_user_id'], 'update'); + if (!in_array($contractData['owner_user_id'],$auth_user_ids) && !$rwPre) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } $res = $receivablesPlanModel->updateDataById($param, $param['id']); if ($res) { return resultArray(['data' => '编辑成功']); } else { return resultArray(['error' => $receivablesPlanModel->getError()]); } - } + } + + /** + * 删除回款计划 + * @author Michael_xu + * @param + * @return + */ + public function delete() + { + $userModel = new \app\admin\model\User(); + $param = $this->param; + $userInfo = $this->userInfo; + $plan_id = $param['id']; + if ($plan_id) { + $dataInfo = db('crm_receivables_plan')->where(['plan_id' => $plan_id])->find(); + if (!$dataInfo) { + return resultArray(['error' => '数据不存在或已删除']); + } + $receivablesInfo = db('crm_receivables')->where(['receivables_id' => $dataInfo['receivables_id']])->find(); + if ($receivablesInfo) { + return resultArray(['error' => '已关联回款《'.$receivablesInfo['number'].'》,不能删除']); + } + //根据合同权限判断 + $contractData = db('crm_contract')->where(['contract_id' => $dataInfo['contract_id']])->find(); + $auth_user_ids = $userModel->getUserByPer('crm', 'contract', 'delete'); + //读写权限 + $rwPre = $userModel->rwPre($userInfo['id'], $contractData['ro_user_id'], $contractData['rw_user_id'], 'update'); + if (!in_array($contractData['owner_user_id'],$auth_user_ids) && !$rwPre) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $res = model('ReceivablesPlan')->delDataById($plan_id); + if (!$res) { + return resultArray(['error' => model('ReceivablesPlan')->getError()]); + } + return resultArray(['data' => '删除成功']); + } else { + return resultArray(['error'=>'参数错误']); + } + } } diff --git a/application/crm/controller/Setting.php b/application/crm/controller/Setting.php index d3ecb028..4e7180fa 100644 --- a/application/crm/controller/Setting.php +++ b/application/crm/controller/Setting.php @@ -23,7 +23,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['config','configdata','team','teamsave'] + 'allow'=>['config','configdata','team','teamsave','contractday'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -213,5 +213,23 @@ public function teamSave() } else { return resultArray(['data' => '保存成功']); } + } + + /** + * 合同到期提醒天数 + * @author Michael_xu + * @param + * @return + */ + public function contractDay() + { + $param = $this->param; + $contract_day = $param['contract_day'] ? int($param['contract_day']) : 0; + $res = db('crm_config')->where(['name' => 'contract_day'])->update(['value' => $contract_day]); + if ($res) { + return resultArray(['data' => '设置成功']); + } else { + return resultArray(['error' => '设置失败,请重试!']); + } } } \ No newline at end of file diff --git a/application/crm/model/Achievement.php b/application/crm/model/Achievement.php index 024960f2..a29a4c7e 100644 --- a/application/crm/model/Achievement.php +++ b/application/crm/model/Achievement.php @@ -96,7 +96,7 @@ public function getDataListForUser($request){ $ret['name'] = $userinfo['realname']; $data[] = $ret; return $data; - } else if($request['structure_id']) { + } elseif ($request['structure_id']) { $map['type'] = 3; $result = array(); $userlist = Db::name('AdminUser')->field('id,realname as name')->where('structure_id = '.$request['structure_id'].'')->select(); @@ -118,10 +118,10 @@ public function getDataListForUser($request){ $map['type'] = 3; $result = array(); $userlist = Db::name('AdminUser')->field('id,realname as name')->select(); - foreach($userlist as $k=>$v){ + foreach ($userlist as $k=>$v) { $map['obj_id'] = $v['id']; $ret = Db::name('CrmAchievement')->where($map)->find(); - if(!$ret){ + if (!$ret) { Db::name('CrmAchievement')->insert($map); $ret = Db::name('CrmAchievement')->where($map)->find(); } @@ -139,14 +139,15 @@ public function getDataListForUser($request){ public function getList($param) { $monthList = getMonthStart($param['year']); - $receivablesmodel = new \app\crm\model\Receivables(); + $receivablesModel = new \app\crm\model\Receivables(); + $contractModel = new \app\crm\model\Contract(); $user_ids = []; //业绩目标 - if($param['user_id']){ - $dataList = Db::name('CrmAchievement')->where('type=1 and obj_id ='.$param['user_id'].' and year ='.$param['year'].'')->find(); + if ($param['user_id']) { + $dataList = Db::name('CrmAchievement')->where(['type' => 1,'obj_id' => $param['user_id'],'year' => $param['year'],'status' => $param['status']])->find(); } else { - if($param['structure_id']) { - $dataList = Db::name('CrmAchievement')->where('type=2 and obj_id ='.$param['structure_id'].' and year ='.$param['year'].'')->find(); + if ($param['structure_id']) { + $dataList = Db::name('CrmAchievement')->where(['type' => 2,'obj_id' => $param['structure_id'],'year' => $param['year'],'status' => $param['status']])->find(); } } $map = []; @@ -202,15 +203,12 @@ public function getList($param) ]; //员工统计 - if($param['user_id']) { + if ($param['user_id']) { $user_ids[] = $param['user_id']; $map['obj_id'] = $param['user_id']; $map['obj_type'] = 2; - } else if ($param['structure_id']) { + } elseif ($param['structure_id']) { //部门统计 - //$userModel = new \app\admin\model\User(); - //$userList = $userModel->getSubUserByStr($param['structure_id'],1); //根据部门获取员工列表 - //$user_ids = $userList ? : []; $map['obj_id'] = $param['structure_id']; $map['obj_type'] = 1; } @@ -220,10 +218,14 @@ public function getList($param) $map['start_time'] = $monthList[$i]; $map['end_time'] = $monthList[$i+1]; $ret[$i]['month'] = $achiementList[$i]['month']; - $ret[$i]['receivables'] = $receivablesmodel->getDataByUserId($map); //user_id, year 回款 - $ret[$i]['achiement'] = (float) $achiementList[$i]['data']?:'0'; //目标 + if ($param['status'] == 1) { + $ret[$i]['receivables'] = $contractModel->getDataByUserId($map);//合同 + } else { + $ret[$i]['receivables'] = $receivablesModel->getDataByUserId($map); //回款 + } + $ret[$i]['achiement'] = (float)$achiementList[$i]['data']?:'0'; //目标 $rate = 0.00; - if($ret[$i]['achiement']){ + if ($ret[$i]['achiement']) { $rate = round(($ret[$i]['receivables']/$ret[$i]['achiement']),4)*100; } $ret[$i]['rate'] = $rate; diff --git a/application/crm/model/Business.php b/application/crm/model/Business.php index 9772ba41..17f17b00 100644 --- a/application/crm/model/Business.php +++ b/application/crm/model/Business.php @@ -72,7 +72,6 @@ public function getDataList($request) } else { $map = $requestMap ? array_merge($sceneMap, $requestMap) : $sceneMap; } - //高级筛选 $map = where_arr($map, 'crm', 'business', 'index'); $authMap = []; @@ -121,7 +120,7 @@ public function getDataList($request) ->where($map) ->where($partMap) ->where($authMap) - ->page($request['page'], $request['limit']) + ->limit(($request['page']-1)*$request['limit'], $request['limit']) ->field('business.*,customer.name as customer_name') // ->field('business_id,'.implode(',',$indexField)) ->order($order) @@ -332,8 +331,14 @@ public function getFunnel($request) $userModel = new \app\admin\model\User(); $where = []; //时间段 - $start_time = $request['start_time']; - $end_time = $request['end_time'] ; + if(!empty($request['type'])){ + $between_time = getTimeByType($request['type']); + $start_time = $between_time[0]; + $end_time = $between_time[1]; + }else{ + $start_time = strtotime($request['start_time']); + $end_time = strtotime($request['end_time']); + } $create_time = []; if ($start_time && $end_time) { $where['create_time'] = array('between',array($start_time,$end_time)); @@ -355,7 +360,6 @@ public function getFunnel($request) //赢单 $map['create_time'] = $where['create_time']; $map['owner_user_id'] = ['in',$request['userIds']]; - $sum_ying = Db::name('CrmBusiness')->where($map)->where('status_id=1')->sum('money'); //输单 $sum_shu = Db::name('CrmBusiness')->where($map)->where('status_id=2')->sum('money'); diff --git a/application/crm/model/BusinessStatus.php b/application/crm/model/BusinessStatus.php index e1a2b29a..5fb4debb 100644 --- a/application/crm/model/BusinessStatus.php +++ b/application/crm/model/BusinessStatus.php @@ -25,9 +25,13 @@ class BusinessStatus extends Common * @param type_id 商机组ID * @return */ - public function getDataList($type_id) + public function getDataList($type_id, $type = 0) { - $list = db('crm_business_status')->where(['type_id' => $type_id])->order('order_id asc')->select(); + if ($type == 1) { + $list = db('crm_business_status')->where(['type_id' => $type_id])->whereOr(['type_id' => 0])->order('order_id asc')->select(); + } else { + $list = db('crm_business_status')->where(['type_id' => $type_id])->order('order_id asc')->select(); + } return $list ? : []; } diff --git a/application/crm/model/Contacts.php b/application/crm/model/Contacts.php index 797548d1..42078505 100644 --- a/application/crm/model/Contacts.php +++ b/application/crm/model/Contacts.php @@ -38,9 +38,11 @@ public function getDataList($request) $search = $request['search']; $user_id = $request['user_id']; $scene_id = (int)$request['scene_id']; + $is_excel = $request['is_excel']; //导出 unset($request['scene_id']); unset($request['search']); - unset($request['user_id']); + unset($request['user_id']); + unset($request['is_excel']); $request = $this->fmtRequest( $request ); $requestMap = $request['map'] ? : []; @@ -62,8 +64,10 @@ public function getDataList($request) //高级筛选 $map = where_arr($map, 'crm', 'contacts', 'index'); //权限 + $a = 'index'; + if ($is_excel) $a = 'excelExport'; $authMap = []; - $auth_user_ids = $userModel->getUserByPer('crm', 'contacts', 'index'); + $auth_user_ids = $userModel->getUserByPer('crm', 'contacts', $a); if (isset($map['contacts.owner_user_id'])) { if (!is_array($map['contacts.owner_user_id'][1])) { $map['contacts.owner_user_id'][1] = [$map['contacts.owner_user_id'][1]]; @@ -89,7 +93,6 @@ public function getDataList($request) } else { $order = 'contacts.update_time desc'; } - $readAuthIds = $userModel->getUserByPer('crm', 'contacts', 'read'); $updateAuthIds = $userModel->getUserByPer('crm', 'contacts', 'update'); $deleteAuthIds = $userModel->getUserByPer('crm', 'contacts', 'delete'); @@ -98,7 +101,7 @@ public function getDataList($request) ->join('__CRM_CUSTOMER__ customer','contacts.customer_id = customer.customer_id','LEFT') ->where($map) ->where($authMap) - ->page($request['page'], $request['limit']) + ->limit(($request['page']-1)*$request['limit'], $request['limit']) ->field('contacts.*,customer.name as customer_name') // ->field('contacts_id,'.implode(',',$indexField) ->order($order) @@ -151,20 +154,17 @@ public function createData($param) // 自动验证 $validateArr = $fieldModel->validateField($this->name); //获取自定义字段验证规则 $validate = new Validate($validateArr['rule'], $validateArr['message']); - $result = $validate->check($param); if (!$result) { $this->error = $validate->getError(); return false; } - //处理部门、员工、附件、多选类型字段 $arrFieldAtt = $fieldModel->getArrayField('crm_contacts'); foreach ($arrFieldAtt as $k=>$v) { $param[$v] = arrayToString($param[$v]); } - - if ($this->data($param)->allowField(true)->save()) { + if ($this->data($param)->allowField(true)->isUpdate(false)->save()) { $data = []; $data['contacts_id'] = $this->contacts_id; return $data; @@ -204,7 +204,6 @@ public function updateDataById($param, $contacts_id = '') foreach ($unUpdateField as $v) { unset($param[$v]); } - $fieldModel = new \app\admin\model\Field(); // 自动验证 $validateArr = $fieldModel->validateField($this->name); //获取自定义字段验证规则 diff --git a/application/crm/model/Contract.php b/application/crm/model/Contract.php index ec9c3419..585f2abe 100644 --- a/application/crm/model/Contract.php +++ b/application/crm/model/Contract.php @@ -118,7 +118,7 @@ public function getDataList($request) ->where($map) ->where($partMap) ->where($authMap) - ->page($request['page'], $request['limit']) + ->page(($request['page']-1)*$request['limit'], $request['limit']) ->field('contract.*,customer.name as customer_name,business.name as business_name,contacts.name as contacts_name') // ->field('contract_id,'.implode(',',$indexField)) ->order($order) @@ -220,7 +220,7 @@ public function createData($param) //站内信 $createUserInfo = $userModel->getDataById($param['create_user_id']); $send_user_id = stringToArray($param['check_user_id']); - $sendContent = $createUserInfo['realname'].'提交了合同【'.$dataInfo['name'].'】,需要您审批'; + $sendContent = $createUserInfo['realname'].'提交了合同【'.$param['name'].'】,需要您审批'; if ($send_user_id) { sendMessage($send_user_id, $sendContent, $this->contract_id, 1); } @@ -276,7 +276,7 @@ public function updateDataById($param, $contract_id = '') //站内信 $createUserInfo = $userModel->getDataById($param['user_id']); $send_user_id = stringToArray($param['check_user_id']); - $sendContent = $createUserInfo['realname'].'提交了合同【'.$dataInfo['name'].'】,需要您审批'; + $sendContent = $createUserInfo['realname'].'提交了合同【'.$param['name'].'】,需要您审批'; if ($send_user_id) { sendMessage($send_user_id, $sendContent, $contract_id, 1); } @@ -355,5 +355,31 @@ public function transferDataById($ids, $owner_user_id, $type = 1, $is_remove) } else { return true; } - } + } + + /** + * 根据对象ID 获取该年各个月合同金额 + * @return [year] [哪一年] + * @return [owner_user_id] [哪个员工] + * @return [start_time] [开始时间] + * @return [end_time] [结束时间] + */ + public function getDataByUserId($param) + { + if ($param['obj_type']) { + if ($param['obj_type'] == 1) { //部门 + $userModel = new \app\admin\model\User(); + $str = $userModel->getSubUserByStr($param['obj_id'], 1) ? : ['-1']; + $map['owner_user_id'] = array('in',$str); + } else { //员工 + $map['owner_user_id'] = $param['obj_id']; + } + } + //审核状态 + $start = date('Y-m-d',$param['start_time']); + $stop = date('Y-m-d',$param['end_time']); + $map['check_status'] = 2; + $data = $this->where($map)->where(['order_date' => ['between',[$start, $stop]]])->sum('money'); + return $data; + } } \ No newline at end of file diff --git a/application/crm/model/Customer.php b/application/crm/model/Customer.php index b262ba96..19a90093 100644 --- a/application/crm/model/Customer.php +++ b/application/crm/model/Customer.php @@ -46,7 +46,7 @@ public function getDataList($request) unset($request['scene_id']); unset($request['search']); unset($request['user_id']); - if ($request['is_excel']) unset($request['is_excel']); + unset($request['is_excel']); $request = $this->fmtRequest( $request ); $requestMap = $request['map'] ? : []; @@ -133,7 +133,7 @@ public function getDataList($request) $structureField = $fieldModel->getFieldByFormType('crm_customer', 'structure'); //部门类型 //排序 if ($request['order_type'] && $request['order_field']) { - $order = trim($request['order_field']).' '.trim($request['order_type']); + $order = 'customer.'.trim($request['order_field']).' '.trim($request['order_type']); } else { $order = 'customer.update_time desc'; } @@ -144,7 +144,7 @@ public function getDataList($request) ->where($authMap) ->where($partMap) ->where($poolMap) - ->page($request['page'], $request['limit']) + ->limit(($request['page']-1)*$request['limit'], $request['limit']) // ->field('customer_id,'.implode(',',$indexField)) ->order($order) ->select(); @@ -232,6 +232,10 @@ public function createData($param) } //地址 $param['address'] = $param['address'] ? implode(chr(10),$param['address']) : ''; + $param['deal_time'] = time(); + if (!$param['deal_status']) { + $param['deal_status'] = '未成交'; + } //处理部门、员工、附件、多选类型字段 $arrFieldAtt = $fieldModel->getArrayField('crm_customer'); @@ -294,12 +298,16 @@ public function updateDataById($param, $customer_id = '') } //地址 $param['address'] = $param['address'] ? implode(chr(10),$param['address']) : ''; + if ($param['deal_status'] == '已成交' && $dataInfo->data['deal_status'] == '未成交') { + $param['deal_time'] = time(); + } //处理部门、员工、附件、多选类型字段 $arrFieldAtt = $fieldModel->getArrayField('crm_customer'); foreach ($arrFieldAtt as $k=>$v) { $param[$v] = arrayToString($param[$v]); } + $param['follow'] = '已跟进'; if ($this->allowField(true)->save($param, ['customer_id' => $customer_id])) { //修改记录 updateActionLog($user_id, 'crm_customer', $customer_id, $dataInfo->data, $param); @@ -346,12 +354,13 @@ public function getStatistics($request) $where = []; //时间段 $start_time = $map['start_time']; - $end_time = $map['end_time'] ? $map['end_time']+86399 : time(); + // $end_time = $map['end_time'] ? $map['end_time']+86399 : time(); + $end_time = $map['end_time'] ? $map['end_time'] : time(); $create_time = []; if ($start_time && $end_time) { $create_time = array('between',array($start_time,$end_time)); } - + //员工IDS $map_user_ids = []; if ($map['user_id']) { @@ -387,7 +396,7 @@ public function getStatistics($request) $whereArr['check_status'] = 2; $userList[$k]['contract_money'] = $contract_money = db('crm_contract')->where($whereArr)->sum('money'); $userList[$k]['receivables_money'] = $receivables_money = db('crm_receivables')->where($whereArr)->sum('money'); - $userList[$k]['un_receivables_money'] = $contract_money-$receivables_money >= 0 ? : '0.00'; + $userList[$k]['un_receivables_money'] = $contract_money-$receivables_money >= 0 ? $contract_money-$receivables_money : '0.00'; $userList[$k]['deal_receivables_rate'] = $contract_money ? round(($receivables_money/$contract_money), 2)*100 : 0; } return $userList ? : []; diff --git a/application/crm/model/Leads.php b/application/crm/model/Leads.php index 01800c3c..3f60d8c2 100644 --- a/application/crm/model/Leads.php +++ b/application/crm/model/Leads.php @@ -38,10 +38,11 @@ public function getDataList($request) $search = $request['search']; $user_id = $request['user_id']; $scene_id = (int)$request['scene_id']; + $is_excel = $request['is_excel']; //导出 unset($request['scene_id']); unset($request['search']); unset($request['user_id']); - if ($request['is_excel']) unset($request['is_excel']); + unset($request['is_excel']); $request = $this->fmtRequest( $request ); $requestMap = $request['map'] ? : []; @@ -104,7 +105,7 @@ public function getDataList($request) ->alias('leads') ->where($map) ->where($authMap) - ->page($request['page'], $request['limit']) + ->limit(($request['page']-1)*$request['limit'], $request['limit']) // ->field('leads_id,'.implode(',',$indexField)) ->order($order) ->select(); @@ -212,6 +213,7 @@ public function updateDataById($param, $leads_id = '') foreach ($arrFieldAtt as $k=>$v) { $param[$v] = arrayToString($param[$v]); } + $param['follow'] = '已跟进'; if ($this->allowField(true)->save($param, ['leads_id' => $leads_id])) { //修改记录 updateActionLog($param['user_id'], 'crm_leads', $leads_id, $dataInfo->data, $param); diff --git a/application/crm/model/Message.php b/application/crm/model/Message.php index 20ff7051..0310ba52 100644 --- a/application/crm/model/Message.php +++ b/application/crm/model/Message.php @@ -56,7 +56,7 @@ public function getDataList($request) foreach ($list as $k=>$v) { $list[$k][''] } - $dataCount = $this->where($map)->count('customer_id'); + $dataCount = $this->where($map)->count('message_id'); $data = []; $data['list'] = $list; $data['dataCount'] = $dataCount ? : 0; diff --git a/application/crm/model/Product.php b/application/crm/model/Product.php index 50e46b9b..162fdb3f 100644 --- a/application/crm/model/Product.php +++ b/application/crm/model/Product.php @@ -40,7 +40,7 @@ public function getDataList($request) $scene_id = (int)$request['scene_id']; unset($request['scene_id']); unset($request['search']); - unset($request['user_id']); + unset($request['user_id']); $request = $this->fmtRequest($request); $requestMap = $request['map'] ? : []; @@ -84,7 +84,7 @@ public function getDataList($request) ->where($map) ->join($join); $list = $list_view - ->page($request['page'], $request['limit']) + ->limit(($request['page']-1)*$request['limit'], $request['limit']) // ->field('product_id,'.implode(',',$indexField).',product_category.name as category_name') ->field('product.*,product_category.name as category_name') ->select(); @@ -94,6 +94,7 @@ public function getDataList($request) ->count('product_id'); foreach ($list as $k=>$v) { $list[$k]['create_user_id_info'] = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : []; + $list[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : []; foreach ($userField as $key => $val) { $list[$k][$val.'_info'] = isset($v[$val]) ? $userModel->getListByStr($v[$val]) : []; } @@ -250,6 +251,7 @@ public function createObject($types, $param, $objId) } $total_price = 0; + if ($param['product']) { $product = []; // 启动事务 @@ -257,14 +259,15 @@ public function createObject($types, $param, $objId) try { foreach ($param['product'] as $key => $value) { $discount = 0; - $discount = ((100 - $value['discount']) > 0) ? (100 - $value['discount'])/100 : 0; //折扣 + // $discount = ((100 - $value['discount']) > 0) ? (100 - $value['discount'])/100 : 0; //折扣 $product[$key]['product_id'] = $value['product_id']; $product[$key]['price'] = $value['price']; //产品单价 $product[$key]['sales_price'] = $value['sales_price']; //售价 $product[$key]['num'] = $value['num']; //数量 $product[$key]['discount'] = $value['discount']; //折扣 $product[$key]['unit'] = $value['unit'] ? : ''; //单位 - $total_price += $product[$key]['subtotal'] = round(($value['price'] * $value['num']) * $discount); //总价 + $product[$key]['subtotal'] = $value['subtotal']; + // $total_price += $product[$key]['subtotal'] = round(($value['price'] * $value['num']) * $discount); //总价 $product[$key][$db_id] = $objId; } @@ -275,9 +278,10 @@ public function createObject($types, $param, $objId) $rData = []; //产品合计 - $rData['discount_rate'] = !empty($param['discount_rate']) ? : 0.00; //整单折扣 + $rData['discount_rate'] = !empty($param['discount_rate']) ? $param['discount_rate'] : 0.00; //整单折扣 $discount_rate = ((100 - $rData['discount_rate']) > 0) ? (100 - $rData['discount_rate'])/100 : 0; - $rData['total_price'] = $total_price ? $total_price*$discount_rate : '0.00'; //整单合计 + // $rData['total_price'] = $total_price ? $total_price*$discount_rate : '0.00'; //整单合计 + $rData['total_price'] = $param['total_price'] ? : '0.00'; //整单合计 db($rDb)->where([$db_id => $objId])->update($rData); // 提交事务 @@ -314,8 +318,8 @@ public function getStatistics($request) if ($request['user_id']) { $map_user_ids = [$request['user_id']]; } else { - if ($param['structure_id']) { - $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2); + if ($request['structure_id']) { + $map_user_ids = $userModel->getSubUserByStr($request['structure_id'], 2); } } $perUserIds = $userModel->getUserByPer('bi', 'product', 'read'); //权限范围内userIds @@ -347,5 +351,25 @@ public function getStatistics($request) $list[$k]['owner_user_id_info'] = $owner_user_info ? : array(); } return $list; - } + } + + /** + * [根据产品类别ID,查询父级ID] + * @author Michael_xu + * @param + * @return + */ + public function getPidStr($category_id, $idArr, $first) + { + if ($first == 1) $idArr = []; + $idArr[] = $category_id; + $pid = db('crm_product_category')->where(['category_id' => $category_id])->value('pid'); + if ($pid) { + $idArr[] = $pid; + $this->getPidStr($pid, $idArr); + } + $arr = array_reverse($idArr); + $resStr = ','.implode(',',$arr).','; + return $resStr; + } } \ No newline at end of file diff --git a/application/crm/model/Receivables.php b/application/crm/model/Receivables.php index 58105caf..eb145571 100644 --- a/application/crm/model/Receivables.php +++ b/application/crm/model/Receivables.php @@ -100,7 +100,7 @@ public function getDataList($request) ->join('__CRM_CONTRACT__ contract','receivables.contract_id = contract.contract_id','LEFT') ->where($map) ->where($authMap) - ->page($request['page'], $request['limit']) + ->limit(($request['page']-1)*$request['limit'], $request['limit']) ->field('receivables.*,customer.name as customer_name,contract.name as contract_name,contract.num as contract_num,contract.money as contract_money') ->order($order) ->select(); @@ -115,7 +115,7 @@ public function getDataList($request) $list[$k]['customer_id_info']['customer_id'] = $v['customer_id'] ? : ''; $list[$k]['customer_id_info']['name'] = $v['customer_name'] ? : ''; $list[$k]['contract_id_info']['contract_id'] = $v['contract_id'] ? : ''; - $list[$k]['contract_id_info']['name'] = $v['contract_name'] ? : ''; + $list[$k]['contract_id_info']['name'] = $v['contract_num'] ? : ''; $list[$k]['contract_id_info']['money'] = $v['contract_money'] ? : '0.00'; $list[$k]['contract_money'] = $v['contract_money'] ? : '0.00'; foreach ($userField as $key => $val) { @@ -185,28 +185,27 @@ public function createData($param) /** * 根据对象ID 获取该年各个月回款情况 - * @return [year] [哪一年] - * @return [owner_user_id] [哪个员工] - * @return [start_time] [开始时间] - * @return [end_time] [结束时间] + * @param [year] [哪一年] + * @param [owner_user_id] [哪个员工] + * @param [start_time] [开始时间] + * @param [end_time] [结束时间] */ public function getDataByUserId($param) { - if($param['obj_type']){ - if($param['obj_type']==1){ //部门 - $structureList = Db::name('AdminUser')->field('id')->where('structure_id = '.$param['obj_id'])->select(); - $ary = array_map('array_shift',$structureList); - $str = implode(',',$ary); + if ($param['obj_type']) { + if ($param['obj_type'] == 1) { //部门 + $userModel = new \app\admin\model\User(); + $str = $userModel->getSubUserByStr($param['obj_id'], 1) ? : ['-1']; $map['owner_user_id'] = array('in',$str); - }else{ //员工 - $map['owner_user_id'] = array('=',$param['obj_id']); + } else { //员工 + $map['owner_user_id'] = $param['obj_id']; } } //审核状态 $start = date('Y-m-d',$param['start_time']); $stop = date('Y-m-d',$param['end_time']); $map['check_status'] = 2; - $data = $this->where($map)->where(' return_time >"'.$start.'" and return_time < "'.$stop.'"' )->sum('money'); + $data = $this->where($map)->where(['return_time' => ['between',[$start,$stop]]])->sum('money'); return $data; } @@ -219,7 +218,7 @@ public function getDataByUserId($param) public function updateDataById($param, $receivables_id = '') { $userModel = new \app\admin\model\User(); - $dataInfo = $this->getDataById($receivables_id); + $dataInfo = db('crm_receivables')->where(['receivables_id' => $receivables_id])->find(); if (!$dataInfo) { $this->error = '数据不存在或已删除'; return false; diff --git a/application/crm/model/ReceivablesPlan.php b/application/crm/model/ReceivablesPlan.php index d132b641..c1293b8e 100644 --- a/application/crm/model/ReceivablesPlan.php +++ b/application/crm/model/ReceivablesPlan.php @@ -50,7 +50,7 @@ public function getDataList($request) $map = where_arr($map, 'crm', 'receivables_plan', 'index'); //高级筛选 } - $list = db('crm_receivables_plan')->alias('receivables_plan')->where($map)->page($request['page'], $request['limit'])->select(); + $list = db('crm_receivables_plan')->alias('receivables_plan')->where($map)->limit(($request['page']-1)*$request['limit'], $request['limit'])->select(); $dataCount = db('crm_receivables_plan')->alias('receivables_plan')->where($map)->count('plan_id'); foreach ($list as $k=>$v) { $list[$k]['create_user_id_info'] = $userModel->getUserById($v['create_user_id']); @@ -70,8 +70,7 @@ public function getDataList($request) * @return */ public function createData($param) - { - if (!$param['contract_id']) { + { if (!$param['contract_id']) { $this->error = '请先选择合同'; } // 自动验证 @@ -84,7 +83,8 @@ public function createData($param) //期数规则(1,2,3..) $maxNum = db('crm_receivables_plan')->where(['contract_id' => $param['contract_id']])->max('num'); $param['num'] = $maxNum ? $maxNum+1 : 1; - + //提醒日期 + $param['remind_date'] = $param['remind'] ? date('Y-m-d',strtotime($param['return_date'])-86400*$param['remind']) : $param['return_date']; if ($this->data($param)->allowField(true)->save()) { $data = []; $data['plan_id'] = $this->plan_id; @@ -122,7 +122,8 @@ public function updateDataById($param, $plan_id = '') return false; } if ($param['file_ids']) $param['file'] = arrayToString($param['file_ids']); //附件 - + //提醒日期 + $param['remind_date'] = $param['remind'] ? date('Y-m-d',strtotime($param['return_date'])-86400*$param['remind']) : $param['return_date']; if ($this->allowField(true)->save($param, ['plan_id' => $plan_id])) { $data = []; $data['plan_id'] = $plan_id; @@ -206,5 +207,5 @@ public function getField() ] ]; return $field_arr; - } + } } \ No newline at end of file diff --git a/application/oa/controller/Announcement.php b/application/oa/controller/Announcement.php index 2d0f477f..d4c6392c 100644 --- a/application/oa/controller/Announcement.php +++ b/application/oa/controller/Announcement.php @@ -57,8 +57,7 @@ public function index() $adminTypes = adminGroupTypes($userInfo['id']); $param['user_id'] = $userInfo['id']; - $data = $announcementModel->getDataList($param); - //var_dump($adminTypes); + $data = $announcementModel->getDataList($param); if( !in_array(8,$adminTypes) && !in_array(1,$adminTypes) ){ $data['is_create'] = 0; } else { @@ -79,8 +78,7 @@ public function save() if (!in_array(8,$adminTypes) && !in_array(1,$adminTypes)) { header('Content-Type:application/json; charset=utf-8'); exit(json_encode(['code'=>102,'error'=>'无权操作'])); - } - + } $res = $announcementModel->createData($param); if ($res) { $res['realname'] = $userInfo['realname']; diff --git a/application/oa/controller/Examine.php b/application/oa/controller/Examine.php index 0247b356..f0df4595 100644 --- a/application/oa/controller/Examine.php +++ b/application/oa/controller/Examine.php @@ -24,7 +24,7 @@ public function _initialize() { $action = [ 'permission'=>[''], - 'allow'=>['index','save','read','update','delete','categorylist','check','revokecheck'] + 'allow'=>['index','save','read','update','delete','categorylist','check','revokecheck','category','categorysave','categoryupdate','categorydelete','categoryenables'] ]; Hook::listen('check_auth',$action); $request = Request::instance(); @@ -32,6 +32,14 @@ public function _initialize() if (!in_array($a, $action['permission'])) { parent::_initialize(); } + $userInfo = $this->userInfo; + //权限判断 + $unAction = ['index','save','read','update','delete','categorylist','check','revokecheck']; + $adminTypes = adminGroupTypes($userInfo['id']); + if (!in_array(5,$adminTypes) && !in_array(1,$adminTypes) && !in_array(2,$adminTypes) && !in_array($a, $unAction)) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } } /** @@ -88,7 +96,7 @@ public function save() if (!$check_user_id) { return resultArray(['error' => '无可用审批人,请联系管理员']); } - $param['check_user_id'] = $check_user_id; + $param['check_user_id'] = is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id; //流程审批人 // $flow_user_id = $examineFlowModel->getUserByFlow($examineFlowData['flow_id'], $userInfo['id']); // $param['flow_user_id'] = $flow_user_id ? arrayToString($flow_user_id) : ''; @@ -176,7 +184,7 @@ public function update() if (!$check_user_id) { return resultArray(['error' => '无可用审批人,请联系管理员']); } - $param['check_user_id'] = $check_user_id; + $param['check_user_id'] = is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id; $param['check_status'] = 0; //流程审批人 // $flow_user_id = $examineFlowModel->getUserByFlow($examineFlowData['flow_id'], $dataInfo['create_user_id']); @@ -286,7 +294,8 @@ public function categoryUpdate() return resultArray(['error' => '数据不存在或已删除']); } //将当前审批流标记为已删除,重新创建审批流(目的:保留审批流程记录) - $newData = db('admin_examine_flow')->where(['flow_id' => $dataInfo['flow_id']])->find(); + // $newData = db('admin_examine_flow')->where(['flow_id' => $dataInfo['flow_id']])->find(); + $param['name'] = $param['title'].'流程'; $param['types'] = 'oa_examine'; $param['types_id'] = $category_id; @@ -305,15 +314,18 @@ public function categoryUpdate() return resultArray(['error' => $examineStepModel->getError()]); } } - $upData = []; - $upData['is_deleted'] = 1; - $upData['delete_time'] = time(); - $upData['delete_user_id'] = $userInfo['id']; - $upData['status'] = 0; - $resFlow = db('admin_examine_flow')->where(['flow_id' => $dataInfo['flow_id']])->update($upData); - if (!$resFlow) { - return resultArray(['error' => '编辑失败']); - } + if ($dataInfo['flow_id']) { + $upData = []; + $upData['is_deleted'] = 1; + $upData['delete_time'] = time(); + $upData['delete_user_id'] = $userInfo['id']; + $upData['status'] = 0; + $resFlow = db('admin_examine_flow')->where(['flow_id' => $dataInfo['flow_id']])->update($upData); + if (!$resFlow) { + return resultArray(['error' => '编辑失败']); + } + } + $param['flow_id'] = $resUpdate['flow_id']; $res = $categoryModel->updateDataById($param, $param['id']); if (!$res) { diff --git a/application/oa/controller/Index.php b/application/oa/controller/Index.php index 1e36f7af..fe315e97 100644 --- a/application/oa/controller/Index.php +++ b/application/oa/controller/Index.php @@ -55,7 +55,7 @@ public function index() } elseif ($param['type'] == 3) { //公告 $where = ' controller_name = "announcement" and module_name = "oa" '; } elseif ($param['type'] == 4) { //任务 - $where = ' ( controller_name = "task" and module_name = "work" ) '; + $where = ' ( controller_name = "task" and module_name = "oa" ) '; } elseif ($param['type'] == 5) { //审批 $where = ' ( controller_name = "examine" and module_name = "oa" ) '; } else { //全部 diff --git a/application/oa/controller/Log.php b/application/oa/controller/Log.php index a8c7af86..71a1e52e 100644 --- a/application/oa/controller/Log.php +++ b/application/oa/controller/Log.php @@ -118,7 +118,7 @@ public function read() $param = $this->param; $userInfo = $this->userInfo; $logModel = model('Log'); - $data = $logModel->getDataById($param['id']); + $data = db('oa_log')->where(['log_id' => $param['id']])->find(); //权限判断 $auth_user_ids = getSubUserId(); if (!in_array($userInfo['id'], $auth_user_ids) && $data['create_user_id'] !== $userInfo['id'] && !in_array($userInfo['id'],stringToArray($data['send_user_ids']))) { @@ -141,17 +141,28 @@ public function update() { $param = $this->param; $userInfo = $this->userInfo; - $logModel = model('Log'); - $res = $logModel->updateDataById($param, $param['id']); - if ($res) { - return resultArray(['data' => '编辑成功']); + $log_id = $param['id']; + $logModel = model('Log'); + if ($log_id) { + $dataInfo = db('oa_log')->where(['log_id' => $log_id])->find(); + //权限判断 + if ($dataInfo['create_user_id'] !== $userInfo['id']) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $res = $logModel->updateDataById($param, $param['id']); + if ($res) { + return resultArray(['data' => '编辑成功']); + } else { + return resultArray(['error' => $logModel->getError()]); + } } else { - return resultArray(['error' => $logModel->getError()]); - } + return resultArray(['error'=>'参数错误']); + } } /** - * 删除日志(逻辑删) + * 删除日志 * @author Michael_xu * @param * @return @@ -159,15 +170,22 @@ public function update() public function delete() { $param = $this->param; + $userInfo = $this->userInfo; $log_id = $param['log_id']; if ($log_id) { - $dataInfo = db('oa_log')->where(['log_id' => $log_id])->find(); + $dataInfo = db('oa_log')->where(['log_id' => $log_id])->find(); + $adminTypes = adminGroupTypes($userInfo['id']); //3天内的日志可删 - if (date('Ymd',$dataInfo['create_time']) < date('Ymd',(strtotime(date('Ymd',time()))-86400*3))) { + if (date('Ymd',$dataInfo['create_time']) < date('Ymd',(strtotime(date('Ymd',time()))-86400*3)) && !in_array(1,$adminTypes)) { return resultArray(['error' => '已超3天,不能删除']); - } - $data = model('Log')->delDataById($param); - if (!$data) { + } + //权限判断 + if ($dataInfo['create_user_id'] !== $userInfo['id'] && !in_array(1,$adminTypes)) { + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode(['code'=>102,'error'=>'无权操作'])); + } + $res = model('Log')->delDataById($param); + if (!$res) { return resultArray(['error' => model('Log')->getError()]); } return resultArray(['data' => '删除成功']); diff --git a/application/oa/model/Announcement.php b/application/oa/model/Announcement.php index 9a6f965e..99e758d2 100644 --- a/application/oa/model/Announcement.php +++ b/application/oa/model/Announcement.php @@ -48,11 +48,11 @@ public function getDataList($request) $request = $this->fmtRequest( $request ); $requestMap = $request['map'] ? : []; - $time = time(); + $time = strtotime(date('Y-m-d',time())); $map = array(); - if($requestMap['type'] && $requestMap['type'] == 1) { + if ($requestMap['type'] && $requestMap['type'] == 1) { $time = 'end_time >= '.$time.' AND start_time <= '.$time.' AND '; - } else if($requestMap['type'] && $requestMap['type']==2) { + } elseif ($requestMap['type'] && $requestMap['type'] == 2) { $time = 'end_time < '.$time.' AND '; } else { $time = ''; @@ -69,13 +69,13 @@ public function getDataList($request) ->order('announcement.create_time desc') ->select(); $adminTypes = adminGroupTypes($user_id); - foreach($list as $k=>$v){ + foreach ($list as $k=>$v) { $list[$k]['thumb_img'] = $v['thumb_img']?getFullPath($v['thumb_img']):''; $list[$k]['structureList'] = $structureModel->getDataByStr($v['structure_ids']) ? : array(); $list[$k]['ownerList'] = $userModel->getDataByStr($v['owner_user_ids']) ? : array(); $is_update = 0; $is_delete = 0; - if(in_array(8,$adminTypes) || in_array(1,$adminTypes)){ + if (in_array(8,$adminTypes) || in_array(1,$adminTypes)) { $is_update = 1; $is_delete = 1; } diff --git a/application/oa/model/Examine.php b/application/oa/model/Examine.php index 5e40351f..a5b14014 100644 --- a/application/oa/model/Examine.php +++ b/application/oa/model/Examine.php @@ -41,7 +41,7 @@ public function getDataList($request) $contractModel = new \app\crm\model\Contract(); $customerModel = new \app\crm\model\Customer(); - $by = $request['by'] ? : 'my'; //my我发起的,examine我审批的 + $by = $request['by'] ? : 'my'; //my我发起的,examine我审批的,all全部(下属发起的) $user_id = $request['user_id']; $check_status = $request['check_status']; unset($request['by']); @@ -68,6 +68,7 @@ public function getDataList($request) break; case 'already_examine' : $map['flow_user_id'] = [['like','%,'.$user_id.',%'],['eq',$user_id],'or']; break; //已审 case 'stay_examine' : $map['check_user_id'] = [['like','%,'.$user_id.',%'],['eq',$user_id],'or']; break; //待审 + case 'all' : $auth_user_ids = getSubUserId(); $map['examine.create_user_id'] = array('in',$auth_user_ids); break; //全部 default : $map['examine.create_user_id'] = $user_id; break; } $order = 'examine.update_time desc,examine.create_time asc'; @@ -185,18 +186,19 @@ public function createData($param) $userModel = new \app\admin\model\User(); $examineCategoryModel = new \app\oa\model\ExamineCategory(); $examineDataModel = new \app\oa\model\ExamineData(); + if (!$param['category_id']) { + $this->error = '参数错误'; + return false; + } // 自动验证 - $validateArr = $fieldModel->validateField($this->name); //获取自定义字段验证规则 + $validateArr = $fieldModel->validateField($this->name,$param['category_id']); //获取自定义字段验证规则 $validate = new Validate($validateArr['rule'], $validateArr['message']); $result = $validate->check($param); if (!$result) { $this->error = $validate->getError(); return false; } - if (!$param['category_id']) { - $this->error = '参数错误'; - return false; - } + $categoryInfo = $examineCategoryModel->getDataById($param['category_id']); $fileArr = $param['file_id']; //接收表单附件 @@ -277,10 +279,10 @@ public function updateDataById($param, $examine_id = '') foreach ($unUpdateField as $v) { unset($param[$v]); } - $categoryInfo = $examineCategoryModel->getDataById($param['category_id']); + $categoryInfo = $examineCategoryModel->getDataById($dataInfo['category_id']); //验证 - $validate = validate($this->name); + $validate = validate($this->name, $dataInfo['category_id']); if (!$validate->check($param)) { $this->error = $validate->getError(); return false; diff --git a/application/oa/model/Log.php b/application/oa/model/Log.php index 1e8a56ce..ec179010 100644 --- a/application/oa/model/Log.php +++ b/application/oa/model/Log.php @@ -382,11 +382,6 @@ public function delDataById($param) $this->error = '数据不存在或已删除'; return false; } - //超过3天不能删除 - if( $dataInfo['create_time'] < time()-3600*24*3 ){ - $this->error = '超过时效,不可删除'; - return false; - } $flag = Db::name('OaLog')->where($map)->delete(); if ($flag) { actionLog($param['log_id'],$dataInfo['send_structure_ids'],$dataInfo['send_structure_ids'],'删除了日志'); diff --git a/application/work/model/Task.php b/application/work/model/Task.php index 33e7dd57..8f56c7e9 100644 --- a/application/work/model/Task.php +++ b/application/work/model/Task.php @@ -239,26 +239,26 @@ public function createTask($param) if($param['main_user_id']){ $param['owner_user_id'] = ','.$param['main_user_id'].','; } - $flag = $this->insertGetId($param); //添加任务 + $task_id = $this->insertGetId($param); //添加任务 - if ($flag) { + if ($task_id) { $rdata['status'] = 1; $rdata['create_time'] = time(); - $rdata['task_id'] = $flag; + $rdata['task_id'] = $task_id; Db::name('TaskRelation')->insert($rdata); if(!$param['pid']){ $taskLog = new LogModel();// model('TaskLog'); $datalog['name'] = $param['name']; $datalog['user_id'] = $param['create_user_id']; - $datalog['task_id'] = $flag;//添加任务ID + $datalog['task_id'] = $task_id;//添加任务ID $datalog['work_id'] = $param['work_id']?:'';//添加任务ID $ret = $taskLog->newTaskLog($datalog); //操作日志 - actionLog($flag,'','','新建了任务'); + actionLog($task_id,'','','新建了任务'); } - return $flag; + return $task_id; } else { $this->error = '添加失败'; return false; diff --git a/config/route_admin.php b/config/route_admin.php index c336bdb5..e9c5a91e 100644 --- a/config/route_admin.php +++ b/config/route_admin.php @@ -156,6 +156,8 @@ 'admin/field/columnWidth' => ['admin/field/columnWidth', ['method' => 'POST']], // 【自定义字段】列表排序数据 'admin/field/configIndex' => ['admin/field/configIndex', ['method' => 'POST']], + // 【自定义字段】自定义验重字段 + 'admin/field/uniqueField' => ['admin/field/uniqueField', ['method' => 'POST']], // 【站内信】列表 'admin/message/index' => ['admin/message/index', ['method' => 'POST']], @@ -164,6 +166,8 @@ 'admin/record/index' => ['admin/record/index', ['method' => 'POST']], // 【跟进记录】创建 'admin/record/save' => ['admin/record/save', ['method' => 'POST']], + // 【跟进记录】删除 + 'admin/record/delete' => ['admin/record/delete', ['method' => 'POST']], // 【审批流程】列表 'admin/examine_flow/index' => ['admin/examine_flow/index', ['method' => 'POST']], diff --git a/config/route_bi.php b/config/route_bi.php index 730506e0..5f56c751 100644 --- a/config/route_bi.php +++ b/config/route_bi.php @@ -15,7 +15,7 @@ 'bi/customer/statistics' => ['bi/customer/statistics', ['method' => 'POST']], // 【商业智能】销售漏斗 'bi/business/funnel' => ['bi/business/funnel', ['method' => 'POST']], - // 【商业智能】回款统计 + // 【商业智能】回款统计 柱状图 'bi/receivables/statistics' => ['bi/receivables/statistics', ['method' => 'POST']], // 【商业智能】回款统计列表 'bi/receivables/statisticList' => ['bi/receivables/statisticList', ['method' => 'POST']], @@ -23,6 +23,62 @@ 'bi/product/statistics' => ['bi/product/statistics', ['method' => 'POST']], // 【商业智能】业绩目标完成情况 'bi/achievement/statistics' => ['bi/achievement/statistics', ['method' => 'POST']], + // 【商业智能】新增商机数与金额趋势分析 + 'bi/business/businessTrend' => ['bi/business/businessTrend', ['method' => 'POST']], + // 【商业智能】新增商机数与金额趋势分析 列表 + 'bi/business/trendList' => ['bi/business/trendList', ['method' => 'POST']], + // 【商业智能】赢单机会转化率趋势分析 + 'bi/business/win' => ['bi/business/win', ['method' => 'POST']], + // 【商业智能】合同金额排行 + 'bi/ranking/contract' => ['bi/ranking/contract', ['method' => 'POST']], + // 【商业智能】回款金额排序 + 'bi/ranking/receivables' => ['bi/ranking/receivables', ['method' => 'POST']], + // 【商业智能】签约合同排序 + 'bi/ranking/signing' => ['bi/ranking/signing', ['method' => 'POST']], + // 【商业智能】新增客户排序 + 'bi/ranking/addCustomer' => ['bi/ranking/addCustomer', ['method' => 'POST']], + // 【商业智能】新增联系人排序 + 'bi/ranking/addContacts' => ['bi/ranking/addContacts', ['method' => 'POST']], + // 【商业智能】跟进次数排行 + 'bi/ranking/recordNun' => ['bi/ranking/recordNun', ['method' => 'POST']], + // 【商业智能】跟进客户数排行 + 'bi/ranking/recordCustomer' => ['bi/ranking/recordCustomer', ['method' => 'POST']], + // 【商业智能】出差次数排行 + 'bi/ranking/examine' => ['bi/ranking/examine', ['method' => 'POST']], + // 【商业智能】产品销量排行 + 'bi/ranking/product' => ['bi/ranking/product', ['method' => 'POST']], + // 【商业智能】产品分类销量分析 + 'bi/product/productCategory' => ['bi/product/productCategory', ['method' => 'POST']], + // 【商业智能】合同数量分析/金额分析/回款金额分析 + 'bi/contract/analysis' => ['bi/contract/analysis', ['method' => 'POST']], + // 【商业智能】合同汇总表 + 'bi/contract/summary' => ['bi/contract/summary', ['method' => 'POST']], + // 【商业智能】员工客户总量分析 + 'bi/customer/total' => ['bi/customer/total', ['method' => 'POST']], + // 【商业智能】员工客户跟进次数分析 + 'bi/customer/recordTimes' => ['bi/customer/recordTimes', ['method' => 'POST']], + // 【商业智能】员工客户跟进次数分析 具体员工列表 + 'bi/customer/recordList' => ['bi/customer/recordList', ['method' => 'POST']], + // 【商业智能】员工跟进方式分析 + 'bi/customer/recordMode' => ['bi/customer/recordMode', ['method' => 'POST']], + // 【商业智能】客户转化率分析 + 'bi/customer/conversion' => ['bi/customer/conversion', ['method' => 'POST']], + // 【商业智能】客户转化率分析具体数据 + 'bi/customer/conversionInfo' => ['bi/customer/conversionInfo', ['method' => 'POST']], + // 【商业智能】公海客户分析 + 'bi/customer/pool' => ['bi/customer/pool', ['method' => 'POST']], + // 【商业智能】公海客户分析 列表 + 'bi/customer/poolList' => ['bi/customer/poolList', ['method' => 'POST']], + // 【商业智能】员工客户成交周期 + 'bi/customer/userCycle' => ['bi/customer/userCycle', ['method' => 'POST']], + // 【商业智能】产品成交周期 + 'bi/customer/productCycle' => ['bi/customer/productCycle', ['method' => 'POST']], + // 【商业智能】地区成交周期 + 'bi/customer/addressCycle' => ['bi/customer/addressCycle', ['method' => 'POST']], + // 【商业智能】客户所在城市分析 + 'bi/customer/addressAnalyse' => ['bi/customer/addressAnalyse', ['method' => 'POST']], + // 【商业智能】客户行业/级别/来源分析 + 'bi/customer/portrait' => ['bi/customer/portrait', ['method' => 'POST']], // MISS路由 '__miss__' => 'admin/base/miss', diff --git a/config/route_crm.php b/config/route_crm.php index 183cb050..0c17a6be 100644 --- a/config/route_crm.php +++ b/config/route_crm.php @@ -90,7 +90,13 @@ // 【联系人】转移 'crm/contacts/transfer' => ['crm/contacts/transfer', ['method' => 'POST']], // 【联系人】删除 - 'crm/contacts/delete' => ['crm/contacts/delete', ['method' => 'POST']], + 'crm/contacts/delete' => ['crm/contacts/delete', ['method' => 'POST']], + // 【联系人】导出 + 'crm/contacts/excelExport' => ['crm/contacts/excelExport', ['method' => 'POST']], + // 【联系人】导入模板下载 + 'crm/contacts/excelDownload' => ['crm/contacts/excelDownload', ['method' => 'GET']], + // 【联系人】导入 + 'crm/contacts/excelImport' => ['crm/contacts/excelImport', ['method' => 'POST']], // 【商机】列表 'crm/business/index' => ['crm/business/index', ['method' => 'POST']], @@ -145,7 +151,13 @@ // 【产品】详情 'crm/product/read' => ['crm/product/read', ['method' => 'POST']], // 【产品】上架/下架 - 'crm/product/status' => ['crm/product/status', ['method' => 'POST']], + 'crm/product/status' => ['crm/product/status', ['method' => 'POST']], + // 【产品】导出 + 'crm/product/excelExport' => ['crm/product/excelExport', ['method' => 'POST']], + // 【产品】导入模板下载 + 'crm/product/excelDownload' => ['crm/product/excelDownload', ['method' => 'GET']], + // 【产品】导入 + 'crm/product/excelImport' => ['crm/product/excelImport', ['method' => 'POST']], // 【回款】列表 'crm/receivables/index' => ['crm/receivables/index', ['method' => 'POST']], @@ -167,13 +179,15 @@ 'crm/receivables/revokeCheck' => ['crm/receivables/revokeCheck', ['method' => 'POST']], // 【回款计划】列表 - 'crm/receivablesPlan/index' => ['crm/receivablesPlan/index', ['method' => 'POST']], + 'crm/receivables_plan/index' => ['crm/receivables_plan/index', ['method' => 'POST']], // 【回款计划】创建 - 'crm/receivablesPlan/save' => ['crm/receivablesPlan/save', ['method' => 'POST']], + 'crm/receivables_plan/save' => ['crm/receivables_plan/save', ['method' => 'POST']], // 【回款计划】编辑 - 'crm/receivablesPlan/update' => ['crm/receivablesPlan/update', ['method' => 'POST']], + 'crm/receivables_plan/update' => ['crm/receivables_plan/update', ['method' => 'POST']], // 【回款计划】详情 - 'crm/receivablesPlan/read' => ['crm/receivablesPlan/read', ['method' => 'POST']], + 'crm/receivables_plan/read' => ['crm/receivables_plan/read', ['method' => 'POST']], + // 【回款计划】删除 + 'crm/receivables_plan/delete' => ['crm/receivables_plan/delete', ['method' => 'POST']], // 【相关团队】列表 'crm/setting/team' => ['crm/setting/team', ['method' => 'POST']], @@ -182,7 +196,9 @@ // 【客户保护规则】保存 'crm/setting/config' => ['crm/setting/config', ['method' => 'POST']], // 【客户保护规则】详情 - 'crm/setting/configData' => ['crm/setting/configData', ['method' => 'POST']], + 'crm/setting/configData' => ['crm/setting/configData', ['method' => 'POST']], + // 【合同到期提醒】 + 'crm/setting/contractDay' => ['crm/setting/contractDay', ['method' => 'POST']], // 【商机状态组】列表 'crm/business_status/type' => ['crm/business_status/type', ['method' => 'POST']], @@ -220,7 +236,9 @@ // 【工作台】销售漏斗 'crm/index/funnel' => ['crm/index/funnel', ['method' => 'POST']], // 【工作台】销售趋势 - 'crm/index/saletrend' => ['crm/index/saletrend', ['method' => 'POST']], + 'crm/index/saletrend' => ['crm/index/saletrend', ['method' => 'POST']], + // 【工作台】查重 + 'crm/index/search' => ['crm/index/search', ['method' => 'POST']], // MISS路由 '__miss__' => 'admin/base/miss', diff --git a/config/version.php b/config/version.php index e2dd35af..ede25711 100644 --- a/config/version.php +++ b/config/version.php @@ -1,5 +1,5 @@ '9.0.0', -'RELEASE'=>'20190330', +'VERSION'=>'9.0.1', +'RELEASE'=>'20190508', ); \ No newline at end of file diff --git a/index.html b/index.html index c21ba169..f669520a 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -