828华为云征文|华为云服务器Flexus X搭建悟空crm管理系统——助力企业云上管理(解决APP Referer校验失败问题)

1、为什么我们企业会选择Flexus云服务器X实例来部署自己的CRM管理系统?

在这里插入图片描述

在这里插入图片描述在这里插入图片描述因为基于华为云Flexus X实例搭建CRM管理平台,可以从容面对企业内部瞬息万变的业务压力变化

2、华为云服务器Flexus X方案及优势:

灵活伸缩
搭配弹性伸缩服务AS及负载均衡服务ELB,可以实现基于业务负载的快速弹缩,从容应对多变的市场业务压力

数据可靠
搭配华为云数据库服务,存储电商持久化数据,使用方便,可靠性高

安全可靠
搭配WAF、DDoS等网络安全服务,实现对电商业务全方位安全防护,降低黑客入侵风险

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

3、在宝塔里面安装必要的环境PHP7.3、Mysql5.6+、NGINX

在这里插入图片描述

在这里插入图片描述

4、安装搭建好,进入CRM管理界面:

在这里插入图片描述

点击添加客户信息的时候就会发现,提示:

APP Referer校验失败。请检查该ak设置的白名单与访问所有的域名是否一致。详情查看:http://lbsyun.baidu.com/apiconsole/key#

这是由于百度地图api接口没有配置好导致的问题出现

在这里插入图片描述当配置好地图参数之后,就可以进行地区定位和使用附件客户等功能了
在这里插入图片描述在这里插入图片描述在这里插入图片描述

5、客户详情功能模块代码

public function read()
    {
        $customerModel = model('Customer');
        $cutomerLogic = new CustomerLogic();
        $param = $this->param;
        $userInfo = $this->userInfo;
        $data = $customerModel->getDataById($param['id'], $userInfo['id']);
        if (!$data) {
            return resultArray(['error' => $customerModel->getError()]);
        }
        //数据权限判断
        $userModel = new \app\admin\model\User();
        $auth_user_ids = $userModel->getUserByPer('crm', 'customer', 'read');
        //读权限
        $roPre = $userModel->rwPre($userInfo['id'], $data['ro_user_id'], $data['rw_user_id'], 'read');
        $rwPre = $userModel->rwPre($userInfo['id'], $data['ro_user_id'], $data['rw_user_id'], 'update');
        //判断是否客户池数据
        $wherePool = $customerModel->getWhereByPool();
        $resPool = db('crm_customer')->alias('customer')->where(['customer_id' => $param['id']])->where($wherePool)->find();
      if (!$resPool && !in_array($data['owner_user_id'], $auth_user_ids) && !$roPre && !$rwPre) {
            $authData['dataAuth'] = (int)0;
            return resultArray(['data' => $authData]);
        }
        return resultArray(['data' => $data]);
    }

6、编辑客户功能模块代码

public function update()
    {
        $customerModel = model('Customer');
        $param = $this->param;
        $userInfo = $this->userInfo;
        //数据详情
        $data = $customerModel->getDataById($param['id']);
        if (!$data) {
            return resultArray(['error' => $customerModel->getError()]);
        }

        $param['user_id'] = $userInfo['id'];
        if ($customerModel->updateDataById($param, $param['id'])) {
            return resultArray(['data' => '编辑成功']);
        } else {
            return resultArray(['error' => $customerModel->getError()]);
        }
    }

7、删除客户功能模块代码

 public function delete()
    {
        $param = $this->param;
        $user = new ApiCommon();
        $userInfo = $user->userInfo;
        // 是否客户池
        if ($param['isSeas'] == 1) {
            $permission = checkPerByAction('crm', 'customer', 'poolDelete');
        } else {
            $permission = checkPerByAction('crm', 'customer', 'delete');
        }
        if ($permission == false) {
            return resultArray(['error' => '无权操作']);
        }
        $customerModel = model('Customer');
        $userModel = new \app\admin\model\User();
        $recordModel = new \app\admin\model\Record();
        $fileModel = new \app\admin\model\File();
        $actionRecordModel = new \app\admin\model\ActionRecord();
        if (!is_array($param['id'])) {
            $customer_id[] = $param['id'];
        } else {
            $customer_id = $param['id'];
        }
        $delIds = [];
        $errorMessage = [];

        //数据权限判断
        $auth_user_ids = $userModel->getUserByPer('crm', 'customer', 'delete');
        //判断是否客户池数据(客户池数据只有管理员可以删)
        $adminId = $userModel->getAdminId();
        $wherePool = $customerModel->getWhereByPool();
        foreach ($customer_id as $k => $v) {
            $isDel = true;
            //数据详情
            $data = db('crm_customer')->where(['customer_id' => $v])->find();
            if (!$data) {
                $isDel = false;
                $errorMessage[] = 'id为' . $v . '的客户删除失败,错误原因:' . $customerModel->getError();
            }
            $resPool = db('crm_customer')->alias('customer')->where(['customer_id' => $v])->where($wherePool)->find();
            if (!$resPool && !in_array($data['owner_user_id'], $auth_user_ids) && $isDel) {
                $isDel = false;
                $errorMessage[] = '无权操作';
            }
            // 公海 (原逻辑,公海仅允许管理员删除,修改为授权,不再限制)
            // if ($resPool && !in_array($data['owner_user_id'],$adminId)) {
            //     $isDel = false;
            //     $errorMessage[] = '名称为'.$data['name'].'的客户删除失败,错误原因:无权操作';
            // }
            //有商机、合同、联系人则不能删除
            if ($isDel) {
                $resBusiness = db('crm_business')->where(['customer_id' => $v])->find();
                if ($resBusiness) {
                    $isDel = false;
                    $errorMessage[] = '客户下存在商机,不能删除';
                }
            }
            if ($isDel) {
                $resContacts = db('crm_contacts')->where(['customer_id' => $v])->find();
                if ($resContacts) {
                    $isDel = false;
                    // $errorMessage[] = '名称为' . $data['name'] . '的客户删除失败,错误原因:客户下存在联系人,不能删除';
                    $errorMessage[] = '客户下存在联系人,不能删除';
                }
            }
            if ($isDel) {
                $resContract = db('crm_contract')->where(['customer_id' => $v])->find();
                if ($resContract) {
                    $isDel = false;
                    $errorMessage[] = '客户下存在合同,不能删除';
                }
            }
            if ($isDel) {
                $delIds[] = $v;
            }
        }
        $dataInfo = $customerModel->where('customer_id', ['in', $delIds])->select();
        if ($delIds) {
            $delRes = $customerModel->delDatas($delIds);
            if (!$delRes) {
                return resultArray(['error' => $customerModel->getError()]);
            }
            // 删除客户扩展数据
            db('crm_customer_data')->whereIn('customer_id', $delIds)->delete();
            // 删除跟进记录
            $recordModel->delDataByTypes(2, $delIds);
            // 删除关联附件
            $fileModel->delRFileByModule('crm_customer', $delIds);
            // 删除关联操作记录
            $actionRecordModel->delDataById(['types' => 'crm_customer', 'action_id' => $delIds]);
            foreach ($dataInfo as $k => $v) {
                RecordActionLog($userInfo['id'], 'crm_customer', 'delete', $v['name'], '', '', '删除了客户:' . $v['name']);
            }
        }
        if ($errorMessage) {
            return resultArray(['error' => $errorMessage]);
        } else {
            return resultArray(['data' => '删除成功']);
        }
    }

8、客户信息详情界面

在这里插入图片描述

9、客户转移功能

public function transfer()
    {
        $param = $this->param;
        $userInfo = $this->userInfo;
        $customerModel = model('Customer');
        $businessModel = model('Business');
        $contractModel = model('Contract');
        $contactsModel = model('Contacts');
        $settingModel = model('Setting');
        $customerConfigModel = model('CustomerConfig');
        $userModel = new \app\admin\model\User();

        if (!$param['owner_user_id']) {
            return resultArray(['error' => '变更负责人不能为空']);
        }
        if (!$param['customer_id'] || !is_array($param['customer_id'])) {
            return resultArray(['error' => '请选择需要转移的客户']);
        }
        $is_remove = ($param['is_remove'] == 2) ? 2 : 1;
        $type = $param['type'] == 2 ?: 1;
        $types = $param['types'] ?: [];

        $data = [];
        $data['owner_user_id'] = $param['owner_user_id'];
        $data['update_time'] = time();
        $data['follow'] = '待跟进';
        # 获取客户的时间
        $data['obtain_time'] = time();

        $ownerUserName = $userModel->getUserNameById($param['owner_user_id']);
        $errorMessage = [];
        foreach ($param['customer_id'] as $customer_id) {
            $customerInfo = db('crm_customer')->where(['customer_id' => $customer_id])->find();
            if (!$customerInfo) {
                $errorMessage[] = '名称:为《' . $customerInfo['name'] . '》的客户转移失败,错误原因:数据不存在;';
                continue;
            }
            $resCustomer = true;
            //权限判断
            if (!$customerModel->checkData($customer_id)) {
                $errorMessage[] = $customerInfo['name'] . '转移失败,错误原因:无权限;';
                continue;
            }
            //拥有客户数上限检测
            if (!$customerConfigModel->checkData($param['owner_user_id'], 1)) {
                $errorMessage[] = $customerInfo['name'] . '转移失败,错误原因:' . $customerConfigModel->getError();
                continue;
            }

            //团队成员
            $teamData = [];
            $teamData['type'] = $type; //权限 1只读2读写
            $teamData['user_id'] = [$customerInfo['owner_user_id']]; //协作人
            $teamData['types'] = 'crm_customer'; //类型
            $teamData['types_id'] = $customer_id; //类型ID
            $teamData['is_del'] = ($is_remove == 1) ? 1 : '';
            $res = $settingModel->createTeamData($teamData);

            # 处理分配标识,待办事项专用
            $data['is_allocation'] = 1;

            $resCustomer = db('crm_customer')->where(['customer_id' => $customer_id])->update($data);
            if (!$resCustomer) {
                $errorMessage[] = $customerInfo['name'] . '转移失败,错误原因:数据出错;';
                continue;
            } else {
                # 处理转移时,负责人出现在只读和读写成员列表中
                $customerArray = [];
                $teamCustomer = db('crm_customer')->field(['owner_user_id', 'ro_user_id', 'rw_user_id'])->where('customer_id', $customer_id)->find();
                if (!empty($teamCustomer['ro_user_id'])) {
                    $customerRo = arrayToString(array_diff(stringToArray($teamCustomer['ro_user_id']), [$teamCustomer['owner_user_id']]));
                    $customerArray['ro_user_id'] = $customerRo;
                }
                if (!empty($teamCustomer['rw_user_id'])) {
                    $customerRo = arrayToString(array_diff(stringToArray($teamCustomer['rw_user_id']), [$teamCustomer['owner_user_id']]));
                    $customerArray['rw_user_id'] = $customerRo;
                }
                db('crm_customer')->where('customer_id', $customer_id)->update($customerArray);
            }

            if (in_array('crm_contacts', $types)) {
                $contactsIds = [];
                $contactsIds = db('crm_contacts')->where(['customer_id' => $customer_id])->column('contacts_id');
                if ($contactsIds) {
                    $resContacts = $contactsModel->transferDataById($contactsIds, $param['owner_user_id'], $type, $is_remove);
                    if ($resContacts !== true) {
                        $errorMessage[] = $resContacts;
                        continue;
                    }
                }
            }

            //商机、合同转移
            if (in_array('crm_business', $types)) {
                $businessIds = [];
                $businessIds = db('crm_business')->where(['customer_id' => $customer_id])->column('business_id');
                if ($businessIds) {
                    $resBusiness = $businessModel->transferDataById($businessIds, $param['owner_user_id'], $type, $is_remove);
                    if ($resBusiness !== true) {
                        $errorMessage = $errorMessage ? array_merge($errorMessage, $resBusiness) : $resBusiness;
                        continue;
                    }
                }
            }

            if (in_array('crm_contract', $types)) {
                $contractIds = [];
                $contractIds = db('crm_contract')->where(['customer_id' => $customer_id])->column('contract_id');
                if ($contractIds) {
                    $resContract = $contractModel->transferDataById($contractIds, $param['owner_user_id'], $type, $is_remove);
                    if ($resContract !== true) {
                        $errorMessage = $errorMessage ? array_merge($errorMessage, $resContract) : $resContract;
                        continue;
                    }
                }
            }
            //修改记录
            updateActionLog($userInfo['id'], 'crm_customer', $customer_id, '', '', '将客户转移给:' . $ownerUserName);
            RecordActionLog($userInfo['id'], 'crm_customer', 'transfer', $customerInfo['name'], '', '', '将客户:' . $customerInfo['name'] . '转移给:' . $ownerUserName);
        }
        if (!$errorMessage) {
            return resultArray(['data' => '转移成功']);
        } else {
            return resultArray(['error' => $errorMessage]);
        }
    }

企业CRM管理系统部署上线之后,我们可以在华为云的控制台可以观察监控着CPU使用情况、内存、磁盘等等一切运作情况。华为云真的是性能强大、安全、稳定的云产品!!!
在这里插入图片描述

华为云828 为企业提供多行业场景解决方案及企业专属优惠,助力企业实现数字化转型升级,大家赶紧去选购吧!!

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Selenium 实现图片验证码识别

前言 在测试过程中,有的时候登录需要输入图片验证码。这时候使用Selenium进行自动化测试,怎么做图片验证码识别?本篇内容主要介绍使用Selenium、BufferedImage、Tesseract进行图片 验证码识别。 环境准备 jdk:1.8 tessdata&…

2024国赛数学建模B题完整分析参考论文38页(含模型和可运行代码)

2024 高教社杯全国大学生数学建模完整分析参考论文 B 题 生产过程中的决策问题 目录 摘要 一、问题重述 二、问题分析 三、 模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1样例代码(仅供参考) 4.…

复数随机变量(信号)的方差和协方差矩阵的计算

怎么计算复数随机变量的方差和协方差矩阵? 使得其与MATLAB中var函数和cov函数的结果一致。 前言 复信号在信号处理中随处可见,关于复信号(复随机变量)的方差和协方差矩阵该如何计算呢?本文给出了复信号的方差和协方差矩…

MarkdownEditor 配置以及使用

MarkdownEditor 配置以及使用 MarkdownEditor是一款基于浏览器的 Markdown 编辑器,虽然他是独立软件,但该软件内嵌一个浏览器。功能非常简单实用、反应速度很快,号称是Markdown领域的NotePad(记事本)。 MarkdownEdit…

自动驾驶---Motion Planning之轨迹拼接

1 背景 笔者在之前的专栏中已经详细讲解了自动驾驶Planning模块的内容:包括行车的Behavior Planning和Motion Planning,以及低速记忆泊车的Planning。 本篇博客主要聊一聊Motion Planning中轨迹拼接的相关内容。从网络上各大品牌的车主拍摄的智驾视频来看…

B端产品经理的流程设计思维

回首入行产品经理也已多年,做的项目也由C到B,由前到后都已涉及,辗转跨行仍觉互联网学海无涯,还是需要保持输出。思前想后还是决定聊一聊在过往服务多家大型集团的工作经历中十分重要,但却普遍不被视为产品经理必备能力…

Rhinoceros 8 for Mac/Win:重塑三维建模边界的革新之作

Rhinoceros 8(简称Rhino 8),作为一款由Robert McNeel & Assoc公司开发的顶尖三维建模软件,无论是对于Mac还是Windows用户而言,都是一款不可多得的高效工具。Rhino 8以其强大的功能、广泛的应用领域以及卓越的性能&…

linux dlopen手册翻译

名称 dlclose, dlopen, dlmopen 打开和关闭一个共享对象 简介 #include <dlfcn.h> void *dlopen(const char*filename, int flags); int dlclose(void *handle);#define _GNU_SOURCE #include <dlfcn.h> void *dlmoopen(Lmid_t lmid, const char *filename, int…

归并排序/计数排序

1&#xff1a;归并排序 1.1&#xff1a;代码 void _MergeSort(int* arr, int left, int right, int* tmp) {if (left > right){return;}int mid (left right) / 2; _MergeSort(arr, left, mid, tmp); _MergeSort(arr, mid1, right, tmp); int begin1 left…

空气能热泵热水器

空气能热泵热水器压缩机把低温低压气态冷媒转换成高压高温气态&#xff0c;压缩机压缩功能转化的热量为q1&#xff0c;高温高压的气态冷媒与水进行热交换&#xff0c;高压的冷媒在常温下被冷却、冷凝为液态。这过程中&#xff0c;冷媒放出热量用来加热水&#xff0c;使水升温变…

【Python知识宝库】文件操作:读写文件的最佳实践

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言一、文件读取1. 使用open函数2. 逐行读取3. 使用readlines和readline 二、文件写入1. 写入文本2. 追加内容3. 写入…

Node.js学习记录(一)

目录 一、文件读取 readFile 二、写入文件 writeFile 三、动态路径 __dirname:表示当前文件所处的目录、path.join 四、获取路径文件名 path.basename 五、提取某文件中的css、JS、html 六、http 七、启动创建web服务器 服务器响应 八、将资源请求的 url 地址映射为文…

ARM基础知识---CPU---处理器

目录 一、ARM架构 1.1.RAM---随机存储器 1.2.ROM---只读存储器 1.3.flash---闪存存储器 1.4.时钟&#xff08;振晶&#xff09; 1.5.复位 二、CPU---ARM920T 2.1.R0~R12---通用寄存器 2.2.PC程序计数器 2.3.LR连接寄存器 2.4.SP栈指针寄存器 2.5.CPSR当前程序状态寄存…

【CSS in Depth 2 精译_024】4.2 弹性子元素的大小

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

文本分类场景下微调BERT

How to Fine-Tune BERT for Text Classification 论文《How to Fine-Tune BERT for Text Classification?》是2019年发表的一篇论文。这篇文章做了一些实验来分析了如何在文本分类场景下微调BERT&#xff0c;是后面网上讨论如何微调BERT时经常提到的论文。 结论与思路 先来看…

海外云手机是否适合运营TikTok?

随着科技的迅猛发展&#xff0c;海外云手机逐渐成为改变工作模式的重要工具。这种基于云端技术的虚拟手机&#xff0c;不仅提供了更加便捷、安全的使用体验&#xff0c;还在电商引流和海外社媒管理等领域展示了其巨大潜力。那么&#xff0c;海外云手机究竟能否有效用于运营TikT…

MDC实现日志链路追踪

MDC是基于Slf4j的 MDC是什么:&#xff08;简单理解&#xff09;线程上下文 日志链路追踪解决了什么&#xff1a;1:增强了代码的调试机制2&#xff1a;重点&#xff1a;实现了 多线程环境下 代码链路追踪 基础版本&#xff08;不涉及异步&#xff09; 1&#xff1a;引入日志依赖…

计算机网络 第2章 物理层

文章目录 通信基础基本概念信道的极限容量编码与调制常用的编码方法常用的调制方法 传输介质双绞线同轴电缆光纤以太网对有限传输介质的命名规则无线传输介质物理层接口的特性 物理层设备中继器集线器一些特性 物理层任务&#xff1a;实现相邻节点之间比特&#xff08;0或1&…

鸿蒙开发5.0【Picker的受限权限适配方案】

Picker由系统独立进程实现&#xff0c;应用可以通过拉起Picker组件&#xff0c;用户在Picker上选择对应的资源&#xff08;如图片、文档等&#xff09;&#xff0c;应用可以获取Picker返回的结果。 类型受限权限使用的picker音频ohos.permission.READ_AUDIO&#xff0c;ohos.p…

Java JVM 垃圾回收算法详解

Java 虚拟机&#xff08;JVM&#xff09;是运行 Java 应用程序的核心&#xff0c;它的垃圾回收&#xff08;Garbage Collection, GC&#xff09;机制是 JVM 中非常重要的一个部分。垃圾回收的主要任务是自动管理内存&#xff0c;回收那些不再被使用的对象&#xff0c;从而释放内…