所有系统的开发都受限于当时的技术积累、人力资源、设计方案,没有完美的系统,
我们只是在自己的技术能力内做到100分。 -- fuyuan
没有完美的系统,只有适合的系统。我不是大神,本文结合我以前在一个企业的CRM管理系统和后来开发维护的一个系统来说介绍下我踩过的坑。
业务背景
先说下业务背景吧,我当时接手重构改造任务的时候,面临如下情况:
- 老系统部署环境比较陈旧,还是apache+php, 比较老的环境了,经过若干年人员更替,部门分拆,已经不能说清楚上面运行的各种服务了,运维部署起来也比较困难,哪天死了,基本上无法复制,单点情况比较严重。
- 所用框架也比较老旧,自有框架,不仅包含后台服务代码,还包含管理系统代码,开发维护也比较困难。
- 界面风格也比较旧,还是十几年前的风格,操作起来比较怪异。
- 领导授权说重构吧。这个是最关键的,领导授权,是一个项目启动的旗帜。 系统从开发到后来的优化都是遵循的原则PDCA。
好,汇总各方面需求总结的情况如下:
- 新作一个管理后台系统,最好与主业务一样的结构,这样便于开发。即linux + nginx + php + yaf + memcache + yaconf + mysql等等。
- 迁移旧系统功能,按时完成,实现新的需要的功能。
- 找个流行的响应式模版。
- 技术栈升级,这个是最近才加入的内容。
系统整体架构设计
开始的时候因为对yaf不太熟,所以没有注意到application.dispatcher.defaultRoute.controllerPrefer=true 这个配置。以至于 每次一个接口,都得重建一个文件,写一个controller。 后来我想了一方法:对于a/b/c_d 这种路由,自己写了个规则,映射到A_B_C controller的d action方法中。 这样 对于简单的增删改查方法,就可以放在一个文件里了。
model设计
访问数据库的model,因为yaf框架比较简单,所以我参照了thinkphp的访问数据库部分自己写了一个简单的模块。 后来一个兄弟引入了laravel的ORM模块Eloquent,不过没有迁移所有的业务,所以存在了两套内容。
账号
这个比较简单,跟常用的系统相同。
角色
角色管理是确定角色具备哪些权限的一个过程,他是一个集合的概念,是众多最小权限颗粒的组成。我们通过把权限给这个角色,再把角色给账号,从而实现账号的权限,这是网上摘抄的,我在系统中并没有实现这么复杂。没用用到 超级管理员,管理员,普通用户角色区分,这个要看系统应用场景吧。
权限的定义
网上有各种个样的帖子介绍管理系统的,我也介绍下我的这个系统里面权限的部分。
权限可以分为三种:页面权限,操作权限,数据权限 页面权限:即入口,用户可以看到哪个页面,看不到哪个页面。 操作权限:进入同样的页面,有些人看到这个按钮可点击,有些人只能浏览这个页面的数据。 数据权限:则是控制你可以看到哪些数据,比如会员的人A只能看到或者修改A部创建的数据,他看不到或者不能修改B部的数据。
我这边实现是限定一个一个常量列表和一个权限菜单。可以是增删改查的,我这边考虑到这个变化有限,所以只在代码中写成了固定的内容,增加一项菜单就改回代码就行了。
// 常量定义
define('P_USER_MANAGE', 1); // 后台用户管理
define('P_USER', 2); // 用户管理列表
define('P_GROUP', 3); // 组管理列表
... ...
// 权限树
P_USER_MANAGE => [
'title' => '后台管理',
'link' => '',
'class' => 'fa fa-user',
'child' => [
P_USER => [
'title' => '用户列表',
'link' => '/user/list',
'class' => '',
'child' => array()
],
P_GROUP => [
'title' => '组列表',
'link' => '/group/list',
'class' => '',
'child' => array()
]
]
]
这样 每次用户进入页面 再根据一定的算法获得用户 应该有的权限,相关代码可以参考: https://github.com/netbird/permission
这个是以前实现的一个类,是将权限由低到高排列,保存的时候每4位转变成1个十六进制的字符,然后合并。 例如: 用户权限是 '', 把权限 12加上,就是1000 0000 0000, 保存就是,800。 主要实现了以下方法:
Permission::setuserPermission($permission_index, $user_perm)
// 这个是设置权限,比如用户的现在权限是'', 如果把12这个权限号码加上则执行:
// $user_permission = Permission::setuserPermission(12, $user_permission)
Permission::deleteUserPermission($permission_index, $user_perm)
// 删除权限
Permission::isAllowUserPermission($permission_index, $user_perm)
// 判断用户是否有权限
至于按钮权限,这个也可以参照这个进行,定义一个按钮的设置常量,判断有那个权限,则展示按钮。 数据访问,这个具体场景 具体分析了,不过每个接口入口的地方 至少需要判定访问权限。
响应式模版
技术讲究厚积薄发,只有平时多积累多实践,关键的时候才能发挥用途。因为以前做了类似的系统,所以利用了以下一个模版框架。然后进行改造。 我不愿意每次都写表格页面,所以使用jquery table这个第三方的插件,采用异步加载数据的方式。在这个插件上面进行了简单的二次开发。后来的大多数功能都是采用的这个插件。 bootstrap是个好东西,以前用的少,这次大规模使用,每天就是调页面,调前端。在笔记本上看着不错,到了显示器上就走样,很苦恼。不过我经手的页面普遍没啥问题。
功能改进
之前每次新建功能都得新建个表,然后写编辑页面,好烦啊。能不能搞个公用的机制,简单的引用就生成个简单的编辑页面。于是,我对编辑部分进行了封装改进。 先说下数据库:建造个公共表:主要包含 main_key, second_key, config_value,等内容,config_value是参照key-value格式数据库的value字段使用,当然 text类型最高65535个字节把,如果太大,会造成bug。 就是将关系型数据库作为key-value用了,一些加单的配置信息,经过json转成字符串然后保存下来。
自定义通用配置
有没有一种方案,能够不编写代码,仅靠后台点点就能满足配置? 于是先出设计方案,后加工。 一般的项目配置分成单页和列表的配置。可参照如下需求:
- 进入设置页面,创建1个item,类型分成单页和列表。
- 选择 编辑页面是否包含日期,发布权限的人员,可修改字段的人员,发布的文件名称等等吧。
- 单页面或者列表的单页面编辑页支持自定义字段编辑(可添加或减少字段)。
于是这个项目就产生了。虽然体验差了一点,但是基本满足需求,节约开发时间还是没有问题的。
模版
关于模版是在列表页面提出的,在自定义列表页,每次创建单页面的时候都需要重建数据很麻烦。于是改进了下,在配置页面有个模版设置页面,模版页面可以添加删除定义字段。这样在创建新页面的时候就可以继承模版了。
ini配置文件
关于生成的配置信息,我们还是采用了yaconf的php扩展插件,所以大部分配置以ini文件的形式推到线上。yaconf的用户可以参考线上说明。下面博客也总结了一些yaconf使用的坑。 一些使用Yaconf的经验分享
日志及备份
一开始记录mysql,每条都记录,后来发现不太好,需要的时候什么也查不出来。还是应该从产品的角度看这个日志吧。 这个模块一直在开发改进中。大致的方向是给使用者一个友好的查询界面,去查询相关的内容。 因为一些隐患,后来我加入了配置信息备份功能,每次配置更新的时候保存已有的线上这个文件配置,并且记录到数据库。然后做个后台,可以查看,比对配置并且上线。 这个地方引用了一个公共类库:https://github.com/chrisboulton/php-diff
vue
一次偶然的机会接触到vue基础知识,在系统的某些页面决定尝试以下,没有深入使用,只是引入了 vue.js。进行了一些页面处理,感觉确实方便了很多。当时只是看了vue的一些基础知识,有很多问题还停留在表面层,所以没有深入应用。
类似下面的代码,很舒服的感觉。
new Vue({
el: '#app',
data: {
source_url:"",
count_result_text: "",
uid: ""
},
methods: {
count_result: function () {
var that = this;
if (this.source_url == '') {
bootbox.alert('url不能为空');
return;
}
var param = {
"source_url": this.source_url,
"uid": this.uid
};
$.post('/api/counts', param, function(return_data){
that.count_result_text = return_data.s;
}, 'json');
}
}
});
Vue.js 组件与路由
ant design
年初,想对系统升级改造。增加几个模块,朋友推荐ant design。感觉挺好,使用各种入坑。 下面是一些问题的总结, 我在另外的两篇文章中提到的: ant design form表单的时间处理 碰到一个ant design跨域问题
全新的开发模式,我很喜欢。 技术栈:react,ant-design,dva,Mock 关于dva,有个图,我想大家应该学习下:
本次学会使用了npm,webpack, mock.js, node.js等相关内容。 最后学以致用,技术永远为业务服务。这个是历史以来的道理。多运用,多思考。