fix(积分): 积分累计改按收支方向聚合,移除已废弃的过期提示

- UserBillServices 新增 getIntegralSumByPm():按 category=integral + status=1 +
  pm 方向求和,支持时间筛选与冻结期内(is_frozen=1)统计。
- 签到页用户信息统计不再枚举 type 白名单:新增积分类型(order_give_integral、
  order_gain_refund 等)无需同步维护即可正确计入累计/支出/今日;
  冻结积分改为只统计积分流水中的冻结收入项。
- 用户端积分页移除 clear_time 过期提示(对应逻辑已废弃),清理 dayjs 依赖与
  isTime 状态。
This commit is contained in:
吴昊天 2026-10-23 14:09:51 +08:00
parent 51f76ec771
commit d90135d2fc
3 changed files with 34 additions and 23 deletions

View File

@ -457,6 +457,32 @@ class UserBillServices extends BaseService
return $this->dao->getBillSumColumn($where);
}
/**
* 按收支方向统计用户积分合计
* 用 pm 方向聚合替代 type 白名单,避免新增积分类型漏统计
* @param int $uid 用户ID
* @param int $pm 1=收入 0=支出
* @param string $time 时间筛选(today/week/month 等),空则不限
* @param bool $frozen 是否只统计冻结期内(frozen_time > 当前时间)的流水
* @return float
*/
public function getIntegralSumByPm(int $uid, int $pm, string $time = '', bool $frozen = false): float
{
$where = [
'uid' => $uid,
'category' => 'integral',
'status' => 1,
'pm' => $pm,
];
if ($time !== '') {
$where['time'] = $time;
}
if ($frozen) {
$where['is_frozen'] = 1;
}
return (float)$this->dao->getBillSumColumn($where);
}
/**
* 获取用户|所有佣金总数

View File

@ -281,12 +281,13 @@ class UserSignServices extends BaseService
if ($integral || $all) {
/** @var UserBillServices $userBill */
$userBill = app()->make(UserBillServices::class);
$user['sum_integral'] = intval($userBill->getRecordCount($user['uid'], 'integral', 'sign,system_add,gain,lottery_add,product_gain,pay_product_integral_back'));
$user['deduction_integral'] = intval($userBill->getRecordCount($user['uid'], 'integral', 'deduction,lottery_use,order_deduction,storeIntegral_use', '', true) ?? 0);
$user['today_integral'] = intval($userBill->getRecordCount($user['uid'], 'integral', 'sign,system_add,gain,product_gain,lottery_add,pay_product_integral_back', 'today'));
/** @var UserBillServices $userBillServices */
$userBillServices = app()->make(UserBillServices::class);
$user['frozen_integral'] = $userBillServices->getBillSum(['uid' => $user['uid'], 'is_frozen' => 1]);
// 按收支方向(pm)聚合,不再枚举 type 白名单:新增积分类型(如下单赠送 order_give_integral、
// 退款回收 order_gain_refund 等)无需同步维护即可正确计入累计
$user['sum_integral'] = intval($userBill->getIntegralSumByPm($user['uid'], 1));
$user['deduction_integral'] = intval($userBill->getIntegralSumByPm($user['uid'], 0));
$user['today_integral'] = intval($userBill->getIntegralSumByPm($user['uid'], 1, 'today'));
// 冻结积分:仅统计积分流水中处于冻结期内的收入项
$user['frozen_integral'] = $userBill->getIntegralSumByPm($user['uid'], 1, '', true);
}
unset($user['pwd']);
if (!$user['is_promoter']) {

View File

@ -34,11 +34,8 @@
:class="item.icon"></text>{{item.name}}</view>
</view>
<view class='list' :class="{'bag-white': integralList.length}" :hidden='current!=0'>
<view class='tip acea-row row-middle' v-if="!isTime"><text
<view class='tip acea-row row-middle'><text
class='iconfont icon-shuoming'></text>{{$t(`提示:积分数值的高低会直接影响您的会员等级`)}}</view>
<view class='tip acea-row row-middle' v-else><text
class='iconfont icon-shuoming'></text>{{$t(`提示:你有`)}}{{userInfo.clear_integral}}{{$t(`积分在`)}}{{ dateFormat(userInfo.clear_time) }}{{$t(`过期,请尽快使用`)}}
</view>
<view class='item acea-row row-between-wrapper' v-for="(item,index) in integralList" :key="index">
<view>
<view class='state'>{{$t(item.title)}}</view>
@ -88,7 +85,6 @@ import {
postSignUser,
getIntegralList as getIntegralListApi
} from '@/api/user.js';
import dayjs from '@/plugin/dayjs/dayjs.min.js';
import {
toLogin
} from '@/libs/login.js';
@ -125,7 +121,6 @@ const loading = ref(false);
const loadTitle = ref(i18n.t(`加载更多`));
const isAuto = ref(false); //没有授权的不会自动授权
const isShowAuth = ref(false); //是否隐藏授权
const isTime = ref(0);
// ---------- watch ----------
watch(isLogin, (newV, oldV) => {
@ -152,9 +147,6 @@ onReachBottom(() => {
});
// ---------- methods ----------
function dateFormat(value) {
return dayjs(value * 1000).format('YYYY-MM-DD');
}
/**
* 授权回调
*/
@ -173,14 +165,6 @@ function getUserInfo() {
all: 1
}).then(function(res) {
userInfo.value = res.data;
let clearTime = res.data.clear_time;
let showTime = clearTime - (86400 * 14);
let timestamp = Date.parse(new Date()) / 1000;
if (showTime < timestamp) {
isTime.value = 1
} else {
isTime.value = 0
}
});
}