悟空crm客户管理系统二次开发 单独新增表格字段

1,仪表盘(数据来源修改)

注意点:有层级关系,管理员账号可以看到全部数据,主管只能看到下属数据。
在这里插入图片描述

在这里插入图片描述

2、在客户管理菜单里面 增加一个时间筛选、额度汇总

在这里插入图片描述

    /*** 获取客户列表** @param $type* @param $content* @return bool|\PDOStatement|string|\think\Collection* @throws \think\db\exception\DataNotFoundException* @throws \think\db\exception\ModelNotFoundException* @throws \think\exception\DbException*/private function getCustomerList($type, $content)
{# 默认条件$customerWhere = $this->getCustomerWhere();# 查询条件$searchWhere = $this->getSearchWhere($type, $content);# 查询字段$field = ['customer_id', 'name', 'create_time', 'owner_user_id', 'deal_time', 'telephone', 'mobile'];return db('crm_customer')->alias('customer')->field($field)->where($customerWhere)->where($searchWhere)->limit(10)->order('update_time', 'desc')->select();
}

3,单独新增一个今日数据表格

(以表格的形式呈现出来)
需求:
3.1,需要关联部门和员工层级关系,比如:普通员工只填写自己的数据,部门领导客户看到下面人员所有数据,管理员可以看到所有部门数据。
3.2,条件筛选,时间筛选、部门筛选、员工筛选、全部
3.3,表格可以自定义增删改,自定义隐藏和开启字段
在这里插入图片描述

  public function getDataList($request){$userModel = new \app\admin\model\User();$structureModel = new \app\admin\model\Structure();$fieldModel = new \app\admin\model\Field();$customerModel = new \app\crm\model\Customer();$search = $request['search'];$user_id = $request['user_id'];$scene_id = (int)$request['scene_id'];$is_excel = $request['is_excel']; //导出$order_field = $request['order_field'];$order_type = $request['order_type'];$pageType = $request['pageType'];$getCount = $request['getCount'];$cstart_time = $request['cstart_time'];$cend_time = $request['cend_time'];//需要过滤的参数$unsetRequest = ['scene_id', 'search', 'user_id', 'is_excel', 'action', 'order_field', 'order_type', 'is_remind', 'getCount', 'type', 'otherMap', 'business_id', 'check_status','cstart_time','cend_time'];foreach ($unsetRequest as $v) {unset($request[$v]);}$request = $this->fmtRequest($request);$requestMap = $request['map'] ?: [];$sceneModel = new \app\admin\model\Scene();if ($scene_id) {//自定义场景$sceneMap = $sceneModel->getDataById($scene_id, $user_id, 'todaydata') ?: [];} else {//默认场景$sceneMap = $sceneModel->getDefaultData('crm_todaydata', $user_id) ?: [];}$searchMap = [];if ($search || $search == '0') {//普通筛选$searchMap = function ($query) use ($search) {$query->where('todaydata.name', array('like', '%' . $search . '%'))->whereOr('todaydata.mobile', array('like', '%' . $search . '%'))->whereOr('todaydata.telephone', array('like', '%' . $search . '%'));};}$partMap = [];//优先级:普通筛选>高级筛选>场景$teamMap=$requestMap['team_id'];//团队成员 高级筛选if($teamMap){$partMap= advancedQueryFormatForTeam($teamMap,'todaydata','todaydata_id');unset($requestMap['team_id']);$map = $requestMap ? array_merge($sceneMap, $requestMap) : $sceneMap;} else {$map = $requestMap ? array_merge($sceneMap, $requestMap) : $sceneMap;}//高级筛选$map = advancedQuery($map, 'crm', 'todaydata', 'index');//权限$a = 'index';if ($is_excel) $a = 'excelExport';$authMap = [];$auth_user_ids = $userModel->getUserByPer('crm', 'todaydata', $a);if (isset($map['todaydata.owner_user_id'])) {if (!is_array($map['todaydata.owner_user_id'][1])) {$map['todaydata.owner_user_id'][1] = [$map['todaydata.owner_user_id'][1]];}if (in_array($map['todaydata.owner_user_id'][0], ['neq', 'notin'])) {$auth_user_ids = array_diff($auth_user_ids, $map['todaydata.owner_user_id'][1]) ?: [];    //取差集} else {$auth_user_ids = array_intersect($map['todaydata.owner_user_id'][1], $auth_user_ids) ?: [];    //取交集}unset($map['todaydata.owner_user_id']);$auth_user_ids = array_merge(array_unique(array_filter($auth_user_ids))) ?: ['-1'];//负责人、相关团队$authMap['todaydata.owner_user_id'] = ['in', $auth_user_ids];} else {$authMapData = [];$authMapData['auth_user_ids'] = $auth_user_ids;$authMapData['user_id'] = $user_id;$authMap = function ($query) use ($authMapData) {$query->where('todaydata.owner_user_id', array('in', $authMapData['auth_user_ids']));// ->whereOr('todaydata.ro_user_id', array('like', '%,' . $authMapData['user_id'] . ',%'))// ->whereOr('todaydata.rw_user_id', array('like', '%,' . $authMapData['user_id'] . ',%'));};}$timeWhere = '';if($cstart_time){$timeWhere .= 'todaydata.create_time>='.strtotime($cstart_time);}if($cend_time){if($timeWhere) $timeWhere .= ' and ';$timeWhere .= 'todaydata.create_time<'.strtotime('+1 day', strtotime($cend_time));}//列表展示字段$indexField = $fieldModel->getIndexField('crm_todaydata', $user_id, 1) ?: array('name');$userField = $fieldModel->getFieldByFormType('crm_todaydata', 'user'); //人员类型$structureField = $fieldModel->getFieldByFormType('crm_todaydata', 'structure');  //部门类型$datetimeField = $fieldModel->getFieldByFormType('crm_todaydata', 'datetime'); //日期时间类型$booleanField = $fieldModel->getFieldByFormType('crm_todaydata', 'boolean_value'); //布尔值$dateIntervalField = $fieldModel->getFieldByFormType('crm_todaydata', 'date_interval'); // 日期区间类型字段$positionField = $fieldModel->getFieldByFormType('crm_todaydata', 'position'); // 地址类型字段$handwritingField = $fieldModel->getFieldByFormType('crm_todaydata', 'handwriting_sign'); // 手写签名类型字段$locationField = $fieldModel->getFieldByFormType('crm_todaydata', 'location'); // 定位类型字段$boxField = $fieldModel->getFieldByFormType('crm_todaydata', 'checkbox'); // 多选类型字段$floatField = $fieldModel->getFieldByFormType('crm_todaydata', 'floatnumber'); // 货币类型字段
//        $fieldGrant = db('admin_field_mask')->where('types', 'todaydata')->select();# 处理人员和部门类型的排序报错问题(前端传来的是包含_name的别名字段)$temporaryField = str_replace('_name', '', $order_field);if (in_array($temporaryField, $userField) || in_array($temporaryField, $structureField)) {$order_field = $temporaryField;}//排序if ($order_type && $order_field) {$order = $fieldModel->getOrderByFormtype('crm_todaydata', 'todaydata', $order_field, $order_type);} else {$order = 'todaydata.update_time desc';}$readAuthIds = $userModel->getUserByPer('crm', 'todaydata', 'read');$updateAuthIds = $userModel->getUserByPer('crm', 'todaydata', 'update');$deleteAuthIds = $userModel->getUserByPer('crm', 'todaydata', 'delete');$customerWhere = [];if ($pageType == !'all') {//非客户池条件// $customerWhere = $customerModel->getWhereByCustomer();}$dataCount = db('crm_todaydata')->alias('todaydata')->join('__CRM_CUSTOMER__ customer', 'todaydata.customer_id = customer.customer_id', 'LEFT')->where($map)->where($searchMap)->where($authMap)->where($partMap)->where($customerWhere)->where($timeWhere)->count('todaydata_id');if ($getCount == 1) {$data['dataCount'] = $dataCount ?: 0;return $data;}$statisticsField = ['sum(jrxh) as total_jrxh','sum(jrjfrs) as total_jrjfrs','sum(zsy) as total_zsy','sum(total_follow_buy) as total_total_follow_buy','sum(yxkh) as total_yxkh','sum(zgm) as total_zgm',];if($dataCount > 0){$statisticsField[] = 'ROUND(sum(zhl) / '.$dataCount.', 2) as total_zhl';}else{$statisticsField[] = '0 as total_zhl';}$statistics = db('crm_todaydata')->alias('todaydata')->field($statisticsField)->where($map)->where($searchMap)->where($partMap)->where($authMap)->where($customerWhere)->where($timeWhere)->find();if(!$statistics){$statistics = ['total_jrxh' => 0,'total_jrjfrs' => 0,'total_zsy' => 0,'total_total_follow_buy' => 0,'total_yxkh' => 0,'total_zgm' => 0,'total_zhl' => 0,];}$list = db('crm_todaydata')->alias('todaydata')->join('__CRM_CUSTOMER__ customer', 'todaydata.customer_id = customer.customer_id', 'LEFT')->where($map)->where($searchMap)->where($partMap)->where($authMap)->where($customerWhere)->where($timeWhere)->limit($request['offset'], $request['length'])->field('todaydata.*,customer.name as customer_name')->orderRaw($order)->select();# 扩展数据$extraData = [];$todaydata_id_list = !empty($list) ? array_column($list, 'todaydata_id') : [];$grantData = getFieldGrantData($user_id);foreach ($grantData['crm_todaydata'] as $key => $value) {foreach ($value as $ke => $va) {if($va['maskType']!=0){$fieldGrant[$ke]['maskType'] = $va['maskType'];$fieldGrant[$ke]['form_type'] = $va['form_type'];$fieldGrant[$ke]['field'] = $va['field'];}}}foreach ($list as $k => $v) {$list[$k]['create_user_id_info'] = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];$list[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];$list[$k]['customer_id_info']['customer_id'] = $v['customer_id'] ?: '';$list[$k]['customer_id_info']['name'] = $v['customer_name'] ?: '';foreach ($userField as $key => $val) {$usernameField = !empty($v[$val]) ? db('admin_user')->whereIn('id', stringToArray($v[$val]))->column('realname') : [];$list[$k][$val] = implode($usernameField, ',');}foreach ($structureField as $key => $val) {$structureNameField = !empty($v[$val]) ? db('admin_structure')->whereIn('id', stringToArray($v[$val]))->column('name') : [];$list[$k][$val] = implode($structureNameField, ',');}foreach ($datetimeField as $key => $val) {$list[$k][$val] = !empty($v[$val]) ? date('Y-m-d H:i:s', $v[$val]) : null;}foreach ($booleanField as $key => $val) {$list[$k][$val] = !empty($v[$val]) ? (string)$v[$val] : '0';}// 处理日期区间类型字段的格式foreach ($dateIntervalField as $key => $val) {$list[$k][$val] = !empty($extraData[$v['todaydata_id']][$val]) ? json_decode($extraData[$v['todaydata_id']][$val], true) : null;}// 处理地址类型字段的格式foreach ($positionField as $key => $val) {$list[$k][$val] = !empty($extraData[$v['todaydata_id']][$val]) ? json_decode($extraData[$v['todaydata_id']][$val], true) : null;}// 手写签名类型字段foreach ($handwritingField as $key => $val) {$handwritingData = !empty($v[$val]) ? db('admin_file')->where('file_id', $v[$val])->value('file_path') : null;$list[$k][$val] = ['url' => !empty($handwritingData) ? getFullPath($handwritingData) : null];}// 定位类型字段foreach ($locationField AS $key => $val) {$list[$k][$val] = !empty($extraData[$v['todaydata_id']][$val]) ? json_decode($extraData[$v['todaydata_id']][$val], true) : null;}// 多选框类型字段foreach ($boxField AS $key => $val) {$list[$k][$val] = !empty($v[$val]) ? trim($v[$val], ',') : null;}// 货币类型字段foreach ($floatField AS $key => $val) {$list[$k][$val] = $v[$val]!='0.00' ? (string)$v[$val] : null;}//掩码相关类型字段foreach ($fieldGrant AS $key => $val){//掩码相关类型字段if ($val['maskType']!=0 && $val['form_type'] == 'mobile') {$pattern = "/(1[3458]{1}[0-9])[0-9]{4}([0-9]{4})/i";$rs = preg_replace($pattern, "$1****$2", $v[$val['field']]);$list[$k][$val['field']] = !empty($v[$val['field']]) ? (string)$rs : null;} elseif ($val['maskType']!=0 && $val['form_type'] == 'email') {$email_array = explode("@", $v[$val['field']]);$prevfix = (strlen($email_array[0]) < 4) ? "" : substr($v[$val['field']], 0, 2); //邮箱前缀$str = preg_replace('/([\d\w+_-]{0,100})@/', "***@", $v[$val['field']], -1, $count);$rs = $prevfix . $str;$list[$k][$val['field']] = !empty($v[$val['field']]) ?$rs: null;} elseif ($val['maskType']!=0 && in_array($val['form_type'],['position','floatnumber'])) {$list[$k][$val['field']] = !empty($v[$val['field']]) ? (string)substr_replace($v[$val['field']], '*****',0,strlen($v[$val['field']])) : null;}}//权限$permission = [];$is_read = 0;$is_update = 0;$is_delete = 0;if (in_array($v['owner_user_id'], $readAuthIds)) $is_read = 1;if (in_array($v['owner_user_id'], $updateAuthIds)) $is_update = 1;if (in_array($v['owner_user_id'], $deleteAuthIds)) $is_delete = 1;$permission['is_read'] = $is_read;$permission['is_update'] = $is_update;$permission['is_delete'] = $is_delete;$list[$k]['permission'] = $permission;# 关注$starWhere = ['user_id' => $user_id, 'target_id' => $v['todaydata_id'], 'type' => 'crm_todaydata'];$star = Db::name('crm_star')->where($starWhere)->value('star_id');$list[$k]['star'] = !empty($star) ? 1 : 0;# 日期// $list[$k]['create_time'] = !empty($v['create_time']) ? date('Y-m-d H:i:s', $v['create_time']) : null;$list[$k]['create_time'] = !empty($v['create_time']) ? date('Y-m-d', $v['create_time']) : null;$list[$k]['update_time'] = !empty($v['update_time']) ? date('Y-m-d H:i:s', $v['update_time']) : null;$list[$k]['last_time'] = !empty($v['last_time']) ? date('Y-m-d H:i:s', $v['last_time']) : null;# 创建人$list[$k]['create_user_name'] = !empty($list[$k]['create_user_id_info']['realname']) ? $list[$k]['create_user_id_info']['realname'] : '';# 负责人$list[$k]['owner_user_name'] = !empty($list[$k]['owner_user_id_info']['realname']) ? $list[$k]['owner_user_id_info']['realname'] : '';# 系统字段  负责人部门   zjf  20210726$list[$k]['owner_user_structure_name'] = $list[$k]['owner_user_id_info']['structure_name'];}$data = [];$data['list'] = $list;$data['dataCount'] = $dataCount ?: 0;$data['statistics'] = $statistics ?: [];return $data;}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二次开发增加的条件筛选:

时间筛选、部门筛选、员工筛选、全部
在这里插入图片描述

  /*** 获取查询条件** @param $type* @param $content* @return array|\Closure*/private function getSearchWhere($type, $content)
{$searchWhere = [];# 查询客户名称if ($type == 'name') {$searchWhere = function ($query) use ($content) {$query->where('name', 'like', '%' . $content . '%');};}# 查询手机或电话if ($type == 'phone') {$searchWhere = function ($query) use ($content) {$query->where(function ($query) use ($content) {$query->whereOr('telephone', $content);$query->whereOr('mobile', $content);});};}return $searchWhere;
}

悟空crm客户管理系统二次开发
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1534596.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vagrant+virtualbox+ubuntu22.04无法上网问题

一、过程 vagrantfile配置私有网络 config.vm.network "private_network", ip: "192.168.56.10"启动虚拟机&#xff0c;可以ping通百度的实际IP&#xff0c;ping不通域名修改/etc/netplan/50-vagrant.yaml&#xff0c;配置DNS network:renderer: Networ…

2024年9月一区SCI-神经种群动态优化算法NPDOA-附Matlab免费代码

引言 本期介绍了一种受脑神经科学启发的元启发式算法&#xff0c;称为神经种群动态优化算法Neural population dynamics optimization algorithm(NPDOA)的元启发式算法。该成果于2024年9月最新发表在中科院1区 Top SCI期刊 Knowledge-Based Systems。 原文作者将NPDOA与其他9种…

智慧体育场馆:科技引领未来运动体验

在当今数字化时代&#xff0c;​智慧体育场馆​的建设不仅提升了观众、运动员和管理者的体验质量&#xff0c;也为体育产业注入了新的活力和创新。通过整合先进科技和智能系统&#xff0c;体育场馆能够实现更高效的运营管理、提升赛事体验以及优化资源利用。以下是古河云科技构…

JavaSE - 易错题集 - 006

1. 哪个正确 A abstract类只能用来派生子类&#xff0c;不能用来创建abstract类的对象。 B final类不但可以用来派生子类&#xff0c;也可以用来创建final类的对象。 C abstract不能与final同时修饰一个类。 D abstract类定义中可以没有abstract方法。 正确答案&#xff1…

GMB外链是什么?

GMB外链其实就是百万外链&#xff0c;它是一种通过大量反向链接来提升网站页面权重的方法。如果你刚建了一个新网站&#xff0c;想在短时间内被收录并获得排名&#xff0c;GMB外链能帮你做到这点。它不像传统SEO那样需要等待好几个月的效果&#xff0c;GMB外链能在24小时内帮你…

TVS瞬态抑制二极管,单向和双向有什么区别?

1、TVS瞬态抑制二极管的分类 根据方向来分&#xff0c;有单向和双向之分&#xff1b; 根据外形来看&#xff0c;有直插和贴片之分&#xff1b; 根据工作电压来分&#xff0c;有高压和低压之分&#xff1b; 根据功率大小来分&#xff0c;有小功率和大功率之分&#xff1b; …

论文解读《NewsBench:一个评估中文新闻大型语言模型编辑能力的系统评估框架》

引言&#xff1a;感觉这篇文章&#xff0c;对 LLMs 的新闻编辑能力做了一个详细的实验和分析&#xff0c;而且还贡献了一个宝贵的中文新闻数据集&#xff0c;蛮不错的&#xff0c;后面或许可以用起来&#xff0c;就拜读了一下。 这篇博客的题目说是解读&#xff0c;其实大部分…

在Ubuntu中编译含有JSON的文件出现报错

在ubuntu中进行JSON相关学习的时候&#xff0c;我发现了一些小问题&#xff0c;决定与大家进行分享&#xff0c;减少踩坑时候出现不必要的时间耗费 截取部分含有JSON部分的代码进行展示 char *str "{ \"title\":\"JSON Example\", \"author\&…

Debian11源码安装mysql5.7

#!/bin/bash# 安装依赖 apt-get update && apt-get install -y wget make gcc g cmake bison libncurses5-dev libssl-dev libtool pkg-config> /dev/null # 安装包所在目录 packages"/usr/local/src" # 数据目录 datadir"/hskj/mysql" # pid文…

解决Docker镜像不可下载

使用国内可信的镜像中心 可信国内镜像网址&#xff1a;https://hub.atomgit.com/ 点击镜像仓库 搜索想要的镜像 按如图所示&#xff0c;即可查看对应的版本 点击复制&#xff0c;即可下载使用 缺点&#xff1a; 可用的镜像相比于docker官方量少 并且&#xff0c;获取的镜像名字…

文献速递 | E3泛素连接酶PELI2介导STING信号激活的阈值设定

自从2013年cGAS被发现&#xff0c;cGAS-STING通路在检测和应对病毒和细菌感染等外部威胁和癌症发展等内部威胁中的作用已经越来越多的被提及。cGAS-STING通路几乎无处不在&#xff0c;它可以监测细胞质中的dsDNA&#xff0c;而dsDNA是病原体感染、细胞损伤和癌症等多种威胁的危…

OM6626国产低功耗蓝牙对比NRF52832/NRF52810

OM6626 是一款超低功耗的蓝牙soc 主要特性&#xff1a; 支持BLE5.3支持SIG Mesh支持2.4G长包主频64Mhz&#xff0c;80KB RAM主要应用在esl电子价签&#xff0c;IoT模组、CGM、高报告率HID设备 PUM特点 1.71~3.6v供电电压1秒间隔广播平均电流&#xff1a;9uA&#xff1b;1秒间…

会议室占用【python实现】

题目来自此 思路见代码随想录合并区间 def main():import astmeetings ast.literal_eval(input())meetings.sort(keylambda x:x[0])result [meetings[0]]for meeting in meetings:if meeting[0] < result[-1][1]:result[-1][1] meeting[1]else:result.append(meeting)pr…

轨到轨运算放大器

轨到轨并不一定是指输出轨到轨&#xff0c;也有可能是输入轨到轨&#xff1a; 例如LM358不是轨到轨运放&#xff0c;输出信号电压是VCC - 1.5v &#xff0c; 如果采用锂电池供电&#xff0c;量取锂电池的电压&#xff0c;输出电压等于锂电池的3.7 - 1.5V&#xff0c;这样电压区…

下一代 AI 医疗:知识图谱RAG + 多智能体,听医生的话没前途,让医生听你的话才是正道!

下一代 AI 医疗&#xff1a;知识图谱RAG 多智能体&#xff0c;听医生的话没前途&#xff0c;让医生听你的话才是正道&#xff01; 医疗算法趋势现代 AI 医疗算法问题医学影像算法的局限医疗知识图谱的问题基于最本质循证医学实现人类级因果推理摆脱LLM概率性输出 嘘&#xff0…

【二叉树遍历算法应用】------补录

0.二叉树结点的链式存储结构 #include<stdio.h> #include<stdlib.h> #include<stdbool.h>typedef char TElemType;//树中元素基本类型为char类型//二叉树结点链式存储结构&#xff08;二叉链表&#xff09; typedef struct BiNode {TElemType data;//数据域…

【面试干货】软件测试面试题库

我把软件测试面试的整个题库都搬来啦&#xff0c;面试能拿下80%&#xff0c;剩下就看你满不满意公司的开价咯。以下答案都是我自己写的&#xff0c;大家根据自己的经历稍作改动&#xff0c;答案仅供参考哦&#xff01;题库持续更新&#xff0c;需要PDF版可以点击文末小卡片领取…

牛耕分解+形态学分割 全覆盖路径规划(二)Part1. 分割

书接上文&#xff1a;牛耕分解形态学分割 全覆盖路径规划&#xff08;一&#xff09; 前置文章1&#xff1a;房屋区域分割算法 Morphological Segmentation 前置文章2&#xff1a;牛耕覆盖算法 Boustrophedon Coverage Path Planning 项目地址&#xff1a;ipa320 / ipa_cove…

2.Jmeter安装配置,核心目录详情,组件和作用域

一、Jmeter安装配置以及核心目录详情 Jmeter基于java语言来开发&#xff0c;java需要jdk环境。 1.安装jdk并且配置jdk的环境变量。 2.jmeter只需要解压就可以使用了。 3.在D:\apache-jmeter-5.5\bin目录下双击jmeter.bat文件就可以启动使用了 backups&#xff1a;自动备份的目录…

开放混合 数据驱动 Cloudera的商业AI布局

8月7日在新加坡揭幕的Cloudera EVOLVE24大会&#xff0c;是全球系列活动的第一站&#xff0c;此后还将在全球多个国家陆续举行。大会从亚太地区起步&#xff0c;也彰显了Cloudera对亚太市场的重视。“亚太地区已经成为我们业务增长最快的区域。在混合云环境之下&#xff0c;越来…