'use strict';
const Service = require('egg').Service;
const moment = require('moment');
const redis = require('redis');
const RedlockClass = require('redlock');
const { port, host, password } = require('../../../config/config.default')({ getter: 'redis' }).client;
class BusinessHandlingService extends Service {
// sql实例
sqlClient() {
return this.ctx.state.sqlClient || this.app.mysql.get(this.ctx.session.sqlName)
}
// redlock实例
redlockClient() {
// redis客户端
const redisClient = redis.createClient(port, host, { password: password, db: '1' })
redisClient.on('redisClient-err', err => { redisClient.quit() })
const redlock = new RedlockClass(
[redisClient],
{
driftFactor: 0.01, // 漂移值
retryCount: 60, // 重试次数
retryDelay: 500, // 重试间隔
retryJitter: 200 // 间隔增量随机最大值
}
)
return redlock
}
// 生成受理单号
async createBusNo() {
const { ctx } = this
// 分布式锁
const redlockClient = this.redlockClient()
const flag = `createBus` // 锁名(场景唯一标识)
const ttl = 1 * 30 * 1000 // 有效期(过期自动释放锁)
const lock = await redlockClient.lock(flag, ttl).then(lock => lock).catch(err => false)
if (!lock) {
return { code: 1, msg: '【生成受理单号】系统繁忙,请稍后重试' }
}
// 新增号
const nowDate = moment().format('YYYYMMDD')
const lastNoRes = await this.sqlClient().query(`select substring(acceptNum, -4) as no from bus_accept_num where acceptNum is not null and substring(acceptNum, 1, 8) = '${nowDate}' order by (substring(acceptNum, -4)) desc limit 0, 1`)
const no = lastNoRes.length ? +lastNoRes[0].no : 0
const acceptNum = nowDate + ('' + (no + 1)).padStart(4, 0) // 202403180009
// 记录号
await this.sqlClient().insert('bus_accept_num', { acceptNum, acceptTime: moment().format('YYYY-MM-DD HH:mm:ss') })
// 解锁
lock.unlock()
return { code: 0, data: { acceptNum }, msg: '受理单号生成成功' }
}
}