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

news2025/1/10 11:31:19

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.coloradmin.cn/o/2112817.html

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

相关文章

Python Flask 实现图片上传页面

其中index.html文件&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Image and Text U…

地理信息系统设计与开发第一次作业,配置QGIS二次开发环境

我是根据这篇来配置的&#xff1a;QGIS二次开发环境配置&#xff08;VS2019QT5.12.2QGIS3.26.3&#xff09;-CSDN博客 其中&#xff0c; 我错误的理解了这里的意思&#xff0c;这些bin里面的东西和exe要在一个目录下。然后就不会有这样的问题了&#xff0c;

Swift知识点---RxSwift学习

1. 什么是RxSwift RxSwift是Swift函数响应式编程的一个开源库&#xff0c;由Github的ReactiveX组织开发、维护 RxSwift的目的是&#xff1a;让数据/事件流 和 异步任务能够更方便的序列化处理&#xff0c;能够使用Swift进行响应式编程 RxSwift本质上还是观察者模式&#xff…

栈—数据结构

一、系统栈 系统栈&#xff08;System Stack&#xff09;&#xff1a; 用途&#xff1a;系统栈通常指的是调用栈&#xff08;Call Stack&#xff09;&#xff0c;它用于存储程序执行期间的函数调用信息。每当一个函数被调用时&#xff0c;系统栈会记录这个调用的状态&#xff0…

notepad下载安装使用以及高级使用技巧

前言 Notepad是一款广受欢迎的文本编辑器&#xff0c;尤其受到开发者和编程人员的喜爱。它支持多种编程语言的语法高亮显示&#xff0c;并且提供了丰富的插件系统&#xff0c;使得功能可以轻松扩展。本文将详细介绍如何在Windows操作系统上下载、安装Notepad&#xff0c;以及基…

数据结构与算法 第11天 (查找)

一、概念 查找表 查找表是一个集合 静态查找表&#xff1a;查找完没变化 动态查找表&#xff1a;进行插入删除操作 主关键字 类似主键能唯一确定一个元素 平均查找长度ASL average search length 评价查找算法的指标 查找目的 1、查询某个“特定的”数据元素是…

Ifream实现微前端效果

记得有人曾问过我&#xff0c;老旧的项目内容很多&#xff0c;项目卡&#xff0c;想要改造成类似微前端&#xff0c;领导想要快速&#xff0c;又不想系统重构、而且是不同子系统的协同&#xff0c;要怎么做&#xff1f;对方不想做太大的改造&#xff0c;所以想用ifream的方式动…

图片隐写方法

1、常规隐写 思路&#xff1a; 1、文件头部被破坏&#xff1b;修复文件头部 2、16进制异或&#xff08;1E&#xff09; 3、宽高被修改&#xff1b;修复宽高&#xff1b;使用python脚本获取宽高或者使用tweakpng工具获取宽高 4、图片转化成base编码&#xff1b;让你还原图片 5、…

MySQL数据库的基本使用

目录 1.MySQL数据库中的用户管理与登录 1.1用户管理 root用户 其他用户 1.2MySQL数据库的登录 2.使用MySQL的前置知识 2.1SQL语言 SQL语言简介 SQL语句的分类 2.2编码集的认识 字符集 校验集 字符集和校验集的关系 如何查看和修改字符集与校验集 3.MySQL数据库的…

【Pyhton报错已解决】`AttributeError: ‘list‘ object has no attribute ‘text‘`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述&#xff1a;1.1 报错示例&#xff1a;1.2 报错分析&#xff1a;1.3 解决思路&#xff…

2024 年,数据中台引领企业走向何方?

2024 年&#xff0c;数据中台引领企业走向何方&#xff1f; 前言数据中台引领企业走向何方 前言 在当今数字化时代&#xff0c;数据已成为企业发展的核心资产。随着企业业务的不断扩展和数据量的急剧增长&#xff0c;如何有效地管理和利用数据&#xff0c;成为企业面临的重要挑…

计算机论文七种流程图画法,详细教程来袭!(导师都说我图画的标准)

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教程 或 前端全套视频…

Linux学习~树莓派gpio控制(1)

git clone git://git.drogon.net/wiringPi cd wiringPi ./build build 脚本会帮助你编译和安装 wiringPi。 方案B——直接下载 tar xfz wiringPi-xx.tar.gz cd wiringPi-xx ./build wiringPi 包括一套 gpio 命令&#xff0c;使用 gpio 命令可以控制树莓派上的各种接口&…

【物理密度计工作原理图】密度大小与密度计浸没深度关系图

密度大小与密度计浸没深度关系图 绘制图像的好处&#xff1a; 直观展示数据&#xff1a;图形可以直观地展示数据之间的关系&#xff0c;使得理解和分析数据变得更加容易。 便于比较&#xff1a;通过图形可以快速比较不同液体密度下密度计的浸没深度变化。 科学验证&#xff…

我的私人助理 | 办公小浣熊

我的私人助理 | 办公小浣熊 办公小浣熊上手实操业务场景分析一&#xff08;数据处理&#xff09;demo 本地数据库操作业务场景分析二&#xff08;数据处理&#xff09;Excel 本地文件操作业务场景分析三&#xff08;数据可视化&#xff09;业务场景分析四&#xff08;趋势判断&…

【B题第二套完整论文已出】2024数模国赛B题第二套完整论文+可运行代码参考(无偿分享)

2024数模国赛B题完整论文 摘要&#xff1a; 随着电子产品制造业的快速发展&#xff0c;质量控制与成本优化问题成为生产过程中亟待解决的核心挑战。为应对生产环节中的质量不确定性及成本控制需求&#xff0c;本文结合抽样检测理论和成本效益分析&#xff0c;通过构建数学模型…

Leetcode面试经典150题-128.最长连续序列-递归版本另解

之前写过一篇这个题的&#xff0c;但是可能代码比较复杂&#xff0c;这回来个简洁版的&#xff0c;这个是递归版本 可以看看之前的版本&#xff0c;两个版本面试用哪个都保过 解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {/**对于之前的解法&#xff0c;我…

【vulhub】thinkphp5 2-rce 5.0.23-rce 5-rce 漏洞复现

2-rec 1.启动环境 cd /.../vulhub/thinkphp/2-rce # cd进入2-rce靶场文件环境下 docker-compose up -d # docker-compose启动靶场 docker ps -a # 查看开启的靶场信息2.访问192.168.146.136&#xff1a;8080网页 3.构造payload http://192.168.146.136:80…

Openharmony 下载到rk3568实现横屏

前言&#xff1a; Openharmony 源码版本4.1 release 板子&#xff1a;rk3568 1.修改“abilities”中的“orientation”实现横竖屏 entyr->src->module.json5文件里面添加 "orientation": "landscape", 2.修改系统源码属性实现横竖屏切换 通过这…

IDEA取消自动选择光标所在行

今天出现了一个怪事&#xff1a; 当我使用IDEA编写代码的时候&#xff0c;单击下一行或者上一行的时候&#xff0c;莫名其妙它会自己选中一行&#xff0c;导致我要么是回车代码直接没了&#xff0c;要么是代码直接给我搞错位了&#xff0c;还得按ctrlz返回&#xff0c;十分的恶…