Phase1 后端核心:
- 新增 fsgx_v1.sql 迁移脚本(is_queue_goods/frozen_points/available_points/no_assess)
- SystemConfigServices 返佣设置扩展(周期人数/分档比例/范围/时机)
- StoreOrderCreateServices 周期循环佣金计算
- StoreOrderTakeServices 佣金发放后同步冻结积分
- StoreProductServices/StoreProduct 保存 is_queue_goods
Phase2 后端接口:
- GET /api/hjf/brokerage/progress 佣金周期进度
- GET /api/hjf/assets/overview 资产总览
- HjfPointsServices 每日 frozen_points 0.4‰ 释放定时任务
- PUT /adminapi/hjf/member/{uid}/no_assess 不考核接口
- GET /adminapi/hjf/points/release_log 积分日志接口
Phase3 前端清理:
- hjfCustom.js 路由精简(仅保留 points/log)
- hjfQueue.js/hjfMember.js API 清理/重定向至 CRMEB 原生接口
- pages.json 公排→推荐佣金/佣金记录/佣金规则
Phase4-5 前端改造:
- queue/status.vue 推荐佣金进度页整体重写
- 商品详情/订单确认/支付结果页文案与逻辑改造
- 个人中心/资产页/引导页/规则页文案改造
- HjfQueueProgress/HjfRefundNotice/HjfAssetCard 组件改造
- 推广中心嵌入佣金进度摘要
- hjfMockData.js 全量更新(公排字段→佣金字段)
Phase6 Admin 增强:
- 用户列表新增 frozen_points/available_points 列及不考核操作按钮
- hjfPoints.js USE_MOCK=false 对接真实积分日志接口
Phase7 配置文档:
- docs/fsgx-phase7-config-checklist.md 后台配置与全链路验收清单
Made-with: Cursor
229 lines
5.4 KiB
JavaScript
229 lines
5.4 KiB
JavaScript
// +----------------------------------------------------------------------
|
||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||
// +----------------------------------------------------------------------
|
||
// | Author: CRMEB Team <admin@crmeb.com>
|
||
// +----------------------------------------------------------------------
|
||
|
||
import { EXPIRE } from '../config/app';
|
||
|
||
class Cache {
|
||
|
||
constructor(handler) {
|
||
this.cacheSetHandler = uni.setStorageSync;
|
||
this.cacheGetHandler = uni.getStorageSync;
|
||
this.cacheClearHandler = uni.removeStorageSync;
|
||
this.cacheExpire = 'UNI-APP-CRMEB:TAG';
|
||
this.clearOverdue();
|
||
}
|
||
|
||
/**
|
||
* 获取当前时间戳
|
||
*/
|
||
time() {
|
||
return Math.round(new Date() / 1000);
|
||
}
|
||
|
||
/**
|
||
* 字符串转时间戳
|
||
* @param {Object} expiresTime
|
||
*/
|
||
strTotime(expiresTime){
|
||
let expires_time = expiresTime.substring(0, 19);
|
||
expires_time = expires_time.replace(/-/g, '/');
|
||
return Math.round(new Date(expires_time).getTime() / 1000);
|
||
}
|
||
|
||
|
||
/**
|
||
* 设置过期时间缓存
|
||
* @param {Object} key
|
||
* @param {Object} expire
|
||
*/
|
||
setExpireCaheTag(key, expire) {
|
||
expire = expire !== undefined ? expire : EXPIRE;
|
||
if (typeof expire === 'number') {
|
||
let tag = this.cacheGetHandler(this.cacheExpire), newTag = [],newKeys = [];
|
||
if (typeof tag === 'object' && tag.length) {
|
||
newTag = tag.map(item => {
|
||
newKeys.push(item.key);
|
||
if (item.key === key) {
|
||
item.expire = expire === 0 ? 0 : this.time() + expire;
|
||
}
|
||
return item;
|
||
});
|
||
}
|
||
if (!newKeys.length || newKeys.indexOf(key) === -1) {
|
||
newTag.push({
|
||
key: key,
|
||
expire: expire === 0 ? 0 : this.time() + expire
|
||
});
|
||
}
|
||
this.cacheSetHandler(this.cacheExpire, newTag);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 缓存是否过期,过期自动删除
|
||
* @param {Object} key
|
||
* @param {Object} $bool true = 删除,false = 不删除
|
||
*/
|
||
getExpireCahe(key, $bool) {
|
||
try {
|
||
let tag = this.cacheGetHandler(this.cacheExpire),time = 0,index = false;
|
||
if (typeof tag === 'object' && tag.length) {
|
||
tag.map((item,i) => {
|
||
if(item.key === key){
|
||
time = item.expire
|
||
index = i
|
||
}
|
||
});
|
||
if (time) {
|
||
let newTime = parseInt(time);
|
||
if (time && time < this.time() && !Number.isNaN(newTime)) {
|
||
if ($bool === undefined || $bool === true) {
|
||
this.cacheClearHandler(key);
|
||
if(index !== false){
|
||
tag.splice(index,1)
|
||
this.cacheSetHandler(this.cacheExpire,tag);
|
||
}
|
||
}
|
||
return false;
|
||
} else
|
||
return true;
|
||
} else {
|
||
return !!this.cacheGetHandler(key);
|
||
}
|
||
}
|
||
return false;
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 设置缓存
|
||
* @param {Object} key
|
||
* @param {Object} data
|
||
*/
|
||
set(key, data, expire) {
|
||
if (data === undefined) {
|
||
return true;
|
||
}
|
||
if (typeof data === 'object')
|
||
data = JSON.stringify(data);
|
||
try {
|
||
this.setExpireCaheTag(key, expire);
|
||
return this.cacheSetHandler(key, data);
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检测缓存是否存在
|
||
* @param {Object} key
|
||
*/
|
||
has(checkwhethethecacheexists) {
|
||
this.clearOverdue();
|
||
return this.getExpireCahe(checkwhethethecacheexists);
|
||
}
|
||
|
||
/**
|
||
* 获取缓存
|
||
* @param {Object} key
|
||
* @param {Object} $default
|
||
* @param {Object} expire
|
||
*/
|
||
get(key, $default, expire) {
|
||
this.clearOverdue();
|
||
try {
|
||
let isBe = this.getExpireCahe(key);
|
||
let data = this.cacheGetHandler(key);
|
||
if (data && isBe) {
|
||
if (typeof $default === 'boolean')
|
||
return JSON.parse(data);
|
||
else
|
||
return data;
|
||
} else {
|
||
if (typeof $default === 'function') {
|
||
let value = $default();
|
||
this.set(key, value, expire);
|
||
return value;
|
||
} else {
|
||
this.set(key, $default, expire);
|
||
return $default;
|
||
}
|
||
}
|
||
} catch (e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除缓存
|
||
* @param {Object} key
|
||
*/
|
||
clear(key) {
|
||
try {
|
||
let cahceValue = this.cacheGetHandler(this.cacheExpire),
|
||
index = false;
|
||
if (cahceValue && typeof cahceValue === 'object' && cahceValue.length) {
|
||
cahceValue.map((item, i) => {
|
||
if (item.key === key) {
|
||
index = i;
|
||
}
|
||
});
|
||
|
||
if (index !== false) {
|
||
cahceValue.splice(index, 1);
|
||
}
|
||
this.cacheSetHandler(this.cacheExpire, cahceValue);
|
||
}
|
||
return this.cacheClearHandler(key);
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清除过期缓存
|
||
*/
|
||
clearOverdue() {
|
||
try {
|
||
let cahceValue = this.cacheGetHandler(this.cacheExpire),
|
||
time = this.time(),
|
||
newBeOverdueValue = [],
|
||
newTagValue = [];
|
||
|
||
if (Array.isArray(cahceValue) && cahceValue.length) {
|
||
cahceValue.map(item => {
|
||
if (item) {
|
||
if ((item.expire !== undefined && item.expire > time) || item.expire === 0) {
|
||
newTagValue.push(item);
|
||
} else {
|
||
newBeOverdueValue.push(item.key);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
//保存没有过期的缓存标签
|
||
if (!Array.isArray(cahceValue) || newTagValue.length !== cahceValue.length) {
|
||
this.cacheSetHandler(this.cacheExpire, newTagValue);
|
||
}
|
||
//删除过期缓存
|
||
newBeOverdueValue.forEach(k => {
|
||
this.cacheClearHandler(k);
|
||
})
|
||
} catch (e) {
|
||
// H5 初始化阶段 uni 存储 API 可能尚未就绪,忽略错误
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
export default new Cache;
|