CRM项目: 编程思想和编程习惯
web项目的开发:如何分析、设计、编码、测试
技术架构
- 视图层(View)
展示数据,跟用户交互
html,css,js,jquery,bootstrap(ext|easyUI),jsp
- 控制层(Controller)
控制业务处理流程(接受请求、接收参数、封装参数;根据不同的请求调用业务层处理业务;根据处理结果,返回相应信息)
servlet,springMVC(webwork,struts1,struts2)
- 业务层(Service)
处理业务逻辑(处理业务的步骤以及操作的原子性)
JavaSE(工作流:activity|JBPM)
1. 添加学生
2. 记录操作日志
- 持久层(Dao/Mapper)
访问数据库
(jdbc),MyBatis,Hibernate,MyBatis-plus
- 整合层
处理类资源,处理类与类的关系,维护数据库资源
spring(IoC,AOP),(ejb,corba)
软件公司的组织结构
研发部(程序员、美工、DBA)、测试部、产品部、实施部、运维部、市场部
软件开发的生命周期
- 招标
投标: ----> 标书
甲方:
乙方:
- 可行性分析 -----> 可行性分析报告
技术方面能不能做这个项目? 经济 + 技术
- 需求分析 --------> 需求文档
产品经理,需求调研
项目原型: 容易确定需求,开发项目作为jsp网页
- 分析与设计
架构设计 --------> 架构文档
物理架构设计:
应用服务器:
tomcat (apache), weblogic(bea-->oracle), websphere (ibm), jboss(redhat), resin(MS).
web javaee: 13种协议 (servlet,jsp,xml,jdbc),mq + 标准
数据库服务器: mysql,oracle,DB2,sqlserver,达梦
逻辑架构设计: 代码分层
视图层-->控制层-->业务层-->持久层-->数据库
技术选型: java, .net
项目设计 ----------> 项目设计文档
物理模型设计: 表、字段、字段的类型和长度、以及表和表之间的关系
powerdesigner ----> xxxx.dpm
逻辑模型设计: 类、属性、方法、方法的参数和返回值,以及类与类之间的关系
relational rose -----> xxx.pdl
界面设计: 企业级应用 朴素. ---------> 项目原理
互联网应用 炫酷
算法设计: ----> 算法设计文档
- 搭建开发环境 ------> 技术架构文档
创建项目,添加jar包,添加配置文件,添加静态页面,添加公共类以及其它资源;
能够正常启动正常运行
- 编码实现 ---------> 注释
- 测试 ---------------> 测试用例
- 试运行 1-2周 ----> 使用手册
- 上线 ---------------> 实施手册
- 运维 ---------------> 运维手册
- 文档编纂
CRM 项目的核心业务
- CRM项目的简介 (Customer Relationship Management 客户关系管理系统)
企业级应用: 传统应用(另外一个分类: 互联网项目; 给销售或者贸易型公司使用,在市场,销售,客服等各个环节种维护客户关系,CRM项目的宗旨,增加新客户,留住老客户,把已有客户转换为中忠诚客户。
- CRM是一类项目
我们的CRM是给一个大型的进出口贸易公司来使用的,做大众商品的进出口贸易;商品受国家管制的
- CRM项目的核心业务
系统管理功能: 不是直接处理业务数据,为了保证业务管理的功能正常安全运行而设计的功能
用户登录,安全退出,登录验证等
超级管理员,开发和运维人员使用
业务管理功能: 处理业务数据
市场活动: 市场部,设计市场活动营销获取
线索: 销售部(初级销售)增加线索
客户和联系人:销售部(高级销售)有效地区分和跟踪客户和联系人
交易:销售部(高级销售)更好地区分和统计交易的各个阶段
售后回访: 客服部,妥善安排售后回访,主动提醒
统计图表: 管理层,统计交易表中各个阶段的数据量(销售漏斗管理)
[web开发: 前台发送请求--->后台java--->请求驱动--->http(长连接协议)]
物理模型结构
CRM的表结构
表格名称 | 中文名称 |
tb1_user | 用户表 |
tb1_dic_type (system) | 数据字典类型表 |
tb1_dic_value (system) | 数据字典值 |
tb1_activity | 市场活动表 |
tb1_activity_remark | 市场活动备注表 |
tb1_clue | 线索表 |
tb1_clue_remark | 线索备注表 |
tb1_clue_activity_relation | 线索和市场活动的关联关系表 |
tb1_customer | 客户表 |
tb1_customer_remark | 客户备注表 |
tb1_contacts | 联系人表 |
tb1_contacts_remark | 联系人备注表 |
tb1_tran | 交易表 |
tb1_tran_remark | 交易备注表 |
tb1_tran_history | 交易历史表 |
tb1_task | 任务表 |
- 主键字段:在数据库表中,如果有一组字段能够唯一确定一条记录,则可以把他们设计成表的主键字,推荐使用一个字段做主键,而且推荐使用没有业务含义的字段做主键,比如:id等
主键字段的类型和长度(由主键值的生成方式来决定):
主键值的生成方式:
1. 自增: 借助数据库自身主键生成机制,
数值型 (number) 长度由数据量来决定
运行效率低
开发效率高
2. assighed: 程序员手动生成主键值,唯一非空,算法
high/low 算法: 数据型 长度由数据量决定
UUID: 字符串 长度是 32 位
3. 共享主键:由另一张表的类型和长度决定
4. 联合主键: 由多个字段的类型和长度决定
- 外键字段:用来确定表与表之间的关系
1. 一对多: 一张表(A)中的一条记录可以对应另一张表(B)中的多条记录 ----> A(1) ----- B(n);
另一张表(B)中的一条记录只能对应一张表(A)中的一条记录 ----> B(1) ----- A(1)
添加数据时,先添加父类记录,再添加子类记录
删除数据时,先删除子类记录,再删除父类记录
查询数据时,可能进行关联查询 // 查询所有姓张的id,name和所在班级name
内连接:查询所有符合条件的数据,并且要求结果再两张表中都有相对应的记录
左外连接: 查询左侧表中所有复合条件的数据,即使在右侧表中没有相对应的记录
* 如果外键不能为空,优先使用内连接
如果外键可以为空,
-- 假如只需要查询那些在另一种张表中有相对应的记录,使用内连接
-- 假如需要查询左侧表中所有符合条件的记录,使用左外连接
2. 一对一: 一张表(A)中的一条记录可以对应另一张表(B)中的一条记录 ----> A(1) ----- B(1);
另一张表(B)中的一条记录只能对应一张表(A)中的一条记录 ----> B(1) ----- A(1)
· 1. 共享主键: (不推荐)
添加数据时,先添加先产生的表,再添加后产生的表记录
删除数据时,先删除后产生的表记录,再删除先产生的表记录
查询数据时,无需进行连接查询
2. 唯一外键:
*一对一就是特殊的一对多的关系
*操作和一对多完全一样
3. 多对多: 一张表(A)中的多条记录可以对应另一张表(B)中的多条记录 ----> A(n) ----- B(n);
另一张表(B)中的多条记录只能对应一张表(A)中的多条记录 ----> B(n) ----- A(n)
添加数据时,先添加父类记录(tb1_student, tb2_course) 再添加子表 (tb1_student_course_relation)
删除数据时,先删除子类记录,再删除父类记录
查询数据时,可能会进行关联查询
- 关于日期和时间的字段的字段
都按照字符串处理:
char(10) yyyy-mm-dd
char(19) yyyy-mm-dd HH:mm:ss
创建crm的数据库实例
1> 创建数据库
2> 执行sql脚本
- 执行 tb1_user.sql
-- ----------------------------
-- Table structure for `tbl_user`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
`id` char(32) NOT NULL COMMENT 'uuid\r\n ',
`login_act` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`login_pwd` varchar(255) DEFAULT NULL COMMENT '密码不能采用明文存储,采用密文,MD5加密之后的数据',
`email` varchar(255) DEFAULT NULL,
`expire_time` char(19) DEFAULT NULL COMMENT '失效时间为空的时候表示永不失效,失效时间为2018-10-10 10:10:10,则表示在该时间之前该账户可用。',
`lock_state` char(1) DEFAULT NULL COMMENT '锁定状态为空时表示启用,为0时表示锁定,为1时表示启用。',
`deptno` char(4) DEFAULT NULL,
`allow_ips` varchar(255) DEFAULT NULL COMMENT '允许访问的IP为空时表示IP地址永不受限,允许访问的IP可以是一个,也可以是多个,当多个IP地址的时候,采用半角逗号分隔。允许IP是192.168.100.2,表示该用户只能在IP地址为192.168.100.2的机器上使用。',
`createTime` char(19) DEFAULT NULL,
`create_by` varchar(255) DEFAULT NULL,
`edit_time` char(19) DEFAULT NULL,
`edit_by` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tbl_user
-- ----------------------------
INSERT INTO `tbl_user` VALUES ('06f5fc056eac41558a964f96daa7f27c', 'ls', '李四', 'yf123', 'ls@163.com', '2018-11-27 21:50:05', '1', 'A001', '192.168.1.1,0:0:0:0:0:0:0:1', '2018-11-22 12:11:40', '李四', null, null);
INSERT INTO `tbl_user` VALUES ('40f6cdea0bd34aceb77492a1656d9fb3', 'zs', '张三', 'yf123', 'zs@qq.com', '2018-11-30 23:50:55', '1', 'A001', '192.168.1.1,192.168.1.2,127.0.0.1,0:0:0:0:0:0:0:1', '2018-11-22 11:37:34', '张三', null, null);
- 执行 dictionary.sql
/*==============================================================*/
/* DBMS name: MySQL 5.0 */
/* Created on: 2020/3/5 9:12:54 */
/*==============================================================*/
drop table if exists tbl_dic_type;
drop table if exists tbl_dic_value;
/*==============================================================*/
/* Table: tbl_dic_type */
/*==============================================================*/
create table tbl_dic_type
(
code varchar(255) not null comment '编码是主键,不能为空,不能含有中文。',
name varchar(255),
description varchar(255),
primary key (code)
);
/*==============================================================*/
/* Table: tbl_dic_value */
/*=============================================