From e3d4ec46243f9e1bfd3d72c1486cc9af352e5ba1 Mon Sep 17 00:00:00 2001
From: zhenhui <1276357500@qq.com>
Date: Fri, 24 Jul 2026 12:01:41 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=AF=8F=E6=97=A5=E6=8E=A8?=
=?UTF-8?q?=E9=80=81=E5=92=8C=E7=A7=AF=E5=88=86=E8=BD=AC=E5=8C=96=E5=A4=9A?=
=?UTF-8?q?=E8=AF=AD=E8=A8=80=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/admin/controller/mall/PlayxConfig.php | 12 ++-
app/admin/lang/en.php | 2 +
app/admin/lang/zh-cn.php | 2 +
app/common/library/MallPointsConversion.php | 4 +-
web/src/api/backend/mall/playxConfig.ts | 13 +--
web/src/lang/backend/en/mall/pageIntro.ts | 4 +-
web/src/lang/backend/en/mall/playxConfig.ts | 1 +
.../lang/backend/en/mall/playxDailyPush.ts | 24 ++---
web/src/lang/backend/en/mall/userAsset.ts | 26 ++---
web/src/lang/backend/zh-cn/mall/pageIntro.ts | 4 +-
.../lang/backend/zh-cn/mall/playxConfig.ts | 1 +
.../views/backend/mall/dailyPush/index.vue | 11 ++-
.../views/backend/mall/playxConfig/index.vue | 12 ++-
.../backend/mall/playxDailyPush/index.vue | 95 ++++++++++++++++---
.../views/backend/mall/userAsset/index.vue | 58 +++++++++--
15 files changed, 204 insertions(+), 65 deletions(-)
diff --git a/app/admin/controller/mall/PlayxConfig.php b/app/admin/controller/mall/PlayxConfig.php
index 8ae7aee..9f2663f 100644
--- a/app/admin/controller/mall/PlayxConfig.php
+++ b/app/admin/controller/mall/PlayxConfig.php
@@ -144,9 +144,17 @@ class PlayxConfig extends Backend
} catch (\Throwable $e) {
Db::rollback();
- return $this->error($e->getMessage());
+ return $this->error(__($e->getMessage()));
}
- return $this->success(__('Operation completed'), $stats);
+ return $this->success(
+ sprintf(
+ __('Lifetime points calculation completed'),
+ $stats['processed'],
+ $stats['updated'],
+ $stats['skipped']
+ ),
+ $stats
+ );
}
}
diff --git a/app/admin/lang/en.php b/app/admin/lang/en.php
index d1dfe68..f85d677 100644
--- a/app/admin/lang/en.php
+++ b/app/admin/lang/en.php
@@ -28,6 +28,8 @@ return [
'Deleted successfully' => 'Deleted successfully!',
'Parameter error' => 'Parameter error!',
'Lifetime points source is disabled' => 'Lifetime points source is disabled',
+ 'Operation completed' => 'Operation completed!',
+ 'Lifetime points calculation completed' => 'Lifetime conversion done: %d processed, %d updated, %d skipped',
'File uploaded successfully' => 'File uploaded successfully',
'No files were uploaded' => 'No files were uploaded',
'The uploaded file format is not allowed' => 'The uploaded file format is no allowance.',
diff --git a/app/admin/lang/zh-cn.php b/app/admin/lang/zh-cn.php
index 9f797dc..a26b869 100644
--- a/app/admin/lang/zh-cn.php
+++ b/app/admin/lang/zh-cn.php
@@ -28,6 +28,8 @@ return [
'Deleted successfully' => '删除成功!',
'Parameter error' => '参数错误!',
'Lifetime points source is disabled' => '终身总输赢积分来源未启用',
+ 'Operation completed' => '操作完成!',
+ 'Lifetime points calculation completed' => '终身总输赢积分折算完成:共处理 %d 条,更新 %d 条,跳过 %d 条',
'Please use the %s field to sort before operating' => '请使用 %s 字段排序后再操作',
'File uploaded successfully' => '文件上传成功!',
'No files were uploaded' => '没有文件被上传',
diff --git a/app/common/library/MallPointsConversion.php b/app/common/library/MallPointsConversion.php
index a14440d..662dff4 100644
--- a/app/common/library/MallPointsConversion.php
+++ b/app/common/library/MallPointsConversion.php
@@ -142,13 +142,13 @@ final class MallPointsConversion
public static function recalculateAllLifetimePoints(MallBusinessConfig $row): array
{
if (intval($row->lifetime_points_enabled ?? 0) !== 1) {
- throw new \RuntimeException(__('Lifetime points source is disabled'));
+ throw new \RuntimeException('Lifetime points source is disabled');
}
$config = self::configFromRow($row);
$ratio = floatval($config['lifetime_points_ratio'] ?? 0);
if ($ratio < 0) {
- throw new \RuntimeException(__('Parameter error'));
+ throw new \RuntimeException('Parameter error');
}
$stats = ['processed' => 0, 'updated' => 0, 'skipped' => 0];
diff --git a/web/src/api/backend/mall/playxConfig.ts b/web/src/api/backend/mall/playxConfig.ts
index e6ed998..8327ae9 100644
--- a/web/src/api/backend/mall/playxConfig.ts
+++ b/web/src/api/backend/mall/playxConfig.ts
@@ -29,13 +29,8 @@ export function save(data: anyObj) {
}
export function calculateLifetimePoints() {
- return createAxios(
- {
- url: actionUrl.get('calculateLifetimePoints'),
- method: 'post',
- },
- {
- showSuccessMessage: true,
- }
- )
+ return createAxios({
+ url: actionUrl.get('calculateLifetimePoints'),
+ method: 'post',
+ })
}
diff --git a/web/src/lang/backend/en/mall/pageIntro.ts b/web/src/lang/backend/en/mall/pageIntro.ts
index b514972..516c5ac 100644
--- a/web/src/lang/backend/en/mall/pageIntro.ts
+++ b/web/src/lang/backend/en/mall/pageIntro.ts
@@ -13,7 +13,7 @@ export default {
},
dailyPush: {
title: 'About this page',
- desc: 'Daily T+1 snapshots pushed by the partner; rows are stored here and drive user-asset related updates.',
+ desc: 'Daily T+1 snapshots from the partner; each row stores converted points per mall settings and syncs user assets.',
},
claimLog: {
title: 'About this page',
@@ -57,6 +57,6 @@ export default {
},
playxConfig: {
title: 'About this page',
- desc: 'Edit return/unlock/points-to-cash ratios used by daily push and asset APIs; values are stored in mall_business_config and apply immediately after save.',
+ desc: 'Configure daily and lifetime loss-to-points sources (switches and ratios), mall open date, unlock ratio, and points-to-cash ratio. Open date changes take effect the next calendar day.',
},
}
diff --git a/web/src/lang/backend/en/mall/playxConfig.ts b/web/src/lang/backend/en/mall/playxConfig.ts
index c0401d8..29fa759 100644
--- a/web/src/lang/backend/en/mall/playxConfig.ts
+++ b/web/src/lang/backend/en/mall/playxConfig.ts
@@ -12,6 +12,7 @@ export default {
calculate_lifetime_btn: 'Calculate lifetime loss points',
calculate_lifetime_tip: 'Batch update from latest daily push lifetime field and ratio above.',
calculate_lifetime_confirm: 'Recalculate all members with the current lifetime ratio (reverses previous lifetime conversion first). Continue?',
+ calculate_lifetime_success: 'Lifetime conversion done: {processed} processed, {updated} updated, {skipped} skipped',
section_mall_open: 'Mall open date',
mall_open_date: 'Mall open date',
mall_open_date_tip: 'Takes effect the next calendar day. E.g. set Aug 1: from Aug 2, daily push rows with business date on/after Aug 1 convert yesterday loss to points.',
diff --git a/web/src/lang/backend/en/mall/playxDailyPush.ts b/web/src/lang/backend/en/mall/playxDailyPush.ts
index 13fff88..2c6e7b8 100644
--- a/web/src/lang/backend/en/mall/playxDailyPush.ts
+++ b/web/src/lang/backend/en/mall/playxDailyPush.ts
@@ -1,14 +1,14 @@
export default {
- id: 'id',
- user_id: 'user_id',
- date: 'date',
- username: 'username',
- yesterday_win_loss_net: 'yesterday_win_loss_net',
- converted_points: 'converted_points',
- yesterday_total_deposit: 'yesterday_total_deposit',
- lifetime_total_deposit: 'lifetime_total_deposit',
- lifetime_total_withdraw: 'lifetime_total_withdraw',
- lifetime_win_loss_net: 'lifetime_win_loss_net',
- create_time: 'create_time',
- 'quick Search Fields': 'id',
+ id: 'ID',
+ user_id: 'PlayX user ID',
+ date: 'Business date',
+ username: 'Username',
+ yesterday_win_loss_net: 'Yesterday net win/loss',
+ converted_points: 'Converted points',
+ yesterday_total_deposit: 'Yesterday total deposit',
+ lifetime_total_deposit: 'Lifetime total deposit',
+ lifetime_total_withdraw: 'Lifetime total withdraw',
+ lifetime_win_loss_net: 'Lifetime net win/loss',
+ create_time: 'Created at',
+ 'quick Search Fields': 'ID',
}
diff --git a/web/src/lang/backend/en/mall/userAsset.ts b/web/src/lang/backend/en/mall/userAsset.ts
index 3908987..648d0ce 100644
--- a/web/src/lang/backend/en/mall/userAsset.ts
+++ b/web/src/lang/backend/en/mall/userAsset.ts
@@ -1,17 +1,17 @@
export default {
- id: 'id',
- username: 'username',
- phone: 'phone',
- playx_user_id: 'playX_user_id',
- locked_points: 'locked_points',
- available_points: 'available_points',
+ id: 'ID',
+ username: 'Username',
+ phone: 'Phone',
+ playx_user_id: 'PlayX user ID',
+ locked_points: 'Locked points',
+ available_points: 'Available points',
adjust_available_points: 'Adjust points',
- today_limit: 'today_limit',
- today_claimed: 'today_claimed',
- today_limit_date: 'today_limit_date',
- points_claim_cap: 'Points claim cap',
+ today_limit: 'Daily claim cap',
+ today_claimed: 'Claimed today',
+ today_limit_date: 'Daily cap date',
+ points_claim_cap: 'Lifetime claim cap',
total_points_claimed: 'Total points claimed',
- create_time: 'create_time',
- update_time: 'update_time',
- 'quick Search Fields': 'id, playX_user_id, username, phone',
+ create_time: 'Created at',
+ update_time: 'Updated at',
+ 'quick Search Fields': 'ID, PlayX user ID, username, phone',
}
diff --git a/web/src/lang/backend/zh-cn/mall/pageIntro.ts b/web/src/lang/backend/zh-cn/mall/pageIntro.ts
index 8f06c0b..c86dfea 100644
--- a/web/src/lang/backend/zh-cn/mall/pageIntro.ts
+++ b/web/src/lang/backend/zh-cn/mall/pageIntro.ts
@@ -13,7 +13,7 @@ export default {
},
dailyPush: {
title: '页面说明',
- desc: '展示合作方 T+1 每日推送的经营数据快照;接口写入后在此留痕,并用于同步用户资产相关字段。',
+ desc: '展示合作方 T+1 每日推送的经营数据快照;入库时按商城参数折算「转换积分」并同步用户资产。',
},
claimLog: {
title: '页面说明',
@@ -57,6 +57,6 @@ export default {
},
playxConfig: {
title: '页面说明',
- desc: '配置每日推送用到的返还比例、解锁比例及积分折算现金比例;保存后立即作用于接口逻辑(mall_business_config)。',
+ desc: '配置昨日净输赢、终身总输赢两种积分来源(开关与兑换比例)、商城开放日,以及解锁比例与积分折算现金比例;保存后按规则生效(开放日隔日生效)。',
},
}
diff --git a/web/src/lang/backend/zh-cn/mall/playxConfig.ts b/web/src/lang/backend/zh-cn/mall/playxConfig.ts
index fc6fc38..ff5cbce 100644
--- a/web/src/lang/backend/zh-cn/mall/playxConfig.ts
+++ b/web/src/lang/backend/zh-cn/mall/playxConfig.ts
@@ -12,6 +12,7 @@ export default {
calculate_lifetime_btn: '一键计算终身总输赢',
calculate_lifetime_tip: '按各会员最新每日推送中的终身总输赢与上方比例,批量更新待领取积分与领取上限。无终身总输赢数据的会员将跳过。',
calculate_lifetime_confirm: '将按当前终身总输赢兑换比例重新折算全部会员积分,已折算部分会先扣回再按新比例增加。是否继续?',
+ calculate_lifetime_success: '终身总输赢积分折算完成:共处理 {processed} 条,更新 {updated} 条,跳过 {skipped} 条',
section_mall_open: '商城开放日',
mall_open_date: '商城开放日',
mall_open_date_tip: '设置后隔日生效。例如设为 8 月 1 日,则从 8 月 2 日起对业务日期为 8 月 1 日及之后的每日推送执行「昨日净输赢」转积分(T+1:开放日前一日产生的输赢在开放日次日开始折算)。',
diff --git a/web/src/views/backend/mall/dailyPush/index.vue b/web/src/views/backend/mall/dailyPush/index.vue
index 983d077..f38c0b4 100644
--- a/web/src/views/backend/mall/dailyPush/index.vue
+++ b/web/src/views/backend/mall/dailyPush/index.vue
@@ -70,7 +70,9 @@ const baTable = new baTableClass(
label: t('mall.dailyPush.username'),
prop: 'username',
align: 'center',
+ minWidth: 95,
operatorPlaceholder: t('Fuzzy query'),
+ showOverflowTooltip: true,
sortable: false,
operator: 'LIKE',
},
@@ -78,6 +80,7 @@ const baTable = new baTableClass(
label: t('mall.dailyPush.yesterday_win_loss_net'),
prop: 'yesterday_win_loss_net',
align: 'center',
+ minWidth: 90,
operator: 'RANGE',
sortable: 'custom',
},
@@ -85,14 +88,15 @@ const baTable = new baTableClass(
label: t('mall.dailyPush.converted_points'),
prop: 'converted_points',
align: 'center',
+ minWidth: 80,
operator: 'RANGE',
sortable: 'custom',
- width: 100,
},
{
label: t('mall.dailyPush.yesterday_total_deposit'),
prop: 'yesterday_total_deposit',
align: 'center',
+ minWidth: 90,
operator: 'RANGE',
sortable: 'custom',
},
@@ -100,6 +104,7 @@ const baTable = new baTableClass(
label: t('mall.dailyPush.lifetime_total_deposit'),
prop: 'lifetime_total_deposit',
align: 'center',
+ minWidth: 90,
operator: 'RANGE',
sortable: 'custom',
},
@@ -107,7 +112,7 @@ const baTable = new baTableClass(
label: t('mall.dailyPush.lifetime_total_withdraw'),
prop: 'lifetime_total_withdraw',
align: 'center',
- minWidth: 95,
+ minWidth: 90,
operator: 'RANGE',
sortable: 'custom',
},
@@ -115,7 +120,7 @@ const baTable = new baTableClass(
label: t('mall.dailyPush.lifetime_win_loss_net'),
prop: 'lifetime_win_loss_net',
align: 'center',
- minWidth: 95,
+ minWidth: 90,
operator: 'RANGE',
sortable: 'custom',
},
diff --git a/web/src/views/backend/mall/playxConfig/index.vue b/web/src/views/backend/mall/playxConfig/index.vue
index ae95aa5..4838475 100644
--- a/web/src/views/backend/mall/playxConfig/index.vue
+++ b/web/src/views/backend/mall/playxConfig/index.vue
@@ -113,7 +113,7 @@
-
diff --git a/web/src/views/backend/mall/userAsset/index.vue b/web/src/views/backend/mall/userAsset/index.vue
index 2d033a3..1c1bdf2 100644
--- a/web/src/views/backend/mall/userAsset/index.vue
+++ b/web/src/views/backend/mall/userAsset/index.vue
@@ -45,6 +45,7 @@ const baTable = new baTableClass(
prop: 'username',
align: 'center',
operatorPlaceholder: t('Fuzzy query'),
+ showOverflowTooltip: true,
sortable: false,
operator: 'LIKE',
},
@@ -52,7 +53,9 @@ const baTable = new baTableClass(
label: t('mall.userAsset.phone'),
prop: 'phone',
align: 'center',
+ minWidth: 100,
operatorPlaceholder: t('Fuzzy query'),
+ showOverflowTooltip: true,
sortable: false,
operator: 'LIKE',
},
@@ -60,16 +63,59 @@ const baTable = new baTableClass(
label: t('mall.userAsset.playx_user_id'),
prop: 'playx_user_id',
align: 'center',
+ minWidth: 120,
operatorPlaceholder: t('Fuzzy query'),
sortable: false,
operator: 'LIKE',
},
- { label: t('mall.userAsset.locked_points'), prop: 'locked_points', align: 'center', operator: 'RANGE', sortable: false },
- { label: t('mall.userAsset.available_points'), prop: 'available_points', align: 'center', operator: 'RANGE', sortable: false },
- { label: t('mall.userAsset.today_limit'), prop: 'today_limit', align: 'center', operator: 'RANGE', sortable: false },
- { label: t('mall.userAsset.today_claimed'), prop: 'today_claimed', align: 'center', operator: 'RANGE', sortable: false },
- { label: t('mall.userAsset.points_claim_cap'), prop: 'points_claim_cap', align: 'center', operator: 'RANGE', sortable: false },
- { label: t('mall.userAsset.total_points_claimed'), prop: 'total_points_claimed', align: 'center', operator: 'RANGE', sortable: false },
+ {
+ label: t('mall.userAsset.locked_points'),
+ prop: 'locked_points',
+ align: 'center',
+ minWidth: 120,
+ operator: 'RANGE',
+ sortable: true,
+ },
+ {
+ label: t('mall.userAsset.available_points'),
+ prop: 'available_points',
+ align: 'center',
+ minWidth: 120,
+ operator: 'RANGE',
+ sortable: true,
+ },
+ {
+ label: t('mall.userAsset.today_limit'),
+ prop: 'today_limit',
+ align: 'center',
+ minWidth: 160,
+ operator: 'RANGE',
+ sortable: true,
+ },
+ {
+ label: t('mall.userAsset.today_claimed'),
+ prop: 'today_claimed',
+ align: 'center',
+ minWidth: 120,
+ operator: 'RANGE',
+ sortable: true,
+ },
+ {
+ label: t('mall.userAsset.points_claim_cap'),
+ prop: 'points_claim_cap',
+ align: 'center',
+ minWidth: 160,
+ operator: 'RANGE',
+ sortable: true,
+ },
+ {
+ label: t('mall.userAsset.total_points_claimed'),
+ prop: 'total_points_claimed',
+ align: 'center',
+ minWidth: 160,
+ operator: 'RANGE',
+ sortable: true,
+ },
{
label: t('mall.userAsset.today_limit_date'),
prop: 'today_limit_date',