机房收费系统——结账逻辑大BUG

时间:2024-03-31 10:17:05

博文背景

今天帮好朋友测机房系统发现的问题,是一个逻辑问题,而且非常致命,我说一下,大家以后做机房要注意这个问题。

A:结账原有逻辑

1.分别计算未结账的A(充值记录总值)、B(临时用户的消费总值)、C(销卡的总值)
2.应收 = A+B-C


但是有一些问题我们从原系统中没能得到解决:
1.用户开卡的时候,交的钱应该算在A、B中的谁?
2.为什么要把临时用户的钱单算?

我们把所有类型用户都进行设置成同样的模式,那么实际的应收金额应该是下述公式:

应收金额 = 开卡的钱+充值的钱-退卡的钱
(不论临时还是固定用户,都要进行开卡的退卡这两个步骤。)


B:灵魂拷问:那么这样,结账就没有问题了吗?

请大家注意【开卡时充的钱】(student_info cash)
请问数据库中的cash是你想要的cash吗?

请注意:
1.数据库中该表(student_info)的cash属性,不是固定不变的。
2.我们每次充值的钱,都要加入到cash属性当中。
3.我们每次上下机,cash的钱都会变动。

那么请问,我们上一部分的公式是不是有错误的?
我再一次解释一下:
1.我们student表的cash属性,每一次的充值操作,都会使其值增加。
那么cash值是:cash+充值的钱

2.每一次的上下机,都会使cash值减少。
那么cash值是:cash-消费的钱

3.所以,我们所用的第一次机房的数据库中的cash值实际上是:
A:首次开卡交的钱
B:充值的钱
C:消费的钱(非退卡的钱,是上下机消费的钱)
cash = A + B - C

但是我们的数据库中根本没有A所代表的值,所以cash值是无效的,对于结账没有任何意义。


C:真实的公式

既然cash值是错误的,那么我们刚才用cash的公式真相是什么?

我们再来看看模块A的公式:
应收金额 = 开卡的钱+充值的钱-退卡的钱
(基本上所有人理解的开卡的钱是cash吧?不会只有我一个吧。。。)

实际上我们的公式是:
应收金额 = 首次开卡的钱 + 充值的钱 * 2 - 消费的钱 - 退卡的钱


D:错误的公式得到的恶果

如果我们用cash作为开卡的钱,那么有什么后果?

情景:
顾客:老师,我想开个固定用户的卡,我交100块钱,卡号最好是10086。
老师:好的。
(老师注册了一个卡号为10086的卡。)
机房收费系统——结账逻辑大BUG
老师:同学,给你卡,现在你可以选一台机器去上机了。
同学:老师,我想再充100块。
老师:好的。
(老师为卡号为10086的卡,充了100元。)
机房收费系统——结账逻辑大BUG
同学:老师,我突然不想要张卡了,我能推掉吗?
老师:当然可以。
(老师对卡号为10086的卡,进行退卡。)
机房收费系统——结账逻辑大BUG
夜幕到临,主任来进行结账,并查看。
机房收费系统——结账逻辑大BUG
主任:王老师,怎么钱箱少了100块钱。
老师:没有啊,今天下雨,就一位比较二的同学来了。开卡交了100块,又充了100,退了200块。压根没有挣钱。
主任:休想骗我,系统人家说开了200块钱。
老师:嗯哼?WTF?


如果用户在结账之前进行上下机,比如说早上上机2小时且没充钱,那么cash值变少了。如果是网吧系统,那么操作员可能会把多余的钱(首次开卡-下机之后的cash钱)装进自己口袋。