1.新增商城参数配置菜单-管理兑换比例
This commit is contained in:
@@ -18,6 +18,7 @@ DATABASE_CHARSET = utf8mb4
|
|||||||
DATABASE_PREFIX =
|
DATABASE_PREFIX =
|
||||||
|
|
||||||
# PlayX 配置
|
# PlayX 配置
|
||||||
|
# 以下三项比例以数据库表 mall_config 为准(后台 积分商城 → 商城参数配置);未迁移或无记录时回退为下列 env 默认值
|
||||||
# 提现折算:积分 -> 现金(如 10 分 = 1 元,则 points_to_cash_ratio=0.1)
|
# 提现折算:积分 -> 现金(如 10 分 = 1 元,则 points_to_cash_ratio=0.1)
|
||||||
PLAYX_POINTS_TO_CASH_RATIO=0.1
|
PLAYX_POINTS_TO_CASH_RATIO=0.1
|
||||||
# 返还比例:新增保障金 = ABS(yesterday_win_loss_net) * return_ratio(仅亏损时)
|
# 返还比例:新增保障金 = ABS(yesterday_win_loss_net) * return_ratio(仅亏损时)
|
||||||
|
|||||||
91
app/admin/controller/mall/PlayxConfig.php
Normal file
91
app/admin/controller/mall/PlayxConfig.php
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\admin\controller\mall;
|
||||||
|
|
||||||
|
use app\common\controller\Backend;
|
||||||
|
use app\common\library\MallPlayxRatios;
|
||||||
|
use app\common\model\MallConfig;
|
||||||
|
use support\Response;
|
||||||
|
use Webman\Http\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分商城参数(PlayX 比例等)
|
||||||
|
*/
|
||||||
|
class PlayxConfig extends Backend
|
||||||
|
{
|
||||||
|
public function index(Request $request): Response
|
||||||
|
{
|
||||||
|
$response = $this->initializeBackend($request);
|
||||||
|
if ($response !== null) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = MallConfig::order('id', 'asc')->find();
|
||||||
|
if (!$row) {
|
||||||
|
$now = time();
|
||||||
|
MallConfig::create([
|
||||||
|
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
||||||
|
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_RATIO', '0.1')),
|
||||||
|
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
|
||||||
|
'create_time' => $now,
|
||||||
|
'update_time' => $now,
|
||||||
|
]);
|
||||||
|
$row = MallConfig::order('id', 'asc')->find();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success('', [
|
||||||
|
'row' => $row ? $row->toArray() : [],
|
||||||
|
'remark' => get_route_remark(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(Request $request): Response
|
||||||
|
{
|
||||||
|
$response = $this->initializeBackend($request);
|
||||||
|
if ($response !== null) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $request->post();
|
||||||
|
if (empty($data) || !is_array($data)) {
|
||||||
|
return $this->error(__('Parameter %s can not be empty', ['']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = $data['return_ratio'] ?? null;
|
||||||
|
$unlock = $data['unlock_ratio'] ?? null;
|
||||||
|
$cash = $data['points_to_cash_ratio'] ?? null;
|
||||||
|
if (!is_numeric($return) || !is_numeric($unlock) || !is_numeric($cash)) {
|
||||||
|
return $this->error(__('Parameter error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$returnF = floatval($return);
|
||||||
|
$unlockF = floatval($unlock);
|
||||||
|
$cashF = floatval($cash);
|
||||||
|
if ($returnF < 0 || $unlockF < 0 || $cashF < 0) {
|
||||||
|
return $this->error(__('Parameter error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = MallConfig::order('id', 'asc')->find();
|
||||||
|
if (!$row) {
|
||||||
|
$now = time();
|
||||||
|
MallConfig::create([
|
||||||
|
'return_ratio' => $returnF,
|
||||||
|
'unlock_ratio' => $unlockF,
|
||||||
|
'points_to_cash_ratio' => $cashF,
|
||||||
|
'create_time' => $now,
|
||||||
|
'update_time' => $now,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$row->return_ratio = $returnF;
|
||||||
|
$row->unlock_ratio = $unlockF;
|
||||||
|
$row->points_to_cash_ratio = $cashF;
|
||||||
|
$row->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
MallPlayxRatios::forget();
|
||||||
|
|
||||||
|
return $this->success(__('The current page configuration item was updated successfully'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ use app\common\model\MallDailyPush;
|
|||||||
use app\common\model\MallSession;
|
use app\common\model\MallSession;
|
||||||
use app\common\model\MallOrder;
|
use app\common\model\MallOrder;
|
||||||
use app\common\model\MallUserAsset;
|
use app\common\model\MallUserAsset;
|
||||||
|
use app\common\library\MallPlayxRatios;
|
||||||
use app\common\model\MallAddress;
|
use app\common\model\MallAddress;
|
||||||
use support\think\Db;
|
use support\think\Db;
|
||||||
use Webman\Http\Request;
|
use Webman\Http\Request;
|
||||||
@@ -231,8 +232,9 @@ class Playx extends Api
|
|||||||
$requestId = 'report_' . $date;
|
$requestId = 'report_' . $date;
|
||||||
}
|
}
|
||||||
|
|
||||||
$returnRatio = config('playx.return_ratio', 0.1);
|
$ratios = MallPlayxRatios::get();
|
||||||
$unlockRatio = config('playx.unlock_ratio', 0.1);
|
$returnRatio = $ratios['return_ratio'];
|
||||||
|
$unlockRatio = $ratios['unlock_ratio'];
|
||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
$allDeduped = true;
|
$allDeduped = true;
|
||||||
@@ -332,8 +334,9 @@ class Playx extends Api
|
|||||||
$exists = MallDailyPush::where('user_id', $playxUserId)->where('date', $date)->find();
|
$exists = MallDailyPush::where('user_id', $playxUserId)->where('date', $date)->find();
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
$newLocked = 0;
|
$newLocked = 0;
|
||||||
$returnRatio = config('playx.return_ratio', 0.1);
|
$ratios = MallPlayxRatios::get();
|
||||||
$unlockRatio = config('playx.unlock_ratio', 0.1);
|
$returnRatio = $ratios['return_ratio'];
|
||||||
|
$unlockRatio = $ratios['unlock_ratio'];
|
||||||
if ($yesterdayWinLossNet < 0) {
|
if ($yesterdayWinLossNet < 0) {
|
||||||
$newLocked = intval(round(abs(floatval($yesterdayWinLossNet)) * $returnRatio));
|
$newLocked = intval(round(abs(floatval($yesterdayWinLossNet)) * $returnRatio));
|
||||||
}
|
}
|
||||||
@@ -365,8 +368,9 @@ class Playx extends Api
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$newLocked = 0;
|
$newLocked = 0;
|
||||||
$returnRatio = config('playx.return_ratio', 0.1);
|
$ratios = MallPlayxRatios::get();
|
||||||
$unlockRatio = config('playx.unlock_ratio', 0.1);
|
$returnRatio = $ratios['return_ratio'];
|
||||||
|
$unlockRatio = $ratios['unlock_ratio'];
|
||||||
if ($yesterdayWinLossNet < 0) {
|
if ($yesterdayWinLossNet < 0) {
|
||||||
$newLocked = intval(round(abs(floatval($yesterdayWinLossNet)) * $returnRatio));
|
$newLocked = intval(round(abs(floatval($yesterdayWinLossNet)) * $returnRatio));
|
||||||
}
|
}
|
||||||
@@ -668,7 +672,7 @@ class Playx extends Api
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ratio = config('playx.points_to_cash_ratio', 0.1);
|
$ratio = MallPlayxRatios::get()['points_to_cash_ratio'];
|
||||||
$withdrawableCash = round($asset->available_points * $ratio, 2);
|
$withdrawableCash = round($asset->available_points * $ratio, 2);
|
||||||
|
|
||||||
return $this->success('', [
|
return $this->success('', [
|
||||||
@@ -1257,7 +1261,7 @@ SQL;
|
|||||||
'withdrawable_cash' => 0,
|
'withdrawable_cash' => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$ratio = config('playx.points_to_cash_ratio', 0.1);
|
$ratio = MallPlayxRatios::get()['points_to_cash_ratio'];
|
||||||
return [
|
return [
|
||||||
'locked_points' => $asset->locked_points,
|
'locked_points' => $asset->locked_points,
|
||||||
'available_points' => $asset->available_points,
|
'available_points' => $asset->available_points,
|
||||||
|
|||||||
58
app/common/library/MallPlayxRatios.php
Normal file
58
app/common/library/MallPlayxRatios.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\common\library;
|
||||||
|
|
||||||
|
use app\common\model\MallConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PlayX 与积分商城相关的比例配置:优先读 mall_config,无表记录时回退 .env
|
||||||
|
*/
|
||||||
|
final class MallPlayxRatios
|
||||||
|
{
|
||||||
|
private static ?array $cache = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{return_ratio: float, unlock_ratio: float, points_to_cash_ratio: float}
|
||||||
|
*/
|
||||||
|
public static function get(): array
|
||||||
|
{
|
||||||
|
if (self::$cache !== null) {
|
||||||
|
return self::$cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = MallConfig::order('id', 'asc')->find();
|
||||||
|
if ($row) {
|
||||||
|
self::$cache = [
|
||||||
|
'return_ratio' => self::toFloat($row->return_ratio),
|
||||||
|
'unlock_ratio' => self::toFloat($row->unlock_ratio),
|
||||||
|
'points_to_cash_ratio' => self::toFloat($row->points_to_cash_ratio),
|
||||||
|
];
|
||||||
|
|
||||||
|
return self::$cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$cache = [
|
||||||
|
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
||||||
|
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_RATIO', '0.1')),
|
||||||
|
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
|
||||||
|
];
|
||||||
|
|
||||||
|
return self::$cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function forget(): void
|
||||||
|
{
|
||||||
|
self::$cache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function toFloat(mixed $v): float
|
||||||
|
{
|
||||||
|
if (is_numeric($v)) {
|
||||||
|
return floatval($v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/common/model/MallConfig.php
Normal file
25
app/common/model/MallConfig.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\common\model;
|
||||||
|
|
||||||
|
use support\think\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分商城配置(比例等)
|
||||||
|
*/
|
||||||
|
class MallConfig extends Model
|
||||||
|
{
|
||||||
|
protected string $name = 'mall_config';
|
||||||
|
|
||||||
|
protected bool $autoWriteTimestamp = true;
|
||||||
|
|
||||||
|
protected array $type = [
|
||||||
|
'create_time' => 'integer',
|
||||||
|
'update_time' => 'integer',
|
||||||
|
'return_ratio' => 'float',
|
||||||
|
'unlock_ratio' => 'float',
|
||||||
|
'points_to_cash_ratio' => 'float',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -4,11 +4,12 @@
|
|||||||
* PlayX 积分商城对接配置
|
* PlayX 积分商城对接配置
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
// 返还比例:新增保障金 = ABS(yesterday_win_loss_net) * 返还比例(仅亏损时)
|
/**
|
||||||
|
* 以下三项比例以数据表 mall_config 为准(后台「商城参数配置」)。
|
||||||
|
* 此处保留 env 仅作兼容/文档默认值;业务代码请使用 MallPlayxRatios::get()。
|
||||||
|
*/
|
||||||
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
'return_ratio' => floatval(env('PLAYX_RETURN_RATIO', '0.1')),
|
||||||
// 解锁比例:今日可领取上限 = yesterday_total_deposit * 解锁比例
|
|
||||||
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_RATIO', '0.1')),
|
'unlock_ratio' => floatval(env('PLAYX_UNLOCK_RATIO', '0.1')),
|
||||||
// 提现折算:积分 → 现金(如 10 分 = 1 元)
|
|
||||||
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
|
'points_to_cash_ratio' => floatval(env('PLAYX_POINTS_TO_CASH_RATIO', '0.1')),
|
||||||
// Daily Push 签名校验(PlayX 调用商城时使用)
|
// Daily Push 签名校验(PlayX 调用商城时使用)
|
||||||
'daily_push_secret' => strval(env('PLAYX_DAILY_PUSH_SECRET', '')),
|
'daily_push_secret' => strval(env('PLAYX_DAILY_PUSH_SECRET', '')),
|
||||||
|
|||||||
@@ -217,6 +217,10 @@ Route::post('/admin/user/moneyLog/add', [\app\admin\controller\user\MoneyLog::cl
|
|||||||
// admin/mall/dailyPush
|
// admin/mall/dailyPush
|
||||||
Route::post('/admin/mall/dailyPush/backfillUsers', [\app\admin\controller\mall\DailyPush::class, 'backfillUsers']);
|
Route::post('/admin/mall/dailyPush/backfillUsers', [\app\admin\controller\mall\DailyPush::class, 'backfillUsers']);
|
||||||
|
|
||||||
|
// admin/mall/playxConfig(积分商城参数)
|
||||||
|
Route::get('/admin/mall.PlayxConfig/index', [\app\admin\controller\mall\PlayxConfig::class, 'index']);
|
||||||
|
Route::post('/admin/mall.PlayxConfig/save', [\app\admin\controller\mall\PlayxConfig::class, 'save']);
|
||||||
|
|
||||||
// admin/routine/config
|
// admin/routine/config
|
||||||
Route::get('/admin/routine/config/index', [\app\admin\controller\routine\Config::class, 'index']);
|
Route::get('/admin/routine/config/index', [\app\admin\controller\routine\Config::class, 'index']);
|
||||||
Route::post('/admin/routine/config/edit', [\app\admin\controller\routine\Config::class, 'edit']);
|
Route::post('/admin/routine/config/edit', [\app\admin\controller\routine\Config::class, 'edit']);
|
||||||
|
|||||||
28
web/src/api/backend/mall/playxConfig.ts
Normal file
28
web/src/api/backend/mall/playxConfig.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import createAxios from '/@/utils/axios'
|
||||||
|
|
||||||
|
export const url = '/admin/mall.PlayxConfig/'
|
||||||
|
|
||||||
|
export const actionUrl = new Map([
|
||||||
|
['index', url + 'index'],
|
||||||
|
['save', url + 'save'],
|
||||||
|
])
|
||||||
|
|
||||||
|
export function index() {
|
||||||
|
return createAxios({
|
||||||
|
url: actionUrl.get('index'),
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function save(data: anyObj) {
|
||||||
|
return createAxios(
|
||||||
|
{
|
||||||
|
url: actionUrl.get('save'),
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showSuccessMessage: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
33
web/src/components/mall/MallPageIntro.vue
Normal file
33
web/src/components/mall/MallPageIntro.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<el-alert class="ba-table-alert mall-page-intro" type="info" show-icon :closable="false">
|
||||||
|
<template #title>{{ title }}</template>
|
||||||
|
<div class="mall-page-intro__desc">{{ desc }}</div>
|
||||||
|
</el-alert>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
/** 与 mall.pageIntro.<pageKey> 对应,如 dailyPush、userAsset */
|
||||||
|
pageKey: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const title = computed(() => t(`mall.pageIntro.${props.pageKey}.title`))
|
||||||
|
const desc = computed(() => t(`mall.pageIntro.${props.pageKey}.desc`))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.mall-page-intro {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.mall-page-intro__desc {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
id: 'id',
|
id: 'ID',
|
||||||
user_id: 'user_id',
|
user_id: 'PlayX user ID',
|
||||||
date: 'date',
|
date: 'Business date',
|
||||||
username: 'username',
|
username: 'Username',
|
||||||
yesterday_win_loss_net: 'yesterday_win_loss_net',
|
yesterday_win_loss_net: 'Yesterday net win/loss',
|
||||||
yesterday_total_deposit: 'yesterday_total_deposit',
|
yesterday_total_deposit: 'Yesterday total deposit',
|
||||||
lifetime_total_deposit: 'lifetime_total_deposit',
|
lifetime_total_deposit: 'Lifetime total deposit',
|
||||||
lifetime_total_withdraw: 'lifetime_total_withdraw',
|
lifetime_total_withdraw: 'Lifetime total withdraw',
|
||||||
create_time: 'create_time',
|
create_time: 'Created at',
|
||||||
'quick Search Fields': 'id',
|
'quick Search Fields': 'ID',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
58
web/src/lang/backend/en/mall/pageIntro.ts
Normal file
58
web/src/lang/backend/en/mall/pageIntro.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
export default {
|
||||||
|
userAsset: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'Manage mall user asset records, including PlayX binding and points fields used for claims and redemptions.',
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'View and manage user shipping addresses for physical orders.',
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'Central list of mall orders (approval, shipping, points changes) with search and admin actions.',
|
||||||
|
},
|
||||||
|
dailyPush: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'Daily T+1 snapshots pushed by the partner; rows are stored here and drive user-asset related updates.',
|
||||||
|
},
|
||||||
|
claimLog: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'History of users moving points from locked/pending to available, filterable by time and user.',
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'Manage catalog items, stock, and multilingual display text for the points mall.',
|
||||||
|
},
|
||||||
|
pintsOrder: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'Orders paid with points—use for redemption and fulfillment checks.',
|
||||||
|
},
|
||||||
|
redemptionOrder: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'Redemption-style orders (e.g. bonus payouts) for issuance and reconciliation.',
|
||||||
|
},
|
||||||
|
playxCenter: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'PlayX hub: orders, daily push, claim logs, and user assets in one place for integration and troubleshooting.',
|
||||||
|
},
|
||||||
|
playxOrder: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'PlayX-facing order list for cross-checking with the mall.',
|
||||||
|
},
|
||||||
|
playxDailyPush: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'PlayX daily push rows in admin (compare with the standalone Daily push menu when sources align).',
|
||||||
|
},
|
||||||
|
playxClaimLog: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'PlayX users’ claim history on the mall side for amount and frequency checks.',
|
||||||
|
},
|
||||||
|
playxUserAsset: {
|
||||||
|
title: 'About this page',
|
||||||
|
desc: 'PlayX user assets in list form—cross-check with the main User assets screen when needed.',
|
||||||
|
},
|
||||||
|
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_config and apply immediately after save.',
|
||||||
|
},
|
||||||
|
}
|
||||||
8
web/src/lang/backend/en/mall/playxConfig.ts
Normal file
8
web/src/lang/backend/en/mall/playxConfig.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default {
|
||||||
|
return_ratio: 'Return ratio (return_ratio)',
|
||||||
|
return_ratio_tip: 'In daily push, when yesterday net win/loss is negative: locked increment = |net| × this ratio.',
|
||||||
|
unlock_ratio: 'Unlock ratio (unlock_ratio)',
|
||||||
|
unlock_ratio_tip: 'In daily push: daily claim cap = yesterday total deposit × this ratio.',
|
||||||
|
points_to_cash_ratio: 'Points to cash ratio',
|
||||||
|
points_to_cash_ratio_tip: 'For withdrawable cash display: cash ≈ available points × this ratio.',
|
||||||
|
}
|
||||||
@@ -115,5 +115,8 @@ export default {
|
|||||||
mall_playxUserAsset: 'playX user assets',
|
mall_playxUserAsset: 'playX user assets',
|
||||||
mall_pintsOrder: 'Points orders',
|
mall_pintsOrder: 'Points orders',
|
||||||
mall_redemptionOrder: 'Redemption orders',
|
mall_redemptionOrder: 'Redemption orders',
|
||||||
|
mall_playxConfig: 'Mall parameters',
|
||||||
|
mall_playxConfig_index: 'View',
|
||||||
|
mall_playxConfig_save: 'Save',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
58
web/src/lang/backend/zh-cn/mall/pageIntro.ts
Normal file
58
web/src/lang/backend/zh-cn/mall/pageIntro.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
export default {
|
||||||
|
userAsset: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '维护积分商城用户资产主数据,含 PlayX 用户绑定、积分字段等,用于前台领取与兑换鉴权。',
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '查看与管理用户收货地址,供实物类订单发货使用。',
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '集中查看商城订单(含审核、发货、积分变动等),支持按条件检索与后台操作。',
|
||||||
|
},
|
||||||
|
dailyPush: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '展示合作方 T+1 每日推送的经营数据快照;接口写入后在此留痕,并用于同步用户资产相关字段。',
|
||||||
|
},
|
||||||
|
claimLog: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '用户从待领取积分划转至可用积分的操作流水,可按时间与用户追溯。',
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '维护积分商城上架商品、库存与多语言展示信息。',
|
||||||
|
},
|
||||||
|
pintsOrder: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '以积分支付的订单列表,用于核对兑换与发货状态。',
|
||||||
|
},
|
||||||
|
redemptionOrder: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '兑换类业务订单(如礼金等)列表,用于核对发放与对账。',
|
||||||
|
},
|
||||||
|
playxCenter: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: 'PlayX 相关能力的聚合入口:订单、每日推送、领取记录与用户资产分栏查看,便于联调与排障。',
|
||||||
|
},
|
||||||
|
playxOrder: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '从 PlayX 视角查看与商城关联的订单数据,用于对接核对。',
|
||||||
|
},
|
||||||
|
playxDailyPush: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: 'PlayX 每日推送记录在后台的列表视图(与独立「每日推送」菜单数据源一致时可对照查看)。',
|
||||||
|
},
|
||||||
|
playxClaimLog: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: 'PlayX 用户在商城侧的领取流水,用于核对领取额度与频次。',
|
||||||
|
},
|
||||||
|
playxUserAsset: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: 'PlayX 用户资产在后台的列表视图,可与「用户资产」主菜单交叉核对。',
|
||||||
|
},
|
||||||
|
playxConfig: {
|
||||||
|
title: '页面说明',
|
||||||
|
desc: '配置每日推送用到的返还比例、解锁比例及积分折算现金比例;保存后立即作用于接口逻辑(mall_config)。',
|
||||||
|
},
|
||||||
|
}
|
||||||
8
web/src/lang/backend/zh-cn/mall/playxConfig.ts
Normal file
8
web/src/lang/backend/zh-cn/mall/playxConfig.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default {
|
||||||
|
return_ratio: '返还比例(return_ratio)',
|
||||||
|
return_ratio_tip: '每日推送中,仅当昨日净输赢为负时:待领取增量 = |净输赢| × 本比例。',
|
||||||
|
unlock_ratio: '解锁比例(unlock_ratio)',
|
||||||
|
unlock_ratio_tip: '每日推送中:今日可领取上限 = 昨日总充值 × 本比例。',
|
||||||
|
points_to_cash_ratio: '积分折算现金比例',
|
||||||
|
points_to_cash_ratio_tip: '用于资产接口中「可提现现金」等展示:现金 ≈ 可用积分 × 本比例。',
|
||||||
|
}
|
||||||
@@ -116,5 +116,8 @@ export default {
|
|||||||
mall_playxUserAsset: 'playX用户资产',
|
mall_playxUserAsset: 'playX用户资产',
|
||||||
mall_pintsOrder: '积分订单',
|
mall_pintsOrder: '积分订单',
|
||||||
mall_redemptionOrder: '兑换订单',
|
mall_redemptionOrder: '兑换订单',
|
||||||
|
mall_playxConfig: '商城参数配置',
|
||||||
|
mall_playxConfig_index: '查看',
|
||||||
|
mall_playxConfig_save: '保存',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,11 @@ export async function loadLang(app: App) {
|
|||||||
*/
|
*/
|
||||||
if (locale == 'zh-cn') {
|
if (locale == 'zh-cn') {
|
||||||
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./common/zh-cn/**/*.ts', { eager: true }), locale))
|
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./common/zh-cn/**/*.ts', { eager: true }), locale))
|
||||||
|
// 积分商城后台页表格列在 setup 阶段即 t(),若仅依赖路由懒加载会出现列头显示为 key
|
||||||
|
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./backend/zh-cn/mall/**/*.ts', { eager: true }), locale))
|
||||||
} else if (locale == 'en') {
|
} else if (locale == 'en') {
|
||||||
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./common/en/**/*.ts', { eager: true }), locale))
|
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./common/en/**/*.ts', { eager: true }), locale))
|
||||||
|
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./backend/en/mall/**/*.ts', { eager: true }), locale))
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="address" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<!-- 表格顶部菜单 -->
|
<!-- 表格顶部菜单 -->
|
||||||
@@ -25,6 +26,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
import { defaultOptButtons } from '/@/components/table'
|
import { defaultOptButtons } from '/@/components/table'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="claimLog" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="dailyPush" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="item" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<!-- 表格顶部菜单 -->
|
<!-- 表格顶部菜单 -->
|
||||||
@@ -25,6 +26,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
import { defaultOptButtons } from '/@/components/table'
|
import { defaultOptButtons } from '/@/components/table'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="order" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -18,6 +19,7 @@ import { onMounted, provide, useTemplateRef } from 'vue'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
import createAxios from '/@/utils/axios'
|
import createAxios from '/@/utils/axios'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="pintsOrder" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<!-- 表格顶部菜单 -->
|
<!-- 表格顶部菜单 -->
|
||||||
@@ -25,6 +26,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
import { defaultOptButtons } from '/@/components/table'
|
import { defaultOptButtons } from '/@/components/table'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -2,12 +2,7 @@
|
|||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<!-- 语言包注入是异步的:把 t() 调用和子组件渲染都延后到注入完成后,避免 intlify Not found -->
|
<!-- 语言包注入是异步的:把 t() 调用和子组件渲染都延后到注入完成后,避免 intlify Not found -->
|
||||||
<template v-if="langReady">
|
<template v-if="langReady">
|
||||||
<el-card shadow="never" class="mb-4">
|
<MallPageIntro page-key="playxCenter" class="mb-4" />
|
||||||
<template #header>
|
|
||||||
<div class="card-header">{{ t('mall.playxCenter.title') }}</div>
|
|
||||||
</template>
|
|
||||||
<div class="desc">{{ t('mall.playxCenter.desc') }}</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-tabs v-model="activeName" type="border-card">
|
<el-tabs v-model="activeName" type="border-card">
|
||||||
<el-tab-pane :label="t('mall.playxCenter.orders')" name="orders">
|
<el-tab-pane :label="t('mall.playxCenter.orders')" name="orders">
|
||||||
@@ -34,6 +29,7 @@ import PlayxOrderIndex from '/@/views/backend/mall/playxOrder/index.vue'
|
|||||||
import PlayxDailyPushIndex from '/@/views/backend/mall/playxDailyPush/index.vue'
|
import PlayxDailyPushIndex from '/@/views/backend/mall/playxDailyPush/index.vue'
|
||||||
import PlayxClaimLogIndex from '/@/views/backend/mall/playxClaimLog/index.vue'
|
import PlayxClaimLogIndex from '/@/views/backend/mall/playxClaimLog/index.vue'
|
||||||
import PlayxUserAssetIndex from '/@/views/backend/mall/playxUserAsset/index.vue'
|
import PlayxUserAssetIndex from '/@/views/backend/mall/playxUserAsset/index.vue'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import { useConfig } from '/@/stores/config'
|
import { useConfig } from '/@/stores/config'
|
||||||
import { mergeMessage } from '/@/lang/index'
|
import { mergeMessage } from '/@/lang/index'
|
||||||
|
|
||||||
@@ -92,11 +88,5 @@ onMounted(async () => {
|
|||||||
.mb-4 {
|
.mb-4 {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
.card-header {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="playxClaimLog" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
144
web/src/views/backend/mall/playxConfig/index.vue
Normal file
144
web/src/views/backend/mall/playxConfig/index.vue
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="playxConfig" />
|
||||||
|
|
||||||
|
<el-alert class="ba-table-alert" v-if="remark" :title="remark" type="info" show-icon />
|
||||||
|
|
||||||
|
<el-card shadow="never" v-loading="loading">
|
||||||
|
<el-form
|
||||||
|
v-if="!loading"
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
label-position="top"
|
||||||
|
@submit.prevent=""
|
||||||
|
@keyup.enter="onSubmit()"
|
||||||
|
>
|
||||||
|
<el-form-item :label="t('mall.playxConfig.return_ratio')" prop="return_ratio">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.return_ratio"
|
||||||
|
:min="0"
|
||||||
|
:max="100"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
controls-position="right"
|
||||||
|
class="w100"
|
||||||
|
/>
|
||||||
|
<div class="form-tip">{{ t('mall.playxConfig.return_ratio_tip') }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('mall.playxConfig.unlock_ratio')" prop="unlock_ratio">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.unlock_ratio"
|
||||||
|
:min="0"
|
||||||
|
:max="100"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
controls-position="right"
|
||||||
|
class="w100"
|
||||||
|
/>
|
||||||
|
<div class="form-tip">{{ t('mall.playxConfig.unlock_ratio_tip') }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('mall.playxConfig.points_to_cash_ratio')" prop="points_to_cash_ratio">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.points_to_cash_ratio"
|
||||||
|
:min="0"
|
||||||
|
:max="100"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
controls-position="right"
|
||||||
|
class="w100"
|
||||||
|
/>
|
||||||
|
<div class="form-tip">{{ t('mall.playxConfig.points_to_cash_ratio_tip') }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" :loading="submitting" @click="onSubmit()">{{ t('Save') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
|
import { onMounted, reactive, ref, useTemplateRef } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { index, save } from '/@/api/backend/mall/playxConfig'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'mall/playxConfig',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const formRef = useTemplateRef<FormInstance>('formRef')
|
||||||
|
const loading = ref(true)
|
||||||
|
const submitting = ref(false)
|
||||||
|
const remark = ref('')
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
return_ratio: 0.1,
|
||||||
|
unlock_ratio: 0.1,
|
||||||
|
points_to_cash_ratio: 0.1,
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules: FormRules = {
|
||||||
|
return_ratio: [{ required: true, message: t('Please input field', { field: t('mall.playxConfig.return_ratio') }) }],
|
||||||
|
unlock_ratio: [{ required: true, message: t('Please input field', { field: t('mall.playxConfig.unlock_ratio') }) }],
|
||||||
|
points_to_cash_ratio: [{ required: true, message: t('Please input field', { field: t('mall.playxConfig.points_to_cash_ratio') }) }],
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadData = () => {
|
||||||
|
loading.value = true
|
||||||
|
index()
|
||||||
|
.then((res) => {
|
||||||
|
remark.value = res.data.remark ?? ''
|
||||||
|
const row = res.data.row ?? {}
|
||||||
|
if (row.return_ratio !== undefined && row.return_ratio !== null) {
|
||||||
|
form.return_ratio = parseFloat(String(row.return_ratio))
|
||||||
|
}
|
||||||
|
if (row.unlock_ratio !== undefined && row.unlock_ratio !== null) {
|
||||||
|
form.unlock_ratio = parseFloat(String(row.unlock_ratio))
|
||||||
|
}
|
||||||
|
if (row.points_to_cash_ratio !== undefined && row.points_to_cash_ratio !== null) {
|
||||||
|
form.points_to_cash_ratio = parseFloat(String(row.points_to_cash_ratio))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
formRef.value?.validate((valid) => {
|
||||||
|
if (!valid) return
|
||||||
|
submitting.value = true
|
||||||
|
save({
|
||||||
|
return_ratio: form.return_ratio,
|
||||||
|
unlock_ratio: form.unlock_ratio,
|
||||||
|
points_to_cash_ratio: form.points_to_cash_ratio,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
loadData()
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
submitting.value = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.w100 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.form-tip {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="playxDailyPush" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="playxOrder" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import createAxios from '/@/utils/axios'
|
import createAxios from '/@/utils/axios'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="playxUserAsset" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="redemptionOrder" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<!-- 表格顶部菜单 -->
|
<!-- 表格顶部菜单 -->
|
||||||
@@ -25,6 +26,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
import { defaultOptButtons } from '/@/components/table'
|
import { defaultOptButtons } from '/@/components/table'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main ba-table-box">
|
<div class="default-main ba-table-box">
|
||||||
|
<MallPageIntro page-key="userAsset" />
|
||||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||||
|
|
||||||
<TableHeader
|
<TableHeader
|
||||||
@@ -19,6 +20,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { baTableApi } from '/@/api/common'
|
import { baTableApi } from '/@/api/common'
|
||||||
import { defaultOptButtons } from '/@/components/table'
|
import { defaultOptButtons } from '/@/components/table'
|
||||||
|
import MallPageIntro from '/@/components/mall/MallPageIntro.vue'
|
||||||
import TableHeader from '/@/components/table/header/index.vue'
|
import TableHeader from '/@/components/table/header/index.vue'
|
||||||
import Table from '/@/components/table/index.vue'
|
import Table from '/@/components/table/index.vue'
|
||||||
import baTableClass from '/@/utils/baTable'
|
import baTableClass from '/@/utils/baTable'
|
||||||
|
|||||||
Reference in New Issue
Block a user