1.新增马来语ms,修改有商品管理和所有接口返回

This commit is contained in:
2026-04-21 14:30:15 +08:00
parent 3ac825f15d
commit 7b9187fb62
11 changed files with 501 additions and 59 deletions

View File

@@ -620,7 +620,12 @@ class Playx extends Api
}
$list = $query->order('sort', 'asc')->select();
return $this->success('', ['list' => $list->toArray()]);
$out = [];
foreach ($list->toArray() as $row) {
$out[] = $this->applyMallItemLocaleForApi($row);
}
return $this->success('', ['list' => $out]);
}
/**
@@ -676,7 +681,15 @@ class Playx extends Api
->limit(100)
->select();
return $this->success('', ['list' => $list->toArray()]);
$arr = $list->toArray();
foreach ($arr as &$orderRow) {
if (isset($orderRow['mallItem']) && is_array($orderRow['mallItem'])) {
$orderRow['mallItem'] = $this->applyMallItemLocaleForApi($orderRow['mallItem']);
}
}
unset($orderRow);
return $this->success('', ['list' => $arr]);
}
/**
@@ -877,6 +890,18 @@ SQL;
}
}
$itemsMap = $this->buildMallItemLocaleMapForPointsLog($list);
foreach ($list as &$row) {
$id = (int)($row['item_id'] ?? 0);
if ($id > 0 && isset($itemsMap[$id])) {
$row['item_title'] = $itemsMap[$id]['title'];
if (isset($row['mallItem']) && is_array($row['mallItem'])) {
$row['mallItem']['title'] = $itemsMap[$id]['title'];
}
}
}
unset($row);
return $this->success('', [
'list' => $list,
'next_cursor' => $nextCursor,
@@ -1306,6 +1331,75 @@ SQL;
]);
}
private function getApiLocale(): string
{
if (function_exists('locale')) {
$l = locale();
if (is_string($l) && $l !== '') {
return $l;
}
}
return 'zh-cn';
}
/**
* @param array<string,mixed> $item MallItem 行(可含 title_en/title_ms 与 description_en/description_ms
* @return array<string,mixed>
*/
private function applyMallItemLocaleForApi(array $item): array
{
$lang = $this->getApiLocale();
if ($lang === 'en') {
$te = trim((string)($item['title_en'] ?? ''));
$de = trim((string)($item['description_en'] ?? ''));
if ($te !== '') {
$item['title'] = $te;
}
if ($de !== '') {
$item['description'] = $de;
}
} elseif ($lang === 'ms') {
$tm = trim((string)($item['title_ms'] ?? ''));
$dm = trim((string)($item['description_ms'] ?? ''));
if ($tm !== '') {
$item['title'] = $tm;
}
if ($dm !== '') {
$item['description'] = $dm;
}
}
unset($item['title_en'], $item['description_en'], $item['title_ms'], $item['description_ms']);
return $item;
}
/**
* @param list<array<string,mixed>> $list pointsLogs 已组装的列表
* @return array<int,array<string,mixed>> id => item 行(已本地化并去掉 *_ms
*/
private function buildMallItemLocaleMapForPointsLog(array $list): array
{
$ids = [];
foreach ($list as $row) {
$id = (int)($row['item_id'] ?? 0);
if ($id > 0) {
$ids[$id] = true;
}
}
if ($ids === []) {
return [];
}
$idList = array_keys($ids);
$map = [];
$models = MallItem::whereIn('id', $idList)->select();
foreach ($models as $model) {
$map[intval($model->id)] = $this->applyMallItemLocaleForApi($model->toArray());
}
return $map;
}
private function callPlayxBonusGrant(MallOrder $order, MallItem $item, string $userId): void
{
$baseUrl = rtrim(config('playx.api.base_url', ''), '/');

View File

@@ -1,57 +1,87 @@
<?php
/**
* API root language pack (English). Keys must match zh-cn.php / ms.php.
*/
return [
'Login expired, please login again.' => 'Login expired, please login again.',
'Account not exist' => 'Account does not exist',
'Account disabled' => 'Account is disabled',
'Token login failed' => 'Token login failed',
'Please try again after 1 day' => 'The number of failed login attempts has exceeded the limit, please try again after 24 hours.',
'Password is incorrect' => 'Incorrect password',
'You are not logged in' => 'You are not logged in.',
'Unknown operation' => 'Unknown operation',
'No action available, please contact the administrator~' => 'There is no action available, please contact the administrator~',
'Please login first' => 'Please login first',
'You have no permission' => 'No permission to operate',
'Captcha error' => 'Captcha error!',
'Parameter %s can not be empty' => 'Parameter %s can not be empty',
'Parameter signature/secret/agent_id/time can not be empty' => 'Parameter signature/secret/agent_id/time can not be empty',
'Invalid timestamp' => 'Invalid timestamp',
'Timestamp expired' => 'Timestamp expired',
'Invalid agent or secret' => 'Invalid agent or secret',
'Invalid signature' => 'Invalid signature',
'Agent not found' => 'Agent not found',
'Temp login is disabled' => 'Temp login is disabled',
'Failed to create temp account' => 'Failed to allocate a unique phone number, please retry later',
'Parameter username can not be empty' => 'Parameter username can not be empty',
'Token expiration' => 'Session expired, please login again.',
// Member center account
'Data updated successfully~' => 'Data updated successfully~',
'Password has been changed~' => 'Password has been changed~',
'Password has been changed, please login again~' => 'Password has been changed, please login again~',
'already exists' => 'already exists',
'nicknameChsDash' => 'Usernames can only be Chinese characters, letters, numbers, underscores_ and dashes-.',
// PlayX API v1 /api/v1/*
'Invalid token' => 'Invalid or expired token',
'PlayX API not configured' => 'PlayX API is not configured',
'Duplicate input' => 'Duplicate submission',
'Ok' => 'OK',
'Failed to map playx user to mall user' => 'Failed to map PlayX user to mall user',
'Missing required fields: request_id, date, user_id' => 'Missing required fields: request_id, date, user_id',
'Missing required fields: report_date, member' => 'Missing required fields: report_date, member',
'Missing required fields: member_id' => 'Missing required fields: member_id',
'Daily push signature missing or incomplete' => 'Daily push signature missing or incomplete',
'Daily push signature verification failed' => 'Daily push signature verification failed',
'Failed to ensure PlayX user asset' => 'Failed to ensure PlayX user asset',
'claim_request_id and user_id/session_id required' => 'claim_request_id and user_id/session_id/token are required',
'User asset not found' => 'User asset not found',
'No points to claim or limit reached' => 'No points to claim or daily limit reached',
'Claim success' => 'Claim successful',
'item_id and user_id/session_id required' => 'item_id and user_id/session_id/token are required',
'Item not found or not available' => 'Item not found or not available',
'Insufficient points' => 'Insufficient points',
'Redeem submitted, please wait about 10 minutes' => 'Redeem submitted, please wait about 10 minutes',
'Missing required fields' => 'Missing required fields',
'Shipping address not found' => 'Shipping address not found',
'Out of stock' => 'Out of stock',
'Redeem success' => 'Redeem successful',
'Withdraw submitted, please wait about 10 minutes' => 'Withdrawal submitted, please wait about 10 minutes',
];
'%d second%s ago' => '%d second%s ago',
'%d minute%s ago' => '%d minute%s ago',
'%d hour%s ago' => '%d hour%s ago',
'%d day%s ago' => '%d day%s ago',
'%d week%s ago' => '%d week%s ago',
'%d month%s ago' => '%d month%s ago',
'%d year%s ago' => '%d year%s ago',
'%d second%s after' => '%d second%s later',
'%d minute%s after' => '%d minute%s later',
'%d hour%s after' => '%d hour%s later',
'%d day%s after' => '%d day%s later',
'%d week%s after' => '%d week%s later',
'%d month%s after' => '%d month%s later',
'%d year%s after' => '%d year%s later',
'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 not allowed',
'The uploaded image file is not a valid image' => 'The uploaded image is not valid',
'The uploaded file is too large (%sMiB), Maximum file size:%sMiB' => 'The file is too large (%sMiB), maximum: %sMiB',
'No files have been uploaded or the file size exceeds the upload limit of the server' => 'No file uploaded or size exceeds server limit',
'Topic format error' => 'Storage topic format error',
'Driver %s not supported' => 'Driver not supported: %s',
'Username' => 'Username',
'Email' => 'Email',
'Mobile' => 'Mobile',
'Password' => 'Password',
'Login expired, please login again.' => 'Login expired, please login again.',
'Account not exist' => 'Account does not exist',
'Account disabled' => 'Account is disabled',
'Token login failed' => 'Token login failed',
'Please try again after 1 day' => 'Too many failed attempts, please try again after 24 hours',
'Password is incorrect' => 'Incorrect password',
'You are not logged in' => 'You are not logged in',
'Unknown operation' => 'Unknown operation',
'No action available, please contact the administrator~' => 'No action available, please contact the administrator~',
'Please login first' => 'Please login first!',
'You have no permission' => 'No permission!',
'Parameter error' => 'Parameter error!',
'Parameter %s can not be empty' => 'Parameter %s cannot be empty',
'Parameter signature/secret/agent_id/time can not be empty' => 'Parameter signature/secret/agent_id/time cannot be empty',
'Invalid timestamp' => 'Invalid timestamp',
'Timestamp expired' => 'Timestamp expired',
'Invalid agent or secret' => 'Invalid agent or secret',
'Invalid signature' => 'Invalid signature',
'Agent not found' => 'Agent not found',
'Temp login is disabled' => 'Temporary login is disabled',
'Failed to create temp account' => 'Failed to create temporary account, please retry',
'Parameter username can not be empty' => 'Parameter username cannot be empty',
'Token expiration' => 'Session expired, please login again.',
'Captcha error' => 'Captcha error!',
'Data updated successfully~' => 'Profile updated successfully~',
'Password has been changed~' => 'Password has been changed~',
'Password has been changed, please login again~' => 'Password changed, please login again~',
'already exists' => 'already exists',
'nicknameChsDash' => 'Username may only contain letters, numbers, underscores and dashes',
'Invalid token' => 'Invalid or expired token',
'PlayX API not configured' => 'PlayX API is not configured',
'Duplicate input' => 'Duplicate submission',
'Ok' => 'OK',
'Failed to map playx user to mall user' => 'Failed to map PlayX user to mall user',
'Missing required fields: request_id, date, user_id' => 'Missing required fields: request_id, date, user_id',
'Missing required fields: report_date, member' => 'Missing required fields: report_date, member',
'Missing required fields: member_id' => 'Missing required fields: member_id',
'Daily push signature missing or incomplete' => 'Daily push signature missing or incomplete',
'Daily push signature verification failed' => 'Daily push signature verification failed',
'Failed to ensure PlayX user asset' => 'Failed to ensure PlayX user asset',
'claim_request_id and user_id/session_id required' => 'claim_request_id and user_id/session_id/token are required',
'User asset not found' => 'User asset not found',
'No points to claim or limit reached' => 'No points to claim or daily limit reached',
'Claim success' => 'Claim successful',
'item_id and user_id/session_id required' => 'item_id and user_id/session_id/token are required',
'Item not found or not available' => 'Item not found or not available',
'Insufficient points' => 'Insufficient points',
'Redeem submitted, please wait about 10 minutes' => 'Redeem submitted, please wait about 10 minutes',
'Missing required fields' => 'Missing required fields',
'Out of stock' => 'Out of stock',
'Record not found' => 'Record not found',
'Shipping address not found' => 'Shipping address not found',
'Redeem success' => 'Redeem successful',
'Withdraw submitted, please wait about 10 minutes' => 'Withdrawal submitted, please wait about 10 minutes',
];

88
app/api/lang/ms.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
/**
* API 根级语言包(马来语 Bahasa Malaysia
* 键名与 zh-cn.php / en.php 保持一致,供 __() 使用。
*/
return [
'%d second%s ago' => '%d saat yang lalu',
'%d minute%s ago' => '%d minit yang lalu',
'%d hour%s ago' => '%d jam yang lalu',
'%d day%s ago' => '%d hari yang lalu',
'%d week%s ago' => '%d minggu yang lalu',
'%d month%s ago' => '%d bulan yang lalu',
'%d year%s ago' => '%d tahun yang lalu',
'%d second%s after' => '%d saat lagi',
'%d minute%s after' => '%d minit lagi',
'%d hour%s after' => '%d jam lagi',
'%d day%s after' => '%d hari lagi',
'%d week%s after' => '%d minggu lagi',
'%d month%s after' => '%d bulan lagi',
'%d year%s after' => '%d tahun lagi',
'File uploaded successfully' => 'Fail berjaya dimuat naik!',
'No files were uploaded' => 'Tiada fail dimuat naik',
'The uploaded file format is not allowed' => 'Format fail yang dimuat naik tidak dibenarkan',
'The uploaded image file is not a valid image' => 'Fail imej yang dimuat naik tidak sah',
'The uploaded file is too large (%sMiB), Maximum file size:%sMiB' => 'Fail terlalu besar (%sM), saiz maksimum: %sM',
'No files have been uploaded or the file size exceeds the upload limit of the server' => 'Tiada fail dimuat naik atau saiz melebihi had pelayan',
'Topic format error' => 'Ralat format topik storan',
'Driver %s not supported' => 'Pemandu tidak disokong: %s',
'Username' => 'Nama pengguna',
'Email' => 'E-mel',
'Mobile' => 'Telefon bimbit',
'Password' => 'Kata laluan',
'Login expired, please login again.' => 'Log masuk tamat tempoh, sila log masuk semula.',
'Account not exist' => 'Akaun tidak wujud',
'Account disabled' => 'Akaun dilumpuhkan',
'Token login failed' => 'Log masuk token gagal',
'Please try again after 1 day' => 'Percubaan gagal terlalu kerap, sila cuba semula selepas 1 hari',
'Password is incorrect' => 'Kata laluan tidak betul',
'You are not logged in' => 'Anda belum log masuk',
'Unknown operation' => 'Operasi tidak diketahui',
'No action available, please contact the administrator~' => 'Tiada tindakan tersedia, sila hubungi pentadbir~',
'Please login first' => 'Sila log masuk dahulu!',
'You have no permission' => 'Tiada kebenaran!',
'Parameter error' => 'Ralat parameter!',
'Parameter %s can not be empty' => 'Parameter %s tidak boleh kosong',
'Parameter signature/secret/agent_id/time can not be empty' => 'Parameter signature/secret/agent_id/time tidak boleh kosong',
'Invalid timestamp' => 'Cap masa tidak sah',
'Timestamp expired' => 'Cap masa tamat tempoh',
'Invalid agent or secret' => 'Ejen atau rahsia tidak sah',
'Invalid signature' => 'Tandatangan tidak sah',
'Agent not found' => 'Ejen tidak dijumpai',
'Temp login is disabled' => 'Log masuk sementara dilumpuhkan',
'Failed to create temp account' => 'Gagal mencipta akaun sementara, sila cuba lagi',
'Parameter username can not be empty' => 'Parameter username tidak boleh kosong',
'Token expiration' => 'Sesi tamat, sila log masuk semula!',
'Captcha error' => 'Ralat captcha!',
'Data updated successfully~' => 'Data berjaya dikemas kini~',
'Password has been changed~' => 'Kata laluan telah ditukar~',
'Password has been changed, please login again~' => 'Kata laluan ditukar, sila log masuk semula~',
'already exists' => 'sudah wujud',
'nicknameChsDash' => 'Nama pengguna hanya huruf, nombor, garis bawah dan sempang',
'Invalid token' => 'Token tidak sah atau tamat tempoh',
'PlayX API not configured' => 'API PlayX tidak dikonfigurasi',
'Duplicate input' => 'Penghantaran pendua',
'Ok' => 'OK',
'Failed to map playx user to mall user' => 'Gagal memetakan pengguna PlayX ke pengguna mall',
'Missing required fields: request_id, date, user_id' => 'Medan wajib tiada: request_id, date, user_id',
'Missing required fields: report_date, member' => 'Medan wajib tiada: report_date, member',
'Missing required fields: member_id' => 'Medan wajib tiada: member_id',
'Daily push signature missing or incomplete' => 'Tandatangan push harian tiada atau tidak lengkap',
'Daily push signature verification failed' => 'Pengesahan tandatangan push harian gagal',
'Failed to ensure PlayX user asset' => 'Gagal mencipta/memeta aset pengguna',
'claim_request_id and user_id/session_id required' => 'claim_request_id dan user_id/session_id/token diperlukan',
'User asset not found' => 'Aset pengguna tidak dijumpai',
'No points to claim or limit reached' => 'Tiada mata untuk dituntut atau had harian dicapai',
'Claim success' => 'Tuntutan berjaya',
'item_id and user_id/session_id required' => 'item_id dan user_id/session_id/token diperlukan',
'Item not found or not available' => 'Item tidak dijumpai atau tidak tersedia',
'Insufficient points' => 'Mata tidak mencukupi',
'Redeem submitted, please wait about 10 minutes' => 'Penebusan dihantar, sila tunggu kira-kira 10 minit',
'Missing required fields' => 'Medan wajib tiada',
'Out of stock' => 'Stok tidak mencukupi',
'Record not found' => 'Rekod tidak dijumpai',
'Shipping address not found' => 'Alamat penghantaran tidak dijumpai',
'Redeem success' => 'Penebusan berjaya',
'Withdraw submitted, please wait about 10 minutes' => 'Permohonan pengeluaran dihantar, sila tunggu kira-kira 10 minit',
];