举枪消灭"烂代码"的实战案例

前言
之前我写过一篇如何少写PHP "烂"代码 https://segmentfault.com/a/11...
感觉很多新人对此不太理解。今天以打卡功能为例,去讲解其中的奥秘。那篇文章讲过代码开发的过程中分几种类型。
增删改的需求
Route -> Controller -> Service -> Action
查的需求
Route -> Controller -> Service -> Repository
经过多次实际开发验证后,发现Repository完全是多次一举。所以在这里更正下,取消Repository。
Route -> Controller -> Service
打卡系统逻辑架构图

需求是这样的,用户每天打卡获得积分,积分计入用户账户,并且需记录用户积分的获取及消费情况。如图所示,请求到控制器后,通过控制器去调用服务,服务又调用创建用户打卡模块完成打开,在用户打卡过程中对用户账户积分进行变更及记录用户积分获取记录。
数据表结构
打卡数据表
CREATE TABLE `member_attendance` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL COMMENT '用户编码',
`status` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '1签到成功',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
用户钱包表
CREATE TABLE `wallet` (
`user_id` bigint(20) NOT NULL COMMENT '用户标示',
`balance` decimal(12,2) NOT NULL COMMENT '钱包余额',
`integral` decimal(12,2) NOT NULL DEFAULT '0',
`add_time` int(11) NOT NULL COMMENT '添加时间',
`update_time` int(11) NOT NULL COMMENT '更改时间',
UNIQUE KEY `wallet_user_id_unique` (`user_id`),
KEY `wallet_user_id_index` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
用户积分交易记录表
CREATE TABLE `member_integral_detail` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL COMMENT '用户编码',
`title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '来源或消费',
`integral` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '积分数',
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型 0收入 -1支出',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
具体业务实现
Route
$api->post ('user/attendance','UserController@attendance');
MemberController
public function attendance()
{
$result = $this->userService->attendance ($this->request);
if ($result) {
return $this->response->array (Response::return (200, '打卡成功'));
}
return $this->response->array (Response::return (0, "打卡失败或已打卡"));
}
MemberService
public function attendance($request)
{
return (new CreateUserAttendance())->execute ($request);
}
CreateUserAttendance
public function issetToday($userId)
{
$result = MemberAttendance::where ([
['member_id', '=', $userId],
])
->whereDate ('created_at', date ('Y-m-d', time ()))
->exists ();
return $result;
}
// -------------------- 上述是下方issetToday方法,写在MemberModel中
class CreateUserAttendance
{
public function execute($data)
{
if ((new MemberAttendance())->issetToday ($data->user_id)) {
return false;
}
$models = new MemberAttendance();
$models->member_id = $data->user_id;
$models->status = (string)"1";
$result = $models->save ();
if ($result) {
(new CreateUserIntegralDetail())->execute ($data->user_id, '打卡', 10, 0);
return true;
}
return false;
}
}
CreateUserIntegralDetail
interface integralDetail
{
public function execute($userId, $title, $integral, $type);
}
class CreateUserIntegralDetail extends UpdateUserWalletIntegral implements integralDetail
{
public function execute($userId, $title, $integral, $type)
{
parent::exec ($userId, $integral, $type);
$models = new MemberIntegralDetail();
$models->member_id = $userId;
$models->title = $title;
$models->integral = $integral;
$models->type = $type;
return $models->save ();
}
}
上述代码继承了更新用户积分的动作,在每次打卡成功后,我们调用父类方法直接更新用户积分。
UpdateUserWalletIntegral
class UpdateUserWalletIntegral
{
public function exec($userId, $integral, $type)
{
if ($type == 0) {
Wallet::where (['user_id', '=', $userId])->increment ('integral', $integral);
} else {
Wallet::where (['user_id', '=', $userId])->decrement ('integral', $integral);
}
}
}
致谢
感谢你看到这里,希望本篇文章可以帮到你。有什么问题可在下方评论区留言。谢谢
举枪消灭"烂代码"的实战案例的更多相关文章
- php 网站301重定向设置代码实战案例
php 网站301重定向设置代码实战案例 301重定向就是页面永久性移走的意思,搜索引擎知道这个页面是301重定向的话,就会把旧的地址替换成重定向之后的地址. 302重定向就是页面暂时性转移,搜索引擎 ...
- Java生鲜电商平台-一次代码重构的实战案例
Java生鲜电商平台-一次代码重构的实战案例 说明,Java开源生鲜电商平台-一次代码重构的实战案例,根据实际的例子,分析出重构与抽象,使代码更加的健壮与高效. 1.业务说明 系统原先已有登录功能,我 ...
- 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange
如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...
- 【Redis3.0.x】实战案例
Redis3.0.x 实战案例 简介 <Redis实战>的学习笔记和总结. 书籍链接 初识 Redis Redis 简介 Redis 是一个速度非常快的键值对存储数据库,它可以存储键和五种 ...
- python实战案例--银行系统
stay hungry, stay foolish.求知若饥,虚心若愚. 今天和大家分享一个python的实战案例,很多人在学习过程中都希望通过一些案例来试一下,也给自己一点动力.那么下面介绍一下这次 ...
- 分布式事务之——tcc-transaction分布式TCC型事务框架搭建与实战案例(基于Dubbo/Dubbox)
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/73731363 一.背景 有一定分布式开发经验的朋友都知道,产品/项目/系统最初为了 ...
- 企业Shell面试题及企业运维实战案例(三)
1.企业Shell面试题1:批量生成随机字符文件名案例 使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy,名称示例如下: ...
- 烂代码 git blame
关于烂代码的那些事(上) - Axb的自我修养 http://blog.2baxb.me/archives/1343 关于烂代码的那些事(上) 六月 21, 2015 57 条评论 目录 [显示] 1 ...
- 基于SpringCloud的Microservices架构实战案例-在线API管理
simplemall项目前几篇回顾: 1基于SpringCloud的Microservices架构实战案例-序篇 2基于SpringCloud的Microservices架构实战案例-架构拆解 3基于 ...
随机推荐
- MongoDB集群——分片
1. 分片的结构及原理分片集群结构分布: 分片集群主要由三种组件组成:mongos,config server,shard1) MONGOS数据库集群请求的入口,所有的请求都通过mongos进行协调, ...
- hibernate投影查询
1. 投影查询就是想查询某一字段的值或者某几个字段的值 2. 投影查询的案例 * 如果查询多个字段,例如下面这种方式 List<Object[]> list = session.creat ...
- EditText 光标的颜色
EditText有一个属性:android:textCursorDrawable,这个属性是用来控制光标颜色的 android:textCursorDrawable="@null&quo ...
- RK平台Android4.4 添加一个新的遥控器支持以及添加特殊按键【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/52904063 版权声明:本文为博主原创文章,未经博主允许不得转载. 瑞芯微平台 ...
- iOS界面之间的跳转方式
iOS界面之间的跳转方式基本有3种. .改变window的根视图 [self.window setRootViewController:VC]; .模态弹出 [self presentViewCont ...
- MSP430:管脚的第二功能选择
之前在使用PWM,AD时候用到过第二功能,不过都是copy没有注意过PXSEL究竟怎么设置,今天在设置晶振管脚时候遇到了麻烦,细致看了一下其实很简单,在SPEC的最后详细讲了每个管脚如何设置为其他功能 ...
- 红黑树插入操作原理及java实现
红黑树是一种二叉平衡查找树,每个结点上有一个存储位来表示结点的颜色,可以是RED或BLACK.红黑树具有以下性质: (1) 每个结点是红色或是黑色 (2) 根结点是黑色的 (3) 如果一个结点是红色的 ...
- Android.mk添加第三方jar包(转载)
转自:www.cnblogs.com/hopetribe/archive/2012/04/23/2467060.html LOCAL_PATH:= $(call my-dir)include $(CL ...
- E20170930-hm
parse vt. 从语法上描述或分析(词句等);
- U盘在电脑上安装CentOS 7 系统过程详解
U盘制作CentOS系统启动盘 在电脑上下载并安装UltraISO软件,如百度云:http://pan.baidu.com/s/1hrGtvEG 打开UltraISO软件,找到CentOS.iso的映 ...