• crm笔记


    大目标:crm系统。
    --权限组件
    --stark组件
    --crm业务

    	步骤:
    	第一部分权限组件:
    		1.创建django project,luffy-permission
    		2.两个app
    			--rbac,权限组件
    			--web,销售管理系统
    		3.app: rbac
    			-将权限相关的表编写到此app的models.py中
    	4.app:web
    	 	-将销售管理系统表写到此app的models.py中
    		-销售系统的业务代码
    		
    	5.两个app的整合
    		客户管理
    			客户列表:/customer/list/
    			添加客户:/customer/add/
    			删除客户:/customer/del/(?P<cid>d+)/
    			修改客户:/customer/edit/(?P<cid>d+)/
    			批量导入:/customer/import/
    			下载模板:/customer/tpl/
    		账单管理
    			账单列表:/payment/list/
    			添加账单:/payment/add/
    			删除账单:/payment/del/(?P<pid>d+)/
    			修改账单:/payment/edit/(<?P<pid>d+/
    
    		那么接下来,我们就在权限组件中录入相关信息:
    			录入权限
    			创建用户
    			创建角色
    			用户分配角色
    			角色分配权限
    	6.权限控制设计思路--初始化
    		--减少数据库的压力,在中间件request.session中检验权限
    			1.登录页面是否有权限访问。 所有人都可访问
    			2.post请求,用户登录检验是否合法,不合法返回继续登录
    			3.登录成功后,获取当前用户的所有权限并放入session
    			4.中间件中控制:当在向服务器发起请求url时候,后端编写中间件对用户当前访问的url进行权限的判断(是否在session中)
    	7.功能完善,将权限相关的代码当如rbac组件中
    		--权限初始化代码 归类
    			1.登录代码和权限初始化拆分
    			2.settings.PERMISSION_SESSION_KEY 在设置中配置
    	总结:6,7权限的控制
    
    	8.动态菜单
    		--一级菜单 如何实现动态显示一级菜单?
    			a.变结构修改+录入菜单数据
    			b.获取菜单信息并保存到session
    			c.模板中显示信息  引入:inclusion_tag渲染模板
    
    		--二级菜单
    			a.表结构
    				fa-free-code-camp
    				fa-money
    
    				{
    					1:{
    						title:'用户信息',
    						icon:'x1',
    						chirldren:[
    							{title:'个人信息',url:'/userinfo/'},
    						]
    					},
    					2:{
    						title:'客户信息',
    						icon:'x1',
    						chirldren:[
    							{title:'客户列表',:'/userinfo/'},
    						]
    					},				
    				}
    			b.表结构:
    				class Menu(models.Model):
    				    """
    				    菜单表
    				    """
    				    title =models.CharField(verbose_name='一级菜单名称',max_length=32)
    				    icon = models.CharField(verbose_name='图标',max_length=32,blank=True,null=True)
    
    
    				class Permission(models.Model):
    				    """
    				    权限表
    				    """
    				    title = models.CharField(verbose_name='标题',max_length=32)
    				    url = models.CharField(verbose_name='含正则的url',max_length=128)
    
    				    menu= models.ForeignKey(verbose_name='所属菜单',to='Menu',on_delete=models.CASCADE,blank=True,null=True,help_text='null表示不是菜单,非null表示二级菜单')
    				    def __str__(self):
            				return self.title				
            	c.页面显示二级菜单  默认设置一级菜单隐藏 class = hide,并才css中设置具体的样式
    
          9.点击非菜单的权限时,默认选中或默认展开
    	      	当点击某个不能成为菜单的权限时,指定一个可以成为菜单的权限,也让其默认选中以及展开
    	      	在Permission表中加自关联pid,要加一个related_name='parents'
          	a.数据库涉及
          	b.思路
          		-登录,做权限和菜单的初始化
          			--获取菜单信息
    	      			{
    						1:{
    							title:'用户信息',
    							icon:'x1',
    							chirldren:[
    								{id:1,title:'个人信息',url:'/userinfo/'},
    							]
    						},
    						2:{
    							title:'客户信息',
    							icon:'x1',
    							chirldren:[
    								{id:7,title:'客户列表',:'/userinfo/'},
    							]
    						},				
    					}
          			--获取权限信息
          					{
          						{id:1,url:'/customer/list',pid=null}, 客户列表,可做菜单
          						{id:2,url:'/customer/add',pid=1}, #添加菜单不可做菜单,默认选pid=1的客户列表做菜单
          						{id:3,url:'/customer/del/(?P<cid>d+)',pid=7},
          					}
          		-再次登录时,到中间件中做校验(根据权限信息)
    	      		-从request.session中获取权限信息,id或pid 
    	      		-在通过request,将pid或者id传到inclusion_tag
    	      			(request.current_selected_url=item['pid'] or item['id'])
    
          		-模板中使用动态菜单--inclusion_tag动态生成菜单(根据菜单信息)
          			从request.session中获取菜单信息
          10.路径导航  
          			breadcrumb
          			--首页/账单列表/添加账单
          11.权限的粒度控制到按钮级别:
    	      	--修改数据库--加url别名name(customer_list)--->>permission_dict 以URL别名做key值
    	      	--过滤器filter可以在if后面当条件,而tag和inclusion_tag不能(自己定义一个过滤器,最多2个参数)
    	      		 {% if request|has_permission:"customer_add"%}
    	                <a class="btn btn-default" href="/customer/add/">
    	                    <i class="fa fa-plus-square" aria-hidden="true"></i> 添加客户
    	                </a>
    	            {% endif %}
    
    	  总结:
    	  	- 权限控制
    	  	- 动态菜单
    	  	- 权限的分配
    	  	问题:以前你是如何进行权限分配的?给某个用户分配一个角色?某个人分配权限
    	  	答案:django admin进行录入
    
    	  12.权限分配  先把权限校验的中间件去掉了,左边栏和导航栏也去掉了
    		  	a.角色管理 Role
    		  	--forms.ModelForm和forms.Form 
    		  		from django import forms
    	  		class RoleModelForm(forms.ModelForm):
    			    """
    			    角色组件
    			    """
    			    class Meta:
    			        model=models.Role
    			        fields=['title',]
    
    			        widgets={
    			            'title':widgets.TextInput(attrs={'class':'form-control'})
    			        }
    			        labels = {
    			            "title": "角色名称"
    			        }
    			        error_messages = {
    			            'title':{'required':"角色名不能为空",},
    			        }
    
    	  		(RoleModelForm(instance=obj,data=request.POST),编辑的需要把编辑的obj传入组件)
    
    	  	--include路由分发时的名称空间,和rbac.urls里的name
    	  	--django模板的查找顺序,以及add/edit模板复用,del模板复用
    
    	  b.用户管理 UserInfo
    	  	--知识点:
    	  		1.forms.ModelForm 
    		  		字段的新增,
    		  		钩子方法,
    		  		super,重写init方法,统一给所有字段添加属性
    		  		中文显示错误信息:配置中LANGUAGE_CODE = 'zh-hans'
    	  		2.根绝namespace和name反向生成url,在模板中和py文件中2中方式
    	  		3.模板的查找顺序
    	  c.菜单和权限管理 Menu/Permission
    	  		---ModelForm 操作一张表
    	  		1.panel 公告框
    	  		2.保留原有搜索条件 自定义simple_tag:memory_url (类似原生url)
    	  		3.模板中整型转成字符串|safe
    	  		4.ModelForm中 forms.RadioSelect 选择框
    				from django.utils.safestring import mark_safe
    				class MenuModelForm(forms.ModelForm):
    				    class Meta:
    				        model = models.Menu
    				        fields=['title','icon']
    				        widgets = {
    				            'title':forms.TextInput(attrs={'class':'form-control'}),
    				            'icon':forms.RadioSelect(
    				                choices=[
    				                    ['fa-address-book-o',mark_safe('<i class="fa fa-address-book-o" aria-hidden="true"></i>')],
    				                    ['fa-envelope-open',mark_safe('<i class="fa fa-envelope-open" aria-hidden="true"></i>')],
    				                    ['fa-envelope-open-o',mark_safe('<i class="fa fa-envelope-open-o" aria-hidden="true"></i>')],
    				                ],
    				                attrs={'class':'clearfix'}
    
    				            )
    				        }
    			5.ModelForm中 下拉框设置默认值
    				menu_object = models.Menu.objects.filter(pk=menu_id).first() #为了能设置默认值。需要一级菜单的id
    				form = SecondMenuModelForm(initial={'menu':menu_object})
    			6.ModelForm中 save之前 在数据库中设置二级菜单 form.instance.pid = seconde_menu_obj  #在数据库里默认添加二级菜单
    			7.BootstropModelForm 自定义样式定制
    
    
    	  d.权限的批量操作
    	  		--formset
    	  			什么是formset?
    	  				答:Form组件或ModelForm用于做一个表单验证(数据库的一张表里对应的一条数据)
    	  				formset:指的是可以用与多个表单的验证组件
    	  				应用场景?
    	  					--批量操作
    
    	  		--自动发现所有URL	  (from django.urls import URLResolver,URLPattern)
    	  			--问题:找到项目中的所有url
    	  				{
    	  				'rbac:menu_list:{name:'rbac:menu_list',url:'rbac/menu/list'}
    	  				}
    					    
    			--批量的权限操作
    				思路:
    				1.获取项目中所有的权限 set1
    				2.去数据库中获取已经录入的所有权限 set2
    
    				情况1::自动发现的 >数据库中的 -->实现批量添加 ps:通过name进行比对(model中设置唯一)
    				set1 - set2 ==>添加  formset 
    				情况2:数据中的 > 自动发现 -->实现批量删除
    				set2 - set1 ==>删除
    				情况3: 自动发现的 > 数据库有的 --实现批量更新
    				set3 = set1 & set2 ==>更新 formset
    
    	  e.权限分配	  
    	  	--展示用户/角色/权限信息
    	  		
    	  	--选择用户/角色时,页面上的默认选项
    
    	  	--角色和权限分配【保存】	
    	  		列表==>赋值给字典--引用同一块内存地址	
    
     rbac使用文档README
    
    第二部分stark组件:
    	介绍:stark组件,是一个帮助开发者快速实现数据库表的增删改查
    	目标:10s 完成一张表的增删改查
    
    	前戏:
    		1.django项目启动时,自定义执行某个文件
    			在django项目启动前,且在读取路由加载前,执行某个py文件
    			在 任意的 app的apps.py中的Config类,定义ready方法,调用autodiscover_modules
    			from django.apps import AppConfig
    			from django.utils.module_loading import autodiscover_modules
    
    			class App01Config(AppConfig):
    			    name = 'app01'
    
    			    def ready(self):
    			        autodiscover_modules('xxx')
    			django在启动前,就会去已经注册的app的目录下找xxx.py并自动执行
    
    			如果执行两次,是因为django内部自动重启导致,2个线程,一个时启动项目,另一个看代码更新状态
    				python manage.py runserver 127.0.0.1:8001 --noreload #只执行一次
    			提示:
    				如果xxx.py执行的代码,向其他地方放入了一些值,之后的路由加载时,可以去那里读取
    
    		2.单例模式
    			单:一个
    			例:实例,对象
    			通过利用python模块导入的特性,如果已经导入的模块在被重新导入时,python不会在重新解释一遍,而是选择从内存中读取原来导入的值
    			提示:
    				如果以后存在一个单例模式的对象,可以先在此对象中放入一个值,
    				然后在其他的文件中导入该对象,通过对象再次,将值获取到
    
    		3.django路由分发的本质include
    		    re_path(r'^rbac/', include(([
    		    			    re_path(r'^role/list/$', role.role_list,name='role_list'), # rbac:role_list
    							re_path(r'^role/add/$', role.role_add,name='role_add'),
    		    ], 'rbac'),namespace='rbac')),
    
    			--- urlconf_module, app_name, namespace
    

    	开始!
    	1.创建一个project
    	2.创建基础业务表
    	app01/models.py
    		用户表
    		部门表
    	app02/models.py
    		主机表
    	3.对 以上三张表做增删改查
    		a.为每张表创建4个url 
    		b.为每张表创建4个视图函数
    		app01/models.py
                Depart
                    /app01/depart/list/
                    /app01/depart/add/
                    /app01/depart/edit/(d+)/
                    /app01/depart/del/(d+)/				
    
    			UserInfo
                    /app01/userinfo/list/
                    /app01/userinfo/add/
                    /app01/userinfo/edit/(d+)/
                    /app01/userinfo/del/(d+)/		
    		app02/models.py
                Host
                    /app02/host/list/
                    /app02/host/add/
                    /app02/host/edit/(d+)/
                    /app02/host/del/(d+)/
    
            为app中的每个model类 自动创建url以及视图函数
    
             - 动态生成url
             - 视图提取到基类
             - URL&分发扩展 &后缀
             - URL设置别名name
             - URL的别名进行重新的生成 优化
    
             c.定制html页面显示的列
             	- 基本完成列表页面的定制
             	- 未定义list_display字段的页面,默认显示对象
             	- 为页面显示的列预留一个钩子函数 扩展
             	- 页面自定义显示的列的函数
             d.应用模板样式(layout.html/bootstarp)
    
    
             e.分页功能
             f.添加按钮
             	- 如何显示添加按钮
             	- 添加按钮的url
             	- 添加界面进行添加数据(保留原搜索条件)
    
             g.编辑
             	- 编辑按钮
             	- 页面操作
             h.删除
    
    
        4.其他功能
        	- 排序
        	- 模糊搜索
        		- 实现思路:
        			在页面上设置form表单,已get形式提交搜索条件到后台,后台获取数据,
        			进行数据筛选,根据自定义的列表search_list进行查找(多列可以按照或进行查询(crm中Q语法))
    
        	- 动态搜索
        	- 批量操作
        		- 添加checkbox列
        		- 生成批量操作的按钮
        	- 组合搜索
        		- 什么是组合搜索?
        		- 如何实现?
        			- 实现思路:根据字段找到与其关联的数据:choice、foreginkey、manytomany
        			  - 1.配置 search_group = ['gender','depart'] #想要分2组
        			  - 2.根据配置获取到数据
        			  - 3.跟据配置获取到数据(含条件)
        			  - 4.在页面上显示组合搜索的按钮(在后台生成html代码)
        			  		将queryset_or_tuple进行封装
        			  -5.为组合搜索按钮生成URL
        			  -6.多选搜索
    
       	总结: - 页面:了,列表、添加、编辑、删除
       		  -  模糊搜索、批量操作、组合搜索
    
    
    第三部分:crm业务开发
    	1.项目背景介绍:
    		以教育机构为背景的crm项目,系统主要为销售部、运营部、教质部、提供平台,对他们的工作进行量化
    		销售部:
    			- 公户,公共用户
    			- 私户,我的用户。 <=150人 +跟进记录+入班申请(财务审核)
    		运营部:
    			- 录入客户信息(公户)
    		教质部:
    			- 考勤
    			- 学院访谈
    			- 积分管理
    			- 转班申请
    	2.项目开发
    		2.1 概况
    			- 基础业务处理
    				- 校区管理
    				- 部门管理
    				- 用户管理
    				- 课程管理
    				- 开班管理
    			- 客户管理
    				- 公户
    				- 私户
    			- 学员管理
    				- 考勤
    				- 谈话记录
    				- 积分
    			- rbac组件
    		2.2
    			- 2.2.1 创建项目
    			- 2.2.2 校区管理
    			- 2.2.3 部门管理
    			- 2.2.4 用户管理
    				- 页面基本操作 添加 编辑 删除
    				- 添加页面需要新增一个确认字段 $编辑页面删除密码字段
    		 	    - 重置密码	
    		 		- 新加一条路由 (用预留的钩子extra_url)
    		 		- 加视图、前端界面、保留原搜索条件(反向生成url)
    		 		- 页面功能的增加(模糊搜索、组合搜索)
    
    		 	- 2.2.5 客户管理+代码的拆分到views中 
    		 	- 2.2.6 班级管理
    		 			- 班级管理基本操作(定制display_course显示列)
    		 			- 基于limit_choice_to 对于关联的Fk,M2M进行筛选
    		 			limit_choices_to={'depart__title__in':['Linux教学部','Python教学部']}
    		 			- 班级管理时间插件的应用(stark组件新增DateTimePickerInput插件、
    		 			【from stark.forms.DateTimePickerInput import DateTimePickerInput】)
    		 	- 2.2.7 客户管理
    		 		- 公户
    		 			- 公户基本管理:公户列表、录入客户
    		 			- 查看跟进记录
    		 			- 批量申请到私户:个数限制、数据库中事务加锁、添加当前登录人(即为我的私户)
    		 			- 用户登录 后将user_id存到session中,后续取的时候从session中获取
    		 		- 私户
    		 		    - 私户基本管理 添加时客户顾问默认是登录人自己,在数据库中添加(预留的钩子save)
    		 		    - 私户剔到公户
    		 		    - 跟进记录管理 -- 根据strark组件生成url
    		 		    	- 查看 
    		 		    	- 添加 
    		 		    	- 编辑 
    		 		    	- 删除 
    		 		- 缴费&报名
    		 			- 业务分析
    			 			- 学员缴费
    			 			- 课程顾问:提交缴费申请
    			 			- 财务:审核(状态更新、入班学习)
    			 		- 代码实现
    			 			- 表结构设计 
    			 			- 查看缴费列表
    			 			- 添加缴费记录
    			 			- 缴费审批
    
    			- 2.2.8 学员管理
    					- 学生管理
    					- 积分管理
    					- 考勤管理
    						- 上课记录
    						- 考勤记录
    			- 2.2.9 权限应用
    					- 基本权限校验
    					- 粒度控制到按钮
  • 相关阅读:
    jdk源码阅读笔记之java集合框架(四)(LinkedList)
    jdk源码阅读笔记之java集合框架(二)(ArrayList)
    jdk源码阅读笔记之java集合框架(三)(modCount)
    java文件拷贝的一点思考
    mac(10.11.5 )安装pt-query-digest所遇问题总结
    关于springboot启动所需所有jar包详解
    volatile的一点理解
    java 虚拟机自动内存管理
    虚拟机运行时数据区划分
    笔记本连上wifi(WiFi完全没问题)却无法上网
  • 原文地址:https://www.cnblogs.com/hanfe1/p/12517575.html
Copyright © 2020-2023  润新知