pull/1/head
旭晓耿 4 years ago
parent e36dc45de4
commit a20e5ab784

@ -0,0 +1,8 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

@ -0,0 +1,51 @@
用户须知:
悟空CRM管理软件以下简称该软件由 郑州卡卡罗特软件科技有限公司www.5kcrm.com开发以下简称卡卡罗特。卡卡罗特依法拥有该软件的所有版权。本着共享开放的角度卡卡罗特以开放源代码的形式发布该软件。您可以在遵守该协议的前提下使用该软件。
官方地址www.5kcrm.com
官方电话400-0812-558
官方邮箱service@5kcrm.com
官方社区bbs.72crm.com
官方社群悟空CRM交流10群486745026
自您安装该软件开始,您和卡卡罗特之间的合同关系自动成立。除非您停止使用该软件或与卡卡罗特有签署额外合同,您须认真遵循该授权协议约定的每一条款。
约定:
下述条款中所指该软件的标志包括如下方面:
该软件源代码及文档中关于该软件的版权提示、文字、图片和链接。
该软件运行时界面上呈现出来的有关该软件的文字、图片和链接。
不包括如下方面:
该软件提供的演示数据中关于该软件的文字、图片和链接。
一、免责
该软件是以开放源代码的方式发行,您使用该软件无需任何费用,因此在使用该软件前,您须知晓:
1.1 卡卡罗特没有对该软件提供任何技术支持的义务,您可联系卡卡罗特购买商业的技术支持。
1.2 卡卡罗特对因使用该软件而产生直接或间接的任何问题不负任何责任。
1.3 开源不等于免费,开源不等于无版权,开源软件的发展需要您和卡卡罗特共同的努力。
二、自用该软件
2.1 您个人可自由使用或学习该软件,卡卡罗特不对您做任何限制。
2.2 您可以在您个人任意数量的电脑上运行该软件,卡卡罗特不对电脑的数量做任何限制。
2.3 您可以对该软件源代码进行修改以适应您个人学习研究的要求,您做的改动无需对外发布。
2.4 您个人使用该软件时,必须保留该软件的所有标志,不得以任何方式隐藏或遮掩任一标志。
三、企业用户
3.1未获商业授权之前,不得将本软件用于商业用途(包括但不限于企业内部使用、二次开发后进行销售、以营利为目的或实现盈利等形式)。
3.2未经官方许可,禁止在该软件的整体或任何部分基础上发展任何派生版本、修改版本或第三方版本用于重新分发,包括但不限于基于悟空CRM开发SAAS平台等相关服务。
3.3如果您未能遵守本协议的条款,您的授权将被终止,所被许可的权利将被收回,并承担相应法律责任。
四、授权例外
如果上述条款无法满足您使用该软件的要求,可联系卡卡罗特签署额外的合同以获得更灵活的授权许可。
五、合同约束
如果您违反了该协议的任一条款,该授权协议将自动终止,卡卡罗特保留通过法律手段追究责任的权利。

@ -1,7 +1,4 @@
# 72CRM-11.0-PHP
## 悟空CRM介绍
### 悟空CRM9.0版本)
悟空软件长期为企业提供企业管理软件(CRM/HRM/OA/ERP等)的研发、实施、营销、咨询、培训、服务于一体的信息化服务。悟空软件以高科技为起点,以技术为核心、以完善的售后服务为后盾,秉承稳固与发展、求实与创新的精神,已为国内外上千家企业提供服务。
悟空的发展受益于开源也会回馈于开源。2019年悟空CRM会继续秉承“拥抱开放、合作共赢、创造价值”的理念在开源的道路上继续砥砺前行和更多的社区开发者一起为国内外开源做出积极贡献。
@ -12,27 +9,21 @@
论坛:[http://bbs.72crm.net](http://bbs.72crm.net/)
演示地址:[demo11.5kcrm.net](http://demo11.5kcrm.net/)(帐号18888888888 密码123456)
演示地址:[demo9.5kcrm.net](http://demo9.5kcrm.net/)(帐号18888888888 密码123456)
QQ群交流群⑩群[486745026](https:////shang.qq.com/wpa/qunwpa?idkey=f4687b809bf63f08f707aa1c56dee8dbcb9526237c429c4532222021d65bf83c)
JAVA版下载地址[https://gitee.com/wukongcrm/72crm-java](https://gitee.com/wukongcrm/72crm-java)
扫码添加小悟官方客服微信,邀您加入千人微信交流群:
<img src="https://images.gitee.com/uploads/images/2019/1231/115927_f9c580c8_345098.png" width="200">
关注悟空CRM公众号了解更多悟空资讯
赞赏一下吧~~
<img src="https://images.gitee.com/uploads/images/2019/1202/135713_d3566c6a_345098.jpeg" width="200">
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g11.png)
悟空CRM采用全新的前后端分离模式本仓库代码中已集成前端vue打包后文件可免去打包操作
:boom: :boom: :boom: 注悟空CRM采用全新的前后端分离模式本仓库代码中已集成前端vue打包后文件 **可免去打包操作,无需运行前端** 。如需调整前端代码请单独下载前端代码前端代码在根目录的ux文件夹中
如需调整前端代码请单独下载前端代码前端代码在根目录的ux文件夹中
## 主要技术栈
后端框架ThinkPHP 5.0.24
后端框架ThinkPHP 5.0.2
前端MVVM框架Vue.JS 2.5.x
@ -49,11 +40,13 @@ UI框架Element-UI 2.6.3
代码中已集成前端vue打包后文件可免去打包操作
以本地phpstudy集成环境搭建举例
下载悟空CRM11.0开源版在服务器根目录www目录下创建72crm文件夹并放置代码 浏览器访问
下载悟空CRM9.0开源版在服务器根目录www目录下创建72crm文件夹并放置代码 浏览器访问
`http://localhost/72crm/index.php/admin/install/index.html `
根据安装提示步骤完成悟空CRM11.0 的部署安装
根据安装提示步骤完成悟空CRM9.0 的部署安装
@ -65,7 +58,7 @@ UI框架Element-UI 2.6.3
值得注意的一点是跨域的情况下会有预请求OPTION的情况
### Server搭建
服务端使用的框架为thinkphp5.0.24搭建前请确保拥有lamp/lnmp/wamp环境。
服务端使用的框架为thinkphp5.0.2搭建前请确保拥有lamp/lnmp/wamp环境。
这里所说的搭建其实就是把server框架放入WEB运行环境并使用80端口。
导入服务端根文件夹数据库文件public/sql/5kcrm.sql并修改config/database.php配置文件。
@ -91,20 +84,24 @@ PHP >= 5.6.0
## 系统介绍
以下为悟空CRM9.0 部分功能系统截图
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g1.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g2.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g3.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g4.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g5.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g6.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g7.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g8.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g9.png)
![](https://github.com/72crm/72crm/blob/master/ux/intro_img/g10.png)
## 悟空CRM功能模块预览
以下为悟空CRM11.0.0 部分功能系统截图
![仪表盘](https://images.gitee.com/uploads/images/2021/0206/112721_6e50397d_345098.png "仪表盘.png")
![客户列表](https://images.gitee.com/uploads/images/2021/0206/112822_4ab4eb50_345098.png "客户列表.png")
![客户详情](https://images.gitee.com/uploads/images/2021/0206/112842_d69aff0f_345098.png "客户详情.png")
![商机详情](https://images.gitee.com/uploads/images/2021/0206/112902_c38751fe_345098.png "商机详情.png")
![任务详情](https://images.gitee.com/uploads/images/2021/0206/112924_175278e2_345098.png "任务详情.png")
![商业智能](https://images.gitee.com/uploads/images/2021/0206/112938_0cbc95b7_345098.png "商业智能.png")
![审批](https://images.gitee.com/uploads/images/2021/0206/113001_bfcbee0a_345098.png "审批.png")
![自定义字段](https://images.gitee.com/uploads/images/2021/0206/113019_7894e7ed_345098.png "自定义字段.png")
![字段授权](https://images.gitee.com/uploads/images/2021/0206/113030_cefa8932_345098.png "字段授权.png")

@ -0,0 +1 @@
deny from all

@ -0,0 +1,172 @@
<?php
//权限控制
\think\Hook::add('check_auth','app\\common\\behavior\\AuthenticateBehavior');
use think\Db;
function structureList($structid,$str){
$str .= $structid.',';
if(Db::name('AdminStructure')->where('pid ='.$structid)->find() ){
$list = Db::name('AdminStructure')->field('id,name,pid')->where('pid ='.$structid)->select();
foreach($list as $value){
$str = structureList($value['id'],$str);
}
}
return $str;
}
/**
* cookies加密函数
* @param string 加密后字符串
*/
function encrypt($data, $key = '5k-72crm')
{
$cryptdes = new com\Cryptdes($key);
return $cryptdes->encrypt($data);
// $prep_code = serialize($data);
// $block = mcrypt_get_block_size('des', 'ecb');
// if (($pad = $block - (strlen($prep_code) % $block)) < $block) {
// $prep_code .= str_repeat(chr($pad), $pad);
// }
// $encrypt = mcrypt_encrypt(MCRYPT_DES, $key, trim($prep_code), MCRYPT_MODE_ECB);
// return base64_encode($encrypt);
}
/**
* cookies 解密密函数
* @param array 解密后数组
*/
function decrypt($data, $key = '5k-72crm')
{
$cryptdes = new com\Cryptdes($key);
return $cryptdes->decrypt($data);
// $str = base64_decode($str);
// $str = mcrypt_decrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
// $block = mcrypt_get_block_size('des', 'ecb');
// $pad = ord($str[($len = strlen($str)) - 1]);
// if ($pad && $pad < $block && preg_match('/' . chr($pad) . '{' . $pad . '}$/', $str)) {
// $str = substr($str, 0, strlen($str) - $pad);
// }
// return unserialize($str);
}
/**
* 部门树形数组
* @param type 0 下属数组, 1包含自己
*/
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.'--'));
}
}
return $array;
}
/**
* 解析sql语句
* @param string $content sql内容
* @param int $limit 如果为1则只返回一条sql语句默认返回所有
* @param array $prefix 替换表前缀
* @return array|string 除去注释之后的sql语句数组或一条语句
*/
function parse_sql($sql = '', $limit = 0, $prefix = []) {
// 被替换的前缀
$from = '';
// 要替换的前缀
$to = '';
// 替换表前缀
if (!empty($prefix)) {
$to = current($prefix);
$from = current(array_flip($prefix));
}
if ($sql != '') {
// 纯sql内容
$pure_sql = [];
// 多行注释标记
$comment = false;
// 按行分割,兼容多个平台
$sql = str_replace(["\r\n", "\r"], "\n", $sql);
$sql = explode("\n", trim($sql));
// 循环处理每一行
foreach ($sql as $key => $line) {
// 跳过空行
if ($line == '') {
continue;
}
// 跳过以#或者--开头的单行注释
if (preg_match("/^(#|--)/", $line)) {
continue;
}
// 跳过以/**/包裹起来的单行注释
if (preg_match("/^\/\*(.*?)\*\//", $line)) {
continue;
}
// 多行注释开始
if (substr($line, 0, 2) == '/*') {
$comment = true;
continue;
}
// 多行注释结束
if (substr($line, -2) == '*/') {
$comment = false;
continue;
}
// 多行注释没有结束,继续跳过
if ($comment) {
continue;
}
// 替换表前缀
if ($from != '') {
$line = str_replace('`'.$from, '`'.$to, $line);
}
if ($line == 'BEGIN;' || $line =='COMMIT;') {
continue;
}
// sql语句
array_push($pure_sql, $line);
}
// 只返回一条语句
if ($limit == 1) {
return implode($pure_sql, "");
}
// 以数组形式返回sql语句
$pure_sql = implode($pure_sql, "\n");
$pure_sql = explode(";\n", $pure_sql);
return $pure_sql;
} else {
return $limit == 1 ? '' : [];
}
}
function sendRequest($url, $params = array() , $headers = array()) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if (!empty($params)) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
}
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$res = curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$value = curl_exec($ch);
if (curl_errno($ch)) {
$return = array(0, '连接服务器出错', -1);
} else {
if (!$value) {
$return = array(0, '服务器返回数据异常', -1);
}
$return = $value;
}
curl_close($ch);
return $return;
}

@ -0,0 +1,14 @@
<?php
// 基础模块配置文件
return [
//'配置项'=>'配置值'
'LANG_SWITCH_ON' => true, //开启语言包功能
'LANG_AUTO_DETECT' => true, // 自动侦测语言
'DEFAULT_LANG' => 'zh-cn', // 默认语言
'LANG_LIST' => 'en-us,zh-cn,zh-tw', //必须写可允许的语言列表
'VAR_LANGUAGE' => 'l', // 默认语言切换变量
];

@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | Description: Api基础类验证权限
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Request;
use think\Db;
use app\common\adapter\AuthAdapter;
use app\common\controller\Common;
class ApiCommon extends Common
{
public function _initialize()
{
parent::_initialize();
/*获取头部信息*/
$header = Request::instance()->header();
$request = Request::instance();
$authKey = $header['authkey'];
$sessionId = $header['sessionid'];
$paramArr = $request->param();
$platform = $paramArr['platform'] ? '_'.$paramArr['platform'] : ''; //请求平台(mobile,ding)
$cache = cache('Auth_'.$authKey.$platform);
// 校验sessionid和authKey
if (empty($sessionId) || empty($authKey) || empty($cache) || ($cache['sessionId'] !== $sessionId)) {
header('Content-Type:application/json; charset=utf-8');
$dataTime=date('H:i',time());
exit(json_encode(['code' => 302, 'data' => ['extra' => 1, 'extraTime' => $dataTime], 'msg' => '请先登录!']));
}
//登录有效时间
$cacheConfig = config('cache');
$loginExpire = $cacheConfig['expire'] ? : 86400*3;
// 检查账号有效性
$userInfo = $cache['userInfo'];
$map['id'] = $userInfo['id'];
$map['status'] = array('in',['1','2']);
$userData = Db::name('admin_user')->where($map)->find();
if (!$userData) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>103, 'data' => [], 'msg'=>'账号已被删除或禁用']));
}
session('user_id', $userInfo['id']);
// 更新缓存
cache('Auth_'.$authKey, $cache, $loginExpire);
// $GLOBALS['userInfo'] = $userInfo;
}
}

@ -0,0 +1,76 @@
<?php
// +----------------------------------------------------------------------
// | Description: 基础类,无需验证权限。
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\controller;
use com\verify\HonrayVerify;
use app\common\controller\Common;
use think\Request;
use think\Session;
class Base extends Common
{
public function login()
{
$request = Request::instance();
$paramArr = $request->param();
$userModel = model('User');
$param = $this->param;
$username = $param['username'];
$password = $param['password'];
$verifyCode = !empty($param['verifyCode']) ? $param['verifyCode']: '';
$isRemember = !empty($param['isRemember']) ? $param['isRemember']: '';
$data = $userModel->login($username, $password, $verifyCode, $isRemember, $type, $authKey, $paramArr);
Session::set('user_id', $data['userInfo']['id']);
if (!$data) {
return resultArray(['error' => $userModel->getError()]);
}
return resultArray(['data' => $data]);
}
//退出登录
public function logout()
{
$param = $this->param;
$header = Request::instance()->header();
$request = Request::instance();
$paramArr = $request->param();
$platform = $paramArr['platform'] ? '_'.$paramArr['platform'] : ''; //请求平台(mobile,ding)
$cache = cache('Auth_'.$authKey.$platform,null);
cookie(null, '72crm_');
cookie(null, '5kcrm_');
session('user_id','null');
return resultArray(['data'=>'退出成功']);
}
//获取图片验证码
public function getVerify()
{
$captcha = new HonrayVerify(config('captcha'));
return $captcha->entry();
}
//网站信息
public function index()
{
$systemModel = model('System');
$data = $systemModel->getDataList();
return resultArray(['data' => $data]);
}
// miss 路由:处理没有匹配到的路由规则
public function miss()
{
if (Request::instance()->isOptions()) {
return ;
} else {
echo '悟空软件';
}
}
}

@ -0,0 +1,78 @@
<?php
// +----------------------------------------------------------------------
// | Description: 评论
// +----------------------------------------------------------------------
// | Author: yykun
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Request;
use think\Session;
use think\Hook;
use app\common\controller\Common;
class Comment extends Common
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''], //不登录可访问
'allow'=>['save','delete'] //需要登录才能访问
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
$c = strtolower($request->controller());
$m = strtolower($request->module());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
//添加评论
public function save()
{
$param = $this->param;
$model = model('Comment');
if ($param['task_id']) {
$userInfo = $this->userInfo;
$param['create_user_id'] = $userInfo['id'];
$flag = $model->createData($param);
if ($flag) {
return resultArray(['data'=>$flag]);
} else {
return resultArray(['error'=>$workModel->getError()]);
}
} else {
return resultArray(['error'=>'参数错误']);
}
}
//删除评论
public function delete()
{
$param = $this->param;
$commentModel = model('Comment');
if ($param['comment_id']) {
$userInfo = $this->userInfo;
$param['create_user_id'] = $userInfo['id'];
$flag = $commentModel->delDataById($param);
if ($flag) {
return resultArray(['data'=>'删除成功']);
} else {
return resultArray(['error'=>$commentModel->getError()]);
}
} else {
return resultArray(['error'=>'参数错误']);
}
}
}

@ -0,0 +1,68 @@
<?php
// +----------------------------------------------------------------------
// | Description: 应用状态
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
class ConfigSet extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 应用状态列表
* @author Michael_xu
* @return
*/
public function index()
{
$configModel = model('Config');
$data = $configModel->getDataList();
return resultArray(['data' => $data]);
}
/**
* 状态编辑
* @author Michael_xu
* @return
*/
public function update()
{
$configModel = model('Config');
$param = $this->param;
if (!$param['id']) {
return resultArray(['error' => '参数错误']);
}
if ($configModel->updateDataById($param, $param['id'])) {
return resultArray(['data' => '编辑成功']);
}
return resultArray(['error' => $configModel->getError()]);
}
}

@ -0,0 +1,152 @@
<?php
/**
* 日志规则控制器
*
* @author qifan
* @date 2020-12-03
*/
namespace app\admin\controller;
use app\admin\logic\DailyRuleLogic;
use think\Hook;
use think\Request;
class DailyRule extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['welcome', 'setwelcome', 'worklogrule', 'setworklogrule','scheduleList','addschedule','setschedule','delschedule']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 获取欢迎语
*
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
*/
public function welcome(DailyRuleLogic $dailyRuleLogic)
{
$data = $dailyRuleLogic->welcome();
return resultArray(['data' => $data]);
}
/**
* 添加欢迎语
*
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function setWelcome(DailyRuleLogic $dailyRuleLogic)
{
$mark = $this->param['welcome'];
if (empty($mark)) return resultArray(['error' => '缺少日志欢迎语!']);
if (!$dailyRuleLogic->setWelcome($mark)) return resultArray(['error' => '添加失败!']);
return resultArray(['data' => '添加成功!']);
}
/**
* 获取日志规则
*
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function workLogRule(DailyRuleLogic $dailyRuleLogic)
{
$data = $dailyRuleLogic->workLogRule();
return resultArray(['data' => $data]);
}
/**
* 设置日志规则
*
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function setWorkLogRule(DailyRuleLogic $dailyRuleLogic)
{
if (empty($this->param['rule'])) return resultArray(['error' => '缺少规则参数!']);
$dailyRuleLogic->setWorkLogRule($this->param['rule']);
return resultArray(['data' => '设置成功!']);
}
/**
* 获取日程规则
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function scheduleList(DailyRuleLogic $dailyRuleLogic){
$data = $dailyRuleLogic->schedule();
return resultArray(['data' => $data]);
}
/**
* 设置日程自定义规则
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function setSchedule(DailyRuleLogic $dailyRuleLogic){
if(empty($this->param['id'])) return resultArray(['error'=>'缺少参数']);
$dailyRuleLogic->setSchedule($this->param);
return resultArray(['data' => '设置成功!']);
}
/**
* 添加日程自定义规则
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
*/
public function addSchedule(DailyRuleLogic $dailyRuleLogic){
if(empty($this->param['name'])) return resultArray(['error'=>'缺少参数']);
$dailyRuleLogic->addSchedule($this->param);
return resultArray(['data' => '添加成功!']);
}
/**
* 删除日程自定义规则
* @param DailyRuleLogic $dailyRuleLogic
* @return \think\response\Json
*/
public function delSchedule(DailyRuleLogic $dailyRuleLogic){
if(empty($this->param['id'])) return resultArray(['error'=>'缺少参数']);
$dailyRuleLogic->delSchedule($this->param['id']);
return resultArray(['data' => '删除成功!']);
}
}

@ -0,0 +1,369 @@
<?php
// +----------------------------------------------------------------------
// | Description: 审批流程
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
use think\Db;
class ExamineFlow extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[],
'allow'=>['index','save','update','read','delete','enables','steplist','userlist','recordlist']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
//权限判断
$unAction = ['steplist','userlist','recordlist'];
if (!in_array($a, $unAction) && !checkPerByAction('admin', 'examine_flow', 'index')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
/**
* 审批流程列表
* @author Michael_xu
* @return
*/
public function index()
{
$examineFlowModel = model('ExamineFlow');
$param = $this->param;
//过滤审批类型中关联的审批流
$param['types'] = ['neq','oa_examine'];
$data = $examineFlowModel->getDataList($param);
return resultArray(['data' => $data]);
}
/**
* 添加审批流程
*
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function save()
{
if (empty($this->param['types'])) return resultArray(['error' => '请选择关联对象!']);
$examineFlowModel = model('ExamineFlow');
$examineStepModel = model('ExamineStep');
$param = $this->param;
$userInfo = $this->userInfo;
$param['update_user_id'] = $userInfo['id'];
# 验证名称是否重复
$repeatWhere['name'] = $param['name'];
$repeatWhere['is_deleted'] = 0;
$repeatWhere['types'] = ['neq', 'oa_examine'];
if (db('admin_examine_flow')->where($repeatWhere)->value('flow_id')) return resultArray(['error' => '审批流名称重复!']);
//处理
$param['user_ids'] = arrayToString($param['user_ids']);
$param['structure_ids'] = arrayToString($param['structure_ids']);
$res = $examineFlowModel->createData($param);
$param['config'] = $param['config'] ? 1 : 0;
if ($res) {
$config = $param['config'];
if ((int)$config == 1) {
//固定审批流
$resStep = $examineStepModel->createStepData($param['step'], $res['flow_id']);
if ($resStep) {
return resultArray(['data' => '添加成功']);
} else {
db('admin_examine_flow')->where(['flow_id' => $res['flow_id']])->delete();
return resultArray(['error' => $examineStepModel->getError()]);
}
}
return resultArray(['data' => '添加成功']);
} else {
return resultArray(['error' => $examineFlowModel->getError()]);
}
}
/**
* 编辑审批流程
*
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function update()
{
if (empty($this->param['types'])) return resultArray(['error' => '请选择关联对象!']);
$examineFlowModel = model('ExamineFlow');
$examineStepModel = model('ExamineStep');
$param = $this->param;
$userInfo = $this->userInfo;
$param['update_user_id'] = $userInfo['id'];
$param['create_time'] = time();
$param['update_time'] = time();
$flowId = $param['flow_id'];
unset($param['flow_id']);
# 验证名称是否重复
$repeatWhere['name'] = $param['name'];
$repeatWhere['is_deleted'] = 0;
$repeatWhere['types'] = ['neq', 'oa_examine'];
$repeatWhere['flow_id'] = ['neq', $flowId];
if (db('admin_examine_flow')->where($repeatWhere)->value('flow_id')) return resultArray(['error' => '审批流名称重复!']);
//处理
$param['user_ids'] = arrayToString($param['user_ids']);
$param['structure_ids'] = arrayToString($param['structure_ids']);
$res = $examineFlowModel->createData($param);
$param['config'] = $param['config'] ? 1 : 0;
if ($res) {
//将当前审批流标记为已删除,重新创建审批流(目的:保留审批流程记录)
$upData = [];
$upData['is_deleted'] = 1;
$upData['delete_time'] = time();
$upData['delete_user_id'] = $userInfo['id'];
$upData['status'] = 0;
db('admin_examine_flow')->where(['flow_id' => $flowId])->update($upData);
$config = $param['config'];
if ((int)$config == 1) {
//固定审批流
$resStep = $examineStepModel->createStepData($param['step'], $res['flow_id']);
if ($resStep) {
return resultArray(['data' => '添加成功']);
} else {
db('admin_examine_flow')->where(['flow_id' => $res['flow_id']])->delete();
return resultArray(['error' => $examineStepModel->getError()]);
}
}
return resultArray(['data' => '添加成功']);
} else {
return resultArray(['error' => $examineFlowModel->getError()]);
}
// $newData = db('admin_examine_flow')->where(['flow_id' => $param['flow_id']])->find();
// $newData['user_ids'] = arrayToString($param['user_ids']);
// $param['structure_ids'] = arrayToString($param['structure_ids']);
// $param['update_user_id'] = $userInfo['id'];
// $param['create_time'] = time();
// $param['update_time'] = time();
// $param['status'] = 1;
// $resUpdate = $examineFlowModel->updateDataById($param, $param['flow_id']);
//
// if ($resUpdate) {
// if ($param['config'] == 1) {
// $resStep = $examineStepModel->createStepData($param['step'], $resUpdate['flow_id']);
// if (!$resStep) {
// 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' => $param['flow_id']])->update($upData);
// if (!$resFlow) {
// return resultArray(['error' => '编辑失败1']);
// }
// return resultArray(['data' => '编辑成功']);
// } else {
// return resultArray(['error' => '编辑失败2']);
// }
}
/**
* 审批流程详情
* @author Michael_xu
* @param
* @return
*/
public function read()
{
$examineFlowModel = model('ExamineFlow');
$param = $this->param;
$res = $examineFlowModel->getDataById($param['id']);
if (!$res) {
return resultArray(['error' => $examineFlowModel->getError()]);
}
return resultArray(['data' => $res]);
}
/**
* 删除审批流程(逻辑删)
* @author Michael_xu
* @param
* @return
*/
public function delete()
{
$examineFlowModel = model('ExamineFlow');
$param = $this->param;
$data = $examineFlowModel->signDelById($param['flow_id']);
if (!$data) {
return resultArray(['error' => $examineFlowModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
/**
* 审批流程状态
* @author Michael_xu
* @param ids array
* @param status 1启用0禁用
* @return
*/
public function enables()
{
$examineFlowModel = model('ExamineFlow');
$param = $this->param;
$id = [$param['flow_id']];
$data = $examineFlowModel->enableDatas($id, $param['status']);
if (!$data) {
return resultArray(['error' => $examineFlowModel->getError()]);
}
return resultArray(['data' => '操作成功']);
}
/**
* 完整审批步骤(固定审批流)
* @author Michael_xu
* @param flow_id 审批流ID
* @param user_id 审批对象创建人ID
* @return
*/
public function stepList()
{
$param = $this->param;
$userInfo = $this->userInfo;
$examineStepModel = model('ExamineStep');
$examineFlowModel = model('ExamineFlow');
$check_user_id = $userInfo['id'];
$flow_id = $param['flow_id'];
$types = $param['types'];
$types_id = $param['types_id'];
$typesArr = ['crm_contract', 'crm_receivables', 'crm_invoice', 'oa_examine'];
if (!$types || !in_array($types, $typesArr)) {
return resultArray(['error' => '参数错误']);
}
if ($flow_id) {
$examineFlowData = $examineFlowModel->getDataById($param['flow_id']);
if (!$examineFlowData) {
return resultArray(['error' => '参数错误']);
}
$typesInfo = $examineStepModel->getDataByTypes($types, $types_id);
$user_id = $typesInfo['dataInfo']['owner_user_id'];
if ($types == 'oa_examine') {
$user_id = $typesInfo['dataInfo']['create_user_id'];
}
if (!$user_id) {
return resultArray(['error' => '参数错误']);
}
} else {
$user_id = $check_user_id;
// 获取符合条件的审批流
$examineFlowData = $examineFlowModel->getFlowByTypes($user_id, $types, $types_id);
if (!$examineFlowData) {
# 合同、回款、发票模块审批流停用
if (in_array($types, ['crm_contract', 'crm_receivables', 'crm_invoice'])) {
return resultArray(['data' => ['examineStatus' => false]]);
}
return resultArray(['error' => '无可用审批流,请联系管理员']);
}
$flow_id = $examineFlowData['flow_id'];
}
if ($types == 'oa_examine') {
$category_id = db('oa_examine')->where(['examine_id' => $types_id])->value('category_id');
}
$list=[];
//自选还是流程(1固定,0自选)
if ($examineFlowData['config'] == 1) {
//获取审批流程
$stepInfo = $examineStepModel->getStepList($flow_id, $user_id, $types, $types_id, $check_user_id, $param['action'], $category_id);
$stepList = $stepInfo['steplist'];
$list=$stepInfo['steplist'][0]['user_id_info'];
// foreach ($stepInfo['steplist'] as $k=>$v){
// $data['user_id_info'][]=$v['user_id_info'];
// }
} else {
$stepInfo = $examineStepModel->getPerStepList($types, $types_id, $user_id, $check_user_id, $param['action']);
$stepList = $stepInfo['steplist'];
$list=$stepInfo['steplist'][0]['user_id_info'];
// foreach ($stepInfo['steplist'] as $k=>$v){
// $data['user_id_info'][]=$stepInfo['steplist']['user_id_info'];
// }
}
$data = [];
$data['config'] = (int) $examineFlowData['config']; //1固定,0自选
$data['stepList'] = $stepList ? : [];
$data['examine_user'] = $list ? : [];
$data['is_check'] = $stepInfo['is_check'] ? : 0;
$data['is_recheck'] = $stepInfo['is_recheck'] ? : 0;
$data['examineStatus'] = true;
return resultArray(['data' => $data]);
}
/**
* 自选审批人列表(授权审批类型)
* @author Michael_xu
* @param types 类型
* @return
*/
public function userList()
{
$param = $this->param;
$userInfo = $this->userInfo;
$types = $param['types'];
$examineStepModel = model('ExamineStep');
$userModel = model('User');
// $examine_user_ids = $examineStepModel->getUserByPer($types);
//暂定返回全部
$examine_user_ids = getSubUserId(true, 1);
$where = [];
$where['user.id'] = array('in',$examine_user_ids);
$where['status'] = ['gt',0];
$where['pageType'] = 'all';
$userList = $userModel->getDataList($where);
return resultArray(['data' => $userList['list']]);
}
/**
* 审批记录
* @author Michael_xu
* @param types 类型
* @return
*/
public function recordList()
{
$param = $this->param;
$userInfo = $this->userInfo;
$examineRecordModel = model('ExamineRecord');
$list = $examineRecordModel->getDataList($param) ? : [];
return resultArray(['data' => $list]);
}
}

@ -0,0 +1,673 @@
<?php
// +----------------------------------------------------------------------
// | Description: 自定义字段
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\logic\FieldGrantLogic;
use app\crm\logic\VisitLogic;
use app\crm\model\Business;
use app\crm\model\Contacts;
use app\crm\model\Contract;
use app\crm\model\Customer;
use app\crm\model\InvoiceInfoLogic;
use app\crm\model\Leads;
use app\crm\model\Product;
use app\crm\model\Receivables;
use think\Hook;
use think\Request;
use think\Db;
use app\admin\model\User as UserModel;
class Field extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index','getfield','update','read','config','validates','configindex','columnwidth','uniquefield']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 自定义字段列表
*/
public function index()
{
//权限判断
if (!checkPerByAction('admin', 'crm', 'field')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$param = $this->param;
$types_arr = [
['types' => 'crm_leads','name' => '线索管理'],
['types' => 'crm_customer','name' => '客户管理'],
['types' => 'crm_contacts','name' => '联系人管理'],
['types' => 'crm_product','name' => '产品管理'],
['types' => 'crm_business','name' => '商机管理'],
['types' => 'crm_contract','name' => '合同管理'],
['types' => 'crm_receivables','name' => '回款管理'],
['types' => 'crm_visit','name' => '客户回访管理'],
];
$examine_types_arr = [];
switch ($param['type']) {
case 'crm' : $typesArr = $types_arr; break;
case 'examine' : $typesArr = $examine_types_arr; break;
default : $typesArr = $types_arr; break;
}
foreach ($typesArr as $k=>$v) {
$updateTime = db('admin_field')->where(['types' => $v['types']])->max('update_time');
$typesArr[$k]['update_time'] = !empty($updateTime) ? date('Y-m-d H:i:s', $updateTime) : '';
}
return resultArray(['data' => $typesArr]);
}
/**
* 自定义字段数据
*/
public function read()
{
$fieldModel = model('Field');
$param = $this->param;
$data = $fieldModel->getDataList($param);
if ($data === false) {
return resultArray(['error' => $fieldModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 自定义字段创建
*/
public function update()
{
# 权限判断 todo 允许有相应权限的普通员工操作,暂时注释代码,后期修改权限验证。
// if (!checkPerByAction('admin', 'crm', 'field')) {
// header('Content-Type:application/json; charset=utf-8');
// exit(json_encode(['code'=>102,'error'=>'无权操作']));
// }
# 系统审批类型暂不支持编辑
if ($this->param['types'] == 'oa_examine' && $this->param['types_id'] < 7) {
return resultArray(['error' => '系统审批类型暂不支持编辑']);
}
$fieldModel = model('Field');
$param = $this->param;
$types = $param['types'];
$types_id = $param['types_id'] ? : 0;
// $data['types'] = $param['types'];
$data = $param['data'];
$saveParam = []; # 新增数据
$updateParam = []; # 编辑数据
$delParam = []; # 删除数据
$fieldIds = []; # 删除数据兼容前端11.*.*版本)
$i = 0;
foreach ($data AS $k => $v) {
$i++;
if ($v['field_id']) {
if (isset($v['is_deleted']) && $v['is_deleted'] == '1') {
# 删除
$delParam[] = $v['field_id']; //删除
} else {
# 编辑
$updateParam[$k] = $v;
$updateParam[$k]['order_id'] = $i;
# 用来删除自定义字段兼容前端11.*.*版本记录存在的自定义字段ID取出差集就是要删的数。
$fieldIds[] = $v['field_id'];
}
} else {
# 新增
$saveParam[$k] = $v;
$saveParam[$k]['order_id'] = $i;
$saveParam[$k]['types_id'] = $types_id;
}
}
# 错误数据
$errorMessage = [];
# 兼容前端11.*.*版本的删除条件处理,通过比较差异,来确定谁被前端给删除了 todo 这段代码需要写在新增上面,不然会把新增的给删除掉
$oldFieldIds = Db::name('admin_field')->where('types', $types)->column('field_id');
$deleteIds = array_diff($oldFieldIds, $fieldIds);
foreach ($deleteIds AS $key => $value) {
if (!in_array($value, $delParam)) $delParam[] = $value;
}
# 新增
if (!empty($saveParam)) {
if (!$data = $fieldModel->createData($types, $saveParam)) {
$errorMessage[] = $fieldModel->getError();
}
}
# 编辑
if (!empty($updateParam)) {
if (!$data = $fieldModel->updateDataById($updateParam)) {
$errorMessage[] = $fieldModel->getError();
}
}
# 删除
if (!empty($delParam)) {
if (!$data = $fieldModel->delDataById($delParam)) {
$errorMessage[] = $fieldModel->getError();
}
}
# 自定义字段变更后,同步更新字段授权表
(new FieldGrantLogic())->fieldGrantDiyHandle($types);
if ($errorMessage) {
return resultArray(['error' => $errorMessage]);
} else {
return resultArray(['data' => '修改成功']);
}
}
/**
* 自定义字段数据获取
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getField()
{
$fieldModel = model('Field');
$userModel = model('User');
$param = $this->param;
$module = trim($param['module']);
$controller = trim($param['controller']);
$action = trim($param['action']);
$system = !empty($param['system']) ? $param['system'] : 0;
unset($param['system']);
if (!$module || !$controller || !$action) {
return resultArray(['error' => '参数错误']);
}
//判断权限
$userInfo = $this->userInfo;
$user_id = $userInfo['id'];
$types = $param['types'];
$types_id = $param['types_id'] ? : '';
$dataInfo = [];
if ($action == 'read' || $action == 'update') {
//获取详情数据
if (($param['action'] == 'update' || $param['action'] == 'read') && $param['action_id']) {
switch ($param['types']) {
case 'crm_customer' :
$customerModel = new \app\crm\model\Customer();
$dataInfo = $customerModel->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'customer', $param['action']);
//读写权限
$roPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'read');
$rwPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'update');
//判断是否客户池数据
$wherePool = $customerModel->getWhereByPool();
$resPool = db('crm_customer')->alias('customer')->where(['customer_id' => $param['action_id']])->where($wherePool)->find();
if (!$resPool && !in_array($dataInfo['owner_user_id'],$auth_user_ids) && !$roPre && !$rwPre) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_leads' :
$leadsModel = new \app\crm\model\Leads();
$dataInfo = $leadsModel->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'leads', $param['action']);
if (!in_array($dataInfo['owner_user_id'],$auth_user_ids)) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_contacts' :
$contactsModel = new \app\crm\model\Contacts();
$dataInfo = $contactsModel->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'contacts', $param['action']);
if (!in_array($dataInfo['owner_user_id'],$auth_user_ids)) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_business' :
$businessModel = new \app\crm\model\Business();
$dataInfo = $businessModel->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'business', $param['action']);
//读写权限
$roPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'read');
$rwPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'update');
if (!in_array($dataInfo['owner_user_id'],$auth_user_ids) && !$roPre && !$rwPre) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_contract' :
$contractModel = new \app\crm\model\Contract();
$dataInfo = $contractModel->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'contract', $param['action']);
//读写权限
$roPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'read');
$rwPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'update');
if (!in_array($dataInfo['owner_user_id'],$auth_user_ids) && !$roPre && !$rwPre) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_product' :
$productModel = new \app\crm\model\Product();
$dataInfo = $productModel->getDataById(intval($param['action_id']));
break;
case 'crm_receivables' :
$receivablesModel = new \app\crm\model\Receivables();
$dataInfo = $receivablesModel->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'receivables', $param['action']);
if (!in_array($dataInfo['owner_user_id'],$auth_user_ids)) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_receivables_plan' :
$receivablesPlanModel = new \app\crm\model\ReceivablesPlan();
$dataInfo = $receivablesPlanModel->getDataById(intval($param['action_id']));
break;
case 'oa_examine' :
$examineModel = new \app\oa\model\Examine();
$examineFlowModel = new \app\admin\model\ExamineFlow();
$dataInfo = $examineModel->getDataById(intval($param['action_id']));
# 前端没有传types_id,这里需要指定一下types_id
if (!empty($dataInfo['category_id'])) $param['types_id'] = $dataInfo['category_id'];
$adminIds = $userModel->getAdminId(); //管理员
$checkUserIds = $examineFlowModel->getUserByFlow($dataInfo['flow_id'], $dataInfo['create_user_id'], $dataInfo['check_user_id']);
if (((int)$dataInfo['create_user_id'] != $user_id && !in_array($user_id,$adminIds) && !in_array($user_id,$checkUserIds))) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
case 'crm_visit' :
$visit = new \app\crm\model\Visit();
$dataInfo = $visit->getDataById(intval($param['action_id']));
//判断权限
$auth_user_ids = $userModel->getUserByPer('crm', 'visit', $param['action']);
//读写权限
$roPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'read');
$rwPre = $userModel->rwPre($user_id, $dataInfo['ro_user_id'], $dataInfo['rw_user_id'], 'update');
if (!in_array($dataInfo['owner_user_id'],$auth_user_ids) && !$roPre && !$rwPre) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
break;
}
}
}
$param['user_id'] = $user_id;
$action_id = $param['action_id'] ? : '';
$data = $fieldModel->field($param, $dataInfo) ? : [];
# 去掉客户模块下的成交信息
if ($param['types'] == 'crm_customer' && $param['action'] == 'read') {
foreach ($data AS $key => $value) {
if ($value['field'] == 'deal_status') {
unset($data[(int)$key]);
break;
}
}
}
if ($param['types'] == 'crm_customer' && $param['action'] == 'index') {
$data[] = [
'field' => 'pool_day',
'name' => '距进入公海天数',
'form_type' => 'text',
'writeStatus' => 0,
'fieldName' => 'pool_day'
];
}
# 客户锁定状态
if ($param['types'] == 'crm_customer' && $param['action'] == 'index') {
$data[] = [
'field' => "is_lock",
'fieldName' => "is_lock",
'form_type' => "text",
'name' => "锁定状态",
'width' => ""
];
}
# 合同自动编号设置
if ($param['types'] == 'crm_contract') {
foreach ($data AS $key => $value) {
if ($value['field'] == 'num') {
if ($this->getAutoNumberStatus(1)) {
$data[$key]['is_null'] = 0;
$data[$key]['is_unique'] = 0;
}
$data[$key]['autoGeneNumber'] = $this->getAutoNumberStatus(1) ? 1 : 0;
}
}
}
# 回款自动编号设置
if ($param['types'] == 'crm_receivables') {
foreach ($data AS $key => $value) {
if ($value['field'] == 'number') {
if ($this->getAutoNumberStatus(2)) {
$data[$key]['is_null'] = 0;
$data[$key]['is_unique'] = 0;
}
$data[$key]['autoGeneNumber'] = $this->getAutoNumberStatus(2) ? 1 : 0;
}
}
}
# 回访自动编号设置
if ($param['types'] == 'crm_visit') {
foreach ($data AS $key => $value) {
if ($value['field'] == 'number') {
if ($this->getAutoNumberStatus(3)) {
$data[$key]['is_null'] = 0;
$data[$key]['is_unique'] = 0;
}
$data[$key]['autoGeneNumber'] = $this->getAutoNumberStatus(3) ? 1 : 0;
}
}
}
# 隐藏回款计划中的附件
if ($param['types'] == 'crm_receivables_plan') {
foreach ($data AS $key => $value) {
if ($value['field'] == 'file') {
unset($data[(int)$key]);
}
}
}
if (!empty($system) && $system == 1) {
# 商机和合同排除产品字段
if (in_array($param['types'], ['crm_business', 'crm_contract'])) {
foreach ($data AS $key => $value) {
if ($value['field'] == 'product' && $value['name'] == '产品') {
unset($data[(int)$key]);
break;
}
}
}
$data = array_values($data);
# 系统信息
switch ($types) {
case 'crm_leads' :
$leadsModel = new Leads();
$leadsData = $leadsModel->getSystemInfo($action_id);
$leadsArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间', 'follow_time' => '最后跟进时间'];
foreach ($leadsData AS $key => $value) {
if (empty($leadsArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $leadsArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_customer' :
$customerModel = new Customer();
$customerData = $customerModel->getSystemInfo($action_id);
$customerArray = ['obtain_time' => '负责人获取客户时间', 'create_time' => '创建时间', 'update_time' => '更新时间', 'follow_time' => '最后跟进时间', 'follow_record' => '最后跟进记录', 'deal_status' => '成交状态'];
foreach ($customerData AS $key => $value) {
if (empty($customerArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $customerArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_contacts' :
$contactsModel = new Contacts();
$contactsData = $contactsModel->getSystemInfo($action_id);
$contactsArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间', 'follow_time' => '最后跟进时间'];
foreach ($contactsData AS $key => $value) {
if (empty($contactsArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $contactsArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_business' :
$businessModel = new Business();
$businessData = $businessModel->getSystemInfo($action_id);
$businessArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间', 'follow_time' => '最后跟进时间'];
foreach ($businessData AS $key => $value) {
if (empty($businessArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $businessArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_contract' :
$contractModel = new Contract();
$contractData = $contractModel->getSystemInfo($action_id);
$contractArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间', 'follow_time' => '最后跟进时间', 'done_money' => '已收款金额', 'un_money' => '未收款金额'];
foreach ($contractData AS $key => $value) {
if (empty($contractArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $contractArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_receivables' :
$receivablesModel = new Receivables();
$receivablesData = $receivablesModel->getSystemInfo($action_id);
$receivablesArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间'];
foreach ($receivablesData AS $key => $value) {
if (empty($receivablesArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $receivablesArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_product' :
$productModel = new Product();
$productData = $productModel->getSystemInfo($action_id);
$productArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间'];
foreach ($productData AS $key => $value) {
if (empty($productArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $productArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
case 'crm_visit' :
$visitLogic = new VisitLogic();
$visitData = $visitLogic->getSystemInfo($action_id);
$visitArray = ['create_user_name' => '创建人', 'create_time' => '创建时间', 'update_time' => '更新时间'];
foreach ($visitData AS $key => $value) {
if (empty($visitArray[$key])) continue;
$data[] = [
'field' => $key,
'name' => $visitArray[$key],
'form_type' => strpos($key, 'time') ? 'datetime' : 'text',
'value' => $value,
'system' => 1
];
}
break;
}
}
$data = $fieldModel->resetField($param['types'], $data);
return resultArray(['data' => array_values($data)]);
}
/**
* 自定义字段数据验重
*
* @return \think\response\Json
*/
public function validates()
{
$param = $this->param;
$fieldModel = model('Field');
if (is_array($param['val'])) {
//多选类型暂不验证
return resultArray(['data' => '验证通过']);
}
$res = $fieldModel->getValidate(trim($param['field']), trim($param['val']), intval($param['id']), trim($param['types']));
if (!$res) {
return resultArray(['error' => $fieldModel->getError()]);
}
return resultArray(['data' => '验证通过']);
}
/**
* 自定义字段列表设置(排序、展示、列宽度)
* @param types 分类
* @param value 值
*/
public function config()
{
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$userFieldModel = model('UserField');
$res = $userFieldModel->updateConfig($param['types'], $param);
if (!$res) {
return resultArray(['error' => $userFieldModel->getError()]);
}
return resultArray(['data' => '设置成功']);
}
/**
* 自定义字段列宽度设置
* @param types 分类
* @param field 字段名
* @param width 列宽度
*/
public function columnWidth()
{
$param = $this->param;
$userInfo = $this->userInfo;
$userFieldModel = model('UserField');
$width = $param['width'] > 10 ? $param['width'] : '';
$unField = array('pool_day','owner_user_name','is_lock','create_user_name');
if (!in_array($param['field'],$unField)) {
$res = $userFieldModel->setColumnWidth($param['types'], $param['field'], $width, $userInfo['id']);
if (!$res) {
return resultArray(['error' => $userFieldModel->getError()]);
}
}
return resultArray(['data' => '设置成功']);
}
/**
* 自定义字段列表设置数据
* @param types 分类
* @param value 值
*/
public function configIndex()
{
$param = $this->param;
$userInfo = $this->userInfo;
$userFieldModel = model('UserField');
$res = $userFieldModel->getDataList($param['types'], $userInfo['id']);
if (!$res) {
return resultArray(['error' => $userFieldModel->getError()]);
}
return resultArray(['data' => $res]);
}
/**
* 自定义验重字段
* @param types 分类
* @param
*/
public function uniqueField()
{
$param = $this->param;
if ($param['types'] == 'crm_user') {
$list = array_filter(UserModel::$import_field_list, function ($val) {
return $val['is_unique'] == 1;
});
$list = array_column($list, 'name');
} else {
$list = db('admin_field')->where(['types' => $param['types'],'is_unique' => 1])->column('name');
}
$list = $list ? implode(',',$list) : '无';
return resultArray(['data' => $list]);
}
/**
* 获取自动编号状态
*
* @param $type
* @return int|mixed|string|null
*/
private function getAutoNumberStatus($type)
{
return Db::name('crm_number_sequence')->where('number_type', $type)->where('status', 0)->value('number_sequence_id');
}
}

@ -0,0 +1,74 @@
<?php
/**
* 字段授权控制器
*
* @author qifan
* @date 2020-12-02
*/
namespace app\admin\controller;
use app\admin\logic\FieldGrantLogic;
use think\Hook;
use think\Request;
class FieldGrant extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index', 'update']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 字段授权列表
*
* @param FieldGrantLogic $fieldGrantLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index(FieldGrantLogic $fieldGrantLogic)
{
$data = $fieldGrantLogic->index($this->param);
return resultArray(['data' => $data]);
}
/**
* 更新授权信息
*
* @param FieldGrantLogic $fieldGrantLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function update(FieldGrantLogic $fieldGrantLogic)
{
if (empty($this->param['grant_id'])) return resultArray(['error' => '缺少授权ID']);
if (empty($this->param['content'])) return resultArray(['error' => '缺少授权数据!']);
$status = $fieldGrantLogic->update($this->param['grant_id'], $this->param['content']);
if ($status === false) {
return resultArray(['error' => '更新授权信息失败!']);
}
return resultArray(['data' => '更新授权信息成功!']);
}
}

@ -0,0 +1,230 @@
<?php
// +----------------------------------------------------------------------
// | Description: 附件
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\work\traits\WorkAuthTrait;
use think\Hook;
use think\Request;
class File extends ApiCommon
{
use WorkAuthTrait;
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index', 'save', 'delete', 'update', 'read', 'download', 'deleteall', 'downloadimage']
];
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 index()
{
$fileModel = model('File');
$param = $this->param;
$data = $fileModel->getDataList($param, $param['by']);
return resultArray(['data' => $data]);
}
/**
* 附件上传
* @author Michael_xu
* @return
*/
public function save()
{
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
$type = $this->param['type'];
$files = request()->file('file');
$imgs = request()->file('img');
$i = 0;
$newFiles = [];
# 项目上传附件权限
if (!empty($this->param['module']) && $this->param['module'] == 'work_task' && !empty($this->param['work_id'])) {
if (!$this->checkWorkOperationAuth('uploadTaskFile', $this->param['work_id'], $this->userInfo['id'])) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作!']));
}
}
if (!empty($type) && in_array($type, ['img', 'file'])) {
# todo 兼容11.0前端
if ($type == 'img') {
$newFiles[0]['obj'] = $files;
$newFiles[0]['types'] = 'img';
}
if ($type == 'file') {
$newFiles[0]['obj'] = $files;
$newFiles[0]['types'] = 'file';
}
} else {
# todo 兼容9.0前端
if (!empty($files)) {
foreach ($files as $v) {
$newFiles[$i]['obj'] = $v;
$newFiles[$i]['types'] = 'file';
$i++;
}
}
if (!empty($imgs)) {
foreach ($imgs as $v) {
$newFiles[$i]['obj'] = $v;
$newFiles[$i]['types'] = 'img';
$i++;
}
}
}
$fileModel = model('File');
$param = $this->param;
$param['create_user_id'] = $this->userInfo['id'];
$res = $fileModel->createData($newFiles, $param);
if($res){
return resultArray(['data' => $res]);
} else {
return resultArray(['error' => $fileModel->getError()]);
}
}
/**
* 附件删除
* @author Michael_xu
* @param 通过 save_name 作为条件 来删除附件
* @return
*/
public function delete()
{
$fileModel = model('File');
$param = $this->param;
# 项目删除附件权限
if (!empty($this->param['module']) && $this->param['module'] == 'work_task' && !empty($this->param['work_id'])) {
if (!$this->checkWorkOperationAuth('deleteTaskFile', $this->param['work_id'], $this->userInfo['id'])) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作!']));
}
}
$res = $fileModel->delFileBySaveName($param['save_name'], $param);
if (!$res) {
return resultArray(['error' => $fileModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
/**
* 全部删除(活动、产品)
*
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function deleteAll()
{
if ((empty($this->param['module']) && empty($this->param['module_id'])) || empty($this->param['file_id'])) {
return resultArray(['error' => '参数错误!']);
}
$fileModel = new \app\admin\model\File();
if (!$fileModel->deleteAll($this->param)) return resultArray(['error' => '操作失败!']);
return resultArray(['data' => '操作成功!']);
}
/**
* 附件编辑
*/
public function update()
{
$fileModel = model('File');
$param = $this->param;
if ( $param['save_name'] && $param['name'] ) {
$ret = $fileModel->updateNameBySaveName($param['save_name'],$param['name']);
if ($ret) {
return resultArray(['data'=>'操作成功']);
} else {
return resultArray(['error'=>'操作失败']);
}
} else {
return resultArray(['error'=>'参数错误']);
}
}
/**
* 附件查看(下载)
* @author Michael_xu
* @return
*/
public function read()
{
$fileModel = model('File');
$param = $this->param;
$data = $fileModel->getDataBySaveName($param['save_name']);
if (!$data) {
return resultArray(['error' => $this->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 静态资源文件下载
*/
public function download()
{
if(isset($this->param['path'])){
$path = $this->param['path'];
$name = $this->param['name'] ?: '';
if (empty($path)) return resultArray(['error' => '参数错误!']);
return download(realpath('./public/' . $path), $name);
}else{
$path = $this->param['save_name'];
$name = $this->param['name'] ?: '';
if (empty($path)) return resultArray(['error' => '参数错误!']);
if (!strstr($path, 'uploads')) $path = 'uploads/' . $path;
return download(realpath('./public/' . $path), $name);
}
}
/**
* 下载图片(头像),前端要求重写一个。
*
* @return \think\response\Json|void
*/
public function downloadImage()
{
$path = $this->param['path'];
$file = explode('public/', $path);
if (empty($path) || empty($file[1])) return resultArray(['error' => '参数错误!']);
return download(realpath('./public/'.$file[1]));
}
}

@ -0,0 +1,217 @@
<?php
// +----------------------------------------------------------------------
// | Description: 用户组
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\logic\FieldGrantLogic;
use think\Hook;
use think\Request;
class Groups extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index','enables','copy','typelist','save','update','delete']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
//权限判断
$unAction = ['index','typelist'];
if (!in_array($a, $unAction) && !checkPerByAction('admin', 'groups', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
/**
* 角色列表
* @author Michael_xu
* @param
* @return
*/
public function index()
{
$groupModel = model('Group');
$param = $this->param;
$data = $groupModel->getDataList($param);
return resultArray(['data' => $data]);
}
/**
* 角色详情
* @author Michael_xu
* @param
* @return
*/
public function read()
{
$groupModel = model('Group');
$param = $this->param;
$data = $groupModel->getDataById($param['id']);
if (!$data) {
return resultArray(['error' => $groupModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 角色添加
* @author Michael_xu
* @param
* @return
*/
public function save(FieldGrantLogic $fieldGrantLogic)
{
$groupModel = model('Group');
$param = $this->param;
$param['rules'] = arrayToString($param['rules']);
$lastInsId = $groupModel->createData($param);
if (!$lastInsId) {
return resultArray(['error' => $groupModel->getError()]);
}
# 新增客户管理角色的字段授权数据
if (isset($param['pid']) && $param['pid'] == 2) {
$fieldGrantLogic->createCrmFieldGrant($lastInsId);
}
return resultArray(['data' => 1]);
}
/**
* 角色编辑
* @author Michael_xu
* @param
* @return
*/
public function update()
{
$groupModel = model('Group');
$param = $this->param;
$dataInfo = $groupModel->getDataById($param['id']);
if (!$dataInfo) {
return resultArray(['error' => '参数错误']);
}
# 处理前端传来的type是work的错误
if (!empty($param['type']) && $param['type'] == 'work') $param['type'] = 1;
$param['rules'] = arrayToString($param['rules']);
$data = $groupModel->updateDataById($param, $param['id']);
return resultArray(['data' => '编辑成功']);
}
/**
* 角色删除
* @author Michael_xu
* @param
* @return
*/
public function delete(FieldGrantLogic $fieldGrantLogic)
{
$groupModel = model('Group');
$param = $this->param;
$dataInfo = $groupModel->getDataById($param['id']);
if (!$dataInfo) {
return resultArray(['error' => '参数错误']);
}
if ($dataInfo['types']) {
return resultArray(['error' => '系统角色,不能删除']);
}
$data = $groupModel->delGroupById($param['id']);
if (!$data) {
return resultArray(['error' => $groupModel->getError()]);
}
# 删除字段授权数据
$fieldGrantLogic->deleteCrmFieldGrant($param['id']);
return resultArray(['data' => '删除成功']);
}
/**
* 角色启用、禁用
* @author Michael_xu
* @param
* @return
*/
public function enables()
{
$groupModel = model('Group');
$param = $this->param;
$dataInfo = $groupModel->getDataById($param['id']);
if (!$dataInfo) {
return resultArray(['error' => '参数错误']);
}
if ($dataInfo['types']) {
return resultArray(['error' => '系统角色,不能删除']);
}
$data = $groupModel->enableDatas($param['id'], $param['status'], true);
if (!$data) {
return resultArray(['error' => $groupModel->getError()]);
}
return resultArray(['data' => '操作成功']);
}
/**
* 角色复制
* @author Michael_xu
* @param
* @return
*/
public function copy(FieldGrantLogic $fieldGrantLogic)
{
$groupModel = model('Group');
$param = $this->param;
$dataInfo = $groupModel->getDataById($param['id']);
if (!$dataInfo) {
return resultArray(['error' => '参数错误']);
}
$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()]);
}
# 复制客户管理角色的字段授权数据
if (!empty($dataInfo['pid']) && $dataInfo['pid'] == 2) {
$fieldGrantLogic->copyCrmFieldGrant($param['id'], $data);
}
return resultArray(['data' => '操作成功']);
}
/**
* 角色分类列表
* @author Michael_xu
* @param
* @return
*/
public function typeList()
{
$groupModel = model('Group');
$param = $this->param;
$data = $groupModel->getTypeList($param);
return resultArray(['data' => $data]);
}
}

@ -0,0 +1,154 @@
<?php
// +----------------------------------------------------------------------
// | Description: 工作台及基础
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
class Index extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
*/
public function _initialize()
{
parent::_initialize();
$action = [
'permission' => [],
'allow' => ['fields', 'fieldrecord', 'authlist','sort','updatesort',
'importnum','importinfo','importlist'],
];
Hook::listen('check_auth', $action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 获取字段属性,用于筛选或其他操作
* @param
* @return
*/
public function fields()
{
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$fieldModel = model('Field');
$field_arr = $fieldModel->getField($param);
# 转form_type类型用于场景筛选和创建自定义场景
foreach ($field_arr AS $key => $value) {
if ($value['field'] == 'address') $field_arr[$key]['form_type'] = 'map_address';
if ($value['field'] == 'deal_status') $field_arr[$key]['form_type'] = 'deal_status';
if ($value['field'] == 'check_status') $field_arr[$key]['form_type'] = 'check_status';
}
return resultArray(['data' => $field_arr]);
}
/**
* 获取字段修改记录
* @param
* @return
*/
public function fieldRecord()
{
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$actionRecordModel = model('ActionRecord');
$data = $actionRecordModel->getDataList($param);
if (!$data) {
return resultArray(['data' => '暂无数据']);
}
return resultArray(['data' => $data]);
}
/**
* 权限数据返回
* @param
* @return
*/
public function authList()
{
$userInfo = $this->userInfo;
$userModel = model('User');
$dataList = $userModel->getMenuAndRule($userInfo['id']);
return resultArray(['data' => $dataList['authList']]);
}
/**
* todo
* 顶部菜单栏展示
* @return mixed
*/
//todo admin_sort 表数据未完善
public function sort(){
$param = $this->param;
$userModel = model('User');
$userInfo = $this->userInfo;
$param['user_id']= $param['user_id']?:$userInfo['id'];
$dataList = $userModel->sortList($param);
return resultArray(['data' => $dataList]);
}
/**
*顶部菜单栏编辑
*/
public function updateSort(){
$param = $this->param;
$userInfo = $this->userInfo;
$userModel = model('User');
$param['value']=$param;
$param['user_id']= $param['user_id']?:$userInfo['id'];
$dataList = $userModel->updateSort($param);
if (!$dataList) {
return resultArray(['data' => '编辑失败']);
}
return resultArray(['data' => '编辑成功']);
}
/**
* 导入中
* @return \think\response\Json
*/
public function importNum(){
$excelModel = model('Excel');
$data = $excelModel->importNum();
return resultArray(['data'=>$data]);
}
/**
* 导入成功返回值
* @return \think\response\Json
*/
public function importInfo(){
$excelModel = model('Excel');
$data = $excelModel->importInfo();
return resultArray(['data'=>$data]);
}
/**
* 导入历史
* @return \think\response\Json
*/
public function importList(){
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$excelModel = model('Excel');
$data = $excelModel->importList($param);
return resultArray(['data'=>$data]);
}
}

@ -0,0 +1,96 @@
<?php
/**
* 初始化控制器
*
* @author qifan
* @date 2020-01-05
*/
namespace app\admin\controller;
use app\admin\logic\InitializeLogic;
use think\Hook;
use think\Request;
class Initialize extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [],
'allow' => ['verification']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 列表
*
* @return \think\response\Json
*/
public function index()
{
$data = [
['type' => 1, 'name' => '全部应用'],
['type' => 2, 'name' => '客户管理'],
['type' => 3, 'name' => '任务/审批'],
['type' => 4, 'name' => '日志'],
['type' => 5, 'name' => '项目管理'],
['type' => 6, 'name' => '日历'],
// ['type' => 7, 'name' => '知识库'],
];
return resultArray(['data' => $data]);
}
/**
* 初始化数据
*
* @param InitializeLogic $initializeLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function update(InitializeLogic $initializeLogic)
{
if (empty($this->param['type']) || !is_array($this->param['type'])) return resultArray(['error' => '模块类型错误!']);
if (!empty($this->param['password']) && !$initializeLogic->verification($this->userInfo['id'], $this->param['password'])) {
return resultArray(['error' => '密码错误!']);
}
$initializeLogic->update($this->param['type']);
return resultArray(['data' => $initializeLogic->log]);
}
/**
* 验证密码
*
* @param InitializeLogic $initializeLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function verification(InitializeLogic $initializeLogic)
{
if (empty($this->param['password'])) return resultArray(['error' => '参数错误!']);
if (!$initializeLogic->verification($this->userInfo['id'], $this->param['password'])) return resultArray(['error' => '密码错误!']);
return resultArray(['data' => '密码正确!']);
}
}

@ -0,0 +1,382 @@
<?php
// +----------------------------------------------------------------------
// | Description: 安装
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Controller;
use think\Request;
use think\Db;
use Env;
class Install extends Controller
{
// private $count = 100;
// private $now = 0;
public function _initialize()
{
/*防止跨域*/
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, authKey, sessionId");
$param = Request::instance()->param();
$this->param = $param;
$request = request();
$m = strtolower($request->module());
$c = strtolower($request->controller());
$a = strtolower($request->action());
if (!in_array($a, array('upgrade','upgradeprocess','checkversion')) && file_exists(CONF_PATH . "install.lock")) {
echo "<meta http-equiv='content-type' content='text/html; charset=UTF-8'> <script>alert('请勿重复安装!');location.href='".$_SERVER["HTTP_HOST"]."';</script>";
die();
}
}
private $upgrade_site = "http://message.72crm.com/";
/**
* [index 安装步骤]
* @author Michael_xu
* @param
*/
public function index()
{
if (file_exists(CONF_PATH . "install.lock")) {
echo "<meta http-equiv='content-type' content='text/html; charset=UTF-8'> <script>alert('请勿重复安装!');location.href='".$_SERVER["HTTP_HOST"]."';</script>";
die();
}
if (!file_exists(getcwd() . "/public/sql/5kcrm.sql")) {
echo "<meta http-equiv='content-type' content='text/html; charset=UTF-8'> <script>alert('缺少必要的数据库文件!');location.href='".$_SERVER["HTTP_HOST"]."';</script>";
die();
}
return $this->fetch('index');
}
public function step1()
{
session('install_error',null);
$data = [];
$data['env'] = self::checkNnv();
$data['dir'] = self::checkDir();
$data['version'] = $this->version();
$this->assign('data',$data);
return $this->fetch('step1');
}
//版本
public function version()
{
$res = include(CONF_PATH.'version.php');
return $res ? : array('VERSION' => '9.0.0','RELEASE' => '20190330');
}
public function step2(){
if (session('install_error')){
echo "<meta http-equiv='content-type' content='text/html; charset=UTF-8'> <script>alert('环境检测未通过,不能进行下一步操作!');location.href='".$_SERVER["HTTP_REFERER"]."';</script>";
die();
}
$data['os'] = PHP_OS;
$data['php'] = phpversion();
$data['version'] = $this->version();
$this->assign('envir_data',$data);
return $this->fetch();
}
public function step3(){
return $this->fetch();
}
public function step4(){
if (session('install_error')){
return resultArray(['error' => '环境检测未通过,不能进行下一步操作!']);
}
if (file_exists(CONF_PATH . "install.lock")) {
return resultArray(['error' => '请勿重复安装!']);
}
if (!file_exists(getcwd() . "/public/sql/5kcrm.sql")) {
return resultArray(['error' => '缺少必要的数据库文件!']);
}
$temp = $this->param;
$param = $temp['form'];
$db_config['type'] = 'mysql';
$db_config['hostname'] = $param['databaseUrl'];
$db_config['hostport'] = $param['databasePort'];
$db_config['database'] = $param['databaseName'];
$db_config['username'] = $param['databaseUser'];
$db_config['password'] = $param['databasePwd'];
$db_config['prefix'] = $param['databaseTable'];
$username = $param['root'];
$password = $param['pwd'];
if (empty($db_config['hostname'])) {
return resultArray(['error' => '请填写数据库主机!']);
}
if (empty($db_config['hostport'])) {
return resultArray(['error' => '请填写数据库端口!']);
}
if (preg_match('/[^0-9]/', $db_config['hostport'])) {
return resultArray(['error' => '数据库端口只能是数字!']);
}
if (empty($db_config['database'])) {
return resultArray(['error' => '请填写数据库名!']);
}
if (empty($db_config['username'])) {
return resultArray(['error' => '请填写数据库用户名!']);
}
if (empty($db_config['password'])) {
return resultArray(['error' => '请填写数据库密码!']);
}
if (empty($db_config['prefix'])) {
return resultArray(['error' => '请填写表前缀!']);
}
if (preg_match('/[^a-z0-9_]/i', $db_config['prefix'])) {
return resultArray(['error' => '表前缀只能包含数字、字母和下划线!']);
}
if (empty($username)) {
return resultArray(['error' => '请填写管理员用户名!']);
}
if (empty($password)) {
return resultArray(['error' => '请填写管理员密码!']);
}
session('install_count','');
session('install_now','');
$database = $db_config['database'];
unset($db_config['database']);
$connect = Db::connect($db_config);
// 检测数据库连接
try{
$ret = $connect->execute('select version()');
}catch(\Exception $e){
return resultArray(['error' => '数据库连接失败,请检查数据库配置!']);
}
$check = $connect->execute("SELECT * FROM information_schema.schemata WHERE schema_name='".$database."'");
if (!$check && !$connect->execute("CREATE DATABASE IF NOT EXISTS `".$database."` default collate utf8_general_ci ")) {
return resultArray(['error' => '没有找到您填写的数据库名且无法创建!请检查连接账号是否有创建数据库的权限!']);
}
$db_config['database'] = $database;
self::mkDatabase($db_config);
$C_Patch = substr($_SERVER['SCRIPT_FILENAME'],0,-10);
$sql = file_get_contents( $C_Patch.'/public/sql/5kcrm.sql');
$sqlList = parse_sql($sql, 0, ['5kcrm_' => $db_config['prefix']]);
if ($sqlList) {
$sqlList = array_filter($sqlList);
$install_count = count($sqlList);
session('install_count',$install_count);
foreach ($sqlList as $k=>$v) {
$install_now = $k+1;
session('install_now',$install_now);
try {
$temp_sql = $v.';';
Db::connect($db_config)->query($temp_sql);
} catch(\Exception $e) {
// return resultArray(['error' => '请启用InnoDB数据引擎并检查数据库是否有DROP和CREATE权限']);
return resultArray(['error' => '数据库sql安装出错请操作数据库手动导入sql文件']);
}
}
}
$salt = substr(md5(time()),0,4);
$password = user_md5(trim($password), $salt, $username);
//插入信息
Db::connect($db_config)->query("insert into ".$db_config['prefix']."admin_user (username, password, salt, img, thumb_img, realname, create_time, num, email, mobile, sex, status, structure_id, post, parent_id, type, authkey, authkey_time ) values ( '".$username."', '".$password."', '".$salt."', '', '', '管理员', ".time().", '', '', '".$username."', '', 1, 1, 'CEO', 0, 1, '', 0 )");
Db::connect($db_config)->query("insert into ".$db_config['prefix']."hrm_user_det (user_id, join_time, type, status, userstatus, create_time, update_time, mobile, sex, age, job_num, idtype, idnum, birth_time, nation, internship, done_time, parroll_id, email, political, location, leave_time ) values ( 1, ".time().", 1, 1, 2, ".time().", ".time().", '".$username."', '', 0, '', 0, '', '', 0, 0, 0, 0, '', '', '', 0 )");
touch(CONF_PATH . "install.lock");
return resultArray(['data'=>'安装成功']);
}
//ajax 进度条
public function progress()
{
$data['length'] = session('install_count');
$data['now'] = session('install_now');
return resultArray(['data'=>$data]);
}
//添加database.php文件
private function mkDatabase(array $data)
{
$code = <<<INFO
<?php
return [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '{$data['hostname']}',
// 数据库名
'database' => '{$data['database']}',
// 用户名
'username' => '{$data['username']}',
// 密码
'password' => '{$data['password']}',
// 端口
'hostport' => '{$data['hostport']}',
// 连接dsn
'dsn' => '',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '{$data['prefix']}',
// 数据库调试模式
'debug' => true,
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 自动读取主库数据
'read_master' => false,
// 是否严格检查字段是否存在
'fields_strict' => true,
// 数据集返回类型
'resultset_type' => 'array',
];
INFO;
file_put_contents( CONF_PATH.'database.php', $code);
// 判断写入是否成功
$config = include CONF_PATH.'database.php';
if (empty($config['database']) || $config['database'] != $data['database']) {
return resultArray(['error' => '[config/database.php]数据库配置写入失败!']);
}
return true;
}
//检查目录权限
public function check_dir_iswritable($dir_path){
$dir_path=str_replace( '\\','/',$dir_path);
$is_writale=1;
if (!is_dir($dir_path)) {
$is_writale=0;
return $is_writale;
} else {
$file_hd=@fopen($dir_path.'/test.txt','w');
if (!$file_hd) {
@fclose($file_hd);
@unlink($dir_path.'/test.txt');
$is_writale=0;
return $is_writale;
}
$dir_hd = opendir($dir_path);
while (false !== ($file=readdir($dir_hd))) {
if ($file != "." && $file != "..") {
if (is_file($dir_path.'/'.$file)) {
//文件不可写,直接返回
if (!is_writable($dir_path.'/'.$file)) {
return 0;
}
} else {
$file_hd2=@fopen($dir_path.'/'.$file.'/test.txt','w');
if (!$file_hd2) {
@fclose($file_hd2);
@unlink($dir_path.'/'.$file.'/test.txt');
$is_writale=0;
return $is_writale;
}
//递归
$is_writale=check_dir_iswritable($dir_path.'/'.$file);
}
}
}
}
return $is_writale;
}
/**
* [checkVersion 检查升级]
* @author Michael_xu
* @param
*/
public function checkVersion(){
$version = Config::load('version');
$info = sendRequest($this->upgrade_site.'index.php?m=version&a=checkVersion', $version['VERSION']);
if ($info){
return resultArray(['data' => $info]);
} else {
return resultArray(['error' => '检查新版本出错!']);
}
}
/**
* 环境检测
* @return array
*/
private function checkNnv()
{
$items = [
'os' => ['操作系统', PHP_OS, '类Unix', 'ok'],
'php' => ['PHP版本', PHP_VERSION, '7.2 ( <em style="color: #888; font-size: 12px;">>= 5.6</em> )', 'ok','性能更佳'],
'gd' => ['gd', '开启', '开启', 'ok'],
'openssl' => ['openssl', '开启', '开启', 'ok'],
'pdo' => ['pdo', '开启', '开启', 'ok'],
];
session('install_error','');
if (substr($items['php'][1],0,3) < '5.6') {
$items['php'][3] = 'error';
session('install_error', true);
}
if (!extension_loaded('gd')) {
$items['gd'][1] = '未开启';
$items['gd'][3] = 'error';
session('install_error', true);
}
if (!extension_loaded('openssl')) {
$items['openssl'][1] = '未开启';
$items['openssl'][3] = 'error';
session('install_error', true);
}
if (!extension_loaded('pdo')) {
$items['pdo'][1] = '未开启';
$items['pdo'][3] = 'error';
session('install_error', true);
}
// dump($items);die;
return $items;
}
/**
* 目录权限检查
* @return array
*/
private function checkDir()
{
$items = [
['dir', $this->root_path.'application', 'application', '读写', '读写', 'ok'],
['dir', $this->root_path.'extend', 'extend', '读写', '读写', 'ok'],
['dir', $this->root_path.'runtime', './temp', '读写', '读写', 'ok'],
['dir', $this->root_path.'public', './upload', '读写', '读写', 'ok'],
['file', $this->root_path.'config', 'config', '读写', '读写', 'ok'],
];
foreach ($items as &$v) {
if ($v[0] == 'dir') {// 文件夹
if (!is_writable($v[1])) {
if (is_dir($v[1])) {
$v[4] = '不可写';
$v[5] = 'no';
} else {
$v[4] = '不存在';
$v[5] = 'no';
}
session('install_error', true);
}
} else {// 文件
if (!is_writable($v[1])) {
$v[4] = '不可写';
$v[5] = 'no';
session('install_error', true);
}
}
}
return $items;
}
}

@ -0,0 +1,86 @@
<?php
/**
* 日志控制器
*
* @author qifan
* @date 2020-11-30
*/
namespace app\admin\controller;
use app\admin\logic\LogLogic;
use think\Hook;
use think\Request;
class Log extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [''],
'allow' => ['dataRecord', 'systemRecord', 'loginRecord']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 数据操作日志
*
* @param LogLogic $logLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function dataRecord(LogLogic $logLogic)
{
$data['list'] = $logLogic->getRecordLogs($this->param);
$data['count'] = $logLogic->getRecordLogCount($this->param);
$data['modules'] = $logLogic->recordModules;
return resultArray(['data' => $data]);
}
/**
* 系统操作日志
*
* @param LogLogic $logLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function systemRecord(LogLogic $logLogic)
{
$data['list'] = $logLogic->getSystemLogs($this->param);
$data['count'] = $logLogic->getSystemLogCount($this->param);
$data['modules'] = $logLogic->systemModules;
return resultArray(['data' => $data]);
}
/**
* 登录日志
*
* @param LogLogic $logLogic
* @return \think\response\Json
* @throws \think\exception\DbException
*/
public function loginRecord(LogLogic $logLogic)
{
$data = $logLogic->getLoginRecord($this->param);
return resultArray(['data' => $data]);
}
}

@ -0,0 +1,87 @@
<?php
// +----------------------------------------------------------------------
// | Description: 菜单
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
class Menus extends ApiCommon
{
public function index()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->getDataList();
return resultArray(['data' => $data]);
}
public function read()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->getDataById($param['id']);
if (!$data) {
return resultArray(['error' => $menuModel->getError()]);
}
return resultArray(['data' => $data]);
}
public function save()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->createData($param);
if (!$data) {
return resultArray(['error' => $menuModel->getError()]);
}
return resultArray(['data' => '添加成功']);
}
public function update()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $menuModel->getError()]);
}
return resultArray(['data' => '编辑成功']);
}
public function delete()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->delDataById($param['id'], true);
if (!$data) {
return resultArray(['error' => $menuModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
public function deletes()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->delDatas($param['ids'], true);
if (!$data) {
return resultArray(['error' => $menuModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
public function enables()
{
$menuModel = model('Menu');
$param = $this->param;
$data = $menuModel->enableDatas($param['ids'], $param['status'], true);
if (!$data) {
return resultArray(['error' => $menuModel->getError()]);
}
return resultArray(['data' => '操作成功']);
}
}

@ -0,0 +1,205 @@
<?php
// +----------------------------------------------------------------------
// | Description: 工作台及基础
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\logic\MessageLogic;
use think\Db;
use think\Hook;
use app\admin\model\Message as MessageModel;
use think\Request;
class Message extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
parent::_initialize();
$action = [
'permission' => [],
'allow' => ['index', 'markedRead', 'messagelist', 'updatemessage','delete','readallmessage','clear','unreadcount'],
];
Hook::listen('check_auth', $action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 系统信息
*/
public function index()
{
$param = $this->param;
$userInfo = $this->userInfo;
$type = $param['type'] ?: 'all';
if ($type != 'all' && !isset(MessageModel::$typeGroup[$type])) {
return resultArray(['error' => '参数错误']);
}
$where = ['to_user_id' => $userInfo['id']];
if ($type != 'all') {
$where['type'] = ['IN', MessageModel::$typeGroup[$type]];
}
$order = [
'read_time' => 'ASC',
'send_time' => 'DESC',
];
$page = $param['page'] ?: 1;
$limit = $param['limit'] ?: 15;
$data = MessageModel::where($where)
->order($order)
->paginate($limit)
->each(function ($val) {
$val['relation_title'] = $val->relation_title;
$val['from_user_id_info'] = $val->from_user_id_info;
})
->toArray();
return resultArray([
'data' => [
'list' => $data['data'],
'dataCount' => $data['total']
]
]);
}
/**
* 阅读系统通知,修改状态为已读
*/
public function markedRead()
{
$userInfo = $this->userInfo;
$param = $this->param;
$where = [
'to_user_id' => $userInfo['id'],
'message_id' => ['IN', (array)$param['message_id']],
'read_time' => 0,
];
$res = MessageModel::where($where)->update(['read_time' => time()]);
return resultArray(['data' => $res > 0]);
}
/**
* 未读数
*/
// public function unReadCount()
// {
// $data = [];
// foreach (MessageModel::$typeGroup as $key => $val) {
// $data[$key] = MessageModel::where(['type' => ['IN', $val]])->count();
// }
// $data['all'] = array_sum($data);
// return resultArray(['data' => $data]);
// }
/**
* 未读消息列表
* @return \think\response\Json
*/
public function messageList()
{
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$messageLogic = new MessageLogic();
$data = $messageLogic->getDataList($param);
return resultArray(['data' => $data]);
}
/**
*更新消息类型 已读未读
*/
public function updateMessage()
{
$param = $this->param;
$userInfo = $this->userInfo;
$param['id']=$userInfo['id'];
$messageLogic = new MessageLogic();
$data = $messageLogic->endMessage($param);
if(!$data){
return resultArray(['data' => "操作失败!"]);
}
return resultArray(['data' => "操作成功!"]);
}
/**
* 删除消息
*
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function delete()
{
if (empty($this->param['message_id'])) return resultArray(['error' => '参数错误!']);
$userInfo = $this->userInfo;
$param = $this->param;
$data['message_id'] = $param['message_id'];
$data['user_id'] = $userInfo['id'];
$messageLogic = new MessageLogic();
if (!$messageLogic->delete($data)) return resultArray(['error' => '操作失败!']);
return resultArray(['data' => '操作成功!']);
}
/**
* 批量更新
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function readAllMessage(){
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$messageLogic = new MessageLogic();
$data = $messageLogic->readAllMessage($param);
return resultArray(['data' => "操作成功!"]);
}
/**
* 批量删除
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function clear(){
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$messageLogic = new MessageLogic();
$data = $messageLogic->clear($param);
return resultArray(['data' => "操作成功!"]);
}
/**
* 总数
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function unreadCount(){
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$messageLogic = new MessageLogic();
$data = $messageLogic->unreadCount($param);
return resultArray(['data' => $data]);
}
}

@ -0,0 +1,88 @@
<?php
// +----------------------------------------------------------------------
// | Description: 岗位控制器
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
class Posts extends ApiCommon
{
public function index()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->getDataList($param);
return resultArray(['data' => $data]);
}
public function read()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->getDataById($param['id']);
if (!$data) {
return resultArray(['error' => $postModel->getError()]);
}
return resultArray(['data' => $data]);
}
public function save()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->createData($param);
if (!$data) {
return resultArray(['error' => $postModel->getError()]);
}
return resultArray(['data' => '添加成功']);
}
public function update()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $postModel->getError()]);
}
return resultArray(['data' => '编辑成功']);
}
public function delete()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->delDataById($param['id']);
if (!$data) {
return resultArray(['error' => $postModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
public function deletes()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->delDatas($param['ids']);
if (!$data) {
return resultArray(['error' => $postModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
public function enables()
{
$postModel = model('Post');
$param = $this->param;
$data = $postModel->enableDatas($param['ids'], $param['status']);
if (!$data) {
return resultArray(['error' => $postModel->getError()]);
}
return resultArray(['data' => '操作成功']);
}
}

@ -0,0 +1,169 @@
<?php
/**
* 打印设置控制器
*
* @author qifan
* @date 2020-12-03
*/
namespace app\admin\controller;
use app\admin\logic\PrintingLogic;
use think\Hook;
use think\Request;
class Printing extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index', 'create', 'update', 'read', 'delete', 'field', 'copy']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 打印模板列表
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index(PrintingLogic $printingLogic)
{
$page = !empty($this->param['page']) ? $this->param['page'] : 1;
$limit = !empty($this->param['limit']) ? $this->param['limit'] : 15;
$data = $printingLogic->index($page, $limit);
return resultArray(['data' => $data]);
}
/**
* 创建打印模板
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
*/
public function create(PrintingLogic $printingLogic)
{
$param = $this->param;
if (empty($param['name'])) return resultArray(['error' => '缺少模板名称!']);
if (empty($param['type'])) return resultArray(['error' => '缺少模板类型!']);
if (empty($param['content'])) return resultArray(['error' => '缺少模板详情!']);
if (!$printingLogic->create($param)) return resultArray(['error' => '添加失败!']);
return resultArray(['data' => '添加成功!']);
}
/**
* 获取模板详情
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
*/
public function read(PrintingLogic $printingLogic)
{
$id = $this->param['id'];
if (empty($id)) return resultArray('缺少模板ID');
$data = $printingLogic->read($id);
return resultArray(['data' => $data]);
}
/**
* 更新模板数据
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function update(PrintingLogic $printingLogic)
{
$param = $this->param;
if (empty($param['id'])) return resultArray(['error' => '缺少模板ID']);
if (!$printingLogic->update($param)) return resultArray(['error' => '更新失败!']);
return resultArray(['data' => '更新成功!']);
}
/**
* 删除模板数据
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function delete(PrintingLogic $printingLogic)
{
$id = $this->param['id'];
if (empty($id)) return resultArray(['error' => '缺少模板ID']);
if (!$printingLogic->delete($id)) return resultArray(['error' => '删除失败!']);
return resultArray(['data' => '删除成功!']);
}
/**
* 复制模板数据
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function copy(PrintingLogic $printingLogic)
{
$id = $this->param['id'];
if (empty($id)) return resultArray(['error' => '缺少模板ID']);
if (!$printingLogic->copy($id)) return resultArray(['error' => '复制失败!']);
return resultArray(['data' => '复制成功!']);
}
/**
* 获取打印字段
*
* @param PrintingLogic $printingLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function field(PrintingLogic $printingLogic)
{
# 打印类型1商机2合同3回款
$type = !empty($this->param['type']) ? $this->param['type'] : 5;
$data = $printingLogic->getFields($type);
return resultArray(['data' => $data]);
}
}

@ -0,0 +1,131 @@
<?php
// +----------------------------------------------------------------------
// | Description: 跟进记录
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
use think\Db;
class Record extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index','save','update','delete']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 跟进记录列表
* @return
*/
public function index()
{
$param = $this->param;
$by = $param['by'] ? : '';
unset($param['by']);
$recordModel = model('Record');
$data = $recordModel->getDataList($param, $by);
if (!$data) {
return resultArray(['error' => $recordModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 跟进记录创建
* @param
* @return
*/
public function save()
{
$recordModel = model('Record');
$param = $this->param;
$userInfo = $this->userInfo;
$param['create_user_id'] = $userInfo['id'];
$resData = $recordModel->createData($param);
if (!$resData) {
return resultArray(['error' => $recordModel->getError()]);
}
//同时创建日程
if ($param['is_event']) {
$eventModel = new \app\oa\model\Event();
$data['title'] = trim($param['content']);
$data['content'] = trim($param['content']);
$data['start_time'] = $param['next_time'] ? : time();
$data['end_time'] = $param['next_time']+86399;
$data['create_user_id'] = $userInfo['id'];
if ($param['types'] == 'crm_customer') $data['customer_ids'] = $param['types_id'];
$data['business_ids'] = $param['business_ids'];
$data['contacts_ids'] = $param['contacts_ids'];
$resEvent = $eventModel->createData($data);
}
return resultArray(['data' => '添加成功']);
}
/**
* 跟进记录编辑
* @param
* @return
*/
public function update()
{
$recordModel = model('Record');
$param = $this->param;
$data = $recordModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $recordModel->getError()]);
}
return resultArray(['data' => '编辑成功']);
}
/**
* 跟进记录删除
* @param
* @return
*/
public function delete()
{
$recordModel = model('Record');
$param = $this->param;
$userInfo = $this->userInfo;
//权限判断
$dataInfo = $recordModel->getDataById($param['id']);
if (!$dataInfo) {
return resultArray(['error' => '数据不存在或已删除']);
}
//自己(24小时)或者管理员
$adminTypes = adminGroupTypes($userInfo['id']);
if(!in_array(1,$adminTypes)){
if((time()-$dataInfo['create_time']) > 86400){
return resultArray(['error' => '超过24小时不能删除']);
}
if ($dataInfo['create_user_id'] !== $userInfo['id']){
return resultArray(['error' => '无权操作']);
}
}
$resData = $recordModel->delDataById($param['id']);
if (!$resData) {
return resultArray(['error' => $recordModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
}

@ -0,0 +1,79 @@
<?php
// +----------------------------------------------------------------------
// | Description: 规则
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
class Rules extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
$m = $this->m;
$c = $this->c;
$a = $this->a;
}
public function index()
{
$ruleModel = model('Rule');
$param = $this->param;
$data = $ruleModel->getDataList($param);
return resultArray(['data' => $data]);
}
/**
* 新建规则
* @param
* @return
*/
public function save()
{
$ruleModel = model('Rule');
$param = $this->param;
$data = $ruleModel->createData($param);
if (!$data) {
return resultArray(['error' => $ruleModel->getError()]);
}
return resultArray(['data' => '添加成功']);
}
/**
* 编辑规则
* @param
* @return
*/
public function update()
{
$ruleModel = model('Rule');
$param = $this->param;
$data = $ruleModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $ruleModel->getError()]);
}
return resultArray(['data' => '编辑成功']);
}
}

@ -0,0 +1,169 @@
<?php
// +----------------------------------------------------------------------
// | Description: 场景
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Session;
use think\Request;
use think\Db;
class Scene extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index','save','read','update','delete','sort','defaults']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 场景列表
* @return
*/
public function index()
{
$param = $this->param;
$userInfo = $this->userInfo;
$sceneModel = model('Scene');
$data = $sceneModel->getDataList($param['types'], $userInfo['id']);
if (!$data) {
return resultArray(['error' => $sceneModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 场景创建
* @param
* @return
*/
public function save()
{
$sceneModel = model('Scene');
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$data = $sceneModel->createData($param, $param['types']);
if (!$data) {
return resultArray(['error' => $sceneModel->getError()]);
}
return resultArray(['data' => '添加成功']);
}
/**
* 场景详情
* @param int $id
* @return
*/
public function read()
{
$sceneModel = model('Scene');
$param = $this->param;
$userInfo = $this->userInfo;
$data = $sceneModel->getDataById($param['id'], $userInfo['id']);
if (!$data) {
return resultArray(['error' => $sceneModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 编辑场景
* @param int $id
* @return
*/
public function update()
{
$sceneModel = model('Scene');
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id'] = $userInfo['id'];
$data = $sceneModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $sceneModel->getError()]);
}
return resultArray(['data' => '编辑成功']);
}
/**
* 删除场景
* @param int $id
* @return
*/
public function delete($id)
{
$sceneModel = model('Scene');
$param = $this->param;
$userInfo = $this->userInfo;
//权限判断
if (!$sceneModel->getDataById($param['id'], $userInfo['id'])) {
return resultArray(['error' => '数据不存在或已删除']);
}
$dataInfo = db('admin_scene')->where(['scene_id' => $param['id']])->find();
$resData = $sceneModel->delDataById($param['id']);
if ($resData) {
//重新设置默认
$default = db('admin_scene')->where(['types' => $dataInfo['types'],'bydata' => 'all'])->find();
$sceneModel->defaultDataById(['types' => $dataInfo['types'],'user_id' => $userInfo['id']], $default['scene_id']);
return resultArray(['data' => '删除成功']);
} else {
return resultArray(['error' => $sceneModel->getError()]);
}
}
/**
* 场景排序
* @param
* @return
*/
public function sort()
{
$sceneModel = model('Scene');
$param = $this->param;
$userInfo = $this->userInfo;
$param['ids'] = $param['ids'] ? : [];
$param['hide_ids'] = $param['hide_ids'] ? : [];
$resData = $sceneModel->listOrder($param, $userInfo['id']);
if (!$resData) {
return resultArray(['error' => $sceneModel->getError()]);
}
return resultArray(['data' => '设置成功']);
}
/**
* 场景默认
* @param scene_id 场景ID
* @return
*/
public function defaults()
{
$sceneModel = model('Scene');
$param = $this->param;
$userInfo = $this->userInfo;
$scene_id = $param['id'];
$param['user_id'] = $userInfo['id'];
$resData = $sceneModel->defaultDataById($param, $scene_id);
if (!$resData) {
return resultArray(['error' => $sceneModel->getError()]);
}
return resultArray(['data' => '设置成功']);
}
}

@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | Description: 系统设置
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\controller\ApiCommon;
use think\Hook;
use think\Request;
class Setting extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
$userInfo = $this->userInfo;
//权限判断
$unAction = [''];
$adminTypes = adminGroupTypes($userInfo['id']);
if (!in_array(2,$adminTypes) && !in_array(1,$adminTypes) && !in_array($a, $unAction)) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
}

@ -0,0 +1,243 @@
<?php
// +----------------------------------------------------------------------
// | Description: 组织架构
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
use think\Db;
class Structures extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['index','read','save','update','delete','deletes','enables','listdialog','subindex','getsubuserbystructrue']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
//获取权限范围内的部门
public function subIndex()
{
$param = $this->param;
$userInfo = $this->userInfo;
$userModel = model('User');
$m = $param['m'] ? : '';
$c = $param['c'] ? : '';
$a = $param['a'] ? : '';
$ret = $userModel->getUserByPer($m, $c, $a);
$where['au.id'] = ['in',$ret];
$structure_ids = Db::name('AdminUser')
->alias('au')
->join('AdminStructure ast','ast.id = au.structure_id','LEFT')
->where($where)
->group('structure_id')
->order('structure_id asc')
->column('ast.id');
$list = Db::name('AdminStructure')
->group('id')
->order('id asc')
->select();
$result = getSubObj(0, $list, '', 1);
$adminTypes = adminGroupTypes($userInfo['id']);
if(!in_array(1,$adminTypes)){
foreach ($result as $key => $value) {
if(!in_array($value['id'],$structure_ids)){
unset($result[$key]);
}
}
}
return resultArray(['data'=>$result]);
}
//获取部门下权限范围内员工
public function getSubUserByStructrue()
{
$param = $this->param;
$userModel = model('User');
$structureList = $userModel->getSubUserByStr($param['structure_id'],2);
if($param['structure_id']){
$where['id'] = ['in',$structureList];
}
$list =Db::name('AdminUser')->field('id,realname')->where($where)->select();
$list = $list?:array();
return resultArray(['data'=>$list]);
}
/**
* 部门列表
* @author Michael_xu
* @param
* @return
*/
public function index()
{
//权限判断
// if (!checkPerByAction('admin', 'users', 'index')) {
// header('Content-Type:application/json; charset=utf-8');
// exit(json_encode(['code'=>102,'error'=>'无权操作']));
// }
$structureModel = model('Structure');
$param = $this->param;
$type = $param['type'] ? 'tree' : '';
$data = $structureModel->getDataList($type);
return resultArray(['data' => $data]);
}
/**
* 部门详情
* @author Michael_xu
* @param
* @return
*/
public function read()
{
$structureModel = model('Structure');
$param = $this->param;
$data = $structureModel->getDataById($param['id']);
if (!$data) {
return resultArray(['error' => $structureModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 部门添加
* @author Michael_xu
* @param
* @return
*/
public function save()
{
//权限判断
if (!checkPerByAction('admin', 'users', 'structures_save')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$structureModel = model('Structure');
$param = $this->param;
if(!$param['pid']){
resultArray(['error' => '请选择上级部门']);
}
$data = $structureModel->createData($param);
if (!$data) {
return resultArray(['error' => $structureModel->getError()]);
}
return resultArray(['data' => '添加成功']);
}
/**
* 部门编辑
* @author Michael_xu
* @param
* @return
*/
public function update()
{
//权限判断
if (!checkPerByAction('admin', 'users', 'structures_update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$structureModel = model('Structure');
$param = $this->param;
$dataInfo = $structureModel->getDataByID($param['id']);
if (empty($dataInfo['pid']) || $param['id'] == '1') {
unset($param['pid']);
}
$data = $structureModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $structureModel->getError()]);
}
return resultArray(['data' => '编辑成功']);
}
/**
* 部门删除
* @author Michael_xu
* @param
* @return
*/
public function delete()
{
//权限判断
if (!checkPerByAction('admin', 'users', 'structures_delete')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$structureModel = model('Structure');
$param = $this->param;
$data = $structureModel->delStrById($param['id']);
if (!$data) {
return resultArray(['error' => $structureModel->getError()]);
}
return resultArray(['data' => '删除成功']);
}
/**
* 部门启用、停用
* @author Michael_xu
* @param
* @return
*/
public function enables()
{
//权限判断
if (!checkPerByAction('admin', 'users', 'structures_update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$structureModel = model('Structure');
$param = $this->param;
$data = $structureModel->enableDatas($param['ids'], $param['status'], true);
if (!$data) {
return resultArray(['error' => $structureModel->getError()]);
}
return resultArray(['data' => '操作成功']);
}
/**
* 部门list
* @author Michael_xu
* @param
* @return
*/
public function listDialog()
{
$param = $this->param;
$structure_id = $param['id'];
$type = $param['type'];
if (!$structure_id) {
return resultArray(['error' => '参数错误']);
}
$structureList = db('admin_structure')->select();
if ($type == 'update') {
//去除自身及下属部门
foreach ($structureList as $k => $v) {
if (($v['id'] == $structure_id) || ($v['pid'] == $structure_id)) {
unset($structureList[$k]);
}
}
}
$structureList = getSubObj(0, $structureList, '', 1);
return resultArray(['data' => $structureList]);
}
}

@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | Description: 系统配置
// +----------------------------------------------------------------------
// | Author: yykun
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\Hook;
use think\Request;
class System extends ApiCommon
{
//用于判断权限
public function _initialize()
{
$action = [
'permission'=>['index'],
'allow'=>['']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
//信息列表
public function index()
{
$systemModel = model('System');
$data = $systemModel->getDataList();
return resultArray(['data' => $data]);
}
//编辑保存
public function save()
{
$param = $this->param;
if (isset($param['logo'])) {
$logo = !empty($param['logo']) ? './public/uploads/'.$param['logo'] : '';
db('admin_system')->where('name', 'logo')->update(['value' => $logo]);
}
if (isset($param['name'])) {
db('admin_system')->where('name', 'name')->update(['value' => $param['name']]);
}
return resultArray(['data' => '操作成功!']);
}
}

@ -0,0 +1,723 @@
<?php
// +----------------------------------------------------------------------
// | Description: 系统员工
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\controller;
use app\admin\model\User;
use think\Request;
use think\Session;
use think\Hook;
use think\Cache;
use think\Db;
use app\admin\model\LoginRecord;
use app\admin\model\User as UserModel;
use app\admin\logic\UserLogic;
use app\admin\model\Admin as AdminModel;
use app\crm\traits\StarTrait;
class Users extends ApiCommon
{
use StarTrait;
/**
* 用于判断权限
* @permission 无限制
* @allow 登录员工可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => ['exceldownload'],
'allow' => [
'index',
'update',
'updatepwd',
'read',
'updateimg',
'resetpassword',
'userlistbystructid',
'groups',
'groupsdel',
'tobeusers',
'structureuserlist',
'getuserlist',
'usernameedit',
'import',
'setparent',
'loginRecord',
'userstar',
'querylist',
'starlist',
'copyrole',
'subordinate'
]
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 员工列表
* @param
* @return
*/
public function index()
{
$userModel = model('User');
$param = $this->param;
$data = $userModel->getDataList($param);
return resultArray(['data' => $data]);
}
/**
* 员工详情
* @param
* @return
*/
public function read()
{
$userModel = model('User');
$param = $this->param;
$userInfo = $this->userInfo;
if (!$param['id']) $param['id'] = $userInfo['id'];
$data = $userModel->getDataById($param['id']);
if (!$data) {
return resultArray(['error' => $userModel->getError()]);
}
return resultArray(['data' => $data]);
}
/**
* 员工创建
* @param
* @return
*/
public function save()
{
$userModel = model('User');
$param = $this->param;
$userInfo = $this->userInfo;
$data = $userModel->createData($param);
if (!$data) {
return resultArray(['error' => $userModel->getError()]);
}
return resultArray(['data' => '添加成功']);
}
/**
* 员工编辑
* @param
* @return
*/
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'];
} else {
//权限判断
if (!checkPerByAction('admin', 'users', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
unset($param['username']);
$data = $userModel->updateDataById($param, $param['id']);
if (!$data) {
return resultArray(['error' => $userModel->getError()]);
}
$param['userInfo'] = $userData;
$resSync = model('Sync')->syncData($param);
return resultArray(['data' => '编辑成功']);
}
//批量设置密码
public function updatePwd()
{
//权限判断
if (!checkPerByAction('admin', 'users', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$param = $this->param;
if ($param['password'] && is_array($param['id'])) {
$userModel = model('User');
$ret = $userModel->updatePwdById($param);
if ($ret) {
return resultArray(['data'=>true]);
} else {
return resultArray(['error'=>$userModel->getError()]);
}
} else {
return resultArray(['error'=>'参数错误']);
}
}
/**
* 员工状态
* @param status 0禁用,1启用,2禁止登陆,3未激活
* @return
*/
public function enables()
{
$userModel = model('User');
$param = $this->param;
if (!is_array($param['id'])) {
$ids[] = $param['id'];
} else {
$ids = $param['id'];
}
//顶级管理员不能修改
foreach ($ids as $k=>$v) {
if ((int)$v == 1 && $param['status'] == '0') {
unset($ids[$k]);
}
}
$data = $userModel->enableDatas($ids, $param['status']);
if (!$data) {
return resultArray(['error' => $userModel->getError()]);
}
return resultArray(['data' => '操作成功']);
}
/**
* 获取权限范围内的员工数组
* @param
* @return
*/
public function getUserList()
{
$userModel = model('User');
$param = $this->param;
$by = $param['by'] ? : '';
$user_id = $param['user_id'] ? : '';
$where = [];
$belowIds = [];
if ($param['m'] && $param['c'] && $param['a']) {
if ($param['m'] == 'oa' && $param['c'] == 'task') {
$belowIds = getSubUserId(true, 1);
} else {
$belowIds = $userModel->getUserByPer($param['m'], $param['c'], $param['a']);
}
$where['user.id'] = ['in',$belowIds];
} else {
if ($by == 'sub') {
$userInfo = $this->userInfo;
$adminIds = $userModel->getAdminId();
if (in_array($userInfo['id'],$adminIds)) {
$belowIds = getSubUserId(true, 1);
} else {
//下属id
$belowIds = getSubUserId();
}
$where['user.id'] = ['in',$belowIds];
} elseif ($by == 'parent') {
if ($user_id == 1) {
$where['user.id'] = 0;
} else {
$unUserId[] = $user_id;
$subUserId = getSubUser($user_id);
$unUserId = $subUserId ? array_merge($subUserId,$unUserId) : $unUserId;
}
$where['user.id'] = ['not in',$unUserId];
} else {
$belowIds = getSubUserId(true, 1);
$where['user.id'] = ['in',$belowIds];
}
}
$userList = db('admin_user')
->alias('user')
->where($where)
->where('user.status>0 and user.type=1')
->join('__ADMIN_STRUCTURE__ structure', 'structure.id = user.structure_id', 'LEFT')
->field('user.id,user.realname,user.thumb_img,structure.name as s_name')
->select();
# 角色数据
$groupList = db('admin_access')->alias('access')
->join('__ADMIN_GROUP__ group', 'group.id = access.group_id', 'LEFT')
->field('group.id, group.title, access.user_id')->select();
$groupArray = [];
foreach ($groupList AS $key => $value) {
$groupArray[$value['user_id']]['roleId'][] = $value['id'];
$groupArray[$value['user_id']]['roleName'][] = $value['title'];
}
foreach ($userList as $k=>$v) {
$userList[$k]['username'] = $v['realname'];
$userList[$k]['thumb_img'] = $v['thumb_img'] ? getFullPath($v['thumb_img']) : '';
# 员工新增角色ID和角色名称字段
$userList[$k]['roleId'] = !empty($groupArray[$v['id']]['roleId']) ? implode(',', $groupArray[$v['id']]['roleId']) : '';
$userList[$k]['roleName'] = !empty($groupArray[$v['id']]['roleName']) ? implode(',', $groupArray[$v['id']]['roleName']) : '';
# 单独处理admin管理员的角色ID和角色名称字段
if ($v['id'] == 1 && (empty($groupArray[$v['id']]['roleId']) || empty($groupArray[$v['id']]['roleName']))) {
$userList[$k]['roleId'] = '1';
$userList[$k]['roleName'] = '超级管理员角色';
}
}
return resultArray(['data' => $userList ? : []]);
}
/**
* 修改头像
* @param
* @return
*/
public function updateImg()
{
$fileModel = model('File');
$param = $this->param;
$userInfo = $this->userInfo;
//处理图片
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
$param['file'] = request()->file('file');
$resImg = $fileModel->updateByField($param['file'], 'User', $param['id'], 'img', 'thumb_img', 150, 150);
if (!$resImg) {
return resultArray(['error' => $fileModel->getError()]);
}
return resultArray(['data' => '上传成功']);
}
/**
* 重置密码
* @param
* @return
*/
public function resetPassword()
{
$param = $this->param;
$userInfo = $this->userInfo;
$userModel = model('User');
if ($param['id'] && (int)$param['id'] !== $userInfo['id']) {
//权限判断
if (!checkPerByAction('admin', 'users', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$user_id = $param['id'];
if (!$param['new_pwd']) {
$this->error = '请输入重置密码';
return false;
}
$userInfo = $userModel->getDataById($user_id);
if (user_md5($param['new_pwd'], $userInfo['salt'], $userInfo['username']) == $userInfo['password']) {
$this->error = '密码没改变';
return false;
}
if (db('admin_user')->where('id', $user_id)->setField('password', user_md5($param['new_pwd'], $userInfo['salt'], $userInfo['username']))) {
$syncData = [];
$syncModel = new \app\admin\model\Sync();
$syncData['user_id'] = $userInfo['id'];
$syncData['salt'] = $userInfo['salt'];
$syncData['password'] = user_md5($param['new_pwd'], $userInfo['salt'], $userInfo['username']);
$resSync = $syncModel->syncData($syncData);
return resultArray(['data' => '密码重置成功']);
} else {
return resultArray(['error' => '密码重置失败,请重试']);
}
} else {
$userModel = model('User');
$old_pwd = $param['old_pwd'];
$new_pwd = $param['new_pwd'];
$data = $userModel->updatePaw($userInfo, $old_pwd, $new_pwd);
if (!$data) {
return resultArray(['error' => $userModel->getError()]);
}
return resultArray(['data' => $data]);
}
}
/**
* 员工角色关系
* @param
* @return
*/
public function groups()
{
//权限判断
if (!checkPerByAction('admin', 'groups', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$param = $this->param;
if (!$param['users'] && !$param['structures']) {
return resultArray(['error' => '请选择员工']);
}
if (!$param['groups']) {
return resultArray(['error' => '请选择角色']);
}
$userModel = model('User');
//部门下所有员工
$userArr = [];
if (is_array($param['structures'])) {
foreach ($param['structures'] as $v) {
$userArr[] = $userModel->getSubUserByStr($v);
}
}
if ($userArr) $userArr = call_user_func_array('array_merge', $userArr); //数组合并
if ($userArr && $param['users']) {
$userIds = array_merge($userArr, $param['users']);
} elseif ($userArr) {
$userIds = $userArr;
} else {
$userIds = $param['users'];
}
$userIds = array_unique($userIds);
$groups = $param['groups'];
$accessModel = model('Access');
$resData = true;
foreach ($userIds as $k=>$v) {
//角色员工关系处理
$res = $accessModel->userGroup($v, $param['groups']);
if (!$res) {
$resData = false;
}
}
// if ($resData == false) {
// return resultArray(['error' => '操作失败,请重试']);
// }
return resultArray(['data' => '创建成功']);
}
/**
* 员工角色关系(删除)
* @param
* @return
*/
public function groupsDel()
{
//权限判断
if (!checkPerByAction('admin', 'groups', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$param = $this->param;
if (!$param['user_id']) {
return resultArray(['error' => '请选择员工']);
}
if (!$param['group_id']) {
return resultArray(['error' => '参数错误']);
}
# 员工至少保留一个角色
$count = db('admin_access')->where(['user_id' => $param['user_id']])->count();
if ($count == 1) return resultArray(['error' => '员工至少保留一个角色!']);
$res = db('admin_access')->where(['user_id' => $param['user_id'],'group_id' => $param['group_id']])->delete();
if (!$res) {
return resultArray(['error' => '操作失败,请重试']);
}
return resultArray(['data' => '删除成功']);
}
/**
* [structureUserList 部门员工混合数据]
* @param
* @return
*/
public function structureUserList()
{
$structure_list = db('admin_structure')->select();
$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();
$structureList[$k]['userList'] = $userList;
}
return $structureList;
}
//人资员工导入
public function tobeusers(){
$userModel = model('User');
$param = $this->param;
$flag = $userModel->beusers($param);
if ($flag) {
return resultArray(['data'=>$flag]);
} else {
return resultArray(['error'=>$userModel->getError()]);
}
}
//根据部门ID获取员工列表
public function userListByStructId()
{
$usermodel = model('User');
$param = $this->param;
$structure_id = $param['structure_id']?:'';
$ret = $usermodel->getUserListByStructureId($structure_id) ? : [];
return resultArray(['data'=>$ret]);
}
/**
* 员工账号修改
* @param
* @return
*/
public function usernameEdit()
{
//权限判断
if (!checkPerByAction('admin', 'users', 'update')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
$param = $this->param;
$userInfo = $this->userInfo;
//权限判断
if ($param['id'] == 1) {
return resultArray(['error' => '管理员账号暂不能修改']);
}
$adminTypes = adminGroupTypes($userInfo['id']);
if (!in_array(3,$adminTypes) && !in_array(1,$adminTypes) && !in_array(2,$adminTypes)) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
if (!$param['id'] || !$param['username'] || !$param['password']) {
return resultArray(['error' => '参数错误!']);
}
if (db('admin_user')->where(['id' => ['neq',$param['id']],'username' => $param['username']])->find()) {
return resultArray(['error' => '手机号码已存在!']);
}
$userData = db('admin_user')->where(['id' => $param['id']])->field('username,salt,password')->find();
$data = [];
$data['username'] = $param['username'];
$data['password'] = user_md5($param['password'], $userData['salt'], $param['username']);
$data['userInfo'] = $userData;
$resSync = model('Sync')->syncData($data);
if ($resSync) {
unset($data['userInfo']);
$res = db('admin_user')->where(['id' => $param['id']])->update($data);
return resultArray(['data' => '修改成功!']);
} else {
return resultArray(['error' => '修改失败,请重试!']);
}
}
/**
* 登录记录
*/
public function loginRecord()
{
if (!checkPerByAction('admin', 'loginRecord', 'index')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作']));
}
$loginRecordModel = new LoginRecord();
$where = [];
getWhereUserByParam($where, 'create_user_id');
getWhereTimeByParam($where, 'create_time');
$limit = $this->param['limit'] ?: 15;
$data = $loginRecordModel
->where($where)
->order(['create_time' => 'DESC'])
->paginate($limit)
->each(function ($val) {
$val['username'] = $val->create_user_info['realname'];
$val['type_name'] = $val->type_name;
})
->toArray();
return resultArray([
'data' => [
'list' => $data['data'],
'dataCount' => $data['total']
],
]);
}
/**
* 员工导入模板下载
* @author Michael_xu
* @param string $save_path 本地保存路径 用于错误数据导出,在 Admin\Model\Excel::batchImportData()调用
* @return
*/
public function excelDownload($save_path = '')
{
$param = $this->param;
$userInfo = $this->userInfo;
$excelModel = new \app\admin\model\Excel();
// 导出的字段列表
$field_list = UserModel::$import_field_list;
$excelModel->excelImportDownload($field_list, 'admin_user', $save_path);
}
/**
* 员工导入
*/
public function import()
{
// 仅允许超管,系统管理员,部门与员工管理员 导入
if (false === UserModel::checkUserGroup([1, 2, 3])) {
return resultArray(['error' => '没有该权限']);
}
$param = $this->param;
$userInfo = $this->userInfo;
$excelModel = new \app\admin\model\Excel();
$param['types'] = 'admin_user';
$file = request()->file('file');
$res = $excelModel->batchImportData($file, $param, $this);
$list=[];
$list[]=$excelModel->getError();
$item=$list[0];
if (!$res) {
return resultArray(['data' => $item]);
}
Cache::clear('user_info');
return resultArray(['data' => $item]);
}
/**
* 批量设置直属上级
*
* @author Ymob
* @datetime 2019-10-28 13:37:57
*/
public function setParent()
{
// 仅允许超管,系统管理员,部门与员工管理员 批量设置
if (false === UserModel::checkUserGroup([1, 2, 3])) {
return resultArray(['error' => '没有该权限']);
}
$parent_id = (int) $this->param['parent_id'];
$parent_user = UserModel::find($parent_id);
if (!$parent_user) {
return resultArray(['error' => '请选择直属上级']);
}
$user_id_list = (array) $this->param['id_list'];
if (empty($user_id_list)) {
return resultArray(['error' => '请选择员工']);
}
if (in_array(1, $user_id_list)) {
return resultArray(['error' => '超级管理员不能设置上级']);
}
if (in_array($parent_id, $user_id_list)) {
return resultArray(['error' => '直属上级不能为员工自己']);
}
foreach ($user_id_list as $val) {
if (in_array($parent_id, getSubUserId(true, 0, (int) $val))) {
return resultArray(['error' => '直属上级不能是自己下属(包含下属的下属)']);
}
}
$a = new UserModel;
if ($a->where(['id' => ['IN', $user_id_list]])->update(['parent_id' => $parent_id])) {
Cache::clear('user_info');
return resultArray(['data' => '员工直属上级设置成功']);
} else {
return resultArray(['error' => '员工直属上级设置失败' . $a->getError()]);
}
}
/**
* 通讯录列表
* @return mixed
*/
public function queryList(){
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id']=$userInfo['id'];
$userLogic=new UserLogic();
$data=$userLogic->getDataList($param);
return resultArray(['data' => $data]);
}
/**
* 关注的通讯录列表
* @return mixed
*/
public function starList(){
$param = $this->param;
$userInfo = $this->userInfo;
$param['user_id']=$userInfo['id'];
$userLogic=new UserLogic();
$data=$userLogic->queryList($param);
return resultArray(['data' => $data]);
}
/**
* 设置关注
*
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function userStar()
{
$userInfo = $this->userInfo;
$userId = $userInfo['id'];
$targetId = $this->param['target_id'];
$type = $this->param['type'];
if (empty($userId) || empty($targetId) || empty($type)) return resultArray(['error' => '缺少必要参数!']);
if (!$this->setStar($type, $userId, $targetId)) {
return resultArray(['error' => '设置关注失败!']);
}
return resultArray(['data' => '设置关注成功!']);
}
/**
* 复制员工角色
*
* @return \think\response\Json
*/
public function copyRole()
{
$param = $this->param;
if (empty($param['user_id']) && empty($param['structure_id'])) return resultArray(['error' => '请选择员工或部门!']);
if (empty($param['group_id'])) return resultArray(['error' => '请选择角色!']);
$userModel = new User();
if (!$userModel->copyRole($param)) return resultArray(['error' => '操作失败!']);
return resultArray(['data' => '操作成功!']);
}
/**
* 获取下属(全部层级)
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function subordinate()
{
$userId = $this->userInfo['id'];
# 获取下属的ID
$subIds = getSubUserId(false, 0, $userId);
$data = Db::name('admin_user')->field(['id', 'realname', 'thumb_img as img'])->whereIn('id', $subIds)->select();
foreach ($data AS $key => $value) {
$data[$key]['img'] = !empty($data[$key]['img']) ? getFullPath($data[$key]['img']) : '';
}
return resultArray(['data' => $data]);
}
}

@ -0,0 +1,149 @@
<?php
/**
* 项目管理控制器
*
* @author qifan
* @date 2020-12-17
*/
namespace app\admin\controller;
use app\admin\logic\WorkLogic;
use think\Hook;
use think\Request;
class Work extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [''],
'allow' => ['rules', 'roles', 'saverole', 'readrole', 'updaterole', 'deleterole']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
}
/**
* 规则列表
*
* @param WorkLogic $workLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function rules(WorkLogic $workLogic)
{
$data = $workLogic->getRules();
$result = [
'menu_id' => 0,
'menu_name' => "项目管理",
'menu_type' => 1,
'parent_id' => 0,
'realm' => 'work',
'children' => []
];
$result['children'][] = ['id' => 0, 'title' => '项目', 'name' => 'work', 'children' => $data];
return resultArray(['data' => $result]);
}
/**
* 获取角色
*
* @param WorkLogic $workLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function roles(WorkLogic $workLogic)
{
$data = $workLogic->getRoles();
return resultArray(['data' => $data]);
}
/**
* 创建角色
*
* @param WorkLogic $workLogic
* @return \think\response\Json
*/
public function saveRole(WorkLogic $workLogic)
{
if (empty($this->param['title'])) return resultArray(['error' => '请填写权限名称!']);
if (!$workLogic->saveRole($this->param)) return resultArray(['操作失败!']);
return resultArray(['data' => '操作成功!']);
}
/**
* 权限角色详情
*
* @param WorkLogic $workLogic
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function readRole(WorkLogic $workLogic)
{
if (empty($this->param['id'])) return resultArray(['error' => '请选择权限角色!']);
$data = $workLogic->readRole($this->param['id']);
return resultArray(['data' => $data]);
}
/**
* 编辑权限角色
*
* @param WorkLogic $workLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function updateRole(WorkLogic $workLogic)
{
if (empty($this->param['id'])) return resultArray(['error' => '请选择要编辑的权限角色!']);
if (empty($this->param['title'])) return resultArray(['error' => '请填写权限名称!']);
if ($workLogic->updateRole($this->param) === false) return resultArray(['error' => '操作失败!']);
return resultArray(['data' => '操作成功!']);
}
/**
* 删除权限角色
*
* @param WorkLogic $workLogic
* @return \think\response\Json
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function deleteRole(WorkLogic $workLogic)
{
if (empty($this->param['id'])) return resultArray(['error' => '请选择要删除的权限角色!']);
$result = $workLogic->deleteRole($this->param['id']);
if (empty($result['status'])) return resultArray(['error' => $result['error']]);
return resultArray(['data' => '操作成功!']);
}
}

@ -0,0 +1,4 @@
<?php
return [
];

@ -0,0 +1,309 @@
<?php
/**
* 日志规则逻辑类
*
* @author qifan
* @date 2020-12-03
*/
namespace app\admin\logic;
use think\Db;
class DailyRuleLogic
{
/**
* 获取日志欢迎语
*
* @return array|mixed
*/
public function welcome()
{
$mark = Db::name('admin_oalog_rule')->where('type', 4)->value('mark');
return !empty($mark) ? unserialize($mark) : [];
}
/**
* 保存欢迎语
*
* @param $data
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function setWelcome($data)
{
$result = [];
foreach ($data as $key => $value) {
if (!empty($value)) $result[] = $value;
}
$result = serialize($result);
if (Db::name('admin_oalog_rule')->where('type', 4)->value('id')) {
return Db::name('admin_oalog_rule')->where('type', 4)->update(['mark' => $result]);
}
return Db::name('admin_oalog_rule')->insert([
'type' => 4,
'status' => 1,
'mark' => $result
]);
}
/**
* 获取日志规则
*
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function workLogRule()
{
$result[] = $this->getDayLogRule();
$result[] = $this->getWeekLogRule();
$result[] = $this->getMonthLogRule();
return $result;
}
/**
* 设置日志规则
*
* @param $param
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function setWorkLogRule($param)
{
if (!empty($param[0])) $this->setDayLogRule($param[0]);
if (!empty($param[1])) $this->setWeekLogRule($param[1]);
if (!empty($param[2])) $this->setMonthLogRule($param[2]);
}
/**
* 设置日规则
*
* @param $param
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
private function setDayLogRule($param)
{
$data = [
'type' => 1,
'userIds' => $param['userIds'],
'effective_day' => $param['effective_day'],
'start_time' => $param['start_time'],
'end_time' => $param['end_time'],
'status' => $param['status']
];
if (Db::name('admin_oalog_rule')->where('type', 1)->value('id')) {
return Db::name('admin_oalog_rule')->where('type', 1)->update($data);
}
return Db::name('admin_oalog_rule')->insert($data);
}
/**
* 设置周规则
*
* @param $param
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
private function setWeekLogRule($param)
{
$data = [
'type' => 2,
'userIds' => $param['userIds'],
'start_time' => $param['start_time'],
'end_time' => $param['end_time'],
'status' => $param['status']
];
if (Db::name('admin_oalog_rule')->where('type', 2)->value('id')) {
return Db::name('admin_oalog_rule')->where('type', 2)->update($data);
}
return Db::name('admin_oalog_rule')->insert($data);
}
/**
* 设置月规则
*
* @param $param
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
private function setMonthLogRule($param)
{
$data = [
'type' => 3,
'userIds' => $param['userIds'],
'start_time' => $param['start_time'],
'end_time' => $param['end_time'],
'status' => $param['status']
];
if (Db::name('admin_oalog_rule')->where('type', 3)->value('id')) {
return Db::name('admin_oalog_rule')->where('type', 3)->update($data);
}
return Db::name('admin_oalog_rule')->insert($data);
}
/**
* 获取日规则
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getDayLogRule()
{
$day = Db::name('admin_oalog_rule')->where('type', 1)->find();
return [
'type' => $day['type'],
'status' => $day['status'],
'userIds' => $day['userIds'],
'user' => $this->getUsers($day['userIds']),
'effective_day' => $day['effective_day'],
'start_time' => $day['start_time'],
'end_time' => $day['end_time']
];
}
/**
* 获取周规则
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getWeekLogRule()
{
$week = Db::name('admin_oalog_rule')->where('type', 2)->find();
return [
'type' => $week['type'],
'status' => $week['status'],
'userIds' => $week['userIds'],
'user' => $this->getUsers($week['userIds']),
'effective_day' => $week['effective_day'],
'start_time' => $week['start_time'],
'end_time' => $week['end_time']
];
}
/**
* 获取月规则
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getMonthLogRule()
{
$month = Db::name('admin_oalog_rule')->where('type', 3)->find();
return [
'type' => $month['type'],
'status' => $month['status'],
'userIds' => $month['userIds'],
'user' => $this->getUsers($month['userIds']),
'effective_day' => $month['effective_day'],
'start_time' => $month['start_time'],
'end_time' => $month['end_time']
];
}
/**
* 获取用户列表
*
* @param $ids
* @return bool|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getUsers($ids)
{
return Db::name('admin_user')->field(['id', 'realname'])->whereIn('id', $ids)->select();
}
/**
* 自定义日程类型列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function schedule()
{
$list = Db::name('admin_oa_schedule')->where('type', 2)->field(['name,color,schedule_id as id'])->select();
$data = [];
$data['list'] = $list;
return $data;
}
/**
* 设置日程自定义规则
* @param $param
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function setSchedule($param)
{
if (Db::name('admin_oa_schedule')->where('schedule_id', $param['id'])->value('schedule_id')) {
$data = [
'name' => $param['name'],
'update_time' => time(),
'color' => $param['color'],
];
return Db::name('admin_oa_schedule')->where( 'schedule_id', $param['id'])->update($data);
}
}
/**
* 添加自定义日程规则
* @param $param
* @return int|string
*/
public function addSchedule($param)
{
$data = [
'name' => $param['name'],
'create_time' => time(),
'color' => $param['color'],
];
return Db::name('admin_oa_schedule')->insert($data);
}
/**
* 删除日程自定义规则
* @param $param
* @return int
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function delSchedule($param)
{
if (Db::name('admin_oa_schedule')->where('schedule_id', $param)->value('schedule_id')) {
return Db::name('AdminOaSchedule')->where('schedule_id', $param)->delete();
}
}
}

@ -0,0 +1,572 @@
<?php
/**
* 字段授权逻辑类
*
* @author qifan
* @date 2020-12-01
*/
namespace app\admin\logic;
use think\Db;
class FieldGrantLogic
{
/**
* 字段授权列表
*
* @param $param
* @return array|bool|\PDOStatement|string|\think\Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index($param)
{
$where = function ($query) use ($param) {
$query->where('module', $param['module']);
$query->where('column', $param['column']);
$query->where('role_id', $param['role_id']);
};
$count = Db::name('admin_field_grant')->where($where)->count();
# 如果该角色下没有字段授权数据则自动添加
if ($count == 0 && Db::name('admin_group')->where('id', $param['role_id'])->find()) {
$this->createCrmFieldGrant($param['role_id']);
}
$data = Db::name('admin_field_grant')->field(['grant_id', 'content'])->where($where)->find();
if (!empty($data['content'])) $data['content'] = unserialize($data['content']);
return !empty($data) ? $data : [];
}
/**
* 更新授权字段
*
* @param $grantId
* @param $content
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function update($grantId, $content)
{
return Db::name('admin_field_grant')->where('grant_id', $grantId)->update(['content' => serialize(array_values($content))]);
}
/**
* 添加字段授权信息
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function createCrmFieldGrant($roleId)
{
# 添加线索字段授权数据
$this->createLeadsFieldGrant($roleId);
# 添加客户字段授权数据
$this->createCustomerFieldGrant($roleId);
# 添加联系人字段授权数据
$this->createContactsFieldGrant($roleId);
# 添加商机字段授权数据
$this->createBusinessFieldGrant($roleId);
# 添加合同字段授权数据
$this->createContractfieldGrant($roleId);
# 添加回款字段授权数据
$this->createReceivablesFieldGrant($roleId);
# 添加产品字段授权信息
$this->createProductFieldGrant($roleId);
# 添加回访字段授权信息
$this->createVisitFieldGrant($roleId);
}
/**
* 删除授权字段数据
*
* @param $roleId
* @param string $module
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function deleteCrmFieldGrant($roleId)
{
Db::name('admin_field_grant')->where('module', 'crm')->where('role_id', $roleId)->delete();
}
/**
* 拷贝字段授权数据
*
* @param $copyId
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function copyCrmFieldGrant($copyId, $roleId)
{
$data = [];
$list = Db::name('admin_field_grant')->where('module', 'crm')->where('role_id', $copyId)->select();
foreach ($list AS $key => $value) {
$data[] = [
'role_id' => $roleId,
'module' => $value['module'],
'column' => $value['column'],
'content' => $value['content'],
'create_time' => time(),
'update_time' => time()
];
}
if (!empty($data)) Db::name('admin_field_grant')->insertAll($data);
}
/**
* 同步更新自定义字段的授权信息
*
* @param $types
* @return bool
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function fieldGrantDiyHandle($types)
{
$typesArray = explode('_', $types);
# 只处理客户管理角色下的字段授权
if ($typesArray[0] != 'crm') return false;
# 查询自定义字段表
$fieldBaseData = [];
$fieldList = Db::name('admin_field')->field(['name', 'field'])->where('types', $types)->select();
foreach ($fieldList AS $key => $value) {
$fieldBaseData[$value['field']] = $value;
}
# 查询字段授权表
$grantList = Db::name('admin_field_grant')->field(['grant_id', 'content'])->where('column', $typesArray[1])->select();
# 处理授权字段的数据更新
foreach ($grantList AS $key => $value) {
$content = unserialize($value['content']);
$fieldData = $fieldBaseData;
foreach ($content AS $k => $v) {
# 只处理自定义字段
if ($v['is_diy'] == 0) continue;
if (empty($fieldData[$v['field']])) {
# 【处理删除:】没有在$fieldData找到说明自定义字段被删除则进行同步删除。
unset($content[(int)$k]);
} else {
# 【处理更新:】如果在$fieldData找到则进行同步更新。
$content[$k]['name'] = $fieldData[$v['field']]['name'];
$content[$k]['field'] = $fieldData[$v['field']]['field'];
# 删除$fieldData的数据方便统计新增的自定义字段。
unset($fieldData[(string)$v['field']]);
}
}
# 【处理新增】如果$fieldData还有数据说明是新增的则进行同步新增。
if (!empty($fieldData)) {
foreach ($fieldData AS $k => $v) {
$content[] = [
'name' => $v['name'],
'field' => $v['field'],
'read' => 1,
'read_operation' => 1,
'write' => 1,
'write_operation' => 1,
'is_diy' => 1
];
}
}
# todo 暂时将数据库操作写在循环中!!!
Db::name('admin_field_grant')->where('grant_id', $value['grant_id'])->update(['content' => serialize(array_values($content))]);
}
return true;
}
/**
* 添加线索字段授权数据
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createLeadsFieldGrant($roleId)
{
$content = [];
$leadsList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_leads')->select();
# 处理自定义字段
foreach ($leadsList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => in_array($value['field'], ['name', 'next_time']) ? 0 : 1,
'write' => 1,
'write_operation' => $value['field'] == 'next_time' ? 0 : 1,
'is_diy' => 1
];
}
# 处理固定字段
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '最后跟进记录', 'field' => 'record', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'leads',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加客户字段授权数据
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createCustomerFieldGrant($roleId)
{
$content = [];
$customerList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_customer')->select();
# 处理自定义字段
foreach ($customerList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => in_array($value['field'], ['name', 'deal_status']) ? 0 : 1,
'write' => 1,
'write_operation' => $value['field'] == 'deal_status' ? 0 : 1,
];
}
# 处理固定字段
$content[] = ['name' => '合同编号', 'field' => 'contract', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '最后跟进记录', 'field' => 'record', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '最后跟进时间', 'field' => 'record_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '负责人获取客户时间', 'field' => 'deal_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '成交状态', 'field' => 'deal_status', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '锁定状态', 'field' => 'is_lock', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
$content[] = ['name' => '距进入公海天数', 'field' => 'pool_day', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'customer',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加联系人字段授权数据
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createContactsFieldGrant($roleId)
{
$content = [];
$contactsList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_contacts')->select();
# 处理自定义字段
foreach ($contactsList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => in_array($value['field'], ['name', 'next_time']) ? 0 : 1,
'write' => 1,
'write_operation' => $value['field'] == 'next_time' ? 0 : 1,
'is_diy' => 1
];
}
# 处理固定字段
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'contacts',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加商机字段授权数据
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createBusinessFieldGrant($roleId)
{
$content = [];
$BusinessList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_business')->select();
# 处理自定义字段
foreach ($BusinessList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => in_array($value['field'], ['customer_id', 'type_id', 'status_id']) == '' ? 0 : 1,
'write' => 1,
'write_operation' => in_array($value['field'], ['customer_id', 'type_id', 'status_id']) ? 0 : 1,
'is_diy' => 1
];
}
# 处理固定字段
$content[] = ['name' => '整单折扣', 'field' => 'discount_rate', 'read' => 1, 'read_operation' => 1, 'write' => 1, 'write_operation' => 1, 'is_diy' => 0];
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'business',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加合同字段授权数据
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createContractfieldGrant($roleId)
{
$content = [];
$contractList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_contract')->select();
# 处理自定义字段
foreach ($contractList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => $value['field'] == 'num' ? 0 : 1,
'write' => 1,
'write_operation' => 1,
'is_diy' => 1
];
}
# 处理固定字段
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '最后跟进记录', 'field' => 'record', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '最后跟进记录', 'field' => 'record_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '已收款金额', 'field' => 'received', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '未收款金额', 'field' => 'uncollected', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '审核状态', 'field' => 'check_status', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'contract',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加回款字段授权数据
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createReceivablesFieldGrant($roleId)
{
$content = [];
$receivablesList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_receivables')->select();
# 处理自定义字段
foreach ($receivablesList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => 1,
'write' => 1,
'write_operation' => 1,
'is_diy' => 1
];
}
# 处理固定字段
$content[] = ['name' => '合同金额', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '审核状态', 'field' => 'check_status', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'receivables',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加产品字段授权信息
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createProductFieldGrant($roleId)
{
$content = [];
$productList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_product')->select();
# 处理自定义字段
foreach ($productList AS $key => $value) {
$readOperation = 1;
$writeOperation = 1;
if (in_array($value['field'], ['name', 'category_id', 'unit', 'price', 'status'])) $readOperation = 0;
if (in_array($value['field'], ['status'])) $writeOperation = 0;
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => $readOperation,
'write' => 1,
'write_operation' => $writeOperation,
'is_diy' => 1
];
}
# 处理固定字段
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '更新时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 1, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'product',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
/**
* 添加回访字段授权信息
*
* @param $roleId
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function createVisitFieldGrant($roleId)
{
$content = [];
$visitList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_visit')->select();
# 处理自定义字段
foreach ($visitList AS $key => $value) {
$content[] = [
'name' => $value['name'],
'field' => $value['field'],
'read' => 1,
'read_operation' => 1,
'write' => 1,
'write_operation' => 1,
'is_diy' => 1
];
}
# 处理固定字段
// $content[] = ['name' => '回访时间', 'field' => 'visit_time', 'read' => 1, 'read_operation' => 1, 'write' => 1, 'write_operation' => 1, 'is_diy' => 0];
$content[] = ['name' => '负责人', 'field' => 'owner_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '客户', 'field' => 'customer_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '联系人', 'field' => 'contract_id', 'read' => 1, 'read_operation' => 1, 'write' => 1, 'write_operation' => 1, 'is_diy' => 0];
$content[] = ['name' => '创建时间', 'field' => 'create_time', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '编辑时间', 'field' => 'update_time', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '创建人', 'field' => 'create_user_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
$content[] = ['name' => '合同', 'field' => 'contacts_id', 'read' => 1, 'read_operation' => 0, 'write' => 0, 'write_operation' => 0, 'is_diy' => 0];
Db::name('admin_field_grant')->insert([
'role_id' => $roleId,
'module' => 'crm',
'column' => 'visit',
'content' => serialize($content),
'create_time' => time(),
'update_time' => time()
]);
}
}

@ -0,0 +1,996 @@
<?php
/**
* 初始化逻辑类
*
* @author qifan
* @date 2020-01-05
*/
namespace app\admin\logic;
use think\Db;
use think\Exception;
class InitializeLogic
{
public $log = '操作成功!';
# 值为false时终止其他方法的操作
private $status = true;
/**
* 重置数据
*
* @param $param
* @return bool
*/
public function update($param)
{
# 设置脚本执行时间和内存
ini_set('max_execution_time', 0);
ini_set('memory_limit', '256M');
# 重置单个或多个模块
foreach ($param AS $key => $value) {
if ($value == 'crm' && $this->status) $this->resetCustomerManagementData(); # 重置客户管理数据
if ($value == 'taskExamine' && $this->status) $this->resetTaskExamineData(); # 重置任务/审批数据
if ($value == 'log' && $this->status) $this->resetDailyRecordData(); # 重置日志数据
if ($value == 'project' && $this->status) $this->resetProjectManagementData(); # 重置项目管理数据
if ($value == 'calendar' && $this->status) $this->resetCalendarData(); # 重置日历数据
}
return true;
}
/**
* 验证密码
*
* @param $userId
* @param $password
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function verification($userId, $password)
{
$userInfo = Db::name('admin_user')->field(['password', 'salt'])->where('id', $userId)->find();
return user_md5($password, $userInfo['salt']) == $userInfo['password'];
}
/**
* 重置客户管理数据
*/
private function resetCustomerManagementData()
{
# 表前缀
$prefix = config('database.prefix');
# 文件数组
$files = [];
# 启动事务
Db::startTrans();
try {
# ------ 重置产品数据START ------ #
# 获取产品附件ID
$productFileIds = Db::name('crm_product_file')->column('file_id');
# 查询产品文件数据
$productFileInfo = $this->getFileList($productFileIds);
# 合并附件数据
$files = array_merge($files, $productFileInfo);
# 删除产品分类表
Db::name('crm_product_category')->where(['category_id' => ['neq', 1]])->delete();
# 重置产品分类自增ID
Db::query("ALTER TABLE ".$prefix."crm_product_category AUTO_INCREMENT = 1");
# 清除产品附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_product_file");
# 删除产品附件
Db::name('admin_file')->whereIn('file_id', $productFileIds)->delete();
# 清除产品表数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_product");
# ------ 重置产品数据 END ------ #
# ------ 重置回访数据 START ------ #
# 获取回访附件ID
$visitFileIds = Db::name('crm_visit_file')->column('file_id');
# 查询回访文件数据
$visitFileInfo = $this->getFileList($visitFileIds);
# 合并附件数据
$files = array_merge($files, $visitFileInfo);
# 清除回访附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_visit_file");
# 删除回访附件
Db::name('admin_file')->whereIn('file_id', $visitFileIds)->delete();
# 清除回访表数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_visit");
# ------ 重置回访数据 END ------ #
# ------ 重置发票数据 START ------ #
# 获取回访附件ID
$invoiceFileIds = Db::name('crm_invoice_file')->column('file_id');
# 查询回访文件数据
$invoiceFileInfo = $this->getFileList($invoiceFileIds);
# 合并附件数据
$files = array_merge($files, $invoiceFileInfo);
# 清除发票附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_invoice_file");
# 删除发票附件
Db::name('admin_file')->whereIn('file_id', $invoiceFileIds)->delete();
# 清除发票开户行信息数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_invoice_info");
# 清除发票数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_invoice");
# ------ 重置发票数据 END ------ #
# ------ 重置回款数据 START ------ #
# 获取回款附件ID
$receivablesFileIds = Db::name('crm_receivables_file')->column('file_id');
# 查询回访文件数据
$receivablesFileInfo = $this->getFileList($receivablesFileIds);
# 合并附件数据
$files = array_merge($files, $receivablesFileInfo);
# 清除回款附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_receivables_file");
# 删除回款附件
Db::name('admin_file')->whereIn('file_id', $receivablesFileIds)->delete();
# 清除回款计划数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_receivables_plan");
# 清除回款数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_receivables");
# ------ 重置回款数据 END ------ #
# ------ 重置合同数据 START ------ #
# 获取合同附件ID
$contractFileIds = Db::name('crm_contract_file')->column('file_id');
# 查询合同文件数据
$contractFileInfo = $this->getFileList($contractFileIds);
# 合并附件数据
$files = array_merge($files, $contractFileInfo);
# 清除合同附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_contract_file");
# 删除合同附件
Db::name('admin_file')->whereIn('file_id', $contractFileIds)->delete();
# 删除合同产品关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_contract_product");
# 删除合同数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_contract");
# ------ 重置合同数据 END ------ #
# ------ 重置商机数据 START ------ #
# 获取商机附件ID
$businessFileIds = Db::name('crm_business_file')->column('file_id');
# 查询商机文件数据
$businessFileInfo = $this->getFileList($businessFileIds);
# 合并附件数据
$files = array_merge($files, $businessFileInfo);
# 清除商机附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_business_file");
# 删除商机附件
Db::name('admin_file')->whereIn('file_id', $businessFileIds)->delete();
# 清除商机日志数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_business_log");
# 清除商机产品关系数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_business_product");
# 删除商机状态组类别数据
Db::name('crm_business_type')->where(['type_id' => ['neq', 1]])->delete();
# 重置商机状态组类别自增ID
Db::query("ALTER TABLE ".$prefix."crm_business_type AUTO_INCREMENT = 1");
# 删除商机状态数据
Db::name('crm_business_status')->where(['type_id' => ['gt', 1]])->delete();
# 重置商机状态自增ID
Db::query("ALTER TABLE ".$prefix."crm_business_status AUTO_INCREMENT = 1");
# 删除商机数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_business");
# ------ 重置商机数据 END ------ #
# ------ 重置联系人数据 START ------ #
# 获取联系人附件ID
$contactsFileIds = Db::name('crm_contacts_file')->column('file_id');
# 查询联系人文件数据
$contactsFileInfo = $this->getFileList($contactsFileIds);
# 合并附件数据
$files = array_merge($files, $contactsFileInfo);
# 清除联系人附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_contacts_file");
# 删除联系人附件
Db::name('admin_file')->whereIn('file_id', $contactsFileIds)->delete();
# 清除联系人商机关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_contacts_business");
# 清除联系人数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_contacts");
# ------ 重置联系人数据 END ------ #
# ------ 重置客户数据 START ------ #
# 获取客户附件ID
$customerFileIds = Db::name('crm_customer_file')->column('file_id');
# 查询联系人文件数据
$customerFileInfo = $this->getFileList($customerFileIds);
# 合并附件数据
$files = array_merge($files, $customerFileInfo);
# 清除客户附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_customer_file");
# 删除客户附件
Db::name('admin_file')->whereIn('file_id', $customerFileIds)->delete();
# 清除客户数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_customer");
# ------ 重置客户数据 END ------ #
# ------ 重置线索数据 START ------ #
# 获取线索附件ID
$leadsFileIds = Db::name('crm_leads_file')->column('file_id');
# 查询线索文件数据
$leadsFileInfo = $this->getFileList($leadsFileIds);
# 合并附件数据
$files = array_merge($files, $leadsFileInfo);
# 清除线索附件关联数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_leads_file");
# 删除线索附件
Db::name('admin_file')->whereIn('file_id', $leadsFileIds)->delete();
# 清除线索数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_leads");
# ------ 重置线索数据 END ------ #
# ------ 重置附件表自增ID START ------ #
Db::query("ALTER TABLE ".$prefix."admin_file AUTO_INCREMENT = 1");
# ------ 重置附件表自增ID END ------ #
# ------ 清除活动记录中关于客户管理模块的数据 START ------ #
# 获取活动附件ID
$activityFileIds = Db::name('crm_activity_file')->column('file_id');
# 查询活动附件数据
$activityFileInfo = $this->getFileList($activityFileIds);
# 合并附件数据
$files = array_merge($files, $activityFileInfo);
# 清除活动关联附件数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_activity_file");
# 清除活动数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."crm_activity");
# ------ 清除活动记录中关于客户管理模块的数据 END ------ #
# ------ 清除我的关注数据 START ------ #
Db::query("TRUNCATE TABLE ".$prefix."crm_star");
# ------ 清除我的关注数据 END ------ #
# ------ 清除数据操作日志数据 START ------ #
Db::name('admin_operation_log')->where(['module' => ['like', 'crm_%']])->delete();
# ------ 清除数据操作日志数据 END ------ #
# ------ 清除模板打印记录数据 START ------ #
Db::query("TRUNCATE TABLE ".$prefix."crm_customer_config");
# ------ 清除模板打印记录数据 END ------ #
# ------ 清除模板打印记录数据 START ------ #
Db::query("TRUNCATE TABLE ".$prefix."crm_printing_record");
# ------ 清除模板打印记录数据 END ------ #
# ------ 清除导入数据记录表 START ------ #
Db::name('admin_import_record')->where(['type' => ['like', 'crm_%']])->delete();
# ------ 清除导入数据记录表 END ------ #
# ------ 清除字段操作记录表 START ------ #
Db::name('admin_action_record')->where(['types' => ['like', 'crm_%']])->delete();
# ------ 清除字段操作记录表 END ------ #
# ------ 清除数据操作记录表 START ------ #
Db::name('admin_action_log')->where('module_name', 'crm')->delete();
# ------ 清除数据操作记录表 END ------ #
# ------ 清除有关客户模块的审批记录 START ------ #
Db::name('admin_examine_record')->where(['types' => ['like', 'crm_%']])->delete();
# ------ 清除有关客户模块的审批记录 END ------ #
# ------ 清除跟客户模块有关的管理数据表 START ------ #
# 清除项目关联客户模块表并重置字段ID
Db::query("TRUNCATE TABLE ".$prefix."work_relation");
# 清除任务关联客户模块表并重置字段ID
Db::query("TRUNCATE TABLE ".$prefix."task_relation");
# 清除日志关联客户模块表并重置字段ID
Db::query("TRUNCATE TABLE ".$prefix."oa_log_relation");
# 清除审批关联客户模块表并重置字段ID
Db::query("TRUNCATE TABLE ".$prefix."oa_examine_relation");
# 清除日程关联客户模块表并重置字段ID
Db::query("TRUNCATE TABLE ".$prefix."oa_event_relation");
# ------ 清除跟客户模块有关的管理数据表 END ------ #
# ------ 删除审批记录 START ------ #
Db::name('admin_examine_record')->whereLike('types', 'crm%')->delete();
Db::query("ALTER TABLE ".$prefix."admin_examine_record AUTO_INCREMENT = 1");
# ------ 删除审批记录 END ------ #
# ------ 清除消息数据 START ------ #
Db::name('admin_message')->where('module_name', 'crm')->delete();
# ------ 清除消息数据 END ------ #
# ------ 删除附件 START ------ #
if (!empty($files)) {
foreach ($files AS $key => $value) {
unlink($value);
}
}
# ------ 删除附件 START ------ #
# 提交事务
Db::commit();
return true;
} catch (Exception $e) {
# 回滚事务
Db::rollback();
# 将状态设置为false终止其他方法的操作
$this->status = false;
$this->log = '重置客户管理模块时出错!';
return false;
}
}
/**
* 重置任务审批数据
*/
private function resetTaskExamineData()
{
# 表前缀
$prefix = config('database.prefix');
# 文件数组
$files = [];
# 启动事务
Db::startTrans();
try {
# ------ 清除任务数据 START ------ #
// # 获取任务ID
// $taskIds = Db::name('task')->where(['work_id' => ['eq', 0]])->column('task_id');
//
// # 获取任务下关联的附件ID
// $taskFieldIds = Db::name('work_task_file')->whereIn('task_id', $taskIds)->column('file_id');
//
// # 查询活动附件数据
// $taskFileInfo = $this->getFileList($taskFieldIds);
//
// # 合并附件数据
// $files = array_merge($files, $taskFileInfo);
//
// # 删除任务附件关联表
// Db::name('work_task_file')->whereIn('task_id', $taskIds)->delete();
// # 重置自增ID
// Db::query("ALTER TABLE ".$prefix."work_task_file AUTO_INCREMENT = 1");
//
// # 删除附件
// Db::name('admin_file')->whereIn('file_id', $taskFieldIds)->delete();
//
// # 清除任务关联的客户模块数据数据并重置自增ID
// Db::query("TRUNCATE TABLE ".$prefix."task_relation");
//
// # 删除任务log
// Db::name('work_task_log')->whereIn('task_id', $taskIds)->delete();
// # 重置任务log自增ID
// Db::query("ALTER TABLE ".$prefix."work_task_log AUTO_INCREMENT = 1");
//
// # 删除任务
// Db::name('task')->where(['work_id' => ['eq', 0]])->delete();
// # 重置任务自增ID
// Db::query("ALTER TABLE ".$prefix."task AUTO_INCREMENT = 1");
# ------ 清除任务数据 END ------ #
# ------ 清除审批数据 START ------ #
# 获取审批下关联的附件ID
$examineFileIds = Db::name('oa_examine_file')->column('file_id');
# 查询审批附件数据
$examineFileInfo = $this->getFileList($examineFileIds);
# 合并附件数据
$files = array_merge($files, $examineFileInfo);
# 清除审批关联的附件信息并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."oa_examine_file");
# 获取差旅附件ID
$travelFileId = Db::name('oa_examine_travel_file')->column('file_id');
# 查询差旅附件数据
$travelFileInfo = $this->getFileList($travelFileId);
# 合并附件数据
$files = array_merge($files, $travelFileInfo);
# 清除差旅关联的附件信息并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."oa_examine_travel_file");
# 删除差率和审批的附件
Db::name('admin_file')->whereIn('file_id', $examineFileIds)->delete();
Db::name('admin_file')->whereIn('file_id', $travelFileId)->delete();
# 删除差旅数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."oa_examine_travel");
# 删除审批关联的客户模块下的数据并重置ID
Db::query("TRUNCATE TABLE ".$prefix."oa_examine_relation");
# 删除审批数据并重置自增ID
Db::query("TRUNCATE TABLE ".$prefix."oa_examine");
# ------ 清除审批数据 END ------ #
# ------ 清除活动中有关审批的数据 START ------ #
# 获取有关审批的活动ID
$activityIds = Db::name('crm_activity')->where('activity_type', 9)->column('activity_id');
# 获取有关审批的附件ID
$activityFileIds = Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->column('file_id');
# 查询审批附件数据
$activityFileInfo = $this->getFileList($activityFileIds);
# 合并附件数据
$files = array_merge($files, $activityFileInfo);
# 删除有关审批的附件关联记录
Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity_file AUTO_INCREMENT = 1");
# 删除有关审批的活动记录
Db::name('crm_activity')->where('activity_type', 9)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity AUTO_INCREMENT = 1");
# ------ 清除活动中有关审批的数据 END ------ #
# ------ 清除有关审批的数据操作记录 START ------ #
Db::name('admin_action_log')->where('module_name', 'oa')->where('controller_name', 'examine')->delete();
Db::query("ALTER TABLE ".$prefix."admin_action_log AUTO_INCREMENT = 1");
# ------ 清除活动中有关审批的数据 END ------ #
# ------ 清除有关任务的数据操作记录 START ------ #
// Db::name('admin_action_log')->where('module_name', 'oa')->where('controller_name', 'task')->delete();
// Db::query("ALTER TABLE ".$prefix."admin_action_log AUTO_INCREMENT = 1");
# ------ 清除有关任务的数据操作记录 END ------ #
# ------ 清除审批日志 START ------ #
Db::name('admin_examine_record')->where('types', 'oa_examine')->delete();
Db::query("ALTER TABLE ".$prefix."admin_examine_record AUTO_INCREMENT = 1");
# ------ 清除审批日志 END ------ #
# ------ 清除任务和审批操作记录 START ------ #
// Db::name('admin_operation_log')->where('module', 'oa_task')->delete();
Db::name('admin_operation_log')->where('module', 'oa_examine')->delete();
Db::query("ALTER TABLE ".$prefix."admin_operation_log AUTO_INCREMENT = 1");
# ------ 清除任务操作记录 END ------ #
# ------ 清除消息数据 START ------ #
Db::name('admin_message')->where('module_name', 'oa')->where('controller_name', 'examine')->delete();
# ------ 清除消息数据 END ------ #
# ------ 重置附件表自增ID START ------ #
Db::query("ALTER TABLE ".$prefix."admin_file AUTO_INCREMENT = 1");
# ------ 重置附件表自增ID END ------ #
# ------ 删除附件 START ------ #
if (!empty($files)) {
foreach ($files AS $key => $value) {
unlink($value);
}
}
# ------ 删除附件 START ------ #
# 提交事务
Db::commit();
return true;
} catch (Exception $e) {
# 回滚事务
Db::rollback();
# 将状态设置为false终止其他方法的操作
$this->status = false;
$this->log = '重置任务/审批模块时出错!';
return false;
}
}
/**
* 重置日志数据
*/
private function resetDailyRecordData()
{
# 表前缀
$prefix = config('database.prefix');
# 文件数组
$files = [];
# 启动事务
Db::startTrans();
try {
# ------ 清除日志数据 START ------ #
# 获取日志附件ID
$logFileIds = Db::name('oa_log_file')->column('file_id');
# 查询活动附件数据
$logFileInfo = $this->getFileList($logFileIds);
# 合并附件数据
$files = array_merge($files, $logFileInfo);
# 清除日志附件关联数据
Db::query("TRUNCATE TABLE ".$prefix."oa_log_file");
# 清除日志客户管理关联数据
Db::query("TRUNCATE TABLE ".$prefix."oa_log_relation");
# 清楚日志数据
Db::query("TRUNCATE TABLE ".$prefix."oa_log");
# ------ 清除日志数据 START ------ #
# ------ 清除活动中有关审批的数据 START ------ #
# 获取有关日志的活动ID
$activityIds = Db::name('crm_activity')->where('activity_type', 8)->column('activity_id');
# 获取有关日志的附件ID
$activityFileIds = Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->column('file_id');
# 查询日志附件数据
$activityFileInfo = $this->getFileList($activityFileIds);
# 合并附件数据
$files = array_merge($files, $activityFileInfo);
# 删除有关日志的附件关联记录
Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity_file AUTO_INCREMENT = 1");
# 删除有关日志的活动记录
Db::name('crm_activity')->where('activity_type', 8)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity AUTO_INCREMENT = 1");
# ------ 清除活动中有关审批的数据 END ------ #
# ------ 清除日志操作记录表 START ------ #
Db::name('admin_action_log')->where('module_name', 'oa')->where('controller_name', 'log')->delete();
Db::query("ALTER TABLE ".$prefix."admin_action_log AUTO_INCREMENT = 1");
# ------ 清除日志操作记录表 END ------ #
# ------ 清除日志操作记录 START ------ #
Db::name('admin_operation_log')->where('module', 'oa_log')->delete();
Db::query("ALTER TABLE ".$prefix."admin_operation_log AUTO_INCREMENT = 1");
# ------ 清除日志操作记录 END ------ #
# ------ 删除消息数据 START ------ #
Db::name('admin_comment')->where('type', 'oa_log')->delete();
Db::name('admin_message')->where('module_name', 'oa')->where('controller_name', 'log')->delete();
# ------ 删除消息数据 END ------ #
# ------ 重置附件表自增ID START ------ #
Db::query("ALTER TABLE ".$prefix."admin_file AUTO_INCREMENT = 1");
# ------ 重置附件表自增ID END ------ #
# ------ 删除附件 START ------ #
if (!empty($files)) {
foreach ($files AS $key => $value) {
unlink($value);
}
}
# ------ 删除附件 START ------ #
# 提交事务
Db::commit();
return true;
} catch (Exception $e) {
# 回滚事务
Db::rollback();
# 将状态设置为false终止其他方法的操作
$this->status = false;
$this->log = '重置日志模块时出错!';
return false;
}
}
/**
* 重置项目管理数据
*/
private function resetProjectManagementData()
{
# 表前缀
$prefix = config('database.prefix');
# 文件数组
$files = [];
# 启动事务
Db::startTrans();
try {
# ------ 清除项目管理数据 START ------ #
# 获取项目ID
// $workIds = Db::name('work')->column('work_id');
# 获取任务ID
// $taskIds = Db::name('task')->whereIn('work_id', $workIds)->column('task_id');
$taskIds = Db::name('task')->column('task_id');
# 获取关联附件ID
$workTaskFileIds = Db::name('work_task_file')->whereIn('task_id', $taskIds)->column('file_id');
# 查询项目附件数据
$workTaskFileInfo = $this->getFileList($workTaskFileIds);
# 合并附件数据
$files = array_merge($files, $workTaskFileInfo);
# 清除项目中的任务附件关联数据
Db::name('work_task_file')->whereIn('task_id', $taskIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."work_task_file AUTO_INCREMENT = 1");
# 清除标签数据
Db::query("TRUNCATE TABLE ".$prefix."work_task_lable");
# 清除任务日志
Db::name('work_task_log')->whereIn('task_id', $taskIds)->delete();
# 重置任务日志自增ID
Db::query("ALTER TABLE ".$prefix."work_task_log AUTO_INCREMENT = 1");
# 清除项目成员
Db::query("TRUNCATE TABLE ".$prefix."work_user");
# 清除任务分类
Db::query("TRUNCATE TABLE ".$prefix."work_task_class");
# 清除任务与客户模块的管理数据
Db::query("TRUNCATE TABLE ".$prefix."work_relation");
# 清除任务数据
Db::query("TRUNCATE TABLE ".$prefix."task");
// Db::name('task')->where('work_id', '<>', 0)->delete();
// # 重置自增ID
// Db::query("ALTER TABLE ".$prefix."task AUTO_INCREMENT = 1");
# 清除项目数据
Db::query("TRUNCATE TABLE ".$prefix."work");
# ------ 清除项目管理数据 END ------ #
# ------ 清除活动中有关任务的数据 START ------ #
# 获取有关任务的活动ID
$activityIds = Db::name('crm_activity')->where('activity_type', 11)->whereIn('activity_type_id', $taskIds)->column('activity_id');
# 获取有关任务的附件ID
$activityFileIds = Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->column('file_id');
# 查询任务附件数据
$activityFileInfo = $this->getFileList($activityFileIds);
# 合并附件数据
$files = array_merge($files, $activityFileInfo);
# 删除有关任务的附件关联记录
Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity_file AUTO_INCREMENT = 1");
# 删除有关任务的活动记录
Db::name('crm_activity')->where('activity_type', 11)->whereIn('activity_type_id', $taskIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity AUTO_INCREMENT = 1");
# ------ 清除活动中有关任务的数据 END ------ #
# ------ 清除有关项目的数据操作记录 START ------ #
Db::name('admin_action_log')->where('module_name', 'work')->delete();
Db::query("ALTER TABLE ".$prefix."admin_action_log AUTO_INCREMENT = 1");
# ------ 清除有关项目的数据操作记录 END ------ #
# ------ 清除项目操作记录 START ------ #
Db::name('admin_operation_log')->where('module', 'work_task')->delete();
Db::query("ALTER TABLE ".$prefix."admin_operation_log AUTO_INCREMENT = 1");
# ------ 清除项目操作记录 END ------ #
# ------ 清除评论和消息数据 START ------#
Db::name('admin_comment')->where('type', 'task')->delete();
Db::name('admin_message')->where('module_name', 'work')->delete();
Db::name('admin_message')->where('module_name', 'oa')->where('controller_name', 'task')->delete();
# ------ 清除评论和消息数据 END ------ #
# ------ 重置附件表自增ID START ------ #
Db::query("ALTER TABLE ".$prefix."admin_file AUTO_INCREMENT = 1");
# ------ 重置附件表自增ID END ------ #
# ------ 删除附件 START ------ #
if (!empty($files)) {
foreach ($files AS $key => $value) {
unlink($value);
}
}
# ------ 删除附件 START ------ #
# 提交事务
Db::commit();
return true;
} catch (Exception $e) {
# 回滚事务
Db::rollback();
# 将状态设置为false终止其他方法的操作
$this->status = false;
$this->log = '重置项目管理模块时出错!';
return false;
}
}
/**
* 重置日历数据
*/
private function resetCalendarData()
{
# 表前缀
$prefix = config('database.prefix');
# 文件数组
$files = [];
# 启动事务
Db::startTrans();
try {
# ------ 清除日历数据 START ------ #
# 获取日历ID
$eventIds = Db::name('oa_event')->column('event_id');
# 删除日历关联的客户数据
Db::query("TRUNCATE TABLE ".$prefix."oa_event_relation");
# 删除日历的数据操作记录
Db::name('admin_action_log')->where('module_name', 'oa')->where('controller_name', 'event')->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."admin_action_log AUTO_INCREMENT = 1");
# 删除日历的字段操作记录
Db::name('admin_action_record')->where('types', 'oa_event')->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."admin_action_record AUTO_INCREMENT = 1");
# 删除日历提醒
Db::query("TRUNCATE TABLE ".$prefix."oa_event_notice");
# 删除日历数据
Db::query("TRUNCATE TABLE ".$prefix."oa_event");
# ------ 清除日历数据 END ------ #
# ------ 删除活动数据 START ------ #
# 获取活动ID
$activityIds = Db::name('crm_activity')->where('activity_type', 10)->whereIn('activity_type_id', $eventIds)->column('activity_id');
# 获取有关任务的附件ID
$activityFileIds = Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->column('file_id');
# 查询任务附件数据
$activityFileInfo = $this->getFileList($activityFileIds);
# 合并附件数据
$files = array_merge($files, $activityFileInfo);
# 删除有关任务的附件关联记录
Db::name('crm_activity_file')->whereIn('activity_id', $activityIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity_file AUTO_INCREMENT = 1");
# 删除有关任务的活动记录
Db::name('crm_activity')->where('activity_type', 10)->whereIn('activity_type_id', $eventIds)->delete();
# 重置自增ID
Db::query("ALTER TABLE ".$prefix."crm_activity AUTO_INCREMENT = 1");
# ------ 删除活动数据 END ------ #
# ------ 删除消息数据 START ------ #
Db::name('admin_message')->where('module_name', 'oa')->where('controller_name', 'event')->delete();
# ------ 删除消息数据 END ------ #
# ------ 重置附件表自增ID START ------ #
Db::query("ALTER TABLE ".$prefix."admin_file AUTO_INCREMENT = 1");
# ------ 重置附件表自增ID END ------ #
# ------ 删除附件 START ------ #
if (!empty($files)) {
foreach ($files AS $key => $value) {
unlink($value);
}
}
# ------ 删除附件 START ------ #
# 提交事务
Db::commit();
return true;
} catch (Exception $e) {
# 回滚事务
Db::rollback();
# 将状态设置为false终止其他方法的操作
$this->status = false;
$this->log = '重置日历模块时出错!';
return false;
}
}
/**
* 获取文件列表
*
* @param $fileIds
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getFileList($fileIds)
{
$result = [];
$list = Db::name('admin_file')->field([
'file_path',
'file_path_thumb'
])->whereIn('file_id', $fileIds)->select();
foreach ($list AS $key => $value) {
if (!empty($value['file_path'])) $result[] = 'public/uploads/' . $value['file_path'];
if (!empty($value['file_path_thumb'])) $result[] = 'public/uploads/' . $value['file_path_thumb'];
}
return $result;
}
}

@ -0,0 +1,218 @@
<?php
/**
* 日志逻辑类
*
* @author qifan
* @date 2020-11-30
*/
namespace app\admin\logic;
use app\admin\model\LoginRecord;
use app\admin\model\OperationLog;
use app\admin\model\SystemLog;
class LogLogic
{
/**
* 数据操作日志中的模块对应的中文名称
*
* @var string[]
*/
public $recordModules = [
'crm_leads' => '线索',
'crm_customer' => '客户',
'crm_pool' => '客户公海',
'crm_contacts' => '联系人',
'crm_product' => '产品',
'crm_business' => '商机',
'crm_contract' => '合同',
'crm_receivables' => '回款',
'crm_visit' => '回访',
'crm_invoice' => '回款',
'oa_log' => '办公日志',
'oa_examine' => '办公审批',
'work_task' => '任务',
'work' => '项目',
'label' => '标签',
'calendar' => '日历'
];
public $systemModules = [
'company' => '企业首页',
'application' => '应用管理',
'structures' => '部门管理',
'employee' => '员工管理',
'role' => '角色管理',
'approval' => '审批流程管理',
'workbench' => '工作台',
'project' => '项目管理',
'customer' => '客户管理'
];
/**
* 日志记录中的行为所对应的中文名称
*
* @var string[]
*/
private $action = [
'index' => '查看数据',
'save' => '添加数据',
'update' => '编辑数据',
'delete' => '删除数据'
];
private $loginType = [
'成功', '密码错误', '账号禁用'
];
/**
* 登录日志
*
* @param $param
* @return array
* @throws \think\exception\DbException
*/
public function getLoginRecord($param)
{
$loginRecordModel = new LoginRecord();
$limit = !empty($param['limit']) ? $param['limit'] : 15;
$data = $loginRecordModel->where(function ($query) use ($param) {
if (!empty($param['startTime'])) $query->where('create_time', '>=', strtotime($param['startTime']));
if (!empty($param['endTime'])) $query->where('create_time', '<=', strtotime($param['endTime']));
if (!empty($param['userIds'])) $query->whereIn('create_user_id', $param['userIds']);
})->order('id', 'desc')->paginate($limit)->each(function ($value) {
$value['username'] = $value->create_user_info['realname'];
$value['type'] = $this->loginType[$value['type']];
})->toArray();
return ['list' => $data['data'], 'count' => $data['total']];
}
/**
* 获取系统操作日志列表
*
* @param $param 查询条件、分页参数
* @return bool|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getSystemLogs($param)
{
$data = SystemLog::with(['toAdminUser'])
->where(function ($query) use ($param) {
if (!empty($param['startTime'])) $query->where('create_time', '>=', strtotime($param['startTime']));
if (!empty($param['endTime'])) $query->where('create_time', '<=', strtotime($param['endTime']));
if (!empty($param['modules'])) $query->whereIn('modules', $param['modules']);
if (!empty($param['userIds'])) $query->whereIn('user_id', $param['userIds']);
})->limit(($param['page'] - 1) * $param['limit'])->order('log_id', 'desc')->select();
return $this->setSystemData($data);
}
/**
* 获取系统操作日志总数
*
* @param $param 查询条件、分页参数
* @return int|string|null
*/
public function getSystemLogCount($param)
{
return SystemLog::where(function ($query) use ($param) {
if (!empty($param['startTime'])) $query->where('create_time', '>=', strtotime($param['startTime']));
if (!empty($param['endTime'])) $query->where('create_time', '<=', strtotime($param['endTime']));
if (!empty($param['modules'])) $query->whereIn('controller_name', $param['modules']);
if (!empty($param['userIds'])) $query->whereIn('user_id', $param['userIds']);
})->count();
}
/**
* 获取数据操作日志列表
*
* @param $param 查询条件、分页参数
* @return bool|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getRecordLogs($param)
{
$data = OperationLog::with(['toAdminUser'])
->where(function ($query) use ($param) {
if (!empty($param['startTime'])) $query->where('create_time', '>=', strtotime($param['startTime']));
if (!empty($param['endTime'])) $query->where('create_time', '<=', strtotime($param['endTime']));
if (!empty($param['modules'])) $query->whereIn('module', $param['modules']);
if (!empty($param['userIds'])) $query->whereIn('user_id', $param['userIds']);
})
->limit(($param['page'] - 1) * $param['limit'])->order('log_id', 'desc')->select();
return $this->setRecordData($data);
}
/**
* 获取数据操作日志总数
*
* @param $param 查询条件、分页参数
* @return int|string|null
*/
public function getRecordLogCount($param)
{
return OperationLog::where(function ($query) use ($param) {
if (!empty($param['startTime'])) $query->where('create_time', '>=', strtotime($param['startTime']));
if (!empty($param['endTime'])) $query->where('create_time', '<=', strtotime($param['endTime']));
if (!empty($param['modules'])) $query->whereIn('module', $param['module']);
if (!empty($param['userIds'])) $query->whereIn('user_id', $param['userIds']);
})->count();
}
/**
* 组装数据操作日志数据
*
* @param $data
* @return mixed
*/
private function setRecordData($data)
{
$result = [];
foreach ($data AS $key => $value) {
$result[] = [
'log_id' => $value['log_id'],
'source_name' => $value['source_name'],
'create_time' => date('Y-m-d H:i:s', $value['create_time']),
'ip' => $value['client_ip'],
'module' => $this->recordModules[$value['module']],
'content' => $value['content']
];
}
return $result;
}
/**
* 组装数据操作日志数据
*
* @param $data
* @return mixed
*/
private function setSystemData($data)
{
$result = [];
foreach ($data AS $key => $value) {
$result[] = [
'log_id' => $value['log_id'],
'source_name' => $value['source_name'],
'create_time' => date('Y-m-d H:i:s', $value['create_time']),
'ip' => $value['client_ip'],
'module' => $this->systemModules[$value['module']],
'content' => $value['content']
];
}
return $result;
}
}

@ -0,0 +1,282 @@
<?php
namespace app\admin\logic;
use think\Db;
class MessageLogic
{
private function label($label)
{
$where = '';
switch ($label) {
case '1': //任务
$where = array('in', [1, 2, 3]);//
break;
case '2': //日志
$where = array('in', [4, 5]);//27项目导入
break;
case '3': //办公审批
$where = array('in', [6, 7, 8]);
break;
case '4': //公告
$where = array('eq', 9);
break;
case '5' : //日程
$where = 10;
break;
case '6' : //客户管理
$where = array('in', [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 16, 27, 28, 29, 30]);
break;
case '4' :
break;
default:
$where = array('in', [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 16, 27, 28, 29, 30]);//17181920
}
return $where;
}
public function getDataList($param)
{
$userId = $param['user_id'];
unset($param['user_id']);
//types 1表示已读 0表示未读
if (isset($param['is_read'])) {
$where['m.read_time'] = ['=', 0];
}
$where['m.to_user_id'] = $userId;
$where['m.is_delete'] = ['eq', 1];
$order = [
'm.send_time' => 'DESC',
];
$where['m.type'] = $this->label($param['label']);
if ($param['label'] == 4) {
$where['m.type'] = 9;
$list = db('admin_message')
->alias('m')
->join('__ADMIN_USER__ user', 'user.id=m.from_user_id', 'LEFT')
->where($where)
->field('m.*,user.realname as user_name')
->page($param['page'], $param['limit'])
->order($order)
->select();
$dataCount = db('admin_message')
->alias('m')
->join('__ADMIN_USER__ user', 'user.id=m.from_user_id', 'LEFT')
->where($where)->count();
} else {
$list = db('admin_message')
->alias('m')
->join('__ADMIN_USER__ user', 'user.id=m.from_user_id', 'LEFT')
->where($where)
->field('m.*,user.realname as user_name')
->page($param['page'], $param['limit'])
->order($order)
->select();
}
$dataCount = db('admin_message')
->alias('m')
->join('__ADMIN_USER__ user', 'user.id=m.from_user_id', 'LEFT')
->where($where)->count();
//1表示已读 0表示未读
foreach ($list as $k => $v) {
if ($v['read_time'] == 0) {
$list[$k]['is_read'] = 0;
} else {
$list[$k]['is_read'] = 1;
}
$list[$k]['create_time'] = date('Y-m-d H:i:s', $v['send_time']);
if ($v['type'] == 4) {
$content = db('admin_comment')
->where(
[ 'status' => 1,
'comment_id' => $v['action_id'],
'type' => ['like', '%' . $v['controller_name' . '%']],
'user_id' => $v['from_user_id']
])
->find();
if (!empty($content)) {
$list[$k]['content'] = $content['content'];
}
} elseif (in_array($v['type'], ['12', '15'])) {
$content = db('admin_examine_record')->where(['types_id' => $v['action_id'], 'types' => ['like', '%' . $v['controller_name' . '%']], 'check_user_id' => $v['from_user_id']])->field('content')->find();
if ($content['content']) {
$list[$k]['content'] = $content['content'];
}
}
if ($v['type'] == 10) {
$item = db('oa_event_notice')->where('id', $v['action_id'])->find();
if ($item) {
$noticetype = $item['noticetype'];
if($item['noticetype'] == 1){
$advance_time =$v['advance_time'] - ($item['number'] * 60);
}elseif ($item['noticetype'] == 2){
$advance_time =$v['advance_time'] - ($item['number'] * 60 * 60);
}else{
$advance_time = $v['advance_time'] - ($item['number'] * 60 * 60 * 24);
}
$time = time();
if ($time == $advance_time ||$time>$advance_time) {
$type['value']=$item['number'];
$type['type']=$item['noticetype'];
$list[$k]['content']= $type;
$list[$k]['action_id'] = $item['event_id'];
}
}
// p(222);
}
if (in_array($v['type'], ['17', '18', '19', '20', '27'])) {
$error_file_path = db('admin_import_record')->where('id', $v['action_id'])->find();
if($error_file_path['error_data_file_path']==''){
$list[$k]['title'] = '';
}
$list[$k]['error_file_path'] = $error_file_path['error_data_file_path'];
}
}
$data = [];
$data['page']['list'] = $list;
$data['page']['dataCount'] = $dataCount ?: 0;
if ($param['page'] != 1 && ($param['page'] * $param['limit']) >= $dataCount) {
$data['page']['firstPage'] = false;
$data['page']['lastPage'] = true;
} else if ($param['page'] != 1 && (int)($param['page'] * $param['limit']) < $dataCount) {
$data['page']['firstPage'] = false;
$data['page']['lastPage'] = false;
} else if ($param['page'] == 1) {
$data['page']['firstPage'] = true;
$data['page']['lastPage'] = false;
}
return $data;
}
/**
* 修改状态变为已读
* @param $param
* @return array
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function endMessage($param)
{
$where = [
'to_user_id' => $param['id'],
'message_id' => ['IN', (array)$param['message_id']],
'read_time' => 0,
];
$list = db('admin_message')
->where($where)
->update(['read_time' => time()]);
$data = [];
$data['list'] = $list;
return $data;
}
/**
* 删除
*
* @param $messageId
* @return array|int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function delete($param)
{
$res = db('admin_message')->where(['message_id' => $param['message_id']])->find();
if ($res['to_user_id'] != $param['user_id']) {
return resultArray(['error' => '没有权限!']);
}
return db('admin_message')->where(['message_id' => $param['message_id']])->update(['is_delete' => 2]);
}
/**
* 批量更新
* @param $param
* @return array
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function readAllMessage($param)
{
$where = [
'to_user_id' => $param['user_id'],
'read_time' => 0
];
if ($param['label'] == 4) {
$list = db('admin_message')
->where('type', 9)
->where($where)
->update(['read_time' => time()]);
} else {
$where['type'] = $this->label($param['label']);
$list = db('admin_message')
->where($where)
->update(['read_time' => time()]);
}
$data = [];
$data['list'] = $list;
return $data;
}
/**
* 批量删除已读
* @param $param
* @return array
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function clear($param)
{
$where = [];
$where = [
'to_user_id' => $param['user_id'],
'is_delete' => 1,
'read_time' => ['neq', 0],
];
$where['type'] = $this->label($param['label']);
$list = db('admin_message')
->where($where)
->update(['is_delete' => 2]);
$data = [];
$data['list'] = $list;
return $data;
}
public function unreadCount($param)
{
$userId = $param['user_id'];
//types 1表示已读 0表示未读
$where['read_time'] = ['=', 0];
$label = '';
$where['to_user_id'] = ['eq', $userId];
$where['is_delete'] = ['eq', 1];
$where['type'] = $this->label('');
$allCount = db('admin_message')->where($where)->count();
$where['type'] = $this->label(1);
$taskCount = db('admin_message')->where($where)->count();
$where['type'] = $this->label(2);
$logCount = db('admin_message')->where($where)->count();
$where['type'] = $this->label(3);
$jxcCount = db('admin_message')->where($where)->count();
$where['type'] = 9;
$announceCount = db('admin_message')->where($where)->count();
$where['type'] = $this->label(5);
$eventCount = db('admin_message')->where($where)->where('advance_time', '>=', time())->count();
$where['type'] = $this->label(6);
$crmCount = db('admin_message')->where($where)->count();
$data = [];
$data['allCount'] = $allCount ?: 0;
$data['taskCount'] = $taskCount ?: 0;
$data['logCount'] = $logCount ?: 0;
$data['examineCount'] = $jxcCount ?: 0;
$data['announceCount'] = $announceCount ?: 0;
$data['eventCount'] = $eventCount ?: 0;
$data['crmCount'] = $crmCount ?: 0;
return $data;
}
}

@ -0,0 +1,377 @@
<?php
/**
* 打印设置逻辑类
*
* @author qifan
* @date 2020-12-03
*/
namespace app\admin\logic;
use app\admin\controller\ApiCommon;
use think\Db;
class PrintingLogic
{
/**
* 打印模板列表
*
* @param $page
* @param $limit
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function index($page, $limit)
{
$result = [];
$type = [1 => '商机', 2 => '合同', 3 => '回款'];
$field = ['id', 'name', 'type', 'user_name', 'create_time', 'update_time'];
$count = Db::name('admin_printing')->count();
$data = Db::name('admin_printing')->field($field)->order('id', 'desc')->limit(($page - 1) * $limit, $limit)->select();
foreach ($data AS $key => $value) {
$result[] = [
'id' => $value['id'],
'name' => $value['name'],
'type' => $value['type'],
'type_name' => !empty($type[$value['type']]) ? $type[$value['type']] : '',
'create_time' => date('Y-m-d H:i:s', $value['create_time']),
'user_name' => $value['user_name'],
'update_time' => date('Y-m-d H:i:s', $value['update_time'])
];
}
return ['count' => $count, 'list' => $result];
}
/**
* 创建打印模板
*
* @param $param
* @return int|string
*/
public function create($param)
{
$apiCommon = new ApiCommon();
$userId = $apiCommon->userInfo['id'];
$userName = Db::name('admin_user')->where('id', $userId)->value('realname');
$data = [
'user_id' => $userId,
'user_name' => $userName,
'name' => $param['name'],
'type' => $param['type'],
'content' => htmlspecialchars($param['content']),
'create_time' => time(),
'update_time' => time()
];
return Db::name('admin_printing')->insert($data);
}
/**
* 获取模板详情
*
* @param $id
* @return array
*/
public function read($id)
{
$content = Db::name('admin_printing')->where('id', $id)->value('content');
return ['id' => $id, 'content' => htmlspecialchars_decode($content)];
}
/**
* 更新模板数据
*
* @param $param
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function update($param)
{
if (!empty($param['content'])) $param['content'] = htmlspecialchars($param['content']);
return Db::name('admin_printing')->update($param);
}
/**
* 删除模板数据
*
* @param $id
* @return int
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function delete($id)
{
return Db::name('admin_printing')->where('id', $id)->delete();
}
/**
* 复制模板数据
*
* @param $id
* @return false|int|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function copy($id)
{
$apiCommon = new ApiCommon();
$info = Db::name('admin_printing')->where('id', $id)->find();
if (!empty($info['id'])) {
$userId = $apiCommon->userInfo['id'];
$userName = Db::name('admin_user')->where('id', $userId)->value('realname');
$data = [
'user_id' => $userId,
'user_name' => $userName,
'name' => strlen($info['name']) > 25 ? $info['name'] : $info['name'] . rand(111, 999),
'type' => $info['type'],
'content' => $info['content'],
'update_time' => time(),
'create_time' => time()
];
return Db::name('admin_printing')->insert($data);
}
return false;
}
/**
* 获取打印模板需要的字段
*
* @param $type 1商机2合同3回款
* @return array[]
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getFields($type)
{
$result = [];
switch ($type) {
case 1:
$result['business'] = $this->getBusinessFields();
$result['customer'] = $this->getCustomerFields();
$result['product'] = $this->getProductFields();
break;
case 2:
$result['contract'] = $this->getContractFields();
$result['customer'] = $this->getCustomerFields();
$result['contacts'] = $this->getContactsFields();
$result['product'] = $this->getProductFields();
break;
case 3:
$result['receivables'] = $this->getReceivablesFields();
$result['contract'] = $this->getContractFields();
break;
default:
$result['business'] = $this->getBusinessFields();
$result['customer'] = $this->getCustomerFields();
$result['product'] = $this->getProductFields();
$result['contract'] = $this->getContractFields();
$result['contacts'] = $this->getContactsFields();
$result['receivables'] = $this->getReceivablesFields();
}
return $result;
}
/**
* 获取商机字段
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getBusinessFields()
{
$result = [];
$businessList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_business')->select();
# 处理自定义字段
foreach ($businessList AS $key => $value) {
if ($value['field'] == 'customer_id') continue;
$result[] = [
'name' => $value['name'],
'field' => $value['field']
];
}
# 处理固定字段
$result[] = ['name' => '负责人', 'field' => 'owner_user_id'];
$result[] = ['name' => '创建人', 'field' => 'create_user_id'];
$result[] = ['name' => '创建日期', 'field' => 'create_time'];
$result[] = ['name' => '更新日期', 'field' => 'update_time'];
return $result;
}
/**
* 获取客户字段
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getCustomerFields()
{
$result = [];
$customerList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_customer')->select();
# 处理自定义字段
foreach ($customerList AS $key => $value) {
if (in_array($value['field'], ['next_time', 'remark'])) continue;
$result[] = [
'name' => $value['name'],
'field' => $value['field']
];
}
return $result;
}
/**
* 获取产品字段
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getProductFields()
{
$result = [];
$productList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_product')->select();
# 处理自定义字段
foreach ($productList AS $key => $value) {
if ($value['field'] == 'status') continue;
$result[] = [
'name' => $value['name'],
'field' => $value['field']
];
}
# 处理固定字段
$result[] = ['name' => '售价', 'field' => 'sales_price'];
$result[] = ['name' => '数量', 'field' => 'count'];
$result[] = ['name' => '折扣', 'field' => 'discount'];
$result[] = ['name' => '整单折扣', 'field' => 'discount_rate'];
$result[] = ['name' => '合计', 'field' => 'subtotal'];
return $result;
}
/**
* 获取合同字段
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getContractFields()
{
$result = [];
$contractList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_contract')->select();
# 处理自定义字段
foreach ($contractList AS $key => $value) {
$result[] = [
'name' => $value['name'],
'field' => $value['field']
];
}
# 处理固定字段
$result[] = ['name' => '负责人', 'field' => 'owner_user_id'];
$result[] = ['name' => '创建人', 'field' => 'create_user_id'];
$result[] = ['name' => '创建日期', 'field' => 'create_time'];
$result[] = ['name' => '更新日期', 'field' => 'update_time'];
$result[] = ['name' => '已收款金额', 'field' => 'received'];
$result[] = ['name' => '未收款金额', 'field' => 'uncollected'];
return $result;
}
/**
* 获取联系人字段
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getContactsFields()
{
$result = [];
$contactsList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_contacts')->select();
# 处理自定义字段
foreach ($contactsList AS $key => $value) {
if ($value['field'] == 'next_time') continue;
$result[] = [
'name' => $value['name'],
'field' => $value['field']
];
}
return $result;
}
/**
* 获取回款字段
*
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getReceivablesFields()
{
$result = [];
$receivablesList = Db::name('admin_field')->field(['name', 'field'])->where('types', 'crm_receivables')->select();
# 处理自定义字段
foreach ($receivablesList AS $key => $value) {
$result[] = [
'name' => $value['name'],
'field' => $value['field']
];
}
# 处理固定字段
$result[] = ['name' => '负责人', 'field' => 'owner_user_id'];
$result[] = ['name' => '创建人', 'field' => 'create_user_id'];
$result[] = ['name' => '创建日期', 'field' => 'create_time'];
$result[] = ['name' => '更新日期', 'field' => 'update_time'];
return $result;
}
}

@ -0,0 +1,114 @@
<?php
/**
* 项目管理逻辑类
*
* @author qifan
* @date 2020-12-17
*/
namespace app\admin\logic;
use think\Db;
class WorkLogic
{
/**
* 规则列表
*
* @return bool|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getRules()
{
return Db::name('admin_rule')->field(['id', 'title', 'name'])->where(['types' => 3, 'level' => 4, 'status' => 0])->select();
}
/**
* 获取角色
*
* @return bool|\PDOStatement|string|\think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getRoles()
{
$data = Db::name('admin_group')->field(['id', 'title', 'rules', 'remark', 'system'])->where(['pid' => 5, 'types' => 7, 'status' => 1])->select();
foreach ($data AS $key => $value) {
$data[$key]['rules'] = explode(',', trim($value['rules'], ','));
}
return $data;
}
/**
* 创建角色
*
* @param $param
* @return int|string
*/
public function saveRole($param)
{
# 设置参数
$param['pid'] = 5;
$param['status'] = 1;
$param['type'] = 0;
$param['types'] = 7;
$param['system'] = 0;
return Db::name('admin_group')->insert($param);
}
/**
* 权限角色详情
*
* @param $id
* @return array|bool|\PDOStatement|string|\think\Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function readRole($id)
{
$data = Db::name('admin_group')->field(['id', 'title', 'rules', 'remark'])->where('id', $id)->find();
$data['rules'] = trim($data['rules'], ',');
return $data;
}
/**
* 编辑权限角色
*
* @param $param
* @return int|string
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function updateRole($param)
{
return Db::name('admin_group')->update($param);
}
/**
* 删除权限角色
*
* @param $id
* @return array|bool[]
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function deleteRole($id)
{
$system = Db::name('admin_group')->where('id', $id)->value('system');
if (!empty($system)) return ['status' => false, 'error' => '不允许删除系统默认角色!'];
if (!Db::name('admin_group')->where('id', $id)->delete()) return ['status' => false, 'error' => '操作失败!'];
return ['status' => true];
}
}

@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | Description: 角色员工关系
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
use think\Db;
class Access extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_access';
/**
* [getDataList 获取列表]
* @return [array]
*/
public function userGroup($user_id, $groups, $action = '')
{
if (!$user_id) {
$this->error = '参数错误';
return false;
}
$this->startTrans();
try {
if ($action == 'update') {
$this->where('user_id', $user_id)->delete();
}
foreach ($groups as $k => $v) {
if (!db('admin_access')->where(['user_id' => $user_id,'group_id' => $v])->find()) {
$userGroup['user_id'] = $user_id;
$userGroup['group_id'] = $v;
$userGroups[] = $userGroup;
}
}
$this->saveAll($userGroups);
$this->commit();
return true;
} catch(\Exception $e) {
$this->rollback();
$this->error = '编辑失败';
return false;
}
}
}

@ -0,0 +1,111 @@
<?php
// +----------------------------------------------------------------------
// | Description: 字段修改记录
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
class ActionRecord extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_action_record';
public $typesArr = ['crm_leads','crm_customer','crm_contacts','crm_product','crm_business','crm_contract','crm_receivables','crm_visit'];
/**
* [getDataList 获取列表]
* @return [array]
*/
public function getDataList($request)
{
$types = trim($request['types']);
$action_id = intval($request['action_id']);
//判断权限
if (!$this->checkData($types, $action_id, $request['user_id'])) {
return [];
}
$dataList = db('admin_action_record')->where(['types' => $types,'action_id' => $action_id])->order('id','desc')->select();
if($types == 'crm_customer') {
$leads_id = db('crm_leads')->where(['customer_id' => $action_id, 'is_transform' => 1])->value('leads_id');
if($leads_id){
$leads_dataList = db('admin_action_record')->where(['types' => 'crm_leads','action_id' => $leads_id])->order('id','desc')->select();
$dataList = array_merge($leads_dataList, $dataList);
}
}
$userModel = model('User');
foreach ($dataList as $k=>$v) {
$dataList[$k]['user_id_info'] = isset($v['user_id']) ? $userModel->getUserById($v['user_id']) : [];
$dataList[$k]['content'] = explode('.|.', $v['content']);
}
return $dataList;
}
/**
* [checkData 权限判断]
* @return [array]
*/
public function checkData($types, $action_id, $user_id)
{
if (!in_array($types, $this->typesArr)) {
return false;
}
if (!$action_id) {
return false;
}
$adminTypes = adminGroupTypes($user_id);
if (in_array(1,$adminTypes)) {
return true;
}
$checkRes = false;
switch ($types) {
case 'crm_leads' :
$checkRes = checkPerByAction('crm', 'leads', 'read');
break;
case 'crm_customer' :
$checkRes = checkPerByAction('crm', 'customer', 'read');
break;
case 'crm_contacts' :
$checkRes = checkPerByAction('crm', 'contacts', 'read');
break;
case 'crm_product' :
$checkRes = checkPerByAction('crm', 'product', 'read');
break;
case 'crm_business' :
$checkRes = checkPerByAction('crm', 'business', 'read');
break;
case 'crm_contract' :
$checkRes = checkPerByAction('crm', 'contract', 'read');
break;
case 'crm_receivables' :
$checkRes = checkPerByAction('crm', 'receivables', 'read');
break;
case 'crm_visit' :
$checkRes = checkPerByAction('crm', 'visit', 'read');
break;
}
if ($checkRes !== false) {
return true;
}
}
/**
* 删除字段修改记录
* @param
* @return
*/
public function delDataById($request)
{
$types = trim($request['types']);
$action_id = $request['action_id'];
if ($types && $action_id) {
$res = db('admin_action_record')->where(['types' => $types,'action_id' => ['in',$action_id]])->delete();
}
}
}

@ -0,0 +1,91 @@
<?php
// +----------------------------------------------------------------------
// | Description: 系统基础公共
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\controller\ApiCommon;
use app\admin\model\Common;
use think\Db;
class Admin extends Common
{
/**
* 统计筛选条件
* @param $merge 1 user,structure 合并查询0 user_id 优先级高 $is_last 昨天、上周、、、
* @param $perUserIds 权限范围
* @return
* @author Michael_xu
*/
public function getWhere($param, $merge = '', $perUserIds = [], $filter = true, $is_last = false)
{
$apiCommon = new ApiCommon();
$userModel = new \app\admin\model\User();
$user_id = $apiCommon->userInfo['id'];
$structure_id = $apiCommon->userInfo['structure_id'];
//员工IDS
$user_ids = [];
if ($param['userId']) {
$user_ids = array($param['userId']);
}
if ($param['deptId']) {
$userModel->getSubUserByStr($param['deptId'], 2);
}
if ($param['dataType']) {
switch ($param['dataType']) {
case 1 : $user_ids = [$user_id];
break;
case 2 : $user_ids = getSubUserId(true, 0, $apiCommon->userInfo['id']);
break;
case 3 : $user_ids = $userModel->getSubUserByStr($structure_id, 1);
break;
case 4 : $user_ids = $userModel->getSubUserByStr($structure_id, 2);
break;
default : $user_ids = [$user_id];
break;
}
} else {
if ($merge == 1) {
if ($param['structure_id']) {
$str_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2);
}
//合并
if ($user_ids && $str_user_ids) {
$user_ids = array_unique(array_merge($user_ids, $str_user_ids));
} elseif ($str_user_ids) {
$user_ids = $str_user_ids;
}
} else {
if (!$user_ids) {
if ($param['structure_id']) {
$user_ids = $userModel->getSubUserByStr($param['structure_id'], 2);
}
}
}
if (!$user_ids) $user_ids = getSubUserId(true);
}
$perUserIds = $perUserIds ? : getSubUserId(); //权限范围内userIds
$userIds = [];
if ($user_ids) {
$userIds = $perUserIds ? array_intersect($user_ids, $perUserIds) : $perUserIds; //数组交集
}
$where['userIds'] = array_map('intval', $userIds);
if ($param['type']) {
$between_time = getTimeByType($param['type'], $is_last);
} else {
//自定义时间
if ($param['start_time']) {
$between_time = array(strtotime($param['start_time']), strtotime($param['end_time']));
}
//自定义时间
if ($param['startTime']) {
$between_time = array(strtotime($param['startTime']), strtotime($param['endTime']));
}
}
$where['between_time'] = $between_time;
return $where ?: [];
}
}

@ -0,0 +1,173 @@
<?php
// +----------------------------------------------------------------------
// | Description: 评论
// +----------------------------------------------------------------------
// | Author: yykun
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use think\Model;
use app\admin\model\Common;
use com\verify\HonrayVerify;
use think\Cache;
class Comment extends Model
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如微信模块用weixin作为数据表前缀
*/
protected $name = 'admin_comment';
protected $createTime = 'create_time';
protected $autoWriteTimestamp = true;
protected $insert = [
'status' => 1,
];
/**
* 根据ID查看评论
* @author Michael_xu
* @param
* @return
*/
public function read($param)
{
$userModel = new \app\admin\model\User();
$map['comment.type'] = $param['type'] ? : ''; //默认评论类型
$map['comment.type_id'] = $param['type_id'];
$map['comment.isreply'] = 0;
$list = Db::name('AdminComment')
->alias('comment')
->join('admin_user u','u.id=comment.user_id')
->field('comment.*,u.username,u.realname,u.thumb_img')
->where($map)
->select();
foreach ($list as $key => $value) {
$list[$key]['userInfo']['id'] = $value['user_id'];
$list[$key]['userInfo']['username'] = $value['username'];
$list[$key]['userInfo']['realname'] = $value['realname'];
$list[$key]['create_time'] = date('Y-m-d H:i:s',$value['create_time']);
$list[$key]['userInfo']['thumb_img'] = $value['thumb_img'] ? getFullPath($value['thumb_img']) : '';
$list[$key]['replyuserInfo'] = $userModel->getUserById($value['reply_user_id']);
$replyList = [];
$replyList = Db::name('AdminComment')->where(['reply_fid' => $value['comment_id']])->select();
foreach ($replyList as $k=>$v) {
$replyList[$k]['userInfo'] = $userModel->getUserById($v['user_id']);
$replyList[$k]['replyuserInfo'] = $userModel->getUserById($v['reply_user_id']);
}
$list[$key]['childCommentList'] = $replyList ? : array();
}
return $list;
}
/**
* 获取回复
* @author Michael_xu
* @param
* @return
*/
function commentList($parent_id = 0,&$result = array())
{
$list = $this->where(['status' => 1,'reply_id' => $parent_id])->order("create_time desc")->select();
if ($list) {
foreach ($list as $cm) {
$thisArr =& $result[];
$cm["children"] = $this->commentList($cm["comment_id"],$thisArr);
$thisArr = $cm;
}
}
return $result ? : [];
}
/**
* 新建评论
* @author Michael_xu
* @param
* @return
*/
public function createData($param)
{
$commentInfo = [];
if (!empty($param['comment_id'])) $commentInfo = Db::name('admin_comment')->where('comment_id', $param['comment_id'])->find();
$param['reply_content'] = !empty($commentInfo['content']) ? $commentInfo['content'] : ''; //内容拼接保存
$param['isreply'] = $param['comment_id'] ? 1 : 0; //是否是回复评论
$param['reply_id'] = $param['comment_id'] ? $param['comment_id'] : 0; //回复消息id
$param['reply_fid'] = !empty($param['main_id']) ? $param['main_id'] : 0; //回复最上级ID
$param['reply_user_id'] = !empty($commentInfo['user_id']) ? $commentInfo['user_id'] : 0; //回复别人ID
$param['status'] = 1;
unset($param['main_id']);
unset($param['comment_id']);
//print_r($param);exit;
// $param['reply_content'] = $param['reply_content'] ? : ''; //内容拼接保存
// $param['isreply'] = $param['reply_comment_id'] ? 1 : 0; //是否是回复评论
// $param['reply_id'] = $param['reply_comment_id'] ? $param['reply_comment_id'] : 0; //回复消息id
// $param['reply_fid'] = $param['reply_fid'] ? : ''; //回复最上级ID
// $param['reply_user_id'] = $param['reply_user_id'] ? : ''; //回复别人ID
// $param['status'] = 1;
if ($this->data($param)->allowField(true)->save()) {
$userModel = new \app\admin\model\User();
$userInfo = $userModel->getUserById($param['user_id']);
//发送站内信
switch ($param['type']) {
case 'task' :
$taskInfo = db('task')->where(['task_id' => $param['type_id']])->field('name,create_user_id,main_user_id,owner_user_id')->find();
$user_ids[] = $taskInfo['create_user_id'];
if ($taskInfo['main_user_id']) {
$user_ids = array_merge($user_ids,array($taskInfo['main_user_id']));
}
if (stringToArray($taskInfo['owner_user_id'])) {
$user_ids = array_merge($user_ids,stringToArray($taskInfo['owner_user_id']));
}
$user_ids = array_filter(array_unique($user_ids));
$sendContent = $userInfo['realname'].',评论了任务《'.$taskInfo['name'].'》:'.$param['content'];
break;
}
if ($user_ids && $sendContent) {
$resMessage = sendMessage($user_ids, $sendContent, $param['type_id'], 1);
}
return Db::name('AdminComment')->where('comment_id',$this->comment_id)->find();
} else {
$this->error = '回复失败';
return false;
}
}
/**
* 删除评论
* @author Michael_xu
* @param
* @return
*/
public function delDataById($param)
{
if ($param['comment_id']) {
$flag = $this->where(['comment_id' => $param['comment_id']])->delete();
} else {
$flag = $this->where(['type' => $param['type'],'type_id' => $param['type_id']])->delete();
}
if (!$flag){
$this->error = '不存在或已删除';
return false;
}
return true;
}
/**
* 获取评论数
* @author Michael_xu
* @param
* @return
*/
public function getCount($type,$type_id)
{
$count = 0;
if ($type && $type_id) {
$count = $this->where(['type' => $type,'type_id' => $type_id])->count();
}
return $count;
}
}

@ -0,0 +1,336 @@
<?php
// +----------------------------------------------------------------------
// | Description: 公共模型,所有模型都可继承此模型基于RESTFUL CRUD操作
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Model;
use think\Request;
class Common extends Model
{
/**
* [Request 请求参数]
* @Michael_xu
* @return [array]
*/
protected function requestData()
{
$m = strtolower(request()->module());
$c = strtolower(request()->controller());
$a = strtolower(request()->action());
$ret = [
'm' => $m,
'c' => $c,
'a' => $a
];
return $ret;
}
/**
* [fmtRequest 格式化请求参数]
* @Michael_xu
* @param [array] $request [参数]
* @return [array]
*/
public function fmtRequest( $request = [] )
{
$pageType = $request['pageType'] ? 'all' : ''; //all全部不分页
$page = 1;
if (isset($request['page']) && is_numeric($request['page']) ) {
$page = $request['page'];
unset($request['page']);
}
$limit = 15;
if (isset($request['limit']) && is_numeric($request['limit']) ) {
$limit = $request['limit'];
unset($request['limit']);
}
$offset = $length = null;
if ($pageType == 'all') {
$page = 1;
$limit = 0;
unset($request['pageType']);
} else {
// 大数据处理-滚动加载-子分页
if ($request['sub_page'] && $request['sub_limit']) {
$sub_page = $request['sub_page'];
$sub_limit = $request['sub_limit'];
unset($request['sub_page']);
unset($request['sub_limit']);
$offset = ($page - 1) * $limit + ($sub_page - 1) * $sub_limit;
if ($sub_limit * $sub_page > $limit) {
$length = ($page - 1) * $limit + $limit - $offset;
} else {
$length = $sub_limit;
}
if ($length < 0) {
$offset = $length = 0;
}
}
}
if (!isset($offset) || !isset($length)) {
$offset = ($page - 1) * $limit;
$length = $limit;
}
$ret = [
'page' => $page,
'limit' => $limit,
'map' => $request,
'offset' => $offset,
'length' => $length,
];
return $ret;
}
/**
* [getDataById 根据主键获取详情]
* @param string $id [主键]
* @return [array]
*/
public function getDataById($id = '')
{
$data = $this->get($id);
if (!$data) {
$this->error = '暂无此数据';
return false;
}
return $data;
}
/**
* [createData 新建]
* @param array $param [description]
* @return [array] [description]
*/
public function createData($param)
{
// 验证
$validate = validate($this->name);
if (!$validate->check($param)) {
$this->error = $validate->getError();
return false;
}
try {
$this->data($param)->allowField(true)->save();
return true;
} catch(\Exception $e) {
$this->error = '添加失败';
return false;
}
}
/**
* [updateDataById 编辑]
* @param [type] $param [description]
* @param [type] $id [description]
* @return [type] [description]
*/
public function updateDataById($param, $id)
{
$checkData = $this->get($id);
if (!$checkData) {
$this->error = '暂无此数据';
return false;
}
// 验证
$validate = validate($this->name);
if (!$validate->scene('edit')->check($param)) {
$this->error = $validate->getError();
return false;
}
try {
$this->allowField(true)->save($param, [$this->getPk() => $id]);
return true;
} catch(\Exception $e) {
$this->error = '编辑失败';
return false;
}
}
/**
* [delDataById 根据id删除数据]
* @param string $id [主键]
* @param boolean $delSon [是否删除子孙数据]
* @return [type] [description]
*/
public function delDataById($id = '', $delSon = false)
{
if (!$id) {
$this->error = '删除失败';
return false;
}
$this->startTrans();
try {
$this->where($this->getPk(), $id)->delete();
if ($delSon && is_numeric($id)) {
// 删除子孙
$childIds = $this->getAllChild($id);
if($childIds){
$this->where($this->getPk(), 'in', $childIds)->delete();
}
}
$this->commit();
return true;
} catch(\Exception $e) {
$this->error = '删除失败';
$this->rollback();
return false;
}
}
/**
* [delDatas 批量删除数据]
* @param array $ids [主键数组]
* @param boolean $delSon [是否删除子孙数据]
* @return [type] [description]
*/
public function delDatas($ids = [], $delSon = false)
{
if (empty($ids)) {
$this->error = '删除失败';
return false;
}
// 查找所有子元素
if ($delSon) {
foreach ($ids as $k => $v) {
if (!is_numeric($v)) continue;
$childIds = $this->getAllChild($v);
$ids = array_merge($ids, $childIds);
}
$ids = array_unique($ids);
}
try {
$this->where($this->getPk(), 'in', $ids)->delete();
return true;
} catch (\Exception $e) {
$this->error = '操作失败';
return false;
}
}
/**
* [enableDatas 批量启用、禁用]
* @param string $ids [主键数组]
* @param integer $status [状态1启用0禁用]
* @param [boolean] $delSon [是否删除子孙数组]
* @return [type] [description]
*/
public function enableDatas($ids = [], $status = 1, $delSon = false)
{
if (empty($ids)) {
$this->error = '参数错误';
return false;
}
// 查找所有子元素
if ($delSon && $status === '0') {
foreach ($ids as $k => $v) {
$childIds = $this->getAllChild($v);
$ids = array_merge($ids, $childIds);
}
$ids = array_unique($ids);
}
try {
$this->where($this->getPk(),'in',$ids)->setField('status', $status);
return true;
} catch (\Exception $e) {
$this->error = '操作失败';
return false;
}
}
/**
* 获取所有子孙
*/
public function getAllChild($id, &$data = [])
{
$map['pid'] = $id;
$childIds = $this->where($map)->column($this->getPk());
if (!empty($childIds)) {
foreach ($childIds as $v) {
$data[] = $v;
$this->getAllChild($v, $data);
}
}
return $data;
}
/**
* 逻辑删除,将数据标记为删除状态
* @author Michael_xu
*/
public function signDelById($id)
{
if (!$id) {
$this->error = '删除失败';
return false;
}
$this->startTrans();
try {
$data['is_deleted'] = 1;
$data['delete_time'] = time();
$this->allowField(true)->save($data, [$this->getPk() => $id]);
$this->commit();
return true;
} catch(\Exception $e) {
$this->error = '删除失败';
$this->rollback();
return false;
}
}
/**
* 导出数据处理
*/
public function exportHandle($list, $field_list, $type = '')
{
foreach ($list as &$val) {
foreach ($field_list as $field) {
switch ($field['form_type']) {
case 'user':
if (isset($val[$field['field'] . '_info']['realname'])) {
$val[$field['field']] = $val[$field['field'] . '_info']['realname'];
} else {
$val[$field['field']] = implode(',', array_column($val[$field['field'] . '_info'], 'realname'));
}
break;
case 'structure':
$temp = array_map(function ($val) { return $val->toarray(); }, $val[$field['field'] . '_info']);
$val[$field['field']] = implode(',', array_column($temp, 'name'));
break;
case 'datetime':
$val[$field['field']] = strtotime($val[$field['field']]) ? $val[$field['field']] : date('Y-m-d H:i:s', $val[$field['field']]);
break;
case 'customer':
case 'business':
case 'contacts':
$val[$field['field']] = $val[$field['field'] . '_info']['name'];
break;
case 'contacts':
$val[$field['field']] = $val[$field['field'] . '_info']['name'];
break;
default :
switch ($field['field']) {
// 商机销售阶段、商机状态组
case 'status_id':
case 'type_id':
$val[$field['field']] = $val[$field['field'] . '_info'];
break;
}
}
}
}
return $list;
}
}

@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | Description: 应用配置
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
use think\Db;
class Config extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_config';
/**
* [getDataList 获取列表]
* @return [array]
*/
public function getDataList()
{
$list = Db::name('AdminConfig')->order('type asc')->select();
return $list;
}
/**
* 编辑
* @author Michael_xu
* @return
*/
public function updateDataById($param, $id)
{
$data = [];
$data['status'] = $param['status'] ? : '0';
if ($this->where(['id' => $id])->update($data)) {
return true;
}
$this->error = '操作失败';
return false;
}
}

@ -0,0 +1,269 @@
<?php
// +----------------------------------------------------------------------
// | Description: 审批流程
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
class ExamineFlow extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_examine_flow';
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $autoWriteTimestamp = true;
protected $typesArr = ['crm_contract', 'crm_receivables', 'crm_invoice', 'oa_examine'];
/**
* [getDataList 审批流程list]
* @author Michael_xu
* @param [string] $map [查询条件]
* @param [number] $page [当前页数]
* @param [number] $limit [每页数量]
* @return [array] [description]
*/
public function getDataList($request)
{
$userModel = new \app\admin\model\User();
$structureModel = new \app\admin\model\Structure();
$examineStepModel = new \app\admin\model\ExamineStep();
$request = $this->fmtRequest( $request );
$map = $request['map'] ? : [];
if (isset($map['search'])) {
//普通筛选
$map['name'] = ['like', '%'.$map['search'].'%'];
unset($map['search']);
}
$map['is_deleted'] = 0;
$list_view = db('admin_examine_flow')
->where($map)
->alias('examine_flow')
->join('__ADMIN_USER__ user', 'user.id = examine_flow.update_user_id', 'LEFT');
$list = $list_view
->page($request['page'], $request['limit'])
->field('examine_flow.*,user.realname,user.thumb_img')
->order('examine_flow.update_time', 'desc')
->select();
foreach ($list as $k=>$v) {
$list[$k]['user_ids_info'] = $userModel->getListByStr($v['user_ids']);
$list[$k]['structure_ids_info'] = $structureModel->getListByStr($v['structure_ids']);
$stepList = [];
$stepList = $examineStepModel->getDataList($v['flow_id']);
$list[$k]['stepList'] = $stepList ? : [];
$list[$k]['create_time'] = !empty($v['create_time']) ? date('Y-m-d H:i:s', $v['create_time']) : null;
$list[$k]['update_time'] = !empty($v['update_time']) ? date('Y-m-d H:i:s', $v['update_time']) : null;
}
$dataCount = $list_view->where($map)->count('flow_id');
$data = [];
$data['list'] = $list;
$data['dataCount'] = $dataCount ? : 0;
return $data;
}
/**
* 创建审批流程信息
* @author Michael_xu
* @param
* @return
*/
public function createData($param)
{
//验证
if (!$param['name']) {
$this->error = '请填写审批流名称1';
return false;
}
if ($this->data($param)->allowField(true)->save()) {
$data = [];
$data['flow_id'] = $this->flow_id;
return $data;
} else {
$this->error = '添加失败';
return false;
}
}
/**
* 编辑审批流程信息
* @author Michael_xu
* @param
* @return
*/
public function updateDataById($param, $flow_id = '')
{
unset($param['flow_id']);
$dataInfo = $this->get($flow_id);
if (!$dataInfo) {
$this->error = '数据不存在或已删除';
return false;
}
//过滤不能修改的字段
$unUpdateField = ['create_user_id','is_deleted','delete_time'];
foreach ($unUpdateField as $v) {
unset($param[$v]);
}
//验证
if (!$param['name']) {
$this->error = '请填写审批流名称';
return false;
}
// $param['flow_id'] = $flow_id;
if ($this->allowField(true)->save($param)) {
$data = [];
$data['flow_id'] = $flow_id;
return $data;
} else {
$this->error = '编辑失败,请重试';
return false;
}
}
/**
* 审批流程详情
* @author Michael_xu
* @param
* @return
*/
public function getDataById($flow_id = '')
{
$userModel = new \app\admin\model\User();
$dataInfo = $this->get($flow_id);
if (!$dataInfo) {
$this->error = '数据不存在或已删除';
return false;
}
//审批步骤
$stepList = db('admin_examine_step')->where(['flow_id' => $flow_id])->select();
foreach ($stepList as $k=>$v) {
$examine_user_id_arr = [];
switch ($v['status']) {
case 2 :
case 3 : $examine_user_id_arr = stringToArray($v['user_id']); break;
default : $examine_user_id_arr = []; break;
}
$stepList[$k]['user_id_info'] = $userModel->getUserByIdArr($examine_user_id_arr);
}
$dataInfo['stepList'] = $stepList ? : [];
return $dataInfo;
}
/**
* 审批流程(根据对象获取需要执行的审批流程)
* @param types 审批对象
* @param types_id 审批对象ID(如OA审批类型ID)
*/
public function getFlowByTypes($user_id, $types, $types_id = 0)
{
$userModel = new \app\admin\model\User();
if (!in_array($types, $this->typesArr)) {
$this->error = '参数错误';
return false;
}
$map['types'] = $types;
$map['status'] = 1;
$map['is_deleted'] = 0;
if ($types !== 'oa_examine') {
$types_id = 0;
}
$map['types_id'] = $types_id;
//判断用户使用哪个流程(优先级:所属部门 > 全部)
$userData = $userModel->getUserById($user_id);
$userData['map'] = $map;
$flowInfo = db('admin_examine_flow')
->where(function ($query) use ($userData) {
$userData = $userData;
$query->where(['config' => 1])
->where($userData['map'])
->where(function ($query) use ($userData) {
$query->where('structure_ids','like','%,'.$userData['structure_id'].',%')
->whereOr('user_ids','like','%,'.$userData['id'].',%');
});
})->whereOr(function ($query) use ($userData) {
$query->where(['config' => 1])
->where($userData['map'])
->where('structure_ids','eq','')
->where('user_ids','eq','');
})->whereOr(function ($query) use ($userData) {
$query->where(['config' => 0])
->where($userData['map']);
})->order('update_time desc')->find();
return $flowInfo ? : [];
}
/**
* 审批流程权限(创建操作使用)
* @param types 审批对象
* @param user_id 审批对象申请人ID
* @param category_id 审批类型ID或其他类型ID
*/
public function checkExamine($user_id, $types, $category_id = 0)
{
$examineStepModel = new \app\admin\model\ExamineStep();
//符合条件的审批流
$resFlow = $this->getFlowByTypes($user_id, $types, $category_id);
if (!$resFlow) {
return false;
}
if ($resFlow['config'] == 1) {
//审批流是否为空
$stepList = $examineStepModel->getStepList($resFlow['flow_id'], $user_id, $types);
if (!$stepList) {
return false;
}
}
return $resFlow;
}
/**
* 审批流程下所有审批人ID
* @param
* @return
*/
public function getUserByFlow($flow_id, $user_id, $check_user_id = '')
{
$flowInfo = db('admin_examine_flow')->where(['flow_id' => $flow_id])->find();
$userIds = [];
if ($flowInfo['config'] == 1) {
$stepList = db('admin_examine_step')->where(['flow_id' => $flow_id])->select();
foreach ($stepList as $k=>$v) {
if ($v['status'] == 1) {
$userInfo = db('admin_user')->where(['id' => $user_id])->find();
if ($userInfo['parent_id']) {
$userIds[] = $userInfo['parent_id'];
} else {
$userIds[] = 1;
}
}
if (stringToArray($v['user_id'])) $userIds = $userIds ? array_merge($userIds, stringToArray($v['user_id'])) : stringToArray($v['user_id']);
}
} else {
$userIds = [];
$check_user_id = stringToArray($check_user_id);
//查询已审批人ID未失效的
$is_check_user_id = db('admin_examine_record')->where(['flow_id' => $flow_id,'is_end' => 0])->column('check_user_id');
if ($check_user_id && $is_check_user_id) {
$userIds = array_merge($check_user_id, $is_check_user_id);
} elseif ($check_user_id) {
$userIds = $check_user_id;
} else {
$userIds = $is_check_user_id;
}
}
return $userIds ? : [];
}
}

@ -0,0 +1,113 @@
<?php
// +----------------------------------------------------------------------
// | Description: 审批意见
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
class ExamineRecord extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_examine_record';
/**
* 审批意见(创建)
* @param types 关联对象
* @param types_id 联对象ID
* @param flow_id 审批流程ID
* @param step_id 审批步骤ID
* @param user_id 审批人ID
* @param status 1通过0驳回
* @return
*/
public function createData($param)
{
if ($this->data($param)->allowField(true)->save()) {
$data = [];
$data['record_id'] = $this->record_id;
return $data;
} else {
$this->error = '添加失败';
return false;
}
}
/**
* 审批意见(列表)
* @param types 关联对象
* @param types_id 联对象ID
* @return
*/
public function getDataList($param)
{
$userModel = new \app\admin\model\User();
if (empty($param['types']) || empty($param['types_id'])) {
return [];
}
$result = [];
# 获取创建者信息
if (in_array($param['types'], ['crm_contract', 'crm_receivables', 'crm_invoice']) && !empty($param['is_record'])) {
$model = db($param['types']);
$primaryKey = null;
if ($param['types'] == 'crm_contract') $primaryKey = 'contract_id';
if ($param['types'] == 'crm_receivables') $primaryKey = 'receivables_id';
if ($param['types'] == 'crm_invoice') $primaryKey = 'invoice_id';
$info = $model->field(['create_time', 'owner_user_id'])->where($primaryKey, $param['types_id'])->find();
$userInfo = $userModel->getUserById($info['owner_user_id']);
$result[] = [
'check_date' => date('Y-m-d H:i:s', $info['create_time']),
'check_time' => $info['create_time'],
'check_user_id' => $info['owner_user_id'],
'check_user_id_info' => $userInfo,
'content' => '',
'flow_id' => 0,
'is_end' => 0,
'order_id' => 0,
'record_id' => 0,
'status' => 3,
'types' => $param['types'],
'types_id' => $param['types_id']
];
}
unset($param['is_record']);
$list = db('admin_examine_record')->where($param)->order('check_time asc')->select();
foreach ($list as $k=>$v) {
$list[$k]['check_user_id_info'] = $userModel->getUserById($v['check_user_id']);
$list[$k]['check_date'] = date('Y-m-d H:i:s', $v['check_time']);
$result[] = $list[$k];
}
return !empty($result) ? $result : [];
}
/**
* 审批意见(标记无效,撤销审批时使用)
* @param types 关联对象
* @param types_id 关联对象ID
* @return
*/
public function setEnd($param)
{
if (empty($param['types']) || empty($param['types_id'])) {
$this->error = '参数错误';
return false;
}
$res = $this->where(['types' => $param['types'],'types_id' => $param['types_id']])->update(['is_end' => 1]);
return true;
}
}

@ -0,0 +1,495 @@
<?php
// +----------------------------------------------------------------------
// | Description: 审批步骤
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
class ExamineStep extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_examine_step';
/**
* 获取有效审批步骤列表
* @param flow_id 审批流程ID
* @param user_id 审批申请人ID
* @return
*/
public function getDataList($flow_id)
{
$userModel = new \app\admin\model\User();
$list = $this->where(['flow_id' => $flow_id])->order('order_id asc')->select();
foreach ($list as $k=>$v) {
$list[$k]['user_id_info'] = $userModel->getListByStr($v['user_id']);
}
return $list ? : [];
}
/**
* 审批步骤(创建、编辑)
* @param flow_id 审批流程ID
* @param status 1负责人主管2指定用户任意一人3指定用户多人会签4上一级审批人主管
* @return
*/
public function createStepData($data, $flow_id)
{
if (!intval($flow_id)) {
$this->error = '审批流程创建失败';
return false;
}
//处理数据
$resSuccess = true;
$dataStep = [];
foreach ($data as $k=>$v) {
if (!intval($v['status']) || (in_array($v['status'],[2,3]) && !$v['user_id'])) {
$resSuccess = false;
}
$dataStep[$k]['relation'] = 1;
if (in_array($v['status'],[2,3])) {
$dataStep[$k]['user_id'] = $v['user_id'] ? arrayToString($v['user_id']) : ''; //处理user_id
$dataStep[$k]['relation'] = ($v['status'] == 3) ? 1 : 2;
}
if ($v['step']) {
$dataStep[$k]['step_id'] = $v['step'];
}
$dataStep[$k]['order_id'] = $k+1;
$dataStep[$k]['flow_id'] = $flow_id;
$dataStep[$k]['status'] = $v['status'];
$dataStep[$k]['create_time'] = time();
}
if ($resSuccess) {
//提交事务
$this->startTrans();
try {
$this->where(['flow_id' => $flow_id])->delete();
$this->saveAll($dataStep);
$this->commit();
return true;
} catch(\Exception $e) {
$this->error = '审批步骤创建失败';
$this->rollback();
return false;
}
} else {
$this->error = '参数错误';
return false;
}
}
/**
* 审批步骤(排序,防止位置情况造成排序错乱)
* @param flow_id 审批流程ID
* @return
*/
public function orderData($flow_id)
{
$step_list = db('admin_examine_step')->where(['flow_id' => $flow_id])->order('order_id')->select();
foreach ($step_list as $k=>$v) {
$data = [];
$data = ['step_id' => $v['step_id'],'order_id' => $k];
db('admin_examine_step')->update($data);
}
}
/**
* 下一审批人(审批是否结束)
* @param user_id 审批申请人ID
* @param flow_id 审批流ID
* @param types 关联对象
* @param types_id 联对象ID
* @param order_id 审批排序ID
* @param status 1负责人主管2指定用户任意一人3指定用户多人会签4上一级审批人主管
* @param check_user_id 当前审核人ID
*/
public function nextStepUser($user_id, $flow_id, $types, $types_id, $order_id, $check_user_id)
{
$res = nextCheckData($user_id, $flow_id, $types, $types_id, $order_id, $check_user_id);
return $res ? : [];
}
/**
* 审批步骤权限
* @param step_id 审批步骤ID
* @param user_id 审批人ID当前登录人
* @param create_user_id 申请人ID
* @param types 关联对象
* @param types_id 联对象ID
* @param status 1负责人主管2指定用户任意一人3指定用户多人会签4上一级审批人主管
* @return
*/
public function checkExamine($user_id, $types, $types_id)
{
$data = $this->getDataByTypes($types, $types_id);
$dataInfo = $data['dataInfo']; //审批主体信息
$stepInfo = $data['stepInfo']; //审批步骤信息
if (!$dataInfo) {
$this->error = '参数错误!';
return false;
}
if (in_array($dataInfo['check_status'], ['2','3'])) {
$this->error = '审批已经结束!';
return false;
}
if ($dataInfo['flow_id'] > 0) {
//固定流程
//当前步骤已审批user_id
$check_user_ids = $this->getUserByCheck($types, $types_id, $dataInfo['order_id']);
if (in_array($user_id, $check_user_ids)) {
$this->error = '您已审核,请勿重复操作!';
return false;
}
$examine_user_id_arr = array();
// $examine_user_id_arr = $this->getUserByStep($stepInfo['step_id'], $dataInfo['create_user_id']); //获取审批步骤审批人
$examine_user_id_arr = $dataInfo['check_user_id']; //获取审批步骤审批人
$examine_user_id_arr = stringToArray($examine_user_id_arr);
} else {
$examine_user_id_arr = $this->getUserByPer($types);
}
if (!in_array($user_id, $examine_user_id_arr)) {
$this->error = '没有权限';
return false;
}
return true;
}
/**
* 审批对象获取审批相关信息
* @param types 关联对象
* @param types_id 联对象ID
* @return
*/
public function getDataByTypes($types, $types_id)
{
if (empty($types) || empty($types_id)) {
$this->error = '参数错误';
return false;
}
switch (trim($types)) {
case 'oa_examine' : $dataInfo = db('oa_examine')->where(['examine_id' => intval($types_id)])->field('create_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
case 'crm_contract' : $dataInfo = db('crm_contract')->where(['contract_id' => intval($types_id)])->field('create_user_id,owner_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
case 'crm_receivables' : $dataInfo = db('crm_receivables')->where(['receivables_id' => intval($types_id)])->field('create_user_id,owner_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
case 'crm_invoice': $dataInfo = db('crm_invoice')->where(['invoice_id' => intval($types_id)])->field('create_user_id,owner_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
}
$stepInfo = [];
if ($dataInfo['flow_id'] && !in_array($dataInfo['check_status'],['5'])) {
//固定审批流
$stepInfo = db('admin_examine_step')->where(['flow_id' => $dataInfo['flow_id'],'order_id' => $dataInfo['order_id']])->find();
}
$data = [];
$data['stepInfo'] = $stepInfo;
$data['step_id'] = $stepInfo['step_id'] ? : '';
$data['dataInfo'] = $dataInfo;
return $data;
}
/**
* 获取审批步骤审批人信息
* @param step_id 审批步骤ID
* @param status 1负责人主管2指定用户任意一人3指定用户多人会签4上一级审批人主管
* @param user_id 审批主体申请人user_id
* @return
*/
public function getUserByStep($step_id, $user_id)
{
$stepInfo = db('admin_examine_step')->where(['step_id' => $step_id])->find();
$examine_user_id_arr = [];
//固定审批流
switch ($stepInfo['status']) {
case 1 :
$examine_user_id = db('admin_user')->where(['id' => $user_id])->value('parent_id');
if ($examine_user_id) {
$examine_user_id_arr[] = $examine_user_id;
} else {
$examine_user_id_arr[] = 1;
}
break;
case 2 :
case 3 :$examine_user_id_arr = stringToArray($stepInfo['user_id']); break;
case 4 :
$order_id = $stepInfo['order_id'] ? $stepInfo['order_id']-1 : 0;
$last_step_id = db('admin_examine_step')->where(['flow_id' => $stepInfo['flow_id'],'order_id' => $order_id])->value('step_id');
$last_step_info = db('admin_examine_step')->where(['step_id' => $last_step_id])->find();
$last_user_id = $this->getUserByStep($last_step_id, $user_id);
if (count(stringToArray($last_user_id)) !== 1) {
$this->error = '审批流程出错';
return false;
}
$last_user_id_arr = stringToArray($last_user_id);
$examine_user_id = $this->getUserByStep($last_step_id, $last_user_id_arr[0]);
//$examine_user_id = db('admin_user')->where(['id' => $last_step_info['user_id']])->value('parent_id');
$examine_user_id_arr = [];
if ($examine_user_id) {
$examine_user_id_arr = stringToArray($examine_user_id);
}
break;
default : $examine_user_id_arr = [];
}
return array_unique($examine_user_id_arr) ? ','.implode(',',array_filter(array_unique($examine_user_id_arr))).',' : '';
}
/**
* 获取当前步骤已审批的user_id
* @param step_id 审批步骤ID
* @param status 1审核通过0审核失败2撤销
* @return
*/
public function getUserByCheck($types, $types_id = 0, $order_id = 0, $status = 1)
{
if ($types_id == 0 && $order_id == 0) {
$check_user_ids = [];
} else {
$check_user_ids = db('admin_examine_record')->where(['types' => $types,'types_id' => $types_id,'order_id' => $order_id,'is_end' => 0,'status' => $status])->column('check_user_id');
}
return $check_user_ids ? : [];
}
/**
* 获取授权审批的user_id
* @param step_id 审批步骤ID
* @param
* @return
*/
public function getUserByPer($types)
{
if (!in_array($types,['oa_examine','crm_contract','crm_receivables'])) {
$this->error = '参数错误';
return false;
}
$userModel = new \app\admin\model\User();
$adminUserId = model('User')->getAdminId(); //管理员ID
//获取有审核权限的user_id
switch ($types) {
case 'oa_examine' : $examine_user_id_arr = $userModel->getUserByPer('oa', 'examine', 'check'); break;
case 'crm_contract' : $examine_user_id_arr = $userModel->getUserByPer('crm', 'contract', 'check'); break;
case 'crm_receivables' : $examine_user_id_arr = $userModel->getUserByPer('crm', 'receivables', 'check'); break;
case 'crm_invoice' : $examine_user_id_arr = $userModel->getUserByPer('crm', 'invoice', 'check'); break;
}
$examine_user_id_arr = $examine_user_id_arr ? array_merge($examine_user_id_arr, $adminUserId) : $adminUserId;
return $examine_user_id_arr;
}
/**
* 获取审批步骤相关userId
* @param flow_id 流程ID
* @param order_id 排序ID
* @return
*/
public function getStepUserByOrder($flow_id, $order_id, $user_id)
{
$user_ids = [];
if ($flow_id && $order_id) {
$stepInfo = db('admin_examine_step')->where(['flow_id' => $flow_id,'order_id' => $order_id])->find();
$user_ids = $this->getUserByStep($stepInfo['step_id'], $user_id);
}
return $user_ids ? : [];
}
/**
* 获取有效审批步骤列表(固定审批)
* @param flow_id 审批流程ID
* @param user_id 审批申请人ID
* @param check_user_id 当前操作人ID
* @return
*/
public function getStepList($flow_id, $user_id, $types, $types_id = 0, $check_user_id = 0, $action = '', $category_id = '')
{
$userModel = new \app\admin\model\User();
$newlist = [];
$dataInfo['order_id'] = 0;
if ($types_id) {
$typesInfo = $this->getDataByTypes($types, $types_id);
$dataInfo = $typesInfo['dataInfo'];
}
$is_check = 0; //审批权限(1有)
$is_recheck = 0; //撤销审批权限(1有)
$admin_user_ids = $userModel->getAdminId();
//创建人或负责人或管理员有撤销权限
//if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id || in_array($check_user_id, $admin_user_ids)) {
if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id) {
if (!in_array($dataInfo['check_status'],['2','3','4'])) {
$is_recheck = 1;
}
}
if (in_array($check_user_id, stringToArray($dataInfo['check_user_id'])) && !in_array($dataInfo['check_status'],['2','3'])) {
$is_check = 1;
}
if ($action == 'view') {
$createUserInfo = $userModel->getUserById($dataInfo['create_user_id']);
$createUserInfo['check_time'] = !empty($dataInfo['update_time']) ? date('Y-m-d H:i:s', $dataInfo['update_time']) : null;
if ($dataInfo['check_status'] == 4) {
$createUserInfo['check_type'] = 2;
$newlist[0]['type'] = '2'; //撤销
} else {
$createUserInfo['check_type'] = 3;
$newlist[0]['type'] = '3'; //创建
}
$newlist[0]['user_id_info'] = array($createUserInfo);
$newlist[0]['time'] = !empty($dataInfo['update_time']) ? date('Y-m-d H:i:s', $dataInfo['update_time']) : null;
}
$stepList = [];
if ($dataInfo['check_status'] !== 4 || $action !== 'view') {
$list = db('admin_examine_step')->where(['flow_id' => $flow_id])->order('order_id asc')->select();
$is_break = false;
foreach ($list as $k=>$v) {
$type = 4;
$examine_user_ids = '';
//判断步骤审批人是否存在
$examine_user_ids = $this->getUserByStep($v['step_id'], $user_id);
$examine_user_arr = stringToArray($examine_user_ids);
if ($examine_user_arr) {
$newStepInfo = $v;
$user_id_info_arr = [];
foreach ($examine_user_arr as $key=>$val) {
$user_id_info = [];
$user_id_info = $userModel->getUserById($val);
$check_type = 4; //type 0失败1通过2撤销3创建4待审核5未提交
//当前步骤已审批user_id
$check_user_ids = [];
$check_user_ids = $this->getUserByCheck($types, $types_id, $v['order_id'], 1);
if (in_array($val, $check_user_ids)) {
$check_type = 1;
$type = !empty($dataInfo['check_user_id']) ? 4 : 1;
}
$re_check_user_ids = $this->getUserByCheck($types, $types_id, $v['order_id'], 2); //撤销人员
if ($dataInfo['check_status'] == 4) {
if ($re_check_user_ids) {
$is_break = true;
$check_type = 2;
$type = 2;
}
}
$fail_check_user_ids = $this->getUserByCheck($types, $types_id, $v['order_id'], 0); //拒绝人员
if ($dataInfo['check_status'] == 3) {
if (in_array($val,$fail_check_user_ids)) {
$is_break = true;
$check_type = 0;
$type = 0;
}
//if ($action == 'view') break;
}
$user_id_info['check_type'] = $check_type;
$check_time = '';
$check_time = db('admin_examine_record')->where(['types' => $types,'types_id' => $types_id,'flow_id' => $flow_id,'order_id' => $v['order_id'],'check_user_id' => $val,'is_end' =>0])->value('check_time');
$user_id_info['check_time'] = !empty($check_time) ? date('Y-m-d H:i:s', $check_time) : '';
$user_id_info_arr[] = $user_id_info;
}
$newStepInfo['user_id'] = $examine_user_ids;
$newStepInfo['user_id_info'] = $user_id_info_arr;
if ($dataInfo['order_id'] > $v['order_id']) {
$type = 1;
}
//if ($is_break !== false) break;
$newStepInfo['type'] = $type;
$stepList[] = $newStepInfo;
}
}
}
$newStepList = [];
if ($newlist && $stepList) {
$newStepList = array_merge($newlist, $stepList);
} elseif ($stepList) {
$newStepList = $stepList;
} else {
$newStepList = $newlist;
}
$data['steplist'] = $newStepList ? : [];
$data['is_check'] = $is_check;
$data['is_recheck'] = $is_recheck;
return $data ? : [];
}
/**
* 根据order_id获取审批步骤
* @param flow_id 审批流程ID
* @param order_id 审批排序ID
* @return
*/
public function getStepByOrder($flow_id, $order_id)
{
$data = db('admin_examine_step')->where(['flow_id' => $flow_id,'order_id' => $order_id])->find();
return $data ? : [];
}
/**
* 获取有效审批步骤列表(自选审批)
* @param types 类型
* @param types_id 类型ID
* @param action 操作类型: view、save
* @return
*/
public function getPerStepList($types, $types_id, $user_id, $check_user_id, $action = '')
{
$examineRecordModel = new \app\admin\model\ExamineRecord();
$userModel = new \app\admin\model\User();
$userList = [];
//有效的审批记录
$where = [];
$where['types'] = $types;
$where['types_id'] = $types_id;
$where['is_end'] = 0;
$recordList = $examineRecordModel->getDataList($where);
$typeInfo = $this->getDataByTypes($types, $types_id);
$dataInfo = $typeInfo['dataInfo'];
$createUserInfo = $userModel->getUserById($dataInfo['create_user_id']);
$userList[0]['userInfo'] = $createUserInfo;
$userList[0]['type'] = 3; //创建
$userList[0]['time'] = $dataInfo['update_time'] ? : '';
//type 0失败1通过2撤销3创建4待审核5未提交
$i = 1;
foreach ($recordList as $k=>$v) {
$userList[$i]['userInfo'] = $userModel->getUserById($v['check_user_id']);
$userList[$i]['type'] = $v['status'];
$userList[$i]['time'] = $v['check_time'];
$i++;
}
if ($dataInfo['check_status'] <= 1 && $dataInfo['check_user_id']) {
$check_user_id_arr = stringToArray($dataInfo['check_user_id']);
$userList[$i]['userInfo'] = $userModel->getUserById($check_user_id_arr[0]);
$userList[$i]['type'] = '4';
}
if ($dataInfo['check_status'] == 5 && $dataInfo['check_user_id']) {
$userList = [];
$check_user_id_arr = stringToArray($dataInfo['check_user_id']);
$userList[0]['userInfo'] = $userModel->getUserById($check_user_id_arr[0]);
$userList[0]['type'] = '5';
}
$is_check = 0; //审批权限(1有)
$is_recheck = 0; //撤销审批权限(1有)
$admin_user_ids = $userModel->getAdminId();
//创建人或负责人或管理员有撤销权限
// if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id || in_array($check_user_id, $admin_user_ids)) {
if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id) {
if (!in_array($dataInfo['check_status'],['2','3','4','5'])) {
$is_recheck = 1;
}
}
if (in_array($check_user_id, stringToArray($dataInfo['check_user_id'])) && !in_array($dataInfo['check_status'],['2','3','5'])) {
$is_check = 1;
}
$data['steplist'] = $userList;
$data['is_check'] = $is_check;
$data['is_recheck'] = $is_recheck;
return $data ? : [];
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,570 @@
<?php
// +----------------------------------------------------------------------
// | Description: 附件
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
use app\crm\model\Activity;
use app\crm\model\Invoice;
use think\Db;
use think\Request;
class File extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_file';
protected $module_arr = [
'other',
'crm_leads',
'crm_customer',
'crm_contacts',
'crm_business',
'crm_product',
'crm_contract',
'oa_log',
'oa_examine',
'oa_examine_travel',
'work_task',
'admin_record',
'oa_travel',
'hrm_pact',
'hrm_file',
'crm_invoice',
'crm_activity',
'crm_visit',
'crm_receivables'
];
/**
* [createData 添加附件]
* @author Michael_xu
* @param $files 附件数组
* @param $param [module : 模块, module_id : 模块ID]
* @param $x 裁剪图的长 ,$y 裁剪图的宽
* @return [array]
*/
public function createData($files, $param = [], $x = '150', $y = '150')
{
if (empty($files)) {
$this->error = '请选择上传文件';
return false;
}
$resData = [];
$get_filesize_byte = get_upload_max_filesize_byte();
foreach ($files as $k=>$v) {
$info = '';
$upload_name = $v['obj']->getInfo()['name'];
if ($upload_name == 'blob') {
$upload_name = 'logo.png';
$new_info = [];
$new_info = $v['obj']->getInfo();
$new_info['name'] = $upload_name;
$v['obj']->setUploadInfo($new_info);
}
$info = $v['obj']->validate(['size'=>$get_filesize_byte,'ext'=>'jpg,jpeg,png,gif,zip,rar,doc,docx,xls,xlsx,ppt,pptx,txt,pdf,csv'])->move(FILE_PATH . 'public' . DS . 'uploads'); //验证规则
// getimagesize($file["tmp_name"]
if (!$info) {
$this->error = $v['obj']->getError();
return false;
//$resData[$k] = ['key' => $k,'name' => $fileInfo['name'],'status' => 0,'error' => $v['obj']->getError()];
break;
}
$fileInfo = $info->getInfo(); //附件数据
$rSuccess = false;
$ext = '';
$saveName = '';
$thumbSaveName = '';
if ($info) {
//如果是图片类型,生成缩略图
$ext = $info->getExtension();
$saveName = $info->getSaveName();
$fileName = $info->getFilename();
if (in_array($ext, ['jpg','png','jpeg']) && $fileInfo['size'] < 8388608) {
// $image = \think\Image::open($v['obj']);
$image = \think\Image::open(UPLOAD_PATH . str_replace(DS, '/', $saveName));
$thumbSaveName = str_replace(DS, DS.'thumb_', $saveName);
$image->thumb($x, $y,\think\Image::THUMB_FILLED)->save(FILE_PATH . 'public'. DS .'uploads'. DS .$thumbSaveName); //THUMB_SCALING 或 THUMB_FILLED
}
if ($ext == 'gif') {
$thumbSaveName = $saveName;
}
//附件信息存储
$saveData = [];
$saveData['name'] = $fileInfo['name'];
$saveData['size'] = $fileInfo['size'];
$saveData['create_user_id'] = $param['create_user_id'];
$saveData['create_time'] = time();
$saveData['file_path'] = UPLOAD_PATH . str_replace(DS, '/', $saveName);
$saveData['file_path_thumb'] = $thumbSaveName ? UPLOAD_PATH . str_replace(DS, '/', $thumbSaveName) : '';
$saveData['save_name'] = str_replace(DS, '/', $saveName);
$saveData['types'] = $v['types'] ? : 'file';
if ($k > 0) {
$this->data($saveData)->allowField(true)->isUpdate(false)->save();
} else {
$this->data($saveData)->allowField(true)->save();
}
$file_id = $this->file_id;
if ($file_id) {
$rSuccess = true;
//如果是关系表,则保存关系表数据
if (in_array($param['module'],$this->module_arr) && $param['module_id']) {
switch ($param['module']) {
case 'crm_leads' : $r = db('crm_leads_file'); $r_name = 'leads_id'; break;
case 'crm_customer' : $r = db('crm_customer_file'); $r_name = 'customer_id'; break;
case 'crm_contacts' : $r = db('crm_contacts_file'); $r_name = 'contacts_id'; break;
case 'crm_business' : $r = db('crm_business_file'); $r_name = 'business_id'; break;
case 'crm_product' : $r = db('crm_product_file'); $r_name = 'product_id'; break;
case 'crm_contract' : $r = db('crm_contract_file'); $r_name = 'contract_id'; break;
case 'oa_log' : $r = db('oa_log_file'); $r_name = 'log_id'; break;
case 'oa_examine' : $r = db('oa_examine_file'); $r_name = 'examine_id'; break;
case 'work_task' : $r = db('work_task_file'); $r_name = 'task_id'; break;
case 'admin_record' : $r = db('admin_record_file'); $r_name = 'record_id'; break;
case 'oa_travel' : $r = db('oa_travel_file'); $r_name = 'travel_id'; break;
case 'hrm_pact' : $r = db('hrm_pact_file'); $r_name = 'pact_id'; break;
case 'hrm_file' : $r = db('hrm_user_file'); $r_name = 'user_id'; break;
case 'crm_invoice' : $r = db('crm_invoice_file'); $r_name = 'invoice_id'; break;
case 'crm_activity': $r = db('crm_activity_file'); $r_name = 'activity_id'; break;
case 'crm_visit': $r = db('crm_visit_file'); $r_name = 'visit_id'; break;
case 'crm_receivables': $r = db('crm_receivables_file'); $r_name = 'receivables_id'; break;
default : break;
}
$rData = [];
$rData[$r_name] = intval ($param['module_id']);
$rData['file_id'] = $file_id;
$rRes = $r->insert($rData);
if (!$rRes) {
$rSuccess = false;
//删除文件
@unlink($saveData['file_path']);
@unlink($saveData['file_path_thumb']);
}
}
}
if ($rSuccess !== false) {
$path = (UPLOAD_PATH.$saveName);
# 应前端要求将url字段改成跟path一样的内容格式改为一位数组
$resData = ['key' => $k, 'name' => $fileInfo['name'], 'status' => 1, 'path' => getFullPath($path), 'save_name' => str_replace(DS, '/', $saveName), 'url' => getFullPath($path), 'size' => format_bytes($fileInfo['size']), 'file_id' => $file_id];
} else {
$resData[$k] = ['key' => $k,'name' => $fileInfo['name'],'status' => 0,'error' => '上传出错'];
}
} else {
$resData[$k] = ['key' => $k,'name' => $fileInfo['name'],'status' => 0,'error' => $v['obj']->getError()];
}
}
return $resData;
}
/**
* 修改上传文件名
* @param [type] $save_name [description]
* @param [type] $name [description]
* @return [type] [description]
*/
public function updateNameBySaveName($save_name,$name)
{
$flag = $this->where(['save_name' => $save_name])->setField('name',$name);
if ( $flag ) {
return true;
} else {
$this->error = '操作失败';
return false;
}
}
/**
* [delFileById 删除附件]
* @author Michael_xu
* @param $save_name 附件保存名称
* @param $param [module : 模块, module_id : 模块ID]
* @return [array]
*/
public function delFileBySaveName($save_name, $param = [])
{
if (!$save_name) {
$this->error = '请选择需要删除的附件';
return false;
}
$fileInfo = $this->where(['save_name' => trim($save_name)])->find();
if (!$fileInfo) {
$this->error = '附件不存在或已删除';
return false;
}
$file_id = $fileInfo['file_id'];
$res = db('admin_file')->where(['file_id' => $file_id])->delete();
if ($res) {
@unlink($fileInfo['file_path']);//删除文件
if ($fileInfo['file_path_thumb']) @unlink($fileInfo['file_path_thumb']);
//处理附表信息
if (in_array($param['module'], $this->module_arr)) {
switch ($param['module']) {
case 'crm_leads' : $r = db('crm_leads_file'); break;
case 'crm_customer' : $r = db('crm_customer_file'); break;
case 'crm_contacts' : $r = db('crm_contacts_file'); break;
case 'crm_business' : $r = db('crm_business_file'); break;
case 'crm_product' : $r = db('crm_product_file'); break;
case 'crm_contract' : $r = db('crm_contract_file'); break;
case 'oa_log' : $r = db('oa_log_file'); break;
case 'oa_examine' : $r = db('oa_examine_file'); break;
case 'work_task' : $r = db('work_task_file'); break;
case 'admin_record' : $r = db('admin_record_file'); break;
case 'oa_travel' : $r = db('oa_travel_file'); break;
case 'hrm_pact' : $r = db('hrm_pact_file'); break;
case 'hrm_file' : $r = db('hrm_user_file'); break;
case 'crm_invoice' : $r = db('crm_invoice_file'); break;
case 'crm_activity': $r = db('crm_activity_file'); break;
case 'crm_visit': $r = db('crm_visit_file'); break;
case 'crm_receivables': $r = db('crm_receivables_file'); break;
default : break;
}
$resDel = $r->where(['file_id'=>$file_id])->delete();
}
return true;
} else {
$this->error = '删除失败';
return false;
}
}
/**
* 根据主键获取详情
* @author Michael_xu
* @param array $param [description]
*/
public function getDataBySaveName($save_name = '')
{
if (!$save_name) {
$this->error = '参数错误';
return false;
}
$data = $this->where(['save_name' => trim($save_name)])->find();
$data['full_path'] = getFullPath($data['file_path']);
$data['full_path_thumb'] = getFullPath($data['file_path_thumb']);
if (!$data) {
$this->error = '数据不存在或已删除';
return false;
}
return $data;
}
/**
* 根据ID获取列表
* @author Michael_xu
* @param string module [类型]
* @param string by = all 全部(不分页)
* @param int module_id [类型ID]
*/
public function getDataList($request, $by = '')
{
if (!in_array($request['module'], $this->module_arr) || !$request['module_id']) {
$this->error = '参数错误';
return false;
}
$module_ids = $request['module_id'];
if (!is_array($request['module_id'])) {
$module_ids = array($request['module_id']);
}
switch ($request['module']) {
case 'crm_leads' : $r = db('crm_leads_file'); $module = db('crm_leads'); break;
case 'crm_customer' : $r = db('crm_customer_file'); $module = db('crm_customer'); break;
case 'crm_contacts' : $r = db('crm_contacts_file'); $module = db('crm_contacts'); break;
case 'crm_business' : $r = db('crm_business_file'); $module = db('crm_business'); break;
case 'crm_product' : $r = db('crm_product_file'); $module = db('crm_product'); break;
case 'crm_contract' : $r = db('crm_contract_file'); $module = db('crm_contract'); break;
case 'oa_log' : $r = db('oa_log_file'); $module = db('oa_log'); break;
case 'oa_examine' : $r = db('oa_examine_file'); $module = db('oa_examine'); break;
case 'oa_examine_travel' : $r = db('oa_examine_travel_file'); $module = db('oa_examine_travel'); break;
case 'work_task' : $r = db('work_task_file'); $module = db('task'); break;
case 'admin_record' : $r = db('admin_record_file'); $module = db('admin_record'); break;
case 'oa_travel' : $r = db('oa_travel_file'); $module = db('oa_travel'); break;
case 'hrm_pact' : $r = db('hrm_pact_file'); $module = db('hrm_pact'); break;
case 'hrm_file' : $r = db('hrm_user_file'); $module = db('admin_user'); break;
case 'crm_invoice' : $r = db('crm_invoice_file'); $module = db('crm_invoice'); break;
case 'crm_activity' : $r = db('crm_activity_file'); $module = db('crm_activity'); break;
case 'crm_visit' : $r = db('crm_visit_file'); $module = db('crm_visit'); break;
case 'crm_receivables' : $r = db('crm_receivables_file'); $module = db('crm_receivables'); break;
default : break;
}
if ($r) {
$fileIds = $r->where([$module->getPk() => ['in',$module_ids]])->column('file_id');
$request['file_id'] = ['in', $fileIds];
}
unset($request['module']);
unset($request['module_id']);
unset($request['by']);
$userModel = new \app\admin\model\User();
$request = $this->fmtRequest( $request );
$map = $request['map'];
$order = 'create_time desc';
$dataCount = $this->where($map)->count('file_id');
if ($by == 'all') {
$list = Db::name('AdminFile')->where($map)->order($order)->select();
} else {
$list = Db::name('AdminFile')->where($map)->page($request['page'], $request['limit'])->order($order)->select();
}
foreach ($list as $k=>$v) {
$createUserInfo = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
$list[$k]['size'] = format_bytes($v['size']); //字节转换
$list[$k]['create_time'] = date('Y-m-d H:i:s',$v['create_time']);
$list[$k]['create_user_id_info'] = $createUserInfo;
$list[$k]['createName'] = !empty($createUserInfo['realname']) ? $createUserInfo['realname'] : '';
$list[$k]['ext'] = getExtension($v['save_name']);
$list[$k]['file_path'] = getFullPath($v['file_path']);
$list[$k]['file_path_thumb'] = getFullPath($v['file_path_thumb']);
}
$data = [];
$data['list'] = $list ? : [];
$data['dataCount'] = $dataCount ? : 0;
return $data;
}
/**
* 根据表、字段更新上传图片
* @author Michael_xu
* @param $file 附件信息
* @param $module 模块(判断权限),一般是控制器,并且和表名一致
* @param $module_id 模块ID判断权限
* @param $file 字段
* @param $thumb_field 缩略图字段
* @param $x 裁剪宽度
* @param $y 裁剪高度
*/
public function updateByField($file, $module, $module_id, $field, $thumb_field = '', $x = '150', $y = '150')
{
if (empty($module) || empty($module_id) || empty($field)) {
$this->error = '参数错误';
return false;
}
$info = $file->move(FILE_PATH . 'public' . DS . 'uploads'); //验证规则
$fileInfo = $info->getInfo(); //附件数据
$saveName = '';
$thumbSaveName = '';
if ($info) {
//如果是图片类型,生成缩略图
$ext = $info->getExtension();
$saveName = $info->getSaveName();
$fileName = $info->getFilename();
$thumbSaveName = str_replace(DS, DS.'thumb_', $saveName);
//附件信息存储
$saveData = [];
if ($thumb_field) {
// $image = \think\Image::open($file);
$image = \think\Image::open(UPLOAD_PATH . str_replace(DS, '/', $saveName));
$thumbSaveName = str_replace(DS, DS.'thumb_', $saveName);
$image->thumb($x, $y,\think\Image::THUMB_FILLED)->save(FILE_PATH . 'public'. DS .'uploads'. DS .$thumbSaveName); //THUMB_SCALING 或 THUMB_FILLED
$saveData[$thumb_field] = $thumbSaveName ? UPLOAD_PATH . str_replace(DS, '/', $thumbSaveName) : '';
}
$saveData[$field] = UPLOAD_PATH . str_replace(DS, '/', $saveName);
switch ($module) {
case 'crm_customer' : $moduleModel = new \app\crm\model\Customer(); break;
case 'crm_contacts' : $moduleModel = new \app\crm\model\Contacts(); break;
case 'crm_business' : $moduleModel = new \app\crm\model\Business(); break;
case 'crm_product' : $moduleModel = new \app\crm\model\Product(); break;
case 'crm_contract' : $moduleModel = new \app\crm\model\Contract(); break;
case 'User' : $moduleModel = new \app\admin\model\User(); break;
case 'admin_system': $moduleModel = new \app\admin\model\System(); break;
case 'crm_invoice' : $moduleModel = new Invoice(); break;
case 'crm_activity' : $moduleModel = new Activity(); break;
case 'crm_receivables' : $moduleModel = new \app\crm\model\Receivables(); break;
case 'crm_visit' : $moduleModel = new \app\crm\model\Visit(); break;
}
$resFile = $moduleModel->allowField([$field,$thumb_field])->save($saveData, [$moduleModel->getPk() => $module_id]);
if (!$resFile) {
$this->error = '上传失败';
return false;
}
return true;
}
}
/**
* 根据ID保存处理逻辑关系
* @author Michael_xu
* @param $ids 附件ID数组
* @param $module 表名
* @param $module_id 模块ID
*/
public function createDataById($ids, $module, $module_id)
{
if (!$ids || !in_array($module, $this->module_arr) || !$module_id) {
$this->error = '参数错误';
return false;
}
switch (trim($module)) {
case 'crm_customer' : $rDb = db('crm_customer_file'); $r_name = 'customer_id'; break;
case 'crm_contacts' : $rDb = db('crm_contacts_file'); $r_name = 'contacts_id'; break;
case 'crm_business' : $rDb = db('crm_business_file'); $r_name = 'business_id'; break;
case 'crm_product' : $rDb = db('crm_product_file'); $r_name = 'product_id'; break;
case 'crm_contract' : $rDb = db('crm_contract_file'); $r_name = 'contract_id'; break;
case 'oa_log' : $rDb = db('oa_log_file'); $r_name = 'log_id'; break;
case 'oa_examine' : $rDb = db('oa_examine_file'); $r_name = 'examine_id'; break;
case 'oa_examine_travel' : $rDb = db('oa_examine_travel_file'); $r_name = 'travel_id'; break;
case 'admin_record' : $rDb = db('admin_record_file'); $r_name = 'record_id'; break;
case 'oa_travel' : $rDb = db('oa_travel_file'); $r_name = 'travel_id'; break;
case 'crm_invoice' : $rDb = db('crm_invoice_file'); $r_name = 'invoice_id'; break;
case 'crm_activity' : $rDb = db('crm_activity_file'); $r_name = 'activity_id'; break;
case 'crm_visit' : $rDb = db('crm_visit_file'); $r_name = 'activity_id'; break;
case 'crm_receivables' : $rDb = db('crm_receivables_file'); $r_name = 'receivables_id'; break;
}
$res_success = true;
$data = [];
$data[$r_name] = intval ($module_id);
foreach ($ids as $v) {
$data['file_id'] = intval($v);
if (!$rDb->insert($data)) {
$res_success = false;
}
}
if ($res_success == false) {
$this->error = '附件上传失败';
}
return true;
}
/**
* 删除关系表附件
* @author Michael_xu
* @param $module 模块
* @param $module_id 模块ID
*/
public function delRFileByModule($module, $module_id)
{
if (in_array($module,$this->module_arr) && $module_id) {
switch ($module) {
case 'crm_leads' :
$r = db('crm_leads_file');
$r_name = 'leads_id';
break;
case 'crm_customer' :
$r = db('crm_customer_file');
$r_name = 'customer_id';
break;
case 'crm_contacts' :
$r = db('crm_contacts_file');
$r_name = 'contacts_id';
break;
case 'crm_business' :
$r = db('crm_business_file');
$r_name = 'business_id';
break;
case 'crm_product' :
$r = db('crm_product_file');
$r_name = 'product_id';
break;
case 'crm_contract' :
$r = db('crm_contract_file');
$r_name = 'contract_id';
break;
case 'oa_log' :
$r = db('oa_log_file');
$r_name = 'log_id';
break;
case 'oa_examine' :
$r = db('oa_examine_file');
$r_name = 'examine_id';
break;
case 'work_task' :
$r = db('work_task_file');
$r_name = 'task_id';
break;
case 'admin_record' :
$r = db('admin_record_file');
$r_name = 'record_id';
break;
case 'oa_travel' :
$r = db('oa_travel_file');
$r_name = 'travel_id';
break;
case 'hrm_pact' :
$r = db('hrm_pact_file');
$r_name = 'pact_id';
break;
case 'hrm_file' :
$r = db('hrm_user_file');
$r_name = 'user_id';
break;
case 'crm_invoice' :
$r = db('crm_invoice_file');
$r_name = 'invoice_id'; break;
case 'crm_visit' :
$r = db('crm_visit_file');
$r_name = 'visit_id';
break;
case 'crm_activity' :
$r = db('crm_activity_file');
$r_name = 'activity_id';
break;
case 'crm_receivables' :
$r = db('crm_receivables_file');
$r_name = 'receivables_id';
default : break;
}
$rWhere = [];
if(!is_array($module_id)){
$module_id = [intval ($module_id)];
}
$rWhere[$r_name] = ['in',$module_id];
$rFileIds = $r->where($rWhere)->column('file_id');
$rRes = $r->where($rWhere)->delete();
if ($rRes && $rFileIds) {
$fileList = db('admin_file')->where(['file_id' => ['in',$rFileIds]])->field('file_path,file_path_thumb')->select();
foreach ($fileList as $v) {
//删除文件
@unlink($v['file_path']);
@unlink($v['file_path_thumb']);
}
}
}
}
/**
* 全部删除(活动、产品)
*
* @param $param
* @return bool
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
public function deleteAll($param)
{
if (!empty($param['module']) && !empty($param['module_id'])) {
$module = db('crm_activity_file');
$primaryKey = 'activity_id';
switch ($param['module']) {
case 'crm_activity' : $module = db('crm_activity_file'); $primaryKey = 'activity_id'; break;
case 'crm_product' : $module = db('crm_product_file'); $primaryKey = 'product_id'; break;
}
$fileIds = $module->where($primaryKey, $param['module_id'])->column('file_id');
# 删除关联数据
$module->where($primaryKey, $param['module_id'])->delete();
# 删除附件
db('admin_file')->whereIn('file_id', $fileIds)->delete();
}
if (!empty($param['file_id'])) {
db('admin_file')->whereIn('file_id', $param['file_id'])->delete();
}
return true;
}
}

@ -0,0 +1,192 @@
<?php
// +----------------------------------------------------------------------
// | Description: 用户组
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
class Group extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_group';
/**
* [getDataList 获取列表]
* @param tree 1 属性
* @param rules 1 二维数组
* @param pid 分类0客户自定义角色,1系统默认管理角色,2客户管理角色,3人力资源管理角色(原客户),4财务管理角色(原客户),5项目管理角色,6办公管理角色,7人力资源管理角色,8财务管理角色,9项目管理员角色
* @param 备注原自定义角色0,人事管理角色3,财务管理角色4划分至新客户管理角色中
* @param ruletypes 0系统设置1工作台2客户管理3项目管理4人力资源5财务管理6商业智能(客戶)
* @return [array]
*/
public function getDataList($param)
{
$ruleModel = new \app\admin\model\Rule();
$map = [];
if ($param['tree'] == 1) {
$list = $this->getTypeList();
foreach ($list as $k=>$v) {
$where = [];
$where = $this->getNewGroupPid($v['pid']);
$groupList = db('admin_group')->where($where)->select() ? : [];
$list[$k]['list'] = $groupList ? : [];
}
} else {
$where = [];
if (isset($param['type'])) {
$where['pid'] = $param['pid'];
$where['type'] = $param['type'];
} else {
$where = $this->getNewGroupPid($param['pid']);
}
$list = db('admin_group')->where($where)->select() ? : [];
if ($param['rules'] == 1) {
//角色权限分类关系
$ruleTypes = $ruleModel->groupsToRules($param['pid']);
if ($ruleTypes) {
foreach ($list as $key => $val) {
$dataRules = [];
$biRules = [];
$rules = stringToArray($val['rules']) ? : [];
foreach ($rules as $k1=>$v1) {
$ruleInfo = [];
$ruleInfo = db('admin_rule')->where(['id' => $v1])->find();
if ($ruleInfo['types'] == $ruleTypes[0]) {
$dataRules[] = $v1;
} elseif ($ruleInfo['types'] == $ruleTypes[1]) {
$biRules[] = $v1;
}
}
$list[$key]['rules'] = [];
$list[$key]['rules']['data'] = $dataRules ? : [];
$list[$key]['rules']['bi'] = $biRules ? : [];
if ($val['pid'] == 1 || $val['pid'] == 5 || $val['pid'] == 6 || $val['pid'] == 9) {
$list[$key]['type'] = 0;
}
}
}
}
}
return $list ? : [];
}
//新建角色
public function createData($param)
{
unset($param['types']);
if ($param['pid'] == 5 && $param['type'] == 'work') {
//项目模块下角色
$param['type'] = 0;
}
$flag = $this->insertGetId($param);
if ($flag) {
return $flag;
} else {
$this->error = '操作失败';
return false;
}
}
//编辑角色
public function updateDataById($param,$group_id)
{
$dataInfo = $this->get($group_id);
if(!$dataInfo){
$this->error = '该角色不存在或已删除';
return false;
}
unset($param['types']);
# 处理编辑时前端可能不传父id的问题admin_rule表level为1的主键
if (!empty($param['rules'])) {
$rulesParam = stringToArray($param['rules']);
$rulesList = db('admin_rule')->field(['id', 'level', 'pid'])->whereIn('id', $rulesParam)->select();
foreach ($rulesList AS $key => $value) {
if (!empty($value['level']) && $value['level'] == 2) $rulesParam[] = $value['pid'];
if (!empty($value['level']) && $value['level'] == 3) {
$rulesParam[] = $value['pid'];
$rulesParam[] = db('admin_rule')->where('id', $value['pid'])->value('pid');
}
}
$param['rules'] = arrayToString(array_unique($rulesParam));
}
$flag = $this->where('id = '.$group_id)->update($param);
if ($flag) {
return true;
} else {
$this->error = '操作失败';
return false;
}
}
//删除角色
public function delGroupById($group_id = '')
{
$dataInfo = $this->get($group_id);
if(!$dataInfo){
$this->error = '该角色不存在或已删除';
return false;
}
if ($dataInfo['types']) {
$this->error = '系统角色不能删除';
return false;
}
$flag = $this->where('id = '.$group_id)->delete();
if ($flag) {
return true;
} else {
$this->error = '删除失败';
return false;
}
}
/**
* [getTypeList 获取分类列表]
* @param 备注原自定义角色0,人事管理角色3,财务管理角色4划分至客户管理角色中
* @return [array]
*/
public function getTypeList()
{
$list = ['0' => ['name' => '系统管理角色','pid' => 1],'1' => ['name' => '办公管理角色','pid' => 6],'2' => ['name' => '客户管理角色','pid' => 2],'3' => ['name' => '项目管理角色','pid' => '9']];
return $list ? : [];
}
/**
* [getNewGroupPid 兼容9.0.5版本group pid对应关系]
* @param 备注原自定义角色0,人事管理角色3,财务管理角色4划分至客户管理角色中
* @return [array]
*/
protected function getNewGroupPid($pid)
{
switch ($pid) {
case '1' :
$where['pid'] = 1;
$where['types'] = ['not in',['7']];
break;
case '2' :
$where = function($query) {
$query->where(['pid' => ['in',['0','2','3','4']]])
->whereOr('type != 0 AND pid = 5');
};
break;
case '9' :
$where = function($query) {
$query->where(['pid' => 9])
->whereOr('types = 7 AND pid = 1');
};
break;
default :
$where['pid'] = $pid;
break;
}
return $where ? : [];
}
}

@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | Description: 导入记录
// +----------------------------------------------------------------------
// | Author: ymob
// +----------------------------------------------------------------------
namespace app\admin\model;
class ImportRecord extends Common
{
protected $name = 'admin_import_record';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = false;
/**
* 保存记录
*
* @param array $data
* @return void
* @author Ymob
* @datetime 2019-10-22 11:46:41
*/
public function createData($data)
{
$res = $this->save($data);
$message_type_list = [
'crm_customer' => Message::IMPORT_CUSTOMER,
'crm_contacts' => Message::IMPORT_CONTACTS,
'crm_leads' => Message::IMPORT_LEADS,
'crm_product' => Message::IMPORT_PRODUCT,
'task' => Message::IMPORT_TASK,
];
if ($res) {
(new Message())->send(
$message_type_list[$data['type']],
[
'total' => $data['total'],
'error' => $data['error'],
'done' => $data['done'],
'success' => $data['done'] - $data['error'],
'cover' => $data['cover'],
'title' => $data['error'] > 0 ? '点击下载错误数据' : '',
'action_id' => $this->id,
],
User::userInfo('id'),
false
);
}
}
}

@ -0,0 +1,133 @@
<?php
// +----------------------------------------------------------------------
// | Description: 应用配置
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use com\Scan;
class LoginRecord extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_login_record';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = false;
/**
* 登录成功
*/
const TYPE_SUCCESS = 0;
/**
* 密码错误
*/
const TYPE_PWD_ERROR = 1;
/**
* 账号被禁用
*/
const TYPE_USER_BANNED = 2;
// 类型
public $typeList = [
self::TYPE_SUCCESS => '登录成功',
self::TYPE_PWD_ERROR => '密码错误',
self::TYPE_USER_BANNED => '账号被禁用',
];
/**
* 登录员工ID
*/
public $user_id = 0;
/**
* 添加登录记录
*
* @param int $type
*/
public function createRecord($type = 0)
{
$data = [];
$data['type'] = $type;
$data['create_user_id'] = $this->user_id;
$data['create_time'] = time();
$data['ip'] = (new Scan())->get_client_ip();
$data['os'] = getOS();
$data['browser'] = getBrowser();
$ip_address = getAddressById($data['ip']);
$data['address'] = $ip_address['country'];
// 效果图有这个备注字段不知道存啥就把UA记录了一下
$data['remark'] = $_SERVER['HTTP_USER_AGENT'];
$this->save($data);
}
/**
* 创建人
*/
public function getCreateUserInfoAttr($val, $data)
{
return User::getUserById($data['create_user_id']) ?: [];
}
/**
* 获取登录记录类型
*/
public function getTypeNameAttr($val, $data)
{
return $this->typeList[$data['type']];
}
/**
*
*/
/**
* 固定时间内登录密码错超过限制
*
* @param integer $count 登录出错次数
* @param integer $time 等待时间 (分钟)
* @return bool
*/
public function verify($count = 3, $time = 5)
{
$where = [
'create_user_id' => $this->user_id,
'create_time' => ['GT', time() - 60 * $time],
'type' => 1
];
$last_record = $this->order(['id' => 'DESC'])
->where($where)
->find();
// 登录记录
if ($last_record) {
$last_time = strtotime($last_record['create_time']);
$where['create_time'] = [
'BETWEEN',
[
$last_time - 60 * $time,
$last_time
]
];
$list = $this->where($where)
->order(['id' => 'DESC'])
->column('type');
if (count($list) >= $count) {
$surplusTime = getTimeBySec(60 * $time - (time()-strtotime($last_record['create_time'])));
$this->error = "密码错误次数过多,请在{$surplusTime}后重试!";
return false;
}
}
return true;
}
}

@ -0,0 +1,94 @@
<?php
// +----------------------------------------------------------------------
// | Description: 菜单
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use app\admin\model\Common;
class Menu extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_menu';
/**
* [getDataList 获取列表]
* @return [array]
*/
public function getDataList()
{
$cat = new \com\Category('admin_menu', array('id', 'pid', 'title', 'title'));
$data = $cat->getList('', 0, 'sort');
return $data;
}
/**
* [getDataById 根据主键获取详情]
* @param string $id [主键]
* @return [array]
*/
public function getDataById($id = '')
{
$data = $this
->alias('menu')
->where('menu.id', $id)
->join('__ADMIN_RULE__ rule', 'menu.rule_id=rule.id', 'LEFT')
->field('menu.*, rule.title as rule_name')
->find();
if (!$data) {
$this->error = '暂无此数据';
return false;
}
return $data;
}
/**
* 整理菜单树形结构
* @param array $param [description]
*/
protected function getMenuTree()
{
$userInfo = $GLOBALS['userInfo'];
if (!$userInfo) {
return [];
}
$u_id = $userInfo['id'];
if ($u_id === 1) {
$map['status'] = 1;
$menusList = Db::name('admin_menu')->where($map)->order('sort asc')->select();
} else {
$groups = model('User')->get($u_id)->groups;
$ruleIds = [];
foreach($groups as $k => $v) {
$ruleIds = array_unique(array_merge($ruleIds, explode(',', $v['rules'])));
}
$ruleMap['id'] = array('in', $ruleIds);
$ruleMap['status'] = 1;
// 重新设置ruleIds除去部分已删除或禁用的权限。
$ruleIds = Db::name('admin_rule')->where($ruleMap)->column('id');
empty($ruleIds)&&$ruleIds = '';
$menuMap['status'] = 1;
$menuMap['rule_id'] = array('in',$ruleIds);
$menusList = Db::name('admin_menu')->where($menuMap)->order('sort asc')->select();
}
if (!$menusList) {
return [];
}
//处理成树状
// $tree = new \com\Tree();
// $menusList = $tree->list_to_tree($menusList, 'id', 'pid', 'child', 0, true, array('pid'));
// $menusList = memuLevelClear($menusList);
return $menusList? $menusList: [];
}
}

@ -0,0 +1,470 @@
<?php
// +----------------------------------------------------------------------
// | Description: 站内信
// +----------------------------------------------------------------------
// | Author: ymob
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\ImportRecord as ImportRecordModel;
use app\admin\model\User as UserModel;
use app\crm\model\Contract as ContractModel;
use app\crm\model\Invoice;
use app\crm\model\Receivables as ReceivablesModel;
use app\oa\model\Announcement as AnnouncementModel;
use app\oa\model\Event as EventModel;
use app\oa\model\Examine as ExamineModel;
use app\oa\model\ExamineCategory;
use app\oa\model\Log as LogModel;
use app\work\model\Task as TaskModel;
class Message extends Common
{
protected $name = 'admin_message';
protected $autoWriteTimestamp = true;
protected $createTime = 'send_time';
protected $updateTime = false;
/**
* 错误信息
*/
public $error = '';
/**
* 将要发送的消息内容
*/
protected $content = '';
/**
* 消息类型
*/
protected $type = 0;
/**
* 任务分配
*/
const TASK_ALLOCATION = 1;
/**
* 任务邀请
*/
const TASK_INVITE = 2;
/**
* 任务结束
*/
const TASK_OVER = 3;
/**
* 回复日志
*/
const LOG_REPLAY = 4;
/**
* 发送日志
*/
const LOG_SEND = 5;
/**
* 审批待处理
*/
const EXAMINE_TO_DO = 6;
/**
* 审批驳回
*/
const EXAMINE_REJECT = 7;
/**
* 审批通过
*/
const EXAMINE_PASS = 8;
/**
* 公告
*/
const NOTICE_MESSAGE = 9;
/**
* 日程
*/
const EVENT_MESSAGE = 10;
/**
* 合同待审批
*/
const CONTRACT_TO_DO = 11;
/**
* 合同审批驳回
*/
const CONTRACT_REJECT = 12;
/**
* 合同审批通过
*/
const CONTRACT_PASS = 13;
/**
* 回款待审批
*/
const RECEIVABLES_TO_DO = 14;
/**
* 回款审批驳回
*/
const RECEIVABLES_REJECT = 15;
/**
* 回款审批通过
*/
const RECEIVABLES_PASS = 16;
/**
* 客户导入
*/
const IMPORT_CUSTOMER = 17;
/**
* 联系人
*/
const IMPORT_CONTACTS = 18;
/**
* 线索
*/
const IMPORT_LEADS = 19;
/**
* 产品
*/
const IMPORT_PRODUCT = 20;
/**
* 团队成员-客户
*/
const TEAM_CUSTOMER = 21;
/**
* 团队成员-商机
*/
const TEAM_BUSINESS = 22;
/**
* 团队成员-合同
*/
const TEAM_CONTRACT = 23;
/**
* 发票待审批
*/
const INVOICE_TO_DO = 24;
/**
* 发票审批驳回
*/
const INVOICE_REJECT = 25;
/**
* 发票审批通过
*/
const INVOICE_PASS = 26;
/**
* 项目任务导入
*/
const IMPORT_TASK = 27;
/**
* 退出商机团队
*/
const BUSINESS_PASS = 28;
/**
* 退出客户团队
*/
const CUSTOMER_PASS = 29;
/**
* 退出合同团队
*/
const CONTRACT_END = 30;
/**
* 消息类型
*
* @var array
* @author Ymob
* @datetime 2019-10-17 15:27:43
*/
protected $typeList = [
1 => [
'template' => '{from_user} 将 {title} 任务分配给您,请及时查看。',
],
2 => [
'template' => '{from_user} 邀请您参与 {title} 任务,请及时查看。',
],
3 => [
'template' => '{from_user} 将 {title} 任务标记结束。',
],
4 => [
'template' => '{from_user} 回复了您的 {title} 日志:“今天工作状态不错,继续加油!”,请及时查看',
],
5 => [
'template' => '{from_user} 将日志 {title} 发送给您,请及时查看。',
],
6 => [
'template' => '{from_user} 提交 {title} 审批,请及时处理。',
],
7 => [
'template' => '{from_user} 拒绝您的 {title} 审批,拒绝理由:“日期填写错误”,请及时处理。',
],
8 => [
'template' => '{from_user} 已经审核通过您的 {title} ,请及时查看。',
],
9 => [
'template' => '您有一个新公告 {title} ,请及时查看。',
],
10 => [
'template' => '{from_user} 邀请您参与 {title} 日程,将于**分钟后开始,请及时查看。',
],
11 => [
'template' => '{from_user} 提交 {title} 合同审批待您处理,请及时查看。',
],
12 => [
'template' => '{from_user} 拒绝您的 {title} 合同审批,拒绝理由:“日期填写错误”,请及时处理。',
],
13 => [
'template' => '{from_user} 已经审核通过您的 {title} 合同,请及时查看',
],
14 => [
'template' => '{from_user} 提交 {title} 回款审批待您处理,请及时查看。',
],
15 => [
'template' => '{from_user} 拒绝您的 {title} 回款审批,拒绝理由:“日期填写错误”,请及时处理。',
],
16 => [
'template' => '{from_user} 已经审核通过您的 {title} 回款,请及时查看。',
],
17 => [
// 'template' => '{from_user} 导入客户数据,共 {total} 条,已导入 {done} 条 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
'template' => '{total},{cover},{success},{error}',
],
18 => [
// 'template' => '{from_user} 导入联系人数据,共 {total} 条,已导入 {done} 条 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
'template' => '{total},{cover},{success},{error}',
],
19 => [
// 'template' => '{from_user} 导入线索数据,共 {total} 条,已导入 {done} 条 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
'template' => '{total},{cover},{success},{error}',
],
20 => [
// 'template' => '{from_user} 导入产品数据,共 {total} 条,已导入 {done} 条 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
'template' => '{total},{cover},{success},{error}',
],
21 => [
'template' => '{from_user} 将您添加为客户 {title} 的成员。',
],
22 => [
'template' => '{from_user} 将您添加为商机 {title} 的成员。',
],
23 => [
'template' => '{from_user} 将您添加为合同 {title} 的成员。',
],
24 => [
'template' => '{from_user} 提交 {title} 发票审批待您处理,请及时查看。',
],
25 => [
'template' => '{from_user} 拒绝您的 {title} 发票审批,请及时处理。',
],
26 => [
'template' => '您的 {title} 发票已经审批通过,请及时查看。',
],
27 => [
// 'template' => '{date}{from_user} 导入任务,共 {total} 条,已导入 {done} 条 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。{title}',
'template' => '{total},{cover},{success},{error}',
],
28 => [
'template' => '{from_user} 退出了您商机 {title} 的团队。',
],
29 => [
'template' => '{from_user} 退出了您客户 {title} 的团队。',
],
30 => [
'template' => '{from_user} 退出了您合同 {title} 的团队。',
],
];
/**
* 消息类型分组
*/
public static $typeGroup = [
'announcement' => [
self::NOTICE_MESSAGE,
],
'examine' => [
self::EXAMINE_TO_DO,
self::EXAMINE_REJECT,
self::EXAMINE_PASS,
],
'task' => [
self::TASK_ALLOCATION,
self::TASK_INVITE,
self::TASK_OVER,
self::IMPORT_TASK,
],
'log' => [
self::LOG_REPLAY,
self::LOG_SEND,
],
'event' => [
self::EVENT_MESSAGE,
],
'crm' => [
self::CONTRACT_TO_DO,
self::CONTRACT_REJECT,
self::CONTRACT_PASS,
self::RECEIVABLES_TO_DO,
self::RECEIVABLES_REJECT,
self::RECEIVABLES_PASS,
self::IMPORT_CUSTOMER,
self::IMPORT_CONTACTS,
self::IMPORT_LEADS,
self::IMPORT_PRODUCT,
self::TEAM_CUSTOMER,
self::TEAM_BUSINESS,
self::TEAM_CONTRACT,
self::INVOICE_TO_DO,
self::INVOICE_REJECT,
self::INVOICE_PASS,
self::BUSINESS_PASS,
self::CUSTOMER_PASS,
self::CONTRACT_END,
]
];
/**
* 发送系统通知
*
* @param int $type 消息类型
* @param array $data 关联信息
* @param array|int $user_id 接收消息员工ID
* @param boolean $system 是否系统消息
* @return bool
* @author Ymob
* @datetime 2019-10-17 17:23:05
*/
public function send($type, $data, $user_id_list, $system = false)
{
if (!isset($this->typeList[$type])) {
$this->error = '消息类型错误';
return false;
}
$user_id_list = (array)$user_id_list;
$user_id_list = array_unique(array_filter($user_id_list));
if (empty($user_id_list)) {
$this->error = '接收人不能为空';
return false;
}
$action_id = $data['action_id'];
$title = $data['title'];
$content = $this->typeList[$type]['template'];
foreach ($data as $key => $val) {
$content = str_replace('{' . $key . '}', $val, $content);
}
$advance_time= $data['advance_time'];
$content = str_replace('{from_user}', User::userInfo('realname'), $content);
$content = str_replace('{date}', date('Y-m-d'), $content);
$data = [];
$data['type'] = $type;
$data['content'] = $content;
$data['action_id'] = $action_id;
$data['read_time'] = 0;
$data['from_user_id'] = $system ? 0 : User::userInfo('id');
$data['title'] = $title;
$data['advance_time'] = $advance_time ?: 0;
$request = request();
$data['controller_name'] = strtolower($request->controller());
$data['module_name'] = strtolower($request->module());
$data['action_name'] = strtolower($request->action());
$from_user_id = $data['from_user_id'];
if (!in_array($type,[9,17,18,19,20,27])) {
$user_id_list = array_filter($user_id_list, function ($val) use ($from_user_id) {
return $val !== $from_user_id;
});
}
$all_data = [];
foreach ($user_id_list as $user_id) {
$temp = $data;
$temp['to_user_id'] = $user_id;
$all_data[] = $temp;
}
if (!empty($from_user_id) && class_exists('DingTalk')) {
(new Dingtalk())->message($user_id_list, $content);
}
$this->saveAll($all_data);
}
/**
* 获取关联模块数据
*
* @author Ymob
* @datetime 2019-10-22 15:34:35
*/
public function getRelationTitleAttr($val, $data)
{
switch ($data['type']) {
// 任务
case self::TASK_ALLOCATION:
case self::TASK_INVITE:
case self::TASK_OVER:
return TaskModel::where(['task_id' => $data['action_id']])->value('name') ?: '';
// 日志
case self::LOG_REPLAY:
case self::LOG_SEND:
return LogModel::where(['log_id' => $data['action_id']])->value('title') ?: '';
// 审批
case self::EXAMINE_TO_DO:
case self::EXAMINE_REJECT:
case self::EXAMINE_PASS:
$category_id = ExamineModel::where(['examine_id' => $data['action_id']])->value('category_id') ?: 0;
$categoryInfo = (new ExamineCategory())->getDataById($category_id);
return $categoryInfo['title'];
// 公告
case self::NOTICE_MESSAGE:
return AnnouncementModel::where(['announcement_id' => $data['action_id']])->value('title') ?: '';
// 日程
case self::EVENT_MESSAGE:
return EventModel::where(['event_id' => $data['action_id']])->value('title') ?: '';
// 合同
case self::CONTRACT_TO_DO:
case self::CONTRACT_REJECT:
case self::CONTRACT_PASS:
case self::TEAM_CONTRACT:
return ContractModel::where(['contract_id' => $data['action_id']])->value('name') ?: '';
// 回款
case self::RECEIVABLES_TO_DO:
case self::RECEIVABLES_REJECT:
case self::RECEIVABLES_PASS:
return ReceivablesModel::where(['receivables_id' => $data['action_id']])->value('number') ?: '';
// 发票
case self::INVOICE_TO_DO:
case self::INVOICE_REJECT:
case self::INVOICE_PASS:
return Invoice::where(['invoice_id' => $data['action_id']])->value('invoice_apple_number') ?: '';
// 导入数据
case self::IMPORT_CUSTOMER:
case self::IMPORT_CONTACTS:
case self::IMPORT_LEADS:
case self::IMPORT_PRODUCT:
case self::IMPORT_TASK:
$error = ImportRecordModel::where(['id' => $data['action_id']])->value('error');
return $error ? '点击下载错误数据' : '';
// 客户
case self::TEAM_CUSTOMER:
case self::CUSTOMER_PASS:
return CustomerModel::where(['customer_id' => $data['action_id']])->value('name') ?: '';
// 商机
case self::TEAM_BUSINESS:
case self::BUSINESS_PASS:
return BusinessModel::where(['business_id' => $data['action_id']])->value('name') ?: '';
}
return '';
}
/**
* 发送人
*/
public function getFromUserIdInfoAttr($val, $data)
{
return $data['from_user_id'] ? UserModel::getUserById($data['from_user_id']) : [];
}
}

@ -0,0 +1,12 @@
<?php
namespace app\admin\model;
use app\admin\model\Common;
class OaSchedule extends Common{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_group';
}

@ -0,0 +1,28 @@
<?php
/**
* 数据操作日志
*
* @author qifna
* @date 2020-12-29
*/
namespace app\admin\model;
use think\Model;
class OperationLog extends Model
{
protected $name = 'admin_operation_log';
protected $pk = 'log_id';
/**
* 关联后台员工表姓名
*
* @return \think\model\relation\HasOne
*/
public function toAdminUser()
{
return $this->hasOne('User', 'id', 'user_id')->bind(['source_name' => 'realname']);
}
}

@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | Description: 岗位
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
class Post extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_post';
protected $createTime = 'create_time';
protected $updateTime = false;
protected $autoWriteTimestamp = true;
protected $insert = [
'status' => 1,
];
/**
* [getDataList 获取列表]
* @return [array]
*/
public function getDataList($request)
{
$request = $this->fmtRequest( $request );
$map = $request['map'];
if (isset($map['search'])) {
$map['name'] = ['like', '%'.$map['search'].'%'];
unset($map['search']);
} else {
$map = where_arr($map, 'member'); //高级筛选
}
$data = $this->where($map)->page($request['page'], $request['limit'])->select();
return $data;
}
}

@ -0,0 +1,652 @@
<?php
// +----------------------------------------------------------------------
// | Description: 跟进记录
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
class Record extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_record';
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $autoWriteTimestamp = true;
protected $types_arr = ['crm_leads','crm_customer','crm_contacts','crm_product','crm_business','crm_contract','oa_log','admin_record'];
/**
* [getDataList 跟进记录list]
* @author Michael_xu
* @param [string] $map [查询条件]
* @param [number] $page [当前页数]
* @param [number] $limit [每页数量]
* @param [string] $by [分类]
* @param [string] $types [类别]
* @param [number] $types_id [类别Id]
* @return [array]
*/
public function getDataList($request, $by = '')
{
$userModel = new \app\admin\model\User();
$commonModel = new \app\admin\model\Comment();
$fileModel = new \app\admin\model\File();
$structureModel = new \app\admin\model\Structure();
$lableModel = new \app\work\model\WorkLable();
$taskModel = new \app\work\model\Task();
$request = $this->fmtRequest( $request );
$map = $request['map'] ? : [];
if (!$map['types'] || !$map['types_id']) {
$this->error = '参数错误';
return false;
}
switch ($by) {
case 'record' :
$where_record = [];
$where_record['types'] = $map['types'];
$where_record['types_id'] = $map['types_id'];
$contactsWhere = [];
$businessWhere = [];
$contractWhere = [];
//客户模块下包含被转化线索的跟进记录
if ($map['types'] == 'crm_customer') {
if ($leads_id = db('crm_leads')->where(['customer_id' => $map['types_id']])->value('leads_id')) {
$whereOr = [];
$whereOr['types'] = 'crm_leads';
$whereOr['types_id'] = $leads_id;
}
$customerWhere['customer_id'] = $where_record['types_id'];
# 查询客户的联系人ID串
$contacts = Db::name('crm_contacts')->field(['contacts_id'])->where($customerWhere)->select();
if (!empty($contacts)) {
$contactsWhere['types'] = 'crm_contacts';
$contactsWhere['types_id'] = array_reduce($contacts, function ($result, $value) {
return array_merge($result, array_values($value));
}, []);
}
# 查询客户的商机ID串
$business = Db::name('crm_business')->field(['business_id'])->where($customerWhere)->select();
if (!empty($business)) {
$businessWhere['types'] = 'crm_business';
$businessWhere['types_id'] = array_reduce($business, function ($result, $value) {
return array_merge($result, array_values($value));
}, []);
}
# 查询客户的合同ID串
$contract = Db::name('crm_contract')->field(['contract_id'])->where($customerWhere)->select();
if (!empty($contract)) {
$contractWhere['types'] = 'crm_contract';
$contractWhere['types_id'] = array_reduce($contract, function ($result, $value) {
return array_merge($result, array_values($value));
}, []);
}
}
//联系人下包含关联的客户的跟进记录
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')
->select(function($query) use ($where_record, $whereOr, $contractWhere, $businessWhere, $contactsWhere){
$query->where($where_record)
->whereOr(function ($query) use ($whereOr) {
$query->where($whereOr);
})
->whereOr(function ($query) use ($contractWhere) {
if (!empty($contractWhere['types_id'])) $query->where('types', $contractWhere['types']);
if (!empty($contractWhere['types_id'])) $query->whereIn('types_id', $contractWhere['types_id']);
})
->whereOr(function ($query) use ($businessWhere) {
if (!empty($businessWhere['types_id'])) $query->where('types', $businessWhere['types']);
if (!empty($businessWhere['types_id'])) $query->whereIn('types_id', $businessWhere['types_id']);
})
->whereOr(function ($query) use ($contactsWhere) {
if (!empty($contactsWhere['types_id'])) $query->where('types', $contactsWhere['types']);
if (!empty($contactsWhere['types_id'])) $query->whereIn('types_id', $contactsWhere['types_id']);
});
});
foreach ($list as $k=>$v) {
$list[$k]['id'] = $v['record_id'];
$list[$k]['cate'] = 1;
}
$dataCount = db('admin_record')
->where(function($query) use ($where_record, $whereOr, $contractWhere, $businessWhere, $contactsWhere){
$query->where($where_record)->whereOr(function ($query) use ($whereOr) {
$query->where($whereOr);
})
->whereOr(function ($query) use ($contractWhere) {
if (!empty($contractWhere['types'])) $query->where('types', $contractWhere['types']);
if (!empty($contractWhere['types_id'])) $query->whereIn('types_id', $contractWhere['types_id']);
})
->whereOr(function ($query) use ($businessWhere) {
if (!empty($businessWhere['types'])) $query->where('types', $businessWhere['types']);
if (!empty($businessWhere['types_id'])) $query->whereIn('types_id', $businessWhere['types_id']);
})
->whereOr(function ($query) use ($contactsWhere) {
if (!empty($contactsWhere['types'])) $query->where('types', $contactsWhere['types']);
if (!empty($contactsWhere['types_id'])) $query->whereIn('types_id', $contactsWhere['types_id']);
});
})->count();
break;
case 'log' :
$where_log = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'oa_log') ? : [];
$where_log['log_id'] = ['in',$r_logs];
$list = db('oa_log')
->page($request['page'], $request['limit'])
->order('create_time desc')
->where($where_log)
->select();
foreach ($list as $k=>$v) {
$list[$k]['id'] = $v['log_id'];
$list[$k]['cate'] = 2;
}
$dataCount = db('oa_log')->where($where_log)->count();
break;
case 'examine' :
$where_examine = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'oa_examine') ? : [];
$where_examine['examine_id'] = ['in',$r_logs];
$list = db('oa_examine')
->page($request['page'], $request['limit'])
->order('create_time desc')
->where($where_examine)
->select();
foreach ($list as $k=>$v) {
$list[$k]['id'] = $v['examine_id'];
$list[$k]['cate'] = 3;
}
$dataCount = db('oa_examine')->where($where_examine)->count();
break;
case 'task' :
$where_task = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'task') ? : [];
$where_task['task_id'] = ['in',$r_logs];
$list = db('task')
->page($request['page'], $request['limit'])
->order('create_time desc')
->where($where_task)
->select();
foreach ($list as $k=>$v) {
$list[$k]['id'] = $v['task_id'];
$list[$k]['cate'] = 4;
}
$dataCount = db('task')->where($where_task)->count();
break;
case 'event' :
$where_event = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'oa_event') ? : [];
$where_event['event_id'] = ['in',$r_logs];
$list = db('oa_event')
->page($request['page'], $request['limit'])
->order('create_time desc')
->where($where_event)
->select();
foreach ($list as $k=>$v) {
$list[$k]['id'] = $v['event_id'];
$list[$k]['cate'] = 5;
}
$dataCount = db('oa_event')->where($where_event)->count();
break;
default :
$where_log = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'oa_log') ? : [];
$where_log['log_id'] = ['in',$r_logs];
$sqlArr[] = Db::table('__OA_LOG__')
->where($where_log)
->field(['log_id as id,create_time,create_user_id,2 as cate,content'])
->buildSql();
$where_examine = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'oa_examine') ? : [];
$where_examine['examine_id'] = ['in',$r_logs];
$sqlArr[] = Db::table('__OA_EXAMINE__')
->where($where_examine)
->field(['examine_id as id,create_time,create_user_id,3 as cate,content'])
->buildSql();
$where_task = [];
$r_logs = $this->getRelationIdsByType($map['types'], $map['types_id'], 'task') ? : [];
$where_task['task_id'] = ['in',$r_logs];
$sqlArr[] = Db::table('__TASK__')
->where($where_task)
->field(['task_id as id,create_time,create_user_id,4 as cate,name as content'])
->buildSql();
$where_record = [];
$where_record['types'] = $map['types'];
$where_record['types_id'] = $map['types_id'];
//客户模块下包含被转化线索的跟进记录
if ($map['types'] == 'crm_customer') {
if ($leads_id = db('crm_leads')->where(['customer_id' => $map['types_id']])->value('leads_id')) {
$whereOr = [];
$whereOr['types'] = 'crm_leads';
$whereOr['types_id'] = $leads_id;
}
}
$e = Db::table('__ADMIN_RECORD__')
->alias('record')
->where($where_record)
->whereOr($whereOr)
->field(['record_id as id,create_time,create_user_id,1 as cate,content'])
->union($sqlArr)
->buildSql();
$list = Db::table($e.' a')
->page($request['page'], $request['limit'])
->order('create_time desc')
->select();
$dataCount = Db::table($e.' a')->count();
break;
}
$admin_user_ids = $userModel->getAdminId();
foreach ($list as $k=>$v) {
$create_user_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
$list[$k]['create_user_info'] = $create_user_info;
$content = '';
$fileList = [];
$imgList = [];
$where = [];
$where['module_id'] = $v['id'];
$relation_list = [];
switch ($v['cate']) {
case '1' :
$where['module'] = 'admin_record';
$relation_list = $this->getListByRelationId('record', $v['id']);
$dataInfo = [];
break;
case '2' :
$where['module'] = 'oa_log';
$dataInfo = $v;
$dataInfo['create_user_info'] = $create_user_info;
$dataInfo['sendUserList'] = $userModel->getDataByStr($dataInfo['send_user_ids']) ? : [];
$dataInfo['sendStructList'] = $structureModel->getDataByStr($dataInfo['send_structure_ids']) ? : [];
$param['type_id'] = $dataInfo['log_id'];
$param['type'] = 'oa_log';
$dataInfo['replyList'] = $commonModel->read($param);
$is_update = 0;
$is_delete = 0;
//3天内的日志可删,可修改
if (($dataInfo['create_user_id'] == $user_id) && date('Ymd',$dataInfo['create_time']) > date('Ymd',(strtotime(date('Ymd',time()))-86400*3))) {
$is_update = 1;
$is_delete = 1;
}
$permission['is_update'] = $is_update;
$permission['is_delete'] = $is_delete;
$dataInfo['permission'] = $permission;
$relation_list = $this->getListByRelationId('log', $v['id']);
break;
case '3' :
$where['module'] = 'oa_examine';
$dataInfo = $v;
$dataInfo['category_name'] = db('oa_examine_category')->where(['category_id' => $dataInfo['category_id']])->value('title');
$dataInfo['create_user_info'] = $create_user_info;
$causeCount = 0;
$causeTitle = '';
$duration = $dataInfo['duration'] ? : '0.0';
$money = $dataInfo['money'] ? : '0.00';
if (in_array($dataInfo['category_id'],['3','5'])) {
$causeCount = db('oa_examine_travel')->where(['examine_id' => $dataInfo['examine_id']])->count() ? : 0;
if ($dataInfo['category_id'] == 3) $causeTitle = $causeCount.'个行程,共'.$duration.'天';
if ($dataInfo['category_id'] == 5) $causeTitle = $causeCount.'个报销事项,共'.$money.'元';
}
$dataInfo['causeTitle'] = $causeTitle;
$dataInfo['causeCount'] = $causeCount ? : 0;
//权限
//创建人或管理员有撤销权限
$permission = [];
$is_recheck = 0;
$is_update = 0;
$is_delete = 0;
if (((int)$dataInfo['create_user_id'] == $user_id || !in_array($userr_id, $admin_user_ids)) && (!in_array($dataInfo['check_status'],['2','3']) || (empty($dataInfo['check_status']) && empty($dataInfo['check_user_id'])))) {
$is_recheck = 1;
}
//创建人(待审状态且无审批人时可编辑)
if (($user_id == (int)$dataInfo['create_user_id']) && $dataInfo['check_status'] == 0 && empty($dataInfo['check_user_id'])) {
$is_update = 1;
$is_delete = 1;
}
$permission['is_recheck'] = $is_recheck;
$permission['is_update'] = $is_update;
$permission['is_delete'] = $is_delete;
$dataInfo['permission'] = $permission;
$relation_list = $this->getListByRelationId('examine', $v['id']);
break;
case '4' :
$where['module'] = 'work_task';
$relation_list = $this->getListByRelationId('task', $v['id']);
$dataInfo = $v;
$dataInfo['task_name'] = $dataInfo['name'];
if ($dataInfo['pid'] > 0) {
$p_det = Db::name('Task')->field('task_id,name')->where('task_id ='.$dataInfo['pid'])->find();
$dataInfo['pname'] = $p_det['name'];
} else {
$dataInfo['pname'] = '';
}
$subcount = Db::name('Task')->where(' ishidden =0 and ( status=1 ) and pid ='.$dataInfo['task_id'])->count();
$subdonecount = Db::name('Task')->where(' ishidden = 0 and status = 5 and pid ='.$dataInfo['task_id'])->count();
$dataInfo['subcount'] = $subcount; //子任务
$dataInfo['subdonecount'] = $subdonecount; //已完成子任务
$dataInfo['commentcount'] = Db::name('AdminComment')->where('type=1 and type_id ='.$dataInfo['task_id'])->count();
$dataInfo['filecount'] = Db::name('WorkTaskFile')->where('task_id ='.$dataInfo['task_id'])->count();
if ($dataInfo['lable_id']) {
$dataInfo['lableList'] = $lableModel->getDataByStr($dataInfo['lable_id']);
}else{
$dataInfo['lableList'] = array();
}
//参与人列表数组
//$userlist =$userModel->getDataByStr($value['owner_user_id']);
//$dataInfo['own_list'] = $userlist?$userlist: array();
//负责人信息
$dataInfo['main_user'] = $dataInfo['main_user_id'] ? $userModel->getUserById($dataInfo['main_user_id']) : array();
$dataInfo['relationCount'] = $taskModel->getRelationCount($dataInfo['task_id']);
break;
case '5' :
$where['module'] = 'oa_event';
$relation_list = $this->getListByRelationId('event', $v['id']);
$dataInfo = $v;
$dataInfo['create_user_info'] = $userModel->getUserById($dataInfo['create_user_id']);
$dataInfo['ownerList'] = $userModel->getDataByStr($dataInfo['owner_user_ids']) ? : [];
$dataInfo['remindtype'] = (int)$dataInfo['remindtype'];
$noticeList = Db::name('OaEventNotice')->where('event_id = '.$dataInfo['event_id'])->find();
if (!$noticeList) {
$dataInfo['is_repeat'] = 0;
} else {
$dataInfo['is_repeat'] = 1;
}
$dataInfo['stop_time'] = $noticeList ? $noticeList['stop_time'] : '';
$dataInfo['noticetype'] = $noticeList ? $noticeList['noticetype'] : '';
if ($noticeList['noticetype'] == '2') {
$dataInfo['repeat'] = $noticeList['repeated'] ? explode('|||',$noticeList['repeated']) : [];
} else {
$dataInfo['repeat'] = '';
}
break;
case '6' :
$where['module'] = 'work';
$relation_list = $this->getListByRelationId('work', $v['id']);
break;
}
$newFileList = [];
$newFileList = $fileModel->getDataList($where, 'all');
if ($newFileList['list']) {
foreach ($newFileList['list'] as $val) {
if ($val['types'] == 'file') {
$fileList[] = $val;
} else {
$imgList[] = $val;
}
}
}
$dataInfo['fileList'] = $fileList ? : [];
$dataInfo['imgList'] = $imgList ? : [];
$dataInfo['customerList'] = $relation_list['customerList'] ? : [];
$dataInfo['contactsList'] = $relation_list['contactsList'] ? : [];
$dataInfo['businessList'] = $relation_list['businessList'] ? : [];
$dataInfo['contractList'] = $relation_list['contractList'] ? : [];
if ($v['cate'] != 1) {
$list[$k] = ['dataInfo' => $dataInfo];
} else {
$list[$k]['dataInfo'] = $dataInfo;
}
}
$data = [];
$data['list'] = $list ? : [];
$data['dataCount'] = $dataCount ? : 0;
return $data;
}
/**
* 创建跟进记录信息
* @author Michael_xu
* @param
* @return
*/
public function createData($param)
{
$eventModel = new \app\oa\model\Event();
if (!$param['types'] || !$param['types_id'] || !in_array($param['types'], $this->types_arr)) {
$this->error = '参数错误';
return false;
}
//验证
$validate = validate($this->name);
if (!$validate->check($param)) {
$this->error = $validate->getError();
return false;
}
$param['business_ids'] = arrayToString($param['business_ids']);
$param['contacts_ids'] = arrayToString($param['contacts_ids']);
$fileArr = $param['file_id']; //接收表单附件
unset($param['file_id']);
if ($this->data($param)->allowField(true)->save()) {
//下次联系时间
$this->updateNexttime($param['types'], $param['types_id'], $param['next_time']);
//处理附件关系
if ($fileArr) {
$fileModel = new \app\admin\model\File();
$resData = $fileModel->createDataById($fileArr, 'admin_record', $this->record_id);
if ($resData == false) {
$this->error = '附件上传失败';
return false;
}
}
$data = [];
$data['record_id'] = $this->record_id;
return $data;
} else {
$this->error = '添加失败';
return false;
}
}
/**
* 根据主键获取详情
* @param array $param [description]
*/
public function getDataById($id = '')
{
$map['record_id'] = $id;
$dataInfo = db('admin_record')->where($map)->find();
if (!$dataInfo) {
$this->error = '暂无此数据';
return false;
}
$userModel = new \app\admin\model\User();
$dataInfo['create_user_info'] = $userModel->getUserById($dataInfo['create_user_id']);
return $dataInfo;
}
/**
* 相关业务ids
* @param $types 相关业务
* @param $types_id 相关业务ID
* @param $relation 相关模块
*/
public function getRelationIdsByType($types, $types_id, $relation)
{
$rIds = [];
switch ($relation) {
case 'oa_log' : $dbName = db('oa_log_relation'); $relationId = 'log_id'; break; //相关日志
case 'oa_event' : $dbName = db('oa_event_relation'); $relationId = 'event_id'; break; //相关日程
case 'task' : $dbName = db('task_relation'); $relationId = 'task_id'; break; //相关任务
case 'task_work' : $dbName = db('work_relation'); $relationId = 'work_id'; break; //相关项目
case 'oa_examine' : $dbName = db('oa_examine_relation'); $relationId = 'examine_id'; break; //相关审批
default : return []; break;
}
switch ($types) {
case 'crm_customer' : $rIds = $dbName->where(['customer_ids' => ['like', '%,'.$types_id.',%']])->column($relationId); break;
case 'crm_contacts' : $rIds = $dbName->where(['contacts_ids' => ['like', '%,'.$types_id.',%']])->column($relationId); break;
case 'crm_business' : $rIds = $dbName->where(['business_ids' => ['like', '%,'.$types_id.',%']])->column($relationId); break;
case 'crm_contract' : $rIds = $dbName->where(['contract_ids' => ['like', '%,'.$types_id.',%']])->column($relationId); break;
}
return $rIds ? : [];
}
/**
* 相关业务list
* @param $types 相关业务
* @param $types_id 相关业务ID
* @param $relation 相关模块
*/
public function getListByRelationId($relation, $relation_id)
{
$BusinessModel = new \app\crm\model\Business();
$ContactsModel = new \app\crm\model\Contacts();
$ContractModel = new \app\crm\model\Contract();
$CustomerModel = new \app\crm\model\Customer();
$LeadsModel = new \app\crm\model\Leads();
$data = [];
switch ($relation) {
case 'log' : $data = db('oa_log_relation')->where(['log_id' => $relation_id])->find(); break;
case 'event' : $data = db('oa_event_relation')->where(['event_id' => $relation_id])->find(); break;
case 'task' : $data = db('task_relation')->where(['task_id' => $relation_id])->find(); break;
case 'work' : $data = db('work_relation')->where(['work_id' => $relation_id])->find(); break;
case 'examine' : $data = db('oa_examine_relation')->where(['examine_id' => $relation_id])->find(); break;
case 'record' : $data = db('admin_record')->where(['record_id' => $relation_id])->find(); break;
case 'activity' : $data = db('crm_activity')->where(['activity_id' => $relation_id])->find(); break;
default : $data = []; break;
}
$data['customerList'] = $data['customer_ids'] ? $CustomerModel->getDataByStr($data['customer_ids']) : [];
$data['contactsList'] = $data['contacts_ids'] ? $ContactsModel->getDataByStr($data['contacts_ids']) : [];
$data['businessList'] = $data['business_ids'] ? $BusinessModel->getDataByStr($data['business_ids']) : [];
$data['contractList'] = $data['contract_ids'] ? $ContractModel->getDataByStr($data['contract_ids']) : [];
$data['leadsList'] = $data['leads_ids'] ? $LeadsModel->getDataByStr($data['leads_ids']) : [];
return $data ? : [];
}
/**
* 多标签list
* @param $types 相关业务
* @param $types_id 相关业务ID
* @param $relation 相关模块
*/
public function getListByLableId($relation, $relation_id)
{
$TaskModel = new \app\work\model\Task();
$data = [];
switch ($relation) {
case 'task' : $data = db('task')->where(['task_id' => $relation_id])->field('lable_id')->find(); break;
case 'work' : $data = db('work_relation')->where(['work_id' => $relation_id])->find(); break;
default : $data = []; break;
}
$data['lable'] = $data['lable_id'] ? $TaskModel->getDataByStr($data['lable_id']) : [];
return $data ? : [];
}
/**
* 相关模块下次联系时间
* @param types 类型
* @param types 类型ID
* @param next_time 下次联系时间
*/
public function updateNexttime($types, $types_id, $next_time)
{
switch ($types) {
case 'crm_customer' : $dbName = db('crm_customer'); $dbId = 'customer_id'; break;
case 'crm_leads' : $dbName = db('crm_leads'); $dbId = 'leads_id'; break;
case 'crm_contacts' : $dbName = db('crm_contacts'); $dbId = 'contacts_id'; break;
case 'crm_business' : $dbName = db('crm_business'); $dbId = 'business_id'; break;
default : break;
}
if (!$dbName || !$dbId) {
return true;
}
$data = [];
if ($next_time) {
$data['next_time'] = $next_time;
} else {
// 如果未填写下次联系时间,并且 原下次联系时间为当天,则把下次联系时间置空
$next_time = $dbName->where([$dbId => $types_id])->value('next_time');
list($start, $end) = getTimeByType();
if ($next_time >= $start && $next_time <= $end) {
$data['next_time'] = 0;
}
}
$data['update_time'] = time();
if (in_array($types,['crm_customer','crm_leads'])) $data['follow'] = '已跟进';
$dbName->where([$dbId => $types_id])->update($data);
return true;
}
/**
* 跟进记录删除
* @param types 类型
* @param types 类型ID数组
* @param
*/
public function delDataByTypes($types, $types_id)
{
if (!is_array($types_id)) {
$types_id[] = $types_id;
}
$fileModel = new \app\admin\model\File();
$record_ids = db('crm_activity')->where(['activity_type' => $types,'activity_type_id' => ['in',$types_id]])->column('activity_id');
db('crm_activity')->where(['activity_type' => $types,'activity_type_id' => ['in',$types_id],'type'=>1])->delete();
//删除关联附件
$fileModel->delRFileByModule('crm_activity',$record_ids);
return true;
}
/**
* 查询最近更进记录
*
* @param string $types 关联类型
* @param array $types_id_list 类型ID
* @return array
* @author Ymob
* @datetime 2019-12-11 10:43:04
*/
public static function getLastRecord($types, $types_id_list)
{
$prefix = config('database.prefix');
$types_ids = implode(',', $types_id_list) ?: '-1';
$list = self::field(['types_id', 'content'])
->where("
`record_id` IN (
SELECT
MAX(`record_id`)
FROM
`{$prefix}admin_record`
WHERE
`types` = '{$types}'
AND `types_id` IN ({$types_ids})
GROUP BY
`types_id`
)
")
->select();
$res = [];
foreach ($list as $val) {
$res[$val['types_id']] = $val['content'];
}
return $res;
}
}

@ -0,0 +1,131 @@
<?php
// +----------------------------------------------------------------------
// | Description: 规则
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
use \think\Db;
class Rule extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_rule';
/**
* [getDataList 获取列表]
* @param string $type [是否为树状结构]
* @param int $pid 角色分类0客户自定义角色,1系统默认管理角色,2客户管理角色,3人力资源管理角色,4财务管理角色,5项目管理角色,6办公管理角色
* @return [array]
*/
public function getDataList($param)
{
$type = $param['type'];
$groupPid = $param['pid'] ? : 0;
$types = $this->groupsToRules($groupPid);
// 若type为tree则返回树状结构
if ($type == 'tree') {
$cat = new \com\Category('admin_rule', array('id', 'pid', 'title', 'title'));
$data = $cat->getList('', 0, 'id');
foreach ($data as $k => $v) {
if ($v['id'] == '31') {
unset($data[$k]);
continue;
}
$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);
$tree = new \com\Tree();
$list = $tree->list_to_tree($data, 'id', 'pid', 'child', 0, true, array('pid'));
} elseif ($types) {
$list = Db::name('AdminRule')->where(['types' => ['in',$types]])->select();
}
return $list;
}
//添加规则
public function createData($param)
{
if($param['pid'] && $param['name']&&$param['title']){
$pdet = Db::name('AdminRule')->where('id ='.$param['pid'].'')->find();
if ($pdet['level'] == 1) {
$data['level'] = 2;
} elseif ( $pdet['level'] == 2){
$data['level'] = 3;
} else {
$this->error = '等级参数错误';
return false;
}
$data['pid'] = $param['pid']; //上级ID
$data['name'] = $param['name']; //方法名
$data['title'] = $param['title'];//名称
$data['status'] = 1; //状态1 显示
//1超级管理员2系统设置管理员3部门与员工管理员4审批流管理员5工作台管理员6客户管理员7项目管理员8公告管理员
$data['types'] = $param['types'];
$flag = $this->insert($data);
if ($flag) {
return true;
} else {
$this->error = '添加失败';
return false;
}
} else {
$this->error = '参数错误';
return false;
}
}
//编辑规则
public function updateDataById($param,$id)
{
if ($param['id']) {
$flag = $this->where('id ='.$param['id'].'')->update($param);
return true;
} else {
$this->error = '参数错误';
return false;
}
}
/**
* 角色与规则对照表
* @param $groupPid 角色分类0客户自定义角色,1系统默认管理角色,2客户管理角色,3人力资源管理角色(原客户),4财务管理角色(原客户),5项目管理角色,6办公管理角色,7人力资源管理角色,8财务管理角色
* @param ruletypes 0系统设置1工作台2客户管理3项目管理4人力资源5财务管理6商业智能(客戶)
* @return
*/
public function groupsToRules($groupPid)
{
$ruleTypes = [];
switch ($groupPid) {
case '0' :
case '2' :
$ruleTypes = ['2','6'];
break;
case '1' :
$ruleTypes = ['0'];
break;
case '5' :
$ruleTypes = ['3'];
break;
case '6' :
$ruleTypes = ['1','7'];
break;
default : $ruleTypes = [$groupPid];
break;
}
return $ruleTypes;
}
}

@ -0,0 +1,529 @@
<?php
// +----------------------------------------------------------------------
// | Description: 场景
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Db;
use app\admin\model\Common;
class Scene extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_scene';
protected $createTime = 'create_time';
protected $updateTime = false;
protected $autoWriteTimestamp = true;
private $types_arr = ['crm_leads','crm_customer','crm_customer_pool','crm_contacts','crm_product','crm_business','crm_contract','crm_receivables','crm_visit','crm_invoice']; //支持场景的分类
protected $type = [
'data' => 'array',
];
/**
* 创建场景
* @param
* @return
*/
public function createData($param, $types = '')
{
if (empty($types)) {
$this->error = '参数错误';
return false;
}
if (empty($param['name'])) {
$this->error = '场景名称必填';
return false;
}
$user_id = $param['user_id'];
if ($this->where(['types'=>$types,'user_id'=>$user_id,'name'=>$param['name']])->find()) {
$this->error = '场景名称已存在';
return false;
}
# 转自定义场景结构
$sceneData = [];
foreach ($param['data'] AS $key => $value) {
foreach ($value AS $k => $v) {
$sceneData[$k] = [
'condition' => trim($v['condition']),
'value' => $v['value'],
'form_type' => $v['form_type'],
'name' => $v['name'],
'type' => $v['type']
];
}
}
if (!empty($sceneData)) $param['data'] = $sceneData;
$max_order_id = $this->getMaxOrderid($types, $user_id);
$param['order_id'] = $max_order_id ? $max_order_id+1 : 0;
$param['update_time'] = time();
$param['type'] = 0;
$param['bydata'] = '';
$res = $this->allowField(true)->save($param);
if ($res) {
//设置默认
if ($param['is_default']) {
$defaultData = [];
$defaultData['types'] = $types;
$defaultData['user_id'] = $user_id;
$this->defaultDataById($defaultData, $this->scene_id);
}
return true;
} else {
$this->error = '添加失败';
return false;
}
}
/**
* [getDataList 场景list]
* @param types 分类
* @author Michael_xu
* @return [array]
*/
public function getDataList($types, $user_id)
{
$fieldModel = new \app\admin\model\Field();
$userModel = new \app\admin\model\User();
if (!in_array($types, $this->types_arr)) {
$this->error = '参数错误';
return false;
}
$map['user_id'] = $user_id;
$map['is_hide'] = 0;
$map['types'] = $types;
$list = db('admin_scene')
->where($map)
->whereOr(function ($query) use ($types) {
$query->where(['types' => $types,'type' => 1]);
})->order('order_id asc,scene_id asc')
->select();
$defaultSceneId = db('admin_scene_default')->where(['types' => $types,'user_id' => $user_id])->value('scene_id');
$fieldList = $fieldModel->getField(['types' => $types]);
$newFieldList = [];
foreach ($fieldList as $k=>$v) {
$field = $v['field'];
if ($v['field'] == 'customer_id') $field = 'customer_name';
$newFieldList[$field] = $v;
}
foreach ($list as $k=>$v) {
if ($v['scene_id'] == $defaultSceneId) {
$list[$k]['is_default'] = 1;
}
$data = $v['data'] ? json_decode($v['data'],true) : [];
if ($data) {
foreach ($data as $key=>$val) {
$setting = $newFieldList[$key]['setting'];
$data[$key]['setting'] = $setting;
if ($val['form_type'] == 'user' && $val['value']) {
$userInfo = $userModel->getUserById($val['value']);
$data[$key]['setting']['realname'] = $userInfo['realname'];
$data[$key]['setting']['id'] = $userInfo['id'];
}
}
}
$list[$k]['data'] = $data ? : [];
}
$map['is_hide'] = 1;
$hideList = $this->where($map)->order('order_id asc')->select();
$data = [];
$data['list'] = $list;
$data['hideList'] = $hideList;
return $data;
}
/**
* 根据主键获取详情
* @param array $param [description]
* @author Michael_xu
*/
public function getDataById($id = '', $user_id = '', $types = '')
{
$where = [];
$where['scene_id'] = $id;
// $where['user_id'] = [['=',$user_id],['=',0],'or'];
$data = db('admin_scene')->where($where)->find();
if (!$types) {
$types = $data['types'] ? : '';
}
//处理data
if ($data['bydata'] && $types) {
$data = $this->getByData($types, $data['bydata'], $user_id);
} else {
$data = json_decode($data['data'],true);
if (is_array($data)) {
foreach ($data as $k=>$v) {
if ($v['form_type'] == 'business_type') {
$data[$k]['value'] = $v['type_id'];
}
}
}
}
return $data ? : [];
}
/**
* 根据主键修改
* @param array $param [description]
* @author Michael_xu
*/
public function updateDataById($param, $id)
{
$checkData = $this->get($id);
$sceneInfo = $checkData->data;
$user_id = $param['user_id'];
if (!$sceneInfo) {
$this->error = '暂无数据';
return false;
}
//权限(只能编辑自己的)
if ($sceneInfo['user_id'] !== $user_id) {
$this->error = '参数错误';
return false;
}
if (empty($param['name'])) {
$this->error = '场景名称必填';
return false;
}
if ($this->where(['scene_id'=>['neq',$id],'types'=>$types,'user_id'=>$user_id,'name'=>$param['name']])->find()) {
$this->error = '场景名称已存在';
return false;
}
# 转自定义场景结构
$sceneData = [];
foreach ($param['data'] AS $key => $value) {
foreach ($value AS $k => $v) {
$sceneData[$k] = $v;
}
}
if (!empty($sceneData)) $param['data'] = $sceneData;
$param['update_time'] = time();
// $scene_data = $this->dataChangeString($param);
//处理data数据
$res = $this->allowField(true)->save($param, ['scene_id' => $id]);
if ($param['is_default'] == 1) {
$this->defaultDataById($param,$param['id']);
}
if ($res) {
return true;
} else {
$this->error = '修改失败';
return false;
}
}
/**
* 场景设置为默认
* @param types 类型
* @param user_id 人员ID
* @param id 场景ID
* @author Michael_xu
*/
public function defaultDataById($param, $id)
{
if (!$param['types'] || !$id) {
$this->error = '参数错误';
return false;
}
$resInfo = db('admin_scene_default')->where(['types' => $param['types'],'user_id' => $param['user_id']])->find();
if ($resInfo) {
$res = db('admin_scene_default')->where(['types' => $param['types'],'user_id' => $param['user_id']])->update(['scene_id' => $id]);
} else {
$data = [];
$data['types'] = $param['types'];
$data['user_id'] = $param['user_id'];
$data['scene_id'] = $id;
$res = db('admin_scene_default')->insert($data);
}
if (!$res) {
$this->error = '设置失败或数据无变化';
return false;
}
return true;
}
/**
* 场景数据转换(字符串形式存储)
* @param
* @author Michael_xu
* @return
*/
public function dataChangeString($param = [])
{
$scene_data = '[';
$field_arr = [];
$i = 0;
foreach ($param['data'] as $k=>$v) {
if ($v != '' && !in_array($v['field'], $field_arr)) {
$i++;
if ($i == 1) {
$scene_data .= $v['field']."=>[";
} else {
$scene_data .= ",".$v['field']."=>[";
}
$scene_data .= "field=>".$v['field'].",";
//处理条件和值
foreach ($param as $k1=>$v1) {
switch ($k1) {
case 'condition' : $scene_data .= "condition=>".$v1.","; break;
case 'value' : $scene_data .= "value=>".$v1.","; break;
case 'state' :
case 'city' :
case 'area' :
//处理地址类型数据
$scene_data .= $k1."=>".$v1.","; break;
case 'start' : $scene_data .= "start=>".$v1.","; break;
case 'end' : $scene_data .= "end=>".$v1.","; break;
case 'start_date' : $scene_data .= "start_date=>".$v1.","; break;
case 'end_date' : $scene_data .= "end_date=>".$v1.","; break;
}
}
$form_type = '';
//处理字段类型
if ($v['field'] == 'create_time' || $v['field'] == 'update_time') {
$form_type = 'datetime';
} else {
$form_type = db('admin_fields')->where(['types'=>$param['types'],'field'=>$v['field'],'is_main'=>1])->column('form_type');
}
$scene_data .= "form_type=>".$form_type;
$field_arr[] = $v['field'];
}
$scene_data .= ']';
}
$scene_data .= ']';
return $scene_data;
}
/**
* 场景排序最大值
* @param
* @author Michael_xu
* @return
*/
public function getMaxOrderid($types, $user_id)
{
$maxOrderid = $this->where(['types' => $types, 'user_id' => $user_id])->max('order_id');
return $maxOrderid ? : 0;
}
/**
* 场景数据转数组格式用于where条件
* @param
* @author Michael_xu
* @return
*/
public function dataChangeArray($string)
{
$data_arr = [];
$where = [];
eval('$data_arr = '.$string.';');
foreach ($data_arr as $k=>$v) {
if ($v['state']) {
$address_where[] = '%'.$v['state'].'%';
if ($v['city']) {
$address_where[] = '%'.$v['city'].'%';
if ($v['area']) {
$address_where[] = '%'.$v['area'].'%';
}
}
if ($v['condition'] == 'not_contain') {
$where[$k] = ['notlike', $address_where, 'OR'];
} else {
$where[$k] = ['like', $address_where, 'AND'];
}
} elseif (!empty($v['start']) || !empty($v['end'])) {
if ($v['start'] && $v['end']) {
$where[$k] = ['between',[strtotime($v['start']),strtotime($v['end'])+86399]];
} elseif ($v['start']) {
$where[$k] = ['egt',strtotime($v['start'])];
} else {
$where[$k] = ['elt',strtotime($v['end'])+86399];
}
} elseif (!empty($v['value'])) {
$where[$k] = field($v['value'],$v['condition']);
}
}
return $where ? : [];
}
/**
* 场景排序
* @param ids 场景id数组
* @param hide_ids 隐藏场景id数组
* @author Michael_xu
* @return
*/
public function listOrder($param, $user_id)
{
$res = true;
$resHide = true;
//使用
$data = [];
foreach ($param['ids'] as $k=>$v) {
$data[] = ['scene_id' => $v,'order_id' => $k,'update_time' => time(),'user_id' => $user_id,'is_hide' => 0];
}
if ($param['ids']) $res = $this->isUpdate()->saveAll($data);
//隐藏
$hideData = [];
foreach ($param['hide_ids'] as $k=>$v) {
$hideData[] = ['scene_id' => $v,'order_id' => $k,'update_time' => time(),'user_id' => $user_id,'is_hide' => 1];
}
if ($param['hide_ids']) $resHide = $this->isUpdate()->saveAll($hideData);
if ($res == false || $resHide == false) {
$this->error = '设置出错,请重试';
return false;
}
return true;
}
/**
* [getDefaultData 默认场景]
* @param types 分类
* @author Michael_xu
* @return [array]
*/
public function getDefaultData($types, $user_id)
{
$where = [];
$where['types'] = $types;
$where['user_id'] = $user_id;
$scene_id = db('admin_scene_default')->where($where)->value('scene_id');
if (!$scene_id && in_array($types,['crm_leads','crm_customer','crm_business','crm_contacts','crm_contract','crm_receivables','crm_visit'])) {
$resData['bydata'] = 'all';
} else {
$resData = db('admin_scene')->where(['scene_id' => $scene_id])->find();
}
if ($resData['bydata']) {
$data = $this->getByData($types, $resData['bydata'], $user_id);
} else {
//处理data
$data = $resData ? json_decode($resData,true) : [];
}
return $data;
}
/**
* [getByData 系统场景数据]
* @param types 分类
* @author Michael_xu
* @return [array]
*/
public function getByData($types, $bydata, $user_id)
{
// print_r($types . '--');
// print_r($bydata . '--');
// print_r($user_id);
// exit;
$map = [];
$auth_user_ids = [];
$part_user_ids = [];
switch ($bydata) {
case 'me' :
# 我负责的
$auth_user_ids[] = $user_id;
break;
case 'mePart' :
# 我参与的(即相关团队)
$part_user_ids = $user_id;
break;
case 'sub' :
# 下属负责的
$auth_user_ids = getSubUserId(false) ? : ['-1'];
break;
case 'all' :
# 全部
$auth_user_ids = '';
break;
case 'is_transform' :
# 已转化线索
$map['is_transform'] = ['condition' => 'eq', 'value' => 1, 'form_type' => 'text', 'name' => ''];
break;
case 'pool' :
# 今日进入公海的客户
$customerModel = new \app\crm\model\Customer();
$map = $customerModel->getWhereByToday();
break;
case 'win_business' :
# 赢单的商机
$map['is_end'] = ['condition' => 'eq', 'value' => 1];
break;
case 'fail_business' :
# 输单的商机
$map['is_end'] = ['condition' => 'eq', 'value' => 2];
break;
case 'star' :
$where = $this->getStarParam($types, $user_id);
if (!empty($where)) $map = $where;
break;
default :
# 全部
$auth_user_ids = '';
}
$auth_user_ids = $auth_user_ids ? : [];
if ($auth_user_ids) {
$map['owner_user_id'] = ['condition' => 'in','value' => $auth_user_ids,'form_type' => 'text','name' => ''];
}
if ($part_user_ids) {
$map['ro_user_id'] = $part_user_ids ? : '';
$map['rw_user_id'] = $part_user_ids ? : '';
}
return $map;
}
/**
* 获取我的关注条件
*
* @param $types
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getStarParam($types, $user_id)
{
$where = [];
$result = [];
$data = Db::name('crm_star')->field(['target_id'])->where(['user_id' => $user_id, 'type' => 'crm_' . $types])->select();
foreach ($data AS $key => $value) $result[] = $value['target_id'];
if ($types == 'leads') $where['leads_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
if ($types == 'customer') $where['customer_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
if ($types == 'contacts') $where['contacts_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
if ($types == 'business') $where['business_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
return $where;
}
/**
* [updateData 跳过验证的编辑]
* @param types 分类
* @author Michael_xu
* @return [array]
*/
public function updateData($data, $scene_id)
{
$param['data'] = is_array($data) ? $data : '';
$param['update_time'] = time();
$res = $this->allowField(true)->save($param, ['scene_id' => $scene_id]);
if ($res) {
return true;
} else {
$this->error = '修改失败';
return false;
}
}
}

@ -0,0 +1,118 @@
<?php
// +----------------------------------------------------------------------
// | Description: 组织架构
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
use think\Db;
class Structure extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_structure';
/**
* [getDataList 获取列表]
* @return [array]
*/
public function getDataList($type='')
{
$cat = new \com\Category('admin_structure', array('id', 'pid', 'name', 'title'));
$data = $cat->getList('', 0, 'id');
// 若type为tree则返回树状结构
if ($type == 'tree') {
$tree = new \com\Tree();
$data = $tree->list_to_tree($data, 'id', 'pid', 'child', 0, true, array(''));
}
return $data;
}
/*
*根据字符串展示参与部门 use by work
*add by yykun
*/
public function getDataByStr($idstr)
{
$isArr = stringToArray($idstr);
if (!$isArr) {
return false;
}
$list = $this->field('id as structure_id,name')->where(['id' => ['in',$isArr]])->select();
return $list;
}
/*
*根据部门ID获取信息 use by work
*add by yykun
*/
public function getDataByID( $id ='')
{
$det = Db::name('AdminStructure')->where('id ='.$id)->find();
return $det;
}
public function delStrById($id)
{
if (!$id) {
$this->error = '删除失败';
return false;
}
$dataInfo = $this->getDataByID($id);
if (empty($dataInfo['pid'])) {
$this->error = '删除失败';
return false;
}
//部门是否被使用
$allStrIds = [];
$allStrIds[] = $id;
$allSubStrIds = $this->getAllChild($id);
$allStrIds = array_merge($allStrIds, $allSubStrIds); //全部关联部门(包含下属部门)
$resUser = db('AdminUser')->where(['structure_id' => ['in',$allStrIds]])->find();
if ($resUser) {
$this->error = '该部门或其下属部门已存在员工,不能删除';
return false;
}
$resDel = $this->delDataById($id, true);
if (!$resDel) {
$this->error = '删除失败';
return false;
} else {
return true;
}
}
/**
* [getStructureNameByArr 根据主键获取详情]
* @param string $id [主键]
* @return [array]
*/
public function getStructureNameByArr($ids = [])
{
if (!is_array($ids)) {
$idArr[] = $ids;
} else {
$idArr = $ids;
}
$data = $this->where(['id' => array('in', $idArr)])->column('name');
return $data ? : [];
}
/*
*根据字符串展示参与部门 use by work
*add by yykun
*/
public function getListByStr($str)
{
$idArr = stringToArray($str);
$list = $this->field('id,name')->where(['id' => ['in',$idArr]])->select();
return $list;
}
}

@ -0,0 +1,18 @@
<?php
// +----------------------------------------------------------------------
// | Description:
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
class Sync extends Common
{
public function syncData($param)
{
return true;
}
}

@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | Description: 系统基础
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\admin\model\Common;
use think\Db;
class System extends Common
{
protected $name = 'admin_system';
//列表
public function getDataList()
{
$list = Db::name('AdminSystem')->select();
$temp = array();
foreach ($list as $key => $value) {
$temp[$value['name']] = $value['value'];
}
$temp['logo'] = !empty($temp['logo']) ? getFullPath($temp['logo']) : '';
return $temp;
}
//新建
public function createData($param)
{
if( isset($param['name'])){
$data['name'] = 'name';
$data['value'] = $param['name'];
$data['description'] = '网站名称';
$this->where('id=1')->update($data);
}
return true;
}
}

@ -0,0 +1,28 @@
<?php
/**
* 系统日志模型
*
* @author qifan
* @date 2020-11-30
*/
namespace app\admin\model;
use think\Model;
class SystemLog extends Model
{
protected $name = 'admin_system_log';
protected $pk = 'log_id';
/**
* 关联后台员工表姓名
*
* @return \think\model\relation\HasOne
*/
public function toAdminUser()
{
return $this->hasOne('User', 'id', 'user_id')->bind(['source_name' => 'realname']);
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,198 @@
<?php
// +----------------------------------------------------------------------
// | Description: 字段列表配置
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\admin\model;
use think\Config;
use think\Db;
use think\Model;
class UserField extends Model
{
protected $name = 'admin_user_field';
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $autoWriteTimestamp = true;
protected $type = [
'datas' => 'array',
];
/**
* 设置配置信息
* @author Michael_xu
* @param types 分类
* @param param 参数
* @param id 主键ID
* @return
*/
public function updateConfig($types, $param, $id = '')
{
if (!is_array($param['value']) || ($param['hide_value'] && !is_array($param['hide_value']))) {
$this->error = '参数错误';
return false;
}
$data = [];
if ($id) {
$resInfo = $this->where(['id' => $id])->find();
} else {
$resInfo = $this->where(['types' => $types,'user_id' => $param['user_id']])->find();
}
if (!$resInfo) {
$data['types'] = $types;
$data['user_id'] = $param['user_id'];
}
//处理value
$valueData = [];
//展示列
if ($param['value']) {
foreach ($param['value'] as $k=>$v) {
$valueData[$v['field']]['width'] = $v['width'];
$valueData[$v['field']]['is_hide'] = 0;
}
}
//隐藏列
if ($param['hide_value']) {
foreach ($param['hide_value'] as $k=>$v) {
$valueData[$v['field']]['width'] = $v['width'];
$valueData[$v['field']]['is_hide'] = 1;
}
}
$data['datas'] = $valueData;
if ($resInfo) {
$data['id'] = $resInfo['id'];
$res = $this->update($data);
} else {
$res = $this->save($data);
}
if ($res == false) {
$this->error = '设置出错';
return false;
}
return true;
}
/**
* 配置信息详情
* @author Michael_xu
* @param types 分类
* @return
*/
public function getConfig($types, $user_id)
{
$data = $this->where(['types' => $types,'user_id' => $user_id])->value('datas');
return $data ? : [];
}
/**
* 配置列宽度
* @author Michael_xu
* @param types 分类
* @param field 字段
* @param width 宽度
* @return
*/
public function setColumnWidth($types, $field, $width, $user_id)
{
$info = db('admin_user_field')->where(['types' => $types,'user_id' => $user_id])->find();
if ($info) {
$datas = json_decode($info['datas'], true);
$datas[$field]['width'] = $width;
$datas = json_encode($datas);
$res = $this->where(['id' => $info['id']])->update(['datas' => $datas]);
} else {
$newTypes = $types;
if ($types == 'crm_customer_pool') $newTypes = 'crm_customer';
$fieldArr = db('admin_field')->where(['types' => ['in',['',$newTypes]]])->field('field,name')->order('types desc,order_id asc')->select();
$value = [];
foreach ($fieldArr as $k=>$v) {
$field_width = '';
if ($field == $v['field']) {
$field_width = $width;
}
$value[$v['field']]['width'] = $field_width;
$value[$v['field']]['is_hide'] = 0;
$value[$v['field']]['field'] = $v['field'];
}
$param['value'] = $value;
$param['hide_value'] = [];
$param['user_id'] = $user_id;
$res = $this->updateConfig($types, $param);
}
if (!$res) {
$this->error = '设置出错,请重试!';
return false;
}
return true;
}
/**
* 列表数据
* @author Michael_xu
* @param types 分类
* @return
*/
public function getDataList($types, $user_id)
{
$fieldArr = (new Field)->getFieldList($types);
$fieldList = [];
$field_list = [];
foreach ($fieldArr as $k=>$v) {
$fieldList[] = $v['field'];
$field_list[$v['field']]['name'] = $v['name'];
$fieldArr[$k]['width'] = '';
}
//已设置字段
$value = $this->where(['types' => $types,'user_id' => $user_id])->value('datas');
$value = $value ? json_decode($value, true) : [];
$valueList = [];
$value_list = []; //显示列
$hideList = [];
$hide_list = []; //隐藏列
if ($value) {
$a = 0;
$b = 0;
foreach ($value as $k=>$v) {
if (empty($v['is_hide'])) {
$valueList[] = $k;
$value_list[$a]['field'] = $k;
$value_list[$a]['width'] = $v['width'];
$value_list[$a]['name'] = $field_list[$k]['name'];
$a++;
} else {
$hideList[] = $k;
$hide_list[$b]['field'] = $k;
$hide_list[$b]['width'] = $v['width'];
$hide_list[$b]['name'] = $field_list[$k]['name'];
$b++;
}
}
$diffList = $valueList ? array_diff($fieldList, $valueList) : $fieldList;
//隐藏的列(新增的字段数据)
$hideList = $hideList ? array_diff($diffList,$hideList) : $diffList;
foreach ($hideList as $k=>$v) {
$hide_list[$b]['field'] = $v;
$hide_list[$b]['width'] = '';
$hide_list[$b]['name'] = $field_list[$v]['name'];
$b++;
}
} else {
$value_list = array_values($fieldArr);
$hide_list = [];
}
$data = [];
$data['value_list'] = $value_list ? : []; //展示列
$data['hide_list'] = $hide_list ? : []; //隐藏列
return $data ? : [];
}
}

@ -0,0 +1,22 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminField extends Validate{
protected $rule = [
'field' => ['regex'=>'/^[a-z]([a-z]|_)+[a-z]$/i'],
'name' => 'require',
'types' => 'require',
'form_type' => 'require',
];
protected $message = [
'field.regex' => '字段名称格式不正确!',
'name.require' => '字段标识必须填写',
'types.require' => '分类必须填写',
'form_type.require' => '字段类型必须填写',
];
}

@ -0,0 +1,21 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminGroup extends Validate{
protected $rule = [
'title' => 'require',
'types' => 'require',
];
protected $message = [
'title.require' => '角色名称必须填写',
'types.require' => '角色类型必须选择',
];
protected $scene = [
'edit' => ['id'],
];
}

@ -0,0 +1,16 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminPost extends Validate{
protected $rule = [
'name' => 'require',
];
protected $message = [
'name.require' => '岗位名称必须填写',
];
}

@ -0,0 +1,21 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminRecord extends Validate{
protected $rule = [
'category' => 'require',
'content' => 'require',
];
protected $message = [
'category.require' => '跟进类型必须填写',
'content.require' => '日志内容必须填写',
];
protected $scene = [
'edit' => [],
];
}

@ -0,0 +1,20 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminRule extends Validate{
protected $rule = [
'title' => 'require',
'name' => 'require',
'level' => 'require'
];
protected $message = [
'title.require' => '标题必须填写',
'name.require' => '规则定义必须填写',
'level.require' => '级别类型必须填写',
];
}

@ -0,0 +1,16 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminStructure extends Validate{
protected $rule = [
'name' => 'require',
];
protected $message = [
'name.require' => '部门名称必须填写',
];
}

@ -0,0 +1,25 @@
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 设置模型
*/
class AdminUser extends Validate{
protected $rule = array(
'realname' => 'require',
'username' => 'require|unique:admin_user|regex:^1[3456789][0-9]{9}?$',
'structure_id' => 'require',
'password' => 'require|regex:^(?![0-9]*$)[a-zA-Z0-9]{6,20}$',
);
protected $message = array(
'realname.require' => '姓名必须填写',
'username.require' => '手机号码必须填写',
'username.unique' => '手机号码已存在',
'username.regex' => '手机号码格式错误',
'password.require' => '密码必须填写',
'password.regex' => '密码由6-20位字母、数字组成',
'structure_id.require' => '请选择所属部门',
);
}

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>悟空CRM安装向导</title>
<link rel="shortcut icon" href="__STATIC__/icon/favicon.ico">
<link rel="stylesheet" href="__STATIC__/style/base.css">
<link rel="stylesheet" href="__STATIC__/style/index.css">
<script src="__STATIC__/js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="header-wrapper">
{include file="public/header"}
</div>
<div class="top">
<div class="agreement-title">悟空CRM系统开源版使用协议</div>
</div>
<div class="container">
<div class="agreement">
<p style="text-align:center;font-size:18px;">悟空CRM开源版使用协议</p>
<br>
悟空CRMCustomer Relationship Management悟空客户关系管理软件以下简称悟空CRM由郑州卡卡罗特软件科技有限公司以下简称卡卡罗特开发。卡卡罗特依法拥有悟空CRM的所有版权和所有权益。本着共享开放的角度卡卡罗特以开放源代码的形式发布悟空CRM您可以在遵守该协议的前提下使用悟空CRM。<br>
<br>
自您安装悟空CRM开始您和卡卡罗特之间的合同关系自动成立成为卡卡罗特用户以下简称为用户。除非您停止使用悟空CRM或与卡卡罗特有签署额外合同您须认真遵循该用户协议约定的每一项条款。<br>
<br>
官方地址:<a target="_blank" href="http://www.5kcrm.com">www.5kcrm.com</a> / <a target="_blank" href="https://www.72crm.com">www.72crm.com</a><br>
官方电话400-0812-558<br>
官方邮箱service@5kcrm.com<br>
官方社区:<a target="_blank" href="http://www.72crm.net">bbs.72crm.net</a><br>
官方社群:<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=f4687b809bf63f08f707aa1c56dee8dbcb9526237c429c4532222021d65bf83c">悟空CRM交流10群486745026</a><br>
<br>
<p>一、协议中提到的名词约定</p>
1.1下述条款中所指悟空CRM的标志包括如下方面<br>
悟空CRM源代码及文档中关于悟空CRM的版权提示、文字、图片和链接。<br>
悟空CRM运行时界面上呈现出来的有关悟空CRM的文字、图片和链接。<br>
1.2不包括如下方面:<br>
悟空CRM提供的演示数据中关于悟空CRM的文字、图片和链接。<br>
<br>
<p>二、免责声明</p>
2.1用户出于自愿而使用本软件,必须了解使用本软件的风险,在尚未购买产品技术服务或商业授权之前,我们不承诺对免费用户提供任何形式的技术支持、使用担保,也不承担任何因使用本软件而产生问题的相关责任。<br>
2.2电子文本形式的使用协议如同双方书面签署的协议一样具有完全的和等同的法律效力。您一旦开始确认本协议并安装悟空CRM即被视为完全理解并接受本协议的各项条款在享有以下条款授予的权力的同时受到相关的约束和限制。<br>
2.3协议许可范围以外的行为,将直接违反本授权协议并构成侵权,我们有权随时终止授权,责令停止损害,并保留追究相关责任的权利。<br>
<br>
<p>三、协议许可的权利</p>
3.1 如果您以学习或研究为目的使用悟空CRM卡卡罗特不对您做任何限制。<br>
3.2 您可以在您个人任意数量的电脑上运行悟空CRM卡卡罗特不对电脑的数量做任何限制。<br>
3.3 您可以对悟空CRM源代码进行修改以适应您个人学习研究的要求您做的改动无需对外发布。<br>
3.4卡卡罗特依法拥有悟空CRM的所有版权和软件权益未经商业授权您无任何版权及软件相关权益。<br>
<br>
<p>四、协议规定的约束和限制</p>
4.1当您开始将悟空CRM用于企业内部管理使用意味着已经商用需购买相应的商业授权 <br>
4.2未获得商业授权之前,不得将本软件用于商业用途(包括但不限于企业内部使用、二次开发后进行销售、以营利为目的或实现盈利等形式)。<br>
4.3未经官方许可禁止在悟空CRM的整体或任何部分基础上发展任何派生版本、修改版本或第三方版本用于重新分发,包括但不限于基于悟空CRM开发SAAS平台等相关服务。<br>
4.4如果您未能遵守本协议的条款,您的授权将被终止,所被许可的权利将被收回,并承担相应法律责任。<br>
4.5 您使用悟空CRM时必须保留悟空CRM的所有标志不得以任何方式隐藏或遮掩任一标志。<br>
<br>
<p>五、未尽事项</p>
如果上述条款无法满足您使用悟空CRM的要求可联系卡卡罗特签署额外的合同以获得更灵活的授权许可。<br>
<br>
<p>六、合同约束</p>
如果您违反了该协议的任一条款,该用户协议将自动终止,您必须停止使用,卡卡罗特保留通过法律手段追究责任的权利。<br>
<br>
</div>
<div class="agree-btn">我同意</div>
</div>
<div class="footer-wrapper">
{include file="public/footer"}
</div>
</body>
<script>
$('.agree-btn').click(function () {
window.location = 'step1.html'
});
</script>
</html>

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>悟空CRM安装向导</title>
<link rel="shortcut icon" href="__STATIC__/icon/favicon.ico">
<link rel="stylesheet" href="__STATIC__/style/base.css">
<link rel="stylesheet" href="__STATIC__/style/step1.css">
<script src="__STATIC__/js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="header-wrapper">
{include file="public/header"}
</div>
<div class="top">
<div class="step-group">
<div class="step active">
<div class="sort">1</div>
<div class="desc">检查安装环境</div>
</div>
<div class="step line"></div>
<div class="step">
<div class="sort">2</div>
<div class="desc">创建数据库</div>
</div>
<div class="step line"></div>
<div class="step">
<div class="sort">3</div>
<div class="desc">安装成功</div>
</div>
</div>
</div>
<div class="container">
<div class="content">
<div class="base-top">
<span class="title">1 检查安装环境</span>
<span class="version">当前版本:{$data['version']['VERSION']} {$data['version']['RELEASE']}</span>
</div>
<div class="table">
<table class="table_01">
<thead>
<tr>
<th>检查项</th>
<th>当前环境</th>
<th>悟空CRM建议</th>
<th>当前状态</th>
</tr>
</thead>
<tbody>
{volist name="data['env']" id="row"}
<tr>
<td>{$row[0]}</td>
<td>{$row[1]}</td>
<td>{$row[2]}</td>
<td>
{if condition="$row['3'] == 'ok'"}
<img src="__STATIC__/icon/success.png" width="20">
{else /}
<img src="__STATIC__/icon/error.png" width="20">
{/if}
</td>
</tr>
{/volist}
</tbody>
</table>
<table class="catalogue-table">
<thead>
<tr>
<th>目录文件</th>
<th>所需状态</th>
<th>当前状态</th>
</tr>
</thead>
<tbody>
<?php foreach($data['dir'] as $value){ ?>
<tr>
<td>{$value[1]}</td>
<td>{$value[3]}</td>
<?php if($value[5] =='ok') { ?>
<td><img src="__STATIC__/icon/success.png" width="20"></td>
<?php } else { ?>
<td><img src="__STATIC__/icon/error.png" width="20"></td>
<?php } ?>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<div class="control">
<div class="prev btn">上一步</div>
<div class="next btn primary">下一步</div>
</div>
</div>
</div>
<div class="footer-wrapper">
{include file="public/footer"}
</div>
</body>
<script src="__STATIC__/js/step1.js"></script>
</html>

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>悟空CRM安装向导</title>
<link rel="shortcut icon" href="__STATIC__/icon/favicon.ico">
<link rel="stylesheet" href="__STATIC__/style/base.css">
<link rel="stylesheet" href="__STATIC__/style/step2.css">
<script src="__STATIC__/js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="header-wrapper">
{include file="public/header"}
</div>
<div class="top">
<div class="step-group">
<div class="step active">
<div class="sort">1</div>
<div class="desc">检查安装环境</div>
</div>
<div class="step active line"></div>
<div class="step active">
<div class="sort">2</div>
<div class="desc">创建数据库</div>
</div>
<div class="step line"></div>
<div class="step">
<div class="sort">3</div>
<div class="desc">安装成功</div>
</div>
</div>
</div>
<div class="container">
<div class="content">
<div class="base-top">
<span class="title">2 创建数据库</span>
<span class="version">当前版本:{$envir_data['version']['VERSION']} {$envir_data['version']['RELEASE']}</span>
</div>
<div class="form">
<div class="form-sec-title">请填写数据库信息</div>
<div class="form-item">
<div class="form-label">数据库主机:</div>
<input type="text" name="databaseUrl">
<!--<div class="error" style="display: none">数据库主机不能空</div>-->
<div class="remind">数据库地址一般为127.0.0.1</div>
</div>
<div class="form-item">
<div class="form-label">数据库名:</div>
<input type="text" name="databaseName">
</div>
<div class="form-item">
<div class="form-label">端口:</div>
<input type="text" name="databasePort">
<div class="remind">一般为 3306</div>
</div>
<div class="form-item">
<div class="form-label">数据库用户名:</div>
<input type="text" name="databaseUser">
<div class="remind">生产环境建议创建独立账号</div>
</div>
<div class="form-item">
<div class="form-label">数据库密码:</div>
<input type="password" name="databasePwd">
</div>
<div class="form-item">
<div class="form-label">表前缀:</div>
<input type="text" name="databaseTable">
<div class="remind">默认为5kcrm_</div>
</div>
<div class="form-sec-title">请填写管理员信息</div>
<div class="form-item">
<div class="form-label">管理员账号:</div>
<input type="text" name="root" placeholder="请输入手机号码">
</div>
<div class="form-item">
<div class="form-label">管理员密码:</div>
<input type="password" name="pwd">
</div>
</div>
<div class="install_progress_a">
<!-- <progress class="install_progress" max="97" value="8"></progress> -->
</div>
<div class="control">
<div class="prev btn">上一步</div>
<div class="next btn primary">下一步</div>
</div>
</div>
</div>
<div class="footer-wrapper">
{include file="public/footer"}
</div>
</body>
<!-- <script src="__STATIC__/js/base.js"></script> -->
<script src="__STATIC__/js/step2.js"></script>
</html>

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>悟空CRM安装向导</title>
<link rel="shortcut icon" href="__STATIC__/icon/favicon.ico">
<link rel="stylesheet" href="__STATIC__/style/base.css">
<link rel="stylesheet" href="__STATIC__/style/step3.css">
<script src="__STATIC__/js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="header-wrapper">
{include file="public/header"}
</div>
<div class="top">
<div class="step-group">
<div class="step active">
<div class="sort">1</div>
<div class="desc">检查安装环境</div>
</div>
<div class="step active line"></div>
<div class="step active">
<div class="sort">2</div>
<div class="desc">创建数据库</div>
</div>
<div class="step line active"></div>
<div class="step">
<div class="sort">3</div>
<div class="desc">安装成功</div>
</div>
</div>
</div>
<div class="container">
<div class="result">
<div class="status-box">
<img class="pic" src="__STATIC__/icon/error.png" alt="">
<span class="status">安装失败</span>
</div>
<div class="desc">未按照正确的方式进行安装</div>
<div class="control">
<div class="prev btn primary">返回上一步</div>
</div>
</div>
</div>
<div class="footer-wrapper">
{include file="public/footer"}
</div>
</body>
<script>
$('.prev').click(function () {
window.location = 'step2.html'
})
</script>
</html>

@ -0,0 +1,6 @@
<footer class="footer">
<div class="content">
悟空CRM受国家计算机软件著作权保护未经授权不得进行商业行为违者必究。<br>
&copy;2021 悟空软件<a target="_blank" href="http://www.5kcrm.com">www.5kcrm.com</a>
</div>
</footer>

@ -0,0 +1,14 @@
<header class="header">
<div class="header-content">
<h1 class="logo">
<a href="http://www.5kcrm.com"><img class="pic" src="__STATIC__/img/logo.png" alt=""></a>
</h1>
<div class="title">
悟空CRM11.0安装向导
</div>
<div class="concat-us">
<img class="icon" src="__STATIC__/icon/phone.png" alt="">
<span class="desc">官方电话400-0812-558</span>
</div>
</div>
</header>

@ -0,0 +1,18 @@
<?php
//权限控制
\think\Hook::add('check_auth','app\\common\\behavior\\AuthenticateBehavior');
use think\Db;
//获取一年中每个月开始结束时间
function getMonthStart($year)
{
$i = 1;
for($i=1;$i<13;$i++) {
$time = $year.'-'.$i.'-01';
$data[$i]= strtotime($time);
}
$newyear = $year+1;
$data[13] = strtotime($newyear.'-01-01');
return $data;
}

@ -0,0 +1,14 @@
<?php
// 基础模块配置文件
return [
//'配置项'=>'配置值'
'LANG_SWITCH_ON' => true, //开启语言包功能
'LANG_AUTO_DETECT' => true, // 自动侦测语言
'DEFAULT_LANG' => 'zh-cn', // 默认语言
'LANG_LIST' => 'en-us,zh-cn,zh-tw', //必须写可允许的语言列表
'VAR_LANGUAGE' => 'l', // 默认语言切换变量
];

@ -0,0 +1,419 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-业绩目标
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use think\Db;
use think\Hook;
use think\Request;
use app\bi\logic\ExcelLogic;
class Achievement extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [''],
'allow' => ['statistics', 'excelexport']
];
Hook::listen('check_auth', $action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'achievement', 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作']));
}
}
/**
* 业绩目标完成情况
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function statistics($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
// $achievementModel = new \app\crm\model\Achievement();
// $list = $achievementModel->getList($param) ? : [];
$list = $this->getAchievementStatistics($param) ?: [];
//导出使用
if (!empty($param['excel_type'])) {
$list = $this->excelStatistics($param) ?: [];
return $list;
}
return resultArray(['data' => $list]);
}
/**
* 业绩目标完成情况列表
*
* @param $param
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getAchievementStatistics($param)
{
# 结果数据
$result = [];
# 参数
$status = !empty($param['status']) ? $param['status'] : 1; # 类型1合同目标2回款目标
$year = !empty($param['year']) ? $param['year'] : 0; # 年份
$structureId = !empty($param['structure_id']) ? $param['structure_id'] : 0; # 部门
$userId = !empty($param['user_id']) ? $param['user_id'] : 0; # 员工
$type = !empty($param['type']) ? $param['type'] : 1; # 类型1部门2员工
# 设置业绩目标条件
$achievementWhere['year'] = $year;
$achievementWhere['status'] = $status;
$achievementWhere['type'] = !empty($type) && $type == 1 ? 2 : 3;
if (!empty($userId)) $achievementWhere['obj_id'] = $userId;
if (!empty($structureId)) $achievementWhere['obj_id'] = $structureId;
# 查询业绩目标数据
$achievementList = Db::name('crm_achievement')->where($achievementWhere)->select();
if (empty($achievementList)) return [];
# 部门
if ($type == 1) {
foreach ($achievementList as $key => $value) {
# 组装结果数据
$result[$value['obj_id']] = [
'name' => $value['name'],
'list' => [
'01' => ['achievement' => (int)$value['january'], 'money' => 0, 'rate' => 0, 'month' => '一月'],
'02' => ['achievement' => (int)$value['february'], 'money' => 0, 'rate' => 0, 'month' => '二月'],
'03' => ['achievement' => (int)$value['march'], 'money' => 0, 'rate' => 0, 'month' => '三月'],
'04' => ['achievement' => (int)$value['april'], 'money' => 0, 'rate' => 0, 'month' => '四月'],
'05' => ['achievement' => (int)$value['may'], 'money' => 0, 'rate' => 0, 'month' => '五月'],
'06' => ['achievement' => (int)$value['june'], 'money' => 0, 'rate' => 0, 'month' => '六月'],
'07' => ['achievement' => (int)$value['july'], 'money' => 0, 'rate' => 0, 'month' => '七月'],
'08' => ['achievement' => (int)$value['august'], 'money' => 0, 'rate' => 0, 'month' => '八月'],
'09' => ['achievement' => (int)$value['september'], 'money' => 0, 'rate' => 0, 'month' => '九月'],
'10' => ['achievement' => (int)$value['october'], 'money' => 0, 'rate' => 0, 'month' => '十月'],
'11' => ['achievement' => (int)$value['november'], 'money' => 0, 'rate' => 0, 'month' => '十一月'],
'12' => ['achievement' => (int)$value['december'], 'money' => 0, 'rate' => 0, 'month' => '十二月']
]
];
# 获取部门下的员工ID
$userIds = Db::name('admin_user')->where('structure_id', $value['obj_id'])->column('id');
# 业绩完成字段
$finishField = ["DATE_FORMAT(FROM_UNIXTIME(`create_time`,'%Y-%m-%d'),'%m') AS time", 'sum(money) AS money'];
# 业绩完成条件
$finishWhere['check_status'] = 2;
$finishWhere['owner_user_id'] = ['in', $userIds];
# 合同
if ($status == 1) {
$finishArray = Db::name('crm_contract')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 回款
if ($status == 2) {
$finishArray = Db::name('crm_receivables')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 计算完成情况
foreach ($finishArray as $k => $v) {
if (!empty($result[$value['obj_id']]['list'][$v['time']])) {
$achievement = $result[$value['obj_id']]['list'][$v['time']]['achievement'];
$result[$value['obj_id']]['list'][$v['time']]['money'] = (int)$v['money'];
$result[$value['obj_id']]['list'][$v['time']]['rate'] = (int)(($v['money'] / $achievement) * 100);
}
}
$result[$value['obj_id']]['list'] = array_values($result[$value['obj_id']]['list']);
}
}
# 员工
if ($type == 2) {
$userData = [];
$userList = db('admin_user')->field(['id', 'realname'])->select();
foreach ($userList AS $key => $value) {
$userData[$value['id']] = $value['realname'];
}
foreach ($achievementList as $key => $value) {
# 组装结果数据
$result[$value['obj_id']] = [
'name' => !empty($value['name']) ? $value['name'] : $userData[$value['obj_id']],
'list' => [
'01' => ['achievement' => (int)$value['january'], 'money' => 0, 'rate' => 0, 'month' => '一月'],
'02' => ['achievement' => (int)$value['february'], 'money' => 0, 'rate' => 0, 'month' => '二月'],
'03' => ['achievement' => (int)$value['march'], 'money' => 0, 'rate' => 0, 'month' => '三月'],
'04' => ['achievement' => (int)$value['april'], 'money' => 0, 'rate' => 0, 'month' => '四月'],
'05' => ['achievement' => (int)$value['may'], 'money' => 0, 'rate' => 0, 'month' => '五月'],
'06' => ['achievement' => (int)$value['june'], 'money' => 0, 'rate' => 0, 'month' => '六月'],
'07' => ['achievement' => (int)$value['july'], 'money' => 0, 'rate' => 0, 'month' => '七月'],
'08' => ['achievement' => (int)$value['august'], 'money' => 0, 'rate' => 0, 'month' => '八月'],
'09' => ['achievement' => (int)$value['september'], 'money' => 0, 'rate' => 0, 'month' => '九月'],
'10' => ['achievement' => (int)$value['october'], 'money' => 0, 'rate' => 0, 'month' => '十月'],
'11' => ['achievement' => (int)$value['november'], 'money' => 0, 'rate' => 0, 'month' => '十一月'],
'12' => ['achievement' => (int)$value['december'], 'money' => 0, 'rate' => 0, 'month' => '十二月']
]
];
# 业绩完成字段
$finishField = ["DATE_FORMAT(FROM_UNIXTIME(`create_time`,'%Y-%m-%d'),'%m') AS time", 'sum(money) AS money'];
# 业绩完成条件
$finishWhere = ['check_status' => 2, 'owner_user_id' => $value['obj_id']];
# 合同
if ($status == 1) {
$finishArray = Db::name('crm_contract')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 回款
if ($status == 2) {
$finishArray = Db::name('crm_receivables')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 计算完成情况
foreach ($finishArray as $k => $v) {
if (!empty($result[$value['obj_id']]['list'][$v['time']])) {
$achievement = $result[$value['obj_id']]['list'][$v['time']]['achievement'];
$result[$value['obj_id']]['list'][$v['time']]['money'] = (int)$v['money'];
$result[$value['obj_id']]['list'][$v['time']]['rate'] = (int)(($v['money'] / $achievement) * 100);
}
}
$result[$value['obj_id']]['list'] = array_values($result[$value['obj_id']]['list']);
}
}
return array_values($result);
}
public function excelStatistics($param)
{
# 结果数据
$result = [];
# 参数
$status = !empty($param['status']) ? $param['status'] : 1; # 类型1合同目标2回款目标
$year = !empty($param['year']) ? $param['year'] : 0; # 年份
$structureId = !empty($param['structure_id']) ? $param['structure_id'] : 0; # 部门
$userId = !empty($param['user_id']) ? $param['user_id'] : 0; # 员工
$type = !empty($param['type']) ? $param['type'] : 1; # 类型1部门2员工
# 设置业绩目标条件
$achievementWhere['year'] = $year;
$achievementWhere['status'] = $status;
$achievementWhere['type'] = !empty($type) && $type == 1 ? 2 : 3;
if (!empty($userId)) $achievementWhere['obj_id'] = $userId;
if (!empty($structureId)) $achievementWhere['obj_id'] = $structureId;
# 查询业绩目标数据
$achievementList = Db::name('crm_achievement')->where($achievementWhere)->select();
if (empty($achievementList)) return [];
# 部门
if ($type == 1) {
foreach ($achievementList as $key => $value) {
# 组装结果数据
$result[] = [
['name' => $value['name'], 'achievement' => (int)$value['january'], 'money' => 0, 'rate' => 0, 'month' => '一月'],
['name' => $value['name'], 'achievement' => (int)$value['february'], 'money' => 0, 'rate' => 0, 'month' => '二月'],
['name' => $value['name'], 'achievement' => (int)$value['march'], 'money' => 0, 'rate' => 0, 'month' => '三月'],
['name' => '', 'achievement' => 0, 'money' => 0, 'rate' => 0, 'month' => '第一季度'],
['name' => $value['name'], 'achievement' => (int)$value['april'], 'money' => 0, 'rate' => 0, 'month' => '四月'],
['name' => $value['name'], 'achievement' => (int)$value['may'], 'money' => 0, 'rate' => 0, 'month' => '五月'],
['name' => $value['name'], 'achievement' => (int)$value['june'], 'money' => 0, 'rate' => 0, 'month' => '六月'],
['name' => $value['name'], 'achievement' => (int)$value['april'], 'money' => 0, 'rate' => 0, 'month' => '第二季度'],
['name' => $value['name'], 'achievement' => (int)$value['july'], 'money' => 0, 'rate' => 0, 'month' => '七月'],
['name' => $value['name'], 'achievement' => (int)$value['august'], 'money' => 0, 'rate' => 0, 'month' => '八月'],
['name' => $value['name'], 'achievement' => (int)$value['september'], 'money' => 0, 'rate' => 0, 'month' => '九月'],
['name' => $value['name'], 'achievement' => 0, 'money' => 0, 'rate' => 0, 'month' => '第三季度'],
['name' => $value['name'], 'achievement' => (int)$value['october'], 'money' => 0, 'rate' => 0, 'month' => '十月'],
['name' => $value['name'], 'achievement' => (int)$value['november'], 'money' => 0, 'rate' => 0, 'month' => '十一月'],
['name' => $value['name'], 'achievement' => (int)$value['december'], 'money' => 0, 'rate' => 0, 'month' => '十二月'],
['name' => $value['name'], 'achievement' => 0, 'money' => 0, 'rate' => 0, 'month' => '第四季度'],
['name' => $value['name'], 'achievement' => (int)$value['yeartarget'], 'money' => 0, 'rate' => 0, 'month' => '全年'],
];
# 获取部门下的员工ID
$userIds = Db::name('admin_user')->where('structure_id', $value['obj_id'])->column('id');
# 业绩完成字段
$finishField = ["DATE_FORMAT(FROM_UNIXTIME(`create_time`,'%Y-%m-%d'),'%m') AS time", 'sum(money) AS money'];
# 业绩完成条件
$finishWhere['check_status'] = 2;
$finishWhere['owner_user_id'] = ['in', $userIds];
# 合同
if ($status == 1) {
$finishArray = Db::name('crm_contract')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 回款
if ($status == 2) {
$finishArray = Db::name('crm_receivables')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 计算完成情况
foreach ($finishArray as $k => $v) {
if (!empty($result[$v['time']])) {
$achievement = $result[$v['time']]['achievement'];
$result[$v['time']]['money'] = (int)$v['money'];
$result[$v['time']]['rate'] = (int)(($v['money'] / $achievement) * 100);
}
}
foreach ($result as &$val){
$val[3]['money']=$val[0]['money']+$val[1]['money']+$val[2]['money'];
$val[3]['rate']=$val[0]['rate']+$val[1]['rate']+$val[2]['rate'];
$val[7]['money']=$val[4]['money']+$val[5]['money']+$val[6]['money'];
$val[7]['rate']=$val[4]['rate']+$val[5]['rate']+$val[6]['rate'];
$val[11]['money']=$val[7]['money']+$val[9]['money']+$val[10]['money'];
$val[11]['rate']=$val[8]['rate']+$val[9]['rate']+$val[10]['rate'];
$val[15]['money']=$val[12]['money']+$val[13]['money']+$val[14]['money'];
$val[15]['rate']=$val[12]['rate']+$val[13]['rate']+$val[14]['rate'];
$val[15]['money']=$val[12]['money']+$val[13]['money']+$val[14]['money'];
$val[15]['rate']=$val[12]['rate']+$val[13]['rate']+$val[14]['rate'];
$val[16]['money']=$val[3]['money']+$val[7]['money']+$val[11]['money']+$val[15]['money'];
$val[16]['rate']=$val[3]['rate']+$val[7]['rate']+$val[11]['rate']+$val[15]['rate'];
}
$result = array_values($result);
}
}
# 员工
if ($type == 2) {
foreach ($achievementList AS $key => $value) {
# 组装结果数据
$result[] = [
['name' => $value['name'], 'achievement' => (int)$value['january'], 'money' => 0, 'rate' => 0, 'month' => '一月'],
['name' => $value['name'], 'achievement' => (int)$value['february'], 'money' => 0, 'rate' => 0, 'month' => '二月'],
['name' => $value['name'], 'achievement' => (int)$value['march'], 'money' => 0, 'rate' => 0, 'month' => '三月'],
['name' => '', 'achievement' => 0, 'money' => 0, 'rate' => 0, 'month' => '第一季度'],
['name' => $value['name'], 'achievement' => (int)$value['april'], 'money' => 0, 'rate' => 0, 'month' => '四月'],
['name' => $value['name'], 'achievement' => (int)$value['may'], 'money' => 0, 'rate' => 0, 'month' => '五月'],
['name' => $value['name'], 'achievement' => (int)$value['june'], 'money' => 0, 'rate' => 0, 'month' => '六月'],
['name' => $value['name'], 'achievement' => (int)$value['april'], 'money' => 0, 'rate' => 0, 'month' => '第二季度'],
['name' => $value['name'], 'achievement' => (int)$value['july'], 'money' => 0, 'rate' => 0, 'month' => '七月'],
['name' => $value['name'], 'achievement' => (int)$value['august'], 'money' => 0, 'rate' => 0, 'month' => '八月'],
['name' => $value['name'], 'achievement' => (int)$value['september'], 'money' => 0, 'rate' => 0, 'month' => '九月'],
['name' => $value['name'], 'achievement' => 0, 'money' => 0, 'rate' => 0, 'month' => '第三季度'],
['name' => $value['name'], 'achievement' => (int)$value['october'], 'money' => 0, 'rate' => 0, 'month' => '十月'],
['name' => $value['name'], 'achievement' => (int)$value['november'], 'money' => 0, 'rate' => 0, 'month' => '十一月'],
['name' => $value['name'], 'achievement' => (int)$value['december'], 'money' => 0, 'rate' => 0, 'month' => '十二月'],
['name' => $value['name'], 'achievement' => 0, 'money' => 0, 'rate' => 0, 'month' => '第四季度'],
['name' => $value['name'], 'achievement' => (int)$value['yeartarget'], 'money' => 0, 'rate' => 0, 'month' => '全年'],
];
# 业绩完成字段
$finishField = ["DATE_FORMAT(FROM_UNIXTIME(`create_time`,'%Y-%m-%d'),'%m') AS time", 'sum(money) AS money'];
# 业绩完成条件
$finishWhere = ['check_status' => 2, 'owner_user_id' => $value['obj_id']];
# 合同
if ($status == 1) {
$finishArray = Db::name('crm_contract')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 回款
if ($status == 2) {
$finishArray = Db::name('crm_receivables')->field($finishField)->where($finishWhere)->group('time')->select();
}
# 计算完成情况
foreach ($finishArray AS $k => $v) {
if (!empty($result[$v['time']])) {
$achievement = $result[$v['time']]['achievement'];
$result[$v['time']]['money'] = (int)$v['money'];
$result[$v['time']]['rate'] = (int)(($v['money'] / $achievement) * 100);
}
}
foreach ($result as &$val){
$val[3]['money']=$val[0]['money']+$val[1]['money']+$val[2]['money'];
$val[3]['rate']=$val[0]['rate']+$val[1]['rate']+$val[2]['rate'];
$val[7]['money']=$val[4]['money']+$val[5]['money']+$val[6]['money'];
$val[7]['rate']=$val[4]['rate']+$val[5]['rate']+$val[6]['rate'];
$val[11]['money']=$val[7]['money']+$val[9]['money']+$val[10]['money'];
$val[11]['rate']=$val[8]['rate']+$val[9]['rate']+$val[10]['rate'];
$val[15]['money']=$val[12]['money']+$val[13]['money']+$val[14]['money'];
$val[15]['rate']=$val[12]['rate']+$val[13]['rate']+$val[14]['rate'];
$val[15]['money']=$val[12]['money']+$val[13]['money']+$val[14]['money'];
$val[15]['rate']=$val[12]['rate']+$val[13]['rate']+$val[14]['rate'];
$val[16]['money']=$val[3]['money']+$val[7]['money']+$val[11]['money']+$val[15]['money'];
$val[16]['rate']=$val[3]['rate']+$val[7]['rate']+$val[11]['rate']+$val[15]['rate'];
}
$result = array_values($result);
}
}
return array_values($result);
}
/**
* 导出
* @param $type
* @param $types
*/
public function excelExport()
{
$param = $this->param;
$list = $this->statistics($param);
if(empty($list)){
return resultArray(['data'=>'数据不存在']);
}
$excelLogic = new ExcelLogic();
$data = $excelLogic->achienementExcel($param, $list);
return $data;
}
}

@ -0,0 +1,287 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-商机分析
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use app\bi\traits\SortTrait;
use think\Db;
use think\Hook;
use think\Request;
class Business extends ApiCommon
{
use SortTrait;
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>[
'funnel',
'businesstrend',
'trendlist',
'win',
'winlist'
]
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'business' , 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
/**
* 销售漏斗
* @author Michael_xu
* @param
* @return
*/
public function funnel()
{
if (empty($this->param['type_id'])) return resultArray(['error' => '请选择商机组!']);
$businessModel = new \app\crm\model\Business();
$param = $this->param;
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
unset($param['sort_field']);
unset($param['sort_value']);
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$data = $businessModel->getFunnel($param);
foreach ($data['list'] AS $key => $value) {
if (empty($value['money']) && empty($value['count'])) unset($data['list'][(int)$key]);
}
if (empty($data['total']['money_count']) && empty($data['total']['count'])) return resultArray(['data' => ['list' => []]]);
$data['list'] = array_values($data['list']);
# 排序
if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
return resultArray(['data' => $data]);
}
/**
* 新增商机数与金额趋势分析
* @return
*/
public function businessTrend()
{
$businessModel = new \app\crm\model\Business();
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
$param = $this->param;
$perUserIds = $userModel->getUserByPer('bi', 'business', 'read'); //权限范围内userIds
$whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereArr['userIds'];
if(empty($param['type']) && empty($param['start_time'])){
$param['type'] = 'month';
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$time = getTimeArray($param['start_time'], $param['end_time']);
$where = [
'owner_user_id' => !empty($userIds) ? implode(',',$userIds) : '9999999999'
];
$sql = [];
foreach ($time['list'] as $val) {
$whereArr = $where;
$whereArr['type'] = $val['type'];
$whereArr['start_time'] = $val['start_time'];
$whereArr['end_time'] = $val['end_time'];
$sql[] = $businessModel->getTrendql($whereArr);
}
$sql = implode(' UNION ALL ', $sql);
$list = queryCache($sql);
return resultArray(['data' => $list]);
}
/**
* 新增商机数与金额趋势分析 列表
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function trendList()
{
$businessModel = new \app\bi\model\Business();
$crmBusinessModel = new \app\crm\model\Business();
$userModel = new \app\admin\model\User();
$param = $this->param;
unset($param['types']);
# 日期条件
if (!empty($param['type'])) {
$param['start_time'] = strtotime($param['type'] . '-01 00:00:00');
$endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
$param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth));
unset($param['type']);
} else {
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
}
# 排序参数
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
$dataList = $businessModel->getDataList($param);
foreach ($dataList['list'] as $k => $v) {
$business_info = $crmBusinessModel->getDataById($v['business_id']);
$dataList['list'][$k]['business_name'] = $business_info['name'];
$dataList['list'][$k]['create_time'] = date('Y-m-d',strtotime($business_info['create_time']));
$dataList['list'][$k]['customer_id'] = $v['customer_id'];
$customer = db('crm_customer')->field('name')->where('customer_id',$v['customer_id'])->find();
$dataList['list'][$k]['customer_name'] = $customer['name'];
$create_user_id_info = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
$dataList['list'][$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['list'][$k]['owner_user_name'] = $owner_user_id_info['realname'];
$dataList['list'][$k]['business_stage'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段
$dataList['list'][$k]['business_type'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组
}
# 排序
if (!empty($dataList)) $dataList = $this->sortCommon($dataList, $sortField, $sortValue);
return resultArray(['data' => $dataList]);
}
/**
* 赢单机会转化率趋势分析
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function win()
{
$businessModel = new \app\crm\model\Business();
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
$param = $this->param;
$perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); //权限范围内userIds
$whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereArr['userIds'];
if(empty($param['type']) && empty($param['start_time'])){
$param['type'] = 'month';
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$time = getTimeArray($param['start_time'], $param['end_time']);
$sql = db('crm_business')->alias('business')->field([
"FROM_UNIXTIME(business.create_time, '{$time['time_format']}')" => 'type',
'COUNT(business.business_id)' => 'business_num',
'SUM(
CASE WHEN
`check_status` = 2
THEN 1 ELSE 0 END
)' => 'business_end'
])->join('__CRM_CONTRACT__ contract', 'contract.business_id = business.business_id', 'left')
->where([
'business.owner_user_id' => ['IN', $userIds],
'business.create_time' => ['BETWEEN', $time['between']]
])
->group('type')
->fetchSql()
->select();
$res = queryCache($sql);
$res = array_column($res, null, 'type');
foreach ($time['list'] as $key =>$val) {
$val['business_num'] = (int) $res[$val['type']]['business_num'];
$val['business_end'] = (int) $res[$val['type']]['business_end'];
if($res[$val['type']]['business_num']== 0 || $res[$val['type']]['business_end'] == 0){
$val['proportion'] = 0;
}else{
$val['proportion'] = round(($res[$val['type']]['business_end']/$res[$val['type']]['business_num']),4)*100;
}
$time['list'][$key] = $val;
}
return resultArray(['data' => $time['list']]);
}
/**
* 商机转化率分析 列表
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function winList()
{
$businessModel = new \app\bi\model\Business();
$crmBusinessModel = new \app\crm\model\Business();
$userModel = new \app\admin\model\User();
$param = $this->param;
# 日期条件
if (!empty($param['date'])) {
$param['start_time'] = strtotime($param['date'] . '-01 00:00:00');
$endMonth = strtotime(date('Y-m-d', $param['start_time']) . " +1 month -1 day");
$param['end_time'] = strtotime(date('Y-m-d 23:59:59', $endMonth)) ;
unset($param['type']);
}
# 排序参数
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
# 赢单条件
$param['is_end'] = 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]['business_stage'] = db('crm_business_status')->where('status_id',$v['status_id'])->value('name');//销售阶段
$dataList[$k]['business_type'] = db('crm_business_type')->where('type_id',$v['type_id'])->value('name');//商机状态组
}
# 排序
if (!empty($dataList)) $dataList = $this->sortCommon($dataList, $sortField, $sortValue);
return resultArray(['data' => $dataList]);
}
}

@ -0,0 +1,359 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-员工业绩分析
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use app\bi\traits\SortTrait;
use app\crm\model\Contract as ContractModel;
use app\crm\model\Receivables as ReceivablesModel;
use think\Db;
use think\Hook;
use think\Request;
use app\bi\logic\ExcelLogic;
class Contract extends ApiCommon
{
use SortTrait;
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [''],
'allow' => [
'analysis',
'summary',
'invoice',
'excelexport'
]
];
Hook::listen('check_auth', $action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'contract', 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作']));
}
}
/**
* 合同数量分析/金额分析/回款金额分析
*
* @param string $param
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function analysis($param='')
{
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
if ($param['excel_type'] != 1) {
$param = $this->param;
}
$perUserIds = $userModel->getUserByPer('bi', 'contract', 'read'); // 权限范围内userIds
$whereArr = $adminModel->getWhere($param, '', $perUserIds); // 统计条件
$userIds = $whereArr['userIds'];
$year = !empty($param['year']) ? $param['year'] : date('Y');
$start_time = strtotime(date(($year - 1) . '-01-01'));
$end_time = strtotime('+2 year', $start_time) - 1;
$time = getTimeArray($start_time, $end_time);
if ($param['type'] == 'back' || $param['excel_type'] == 'back') {
$model = new ReceivablesModel;
$time_field = 'return_time';
} else {
$model = new ContractModel;
$time_field = 'order_date';
}
if ($param['type'] == 'count' || $param['$excel_type'] == 'count') {
$field['COUNT(*)'] = 'total';
} else {
$field['SUM(`money`)'] = 'total';
}
$between_time = [date('Y-m-d', $time['between'][0]), date('Y-m-d', $time['between'][1])];
$field["SUBSTR(`{$time_field}`, 1, 7)"] = 'type';
$sql = $model->field($field)
->where([
'owner_user_id' => ['IN', $userIds],
'check_status' => 2,
$time_field => ['BETWEEN', $between_time]
])
->group('type')
->fetchSql()
->select();
$res = queryCache($sql);
$res = array_column($res, null, 'type');
$data = [];
for ($i = 12; $i < 24; $i++) {
$k = $time['list'][$i]['type'];
$k2 = $time['list'][$i - 1]['type'];
$k3 = $time['list'][$i - 12]['type'];
$item['month'] = ($i - 11) < 10 ? $param['year']. '0' . $i - 11 : $param['year'] . $i - 11;
$item['thisMonth'] = $res[$k] ? $res[$k]['total'] : 0; # 本月
$item['lastMonthGrowth'] = $res[$k2] ? $res[$k2]['total'] : 0; # 上月
$item['lastYearGrowth'] = $res[$k3] ? $res[$k3]['total'] : 0; # 上年本月
# 环比
$item['chain_ratio'] = $item['thisMonth'] && $item['lastMonthGrowth'] ? round(($item['thisMonth'] / $item['lastMonthGrowth']) * 100, 4) : 0;
# 同比
$item['year_on_year'] = $item['thisMonth'] && $item['lastYearGrowth'] ? round(($item['thisMonth'] / $item['lastYearGrowth']) * 100, 4) : 0;
$data[] = $item;
}
//导出使用
if (!empty($param['excel_type'])) {
return $data;
}
return resultArray(['data' => $data]);
}
/**
* 合同汇总表
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function summary($param='')
{
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
if($param['excel_type']!=1){
$param = $this->param;
}
$perUserIds = $userModel->getUserByPer('bi', 'contract', 'read'); //权限范围内userIds
$whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereArr['userIds'];
if (empty($param['type']) && empty($param['start_time'])) {
$param['type'] = 'month';
}
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
unset($param['sort_field']);
unset($param['sort_value']);
$year = !empty($param['year']) ? $param['year'] : date('Y');
$start_time = strtotime($year . '-01-01');
$end_time = strtotime('+1 year', $start_time) - 1;
$time = getTimeArray($start_time, $end_time);
$ax = 7;
if ($time['time_format'] == '%Y-%m-%d') {
$ax = 10;
}
$between_time = [date('Y-m-d', $time['between'][0]), date('Y-m-d', $time['between'][1])];
$sql = ContractModel::field([
'SUBSTR(`order_date`, 1, ' . $ax . ')' => 'type',
'COUNT(*)' => 'count',
'SUM(`money`)' => 'money'
])
->where([
'owner_user_id' => ['IN', $userIds],
'check_status' => 2,
'order_date' => ['BETWEEN', $between_time]
])
->group('type')
->fetchSql()
->select();
$contract_data = queryCache($sql);
$contract_data = array_column($contract_data, null, 'type');
$sql = ReceivablesModel::field([
'SUBSTR(`return_time`, 1, ' . $ax . ')' => 'type',
'SUM(`money`)' => 'money'
])
->where([
'owner_user_id' => ['IN', $userIds],
'check_status' => 2,
'return_time' => ['BETWEEN', $between_time]
])
->group('type')
->fetchSql()
->select();
$receivables_data = queryCache($sql);
$receivables_data = array_column($receivables_data, null, 'type');
$items = [];
$count_zong = 0;
$money_zong = 0;
$back_zong = 0;
foreach ($time['list'] as $val) {
$item = ['type' => $val['type']];
$count_zong += $item['count'] = $contract_data[$val['type']]['count'] ?: 0;
$money_zong += $item['money'] = $contract_data[$val['type']]['money'] ?: 0;
$back_zong += $item['back'] = $receivables_data[$val['type']]['money'] ?: 0;
$items[] = $item;
}
$data = [
'list' => $items,
'count_zong' => $count_zong,
'money_zong' => $money_zong,
'back_zong' => $back_zong,
'w_back_zong' => $money_zong - $back_zong,
];
if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
//导出使用
if (!empty($param['excel_type'])) return $data;
return resultArray(['data' => $data]);
}
/**
* 发票统计分析
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function invoice($param='')
{
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
if($param['excel_type']!=1){
$param = $this->param;
}
$perUserIds = $userModel->getUserByPer('bi', 'contract', 'read'); //权限范围内userIds
$whereArr = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereArr['userIds'];
if (empty($param['type']) && empty($param['start_time'])) {
$param['type'] = 'month';
}
$sortField = !empty($param['sort_field']) ? $param['sort_field'] : '';
$sortValue = !empty($param['sort_value']) ? $param['sort_value'] : '';
unset($param['sort_field']);
unset($param['sort_value']);
$time = getTimeArray();
$ax = 7;
if ($time['time_format'] == '%Y-%m-%d') {
$ax = 10;
}
$between_time = [date('Y-m-d', $time['between'][0]), date('Y-m-d', $time['between'][1])];
$sql = Db::name('crm_invoice')->field([
'SUBSTR(`invoice_date`, 1, ' . $ax . ')' => 'type',
'SUM(`invoice_money`)' => 'money'
])
->where([
'owner_user_id' => ['IN', $userIds],
'check_status' => 2,
'invoice_status' => 1,
'invoice_date' => ['BETWEEN', $between_time]
])
->group('type')
->fetchSql()
->select();
$invoice_data = queryCache($sql);
$invoice_data = array_column($invoice_data, null, 'type');
$sql = ReceivablesModel::field([
'SUBSTR(`return_time`, 1, ' . $ax . ')' => 'type',
'SUM(`money`)' => 'money'
])
->where([
'owner_user_id' => ['IN', $userIds],
'check_status' => 2,
'return_time' => ['BETWEEN', $between_time]
])
->group('type')
->fetchSql()
->select();
$receivables_data = queryCache($sql);
$receivables_data = array_column($receivables_data, null, 'type');
$items = [];
$invoiceCount = 0;
$receivablesCount = 0;
foreach ($time['list'] as $val) {
$receivablesModel = !empty($receivables_data[$val['type']]['money']) ? $receivables_data[$val['type']]['money'] : 0;
$invoiceModel = !empty($invoice_data[$val['type']]['money']) ? $invoice_data[$val['type']]['money'] : 0;
$items[] = [
'type' => $val['type'],
'receivables_money' => $receivablesModel,
'invoice_money' => $invoiceModel,
'not_invoice' => $receivablesModel - $invoiceModel > 0 ? $receivablesModel - $invoiceModel : 0,
'not_receivables' => $invoiceModel - $receivablesModel > 0 ? $invoiceModel - $receivablesModel : 0
];
$invoiceCount += $invoiceModel;
$receivablesCount += $receivablesModel;
}
$data = [
'list' => $items,
'receivables_count' => $receivablesCount,
'invoice_count' => $invoiceCount
];
if (!empty($data['list'])) $data['list'] = $this->sortCommon($data['list'], $sortField, $sortValue);
//导出使用
if (!empty($param['excel_type'])) return $data;
return resultArray(['data' => $data]);
}
/**
* 导出
* @param $type
* @param $types
*/
public function excelExport()
{
$param = $this->param;
$excel_type = $param['excel_type'];
$type=[];
$type['excel_types']=$param['excel_types'];
switch ($param['excel_types']) {
case 'analysis':
if ($param['type'] == 'count') {
$type['type'] = '合同数量分析';
} elseif ($param['type'] == 'back') {
$type['type'] = '回款金额分析';
} else {
$type['type'] = '金额分析';
}
$list = $this->analysis($param);
break;
case 'summary':
$list = $this->summary($excel_type);
$type['type'] = '合同汇总表';
break;
case 'invoice':
$list = $this->invoice($excel_type);
$type['type'] = '发票统计分析表';
break;
}
if(empty($list)){
return resultArray(['data'=>'数据不存在']);
}
$excelLogic = new ExcelLogic();
$data = $excelLogic->contractExcel($type, $list);
return $data;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,173 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-审核统计
// +----------------------------------------------------------------------
// | Author: zhi | zhijunfu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use think\Hook;
use think\Request;
use think\Db;
class Examine extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['statistics','index','excelexport']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'oa', 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
/**
* 审核统计列表
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function statistics()
{
$param = $this->param;
if ($param['type']) {
$timeArr = getTimeByType($param['type']);
$param['start_time'] = $timeArr[0];
$param['end_time'] = $timeArr[1];
} else {
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
}
$examineModel = new \app\bi\model\Examine();
$list = $examineModel->getStatistics($param) ? : [];
return resultArray(['data'=>$list]);
}
/**
* 审核统计详情列表
* @return
*/
public function index()
{
$examineModel = new \app\oa\model\Examine();
$param = $this->param;
$user_id = $param['user_id'];
$category_id = $param['category_id'];
$type = $param['type'];
if (!$user_id || !$category_id) {
return resultArray(['error'=>'参数错误']);
}
//时间
if ($type) {
$timeArr = getTimeByType($type);
$start_time = $timeArr[0];
$end_time = $timeArr[1];
} else {
$start_time = $param['start_time'] ? : strtotime(date('Y-m-d',time()));
$end_time = $param['end_time'] ? : strtotime(date('Y-m-d',time()))+86399;
}
$create_time = array('between',array($start_time,$end_time));
$where = [];
$where['create_user_id'] = $user_id;
$where['check_status'] = 2;
$where['create_time'] = $create_time;
$where['category_id'] = $category_id;
$sumData = 0;
$categoryName = '普通审批';
switch ($category_id) {
case '2' :
$sumData = db('oa_examine')->where($where)->sum('duration');
$categoryName = '请假审批';
break;
case '3' :
$sumData = db('oa_examine')->where($where)->sum('duration');
$categoryName = '出差审批';
break;
case '4' :
$sumData = db('oa_examine')->where($where)->sum('duration');
$categoryName = '加班审批';
break;
case '5' :
$sumData = db('oa_examine')->where($where)->sum('money');
$categoryName = '差旅报销';
break;
case '6' :
$sumData = db('oa_examine')->where($where)->sum('money');
$categoryName = '借款申请';
break;
default :
$categoryName = db('oa_examine_category')->where(['category_id' => $category_id])->value('title');
break;
}
unset($where['create_time']);
unset($where['create_user_id']);
unset($where['create_user_id']);
$where['check_status'] = 'all';
$where['page'] = $param['page'];
$where['limit'] = $param['limit'];
$where['user_id'] = $user_id;
$where['between_time'] = array($start_time,$end_time);
$list = $examineModel->getDataList($where);
$data = [];
$data['list'] = $list ? : [];
$data['sumData'] = $sumData;
$data['categoryName'] = $categoryName;
return resultArray(['data'=>$data]);
}
/**
* 统计导出
* @author Michael_xu
* @param
* @return
*/
public function excelExport()
{
$param = $this->param;
$excelModel = new \app\admin\model\Excel();
// 导出的字段列表
$category_list = db('oa_examine_category')->where(['status' => 1,'is_deleted' => ['neq',1]])->field('title,category_id')->select();
$field_list = [];
$field_list[0]['name'] = '员工';
$field_list[0]['field'] = 'realname';
$i = 1;
foreach ($category_list as $k=>$v) {
$field_list[$i]['name'] = strstr($v['title'],'审批') ? str_replace('审批','次数',$v['title']) : $v['title'].'次数';
$field_list[$i]['field'] = 'count_'.$v['category_id'];
$i++;
}
// 文件名
$file_name = '5kcrm_examine_'.date('Ymd');
$excelModel->dataExportCsv($file_name, $field_list, function($list) use ($param){
$examineModel = new \app\bi\model\Examine();
if ($param['type']) {
$timeArr = getTimeByType($param['type']);
$param['start_time'] = $timeArr[0];
$param['end_time'] = $timeArr[1];
}
$list = $examineModel->getStatistics($param);
return $list['userList'];
});
}
}

@ -0,0 +1,93 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-日志分析
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use think\Db;
use think\Hook;
use think\Request;
class Log extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['statistics','excelexport']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'oa', 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
/**
* 日志统计列表
* @return
*/
public function statistics()
{
$param = $this->param;
if ($param['type']) {
$timeArr = getTimeByType($param['type']);
$param['start_time'] = $timeArr[0];
$param['end_time'] = $timeArr[1];
} else {
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
}
$loglModel = new \app\bi\model\Log();
$list = $loglModel->getStatistics($param) ? : [];
return resultArray(['data'=>$list]);
}
/**
* 统计导出
* @author Michael_xu
* @param
* @return
*/
public function excelExport()
{
$param = $this->param;
$excelModel = new \app\admin\model\Excel();
// 导出的字段列表
$field_list = [
'0' => ['field' => 'realname','name' => '员工'],
'1' => ['field' => 'count','name' => '填写数'],
'2' => ['field' => 'unReadCont','name' => '接收人未读数'],
'3' => ['field' => 'unCommentCount','name' => '未评论数'],
'4' => ['field' => 'commentCount','name' => '已评论数'],
];
// 文件名
$file_name = '5kcrm_log_'.date('Ymd');
$excelModel->dataExportCsv($file_name, $field_list, function($list) use ($param){
$loglModel = new \app\bi\model\Log();
if ($param['type']) {
$timeArr = getTimeByType($param['type']);
$param['start_time'] = $timeArr[0];
$param['end_time'] = $timeArr[1];
}
$list = $loglModel->getStatistics($param);
return $list ? : [];
});
}
}

@ -0,0 +1,150 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-产品分析
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use think\Db;
use think\Hook;
use think\Request;
use app\bi\logic\ExcelLogic;
class Product extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [''],
'allow' => ['statistics', 'productcategory', 'excelexport']
];
Hook::listen('check_auth', $action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'product', 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作']));
}
}
/**
* 产品销量统计
*
* @param string $param
* @return mixed|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function statistics($param = '')
{
$productModel = new \app\crm\model\Product();
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$list = $productModel->getStatistics($param);
//导出使用
if (!empty($param['excel_type'])) {
return $list;
}
return resultArray(['data' => $list]);
}
/**
* 产品分类销量分析
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function productCategory()
{
$param = $this->param;
$productModel = new \app\bi\model\Product();
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$list = $productModel->getStatistics($param);
return resultArray(['data' => $list]);
}
/**
* 导出
*
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function excelExport()
{
$param = $this->param;
$list = $this->statistics($param);
$data = [];
$subtotalCount = [];
$sumCount = [];
$item = [];
$unm = 0;
$subtotal = 0;
$res = [];
foreach ($list as $val) {
$res[] = $val['product_id'];
$data[$val['product_id']][] = $val;
}
$res = array_unique($res);
foreach ($res as $e) {
foreach ($list as $v) {
if ($e == $v['product_id']) {
$unm += $v['num'];
$subtotal += $v['subtotal'];
$sumCount[$e] = $unm + $v['num'];
$subtotalCount[$e] = (float)$subtotal + $v['subtotal'];
}
}
$item[$e][] = [
'type' => '',
'category_id_info' => '',
'product_name' => '',
'contract_name' => '',
'realname' => '',
'name' => '',
'price' => '合计',
'num' => $sumCount[$e],
'subtotal' => $subtotalCount[$e],
];
}
$items = [];
foreach ($data as $key => $value) {
$items[] = array_merge($data[$key], $item[$key]);
}
foreach ($items as $u) {
foreach ($u as $d) {
$field[] = $d;
}
}
$excelLogic = new ExcelLogic();
$data = $excelLogic->productExcel($param, $field);
return $data;
}
}

@ -0,0 +1,565 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-排行榜
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use app\bi\traits\SortTrait;
use think\Hook;
use think\Request;
use think\Db;
use app\bi\model\Customer as CustomerModel;
use app\bi\model\Contract as ContractModel;
use app\bi\logic\ExcelLogic;
class Ranking extends ApiCommon
{
use SortTrait;
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission' => [''],
'allow' => [
'contract',
'receivables',
'signing',
'addcustomer',
'addcontacts',
'recordnun',
'recordcustomer',
'examine',
'product',
'excelexport'
]
];
Hook::listen('check_auth', $action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'ranking', 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code' => 102, 'error' => '无权操作']));
}
}
/**
* 合同金额排行
* @param
* @return
* @author Michael_xu
*/
public function contract($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'contract');
$whereArr['check_status'] = 2;
//导出使用
if (!empty($param['excel_type'])) return $this->handel(
new \app\bi\model\Contract,
$whereArr,
['field' => 'SUM(`money`)', 'alias' => 'money', 'default' => '0.00'],
$param['excel_type']
);
return $this->handel(
new \app\bi\model\Contract,
$whereArr,
['field' => 'SUM(`money`)', 'alias' => 'money', 'default' => '0.00']
);
}
/**
* 回款金额排序
* @return
*/
public function receivables($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'receivables');
$whereArr['check_status'] = 2;
//导出使用
if (!empty($param['excel_type'])) return $this->handel(
new \app\bi\model\Receivables,
$whereArr,
['field' => 'SUM(`money`)', 'alias' => 'money', 'default' => '0.00'],
$param['excel_type']
);
return $this->handel(
new \app\bi\model\Receivables,
$whereArr,
['field' => 'SUM(`money`)', 'alias' => 'money', 'default' => '0.00']
);
}
/**
* 签约合同排序
* @return
*/
public function signing($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'contract');
$whereArr['check_status'] = 2;
//导出使用
if (!empty($param['excel_type'])) $this->handel(
new ContractModel,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0],
$param['excel_type']
);
return $this->handel(
new ContractModel,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0]
);
}
/**
* 新增客户排序
* @return
*/
public function addCustomer($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'customer');
$poolWhere = $this->getWhereByPool();
$poolId = db('crm_customer')->alias('customer')->where($poolWhere)->column('customer_id');
if (!empty($poolId)) $whereArr['customer_id'] = ['notin', $poolId];
//导出使用
if (!empty($param['excel_type'])) return $this->handel(
new \app\bi\model\Customer,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0],
$param['excel_type']
);
return $this->handel(
new \app\bi\model\Customer,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0]
);
}
/**
* 新增联系人排序
* @return
*/
public function addContacts()
{
$param = $this->param;
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'contacts');
//导出使用
if (!empty($param['excel_type'])) return $this->handel(
new \app\bi\model\Contacts,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0],
$param['excel_type']
);
return $this->handel(
new \app\bi\model\Contacts,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0]
);
}
/**
* 跟进次数排行
*
* @param string $param
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function recordNun($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'record');
# 权限内的员工列表
$userData = [];
$userList = db('admin_user')->alias('user')
->field(['user.id', 'user.realname AS user_name', 'structure.name AS structure_name'])
->join('__ADMIN_STRUCTURE__ structure', 'structure.id = user.structure_id')
->whereIn('user.id', $whereArr['create_user_id'][1])->select();
foreach ($userList AS $key => $value) {
$userData[$value['id']]['user_name'] = $value['user_name'];
$userData[$value['id']]['structure_name'] = $value['structure_name'];
}
# 跟进记录列表
$data = [];
$recordWhere['type'] = 1;
$recordWhere['activity_type'] = 2;
$recordWhere['create_user_id'] = ['in', $whereArr['create_user_id'][1]];
$recordWhere['create_time'] = ['between', [$whereArr['create_time'][1][0], $whereArr['create_time'][1][1]]];
$recordList = db('crm_activity')->field(['count(*) as count', 'create_user_id'])->where($recordWhere)
->group('create_user_id')->order('count', 'desc')->select();
foreach ($recordList AS $key => $value) {
$data[] = [
'count' => $value['count'],
'user_name' => $userData[$value['create_user_id']]['user_name'],
'structure_name' => $userData[$value['create_user_id']]['structure_name']
];
}
//导出使用
if (!empty($param['excel_type'])) return $data;
return resultArray(['data' => $data]);
}
/**
* 跟进客户数排行
*
* @param string $param
* @return mixed|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function recordCustomer($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'record');
# 权限内的员工列表
$userData = [];
$userList = db('admin_user')->alias('user')
->field(['user.id', 'user.realname AS user_name', 'structure.name AS structure_name'])
->join('__ADMIN_STRUCTURE__ structure', 'structure.id = user.structure_id')
->whereIn('user.id', $whereArr['create_user_id'][1])->select();
foreach ($userList AS $key => $value) {
$userData[$value['id']]['user_name'] = $value['user_name'];
$userData[$value['id']]['structure_name'] = $value['structure_name'];
}
# 跟进记录列表
$data = [];
$recordWhere['type'] = 1;
$recordWhere['activity_type'] = 2;
$recordWhere['create_user_id'] = ['in', $whereArr['create_user_id'][1]];
$recordWhere['create_time'] = ['between', [$whereArr['create_time'][1][0], $whereArr['create_time'][1][1]]];
$recordList = db('crm_activity')->field(['create_user_id', 'activity_type_id'])->where($recordWhere)
->group('create_user_id, activity_type_id')->select();
foreach ($recordList AS $key => $value) {
if (empty($data[$value['create_user_id']]['user_name'])) {
$data[$value['create_user_id']]['user_name'] = $userData[$value['create_user_id']]['user_name'];
$data[$value['create_user_id']]['structure_name'] = $userData[$value['create_user_id']]['structure_name'];
$data[$value['create_user_id']]['count'] = 1;
} else {
$data[$value['create_user_id']]['count'] = $data[$value['create_user_id']]['count'] + 1;
}
}
$data = $this->sortCommon($data, 'count', 'desc');
//导出使用
if (!empty($param['excel_type'])) return $data;
return resultArray(['data' => $data]);
}
/**
* 出差次数排行
* @return
*/
public function examine($param = '')
{
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$whereArr = $this->com($param, 'record');
$whereArr['category_id'] = 3; // 审批类型3出差
$whereArr['check_status'] = 2;
//导出使用
if (!empty($param['excel_type'])) return $this->handel(
new \app\bi\model\Examine,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0],
$param['excel_type'],
'create_user_id'
);
return $this->handel(
new \app\bi\model\Examine,
$whereArr,
['field' => 'COUNT(*)', 'alias' => 'count', 'default' => 0],
'',
'create_user_id'
);
}
/**
* 产品销量排行
* @return
*/
public function product($param = '')
{
$userModel = new \app\admin\model\User();
$productModel = new \app\bi\model\Product();
if($param['excel_type']!=1){
$param = $this->param;
}
if (!empty($param['start_time'])) $param['start_time'] = strtotime($param['start_time'] . ' 00:00:00');
if (!empty($param['end_time'])) $param['end_time'] = strtotime($param['end_time'] . ' 23:59:59');
$list = $productModel->getSortByProduct($param);
$list = array_column($list, null, 'owner_user_id');
$whereArr = $this->com($param, 'contract');
$data = [];
foreach ($whereArr['owner_user_id'][1] as $val) {
$user = $userModel->getUserById($val);
$item = [];
$item['num'] = !empty($list[$val]['num']) ? (int)$list[$val]['num'] : 0;
$item['user_name'] = $user['realname'];
$item['structure_name'] = $user['structure_name'];
$data[] = $item;
}
# 排序
if (!empty($data)) $data = $this->sortCommon($data, 'num', 'desc');
//导出使用
if (!empty($param['excel_type'])) return $data;
return resultArray(['data' => $data]);
}
/**
* 查询条件
* @return
*/
private function com($param, $type = '')
{
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
$perUserIds = $userModel->getUserByPer('bi', 'ranking', 'read'); //权限范围内userIds
$whereData = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereData['userIds'];
$between_time = $whereData['between_time'];
if ($type == 'contract') {
$where_time = 'order_date';
} elseif (in_array($type, ['record', 'customer', 'contacts'])) {
$where_time = 'create_time';
} elseif ($type == 'receivables') {
$where_time = 'return_time';
} else {
$where_time = 'start_time';
}
//时间戳:新增客户排行
if ($type == 'contract' || $type == 'receivables') {
$whereArr[$where_time] = array('between', array(date('Y-m-d', $between_time[0]), date('Y-m-d', $between_time[1])));
} else {
$whereArr[$where_time] = array('between', array($between_time[0], $between_time[1]));
}
if (in_array($type, ['customer', 'contract', 'receivables', 'contacts'])) {
$whereArr['owner_user_id'] = ['IN', $userIds];
} else {
$whereArr['create_user_id'] = ['IN', $userIds];
}
return $whereArr;
}
/**
* 查询统计数据
*
* @param model $model
* @param array $whereArr
* @return void
* @author Ymob
* @datetime 2019-11-25 11:11:59
*/
private function handel($model, $whereArr, $field, $excel_type = '', $user_field = 'owner_user_id')
{
$userModel = new \app\admin\model\User();
$sql = $model->field([
$user_field,
$field['field'] => $field['alias']
])
->where($whereArr)
->group($user_field)
->fetchSql()
->select();
$list = queryCache($sql);
$list = array_column($list, null, $user_field);
$data = [];
foreach ($whereArr[$user_field][1] as $val) {
$user = $userModel->getUserById($val);
$item = [];
$item[$field['alias']] = $list[$val][$field['alias']] ?: $field['default'];
$item['user_name'] = $user['realname'];
$item['structure_name'] = $user['structure_name'];
$data[] = $item;
}
array_multisort($data, SORT_DESC, array_column($data, $field['alias']));
if (!empty($excel_type)) return $data;
return resultArray(['data' => $data]);
}
/**
* 导出
* @param $type
* @param $types
*/
public function excelExport()
{
$param = $this->param;
$excel_type = $param['excel_type'];
$type = [];
$type['excel_types'] = $param['excel_types'];
switch ($param['excel_types']) {
case 'contract':
$list = $this->contract($param);
foreach ($list as $key => $v) {
$list[$key]['id'] = $key + 1;
}
$type['type'] = '合同金额排行';
break;
case'receivables':
$list = $this->receivables($param);
$type['type'] = '回款金额排行';
break;
case 'signing':
$list = $this->signing($param);
$type['type'] = '签约合同排行';
break;
case 'product':
$list = $this->product($param);
$type['type'] = '产品销量排行';
break;
case 'addCustomer':
$list = $this->addCustomer($param);
$type['type'] = '新增客户数排行';
break;
case 'addContacts':
$list = $this->addContacts($param);
$type['type'] = '新增联系人数排行';
break;
case 'recordNun':
$list = $this->recordNun($param);
$type['type'] = '跟进次数排行';
break;
case 'recordCustomer':
$list = $this->recordCustomer($param);
$type['type'] = '跟进客户数排行';
break;
case 'examine':
$list = $this->examine($param);
$type['type'] = '出差次数排行';
break;
}
if(empty($list)){
return resultArray(['data'=>'数据不存在']);
}
$excelLogic = new ExcelLogic();
$data = $excelLogic->rankingExcle($param, $list);
return $data;
}
/**
* [客户公海条件]
* @author Michael_xu
* @param
* @return
*/
public function getWhereByPool()
{
$configModel = new \app\crm\model\ConfigData();
$configInfo = $configModel->getData();
$config = $configInfo['config'] ? : 0;
$follow_day = $configInfo['follow_day'] ? : 0;
$deal_day = $configInfo['deal_day'] ? : 0;
$whereData = [];
//启用
if ($config == 1) {
//默认公海条件(没有负责人或已经到期)
$data['follow_time'] = time()-$follow_day*86400;
$data['deal_time'] = time()-$deal_day*86400;
$data['deal_status'] = '未成交';
if ($follow_day < $deal_day) {
$whereData = function($query) use ($data){
$query->where(['customer.owner_user_id'=>0])
->whereOr(function ($query) use ($data) {
$query->where(function ($query) use ($data) {
$query->where(['customer.update_time' => array('elt',$data['follow_time'])])
->whereOr(['customer.deal_time' => array('elt',$data['deal_time'])]);
})
->where(['customer.is_lock' => 0])
->where(['customer.deal_status' => ['neq','已成交']]);
});
};
} else {
$whereData = function($query) use ($data){
$query->where(['customer.owner_user_id'=>0])
->whereOr(function ($query) use ($data) {
$query->where(function ($query) use ($data) {
$query->where(['customer.deal_time' => array('elt',$data['deal_time'])]);
})
->where(['customer.is_lock' => 0])
->where(['customer.deal_status' => ['neq','已成交']]);
});
};
}
} else {
$whereData['customer.owner_user_id'] = 0;
}
return $whereData ? : '';
}
}

@ -0,0 +1,90 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商业智能-回款分析
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\controller;
use app\admin\controller\ApiCommon;
use think\Hook;
use think\Request;
class Receivables extends ApiCommon
{
/**
* 用于判断权限
* @permission 无限制
* @allow 登录用户可访问
* @other 其他根据系统设置
**/
public function _initialize()
{
$action = [
'permission'=>[''],
'allow'=>['statistics','statisticlist']
];
Hook::listen('check_auth',$action);
$request = Request::instance();
$a = strtolower($request->action());
if (!in_array($a, $action['permission'])) {
parent::_initialize();
}
if (!checkPerByAction('bi', 'receivables' , 'read')) {
header('Content-Type:application/json; charset=utf-8');
exit(json_encode(['code'=>102,'error'=>'无权操作']));
}
}
//回款统计列表
public function statisticList()
{
$receivablesModel = new \app\crm\model\Receivables();
$param = $this->param;
$ret = $receivablesModel->getstatisticsData($param);
return resultArray(['data'=>$ret]);
}
/**
* 回款统计 柱状图
* @author Michael_xu
* @param year 年份 , month 月份
* @return
*/
public function statistics()
{
$receivablesModel = new \app\crm\model\Receivables();
$userModel = new \app\admin\model\User();
$param = $this->param;
$adminModel = new \app\admin\model\Admin();
$perUserIds = $userModel->getUserByPer('bi', 'receivables', 'read'); //权限范围内userIds
$whereData = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereData['userIds'];
$year = $param['year'];
//时间段
if ($param['month']) {
//根据月份计算天数
$days = getmonthdays(strtotime($param['month']));
//获取时间范围内的每日时间戳数组(当月)
$start = strtotime($param['month'].'-'.'01');
$end = (strtotime($param['month'].'-'.$days) > time()) ? time() : strtotime($date.'-'.$days);
$create_time = array($start,$end);
} elseif ($param['year']) {
$next_year = $param['year']+1;
$create_time = array(strtotime($param['year'].'-01-01'),strtotime($next_year.'-01-01'));
} else {
$create_time = getTimeByType('year');
}
unset($param['month']);
unset($param['year']);
$param['create_time']['start'] = $create_time[0];
$param['create_time']['end'] = $create_time[1];
$chartParam = $param;
$chartParam['year'] = $year;
$chartParam['userIds'] = $userIds ? : [];
$chartList = $receivablesModel->getStatistics($chartParam); //柱状图
return resultArray(['data' => $chartList]);
}
}

@ -0,0 +1,5 @@
<?php
return [
'hello thinkphp' => 'hello thinkphp',
'data type error' => 'data type error',
];

@ -0,0 +1,4 @@
<?php
return [
'CUSTOMER' => '客户',
];

@ -0,0 +1,145 @@
<?php
/**
* 员工客户分析逻辑类
*
* @author qifan
* @date 2020-12-24
*/
namespace app\bi\logic;
use app\bi\traits\SortTrait;
use think\Db;
class BiCustomerLogic
{
use SortTrait;
/**
* 员工客户满意度分析
*
* @param $param
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getCustomerSatisfaction($param)
{
$result = [];
$userModel = new \app\admin\model\User();
$perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); # 权限范围内userIds
$userIds = $perUserIds; # 数组交集
if (empty($userIds)) return [];
# 员工信息
$userList = db('admin_user')->field(['id', 'realname'])->whereIn('id', $userIds)->select();
foreach ($userList AS $key => $value) {
$result[$value['id']] = [
'realname' => $value['realname'],
'visitContractNum' => 0,
'很满意' => 0,
'满意' => 0,
'一般' => 0,
'不满意' => 0,
'很不满意' => 0,
];
}
$visitField = ['owner_user_id', 'satisfaction', 'count(`satisfaction`) AS satisfactionCount', 'count(`contract_id`) AS contractCount'];
$where['owner_user_id'] = ['in', $userIds];
$where['create_time'] = ['between', [$param['start_time'], $param['end_time']]];
$where['deleted_state'] = 0;
$visitList = db('crm_visit')->field($visitField)->where($where)->group('owner_user_id, satisfaction')->select();
foreach ($visitList AS $key => $value) {
if (!empty($value['satisfaction']) && trim($value['satisfaction']) == '很满意') {
$result[$value['owner_user_id']]['很满意'] += $value['satisfactionCount'];
}
if (!empty($value['satisfaction']) && trim($value['satisfaction']) == '满意') {
$result[$value['owner_user_id']]['满意'] += $value['satisfactionCount'];
}
if (!empty($value['satisfaction']) && trim($value['satisfaction']) == '一般') {
$result[$value['owner_user_id']]['一般'] += $value['satisfactionCount'];
}
if (!empty($value['satisfaction']) && trim($value['satisfaction']) == '不满意') {
$result[$value['owner_user_id']]['不满意'] += $value['satisfactionCount'];
}
if (!empty($value['satisfaction']) && trim($value['satisfaction']) == '很不满意') {
$result[$value['owner_user_id']]['很不满意'] += $value['satisfactionCount'];
}
$result[$value['owner_user_id']]['visitContractNum'] += $value['contractCount'];
}
$result = $this->sortCommon($result, 'visitContractNum', 'desc');
return array_values($result);
}
/**
* 产品满意度分析
*
* @param $param
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getProductSatisfaction($param)
{
$productData = [];
$userModel = new \app\admin\model\User();
$perUserIds = $userModel->getUserByPer('bi', 'customer', 'read'); # 权限范围内userIds
$userIds = !empty($param['user_id']) ? array_intersect([$param['user_id']], $perUserIds) : $perUserIds; # 数组交集
if (empty($userIds)) return [];
# 产品列表(上架中)
$productList = db('crm_product')->field(['product_id', 'name'])->where('status', '上架')->select();
foreach ($productList AS $key => $value) {
$productData[$value['product_id']] = [
'productName' => $value['name'],
'visitNum' => 0,
'很满意' => 0,
'满意' => 0,
'一般' => 0,
'不满意' => 0,
'很不满意' => 0,
];
}
# 回访条件
$where['visit.owner_user_id'] = ['in', $userIds];
$where['visit.create_time'] = ['between', [$param['start_time'], $param['end_time']]];
$where['visit.deleted_state'] = 0;
# 回访数据
$visitList = db('crm_visit')->alias('visit')->field(['visit.contract_id', 'visit.satisfaction'])
->join('__CRM_CONTRACT__ contract', 'contract.contract_id = visit.contract_id')
->where($where)->select();
# 整理数据
foreach ($visitList AS $key => $value) {
if (empty($value['satisfaction'])) continue;
$productIds = db('crm_contract_product')->where('contract_id', $value['contract_id'])->column('product_id');
foreach ($productIds AS $k => $v) {
if ($productData[$v]) {
if (trim($value['satisfaction']) == '很满意') $productData[$v]['很满意']++;
if (trim($value['satisfaction']) == '满意') $productData[$v]['满意']++;
if (trim($value['satisfaction']) == '一般') $productData[$v]['一般']++;
if (trim($value['satisfaction']) == '不满意') $productData[$v]['不满意']++;
if (trim($value['satisfaction']) == '很不满意') $productData[$v]['很不满意']++;
$productData[$v]['visitNum']++;
}
}
}
$productData = $this->sortCommon($productData, 'visitNum', 'desc');
return array_values($productData);
}
}

@ -0,0 +1,300 @@
<?php
namespace app\bi\logic;
class ExcelLogic
{
/**
* 员工客户分析导出
* @param $type
* @param $param
* @return mixed
*/
public function biexcle($type, $param)
{
$excelModel = new \app\admin\model\Excel();
$file_name='';
$field_list=[];
switch ($type['excel_types']) {
case 'statistics':
$file_name = 'totalCustomerTable';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '新增客户数', 'field' => 'customer_num'],
'2' => ['name' => '成交客户数', 'field' => 'deal_customer_num'],
'3' => ['name' => '客户成交率', 'field' => 'deal_customer_rate'],
'4' => ['name' => '合同总金额', 'field' => 'un_receivables_money'],
'5' => ['name' => '回款金额', 'field' => 'receivables_money'],
];
break;
case 'recordList':
$file_name = 'customerRecordInfo';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '跟进次数', 'field' => 'record_num'],
'2' => ['name' => '跟进客户数', 'field' => 'customer_num'],
];
break;
case 'recordMode':
$file_name = 'customerRecordCategoryStats';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '跟进次数', 'field' => 'record_num'],
'2' => ['name' => '跟进客户数', 'field' => 'customer_num'],
];
break;
case 'poolList':
$file_name = 'poolTable';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '部门', 'field' => 'username'],
'2' => ['name' => '公海池领取客户数', 'field' => 'receive'],
'3' => ['name' => '进入公海客户数', 'field' => 'put_in'],
];
break;
case 'userCycle':
$file_name = 'employeeCycleInfo';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '成交周期(天)', 'field' => 'cycle'],
'2' => ['name' => '成交客户数', 'field' => 'customer_num'],
];
break;
case 'customerSatisfaction':
$file_name = 'customerSatisfaction';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '回访合同总数', 'field' => 'visit'],
'2' => ['name' => '很满意', 'field' => 'satisfaction1'],
'3' => ['name' => '满意', 'field' => 'satisfaction2'],
'4' => ['name' => '一般', 'field' => 'satisfaction3'],
'5' => ['name' => '不满意', 'field' => 'satisfaction4'],
'6' => ['name' => '很不满意', 'field' => 'satisfaction5'],
];
break;
case 'productSatisfaction':
$file_name = 'productSatisfaction';
$field_list = [
'0' => ['name' => '员工姓名', 'field' => 'realname'],
'1' => ['name' => '回访合同总数', 'field' => 'visit'],
'2' => ['name' => '很满意', 'field' => 'satisfaction1'],
'3' => ['name' => '满意', 'field' => 'satisfaction2'],
'4' => ['name' => '一般', 'field' => 'satisfaction3'],
'5' => ['name' => '不满意', 'field' => 'satisfaction4'],
'6' => ['name' => '很不满意', 'field' => 'satisfaction5'],
];
break;
}
return $excelModel->biExportExcel($file_name, $field_list, $type['type'], $param);
}
/**
* 员工业绩分析
* @param $type
* @param $param
* @return mixed
*/
public function contractExcel($type, $param)
{
$excelModel = new \app\admin\model\Excel();
if($type['excel_types']=='analysis'){
$file_name = 'contractNumStats';
$field_list = [];
p($excelModel->template_download($file_name, $field_list, $type['type'], $param));
return $excelModel->template_download($file_name, $field_list, $type['type'], $param);
}elseif ($type['excel_types']=='summary'){
$file_name = 'totalContract';
$field_list = [
'0' => ['name' => '日期', 'field' => 'type'],
'1' => ['name' => '签约合同数(个)', 'field' => 'count'],
'2' => ['name' => '签约合同金额(元)', 'field' => 'money'],
'3' => ['name' => '回款金额(元)', 'field' => 'back'],
];
return $excelModel->biExportExcel($file_name, $field_list, $type['type'], $param['items']);
}elseif ($type['excel_types']=='invoice'){
$file_name = 'invoiceStats';
$field_list = [
'0' => ['name' => '日期', 'field' => 'type'],
'1' => ['name' => '回款金额(元)', 'field' => 'receivables_money'],
'2' => ['name' => '开票金额(元)', 'field' => 'invoice_money'],
'3' => ['name' => '已回款未开票(元)', 'field' => 'not_invoice'],
'4' => ['name' => '已开票未回款(元)', 'field' => 'not_receivables'],
];
return $excelModel->biExportExcel($file_name, $field_list, $type['type'], $param);
}
// switch ($type['excel_types']) {
// case 'analysis':
//
//
// break;
// case 'summary':
// $file_name = 'totalContract';
// $field_list = [
// '0' => ['name' => '日期', 'field' => 'type'],
// '1' => ['name' => '签约合同数(个)', 'field' => 'count'],
// '2' => ['name' => '签约合同金额(元)', 'field' => 'money'],
// '3' => ['name' => '回款金额(元)', 'field' => 'back'],
// ];
// return $excelModel->biExportExcel($file_name, $field_list, $type['type'], $param['items']);
// break;
// case 'invoice':
// $file_name = 'invoiceStats';
// $field_list = [
// '0' => ['name' => '日期', 'field' => 'type'],
// '1' => ['name' => '回款金额(元)', 'field' => 'receivables_money'],
// '2' => ['name' => '开票金额(元)', 'field' => 'invoice_money'],
// '3' => ['name' => '已回款未开票(元)', 'field' => 'not_invoice'],
// '4' => ['name' => '已开票未回款(元)', 'field' => 'not_receivables'],
// ];
// return $excelModel->biExportExcel($file_name, $field_list, $type['type'], $param);
// break;
// }
}
/**
* 产品分析
* @param $type
* @param $param
* @return mixed
*/
public function productExcel($type, $param)
{
$file_name = 'contractNumStats';
$field_list = [
'0' => ['name' => '日期', 'field' => 'type'],
'1' => ['name' => '产品分类', 'field' => 'category_id_info'],
'2' => ['name' => '产品名称', 'field' => 'product_name'],
'3' => ['name' => '合同编号', 'field' => 'contract_name'],
'4' => ['name' => '负责人', 'field' => 'realname'],
'5' => ['name' => '客户名称', 'field' => 'name'],
'6' => ['name' => '销售单价', 'field' => 'price'],
'7' => ['name' => '数量', 'field' => 'num'],
'8' => ['name' => '订单产品小计', 'field' => 'subtotal'],
];
$type = '产品销售情况统计';
$excelModel = new \app\admin\model\Excel();
return $excelModel->biExportExcel($file_name, $field_list, $type, $param);
}
/**
* 排行榜
* @param $type
* @param $param
* @return mixed
*/
public function rankingExcle($type, $param)
{
$excelModel = new \app\admin\model\Excel();
switch ($type['excel_types']) {
case 'contract':
$file_name = 'contractRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '合同金额(元)', 'field' => 'money'],
];
break;
case 'receivables':
$file_name = 'receivablesRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '回款金额(元)', 'field' => 'money'],
];
break;
case 'signing':
$file_name = 'signingRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '签约合同', 'field' => 'count'],
];
break;
case 'product':
$file_name = 'productCountRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '产品销量', 'field' => 'num'],
];
break;
case 'addCustomer':
$file_name = 'customerCountRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '新增客户数(个)', 'field' => 'count'],
];
break;
case 'addContacts':
$file_name = 'contactsCountRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '新增联系人数(个)', 'field' => 'count'],
];
break;
case 'recordNun':
$file_name = 'FollowupRecordCountRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '跟进次数(个)', 'field' => 'count'],
];
break;
case 'recordCustomer':
$file_name = 'customerFollowupCountRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '跟进客户数(个)', 'field' => 'count'],
];
break;
case 'examine':
$file_name = 'travelCountRanKing';
$field_list = [
'0' => ['name' => '公司总排名', 'field' => 'id'],
'1' => ['name' => '签订人', 'field' => 'user_name'],
'2' => ['name' => '部门', 'field' => 'structure_name'],
'3' => ['name' => '出差次数(次)', 'field' => 'count'],
];
break;
}
return $excelModel->biExportExcel($file_name, $field_list, $type['type'], $param);
}
/**
* 业绩目标完成情况
* @param $type
* @param $param
* @return mixed
*/
public function achienementExcel($type, $param)
{
$file_name = 'contractNumStats';
$field_list = [
'0' => ['name' => '名称', 'field' => 'name'],
'1' => ['name' => '月份', 'field' => 'month'],
'2' => ['name' => '目标', 'field' => 'achievement'],
'3' => ['name' => '完成', 'field' => 'money'],
'4' => ['name' => 'rate', 'field' => 'realname'],
];
$type = '业绩目标完成情况';
$excelModel = new \app\admin\model\Excel();
return $excelModel->biExportExcel($file_name, $field_list, $type, $param);
}
}

@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | Description: 操作记录
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
use think\Validate;
class ActionRecord extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'admin_action_record';
/**
* [getDataList 获取列表]
* @return [array]
*/
public function getDataCount($request)
{
$dataCount = db('admin_action_record')->where($request)->count();
return $dataCount;
}
}

@ -0,0 +1,93 @@
<?php
// +----------------------------------------------------------------------
// | Description: 商机
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com
// +----------------------------------------------------------------------
namespace app\bi\model;
use think\Db;
use app\admin\model\Common;
use think\Request;
class Business extends Common
{
/**
* 为了数据库的整洁同时又不影响Model和Controller的名称
* 我们约定每个模块的数据表都加上相同的前缀比如CRM模块用crm作为数据表前缀
*/
protected $name = 'crm_business';
/**
* [getDataCount 商机count]
* @author Michael_xu
* @param
* @return
*/
function getDataCount($whereArr)
{
$where = [];
$dataCount = $this->where($whereArr)->where($where)->count('business_id');
$count = $dataCount ? : 0;
return $count;
}
/**
* [getDataMoney 商机金额]
* @author Michael_xu
* @param
* @return
*/
function getDataMoney($whereArr)
{
$where = [];
$money = $this->where($whereArr)->where($where)->sum('money');
return $money;
}
/**
* 获取商机list
*
* @param $param
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
function getDataList($param)
{
$page = !empty($param['page']) ? $param['page'] : 1;
$limit = !empty($param['limit']) ? $param['limit'] : 15;
unset($param['page']);
unset($param['limit']);
$userModel = new \app\admin\model\User();
$adminModel = new \app\admin\model\Admin();
$perUserIds = $userModel->getUserByPer('bi', 'business', 'read'); //权限范围内userIds
$whereData = $adminModel->getWhere($param, '', $perUserIds); //统计条件
$userIds = $whereData['userIds'];
if (!empty($whereData['between_time']['last_time'])) unset($whereData['between_time']['last_time']);
$between_time = $whereData['between_time'];
$where['business.owner_user_id'] = array('in',$userIds);
$where['business.create_time'] = ['between', $between_time];
$where['check_status'] = 2;
if (!empty($param['is_end']) && $param['is_end'] == 1) $where['is_end'] = 1;
$count = db('crm_business')->alias('business')
->join('__CRM_CONTRACT__ contract', 'contract.business_id = business.business_id', 'left')
->where($where)->group('business.business_id')->count();
$sql = db('crm_business')->alias('business')
->field('business.business_id,business.customer_id,business.money,business.type_id,business.status_id,business.deal_date,business.create_user_id,business.owner_user_id')
->join('__CRM_CONTRACT__ contract', 'contract.business_id = business.business_id', 'left')
->where($where)
->fetchSql()
->limit(($page - 1) * $limit, $limit)
->order(['money' => 'DESC'])
->group('business.business_id')
->select();
return ['dataCount' => $count, 'list' => queryCache($sql)];
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save