Browse Source

Merge remote-tracking branch 'origin/milestone-20251209-多语言二期' into milestone-20251209-多语言二期

# Conflicts:
#	src/components/locales/lang/en.js
#	src/components/locales/lang/zh-CN.js
milestone-20251209-多语言二期
huangqizhen 3 months ago
parent
commit
926e8c99ce
  1. 8
      src/components/MoneyManage/CurrencySelect.vue
  2. 135
      src/components/MoneyManage/ProductSelect.vue
  3. 289
      src/components/locales/lang/en.js
  4. 1280
      src/components/locales/lang/zh-CN.js
  5. 46
      src/components/workspace/CashManagement.vue
  6. 73
      src/components/workspace/GoldGraph.vue
  7. 57
      src/components/workspace/GoldGraphMarkets.vue
  8. 56
      src/components/workspace/GoldManagement.vue
  9. 156
      src/views/activityManage/activity.vue
  10. 2
      src/views/audit/bean/beanAudit.vue
  11. 129
      src/views/channelManage/fans/fans.vue
  12. 189
      src/views/channelManage/reward/reward.vue
  13. 82
      src/views/consume/bean/addBeanConsume.vue
  14. 143
      src/views/consume/bean/articleVideo.vue
  15. 18
      src/views/consume/bean/beanConsume.vue
  16. 127
      src/views/consume/bean/dieHardFan.vue
  17. 133
      src/views/consume/bean/liveStream.vue
  18. 51
      src/views/consume/gold/addCoinConsume.vue
  19. 51
      src/views/history/newHistory.vue
  20. 45
      src/views/history/oldHistory.vue
  21. 206
      src/views/language/languageTranslate.vue
  22. 95
      src/views/managerecharge/rate.vue
  23. 190
      src/views/moneyManage/executor/executor.vue
  24. 2
      src/views/moneyManage/receiveDetail/receiveDetail1.vue
  25. 514
      src/views/moneyManage/receiveDetail/receiveFinance.vue
  26. 386
      src/views/moneyManage/receiveDetail/receiveHead.vue
  27. 518
      src/views/moneyManage/receiveDetail/receiveManage.vue
  28. 443
      src/views/moneyManage/receiveDetail/receiveService.vue
  29. 165
      src/views/moneyManage/receiveDetail/utils/recriveFormRules.js
  30. 182
      src/views/moneyManage/receiveDetail/utils/staticData.js
  31. 120
      src/views/permissions/rolePermission.vue
  32. 275
      src/views/permissions/userPermission.vue
  33. 77
      src/views/recharge/bean/addBeanRecharge.vue
  34. 96
      src/views/recharge/bean/beanOnlineRecharge.vue
  35. 15
      src/views/recharge/bean/beanRecharge.vue
  36. 86
      src/views/recharge/bean/beanSystemRecharge.vue
  37. 2
      src/views/refund/gold/addCoinRefund.vue
  38. 42
      src/views/usergold/bean/userbean.vue
  39. 9
      src/views/workspace/index.vue

8
src/components/MoneyManage/CurrencySelect.vue

@ -31,6 +31,12 @@
<script setup>
import { ref, computed, watchEffect, onMounted, watch } from 'vue';
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const searchData = ref('')
const isOpen = ref(false)
@ -45,7 +51,7 @@ const props = defineProps({
},
placeholder: {
type: String,
default: '请选择支付方式'
default: null
},
modelValue: {
type: String,

135
src/components/MoneyManage/ProductSelect.vue

@ -14,7 +14,7 @@
<div class="menu" v-show="isOpen">
<div class="coinselect" @click="coinhandelMenu" :class="{ 'active': coinisOpen }">
<div class="cointxt">
金币产品
{{ t('cash.goldProduct') }}
</div>
<span class="coin-arrow">
<el-icon>
@ -23,12 +23,12 @@
</span>
</div>
<div class="coinoption" v-show="coinisOpen">
<el-radio v-model="selectedValue" label="金币充值" size="large" />
<el-radio v-model="selectedValue" :label="t('cash.coinRecharge')" size="large" />
</div>
<div class="product">
<div class="coinselect" @click="producthandelMenu" :class="{ 'active': productisOpen }">
<div class="cointxt">
软件产品
{{ t('cash.softwareProduct') }}
</div>
<span class="coin-arrow">
<el-icon>
@ -38,7 +38,7 @@
</div>
<div class="productOption" v-show="productisOpen">
<hr class="line">
<div class="checktxt">软件</div>
<div class="checktxt">{{ t('cash.software') }}</div>
<div class="marketprodut">
<div class="fistlevel" v-for="(menu, index) in menuData" :key="menu.name" @click="clickmenu(index)"
:class="{ 'selected': menu.options.includes(selectedValue) }">
@ -61,7 +61,7 @@
</div>
<hr class="line">
<div class="ai">
<div class="checktxt">AI机构探测神器</div>
<div class="checktxt">{{ t('cash.aiService.aiDetectionTool') }}</div>
<hr class="line">
<el-radio-group v-model="selectedValue">
<el-radio v-for="ai in AIProduct" :key="ai" :label="ai" :value="ai">
@ -70,7 +70,7 @@
</el-radio-group>
</div>
<div class="ai">
<div class="checktxt">超级机构探测神器</div>
<div class="checktxt">{{ t('cash.aiService.superDetectionTool') }}</div>
<hr class="line">
<el-radio-group v-model="selectedValue">
<el-radio v-for="ai in superProduct" :key="ai" :label="ai" :value="ai">
@ -79,7 +79,7 @@
</el-radio-group>
</div>
<div class="ai">
<div class="checktxt">其他</div>
<div class="checktxt">{{ t('cash.other') }}</div>
<hr class="line">
<el-radio-group v-model="selectedValue">
<el-radio v-for="ai in InfoFee" :key="ai" :label="ai" :value="ai">
@ -95,7 +95,10 @@
<script setup>
import { ref, watch, onMounted, computed, onUnmounted, nextTick } from 'vue';
import { ArrowDown } from '@element-plus/icons-vue';
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const searchData = ref('')
const isOpen = ref(false)
@ -103,7 +106,7 @@ const coinisOpen = ref(false)
const productisOpen = ref(false)
const selectedItem = ref('')
const dropdownRef = ref(null)
const placeholder = ref('请选择产品')
const placeholder = ref(t('common_add.productNamePlaceholder'))
const handelMenu = () => {
isOpen.value = !isOpen.value
@ -135,53 +138,115 @@ watch(selectedValue, (newVal) => {
});
const AIProduct = ['AI机构追踪', 'AI机构出击', 'AI机构资金', 'AI机构活跃度','AI机构探测神器']
const superProduct = ['超级机构透视', '超级机构伏击', '超级机构猎杀', '超级机构脉搏', '超级机构罗盘','超级机构探测神器']
const InfoFee = ['静态信息费', '博股会员','HC信息费']
const AIProduct = [
t('cash.aiService.aiTracking'),
t('cash.aiService.aiAttack'),
t('cash.aiService.aiFunds'),
t('cash.aiService.aiActivity'),
t('cash.aiService.aiDetectionTool')
]
const superProduct = [
t('cash.aiService.superPerspective'),
t('cash.aiService.superAmbush'),
t('cash.aiService.superHunting'),
t('cash.aiService.superPulse'),
t('cash.aiService.superCompass'),
t('cash.aiService.superDetectionTool')
]
const InfoFee = [
t('cash.staticInfoFee'),
t('cash.BGmember'),
t('cash.HC')
]
// 使menuData
const menuData = [
{
name: '美股',
options: ['美股软件', '美股金卡', '美股套餐']
name: t('cash.softwareMenu.usStock'),
options: [
t('cash.softwareMenu.usStockSoftware'),
t('cash.softwareMenu.usStockGoldCard'),
t('cash.softwareMenu.usStockPackage')
]
},
{
name: '港股',
options: ['港股软件', '港股金卡', '港股套餐']
name: t('cash.softwareMenu.hkStock'),
options: [
t('cash.softwareMenu.hkStockSoftware'),
t('cash.softwareMenu.hkStockGoldCard'),
t('cash.softwareMenu.hkStockPackage')
]
},
{
name: 'A股',
options: ['A股软件', 'A股金卡', 'A股套餐']
name: t('cash.softwareMenu.aStock'),
options: [
t('cash.softwareMenu.aStockSoftware'),
t('cash.softwareMenu.aStockGoldCard'),
t('cash.softwareMenu.aStockPackage')
]
},
{
name: '新加坡股',
options: ['新加坡股软件', '新加坡股金卡', '新加坡股套餐']
name: t('cash.softwareMenu.singaporeStock'),
options: [
t('cash.softwareMenu.singaporeStockSoftware'),
t('cash.softwareMenu.singaporeStockGoldCard'),
t('cash.softwareMenu.singaporeStockPackage')
]
},
{
name: '马股',
options: ['马股软件', '马股金卡', '马股套餐']
name: t('cash.softwareMenu.malaysiaStock'),
options: [
t('cash.softwareMenu.malaysiaStockSoftware'),
t('cash.softwareMenu.malaysiaStockGoldCard'),
t('cash.softwareMenu.malaysiaStockPackage')
]
},
{
name: '日本股',
options: ['日本股软件', '日本股金卡', '日本股套餐']
name: t('cash.softwareMenu.japanStock'),
options: [
t('cash.softwareMenu.japanStockSoftware'),
t('cash.softwareMenu.japanStockGoldCard'),
t('cash.softwareMenu.japanStockPackage')
]
},
{
name: '泰股',
options: ['泰股软件', '泰股金卡', '泰股套餐']
name: t('cash.softwareMenu.thailandStock'),
options: [
t('cash.softwareMenu.thailandStockSoftware'),
t('cash.softwareMenu.thailandStockGoldCard'),
t('cash.softwareMenu.thailandStockPackage')
]
},
{
name: '越南股',
options: ['越南股软件', '越南股金卡', '越南股套餐']
name: t('cash.softwareMenu.vietnamStock'),
options: [
t('cash.softwareMenu.vietnamStockSoftware'),
t('cash.softwareMenu.vietnamStockGoldCard'),
t('cash.softwareMenu.vietnamStockPackage')
]
},
{
name: '印尼股',
options: ['印尼股软件', '印尼股金卡', '印尼股套餐']
name: t('cash.softwareMenu.indonesiaStock'),
options: [
t('cash.softwareMenu.indonesiaStockSoftware'),
t('cash.softwareMenu.indonesiaStockGoldCard'),
t('cash.softwareMenu.indonesiaStockPackage')
]
},
{
name: '韩国股',
options: ['韩国股软件', '韩国股金卡', '韩国股套餐']
name: t('cash.softwareMenu.koreaStock'),
options: [
t('cash.softwareMenu.koreaStockSoftware'),
t('cash.softwareMenu.koreaStockGoldCard'),
t('cash.softwareMenu.koreaStockPackage')
]
},
{
name: '台湾股',
options: ['台湾股软件', '台湾股金卡', '台湾股套餐']
name: t('cash.softwareMenu.taiwanStock'),
options: [
t('cash.softwareMenu.taiwanStockSoftware'),
t('cash.softwareMenu.taiwanStockGoldCard'),
t('cash.softwareMenu.taiwanStockPackage')
]
}
];
//
@ -325,7 +390,7 @@ defineExpose({ resetSelect });
z-index: 100;
.coinselect {
width: 100px;
width: 126px;
height: 20px;
border: 1px solid #175BE5;
padding: 5px 0 5px 12px;
@ -333,7 +398,7 @@ defineExpose({ resetSelect });
border-radius: 5px;
.cointxt {
width: 70px;
width: 100px;
height: 100%;
display: flex;
justify-content: center;

289
src/components/locales/lang/en.js

@ -7,9 +7,11 @@ export default {
common: {
// Filters
name: 'Name',
account: 'OA Account',
accountPlaceholder: 'Please enter OA account',
jwcode: 'Homily ID',
jwcodePlaceholder: 'Please enter Homily ID',
activityName: 'Activity Name',
activityName: 'Activity',
activityNamePlaceholder: 'Please enter activity name',
goodsName: 'Product Name',
goodsNamePlaceholder: 'Please enter product name',
@ -19,6 +21,10 @@ export default {
refundTypePlaceholder: 'Select refund type',
market: 'Region',
marketPlaceholder: 'Select region',
position: 'Position',
positionPlaceholder: 'Select position',
roleName: 'Role Name',
roleNamePlaceholder: 'Please enter role name',
consumePlatform: 'Consumption Platform',
consumePlatformPlaceholder: 'Select consumption platform',
rechargePlatform: 'Recharge Platform',
@ -27,6 +33,8 @@ export default {
payPlatformPlaceholder: 'Select platform',
updateType: 'Update Type',
updateTypePlaceholder: 'Select update type',
customerBelong: 'Customer Belonging',
activityBelong: 'Activity Belonging',
consumeTime: 'Consumption Time',
rechargeTime: 'Recharge Time',
refundTime: 'Refund Time',
@ -39,16 +47,32 @@ export default {
// Buttons
search: 'Query',
searchLabel: 'Search',
searchPlaceholder: 'Enter keywords',
searchButton: 'Search',
exportExcel: 'Export Excel',
viewExportList: 'View Export List',
reset: 'Reset',
edit: 'Edit',
editPermission: 'Edit Permission',
resetPassword: 'Reset Password',
delete: 'Delete',
pass: 'Approve',
reject: 'Reject',
cancel: 'Cancel',
confirm: 'Confirm',
submit: 'Submit',
add: 'Add',
addUser: 'Add User',
addRole: 'Add Role',
save: 'Save',
saving: 'Saving...',
addActivity: 'Add Activity',
addReceive: 'Add Receive',
confirmRecharge: 'Confirm Recharge',
batchImport: 'Batch Import',
import: 'Import',
uploadHint: 'Drag file here or click to upload',
// Buttons - Date
today: 'Today',
@ -81,14 +105,35 @@ export default {
payType: 'Payment Method',
customerNamePlaceholder: 'Please enter the customer name',
payTime: 'Payment time'
deleteTranslationRecord: 'Delete this translation record',
deleteActivityRecord: 'Delete this activity record',
noData: 'No data'
,
all: 'All'
},
// Permission module
permission: {
warning: 'Warning',
user: 'this user',
changeRoleConfirmContent1: 'Confirm role change?<br>You are changing the role of [',
changeRoleConfirmContent2: '] from [',
changeRoleConfirmContent3: '] to [',
changeRoleConfirmContent4: ']<br>After the change, the user’s permissions will be updated to the new role configuration, including data access and functional operations. Please confirm carefully.',
changeRoleSuccessContent1: 'User ',
changeRoleSuccessContent2: ' role has been changed to [',
roleRegionNote: 'This region setting has no practical effect; it is only for branch managers to view roles by region.'
},
// Message Group
elmessage: {
// Common
addSuccess: 'Added successfully',
submitFailed: 'Submission failed',
searchSuccess: 'Search completed',
requestFailed: 'Request failed',
inNetworkError: 'Network error, please try again',
prompt: 'Prompt',
jwcodeError: 'Invalid Homily ID',
addFailedUnknown: 'Add failed due to an unknown error',
addFailed: 'Add failed. Please check your network or contact the administrator',
@ -141,7 +186,7 @@ export default {
onlyUploadJPGPNG: 'Only JPG/PNG images are allowed',
limitImageSize: 'Image size cannot exceed 1MB',
uploadSuccess: 'Upload successful',
UploadFailed: 'Upload failed',
uploadFailed: 'Upload failed',
// Audit
noPermission: 'No permission',
@ -155,6 +200,41 @@ export default {
activityFormatError: 'Activity data format error. Please contact the administrator',
rechargeFormatError: 'Recharge method format error. Please contact the administrator',
getRechargeError: 'Failed to obtain recharge methods. Please try again later',
deleteSuccess: 'Deleted successfully',
success: 'Success',
confirmDeleteUser: 'Are you sure you want to delete this user?',
resetPasswordConfirm: 'Confirm reset for this account password?',
resetPasswordDefault: 'After reset, the password will be: 123456. Please notify the user to change it.',
checkAccountFormat: 'Please check OA account format',
deviceLimitReached: 'Device count has reached the limit',
noParentRoleMarket: 'The selected parent role has no associated region',
roleAddSuccess: 'Role {roleName} added successfully',
enableSuccess: 'Enabled successfully',
disableSuccess: 'Disabled successfully',
inputRoleName: 'Please enter role name',
roleNameLengthLimit: 'Role name length should be 2–20 characters',
selectPermissionList: 'Please select permission list',
inputAccount: 'Please enter OA account',
onlyDigits: 'Must be digits',
lengthLimit20: 'Length must not exceed 20 characters',
inputUserName: 'Please enter user name',
inputPosition: 'Please enter position',
inputAtLeastOneMachineCode: 'Please enter at least one machine code',
roleNameDuplicate: 'Role name already exists',
resetPasswordSuccess: 'Password reset successful',
resetPasswordFailed: 'Password reset failed',
noPermissionResetMarket: 'You do not have permission to modify passwords for users in the {market} region',
// Import & Upload
importSuccess: 'Import successful',
importFailed: 'Import failed',
importFailedNetworkOrFormat: 'Import failed. Please check your network or file format',
onlyExcelAllowed: 'Only Excel files are allowed',
fileTooLarge5MB: 'File size cannot exceed 5MB',
fileSelectSuccess: 'File selected successfully',
uploadLimitOne: 'You can upload only one file',
selectFileFirst: 'Please select a file first',
// Plain text validation
onlyPlainText: 'Only plain text is supported; HTML is not allowed',
// Export
exportSuccess: 'Export successful',
@ -189,9 +269,24 @@ export default {
// Common List Fields
common_list: {
id: 'No.',
originalChinese: 'Original Chinese',
english: 'English',
thai: 'Thai',
chineseTraditional: 'Traditional Chinese',
malay: 'Malay',
vietnamese: 'Vietnamese',
translated: 'Translated',
untranslated: 'Untranslated',
account: 'OA Account',
name: 'Name',
jwcode: 'Homily ID',
market: 'Region',
position: 'Position',
roleName: 'Role Name',
rolePermission: 'Role Permission',
departmentPermission: 'Department Permission',
parentRole: 'Parent Role',
permissionScope: 'Permission Scope',
sumGold: 'Total Coins',
payPlatform: 'Platform',
type: 'Update Type',
@ -202,7 +297,12 @@ export default {
refundModelAll: 'Full Refund',
refundModelPart: 'Partial Refund',
refundGoldCoin: 'Total refunded coins',
activity: 'Activity Name',
activity: 'Activity',
businessBelong: 'Performance Belonging',
startTime: 'Start Time',
endTime: 'End Time',
status: 'Status',
creator: 'Creator',
rateName: 'Currency',
rechargeAmount: 'Recharge Amount',
Gold: 'Gold Coin Quantity',
@ -225,6 +325,16 @@ export default {
homilyId: 'Homily ID',
goodsNum: 'Quantity',
refundReason: 'Refund Reason',
activityStatus: {
notStarted: 'Not Started',
inProgress: 'In Progress',
ended: 'Ended',
},
operation: 'Operation',
configTime: 'Configuration Time',
status: 'Status',
enable: 'Enable',
disable: 'Disable',
},
// Common Export Fields
@ -241,8 +351,44 @@ export default {
// Add Form Fields
common_add: {
jwcode: 'Homily ID',
activity: 'Activity Name',
addUserPermission: 'Add User Permission',
editUserPermission: 'Edit User Permission',
account: 'OA Account',
accountPlaceholder: 'Please enter OA account',
userName: 'User Name',
userNamePlaceholder: 'Please enter user name',
roleName: 'Role Name',
roleNamePlaceholder: 'Please select role name',
parentRole: 'Parent Role',
noParentRole: 'No Parent Role',
permissionList: 'Permission List',
machineCode: 'Machine Code',
machineCodePlaceholder: 'Please enter machine code',
remark: 'Remark',
addRole: 'Add Role',
editRole: 'Edit Role',
permissionDetails: 'Permission Details',
channelName: 'Channel Name',
channelPlaceholder: 'Please select channel',
originalChinese: 'Original Chinese',
originalChinesePlaceholder: 'Enter original Chinese',
english: 'English',
englishPlaceholder: 'Enter English',
thai: 'Thai',
thaiPlaceholder: 'Enter Thai',
chineseTraditional: 'Traditional Chinese',
chineseTraditionalPlaceholder: 'Enter Traditional Chinese',
malay: 'Malay',
malayPlaceholder: 'Enter Malay',
vietnamese: 'Vietnamese',
vietnamesePlaceholder: 'Enter Vietnamese',
addTranslation: 'Add Translation',
editTranslation: 'Edit Translation',
activity: 'Activity',
activityPlaceholder: 'Please enter activity name',
businessBelong: 'Performance Belonging',
startTime: 'Start Time',
endTime: 'End Time',
permanentGold: 'Permanent Gold Coins',
freeGold: 'Free Gold Coins',
taskGold: 'Task Gold Coins',
@ -313,7 +459,7 @@ export default {
name: 'Name',
jwcode: 'Homily ID',
market: 'Region',
activityName: 'Activity Name',
activityName: 'Activity',
currencyName: 'Currency',
rechargeAmount: 'Recharge Amount',
note: 'Remark',
@ -515,4 +661,137 @@ export default {
unknownSubmitter: 'Unknown',
notRecorded: 'Not Recorded',
},
cash: {
// 收款管理
receiveCashDataTitle: "Data Desc",
receiveCashDataContent: "All cash receipt pages: Orders sorted by payment time desc by default",
currency: {
usd: "US Dollar(USD)",
hkd: "Hong Kong Dollar(HKD)",
sgd: "Singapore Dollar(SGD)",
myr: "Malaysian Ringgit(MYR)",
thb: "Thai Baht(THB)",
cad: "Canadian Dollar(CAD)",
vnd: "Vietnamese Dong(VDN)",
krw: "South Korean Won(KRW)",
},
// 收款方式
payMethods: {
bankTransfer: 'Bank Transfer',
cash: 'Cash',
check: 'Check',
card: 'Card Payment',
grabpay: 'GrabPay',
nets: 'NETS',
paypal: 'PayPal',
stripe: 'Stripe (Link)',
ipay88: 'iPay88 (Link)',
paymentAsia: 'PaymentAsia (Link)',
transfer: "E-Transfer",
},
unit: "Unit",
year: "Year",
month: "Month",
// AI Services
aiService: {
aiTracking: "AI Org Track",
aiAttack: "AI Org Attack",
aiFunds: "AI Org Funds",
aiActivity: "AI Org Activity",
superPerspective: "Super Org View",
superAmbush: "Super Org Ambush",
superHunting: "Super Org Hunt",
superPulse: "Super Org Pulse",
superCompass: "Super Org Compass",
aiDetectionTool: "AI Org Detector",
superDetectionTool: "Super Org Detector"
},
// Markets
markets: {
HongKong: "Hong Kong",
Malaysia: "Malaysia",
Canada: "Canada",
Singapore: "Singapore",
Thailand: "Thailand",
VietnamHCM: "Vietnam HCM"
},
coinRecharge: "Coin Recharge",
staticInfoFee: "Static Fee",
BGmember: "BG Member",
HC: "HC Fee",
goldProduct: "Gold Product",
softwareProduct: "SoftwareProduct",
software: "Software",
other: "Other",
// Software Menu (for ProductSelect component)
softwareMenu: {
// Market Names
usStock: "US Stock",
hkStock: "HK Stock",
aStock: "A Stock",
singaporeStock: "SG Stock",
malaysiaStock: "MY Stock",
japanStock: "JP Stock",
thailandStock: "TH Stock",
vietnamStock: "VN Stock",
indonesiaStock: "ID Stock",
koreaStock: "KR Stock",
taiwanStock: "TW Stock",
// Software Types
usStockSoftware: "US Stock SW",
usStockGoldCard: "US Stock Gold",
usStockPackage: "US Stock Pack",
hkStockSoftware: "HK Stock SW",
hkStockGoldCard: "HK Stock Gold",
hkStockPackage: "HK Stock Pack",
aStockSoftware: "A Stock SW",
aStockGoldCard: "A Stock Gold",
aStockPackage: "A Stock Pack",
singaporeStockSoftware: "SG Stock SW",
singaporeStockGoldCard: "SG Stock Gold",
singaporeStockPackage: "SG Stock Pack",
malaysiaStockSoftware: "MY Stock SW",
malaysiaStockGoldCard: "MY Stock Gold",
malaysiaStockPackage: "MY Stock Pack",
japanStockSoftware: "JP Stock SW",
japanStockGoldCard: "JP Stock Gold",
japanStockPackage: "JP Stock Pack",
thailandStockSoftware: "TH Stock SW",
thailandStockGoldCard: "TH Stock Gold",
thailandStockPackage: "TH Stock Pack",
vietnamStockSoftware: "VN Stock SW",
vietnamStockGoldCard: "VN Stock Gold",
vietnamStockPackage: "VN Stock Pack",
indonesiaStockSoftware: "ID Stock SW",
indonesiaStockGoldCard: "ID Stock Gold",
indonesiaStockPackage: "ID Stock Pack",
koreaStockSoftware: "KR Stock SW",
koreaStockGoldCard: "KR Stock Gold",
koreaStockPackage: "KR Stock Pack",
taiwanStockSoftware: "TW Stock SW",
taiwanStockGoldCard: "TW Stock Gold",
taiwanStockPackage: "TW Stock Pack"
},
statusList: {
pending: "Pending",
passed: "Passed",
recalled: "Recalled",
refunded: "Refunded",
rejected: "Rejected",
},
pending: "Pending",
refundSuccess: "Refund Successful",
},
}

1280
src/components/locales/lang/zh-CN.js
File diff suppressed because it is too large
View File

46
src/components/workspace/CashManagement.vue

@ -2,16 +2,16 @@
<div class="cash-management">
<div class="cash-title">
<div class="text1">
现金管理
{{ t('workbench.cashManagement') }}
<!-- <span class="text1-update-time">-->
<!-- 最后更新时间{{ workDataUpdateTime || '该地区暂无数据' }}-->
<!-- </span>-->
<el-popover
placement="top-start"
title="数据说明"
:title="t('workbench.dataExplanationTitle')"
:width="240"
trigger="hover"
content="此数据实时计算,存在误差,请勿作为最终数据使用。"
:content="t('workbench.dataExplanationContent')"
>
<template #reference>
<el-icon
@ -31,7 +31,7 @@
<div class=" text2
">
<span class="text2-income">总营收{{ totalIncome.toFixed(2) }} 新币</span>
<span class="text2-income">{{ t('workbench.totalRevenue') }}{{ totalIncome.toFixed(2) }} {{ t('workbench.SGD') }}</span>
</div>
<div class="chart-container">
@ -39,11 +39,11 @@
<div class="market-data">
<div v-if="marksFlag" v-for="market in cashData.markets" :key="market.name" class="market-item">
<span class="market-name">{{ market.name }}</span>
<span class="market-value">{{ market.value.toLocaleString() }} 新币</span>
<span class="market-value">{{ market.value.toLocaleString() }} {{ t('workbench.SGD') }}</span>
</div>
<div v-else v-for="item in cashData.markets" :key="item.name" class="market-item">
<span class="market-name">代收{{ item.name }}</span>
<span class="market-value">{{ item.value.toLocaleString() }} </span>
<span class="market-name">{{ t('workbench.collect')}}{{ item.name }}</span>
<span class="market-value">{{ item.value.toLocaleString() }}</span>
</div>
@ -61,6 +61,9 @@ import {onMounted, ref} from 'vue'
import request from "@/util/http.js";
import API from "@/util/http.js";
import {Warning, Service} from "@element-plus/icons-vue";
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const chartRef = ref(null)
@ -75,12 +78,12 @@ const markets = ref()
//
const defaultMarkets = [
{name: '新加坡', value: 0},
{name: '马来西亚', value: 0},
{name: '香港', value: 0},
{name: '泰国', value: 0},
{name: '越南HCM', value: 0},
{name: '加拿大', value: 0},
{name: t('workbench.Singapore'), value: 0},
{name: t('workbench.Malaysia'), value: 0},
{name: t('workbench.HongKong'), value: 0},
{name: t('workbench.Thailand'), value: 0},
{name: t('workbench.VietnamHCM'), value: 0},
{name: t('workbench.Canada'), value: 0},
// {name: '', value: 0},
// { name: '', value: 0 },
// {name: '', value: 0},
@ -132,14 +135,14 @@ const fetchCashData = async () => {
value: resMap.get(m.name) ?? 0
}))
} else if (marksFlag.value=== false) {
// 1.
// 1.
const currencyMap = {
sgd: '新币',
myr: '马币',
hkd: '港币',
cad: '加币',
thb: '泰铢',
vdn: '越南盾',
sgd: t('workbench.SGD'),
myr: t('workbench.MYR'),
hkd: t('workbench.HKD'),
cad: t('workbench.CAD'),
thb: t('workbench.THB'),
vdn: t('workbench.VND'),
};
// 2. market totalSGD currencyMap
@ -191,7 +194,8 @@ const getAdminData = async function () {
try {
loading.value = true; //
const result = await API({url: '/admin/userinfo', data: {}});
marksFlag.value = result.markets === '总部' || result.markets === '研发部';
marksFlag.value = result.markets === '总部' || result.markets === '研发部'
|| result.markets === 'Headquarters' || result.markets === 'R&D Department';
console.log("marksFlag", marksFlag.value);
// alert(marksFlag.value)
} catch (error) {

73
src/components/workspace/GoldGraph.vue

@ -3,46 +3,46 @@
<el-card style="width:100%;" class="graph-card">
<div>
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
<el-tab-pane label="金币充值" name="recharge"></el-tab-pane>
<el-tab-pane label="金币消费" name="consume"></el-tab-pane>
<el-tab-pane :label="t('workbench.coinRecharge')" name="recharge"></el-tab-pane>
<el-tab-pane :label="t('workbench.coinConsume')" name="consume"></el-tab-pane>
</el-tabs>
</div>
<div class="condition">
<div class="stats">
<div v-if="activeTab === 'consume'">合计{{ sumConsume / 100 }}</div>&nbsp;&nbsp;
永久金币: {{ activeTab === 'recharge' ? sumRechargePermanent / 100 : sumConsumePermanent / 100 }}&nbsp;&nbsp;
免费金币: {{ activeTab === 'recharge' ? sumRechargeFree / 100 : sumConsumeFree / 100 }}&nbsp;&nbsp;
任务金币: {{ activeTab === 'recharge' ? sumRechargeTask / 100 : sumConsumeTask / 100 }}&nbsp;&nbsp;
<div v-if="activeTab === 'consume'">{{ t('workbench.total') }} {{ sumConsume / 100 }}</div>&nbsp;&nbsp;
{{ t('workbench.permanentGold') }}{{ activeTab === 'recharge' ? sumRechargePermanent / 100 : sumConsumePermanent / 100 }}&nbsp;&nbsp;
{{ t('workbench.freeGold') }}{{ activeTab === 'recharge' ? sumRechargeFree / 100 : sumConsumeFree / 100 }}&nbsp;&nbsp;
{{ t('workbench.taskGold') }}{{ activeTab === 'recharge' ? sumRechargeTask / 100 : sumConsumeTask / 100 }}&nbsp;&nbsp;
</div>
<div style="display: flex">
<el-button
:style="{ backgroundColor: activeTimeRange === 'yes' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'yes' ? 'white' : '#666' }"
@click="getYes()" size="default">昨天
@click="getYes()" size="default">{{ t('workbench.yesterday') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'today' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'today' ? 'white' : '#666' }"
@click="getToday()" size="default">今天
@click="getToday()" size="default">{{ t('workbench.today') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'week' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'week' ? 'white' : '#666' }"
@click="getWeek()" size="default">本周
@click="getWeek()" size="default">{{ t('workbench.thisWeek') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'month' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'month' ? 'white' : '#666' }"
@click="getMonth()" size="default">本月
@click="getMonth()" size="default">{{ t('workbench.thisMonth') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'year' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'year' ? 'white' : '#666' }"
@click="getYear()" size="default">本年
@click="getYear()" size="default">{{ t('workbench.thisYear') }}
</el-button>
</div>
<div style="display: flex">
<el-date-picker size="small" v-model="dateRange" type="datetimerange" range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss"
:start-placeholder="t('workbench.startTime')" :end-placeholder="t('workbench.endTime')" format="YYYY-MM-DD HH:mm:ss"
style="width:20vw;margin-left:0.5vw;" value-format="YYYY-MM-DD HH:mm:ss"
:default-time="defaultTime"
:disabled-date="disabledDate" @change="handleDatePickerChange"/>
<el-button type="primary" size="small" style="margin-left: 0.5vw" @click="getChartData">查询</el-button>
<el-button type="primary" size="small" style="margin-left: 0.5vw" @click="getChartData">{{ t('workbench.query') }}</el-button>
</div>
</div>
@ -54,22 +54,22 @@
</div>
<div class="right">
<el-card class="graph-card-list">
<div class="card-large">金币{{ activeTab === 'recharge' ? '充值' : '消费' }}排名</div>
<div class="card-large">{{ t('workbench.gold') }}{{ activeTab === 'recharge' ? t('workbench.recharge') : t('workbench.consume') }}{{ t('workbench.rank') }}</div>
<el-select popper-class="mySelectStyle" class="card-select" v-model="selectedType"
style="width: 100%; margin-bottom: 15px">
<el-option label="全部类型" value="all"></el-option>
<el-option label="永久金币" value="permanent"></el-option>
<el-option label="免费金币" value="free"></el-option>
<el-option label="任务金币" value="task"></el-option>
<el-option :label="t('workbench.allTypes')" value="all"></el-option>
<el-option :label="t('workbench.permanentGold')" value="permanent"></el-option>
<el-option :label="t('workbench.freeGold')" value="free"></el-option>
<el-option :label="t('workbench.taskGold')" value="task"></el-option>
</el-select>
<el-table class="card-table" :data="tableData" height="320px">
<el-table-column prop="rank" label="排名" width="60" align="center"></el-table-column>
<el-table-column prop="market" label="地区" align="center">
<el-table-column prop="rank" :label="t('workbench.rank')" width="60" align="center"></el-table-column>
<el-table-column prop="market" :label="t('workbench.region')" align="center">
<template #default="scope">
<span>{{ marketMapping[scope.row.market] || scope.row.market }}</span>
</template>
</el-table-column>
<el-table-column prop="coinAmount" label="金币数量" align="center">
<el-table-column prop="coinAmount" :label="t('workbench.goldCount')" align="center">
<template #default="{ row }">
{{ row.coinAmount.toLocaleString() }}
</template>
@ -90,6 +90,9 @@ import {ElMessage} from 'element-plus'
import dayjs from 'dayjs';
import utc from 'dayjs-plugin-utc'
import {marketMapping} from "@/utils/marketMap.js";
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
dayjs.extend(utc)
@ -359,11 +362,11 @@ const getMarkets = async () => {
console.log('市场列表获取成功:', markets.value)
} else {
console.error('获取市场列表失败', response)
ElMessage.error('获取市场列表失败')
ElMessage.error(t('elmessage.getMarketListFailed'))
}
} catch (error) {
console.error('获取市场列表失败:', error)
ElMessage.error('获取市场列表失败')
ElMessage.error(t('elmessage.getMarketListFailed'))
}
}
@ -398,11 +401,11 @@ const getChartData = async () => {
processRankingData(response.marketGraphs)
} else {
console.error('获取图表数据失败:', response)
ElMessage.error('获取图表数据失败')
ElMessage.error(t('elmessage.getChartDataFailed'))
}
} catch (error) {
console.error('获取图表数据失败:', error)
ElMessage.error('获取图表数据失败')
ElMessage.error(t('elmessage.getChartDataFailed'))
}
}
//
@ -524,7 +527,7 @@ const updateChart = (chartData) => {
if (activeTab.value === 'recharge') {
series = [
{
name: '永久金币',
name: t('workbench.permanentGold'),
type: 'bar',
stack: 'recharge',
data: chartData.rechargePermanent,
@ -532,7 +535,7 @@ const updateChart = (chartData) => {
barWidth: 30
},
{
name: '免费金币',
name: t('workbench.freeGold'),
type: 'bar',
stack: 'recharge',
data: chartData.rechargeFree,
@ -540,7 +543,7 @@ const updateChart = (chartData) => {
barWidth: 30
},
{
name: '任务金币',
name: t('workbench.taskGold'),
type: 'bar',
stack: 'recharge',
data: chartData.rechargeTask,
@ -548,11 +551,11 @@ const updateChart = (chartData) => {
barWidth: 30
}
]
legend = ['永久金币', '免费金币', '任务金币']
legend = [t('workbench.permanentGold'), t('workbench.freeGold'), t('workbench.taskGold')]
} else {
series = [
{
name: '永久金币',
name: t('workbench.permanentGold'),
type: 'bar',
stack: 'consume',
data: chartData.consumePermanent,
@ -560,7 +563,7 @@ const updateChart = (chartData) => {
barWidth: 30
},
{
name: '免费金币',
name: t('workbench.freeGold'),
type: 'bar',
stack: 'consume',
data: chartData.consumeFree,
@ -568,7 +571,7 @@ const updateChart = (chartData) => {
barWidth: 30
},
{
name: '任务金币',
name: t('workbench.taskGold'),
type: 'bar',
stack: 'consume',
data: chartData.consumeTask,
@ -576,7 +579,7 @@ const updateChart = (chartData) => {
barWidth: 30
}
]
legend = ['永久金币', '免费金币', '任务金币']
legend = [t('workbench.permanentGold'), t('workbench.freeGold'), t('workbench.taskGold')]
}
const option = {
@ -592,7 +595,7 @@ const updateChart = (chartData) => {
result += `${param.seriesName}: ${param.value.toLocaleString()}<br/>`;
total += param.value;
})
result += `${activeTab.value === 'recharge' ? '充值' : '消费'}: ${total.toLocaleString()}`;
result += `${t('workbench.all')}${activeTab.value === 'recharge' ? t('workbench.recharge') : t('workbench.consume')}: ${total.toLocaleString()}`;
return result
}
},
@ -648,7 +651,7 @@ const updateChart = (chartData) => {
chartInstance.setOption(option)
} catch (error) {
console.error('图表更新失败:', error)
ElMessage.error('图表渲染失败')
ElMessage.error(t('elmessage.renderChartFailed'))
} finally {
setTimeout(() => {
chartLoading.value = false

57
src/components/workspace/GoldGraphMarkets.vue

@ -5,55 +5,55 @@
<el-card style="width:100%;" class="graph-card">
<div>
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
<el-tab-pane label="金币充值" name="recharge"></el-tab-pane>
<el-tab-pane label="金币消费" name="consume"></el-tab-pane>
<el-tab-pane :label="t('workbench.coinRecharge')" name="recharge"></el-tab-pane>
<el-tab-pane :label="t('workbench.coinConsume')" name="consume"></el-tab-pane>
</el-tabs>
</div>
<div class="condition">
<div class="stats">
<div v-if="activeTab === 'consume'">合计{{ sumConsume }}</div>&nbsp;&nbsp;
永久金币: {{ activeTab === 'recharge' ? sumRechargePermanent : sumConsumePermanent }}&nbsp;&nbsp;
免费金币: {{ activeTab === 'recharge' ? sumRechargeFree : sumConsumeFree }}&nbsp;&nbsp;
任务金币: {{ activeTab === 'recharge' ? sumRechargeTask : sumConsumeTask }}&nbsp;&nbsp;
<div v-if="activeTab === 'consume'">{{ t('workbench.total') }} {{ sumConsume }}</div>&nbsp;&nbsp;
{{ t('workbench.permanentGold') }}: {{ activeTab === 'recharge' ? sumRechargePermanent : sumConsumePermanent }}&nbsp;&nbsp;
{{ t('workbench.freeGold') }}: {{ activeTab === 'recharge' ? sumRechargeFree : sumConsumeFree }}&nbsp;&nbsp;
{{ t('workbench.taskGold') }}: {{ activeTab === 'recharge' ? sumRechargeTask : sumConsumeTask }}&nbsp;&nbsp;
</div>
<div style="display: flex;">
<el-button
:style="{ backgroundColor: activeTimeRange === 'yes' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'yes' ? 'white' : '#666' }"
@click="getYes()" size="default">昨天
@click="getYes()" size="default">{{ t('workbench.yesterday') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'today' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'today' ? 'white' : '#666' }"
@click="getToday()" size="default">今天
@click="getToday()" size="default">{{ t('workbench.today') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'week' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'week' ? 'white' : '#666' }"
@click="getWeek()" size="default">本周
@click="getWeek()" size="default">{{ t('workbench.thisWeek') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'month' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'month' ? 'white' : '#666' }"
@click="getMonth()" size="default">本月
@click="getMonth()" size="default">{{ t('workbench.thisMonth') }}
</el-button>
<el-button
:style="{ backgroundColor: activeTimeRange === 'year' ? '#2741DE' : '#E5EBFE', color: activeTimeRange === 'year' ? 'white' : '#666' }"
@click="getYear()" size="default">本年
@click="getYear()" size="default">{{ t('workbench.thisYear') }}
</el-button>
</div>
<div style="display: flex;">
<el-date-picker size="small" v-model="dateRange" type="datetimerange" range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss"
:start-placeholder="t('workbench.startTime')" :end-placeholder="t('workbench.endTime')" format="YYYY-MM-DD HH:mm:ss"
style="width:20vw;margin-left:0.5vw;" value-format="YYYY-MM-DD HH:mm:ss"
:default-time="defaultTime"
:disabled-date="disabledDate" @change="handleDatePickerChange"/>
<el-button type="primary" size="small" style="margin-left: 0.5vw" @click="getChartData">查询</el-button>
<el-button type="primary" size="small" style="margin-left: 0.5vw" @click="getChartData">{{ t('workbench.query') }}</el-button>
</div>
<el-popover
placement="top-start"
title="数据说明"
:title="t('workbench.marketTitle')"
:width="240"
trigger="hover"
content="若统计周期跨越 40 天以上,将展示月份维度的数据。"
:content="t('workbench.marketContent')"
>
<template #reference>
<el-icon
@ -88,6 +88,9 @@ import dayjs from 'dayjs';
import utc from 'dayjs-plugin-utc'
import {marketMapping} from "@/utils/marketMap.js";
import {Service,Warning} from "@element-plus/icons-vue";
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
dayjs.extend(utc)
@ -360,7 +363,7 @@ const getChartData = async () => {
})
if (!response.marketGraphs || !Array.isArray(response.marketGraphs)) {
ElMessage.error('获取图表数据失败')
ElMessage.error(t('elmessage.getChartDataFailed'))
return
}
@ -415,7 +418,7 @@ const getChartData = async () => {
})
} catch (error) {
console.error('获取图表数据失败:', error)
ElMessage.error('获取图表数据失败')
ElMessage.error(t('elmessage.getChartDataFailed'))
}
}
@ -436,47 +439,47 @@ const updateChart = (chartData) => {
if (activeTab.value === 'recharge') {
series = [
{
name: '永久金币',
name: t('workbench.permanentGold'),
type: 'bar',
stack: 'recharge',
data: chartData.rechargePermanent,
},
{
name: '免费金币',
name: t('workbench.freeGold'),
type: 'bar',
stack: 'recharge',
data: chartData.rechargeFree,
},
{
name: '任务金币',
name: t('workbench.taskGold'),
type: 'bar',
stack: 'recharge',
data: chartData.rechargeTask,
}
]
legend = ['永久金币', '免费金币', '任务金币']
legend = [t('workbench.permanentGold'), t('workbench.freeGold'), t('workbench.taskGold')]
} else {
series = [
{
name: '永久金币',
name: t('workbench.permanentGold'),
type: 'bar',
stack: 'consume',
data: chartData.consumePermanent,
},
{
name: '免费金币',
name: t('workbench.freeGold'),
type: 'bar',
stack: 'consume',
data: chartData.consumeFree,
},
{
name: '任务金币',
name: t('workbench.taskGold'),
type: 'bar',
stack: 'consume',
data: chartData.consumeTask,
}
]
legend = ['永久金币', '免费金币', '任务金币']
legend = [t('workbench.permanentGold'), t('workbench.freeGold'), t('workbench.taskGold')]
}
const option = {
@ -490,7 +493,7 @@ const updateChart = (chartData) => {
result += `${param.seriesName}: ${param.value.toLocaleString()}<br/>`
total += param.value
})
result += `${activeTab.value === 'recharge' ? '充值' : '消费'}: ${total.toLocaleString()}`
result += `${t('workbench.all')}${activeTab.value === 'recharge' ? t('workbench.recharge') : t('workbench.consume')}: ${total.toLocaleString()}`
return result
}
},
@ -545,7 +548,7 @@ const updateChart = (chartData) => {
chartInstance.setOption(option)
} catch (error) {
console.error('图表更新失败:', error)
ElMessage.error('图表渲染失败')
ElMessage.error(t('elmessage.renderChartFailed'))
} finally {
setTimeout(() => (chartLoading.value = false), 300)
}

56
src/components/workspace/GoldManagement.vue

@ -2,9 +2,9 @@
<div class="gold-management">
<div class="gold-title">
<div class="text1">
金币管理
<span class="text1-update-time">最后更新时间{{
workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据'
{{ t('workbench.goldManagement') }}
<span class="text1-update-time">{{ t('workbench.lastUpdateTime') }}{{
workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : t('workbench.noData')
}} </span>
</div>
</div>
@ -13,10 +13,11 @@
<el-col :span="12">
<!-- 第一个卡片 -->
<div class="card-item-row1">
<div class="card-title">当前金币余量
<div class="card-title">
{{ t('workbench.currentGoldBalance') }}
<span style="font-weight: bold">{{
currentGold / 100
}}</span>&nbsp;&nbsp;&nbsp;&nbsp;较前一日
}}</span>&nbsp;&nbsp;&nbsp;&nbsp;{{ t('workbench.compareToPreviousDay') }}
{{ dailyChange / 100 }}&nbsp;
<template v-if="dailyChange > 0">
<el-image :src="upArrow" style="width: 14px;"/>
@ -33,26 +34,26 @@
<!-- 左边文本信息 -->
<el-col :span="12">
<div class="margin-bottom" style="white-space: nowrap;">
永久金币<b>{{ currentPermanent / 100 }}</b>
{{ t('workbench.permanentGold') }}<b>{{ currentPermanent / 100 }}</b>
</div>
<div class="margin-bottom">&nbsp;</div>
<div class="margin-bottom">免费金币{{ currentFree / 100 }}</div>
<div class="margin-bottom">{{ t('workbench.freeGold') }}<b>{{ currentFree / 100 }}</b></div>
<!-- <div class="margin-bottom">&nbsp</div>-->
<!-- <div class="margin-bottom">&nbsp</div>-->
<div class="margin-bottom">
[6月到期{{ currentFreeJune / 100 }}]
[{{ t('workbench.goldExpireIn6Months')}}{{ currentFreeJune / 100 }}]
</div>
<div class="margin-bottom">&nbsp;</div>
<div class="margin-bottom">任务金币{{ currentTask / 100 }}</div>
<div class="margin-bottom">{{ t('workbench.taskGold') }}<b>{{ currentTask / 100 }}</b></div>
</el-col>
<!-- 右边图表 -->
<el-col :span="12">
<!-- <div ref="goldTypeChart" style="width: 100%; height: 100px;"></div>-->
<div style="width: 100%; height: 60px;">&nbsp;</div>
<div class="margin-bottom">
[12月到期{{ currentFreeDecember / 100 }}]
[{{ t('workbench.goldExpireIn12Months')}}{{ currentFreeDecember / 100 }}]
</div>
</el-col>
</el-row>
@ -63,17 +64,17 @@
<el-col :span="12">
<!-- 第二个卡片 -->
<div class="card-item-row1">
<div class="card-title">全年累计充值金币数{{ yearlyRecharge / 100 }}</div>
<div class="card-title">{{ t('workbench.annualCumulativeRecharge')}}{{ yearlyRecharge / 100 }}</div>
<el-row>
<el-col :span="12">
<div class="center-card">折合新币累计金额</div>
<div class="center-card">{{ t('workbench.convertedSGDCumulativeAmount') }}</div>
<el-image :src="svg1" style="width: 88px; display: block;margin: 0 auto;"/>
<div class="center-card">{{ yearlyMoney / 100 }}新币</div>
<div class="center-card">{{ yearlyMoney / 100 }}{{ t('workbench.SGD') }}</div>
</el-col>
<el-col :span="12" style="border-left: 2px solid #CFE6FE; height: 160px">
<div class="center-card" style="white-space: nowrap;">昨日新增金币{{ recharge / 100 }}</div>
<div class="center-card" style="white-space: nowrap;">{{ t('workbench.yesterdayNew')}}{{ recharge / 100 }}</div>
<div ref="rechargeGoldChart" style="width: 88px; height: 88px; display: block;margin: 0 auto;"></div>
<div class="center-card" style="white-space: nowrap;">其中永久金币{{ money / 100 }}</div>
<div class="center-card" style="white-space: nowrap;">{{ t('workbench.wherePermanentGold')}}{{ money / 100 }}</div>
</el-col>
</el-row>
</div>
@ -85,7 +86,7 @@
<el-col :span="12">
<!-- 第三个卡片 -->
<div class="card-item">
<div class="card-title">全年累计消费金币数{{ yearlyReduce / 100 }}</div>
<div class="card-title">{{ t('workbench.annualCumulativeConsume')}}{{ yearlyReduce / 100 }}</div>
<el-row style="height: 200px;">
<el-col :span="12">
<div ref="consumeChart" style="width:100%; height: 88%;"></div>
@ -99,19 +100,19 @@
<el-col :span="12">
<!-- 第四个卡片 -->
<div class="card-item" >
<div class="card-title">全年累计充值人头数{{ yearlyRechargeNum }}</div>
<div class="card-title">{{ t('workbench.annualCumulativeRechargePeople')}}{{ yearlyRechargeNum }}</div>
<el-row style="height: 200px;">
<el-col :span="12" style="border-right: 2px solid #CFE6FE; height: 200px">
<div class="chart5">
<el-image :src="svg2" style="width: 88px; display: block;margin: 0 auto;"/>
<div class="margin-bottom">
<div style="display: flex; gap: 10px; font-size: 16px;">周同比{{ sumWow }}%
<div style="display: flex; gap: 10px; font-size: 16px;">{{ t('workbench.weekYearOnYear')}}{{ sumWow }}%
<el-image v-if="sumWow > 0" :src="upArrow" style="width: 10px;"/>
<el-image v-else-if="sumWow < 0" :src="downArrow" style="width: 10px;"/>
<el-image v-else :src="pingArrow" style="width: 10px;"/>
</div>
<div style="display: flex; gap: 10px; font-size: 16px;">
日环比{{ sumDaily }}%
{{ t('workbench.dayYearOnYear')}}{{ sumDaily }}%
<el-image v-if="sumDaily > 0" :src="upArrow" style="width: 10px;"/>
<el-image v-else-if="sumDaily < 0" :src="downArrow" style="width: 10px;"/>
<el-image v-else :src="pingArrow" style="width: 10px; "/>
@ -145,6 +146,9 @@ import svg2 from '@/assets/SvgIcons/wow.svg'
import upArrow from '@/assets/SvgIcons/up-arrow.svg'
import downArrow from '@/assets/SvgIcons/down-arrow.svg'
import pingArrow from '@/assets/SvgIcons/unchanged.svg'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
dayjs.extend(utc)
@ -388,14 +392,14 @@ const initConsumeChart = () => {
data: [
{
value: yearlyConsume.value / 100,
name: '消耗:' + yearlyConsume.value / 100,
name: t('workbench.consume') + yearlyConsume.value / 100,
// name: '' + 1234567890,
itemStyle: {color: '#7DB7FA'}
},
{
value: yearlyRefund.value / 100,
name: '退款:' + yearlyRefund.value / 100,
name: t('workbench.refund') + yearlyRefund.value / 100,
itemStyle: {color: '#F7D47C'}
}
@ -436,7 +440,7 @@ const initConsumeDetailChart = () => {
data: [
{
value: dailyConsume.value / 100,
name: '昨日新增消费:' + dailyConsume.value / 100,
name: t('workbench.yesterdayNewAll') + dailyConsume.value / 100,
itemStyle: {color: '#65C9C9'}
}
]
@ -453,13 +457,13 @@ const initConsumeDetailChart = () => {
data: [
{
value: dailyReduce.value / 100,
name: '昨日新增消耗:' + dailyReduce.value / 100,
name: t('workbench.yesterdayNewConsume') + dailyReduce.value / 100,
// name: '' + 1234567890,
itemStyle: {color: '#9469D1'}
},
{
value: dailyRefund.value / 100,
name: '昨日新增退款:' + dailyRefund.value / 100,
name: t('workbench.yesterdayNewRefund') + dailyRefund.value / 100,
itemStyle: {color: '#B8DB6E'}
}
]
@ -498,7 +502,7 @@ const initRechargePeopleChart = () => {
data: [
{
value: ydayRechargeNum.value,
name: '昨日充值人数:' + ydayRechargeNum.value,
name: t('workbench.yesterdayRechargePeople') + ydayRechargeNum.value,
itemStyle: {color: '#65C9C9'}
},
],
@ -513,7 +517,7 @@ const initRechargePeopleChart = () => {
data: [
{
value: firstRecharge.value,
name: '其中首充:' + firstRecharge.value,
name: t('workbench.whereFirstRecharge') + firstRecharge.value,
itemStyle: {color: '#9469D1'}
},
{

156
src/views/activityManage/activity.vue

@ -2,30 +2,30 @@
<el-card class="card1" style="margin-bottom: 1vh;">
<div class="condition">
<div class="condition-item1">
<el-text size="large">活动名称</el-text>
<el-input v-model="searchForm.activityName" style="width: 10vw" placeholder="请输入活动名称" clearable />
<el-text size="large">{{ t('common.activityName') }}</el-text>
<el-input v-model="searchForm.activityName" style="width: 10vw" :placeholder="t('common.activityNamePlaceholder')" clearable />
</div>
<div class="condition-item1">
<el-text size="large">业绩归属</el-text>
<el-text size="large">{{ t('common.type') }}</el-text>
<!-- <el-cascader v-model="searchForm.businessBelong" :options="marketOptions" placeholder="请选择所属地区" clearable
style="width: 10vw" /> -->
<el-select v-model="searchForm.businessBelong" placeholder="请选择业绩归属" style="width: 10vw" clearable>
<el-option label="客户归属地" value="客户归属地" />
<el-option label="活动归属地" value="活动归属地" />
<el-select v-model="searchForm.businessBelong" :placeholder="t('common.typePlaceholder')" style="width: 10vw" clearable>
<el-option :label="t('common.customerBelong')" value="客户归属地" />
<el-option :label="t('common.activityBelong')" value="活动归属地" />
</el-select>
</div>
<div class="condition-item2">
<el-text size="large">开始时间</el-text>
<el-date-picker v-model="searchForm.startTime" type="datetime" placeholder="请选择开始时间"
<el-text size="large">{{ t('common.startTime') }}</el-text>
<el-date-picker v-model="searchForm.startTime" type="datetime" :placeholder="t('common.startTime')"
format="YYYY-MM-DD HH:mm:ss" :default-time="defaultStartTime" clearable />
</div>
<div class="condition-item2">
<el-text size="large">结束时间</el-text>
<el-date-picker v-model="searchForm.endTime" type="datetime" placeholder="请选择结束时间"
<el-text size="large">{{ t('common.endTime') }}</el-text>
<el-date-picker v-model="searchForm.endTime" type="datetime" :placeholder="t('common.endTime')"
format="YYYY-MM-DD HH:mm:ss" :default-time="defaultEndTime" clearable />
</div>
<el-button type="primary" @click="getActivity">查询</el-button>
<el-button type="success" @click="reset">重置</el-button>
<el-button type="primary" @click="getActivity">{{ t('common.search') }}</el-button>
<el-button type="success" @click="reset">{{ t('common.reset') }}</el-button>
</div>
</el-card>
@ -33,42 +33,39 @@
<el-card class="card2">
<div class="add-item">
<el-button type="success" @click="showAdd = true">新增活动</el-button>
<el-button type="success" @click="showAdd = true">{{ t('common.addActivity') }}</el-button>
</div>
<div>
<el-table :data="tableData" style="width: 82vw;height:70vh;" :row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
<template #default="scope">
<span>{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}</span>
</template>
</el-table-column>
<el-table-column prop="activityName" label="活动名称" width="150px" show-overflow-tooltip />
<el-table-column prop="businessBelong" label="业绩归属地" width="150px" />
<el-table-column prop="areaName" label="归属地" width="150px" />
<el-table-column prop="startTime" label="开始时间" width="200px">
<el-table-column prop="activityName" :label="t('common_list.activity')" width="150px" show-overflow-tooltip />
<el-table-column prop="businessBelong" :label="t('common_list.businessBelong')" width="150px" />
<el-table-column prop="areaName" :label="t('common_list.market')" width="150px" />
<el-table-column prop="startTime" :label="t('common_list.startTime')" width="200px">
<template #default="scope">
{{ moment(scope.row.startTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column prop="endTime" label="结束时间" width="200px">
<el-table-column prop="endTime" :label="t('common_list.endTime')" width="200px">
<template #default="scope">
{{
moment(scope.row.endTime).format('YYYY-MM-DD HH:mm:ss')
}}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="150px">
<el-table-column prop="status" :label="t('common_list.status')" width="150px">
<template #default="scope">
{{ scope.row.status === '0' ? '未开始' :
scope.row.status === '1' ? '进行中' :
scope.row.status === '2' ? '已结束' : scope.row.status
}}
{{ getActivityStatusText(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="creatorName" label="添加人" width="150px" />
<el-table-column prop="operation" label="操作" width="220px">
<el-table-column prop="creatorName" :label="t('common_list.creator')" width="150px" />
<el-table-column prop="operation" :label="t('common_list.operation')" width="220px">
<template #default="scope">
<el-button type="primary" text @click="editOpen(scope.row)">编辑</el-button>
<el-button type="primary" text @click="editOpen(scope.row)">{{ t('common.edit') }}</el-button>
<!-- <el-button type="danger" text @click="openDel(scope.row)">删除</el-button> -->
</template>
</el-table-column>
@ -84,72 +81,72 @@
<el-dialog v-model="showAdd" width="20vw" draggable align-center style="background-color: rgb(243,250,254);">
<div class="add-item">
<el-text size="large">活动名称</el-text>
<el-input v-model="addForm.activityName" style="width: 12vw" placeholder="请输入活动名称" maxlength="200" clearable />
<el-text size="large">{{ t('common_add.activity') }}</el-text>
<el-input v-model="addForm.activityName" style="width: 12vw" :placeholder="t('common_add.activityPlaceholder')" maxlength="200" clearable />
</div>
<div class="add-item">
<el-text size="large">业绩归属</el-text>
<el-text size="large">{{ t('common_add.businessBelong') }}</el-text>
<el-radio-group v-model="addForm.businessBelong" style="width: 12vw">
<el-radio size="large" value="客户归属地">客户归属地</el-radio>
<el-radio size="large" value="活动归属地">活动归属地</el-radio>
<el-radio size="large" value="客户归属地">{{ t('common.customerBelong') }}</el-radio>
<el-radio size="large" value="活动归属地">{{ t('common.activityBelong') }}</el-radio>
</el-radio-group>
</div>
<div class="add-item" v-show="addForm.businessBelong === '活动归属地'">
<el-text size="large">所属地区</el-text>
<el-cascader v-model="addForm.area" :options="marketOptions" placeholder="请选择所属地区" clearable
<el-text size="large">{{ t('common_add.market') }}</el-text>
<el-cascader v-model="addForm.area" :options="marketOptions" :placeholder="t('common_add.marketPlaceholder')" clearable
style="width: 12vw" />
</div>
<div class="add-item">
<el-text size="large">开始时间</el-text>
<el-date-picker v-model="addForm.startTime" type="datetime" placeholder="请选择开始时间"
<el-text size="large">{{ t('common_add.startTime') }}</el-text>
<el-date-picker v-model="addForm.startTime" type="datetime" :placeholder="t('common_add.startTime')"
:default-time="defaultStartTime" style="width: 12vw" />
</div>
<div class="add-item">
<el-text size="large">结束时间</el-text>
<el-date-picker v-model="addForm.endTime" type="datetime" placeholder="请选择结束时间"
<el-text size="large">{{ t('common_add.endTime') }}</el-text>
<el-date-picker v-model="addForm.endTime" type="datetime" :placeholder="t('common_add.endTime')"
:default-time="defaultEndTime" style="width: 12vw" />
</div>
<div style="display: flex; justify-content: center; margin-top: 5vh;">
<el-button type="primary" @click="hideAdd">取消</el-button>
<el-button type="primary" @click="throttleGetActivity">确定</el-button>
<el-button type="primary" @click="hideAdd">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="throttleGetActivity">{{ t('common.confirm') }}</el-button>
</div>
</el-dialog>
<el-dialog v-model="showEdit" width="20vw" draggable align-center style="background-color: rgb(243,250,254);">
<div class="edit-item">
<el-text size="large">活动名称</el-text>
<el-input v-model="editForm.activityName" style="width: 12vw" placeholder="请输入活动名称" maxlength="200" clearable />
<el-text size="large">{{ t('common_add.activity') }}</el-text>
<el-input v-model="editForm.activityName" style="width: 12vw" :placeholder="t('common_add.activityPlaceholder')" maxlength="200" clearable />
</div>
<div class="edit-item">
<el-text size="large">业绩归属</el-text>
<el-text size="large">{{ t('common_add.businessBelong') }}</el-text>
<el-radio-group v-model="editForm.businessBelong" style="width: 12vw">
<el-radio size="large" value="客户归属地">客户归属地</el-radio>
<el-radio size="large" value="活动归属地">活动归属地</el-radio>
<el-radio size="large" value="客户归属地">{{ t('common.customerBelong') }}</el-radio>
<el-radio size="large" value="活动归属地">{{ t('common.activityBelong') }}</el-radio>
</el-radio-group>
</div>
<div class="edit-item" v-show="editForm.businessBelong === '活动归属地'">
<el-text size="large">所属地区</el-text>
<el-cascader v-model="editForm.area" :options="marketOptions" placeholder="请选择所属地区" clearable
<el-text size="large">{{ t('common_add.market') }}</el-text>
<el-cascader v-model="editForm.area" :options="marketOptions" :placeholder="t('common_add.marketPlaceholder')" clearable
style="width: 12vw" />
</div>
<div class="edit-item">
<el-text size="large">开始时间</el-text>
<el-date-picker v-model="editForm.startTime" type="datetime" placeholder="请选择开始时间"
<el-text size="large">{{ t('common_add.startTime') }}</el-text>
<el-date-picker v-model="editForm.startTime" type="datetime" :placeholder="t('common_add.startTime')"
:default-time="defaultStartTime" style="width: 12vw" />
</div>
<div class="edit-item">
<el-text size="large">结束时间</el-text>
<el-date-picker v-model="editForm.endTime" type="datetime" placeholder="请选择结束时间"
<el-text size="large">{{ t('common_add.endTime') }}</el-text>
<el-date-picker v-model="editForm.endTime" type="datetime" :placeholder="t('common_add.endTime')"
:default-time="defaultEndTime" style="width: 12vw" />
</div>
<div style="display: flex; justify-content: center; margin-top: 5vh;">
<el-button type="primary" @click="hideEdit">取消</el-button>
<el-button type="primary" @click="handleEdit">确定</el-button>
<el-button type="primary" @click="hideEdit">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="handleEdit">{{ t('common.confirm') }}</el-button>
</div>
</el-dialog>
<ConfirmDialog v-model="showDel" message="删除该活动数据" @confirm="handleDel()" @cancel="hideDel" @close="hideDel" />
<ConfirmDialog v-model="showDel" :message="t('common.deleteActivityRecord')" @confirm="handleDel()" @cancel="hideDel" @close="hideDel" />
</template>
<script setup>
import { ElMessage, ElPagination } from 'element-plus';
@ -163,8 +160,19 @@ const adminStore = useAdminStore();
const { adminData, menuTree } = storeToRefs(adminStore)
import ConfirmDialog from '@/components/dialogs/ConfirmDialog.vue'
import _ from 'lodash'
//
import { useI18n } from 'vue-i18n';
const {t} = useI18n();
const getActivityStatusText = (status) => {
if (status === '0') return t('common_list.activityStatus.notStarted')
if (status === '1') return t('common_list.activityStatus.inProgress')
if (status === '2') return t('common_list.activityStatus.ended')
return status
}
//
const activityNameReg = /^[\u4e00-\u9fa5a-zA-Z0-9,。!?、;:“”()‘’《》【】{}——~,.!?:;'--()""\[\]_&+=]+$/;
const activityNameReg = /^[\\u4e00-\\u9fa5a-zA-Z0-9,。!?、;:“”()‘’《》【】{}——~,.!?:;'--()\"\"\\[\\]_&+=]+$/;
// --
const tableData = ref([])
const pagination = ref({
@ -194,7 +202,7 @@ const editForm = ref({
const marketOptions = ref([])
const getActivity = async function () {
if (!hasMenuPermission(menuTree.value,permissionMapping.view_activity)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
const rechargeActivity = {
@ -224,26 +232,26 @@ const getActivity = async function () {
}
const handleAdd = async function () {
if (!hasMenuPermission(menuTree.value,permissionMapping.add_activity)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
const activityName = addForm.value.activityName
if (!validateActivityName(activityName)) return
if (!addForm.value.businessBelong) {
ElMessage.error('请选择业绩归属')
ElMessage.error(t('elmessage.selectBusinessBelong'))
return
}
if (addForm.value.businessBelong === '活动归属地' && addForm.value.area.length === 0) {
ElMessage.error('请选择所属地区')
ElMessage.error(t('elmessage.selectMarket'))
return
}
if (!addForm.value.startTime) {
ElMessage.error('请选择开始时间')
ElMessage.error(t('elmessage.selectStartTime'))
return
}
if (!addForm.value.endTime) {
ElMessage.error('请选择结束时间')
ElMessage.error(t('elmessage.selectEndTime'))
return
}
if (addForm.value.businessBelong === '客户归属地') {
@ -264,7 +272,7 @@ const handleAdd = async function () {
data: params
})
if (res.code === 200) {
ElMessage.success('添加成功')
ElMessage.success(t('elmessage.addSuccess'))
getActivity()
hideAdd()
addForm.value = {
@ -275,7 +283,7 @@ const handleAdd = async function () {
endTime: null,
}
} else {
ElMessage.error(res.msg || '添加失败')
ElMessage.error(res.msg || t('elmessage.addFailed'))
return
}
}
@ -283,30 +291,30 @@ const handleAdd = async function () {
const throttleGetActivity = _.throttle(handleAdd, 5000, { trailing: false });
const handleEdit = async function () {
if (!hasMenuPermission(menuTree.value,permissionMapping.edit_activity)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
const activityName = editForm.value.activityName
if (!validateActivityName(activityName)) return
if (!editForm.value.activityName) {
ElMessage.error('请输入活动名称')
ElMessage.error(t('elmessage.checkActivity'))
return
}
if (!editForm.value.businessBelong) {
ElMessage.error('请选择业绩归属')
ElMessage.error(t('elmessage.selectBusinessBelong'))
return
}
if (editForm.value.businessBelong === '活动归属地' && editForm.value.area.length === 0) {
ElMessage.error('请选择所属地区')
ElMessage.error(t('elmessage.selectMarket'))
return
}
if (!editForm.value.startTime) {
ElMessage.error('请选择开始时间')
ElMessage.error(t('elmessage.selectStartTime'))
return
}
if (!editForm.value.endTime) {
ElMessage.error('请选择结束时间')
ElMessage.error(t('elmessage.selectEndTime'))
return
}
@ -329,18 +337,18 @@ const handleEdit = async function () {
data: params
})
if (res.code === 200) {
ElMessage.success('修改成功')
ElMessage.success(t('elmessage.editSuccess'))
getActivity()
hideEdit()
}
}
const handleDel = async function (row) {
if (!hasMenuPermission(menuTree.value,permissionMapping.delete_activity)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
if (!currentDelRow.value) {
ElMessage.error('当前选择无数据')
ElMessage.error(t('elmessage.currentSelectionEmpty'))
return
}
const res = await API({
@ -350,7 +358,7 @@ const handleDel = async function (row) {
}
})
if (res.code === 200) {
ElMessage.success('删除成功')
ElMessage.success(t('elmessage.deleteSuccess'))
getActivity()
showDel.value = false
}
@ -534,4 +542,4 @@ onMounted(() => {
width: 17vw;
margin-bottom: 1vh;
}
</style>
</style>

2
src/views/audit/bean/beanAudit.vue

@ -19,7 +19,7 @@
<div class="selectRow" style="width: 36vw;">
<el-text class="text" size="large" v-show="checkTab === 'pending'">{{ $t('common.submitTime') }}</el-text>
<el-text class="text" size="large" v-show="checkTab === 'reject' || checkTab === 'pass'">{{ $t('common.auditTime') }}</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" range-separator="" :start-placeholder="$t('common.startTime')"
<el-date-picker v-model="dateRange" type="datetimerange" :range-separator="t('common.to')" :start-placeholder="$t('common.startTime')"
:end-placeholder="$t('common.endTime')" class="selectContent" style="width: 25vw;margin-right:1vw"
@change="handleDatePickerChange" :default-time="defaultTime" />
<!-- <el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>-->

129
src/views/channelManage/fans/fans.vue

@ -8,6 +8,10 @@ import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
const adminStore = useAdminStore();
const { flag } = storeToRefs(adminStore);
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// flag
watch(flag, (newFlag, oldFlag) => {
// flag
@ -68,7 +72,7 @@ const getChannel = async function () {
console.log('请求频道列表失败', error)
ElMessage({
type: 'error',
message: '获取频道列表失败,请稍后重试'
message: t('elmessage.getChannelListFailed')
})
}
}
@ -82,14 +86,14 @@ const getChannel = async function () {
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 },
{ label: '单次付费', value: 7 },
{ label: '连续包月', value: 8 }
{ label: t('consume.consumeTypes.1'), value: 1 },
{ label: t('consume.consumeTypes.2'), value: 2 },
{ label: t('consume.consumeTypes.3'), value: 3 },
{ label: t('consume.consumeTypes.4'), value: 4 },
{ label: t('consume.consumeTypes.5'), value: 5 },
{ label: t('consume.consumeTypes.6'), value: 6 },
{ label: t('consume.consumeTypes.7'), value: 7 },
{ label: t('consume.consumeTypes.8'), value: 8 }
])
// //
@ -247,7 +251,7 @@ const search = function () {
if (beanConsumeFan.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(beanConsumeFan.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
@ -336,7 +340,7 @@ const getDept = async function () {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
message: t('elmessage.getRegionListFailed')
})
}
}
@ -399,14 +403,21 @@ const exportExcel = async function () {
...beanConsumeFan.value,
sortField: sortField.value,
sortOrder: sortOrder.value,
roleId: adminData.value.roleId,
flag: flag.value,
roleId: adminData.value.roleId
},
}
const res = await API({ url: '/export/exportFan', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
try {
const res = await API({url: '/export/exportFan', data: params});
if (res.code === 200) {
ElMessage.success(t('elmessage.exportSuccess'));
} else {
ElMessage.error(res.message || t('elmessage.exportFailed'));
}
} catch (error) {
console.error('导出请求出错:', error);
ElMessage.error(t('elmessage.exportFailed'));
}
}
const exportListVisible = ref(false)
@ -432,11 +443,11 @@ const getExportList = async () => {
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -449,7 +460,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -471,15 +482,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
</script>
@ -489,18 +500,18 @@ const getTagText = (state) => {
<el-col style="margin-bottom: 1vh">
<div class="select">
<div class="selectRow">
<el-text class="text">精网号</el-text>
<el-input class="selectContent" v-model="beanConsumeFan.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeFan.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable />
</div>
<div class="selectRow">
<el-text class="text">地区</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.dept" placeholder="请选择地区" clearable>
<el-text class="text">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.dept" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
</el-select>
</div>
<div class="selectRow">
<el-text class="text">频道</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.channel" placeholder="请选择频道" clearable filterable>
<el-text class="text">{{ t('common.channel') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.channel" :placeholder="t('common.channelPlaceholder')" clearable filterable>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item" />
</el-select>
</div>
@ -509,9 +520,9 @@ const getTagText = (state) => {
<el-col>
<div class="select">
<div class="selectRow" style="width: 36vw;">
<el-text class="text" size="large">消费时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:25vw"
<el-text class="text" size="large">{{ t('common.consumetime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="margin-right:1vw;width:25vw"
@change="handleDatePickerChange" value-format="YYYY-MM-DD HH:mm:ss" :default-time="defaultTime" />
<div v-if="false">
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>
@ -520,24 +531,24 @@ const getTagText = (state) => {
</div>
</div>
<div class="selectRow" style="justify-content: flex-start;">
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
金豆总数{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(Math.abs(freeBean)) }}
{{ t('common.totalGoldBean') }}{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(Math.abs(freeBean)) }}
</div>
<div style="overflow-y: auto">
<el-table :data="tableData" style="width: 82vw" height="69vh" @sort-change="handleSortChange"
<el-table :data="tableData" style="width: 82vw" height="65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -545,20 +556,20 @@ const getTagText = (state) => {
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="name" :label="t('common_list.name')" width="150px" fixed="left" show-overflow-tooltip />
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="beanNum" label="金豆数量" sortable="custom" width="120px" />
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px" />
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px" />
<el-table-column prop="channel" label="频道" width="190px" show-overflow-tooltip />
<el-table-column prop="type" label="会员类型" width="120px">
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="110px" fixed="left" />
<el-table-column prop="dept" :label="t('common_list.market')" width="110px" />
<el-table-column prop="beanNum" :label="t('common_list.beanNum')" sortable="custom" width="120px" />
<el-table-column prop="buyBean" :label="t('common_list.permanentBean')" sortable="custom" width="120px" />
<el-table-column prop="freeBean" :label="t('common_list.freeBean')" sortable="custom" width="120px" />
<el-table-column prop="channel" :label="t('common_list.channel')" width="190px" show-overflow-tooltip />
<el-table-column prop="type" :label="t('common_list.memberType')" width="120px">
<template #default="scope">
{{consumeTypes.find(item => item.value === Number(scope.row.type))?.label || '未知类型'}}
{{consumeTypes.find(item => item.value === Number(scope.row.type))?.label || t('common_list.unknownType')}}
</template>
</el-table-column>
<el-table-column prop="consumeTime" label="加入时间" sortable="custom" width="180px" />
<el-table-column prop="consumeTime" :label="t('common_list.joinTime')" sortable="custom" width="190px" />
</el-table>
</div>
@ -571,33 +582,33 @@ const getTagText = (state) => {
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80%">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')" />
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -663,7 +674,7 @@ const getTagText = (state) => {
padding: 0 0.5vw;
.text {
width: 5vw;
width: 5.3vw;
font-size: 15px;
}

189
src/views/channelManage/reward/reward.vue

@ -1,16 +1,20 @@
<script setup>
import { computed, onMounted, ref, watch } from 'vue'
import { dayjs, ElMessage } from 'element-plus'
import {computed, onMounted, ref, watch} from 'vue'
import {dayjs, ElMessage} from 'element-plus'
import request from '@/util/http.js'
import API from '@/util/http.js'
import moment from 'moment'
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
import {useAdminStore} from "@/store/index.js";
import {storeToRefs} from "pinia";
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const adminStore = useAdminStore();
const { flag } = storeToRefs(adminStore);
const {flag} = storeToRefs(adminStore);
// flag
watch(flag, (newFlag, oldFlag) => {
watch(flag, (newFlag, oldFlag) => {
// flag
if (newFlag !== oldFlag) {
selectLiveBy()
@ -62,7 +66,7 @@ const getGift = async function () {
try {
const result = await request({
url: '/beanConsume/getLiveGift', // todo
data: { account: adminData.value.account }
data: {account: adminData.value.account}
})
console.log('请求礼物列表成功', result)
//
@ -72,7 +76,7 @@ const getGift = async function () {
console.log('请求礼物列表失败', error)
ElMessage({
type: 'error',
message: '获取礼物列表失败,请稍后重试'
message: t('elmessage.getGiftListFailed')
})
}
}
@ -84,7 +88,7 @@ const getChannel = async function () {
try {
const result = await request({
url: '/beanConsume/getLiveChannel', // todo
data: { account: adminData.value.account }
data: {account: adminData.value.account}
})
console.log('请求频道列表成功', result)
//
@ -94,19 +98,19 @@ const getChannel = async function () {
console.log('请求频道列表失败', error)
ElMessage({
type: 'error',
message: '获取频道列表失败,请稍后重试'
message: t('elmessage.getChannelListFailed')
})
}
}
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 }
{label: t('consume.consumeTypes.1'), value: 1},
{label: t('consume.consumeTypes.2'), value: 2},
{label: t('consume.consumeTypes.3'), value: 3},
{label: t('consume.consumeTypes.4'), value: 4},
{label: t('consume.consumeTypes.5'), value: 5},
{label: t('consume.consumeTypes.6'), value: 6}
])
//
const handleTypeChange = (value) => {
@ -149,7 +153,7 @@ const getDept = async function () {
// url: '/general/dept',
url: '/beanConsume/getDept', // todo
data: { account: adminData.value.account }
data: {account: adminData.value.account}
})
console.log('请求地区列表成功', result)
//
@ -159,7 +163,7 @@ const getDept = async function () {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
message: t('elmessage.getRegionListFailed')
})
}
}
@ -254,7 +258,7 @@ const selectLiveBy = async function (val) {
payType: 1, // payType 1
beanConsumeLive: {
...beanConsumeLive.value,
flag: flag.value
flag: flag.value
}
};
@ -288,7 +292,7 @@ const search = function () {
if (beanConsumeLive.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(beanConsumeLive.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
@ -423,6 +427,7 @@ const exportExcel = async function () {
roleId: adminData.value.roleId,
flag: flag.value,
}
}
// 便
@ -430,16 +435,16 @@ const exportExcel = async function () {
try {
console.log('2')
const res = await API({ url: '/export/exportLive', data: params });
const res = await API({url: '/export/exportLive', data: params});
console.log('导出请求响应:', res);
if (res.code === 200) {
ElMessage.success('导出成功');
ElMessage.success(t('elmessage.exportSuccess'));
} else {
ElMessage.error(res.message || '导出失败,请稍后重试');
ElMessage.error(res.message || t('elmessage.exportFailed'));
}
} catch (error) {
console.error('导出请求出错:', error);
ElMessage.error('导出失败,请稍后重试');
ElMessage.error(t('elmessage.exportFailed'));
}
}
const exportListVisible = ref(false)
@ -459,18 +464,18 @@ const exportListLoading = ref(false)
const getExportList = async () => {
exportListLoading.value = true
try {
const result = await API({ url: '/export/export' })
const result = await API({url: '/export/export'})
if (result.code === 200) {
const filteredData = result.data.filter(item => {
return item.type === 6; //6
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -483,7 +488,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -505,15 +510,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
</script>
@ -523,42 +528,43 @@ const getTagText = (state) => {
<el-col style="margin-bottom: 1vh">
<div class="select">
<div class="selectRow">
<el-text class="text">精网号</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable/>
</div>
<div class="selectRow">
<el-text class="text">地区</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.dept" placeholder="请选择地区" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
<el-text class="text">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.dept" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 14vw;">
<el-text class="text">礼物名称</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.gift" placeholder="请选择礼物名称" clearable filterable
allow-create default-first-option>
<el-option v-for="(item, index) in gifts" :key="index" :label="item" :value="item" />
<el-text class="text">{{ t('common.giftName') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.gift" :placeholder="t('common.giftNamePlaceholder')" clearable
filterable
allow-create default-first-option>
<el-option v-for="(item, index) in gifts" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 12vw;">
<el-text class="textB" size="large">频道</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.liveChannel" placeholder="请选择频道" clearable
filterable allow-create default-first-option>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item" />
<div class="selectRow" style="min-width: 12vw;">
<el-text class="textB" size="large">{{ t('common.channel') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.liveChannel" :placeholder="t('common.channelPlaceholder')" clearable
filterable allow-create default-first-option>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 12vw;">
<el-text class="textB" size="large">直播间</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.liveName" placeholder="请输入直播间" clearable />
<div class="selectRow" style="min-width: 12vw;">
<el-text class="textB" size="large">{{ t('common.liveRoom') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.liveName" :placeholder="t('common.liveRoomPlaceholder')" clearable/>
</div>
</div>
</el-col>
<el-col>
<div class="select">
<div class="selectRow" style="width: 31.4vw;">
<el-text class="text">消费时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:480px"
@change="handleDatePickerChange" :default-time="defaultTime" />
<el-text class="text">{{ t('common.consumetime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="margin-right:1vw;width:480px"
@change="handleDatePickerChange" :default-time="defaultTime"/>
<div v-if="false">
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"> </el-button>
<el-button @click="getYesterday()" :type="activeTimeRange === 'yesterday' ? 'primary' : ''"> </el-button>
@ -566,83 +572,84 @@ const getTagText = (state) => {
</div>
</div>
<div class="selectRow" style="justify-content: flex-start;">
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
金豆总数{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(Math.abs(freeBean)) }}
{{ t('common.totalGoldBean') }}{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(Math.abs(freeBean)) }}
</div>
<div style="overflow-y: auto">
<el-table :data="tableData" style="width: 82vw" height="69vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table :data="tableData" style="width: 82vw" height="65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="name" :label="t('common_list.name')" width="150px" fixed="left" show-overflow-tooltip/>
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="gift" label="礼物" width="140px">
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="110px" fixed="left"/>
<el-table-column prop="dept" :label="t('common_list.market')" width="110px"/>
<el-table-column prop="gift" :label="t('common_list.gift')" width="150px">
</el-table-column>
<el-table-column prop="beanNum" label="金豆数量" sortable="custom" width="120px" />
<el-table-column prop="isBackpack" label="背包礼物" width="120px">
<el-table-column prop="beanNum" :label="t('common_list.beanNum')" sortable="custom" width="120px"/>
<el-table-column prop="isBackpack" :label="t('common_list.isBackpack')" width="120px">
<template #default="scope">
{{ scope.row.isBackpack == 1 ? '是' : '否' }}
{{ scope.row.isBackpack == 1 ? t('common_list.yes') : t('common_list.no') }}
</template>
</el-table-column>
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px" />
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px" />
<el-table-column prop="liveChannel" label="频道" width="120px" show-overflow-tooltip />
<el-table-column prop="liveName" label="直播间名称" width="160px" show-overflow-tooltip />
<el-table-column prop="consumeTime" label="消费时间" sortable="custom" width="180px" />
<el-table-column prop="buyBean" :label="t('common_list.permanentBean')" sortable="custom" width="120px"/>
<el-table-column prop="freeBean" :label="t('common_list.freeBean')" sortable="custom" width="120px"/>
<el-table-column prop="liveChannel" :label="t('common_list.channel')" width="120px" show-overflow-tooltip/>
<el-table-column prop="liveName" :label="t('common_list.liveRoomName')" width="160px" show-overflow-tooltip/>
<el-table-column prop="consumeTime" :label="t('common_list.consumetime')" sortable="custom" width="190px"/>
</el-table>
</div>
<el-pagination background :current-page="getObj.pageNum" :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]" style="margin-top: 20px;"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
<el-pagination background :current-page="getObj.pageNum" :page-size="getObj.pageSize"
:page-sizes="[5, 10, 20, 50, 100]" style="margin-top: 20px;"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80%">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')"/>
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
:disabled="scope.row.state !== 2">
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -675,7 +682,7 @@ const getTagText = (state) => {
:deep(.el-table__header-wrapper),
:deep(.el-table__body-wrapper),
:deep(.el-table__cell),
/* 表格 */
/* 表格 */
:deep(.el-table__body td) {
background-color: #F3FAFE !important;
}
@ -707,7 +714,7 @@ const getTagText = (state) => {
padding: 0 0.5vw;
.text {
width: 5vw;
width: 5.3vw;
font-size: 15px;
}

82
src/views/consume/bean/addBeanConsume.vue

@ -14,13 +14,17 @@ import throttle from 'lodash/throttle'
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
import _ from 'lodash'
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const user = ref({})
const getUser = async function (jwcode) {
if (consumeForm.value.jwcode) {
consumeForm.value.jwcode = consumeForm.value.jwcode.replace(/\s/g, '');
} else {
ElMessage.error('请先输入精网号')
ElMessage.error(t('elmessage.checkJwcode'))
return false
}
try {
@ -33,15 +37,15 @@ const getUser = async function (jwcode) {
if (result.code === 0) {
ElMessage.error(result.msg);
} else if (result.data === null) {
ElMessage.error("用户不存在");
ElMessage.error(t('elmessage.noUser'));
} else {
user.value = result.data;
console.log("用户信息", user.value);
ElMessage.success("查询成功");
ElMessage.success(t('elmessage.searchSuccess'));
}
} catch (error) {
console.log("请求失败", error);
ElMessage.error("精网号错误");
ElMessage.error(t('elmessage.jwcodeError'));
}
}
@ -60,22 +64,22 @@ const adminStore = useAdminStore()
const { adminData } = storeToRefs(adminStore)
const rules = reactive({
jwcode: [
{ required: true, message: '请输入精网号', trigger: 'blur' },
{ required: true, message: t('elmessage.checkJwcode'), trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('精网号不能为空'));
callback(new Error(t('elmessage.noEmptyJwcode')));
return;
}
if (/[^0-9]/.test(value)) {
callback(new Error('精网号只能包含数字'));
callback(new Error(t('elmessage.limitDigitJwcode')));
return;
}
callback();
}, trigger: 'blur'
}],
permanentBean: [
{ required: true, message: '请输入付费金豆数', trigger: 'change' },
{ required: true, message: t('elmessage.checkPayBean'), trigger: 'change' },
{
validator: (rule, value, callback) => {
if (!value) {
@ -83,13 +87,13 @@ const rules = reactive({
}
//
if (!/^\d+$/.test(value)) {
callback(new Error('请输入非负整数'));
callback(new Error(t('elmessage.checkNonNegative')));
return;
}
//
if (value.length > 6) {
callback(new Error('整数位数不能超过6位'));
callback(new Error(t('elmessage.limitSix')));
return;
}
callback();
@ -99,7 +103,7 @@ const rules = reactive({
}
],
freeBean: [
{ required: true, message: '请输入免费金豆数', trigger: 'change' },
{ required: true, message: t('elmessage.checkFreeBean'), trigger: 'change' },
{
validator: (rule, value, callback) => {
if (!value) {
@ -107,13 +111,13 @@ const rules = reactive({
}
//
if (!/^\d+$/.test(value)) {
callback(new Error('请输入非负整数'));
callback(new Error(t('elmessage.checkNonNegative')));
return;
}
//
if (value.length > 6) {
callback(new Error('整数位数不能超过6位'));
callback(new Error(t('elmessage.limitSix')));
return;
}
callback();
@ -122,7 +126,7 @@ const rules = reactive({
}
],
remark: [
{ required: true, message: '请输入备注', trigger: 'blur' }
{ required: true, message: t('elmessage.checkRemark'), trigger: 'blur' }
]
});
@ -143,11 +147,11 @@ const handleConsumeForm = async () => {
formRef.value.validate((valid) => {
if (valid) {
if (Number(consumeForm.value.permanentBean) === 0 && Number(consumeForm.value.freeBean) === 0) {
reject(new Error('付费金豆和免费金豆不能同时为0'));
reject(new Error(t('elmessage.noPayBeanFreeBeanZero')));
}
resolve(); //
} else {
reject(new Error('请检查并完善表单信息')); //
reject(new Error(t('elmessage.checkFormInfo'))); //
}
});
});
@ -167,11 +171,11 @@ const handleConsumeForm = async () => {
// }
await ElMessageBox.confirm(
'确认消耗吗?',
'提示',
t('consume.confirmConsume'),
t('consume.prompt'),
{
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
type: "primary",
lockScroll: false,
}
@ -189,7 +193,7 @@ const handleConsumeForm = async () => {
})
addDisabled.value = false
if (result.code == 200) {
ElMessage.success('新增成功')
ElMessage.success(t('elmessage.addsuccess'))
deleteConsumeForm()
user.value = {}
} else {
@ -197,7 +201,7 @@ const handleConsumeForm = async () => {
}
} catch (error) {
console.log('金豆新增充值失败');
ElMessage.error(error.message || '操作失败');
ElMessage.error(error.message || t('elmessage.operationFailed'));
}
}
const throttledHandleConsumeFormt = _.throttle(handleConsumeForm, 5000, {
@ -209,22 +213,22 @@ const throttledHandleConsumeFormt = _.throttle(handleConsumeForm, 5000, {
<div class="left">
<el-form :model="consumeForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px"
class="add-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-form-item prop="jwcode" :label="t('common_add.jwcode')" label-position="left">
<el-input v-model="consumeForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(consumeForm.jwcode)" style="margin-left: 20px">查询</el-button>
<el-button type="primary" @click="getUser(consumeForm.jwcode)" style="margin-left: 20px">{{ t('common.search') }}</el-button>
</el-form-item>
<el-form-item prop="permanentBean" label="付费金豆" label-position="left">
<el-form-item prop="permanentBean" :label="t('common_add.permanentBean')" label-position="left">
<el-input v-model="consumeForm.permanentBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="freeBean" label="免费金豆" label-position="left">
<el-form-item prop="freeBean" :label="t('common_add.freeBean')" label-position="left">
<el-input v-model="consumeForm.freeBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="remark" label="备注" label-position="left">
<el-form-item prop="remark" :label="t('common_add.remark')" label-position="left">
<el-input v-model="consumeForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-button @click="deleteConsumeForm" style="margin-left: 8.5vw;margin-top:1vw" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleConsumeForm" style="margin-top:1vw"> 提交
<el-button @click="deleteConsumeForm" style="margin-left: 9vw;margin-top:1vw" type="success">{{ t('common.reset') }}</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleConsumeForm" style="margin-top:1vw"> {{ t('common.submit') }}
</el-button>
</el-form>
</div>
@ -233,12 +237,12 @@ const throttledHandleConsumeFormt = _.throttle(handleConsumeForm, 5000, {
<div class="right">
<el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" label-position="left">
<el-text size="large" style="margin-left: 7vw">客户信息</el-text>
<el-text size="large" style="margin-left: 5vw">{{ t('common_add_user.customerInfo') }}</el-text>
<!-- 第一行姓名 + 当前付费金豆 -->
<div style="margin-top: 0.5vw;display:flex;">
<p style="width:6vw;">姓名:</p>
<p style="min-width:6vw;">{{ t('common_add_user.name') }}:</p>
<p style="color: #2fa1ff;width:6vw;">{{ user.name }}</p>
<p style="width:7vw;">当前付费金豆:</p>
<p style="width:7vw;">{{ t('common_add_user.permanentBean') }}:</p>
<p v-if="!isNaN(Number(user.permanentBean))" style="color: #2fa1ff;">{{ Number(user.permanentBean) }}</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
@ -246,17 +250,17 @@ const throttledHandleConsumeFormt = _.throttle(handleConsumeForm, 5000, {
<!-- 第二行精网号 + 免费金豆 -->
<div style="display:flex">
<p style="width:6vw;">精网号:</p>
<p style="width:6vw;">{{ t('common_add_user.jwcode') }}:</p>
<p style="color: #2fa1ff;width:6vw;">{{ user.jwcode }}</p>
<p style="width:7vw;">当前免费金豆:</p>
<p style="width:7vw;">{{ t('common_add_user.freeBean') }}:</p>
<p v-if="user.freeBean !== undefined" style="color: #2fa1ff;">{{ user.freeBean }}</p>
</div>
<!-- 第三行消费次数 + 所属门店 -->
<div style="display:flex">
<p style="width:6vw;">所属门店:</p>
<p style="width:6vw;">{{ t('common_add_user.store') }}:</p>
<p style="color: #2fa1ff;width:6vw;">{{ user.market }}</p>
<p style="width:7vw;">消耗金豆总数:</p>
<p style="width:7vw;">{{ t('common_add_user.consumeTotalBean') }}:</p>
<p style="color: #2fa1ff;" v-if="user.consumeSum != null">{{ user.consumeSum }}</p>
<p style="color: #2fa1ff;" v-else>{{ 0 }}</p>
</div>
@ -285,13 +289,13 @@ const throttledHandleConsumeFormt = _.throttle(handleConsumeForm, 5000, {
.right {
flex: 1;
display: flex;
float: left;
// float: left;
.customer-info {
width: 35vw;
min-width: 35vw;
height: 28vh;
margin-top: 5vh;
display: flex;
// display: flex;
justify-content: center;
}
}

143
src/views/consume/bean/articleVideo.vue

@ -9,6 +9,10 @@ import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
const adminStore = useAdminStore();
const { flag } = storeToRefs(adminStore);
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// flag
watch(flag, (newFlag, oldFlag) => {
// flag
@ -55,9 +59,9 @@ const channels = ref([])
//
const consumeTypes = ref([
{ label: '打赏', value: 9 },
{ label: '打赏', value: 10 },
{ label: '付费购买', value: 11 },
{ label: t('consume.consumeTypes.9'), value: 9 },
{ label: t('consume.consumeTypes.10'), value: 10 },
{ label: t('consume.consumeTypes.11'), value: 11 },
])
// payMode
@ -110,7 +114,7 @@ const getDept = async function () {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
message: t('elmessage.getRegionListFailed')
})
}
}
@ -257,14 +261,14 @@ const search = function () {
if (beanConsumeArticle.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(beanConsumeArticle.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
if (beanConsumeArticle.value.articleId) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(beanConsumeArticle.value.articleId)) {
ElMessage.error('请检查文章ID格式')
ElMessage.error(t('elmessage.checkArticleIdFormat'))
return
}
}
@ -401,9 +405,16 @@ const exportExcel = async function () {
},
}
const res = await API({ url: '/export/exportArticle', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
try {
const res = await API({url: '/export/exportArticle', data: params});
if (res.code === 200) {
ElMessage.success(t('elmessage.exportSuccess'));
} else {
ElMessage.error(res.message || t('elmessage.exportFailed'));
}
} catch (error) {
console.error('导出请求出错:', error);
ElMessage.error(t('elmessage.exportFailed'));
}
}
const exportListVisible = ref(false)
@ -429,11 +440,11 @@ const getExportList = async () => {
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -446,7 +457,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -468,15 +479,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
</script>
@ -486,27 +497,27 @@ const getTagText = (state) => {
<el-col style="margin-bottom: 1vh; ">
<div class="select">
<div class="selectRow">
<el-text class="text" size="large">精网号</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text" size="large">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable />
</div>
<div class="selectRow">
<el-text class="text" size="large">地区</el-text>
<el-select class="selectContent" v-model="beanConsumeArticle.dept" placeholder="请选择地区" clearable>
<el-text class="text" size="large">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeArticle.dept" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
</el-select>
</div>
<div class="selectRow">
<el-text class="text" size="large">类型</el-text>
<el-select class="selectContent" style="width: 20px" v-model="beanConsumeArticle.payMode" placeholder="请选择类型"
<el-text class="text" size="large">{{ t('common.type') }}</el-text>
<el-select class="selectContent" style="width: 20px" v-model="beanConsumeArticle.payMode" :placeholder="t('common.typePlaceholder')"
clearable @change="handlePayModeChange">
<el-option label="打赏" value="0" />
<el-option label="付费购买" value="1" />
<el-option label="其他" value="2" />
<el-option :label="t('consume.reward')" value="0" />
<el-option :label="t('consume.payBuy')" value="1" />
<el-option :label="t('consume.other')" value="2" />
</el-select>
</div>
<div class="selectRow">
<el-text class="textB" size="large">文章/视频ID:</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.articleId" placeholder="请输入文章/视频ID" clearable />
<el-text class="textB" size="large">{{ t('common.articleVideoID') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.articleId" :placeholder="t('common.articleVideoIDPlaceholder')" clearable />
</div>
</div>
@ -515,9 +526,9 @@ const getTagText = (state) => {
<el-col>
<div class="select">
<div class="selectRow" style="width: 33vw;">
<el-text class="text" size="large">付费时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="width:25vw" @change="handleDatePickerChange"
<el-text class="text" size="large">{{ t('common.payTime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="width:25vw" @change="handleDatePickerChange"
value-format="YYYY-MM-DD HH:mm:ss" :default-time="defaultTime" />
<div v-if="false">
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>
@ -526,35 +537,35 @@ const getTagText = (state) => {
</div>
</div>
<div class="selectRow">
<el-text class="text" size="large">作者</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.author" placeholder="请输入作者" clearable />
<el-text class="text" size="large">{{ t('common.author') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.author" :placeholder="t('common.authorPlaceholder')" clearable />
</div>
<div class="selectRow">
<el-text class="textB" size="large">文章/视频标题</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.articleName" placeholder="请输入文章/视频标题" clearable />
<el-text class="textB" size="large">{{ t('common.articleVideoTitle') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeArticle.articleName" :placeholder="t('common.articleVideoTitlePlaceholder')" clearable />
</div>
</div>
</el-col>
<el-col>
<div class="selectButton">
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
金豆总数{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(Math.abs(freeBean)) }}
{{ t('common.totalGoldBean') }}{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(Math.abs(freeBean)) }}
</div>
<div style="overflow-y: auto">
<el-table :data="tableData" style="width: 82vw" height="57vh" @sort-change="handleSortChange"
<el-table :data="tableData" style="width: 82vw" height="61vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -562,26 +573,26 @@ const getTagText = (state) => {
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="name" :label="t('common_list.name')" width="150px" fixed="left" show-overflow-tooltip />
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="type" label="类型" width="120px">
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="110px" fixed="left" />
<el-table-column prop="dept" :label="t('common_list.market')" width="110px" />
<el-table-column prop="type" :label="t('consume.type')" width="120px">
<template #default="scope">
{{
Array.isArray(consumeTypes)
? consumeTypes.find(item => item.value === Number(scope.row.type))?.label || '未知类型'
: '未知类型'
? consumeTypes.find(item => item.value === Number(scope.row.type))?.label || t('common_list.unknownType')
: t('common_list.unknownType')
}}
</template>
</el-table-column>
<el-table-column prop="beanNum" label="金豆总数" sortable="custom" width="120px" />
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px" />
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px" />
<el-table-column prop="articleId" label="文章/视频ID" width="150px" />
<el-table-column prop="articleName" label="文章/视频标题" width="150px" show-overflow-tooltip />
<el-table-column prop="author" label="作者" width="120px" show-overflow-tooltip />
<el-table-column prop="consumeTime" label="付费时间" sortable="custom" width="180px">
<el-table-column prop="beanNum" :label="t('common_list.beanNumTotal')" sortable="custom" width="120px" />
<el-table-column prop="buyBean" :label="t('common_list.permanentBean')" sortable="custom" width="120px" />
<el-table-column prop="freeBean" :label="t('common_list.freeBean')" sortable="custom" width="120px" />
<el-table-column prop="articleId" :label="t('common_list.articleVideoID')" width="150px" />
<el-table-column prop="articleName" :label="t('common_list.articleVideoTitle')" width="150px" show-overflow-tooltip />
<el-table-column prop="author" :label="t('common_list.author')" width="120px" show-overflow-tooltip />
<el-table-column prop="consumeTime" :label="t('common_list.payTime')" sortable="custom" width="190px">
<template #default="scope">
{{ formatTime(scope.row.consumeTime) }}
</template>
@ -598,33 +609,33 @@ const getTagText = (state) => {
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80%">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')" />
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -693,11 +704,11 @@ const getTagText = (state) => {
padding: 0 0.5vw;
.text {
width: 5vw;
width: 5.3vw;
font-size: 15px;
}
.textB {
width: 7vw;
width: 7.3vw;
font-size: 15px;
}

18
src/views/consume/bean/beanConsume.vue

@ -6,36 +6,36 @@
:class="{ 'active-btn': activeTab === 'addBeanConsume' }"
@click="navigateTo('addBeanConsume')"
v-if="hasAdd"
style="width: 6.5vw;"
style="min-width: 6.5vw;"
>
新增消耗
{{ t('consume.addBeanConsume') }}
</el-button>
<el-button
class="no-active-btn"
:class="{ 'active-btn': activeTab === 'liveStream' }"
@click="navigateTo('liveStream')"
v-if="hasLive"
style="width: 6.5vw;"
style="min-width: 6.5vw;"
>
直播
{{ t('consume.liveStream') }}
</el-button>
<el-button
class="no-active-btn"
:class="{ 'active-btn': activeTab === 'dieHardFan' }"
@click="navigateTo('dieHardFan')"
v-if="hasFan"
style="width: 6.5vw;"
style="min-width: 6.5vw;"
>
铁粉
{{ t('consume.dieHardFan') }}
</el-button>
<el-button
class="no-active-btn"
:class="{ 'active-btn': activeTab === 'articleVideo' }"
@click="navigateTo('articleVideo')"
v-if="hasArticleVideo"
style="width: 6.5vw;"
style="min-width: 6.5vw;"
>
文章/视频
{{ t('consume.articleVideo') }}
</el-button>
</el-button-group>
</div>
@ -50,6 +50,8 @@ import {useRouter, useRoute} from 'vue-router';
import {storeToRefs} from 'pinia';
import {useAdminStore} from '@/store/index.js';
import {hasMenuPermission, permissionMapping} from "@/utils/menuTreePermission.js";
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const router = useRouter();
const route = useRoute();

127
src/views/consume/bean/dieHardFan.vue

@ -8,6 +8,10 @@ import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
const adminStore = useAdminStore();
const { flag } = storeToRefs(adminStore);
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// flag
watch(flag, (newFlag, oldFlag) => {
// flag
@ -68,7 +72,7 @@ const getChannel = async function () {
console.log('请求频道列表失败', error)
ElMessage({
type: 'error',
message: '获取频道列表失败,请稍后重试'
message: t('elmessage.getChannelListFailed')
})
}
}
@ -82,14 +86,14 @@ const getChannel = async function () {
//
const consumeTypes = ref([
{ label: '发礼物', value: 1 },
{ label: '发红包', value: 2 },
{ label: '发福袋', value: 3 },
{ label: '付费直播', value: 4 },
{ label: '加入粉丝团', value: 5 },
{ label: '发弹幕', value: 6 },
{ label: '单次付费', value: 7 },
{ label: '连续包月', value: 8 }
{ label: t('consume.consumeTypes.1'), value: 1 },
{ label: t('consume.consumeTypes.2'), value: 2 },
{ label: t('consume.consumeTypes.3'), value: 3 },
{ label: t('consume.consumeTypes.4'), value: 4 },
{ label: t('consume.consumeTypes.5'), value: 5 },
{ label: t('consume.consumeTypes.6'), value: 6 },
{ label: t('consume.consumeTypes.7'), value: 7 },
{ label: t('consume.consumeTypes.8'), value: 8 }
])
// //
@ -247,7 +251,7 @@ const search = function () {
if (beanConsumeFan.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(beanConsumeFan.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
@ -336,7 +340,7 @@ const getDept = async function () {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
message: t('elmessage.getRegionListFailed')
})
}
}
@ -404,9 +408,16 @@ const exportExcel = async function () {
},
}
const res = await API({ url: '/export/exportFan', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
try {
const res = await API({url: '/export/exportFan', data: params});
if (res.code === 200) {
ElMessage.success(t('elmessage.exportSuccess'));
} else {
ElMessage.error(res.message || t('elmessage.exportFailed'));
}
} catch (error) {
console.error('导出请求出错:', error);
ElMessage.error(t('elmessage.exportFailed'));
}
}
const exportListVisible = ref(false)
@ -432,11 +443,11 @@ const getExportList = async () => {
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -449,7 +460,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -471,15 +482,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
</script>
@ -489,18 +500,18 @@ const getTagText = (state) => {
<el-col style="margin-bottom: 1vh">
<div class="select">
<div class="selectRow">
<el-text class="text">精网号</el-text>
<el-input class="selectContent" v-model="beanConsumeFan.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeFan.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable />
</div>
<div class="selectRow">
<el-text class="text">地区</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.dept" placeholder="请选择地区" clearable>
<el-text class="text">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.dept" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item" />
</el-select>
</div>
<div class="selectRow">
<el-text class="text">频道</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.channel" placeholder="请选择频道" clearable filterable>
<el-text class="text">{{ t('common.channel') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeFan.channel" :placeholder="t('common.channelPlaceholder')" clearable filterable>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item" />
</el-select>
</div>
@ -509,9 +520,9 @@ const getTagText = (state) => {
<el-col>
<div class="select">
<div class="selectRow" style="width: 36vw;">
<el-text class="text" size="large">消费时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:25vw"
<el-text class="text" size="large">{{ t('common.consumetime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="margin-right:1vw;width:25vw"
@change="handleDatePickerChange" value-format="YYYY-MM-DD HH:mm:ss" :default-time="defaultTime" />
<div v-if="false">
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>
@ -520,24 +531,24 @@ const getTagText = (state) => {
</div>
</div>
<div class="selectRow" style="justify-content: flex-start;">
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
金豆总数{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(Math.abs(freeBean)) }}
{{ t('common.totalGoldBean') }}{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(Math.abs(freeBean)) }}
</div>
<div style="overflow-y: auto">
<el-table :data="tableData" style="width: 82vw" height="57vh" @sort-change="handleSortChange"
<el-table :data="tableData" style="width: 82vw" height="65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -545,20 +556,20 @@ const getTagText = (state) => {
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="name" :label="t('common_list.name')" width="150px" fixed="left" show-overflow-tooltip />
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="dept" label="地区" width="110px" />
<el-table-column prop="beanNum" label="金豆数量" sortable="custom" width="120px" />
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px" />
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px" />
<el-table-column prop="channel" label="频道" width="190px" show-overflow-tooltip />
<el-table-column prop="type" label="会员类型" width="120px">
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="110px" fixed="left" />
<el-table-column prop="dept" :label="t('common_list.market')" width="110px" />
<el-table-column prop="beanNum" :label="t('common_list.beanNum')" sortable="custom" width="120px" />
<el-table-column prop="buyBean" :label="t('common_list.permanentBean')" sortable="custom" width="120px" />
<el-table-column prop="freeBean" :label="t('common_list.freeBean')" sortable="custom" width="120px" />
<el-table-column prop="channel" :label="t('common_list.channel')" width="190px" show-overflow-tooltip />
<el-table-column prop="type" :label="t('common_list.memberType')" width="120px">
<template #default="scope">
{{consumeTypes.find(item => item.value === Number(scope.row.type))?.label || '未知类型'}}
{{consumeTypes.find(item => item.value === Number(scope.row.type))?.label || t('common_list.unknownType')}}
</template>
</el-table-column>
<el-table-column prop="consumeTime" label="加入时间" sortable="custom" width="180px" />
<el-table-column prop="consumeTime" :label="t('common_list.joinTime')" sortable="custom" width="190px" />
</el-table>
</div>
@ -571,33 +582,33 @@ const getTagText = (state) => {
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80%">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')" />
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -663,7 +674,7 @@ const getTagText = (state) => {
padding: 0 0.5vw;
.text {
width: 5vw;
width: 5.3vw;
font-size: 15px;
}

133
src/views/consume/bean/liveStream.vue

@ -6,6 +6,9 @@ import API from '@/util/http.js'
import moment from 'moment'
import {useAdminStore} from "@/store/index.js";
import {storeToRefs} from "pinia";
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const adminStore = useAdminStore();
const {flag} = storeToRefs(adminStore);
@ -73,7 +76,7 @@ const getGift = async function () {
console.log('请求礼物列表失败', error)
ElMessage({
type: 'error',
message: '获取礼物列表失败,请稍后重试'
message: t('elmessage.getGiftListFailed')
})
}
}
@ -95,19 +98,19 @@ const getChannel = async function () {
console.log('请求频道列表失败', error)
ElMessage({
type: 'error',
message: '获取频道列表失败,请稍后重试'
message: t('elmessage.getChannelListFailed')
})
}
}
//
const consumeTypes = ref([
{label: '发礼物', value: 1},
{label: '发红包', value: 2},
{label: '发福袋', value: 3},
{label: '付费直播', value: 4},
{label: '加入粉丝团', value: 5},
{label: '发弹幕', value: 6}
{label: t('consume.consumeTypes.1'), value: 1},
{label: t('consume.consumeTypes.2'), value: 2},
{label: t('consume.consumeTypes.3'), value: 3},
{label: t('consume.consumeTypes.4'), value: 4},
{label: t('consume.consumeTypes.5'), value: 5},
{label: t('consume.consumeTypes.6'), value: 6}
])
//
const handleTypeChange = (value) => {
@ -160,7 +163,7 @@ const getDept = async function () {
console.log('请求地区列表失败', error)
ElMessage({
type: 'error',
message: '获取地区列表失败,请稍后重试'
message: t('elmessage.getRegionListFailed')
})
}
}
@ -289,7 +292,7 @@ const search = function () {
if (beanConsumeLive.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(beanConsumeLive.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
@ -435,13 +438,13 @@ const exportExcel = async function () {
const res = await API({url: '/export/exportLive', data: params});
console.log('导出请求响应:', res);
if (res.code === 200) {
ElMessage.success('导出成功');
ElMessage.success(t('elmessage.exportSuccess'));
} else {
ElMessage.error(res.message || '导出失败,请稍后重试');
ElMessage.error(res.message || t('elmessage.exportFailed'));
}
} catch (error) {
console.error('导出请求出错:', error);
ElMessage.error('导出失败,请稍后重试');
ElMessage.error(t('elmessage.exportFailed'));
}
}
const exportListVisible = ref(false)
@ -468,11 +471,11 @@ const getExportList = async () => {
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -485,7 +488,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -507,15 +510,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
</script>
@ -525,42 +528,42 @@ const getTagText = (state) => {
<el-col style="margin-bottom: 1vh">
<div class="select">
<div class="selectRow">
<el-text class="text">精网号</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.jwcode" placeholder="请输入精网号" clearable/>
<el-text class="text">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable/>
</div>
<div class="selectRow">
<el-text class="text">地区</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.dept" placeholder="请选择地区" clearable>
<el-text class="text">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.dept" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="(item, index) in dept" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 14vw;">
<el-text class="text">礼物名称</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.gift" placeholder="请选择礼物名称" clearable
<el-text class="text">{{ t('common.giftName') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.gift" :placeholder="t('common.giftNamePlaceholder')" clearable
filterable
allow-create default-first-option>
<el-option v-for="(item, index) in gifts" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 12vw;">
<el-text class="textB" size="large">频道</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.liveChannel" placeholder="请选择频道" clearable
<div class="selectRow" style="min-width: 12vw;">
<el-text class="textB" size="large">{{ t('common.channel') }}</el-text>
<el-select class="selectContent" v-model="beanConsumeLive.liveChannel" :placeholder="t('common.channelPlaceholder')" clearable
filterable allow-create default-first-option>
<el-option v-for="(item, index) in channels" :key="index" :label="item" :value="item"/>
</el-select>
</div>
<div class="selectRow" style="width: 12vw;">
<el-text class="textB" size="large">直播间</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.liveName" placeholder="请输入直播间" clearable/>
<div class="selectRow" style="min-width: 12vw;">
<el-text class="textB" size="large">{{ t('common.liveRoom') }}</el-text>
<el-input class="selectContent" v-model="beanConsumeLive.liveName" :placeholder="t('common.liveRoomPlaceholder')" clearable/>
</div>
</div>
</el-col>
<el-col>
<div class="select">
<div class="selectRow" style="width: 31.4vw;">
<el-text class="text">消费时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:480px"
<el-text class="text">{{ t('common.consumetime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="margin-right:1vw;width:480px"
@change="handleDatePickerChange" :default-time="defaultTime"/>
<div v-if="false">
<el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"> </el-button>
@ -569,24 +572,24 @@ const getTagText = (state) => {
</div>
</div>
<div class="selectRow" style="justify-content: flex-start;">
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
金豆总数{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(Math.abs(freeBean)) }}
{{ t('common.totalGoldBean') }}{{ format3(Math.abs(permanentBean + freeBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(Math.abs(permanentBean)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(Math.abs(freeBean)) }}
</div>
<div style="overflow-y: auto">
<el-table :data="tableData" style="width: 82vw" height="56vh" @sort-change="handleSortChange"
<el-table :data="tableData" style="width: 82vw" height="65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -594,23 +597,23 @@ const getTagText = (state) => {
</template>
</el-table-column>
<!-- 固定姓名列 -->
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip/>
<el-table-column prop="name" :label="t('common_list.name')" width="150px" fixed="left" show-overflow-tooltip/>
<!-- 固定精网号列 -->
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left"/>
<el-table-column prop="dept" label="地区" width="110px"/>
<el-table-column prop="gift" label="礼物" width="140px">
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="110px" fixed="left"/>
<el-table-column prop="dept" :label="t('common_list.market')" width="110px"/>
<el-table-column prop="gift" :label="t('common_list.gift')" width="150px">
</el-table-column>
<el-table-column prop="beanNum" label="金豆数量" sortable="custom" width="120px"/>
<el-table-column prop="isBackpack" label="背包礼物" width="120px">
<el-table-column prop="beanNum" :label="t('common_list.beanNum')" sortable="custom" width="120px"/>
<el-table-column prop="isBackpack" :label="t('common_list.isBackpack')" width="120px">
<template #default="scope">
{{ scope.row.isBackpack == 1 ? '是' : '否' }}
{{ scope.row.isBackpack == 1 ? t('common_list.yes') : t('common_list.no') }}
</template>
</el-table-column>
<el-table-column prop="buyBean" label="付费金豆数" sortable="custom" width="120px"/>
<el-table-column prop="freeBean" label="免费金豆数" sortable="custom" width="120px"/>
<el-table-column prop="liveChannel" label="频道" width="120px" show-overflow-tooltip/>
<el-table-column prop="liveName" label="直播间名称" width="160px" show-overflow-tooltip/>
<el-table-column prop="consumeTime" label="消费时间" sortable="custom" width="180px"/>
<el-table-column prop="buyBean" :label="t('common_list.permanentBean')" sortable="custom" width="120px"/>
<el-table-column prop="freeBean" :label="t('common_list.freeBean')" sortable="custom" width="120px"/>
<el-table-column prop="liveChannel" :label="t('common_list.channel')" width="120px" show-overflow-tooltip/>
<el-table-column prop="liveName" :label="t('common_list.liveRoomName')" width="160px" show-overflow-tooltip/>
<el-table-column prop="consumeTime" :label="t('common_list.consumetime')" sortable="custom" width="190px"/>
</el-table>
</div>
<el-pagination background :current-page="getObj.pageNum" :page-size="getObj.pageSize"
@ -620,33 +623,33 @@ const getTagText = (state) => {
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80%">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80%">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名"/>
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')"/>
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -711,7 +714,7 @@ const getTagText = (state) => {
padding: 0 0.5vw;
.text {
width: 5vw;
width: 5.3vw;
font-size: 15px;
}

51
src/views/consume/gold/addCoinConsume.vue

@ -64,7 +64,8 @@ const addConsume = ref({
taskGold: null, //
remark: "",//
adminId: null,// id
adminName: adminData.value.adminName
adminName: adminData.value.adminName,
redMoney: 1 // 使1-使0-使
})
const Ref = ref(null)
const rules = reactive({
@ -163,11 +164,16 @@ function validateInput() {
//
const totalAvailableGold = (user.value.nowSumGold)
// 使
if (user.value.jwcode && sumGold > totalAvailableGold) {
ElMessage.error(t('elmessage.limitExceeded'));
// sumGoldnull
addConsume.value.sumGold = null;
return false;
// 使
if (addConsume.value.redMoney == 0) {
ElMessage.error(t('elmessage.limitExceeded'));
// sumGoldnull
addConsume.value.sumGold = null;
return false;
}
// 使validateRedLimit
}
return true;
@ -183,9 +189,12 @@ function validateRedLimit() {
ElMessage.error(t('elmessage.noEmptySumGold'));
return false;
}
if (sumGold + redMax < price) {
ElMessage.error(t('elmessage.limitRedAmount'));
return false;
// 使 +
if (addConsume.value.redMoney == 1) {
if (sumGold + redMax < price) {
ElMessage.error(t('elmessage.limitRedAmount'));
return false;
}
}
}
return true;
@ -267,14 +276,15 @@ const add = async function () {
permanentGold: addConsume.value.permanentGold * 100,
goodsName: addConsume.value.goodsName.value,
remark: addConsume.value.remark,
adminName: adminData.value.adminName
adminName: adminData.value.adminName,
redMoney: Number(addConsume.value.redMoney) // 1-使0-使
}
})
addDisabled.value = false
console.log("add请求", result);
//
handleResponse(result);
//
//
resetForm();
} catch (error) {
@ -319,6 +329,7 @@ function resetForm() {
remark: "",
adminId: adminData.value.id,
adminName: adminData.value.adminName,
redMoney: 1 // 使
}
console.log("重置表单")
@ -592,9 +603,14 @@ onMounted(async function () {
<el-input v-model="addConsume.price" style="width: 120px" disabled />
</el-form-item>
<el-form-item prop="sumGold" :label="t('common_add.consumeTotalGold')">
<!-- <el-form-item prop="sumGold" :label="t('common_add.consumeTotalGold')">
<el-input v-model="addConsume.sumGold" style="width: 120px"
@blur="validateRedLimit()" />
</el-form-item> -->
<el-form-item prop="sumGold" :label="t('common_add.consumeTotalGold')">
<el-input v-model="addConsume.sumGold" style="width: 120px" @blur="validateRedLimit()" />
<el-radio v-model="addConsume.redMoney" :label="1" style="margin-left: 10px;">使用红包</el-radio>
<el-radio v-model="addConsume.redMoney" :label="0">不使用红包</el-radio>
</el-form-item>
@ -623,10 +639,10 @@ onMounted(async function () {
</el-form-item>
<el-button type="success" @click="resetForm()" style="margin-left: 200px;margin-top:10px">{{ t('common.reset')
}}</el-button>
}}</el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore" style="margin-top:10px">{{
t('common.submit')
}}</el-button>
}}</el-button>
</el-form>
</div>
@ -674,7 +690,7 @@ onMounted(async function () {
</el-form-item>
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<p style="font-size: small; color: #b1b1b1">({{ $t('common_add_user.onlyStatisticsDataAfter20250101')
}})
}})
</p>
</el-form-item>
</el-col>
@ -767,8 +783,8 @@ onMounted(async function () {
</el-dialog>
<el-dialog v-model="ConsumeDialogVisible" :title="$t('common_add.operationConfirm')" :before-close="ConsumeDialogVisiblehandleClose"
:close-on-click-modal="false" width="480px">
<el-dialog v-model="ConsumeDialogVisible" :title="$t('common_add.operationConfirm')"
:before-close="ConsumeDialogVisiblehandleClose" :close-on-click-modal="false" width="480px">
<!-- 内容整体居中且收窄 -->
<div class="confirm-body">
<!-- 用户信息 -->
@ -819,7 +835,8 @@ onMounted(async function () {
<div>
<el-divider border-style="dashed" />
<p>{{ $t('common_add.similarRechargeRecords') }}</p>
· {{ ReadCookiesTime }} {{ $t('common_add.buy') }} {{ addConsume.goodsName.value }}({{ $t('common_add.operator') }}: {{ adminData.adminName }})
· {{ ReadCookiesTime }} {{ $t('common_add.buy') }} {{ addConsume.goodsName.value }}({{
$t('common_add.operator') }}: {{ adminData.adminName }})
</div>
<div style="margin-top: 10px">
<p>{{ $t('common_add.continueOperation') }}</p>

51
src/views/history/newHistory.vue

@ -1,38 +1,38 @@
<template>
<el-card class="card1">
<el-text size="large">姓名</el-text>
<el-input v-model="searchObj.name" placeholder="请输入姓名" style="width: 12vw;margin-right:1vw"
<el-text size="large">{{ t('common.name') }}</el-text>
<el-input v-model="searchObj.name" :placeholder="t('common.pleaseInputName')" style="width: 12vw;margin-right:1vw"
clearable></el-input>
<el-text size="large">精网号</el-text>
<el-input v-model="searchObj.jwcode" placeholder="请输入精网号" style="width: 12vw;margin-right:1vw"
<el-text size="large">{{ t('common.jwcode') }}</el-text>
<el-input v-model="searchObj.jwcode" :placeholder="t('common.jwcodePlaceholder')" style="width: 12vw;margin-right:1vw"
clearable></el-input>
<el-text size="large" style="width: 80px">更新时间</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" :default-time="defaultTime" range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" style="width: 25vw;margin-right:1vw" />
<el-text size="large" style="width: 80px">{{ t('common.updateTime') }}</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" :default-time="defaultTime" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="width: 25vw;margin-right:1vw" />
<el-button type="primary" @click="get">查询</el-button>
<el-button type="success" @click="resetSearch">重置</el-button>
<el-button type="primary" @click="get">{{ t('common.search') }}</el-button>
<el-button type="success" @click="resetSearch">{{ t('common.reset') }}</el-button>
</el-card>
<el-card class="card2" style="margin-top:10px" v-show="tableData.length > 0">
<el-table :data="tableData" style="width: 82vw;height:74vh">
<el-table-column type="index" label="序号" width="100" header-align="center" align="center">
<el-table-column type="index" :label="t('common_list.id')" width="100" header-align="center" align="center">
<template #default="scope">
{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}
</template>
</el-table-column>
<el-table-column prop="name" label="客户姓名" width="180" show-overflow-tooltip />
<el-table-column prop="jwcode" label="精网号" width="180" header-align="center" align="center" />
<el-table-column prop="num" label="数量" width="180" header-align="center" align="center" />
<el-table-column prop="updateType" show-overflow-tooltip label="更新类型" width="180" align="center" />
<el-table-column prop="freeGold" label="免费金币" width="180" align="center" />
<el-table-column prop="permanentGold" label="永久金币" width="180" align="center" />
<el-table-column prop="taskGold" label="任务金币" width="180" align="center" />
<el-table-column prop="operator" label="操作人" width="180" />
<el-table-column prop="createTime" label="更新时间" width="200" header-align="center" align="center" />
<el-table-column prop="remark" label="备注" show-overflow-tooltip width="200" align="center" />
<el-table-column prop="name" :label="t('common_list.customerName')" width="180" show-overflow-tooltip />
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="180" header-align="center" align="center" />
<el-table-column prop="num" :label="t('common_list.number')" width="180" header-align="center" align="center" />
<el-table-column prop="updateType" show-overflow-tooltip :label="t('common_list.type')" width="180" align="center" />
<el-table-column prop="freeGold" :label="t('common_list.freeGold')" width="180" align="center" />
<el-table-column prop="permanentGold" :label="t('common_list.permanentGold')" width="180" align="center" />
<el-table-column prop="taskGold" :label="t('common_list.taskGold')" width="180" align="center" />
<el-table-column prop="operator" :label="t('common_list.operator')" width="180" />
<el-table-column prop="createTime" :label="t('common_list.updateTime')" width="200" header-align="center" align="center" />
<el-table-column prop="remark" :label="t('common_list.remark')" show-overflow-tooltip width="200" align="center" />
</el-table>
<el-pagination background style="margin-top:20px" :current-page="pagination.pageNum"
:page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper"
@ -51,6 +51,11 @@ import dayjs from 'dayjs'
const adminStore = useAdminStore()
const { adminData, menuTree } = storeToRefs(adminStore)
import { permissionMapping, findMenuById } from "@/utils/menuTreePermission.js"
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0),
@ -71,7 +76,7 @@ const pagination = ref({
//
const get = async function () {
if(!canLook.value){
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
try {
@ -89,13 +94,13 @@ const get = async function () {
}
})
if (res.code == 200) {
ElMessage.success('查询成功')
ElMessage.success(t('elmessage.searchSuccess'))
tableData.value = res.data.list
console.log('tableData.value', res.data.list)
pagination.value.total = res.data.total
}
} else {
ElMessage.error('请输入姓名或精网号')
ElMessage.error(t('elmessage.checkNameOrJwcode'))
return
}
} catch (e) {

45
src/views/history/oldHistory.vue

@ -1,35 +1,35 @@
<template>
<el-card class="card1">
<el-text size="large">姓名</el-text>
<el-input v-model="searchObj.name" placeholder="请输入姓名" style="width: 12vw;margin-right:1vw"
<el-text size="large">{{ t('common.name') }}</el-text>
<el-input v-model="searchObj.name" :placeholder="t('common.pleaseInputName')" style="width: 12vw;margin-right:1vw"
clearable></el-input>
<el-text size="large">精网号</el-text>
<el-input v-model="searchObj.jwcode" placeholder="请输入精网号" style="width: 12vw;margin-right:1vw"
<el-text size="large">{{ t('common.jwcode') }}</el-text>
<el-input v-model="searchObj.jwcode" :placeholder="t('common.jwcodePlaceholder')" style="width: 12vw;margin-right:1vw"
clearable></el-input>
<el-text size="large" style="width: 80px">更新时间</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" :default-time="defaultTime" range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" style="width: 25vw;margin-right:1vw" />
<el-text size="large" style="width: 80px">{{ t('common.updateTime') }}</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" :default-time="defaultTime" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="width: 25vw;margin-right:1vw" />
<el-button type="primary" @click="getOld">查询</el-button>
<el-button type="success" @click="resetSearch">重置</el-button>
<el-button type="primary" @click="getOld">{{ t('common.search') }}</el-button>
<el-button type="success" @click="resetSearch">{{ t('common.reset') }}</el-button>
</el-card>
<el-card class="card2" style="margin-top:10px" v-show="tableData.length > 0">
<el-table :data="tableData" style="width: 82vw;height:74vh">
<el-table-column type="index" label="序号" width="100" header-align="center" align="center">
<el-table-column type="index" :label="t('common_list.id')" width="100" header-align="center" align="center">
<template #default="scope">
{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}
</template>
</el-table-column>
<el-table-column prop="name" label="客户姓名" width="180" show-overflow-tooltip />
<el-table-column prop="jwcode" label="精网号" width="180" header-align="center" align="center" />
<el-table-column prop="num" label="数量" width="180" header-align="center" align="center" />
<el-table-column prop="updateType" show-overflow-tooltip label="更新类型" width="180" align="center" />
<el-table-column prop="operator" label="操作人" width="180" />
<el-table-column prop="createTime" label="更新时间" width="200" header-align="center" align="center" />
<el-table-column prop="remark" label="备注" show-overflow-tooltip width="200" align="center" />
<el-table-column prop="name" :label="t('common_list.customerName')" width="180" show-overflow-tooltip />
<el-table-column prop="jwcode" :label="t('common_list.jwcode')" width="180" header-align="center" align="center" />
<el-table-column prop="num" :label="t('common_list.number')" width="180" header-align="center" align="center" />
<el-table-column prop="updateType" show-overflow-tooltip :label="t('common_list.type')" width="180" align="center" />
<el-table-column prop="operator" :label="t('common_list.operator')" width="180" />
<el-table-column prop="createTime" :label="t('common_list.updateTime')" width="200" header-align="center" align="center" />
<el-table-column prop="remark" :label="t('common_list.remark')" show-overflow-tooltip width="200" align="center" />
</el-table>
<el-pagination background style="margin-top:20px" :current-page="pagination.pageNum"
:page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper"
@ -48,6 +48,11 @@ import dayjs from 'dayjs'
const adminStore = useAdminStore()
const { adminData, menuTree } = storeToRefs(adminStore)
import { permissionMapping, findMenuById } from "@/utils/menuTreePermission.js"
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 2, 1, 23, 59, 59),
@ -68,7 +73,7 @@ const pagination = ref({
//
const getOld = async function () {
if(!canLook.value){
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
try {
@ -86,13 +91,13 @@ const getOld = async function () {
}
})
if (res.code == 200) {
ElMessage.success('查询成功')
ElMessage.success(t('elmessage.searchSuccess'))
tableData.value = res.data.list
console.log('tableData.value', res.data.list);
pagination.value.total = res.data.total
}
} else {
ElMessage.error('请输入姓名或精网号')
ElMessage.error(t('elmessage.checkNameOrJwcode'))
return
}
} catch (e) {

206
src/views/language/languageTranslate.vue

@ -3,13 +3,13 @@
<el-card class="card1" style="margin-bottom: 1vh;">
<div class="condition">
<div class="condition-item">
<el-text size="large">搜索</el-text>
<el-input v-model="searchForm.chineseSimplified" style="width: 12vw" placeholder="请输入原文内容" clearable />
<el-text size="large">{{ t('common.searchLabel') }}</el-text>
<el-input v-model="searchForm.chineseSimplified" style="width: 12vw" :placeholder="t('common.searchPlaceholder')" clearable />
</div>
<!-- 移除语言状态筛选 -->
<div class="btn">
<el-button type="primary" @click="search">搜索</el-button>
<el-button type="success" @click="reset">重置</el-button>
<el-button type="primary" @click="search">{{ t('common.searchButton') }}</el-button>
<el-button type="success" @click="reset">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-card>
@ -17,20 +17,20 @@
<el-card class="card2">
<!-- 功能按钮区域 -->
<div class="add-item">
<el-button type="success" @click="handleAdd">添加</el-button>
<el-button type="success" @click="handleAdd">{{ t('common.add') }}</el-button>
<!-- 后续需求 -->
<!-- <el-button class="add-item-export" @click="handleBatchImport">批量导入</el-button> -->
<el-button class="add-item-export" @click="handleBatchImport">{{ t('common.batchImport') }}</el-button>
</div>
<div>
<el-table :data="tableData" style="width: 82vw;height:72vh;" :row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}</span>
</template>
</el-table-column>
<el-table-column prop="chineseSimplified" label="原文(中文)" width="180px">
<el-table-column prop="chineseSimplified" :label="t('common_list.originalChinese')" width="180px">
<template #default="scope">
<el-tooltip :content="scope.row.chineseSimplified" placement="top"
v-if="scope.row.chineseSimplified && scope.row.chineseSimplified.length > 20">
@ -40,7 +40,7 @@
</template>
</el-table-column>
<el-table-column prop="english" label="英文" width="200px" header-align="center">
<el-table-column prop="english" :label="t('common_list.english')" width="200px" header-align="center">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="flex: 1;">
@ -52,13 +52,13 @@
</div>
<el-tag :type="scope.row.english ? 'success' : 'info'" size="small"
style="margin-left: 8px;">
{{ scope.row.english ? '已翻译' : '未翻译' }}
{{ scope.row.english ? t('common_list.translated') : t('common_list.untranslated') }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="thai" label="泰语" width="200px" header-align="center">
<el-table-column prop="thai" :label="t('common_list.thai')" width="200px" header-align="center">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="flex: 1;">
@ -69,13 +69,13 @@
<span v-else>{{ scope.row.thai }}</span>
</div>
<el-tag :type="scope.row.thai ? 'success' : 'info'" size="small" style="margin-left: 8px;">
{{ scope.row.thai ? '已翻译' : '未翻译' }}
{{ scope.row.thai ? t('common_list.translated') : t('common_list.untranslated') }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="chineseTraditional" label="繁体中文" width="180px" header-align="center">
<el-table-column prop="chineseTraditional" :label="t('common_list.chineseTraditional')" width="180px" header-align="center">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="flex: 1;">
@ -87,13 +87,13 @@
</div>
<el-tag :type="scope.row.chineseTraditional ? 'success' : 'info'" size="small"
style="margin-left: 8px;">
{{ scope.row.chineseTraditional ? '已翻译' : '未翻译' }}
{{ scope.row.chineseTraditional ? t('common_list.translated') : t('common_list.untranslated') }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="malay" label="马来语" width="200px" header-align="center">
<el-table-column prop="malay" :label="t('common_list.malay')" width="200px" header-align="center">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="flex: 1;">
@ -104,13 +104,13 @@
<span v-else>{{ scope.row.malay }}</span>
</div>
<el-tag :type="scope.row.malay ? 'success' : 'info'" size="small" style="margin-left: 8px;">
{{ scope.row.malay ? '已翻译' : '未翻译' }}
{{ scope.row.malay ? t('common_list.translated') : t('common_list.untranslated') }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="vietnamese" label="越南语" width="200px" header-align="center">
<el-table-column prop="vietnamese" :label="t('common_list.vietnamese')" width="200px" header-align="center">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="flex: 1;">
@ -122,24 +122,24 @@
</div>
<el-tag :type="scope.row.vietnamese ? 'success' : 'info'" size="small"
style="margin-left: 8px;">
{{ scope.row.vietnamese ? '已翻译' : '未翻译' }}
{{ scope.row.vietnamese ? t('common_list.translated') : t('common_list.untranslated') }}
</el-tag>
</div>
</template>
</el-table-column>
<!-- 移除状态列 -->
<el-table-column prop="configTime" label="配置时间" width="180px" header-align="center">
<el-table-column prop="configTime" :label="t('common_list.configTime')" width="180px" header-align="center">
<template #default="scope">
{{ moment(scope.row.configTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" width="155px" fixed="right" header-align="center">
<el-table-column prop="operation" :label="t('common_list.operation')" width="155px" fixed="right" header-align="center">
<template #default="scope">
<div style="display:flex; justify-content:center; ">
<el-button type="primary" text @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="danger" text @click="handleDelete(scope.row)">删除</el-button>
<el-button type="primary" text @click="handleEdit(scope.row)">{{ t('common.edit') }}</el-button>
<el-button type="danger" text @click="handleDelete(scope.row)">{{ t('common.delete') }}</el-button>
</div>
</template>
</el-table-column>
@ -148,16 +148,9 @@
<!-- 分页组件 -->
<div style="margin-top: 10px;display: flex;">
<el-pagination
background
v-model:current-page="pagination.pageNum"
v-model:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
style="margin-top: 1vh;"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<el-pagination background v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" style="margin-top: 1vh;"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</el-card>
@ -166,61 +159,54 @@
@cancel="handleDeleteCancel" @close="handleDeleteClose" />
<!-- 编辑对话框 -->
<el-dialog v-model="showEditDialog" :title="editForm.id ? '编辑翻译' : '新增翻译'" width="30vw" draggable
:close-on-click-modal="false"
style="background-color: rgb(243,250,254);"
>
<el-form :model="editForm" label-width="120px">
<el-form-item label="原文(中文):">
<el-input v-model="editForm.chineseSimplified" placeholder="请输入原文内容" show-word-limit />
<el-dialog v-model="showEditDialog" :title="editForm.id ? t('common_add.editTranslation') : t('common_add.addTranslation')" width="30vw" draggable
:close-on-click-modal="false" style="background-color: rgb(243,250,254);">
<el-form :model="editForm" label-width="155px">
<el-form-item :label="t('common_add.originalChinese') + ':'">
<el-input v-model="editForm.chineseSimplified" :placeholder="t('common_add.originalChinesePlaceholder')" show-word-limit />
</el-form-item>
<el-form-item label="英文:">
<el-input v-model="editForm.english" placeholder="请输入英文翻译" show-word-limit />
<el-form-item :label="t('common_add.english') + ':'">
<el-input v-model="editForm.english" :placeholder="t('common_add.englishPlaceholder')" show-word-limit />
</el-form-item>
<el-form-item label="泰语:">
<el-input v-model="editForm.thai" placeholder="请输入泰语翻译" show-word-limit />
<el-form-item :label="t('common_add.thai') + ':'">
<el-input v-model="editForm.thai" :placeholder="t('common_add.thaiPlaceholder')" show-word-limit />
</el-form-item>
<el-form-item label="繁体中文:">
<el-input v-model="editForm.chineseTraditional" placeholder="请输入繁体中文翻译" show-word-limit />
<el-form-item :label="t('common_add.chineseTraditional') + ':'">
<el-input v-model="editForm.chineseTraditional" :placeholder="t('common_add.chineseTraditionalPlaceholder')" show-word-limit />
</el-form-item>
<el-form-item label="马来语:">
<el-input v-model="editForm.malay" placeholder="请输入马来语翻译" show-word-limit />
<el-form-item :label="t('common_add.malay') + ':'">
<el-input v-model="editForm.malay" :placeholder="t('common_add.malayPlaceholder')" show-word-limit />
</el-form-item>
<el-form-item label="越南语:">
<el-input v-model="editForm.vietnamese" placeholder="请输入越南语翻译" show-word-limit />
<el-form-item :label="t('common_add.vietnamese') + ':'">
<el-input v-model="editForm.vietnamese" :placeholder="t('common_add.vietnamesePlaceholder')" show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showEditDialog = false">取消</el-button>
<el-button @click="showEditDialog = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" :loading="saveLoading" @click="handleSave">
{{ saveLoading ? '保存中...' : '保存' }}
{{ saveLoading ? t('common.saving') : t('common.save') }}
</el-button>
</template>
</el-dialog>
<!-- 批量导入对话框 -->
<el-dialog v-model="showImportDialog" title="批量导入" width="40vw" draggable>
<div style="margin-bottom: 20px;">
<el-text>下载导入模板</el-text>
<el-button type="text" @click="downloadTemplate">中文/英文/泰语/繁体中文/马来语/越南语模板</el-button>
</div>
<el-upload class="upload-demo" drag action="#" :auto-upload="false" :on-change="handleFileChange"
:show-file-list="false">
<el-dialog v-model="showImportDialog" :title="t('common.import')" width="40vw" draggable>
<el-upload class="upload-demo" drag action="#" :auto-upload="false" :on-change="handleFileChange" limit="1"
:on-exceed="handleExceed">
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__text">{{ t('common.uploadHint') }}</div>
</el-upload>
<template #footer>
<el-button @click="showImportDialog = false">取消</el-button>
<el-button type="primary" @click="handleImport">导入</el-button>
<el-button @click="showImportDialog = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" :loading="importLoading" @click="handleImport">{{ t('common.import') }}</el-button>
</template>
</el-dialog>
</template>
@ -273,7 +259,9 @@ const editForm = ref({
configTime: new Date()
})
//
const uploadFile = ref(null)
const importLoading = ref(false)
// 使
const truncateText = (text) => {
@ -319,7 +307,7 @@ const getTranslationList = async () => {
}
} catch (error) {
console.error('获取翻译列表失败:', error)
ElMessage.error('获取数据失败')
ElMessage.error(t('elmessage.requestFailed'))
}
}
@ -364,7 +352,7 @@ const getMenuTree = async function () {
} catch (error) {
console.error('菜单数据请求失败:', error)
// return { code: 500, msg: '' }
ElMessage.error('网络异常')
ElMessage.error(t('elmessage.inNetworkError'))
adminStore.clearState()
}
// console.log('1')
@ -379,7 +367,7 @@ const handleSave = async () => {
const fields = ['english', 'thai', 'chineseTraditional', 'malay', 'vietnamese']
for (const field of fields) {
if (editForm.value[field] && /<[^>]*>/.test(editForm.value[field])) {
ElMessage.error('译文仅支持纯文本,不支持HTML标签')
ElMessage.error(t('elmessage.onlyPlainText'))
saveLoading.value = false //
return
}
@ -396,7 +384,7 @@ const handleSave = async () => {
await getMenuTree()
if (res.code === 200) {
ElMessage.success(editForm.value.id ? '编辑成功' : '添加成功')
ElMessage.success(editForm.value.id ? t('elmessage.editSuccess') : t('elmessage.addSuccess'))
showEditDialog.value = false
// getTranslationList()
@ -406,14 +394,14 @@ const handleSave = async () => {
}, 500)
} else if (res.code === 0) {
//
ElMessage.error(res.msg || '操作失败')
ElMessage.error(res.msg || t('elmessage.operationFailed'))
} else {
//
ElMessage.error(res.msg || '操作失败')
ElMessage.error(res.msg || t('elmessage.operationFailed'))
}
} catch (error) {
console.error('保存失败:', error)
ElMessage.error('保存失败')
ElMessage.error(t('elmessage.submitFailed'))
} finally {
//
saveLoading.value = false
@ -437,7 +425,7 @@ const handleDeleteConfirm = async () => {
//
await getMenuTree()
if (res.code === 200) {
ElMessage.success('删除成功')
ElMessage.success(t('elmessage.deleteSuccess'))
// getTranslationList()
//
setTimeout(() => {
@ -446,7 +434,7 @@ const handleDeleteConfirm = async () => {
}
} catch (error) {
console.error('删除失败:', error)
ElMessage.error('删除失败')
ElMessage.error(t('elmessage.operationFailed'))
} finally {
showDeleteDialog.value = false
currentDeleteRow.value = null
@ -472,22 +460,72 @@ const handleBatchImport = () => {
showImportDialog.value = true
}
//
const downloadTemplate = () => {
//
ElMessage.info('模板下载功能待实现')
}
//
const handleFileChange = (file) => {
//
console.log('文件变化:', file)
//
if (file.raw.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' &&
file.raw.type !== 'application/vnd.ms-excel') {
ElMessage.error(t('elmessage.onlyExcelAllowed'))
return
}
// 5MB
if (file.raw.size > 5 * 1024 * 1024) {
ElMessage.error(t('elmessage.fileTooLarge5MB'))
return
}
//
uploadFile.value = file.raw
ElMessage.success(t('elmessage.fileSelectSuccess'))
}
//
const handleExceed = (files, fileList) => {
ElMessage.warning(t('elmessage.uploadLimitOne'));
};
//
const handleImport = () => {
//
ElMessage.info('导入功能待实现')
const handleImport = async () => {
if (!uploadFile.value) {
ElMessage.warning(t('elmessage.selectFileFirst'))
return
}
importLoading.value = true
try {
const formData = new FormData()
formData.append('file', uploadFile.value)
const res = await request({
url: '/language/batchImport',
method: 'POST',
data: formData,
headers: {
'Content-Type': 'multipart/form-data' //
}
})
if (res.code === 200) {
ElMessage.success(t('elmessage.importSuccess'))
//
await getMenuTree()
//
setTimeout(() => {
window.location.reload()
}, 500)
//
showImportDialog.value = false
//
uploadFile.value = null
} else {
ElMessage.error(res.msg || t('elmessage.importFailed'))
}
} catch (error) {
console.error('导入失败:', error)
ElMessage.error(t('elmessage.importFailedNetworkOrFormat'))
} finally {
importLoading.value = false
}
}
//
@ -586,4 +624,4 @@ onMounted(() => {
width: 100%;
height: 180px;
}
</style>
</style>

95
src/views/managerecharge/rate.vue

@ -1,13 +1,16 @@
<script setup>
import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import request from '@/util/http'
import {useAdminStore} from "@/store/index.js";
import {storeToRefs} from "pinia";
import {permissionMapping, hasMenuPermission} from "@/utils/menuTreePermission.js"
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
import { permissionMapping, hasMenuPermission } from "@/utils/menuTreePermission.js"
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const adminStore = useAdminStore()
const {adminData, menuTree} = storeToRefs(adminStore)
const { adminData, menuTree } = storeToRefs(adminStore)
const regeEdit = ref(false)
const editFormRef = ref(null)
const tableData = ref([])
@ -66,16 +69,16 @@ const rateNames = [
//
const checkFreeGoldRadio = function (rule, value, callback) {
if (value == '0' || value == null || value == '') {
callback(new Error('请输入汇率比'))
callback(new Error(t('elmessage.pleaseInputRate')))
} else if (value < 0 || isNaN(value)) {
callback(new Error('请输入正确的格式'))
callback(new Error(t('elmessage.pleaseInputCorrectRateFormat')))
} else {
callback()
}
}
//
const rules = reactive({
num: [{validator: checkFreeGoldRadio, trigger: 'blur'}],
num: [{ validator: checkFreeGoldRadio, trigger: 'blur' }],
})
//
const formSize = ref('default')
@ -94,7 +97,7 @@ const getAllRate = async function (val) {
total.value = result.data.total
} catch (error) {
console.log('请求失败', error);
ElMessage.error('请求失败');
ElMessage.error(t('elmessage.requestFailed'));
}
}
const handlePageSizeChange = function (val) {
@ -110,7 +113,7 @@ const getEditData = async function (row) {
console.log('搜索参数', getObj.value)
const result = await request({
url: '/rate/selectById',
data: {id: row.id}
data: { id: row.id }
})
console.log('根据id查 请求成功', result)
rateEdit.value.id = row.id
@ -135,7 +138,7 @@ const initPermissions = () => {
//
const editRate = async function () {
if (!hasrateEdit) {
ElMessage.error('暂无权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
//
@ -200,18 +203,18 @@ function formatDate(value) {
function handleInput(value) {
// 使
if (value.includes('。') || /[^\d.]/g.test(value)) {
ElMessage.warning('请输入正确的符号');
ElMessage.warning(t('elmessage.pleaseInputCorrectSymbol'));
// value = value.replace('', '.');
}
//
const parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
ElMessage.warning('只能包含一个小数点');
ElMessage.warning(t('elmessage.onlyOneDecimalPoint'));
}
//
if (value.startsWith('-')) {
ElMessage.warning('不允许输入负数');
ElMessage.warning(t('elmessage.noNegativeNumber'));
value = value.substring(1);
}
//
@ -220,13 +223,13 @@ function handleInput(value) {
//
if (parts[0].length > 6) {
parts[0] = parts[0].slice(0, 6)
ElMessage.info('整数部分最多允许六位')
ElMessage.info(t('elmessage.integerPartLimit'))
}
//
if (parts[1].length > 7) {
parts[1] = parts[1].slice(0, 7)
value = parts[0] + '.' + parts[1]
ElMessage.info('最多允许七位小数')
ElMessage.info(t('elmessage.decimalPartLimit'))
} else {
value = parts[0] + '.' + parts[1]
}
@ -234,7 +237,7 @@ function handleInput(value) {
//
if (value.length > 6) {
value = value.slice(0, 6)
ElMessage.info('整数部分最多允许六位')
ElMessage.info(t('elmessage.integerPartLimit'))
}
}
// 0
@ -258,15 +261,15 @@ onMounted(async function () {
<template>
<el-card class="card2" style="width:81vw;height:92vh" v-if="hasrateShow">
<el-table :data="tableData" v-if="(tableData.flag = 1)">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
</template>
</el-table-column>
<el-table-column prop="rateName" label="货币名称" :span="2"/>
<el-table-column prop="num" label="汇率" :span="2">
<el-table-column prop="rateName" :label="t('common_list.rateName')" :span="2" />
<el-table-column prop="num" :label="t('common_list.num')" :span="2">
<template #default="scope">
<p>
{{ scope.row.num }} 1
@ -274,17 +277,17 @@ onMounted(async function () {
</template>
</el-table-column>
<el-table-column prop="updateTime" label="更新时间" :span="3">
<el-table-column prop="updateTime" :label="t('common_list.updateTime')" :span="3">
<template #default="scope">
<span>{{ formatDate(scope.row.updateTime) }}</span>
</template>
</el-table-column>
<el-table-column v-if="hasrateEdit" label="操作" :span="3">
<el-table-column v-if="hasrateEdit" :label="t('common_list.operation')" :span="3">
<template #default="scope">
<el-link :underline="false" class="edit-btn" @click="() => {
regeEdit = true
getEditData(scope.row)
}">编辑
}">{{ t('common.edit') }}
</el-link>
</template>
</el-table-column>
@ -293,40 +296,40 @@ onMounted(async function () {
<!-- 分页 -->
<div class="pagination">
<el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
<!-- 这是编辑弹窗 -->
<el-dialog align-center v-model="regeEdit" title="修改汇率" width="30vw" :close-on-click-modal="false"
@close="handleEditDialogClose">
<el-dialog align-center v-model="regeEdit" :title="t('rate.modifyRate')" width="30vw" :close-on-click-modal="false"
@close="handleEditDialogClose">
<el-form ref="editFormRef" :model="rateEdit" :rules="rules" label-width="auto" class="edit-form" :size="formSize"
status-icon>
<el-form-item prop="rateName" label="货币名称:">
<el-input v-model="rateEdit.rateName" disabled style="width: 10vw"/>
status-icon>
<el-form-item prop="rateName" :label="t('common_list.rateName')">
<el-input v-model="rateEdit.rateName" disabled style="width: 10vw" />
</el-form-item>
<el-form-item prop="num" label="汇率:">
<el-input v-model="rateEdit.num" @update:modelValue="handleInput" style="width: 120px"/>
<el-form-item prop="num" :label="t('common_list.num')">
<el-input v-model="rateEdit.num" @update:modelValue="handleInput" style="width: 120px" />
<span class="unit">:1</span>
<span class="rate-tip">
(提示当前规则每
<span>{{ rateEdit.num }}</span>
<span>{{ rateEdit.rateName }}</span>可兑换 1 新币)
</span>
</el-form-item>
<div class="rate-tip">
{{ t('rate.prompt1') }}
<span>{{ rateEdit.num }}</span>
<span>{{ rateEdit.rateName }}</span>{{ t('rate.prompt2') }}
</div>
</el-form>
<div class="dialog-footer">
<el-button type="primary" @click="edit">修改</el-button>
<el-button @click="cancelEdit">取消</el-button>
<el-button type="primary" @click="edit">{{ t('common.modify') }}</el-button>
<el-button @click="cancelEdit">{{ t('common.cancel') }}</el-button>
</div>
</el-dialog>
</template>
<style scoped>
.card1 {
background: #F3FAFE;
}
@ -334,7 +337,7 @@ onMounted(async function () {
:deep(.el-table__header-wrapper),
:deep(.el-table__body-wrapper),
:deep(.el-table__cell),
/* 表格 */
/* 表格 */
:deep(.el-table__body td) {
background-color: #F3FAFE !important;
}
@ -371,6 +374,7 @@ onMounted(async function () {
.rate-tip {
hyphens: auto;
margin-left: 1.4vw;
}
/**表单的卡片样式**/
@ -383,7 +387,7 @@ onMounted(async function () {
:deep(.el-table__header-wrapper),
:deep(.el-table__body-wrapper),
:deep(.el-table__cell),
/* 表格 */
/* 表格 */
:deep(.el-table__body td) {
background-color: #F3FAFE !important;
}
@ -397,5 +401,4 @@ onMounted(async function () {
:deep(.el-table__row:hover > .el-table__cell) {
background-color: #E5EBFE !important;
}
</style>

190
src/views/moneyManage/executor/executor.vue

@ -2,24 +2,24 @@
<el-card style="margin-bottom: 0.5vh;background-color: rgb(243,250,254);">
<div class="condition1">
<div class="search">
<el-text size="large" style="width:4vw;">姓名</el-text>
<el-input v-model="searchForm.name" placeholder="请输入姓名" style="width:9vw;" clearable />
<el-text size="large" style="width:4vw;">{{ t('common.name') }}</el-text>
<el-input v-model="searchForm.name" :placeholder="t('common.pleaseInputName')" style="width:9vw;" clearable />
</div>
<div class="search">
<el-text size="large" style="width:4vw;">精网号</el-text>
<el-input v-model="searchForm.jwcode" placeholder="请输入精网号" style="width:9vw;" clearable />
<el-text size="large" style="width:4vw;">{{ t('common.jwcode') }}</el-text>
<el-input v-model="searchForm.jwcode" :placeholder="t('common.jwcodePlaceholder')" style="width:9vw;" clearable />
</div>
<div class="search">
<el-text size="large" style="width:4vw;">产品名称</el-text>
<el-text size="large" style="width:4vw;">{{ t('common.productName') }}</el-text>
<el-cascader v-model="searchForm.goodsName" :options="productList" style="width: 10vw;" clearable />
</div>
<div class="search" v-if="adminData.markets === '总部'">
<el-text size="large" style="width:4vw;">所属地区</el-text>
<el-cascader style="width: 9vw;" v-model="searchForm.markets" :options="market" placeholder="请选择所属地区"
<div class="search" v-if="adminData.markets === t('common.markets.headquarter')">
<el-text size="large" style="width:4vw;">{{ t('common.market') }}</el-text>
<el-cascader style="width: 9vw;" v-model="searchForm.markets" :options="market" :placeholder="t('common.marketPlaceholder')"
clearable />
</div>
<div class="search">
<el-text size="large" style="width:4vw;">退款币种</el-text>
<el-text size="large" style="width:4vw;">{{ t('common.refundCurrency') }}</el-text>
<el-select v-model="searchForm.refundCurrency" style="width:9vw;" clearable>
<el-option v-for="item in currencies" :key="item" :label="item" :value="item" />
</el-select>
@ -27,96 +27,97 @@
</div>
<div class="condition1">
<div class="search2">
<el-text size="large" style="width:4vw;">退款途径</el-text>
<el-text size="large" style="width:4vw;">{{ t('common.refundMethod') }}</el-text>
<el-select v-model="searchForm.refundChannels" style="width:9vw;" clearable>
<el-option v-for="item in channelOptions" :key="item" :label="item" :value="item" />
</el-select>
</div>
<div class="search2">
<el-text size="large" style="width:4vw;">订单状态</el-text>
<el-text size="large" style="width:4vw;">{{ t('common.orderStatus') }}</el-text>
<el-select v-model="searchForm.statuses" style="width:9vw;" clearable>
<el-option v-for="item in statusList" :label="item" :value="item" :key="item" />
</el-select>
</div>
<div class="search2" style="width: 25.5vw;">
<el-text size="large" style="width:4vw;">退款时间</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" range-separator="" start-placeholder="起始时间"
end-placeholder="结束时间" style="width:18vw;" clearable :disabled-date="disabledDate"
<el-text size="large" style="width:4vw;">{{ t('common.refundTime') }}</el-text>
<el-date-picker v-model="dateRange" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')"
:end-placeholder="t('common.endTime')" style="width:18vw;" clearable :disabled-date="disabledDate"
:default-time="defaultTime" />
</div>
<div>
<el-button type="primary" size="medium" @click="getRefund">查询</el-button>
<el-button type="success" size="medium" @click="reset">重置</el-button>
<el-button type="primary" size="medium" @click="getRefund">{{ t('common.search') }}</el-button>
<el-button type="success" size="medium" @click="reset">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-card>
<el-card style="background-color: rgb(231,244,253);height:80vh;">
<el-table :data="tableData" style="height:70vh;width:82vw;">
<el-table-column type="index" label="序号" width="60" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="60" fixed="left">
<template #default="scope">
{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}
</template>
</el-table-column>
<el-table-column prop="jwcode" label="Homily ID" width="120" fixed="left" />
<el-table-column prop="name" label="姓名" width="120" fixed="left" show-overflow-tooltip />
<el-table-column prop="marketName" label="所属地区" width="120" />
<el-table-column prop="goodsName" label="产品名称" width="120" />
<el-table-column prop="goodsNum" label="产品数量" width="120" />
<el-table-column prop="refundModel" label="退款方式" width="120">
<el-table-column prop="name" :label="t('common_list.name')" width="120" fixed="left" show-overflow-tooltip />
<el-table-column prop="marketName" :label="t('common_list.market')" width="120" />
<el-table-column prop="goodsName" :label="t('common_list.productName')" width="120" />
<el-table-column prop="goodsNum" :label="t('common_list.productNum')" width="120" />
<el-table-column prop="refundModel" :label="t('common_list.refundModel')" width="120">
<template #default="scope">
{{ scope.row.refundModel === 1 ? '部分退款' : '全部退款' }}
{{ scope.row.refundModel === 1 ? t('common_list.refundModelPart') : t('common_list.refundModelAll') }}
</template>
</el-table-column>
<el-table-column prop="refundCurrency" label="退款币种" width="120">
<el-table-column prop="refundCurrency" :label="t('common_list.refundCurrency')" width="120">
<template #default="scope">
<div v-if="!scope.row.refundCurrency">
<text style="color: #FA5A1E;">待补充</text>
<text style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</text>
</div>
</template>
</el-table-column>
<el-table-column prop="refundAmount" label="退款金额" width="120">
<el-table-column prop="refundAmount" :label="t('common_list.refundAmount')" width="120">
<template #default="scope">
<div v-if="!scope.row.refundAmount">
<text style="color: #FA5A1E;">待补充</text>
<text style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</text>
</div>
</template>
</el-table-column>
<el-table-column prop="refundChannels" label="退款途径" width="120">
<el-table-column prop="refundChannels" :label="t('common_list.refundChannels')" width="120">
<template #default="scope">
<div v-if="!scope.row.refundChannels">
<text style="color: #FA5A1E;">待补充</text>
<text style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</text>
</div>
</template>
</el-table-column>
<el-table-column prop="refundVoucher" label="退款截图" width="120">
<el-table-column prop="refundVoucher" :label="t('common_list.refundVoucher')" width="120">
<template #default="scope">
<el-image v-if="scope.row.refundVoucher" :src="scope.row.refundVoucher"
@click="previewImage(scope.row.refundVoucher)"
style="width: 40px; height: 40px; cursor: pointer;z-index: 99999;" fit="cover" />
<span v-else style="color: #FA5A1E;">待补充</span>
<span v-else style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</span>
</template>
</el-table-column>
<el-table-column prop="refundTime" label="退款时间" width="180">
<el-table-column prop="refundTime" :label="t('common_list.refundTime')" width="180">
<template #default="scope">
<div v-if="!scope.row.refundTime">
<text style="color: #FA5A1E;">待补充</text>
<text style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</text>
</div>
</template>
</el-table-column>
<el-table-column prop="status" label="订单状态" width="120">
<el-table-column prop="status" :label="t('common_list.orderStatus')" width="120">
<template #default="scope">
{{ scope.row.status === 41 ? '退款成功' : '待处理' }}
{{ scope.row.status === 41 ? t('common_list.refundSuccess') : t('common_list.pending') }}
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" fixed="right" width="100px">
<el-table-column prop="operation" :label="t('common_list.operation')" fixed="right" width="100px">
<template #default="scope">
<div class="operation">
<el-button v-if="scope.row.status === 40" type="primary" text @click="showEditDialog(scope.row)">
提交
{{ t('common.submit') }}
</el-button>
<el-button v-else type="primary" text @click="showEditDialog(scope.row)">
编辑
{{ t('common.edit') }}
</el-button>
</div>
</template>
@ -132,86 +133,86 @@
<div style="display: flex;">
<div class="left">
<div class="dialog-item">
<el-text style="width:4vw;">精网号</el-text>
<el-text style="width:4vw;">{{ t('common_add.jwcode') }}</el-text>
<el-input v-model="editRow.jwcode" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">客户姓名</el-text>
<el-text style="width:4vw;">{{ t('common_add.customerName') }}</el-text>
<el-input v-model="editRow.name" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">所属地区</el-text>
<el-text style="width:4vw;">{{ t('common_add.market') }}</el-text>
<el-input v-model="editRow.marketName" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">产品名称</el-text>
<el-text style="width:4vw;">{{ t('common_add.productName') }}</el-text>
<el-input v-model="editRow.goodsName" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">退款类型</el-text>
<el-text style="width:4vw;">{{ t('common_add.refundModel') }}</el-text>
<el-select v-model="editRow.refundModel" style="width:10vw;" disabled>
<el-option label="全部退款" :value="0"></el-option>
<el-option label="部分退款" :value="1"></el-option>
<el-option :label="t('common_add.refundModelAll')" :value="0"></el-option>
<el-option :label="t('common_add.refundModelPart')" :value="1"></el-option>
</el-select>
</div>
<div class="dialog-item">
<el-text style="width:4vw;">付款币种</el-text>
<el-text style="width:4vw;">{{ t('common_add.payCurrency') }}</el-text>
<el-input v-model="editRow.paymentCurrency" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">付款金额</el-text>
<el-text style="width:4vw;">{{ t('common_add.payAmount') }}</el-text>
<el-input v-model="editRow.paymentAmount" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">支付方式</el-text>
<el-text style="width:4vw;">{{ t('common_add.payMethod') }}</el-text>
<el-input v-model="editRow.payType" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">付款时间</el-text>
<el-text style="width:4vw;">{{ t('common_add.payTime') }}</el-text>
<el-input v-model="editRow.payTime" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">提交人</el-text>
<el-text style="width:4vw;">{{ t('common_add.submitter') }}</el-text>
<el-input v-model="editRow.submitter" style="width:10vw;" disabled />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">转账凭证</el-text>
<el-text style="width:4vw;">{{ t('common_add.transferVoucher') }}</el-text>
<img v-if="editRow.payVoucher" :src="editRow.payVoucher"
style="width: 80px; height: 80px; object-fit: cover;">
<div v-else>
无转账凭证
{{ t('common_add.noTransferVoucher') }}
</div>
</div>
<div class="dialog-item">
<el-text style="width:4vw;">备注</el-text>
<el-text style="width:4vw;">{{ t('common_add.remark') }}</el-text>
<el-input v-model="editRow.payRemark" style="width:10vw;" :row="3" disabled maxlength="100" type="textarea"
show-word-limit clearable />
</div>
</div>
<div class="right">
<div class="dialog-item">
<el-text style="width:4vw;">退款币种</el-text>
<el-select v-model="editForm.refundCurrency" placeholder="请选择退款币种" style="width:10vw;">
<el-text style="width:4vw;">{{ t('common_add.refundCurrency') }}</el-text>
<el-select v-model="editForm.refundCurrency" :placeholder="t('common_add.refundCurrencyPlaceholder')" style="width:10vw;">
<el-option v-for="item in currencies" :key="item" :label="item" :value="item" />
</el-select>
</div>
<div class="dialog-item">
<el-text style="width:4vw;">退款金额</el-text>
<el-input v-model="editForm.refundAmount" placeholder="请输入退款金额" style="width:10vw;" clearable />
<el-text style="width:4vw;">{{ t('common_add.refundAmount') }}</el-text>
<el-input v-model="editForm.refundAmount" :placeholder="t('common_add.refundAmountPlaceholder')" style="width:10vw;" clearable />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">退款途径</el-text>
<el-select v-model="editForm.refundChannels" placeholder="请选择退款途径" style="width:10vw;">
<el-text style="width:4vw;">{{ t('common_add.refundChannels') }}</el-text>
<el-select v-model="editForm.refundChannels" :placeholder="t('common_add.refundChannelsPlaceholder')" style="width:10vw;">
<el-option v-for="item in channelOptions" :key="item" :label="item" :value="item" />
</el-select>
</div>
<div class="dialog-item">
<el-text style="width:4vw;">退款时间</el-text>
<el-date-picker v-model="editForm.refundTime" type="datetime" placeholder="请选择退款时间" style="width:10vw;"
<el-text style="width:4vw;">{{ t('common_add.refundTime') }}</el-text>
<el-date-picker v-model="editForm.refundTime" type="datetime" :placeholder="t('common_add.refundTimePlaceholder')" style="width:10vw;"
clearable />
</div>
<div class="dialog-item">
<el-text style="width:4vw;">退款截图</el-text>
<el-text style="width:4vw;">{{ t('common_add.refundVoucher') }}</el-text>
<el-upload ref="uploadRef" :http-request="customUpload" list-type="picture-card" :auto-upload="false"
:on-change="handleImageChange" :before-upload="beforeUpload" :show-file-list="false">
<template #default>
@ -224,13 +225,13 @@
</el-upload>
</div>
<div class="dialog-item">
<el-text style="width:4vw;">备注</el-text>
<el-input v-model="editForm.refundRemark" placeholder="请输入备注" style="width:10vw;" :rows="3" maxlength="100"
<el-text style="width:4vw;">{{ t('common_add.remark') }}</el-text>
<el-input v-model="editForm.refundRemark" :placeholder="t('common_add.remarkPlaceholder')" style="width:10vw;" :rows="3" maxlength="100"
show-word-limit type="textarea" clearable />
</div>
<div style="display:flex;justify-content: center;margin-top: 5vh;">
<el-button type="default" @click="hideEditDialog" style="margin-right: 2vw;">取消</el-button>
<el-button type="primary" @click="submitRefund">提交</el-button>
<el-button type="default" @click="hideEditDialog" style="margin-right: 2vw;">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="submitRefund">{{ t('common.submit') }}</el-button>
</div>
</div>
</div>
@ -250,12 +251,15 @@ const { adminData, menuTree } = storeToRefs(adminStore)
import { permissionMapping, findMenuById } from "@/utils/menuTreePermission.js"
import moment from 'moment'
import { isNumber } from 'lodash'
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const uploadUrl = 'https://api.homilychart.com/hljw/api/aws/upload'
const dateRange = ref([])
const tableData = ref([])
const editRow = ref({})//
const statusList = ref(['待处理', '退款成功'])
const statusList = ref([t('cash.pending'), t('cash.refundSuccess')])
const pagination = ref({
pageNum: 1,
pageSize: 50,
@ -289,13 +293,13 @@ const getRefund = async function () {
if (searchForm.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return;
}
}
// 400
if (searchForm.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
ElMessage.error(t('elmessage.limitJwcodeLength'))
return;
}
@ -330,7 +334,7 @@ const getRefund = async function () {
tableData.value = result.data.list || []
pagination.value.total = result.data.total || 0
} catch (error) {
ElMessage.error(error.message || '查询失败')
ElMessage.error(error.message || t('elmessage.searchFailed'))
}
}
//
@ -338,7 +342,7 @@ const submitRefund = async function () {
try {
const numberReg = /^[0-9]+(\.[0-9]+)?$/
if (!numberReg.test(editForm.value.refundAmount)) {
ElMessage.error('请输入数字或小数')
ElMessage.error(t('elmessage.checkNumberOrDecimal'))
return
}
const params = {
@ -358,14 +362,14 @@ const submitRefund = async function () {
data: params
})
if (result.code === 200) {
ElMessage.success('提交成功')
ElMessage.success(t('elmessage.submitSuccess'))
hideEditDialog()
getRefund()
} else {
ElMessage.error(result.msg || '提交失败')
ElMessage.error(result.msg || t('elmessage.submitFailed'))
}
} catch (error) {
ElMessage.error(error.message || '提交失败')
ElMessage.error(error.message || t('elmessage.submitFailed'))
}
}
const getMarket = async function () {
@ -413,8 +417,32 @@ const hideEditDialog = () => {
jwcode: ''
}
}
const currencies = ref(['美元(USD)', '港币(HKD)', '新币(SGD)', '马币(MYR)', '泰铢(THB)', '加币(CAD)', '越南盾(VDN)', '韩元(KRW)'])
const channelOptions = ref(["Stripe-链接收款", "PaymentAsia-链接收款", "Ipay88-链接收款", "银行转账", "刷卡", "现金", "支票", "Grabpay", "Nets", "E-Transfer", "Paypal"])
// const currencies = ref(['(USD)', '(HKD)', '(SGD)', '(MYR)', '(THB)', '(CAD)', '(VDN)', '(KRW)'])
const currencies = ref([
t('cash.currency.usd'), // (USD)
t('cash.currency.hkd'), // (HKD)
t('cash.currency.sgd'), // (SGD)
t('cash.currency.myr'), // (MYR)
t('cash.currency.thb'), // (THB)
t('cash.currency.cad'), // (CAD)
t('cash.currency.vnd'), // (VDN)
t('cash.currency.krw') // (KRW)
])
// const channelOptions = ref(["Stripe-", "PaymentAsia-", "Ipay88-", "", "", "", "", "Grabpay", "Nets", "E-Transfer", "Paypal"])
const channelOptions = ref([
t('cash.payMethods.stripe'),
t('cash.payMethods.paymentAsia'),
t('cash.payMethods.ipay88'),
t('cash.payMethods.bankTransfer'),
t('cash.payMethods.card'),
t('cash.payMethods.cash'),
t('cash.payMethods.check'),
t('cash.payMethods.grabpay'),
t('cash.payMethods.nets'),
t('cash.payMethods.transfer'),
t('cash.payMethods.paypal'),
])
//
const previewImage = (imageUrl) => {
@ -453,11 +481,11 @@ const beforeUpload = (file) => {
const isPNG = file.type === 'image/png'
const isLt1 = file.size / 1024 < 2048
if (!isJPG && !isPNG) {
ElMessage.error('上传图片只能是 JPG 或 PNG 格式')
ElMessage.error(t('elmessage.onlyUploadJPGPNG'))
return false
}
if (!isLt1) {
ElMessage.error('上传图片大小不能超过2MB')
ElMessage.error(t('elmessage.limitImageSize2MB'))
return false
}
return true
@ -476,13 +504,13 @@ const customUpload = async (options) => {
})
if (response.code === 200 && response.data) {
editForm.value.imageUrl = response.data.url
ElMessage.success(response.msg || '上传成功')
ElMessage.success(response.msg || t('elmessage.uploadSuccess'))
} else {
ElMessage.error(response.msg || '上传失败')
ElMessage.error(response.msg || t('elmessage.uploadFailed'))
}
} catch (error) {
console.error('上传错误:', error)
ElMessage.error(`上传失败: ${error.msg || error.message || '网络异常'}`)
ElMessage.error(t('elmessage.uploadFailed') + `: ${error.msg || error.message || t('elmessage.inNetworkError')}`)
}
}
const defaultTime = [

2
src/views/moneyManage/receiveDetail/receiveDetail1.vue

@ -1497,7 +1497,7 @@ onMounted(async function () {
if (adminData.value.roleId == 2) {
superAdmin.value = true
if(adminData.value.markets == '总部' || adminData.value.markets == '研发部' || adminData.value.markets == 'headquarters'){
if(adminData.value.markets == '总部' || adminData.value.markets == '研发部' || adminData.value.markets == 'Headquarters'){
console.log('提示了吗');
ElMessageBox.alert('管理员账号只能看到所属地区对应地区财务数据,请注意设置所属地区','注意',{

514
src/views/moneyManage/receiveDetail/receiveFinance.vue
File diff suppressed because it is too large
View File

386
src/views/moneyManage/receiveDetail/receiveHead.vue

@ -4,34 +4,34 @@
<el-card class="card1" style="margin-bottom: 0.5vh; min-height: 110px;">
<div class="row1">
<div class="rowItem">
<el-text style="width: 4vw;">精网号</el-text>
<el-input v-model="searchData.jwcode" placeholder="请输入精网号" style="width:10vw;"
<el-text style="width: 4vw;">{{ t('common.jwcode') }}</el-text>
<el-input v-model="searchData.jwcode" :placeholder="t('common.jwcodePlaceholder')" style="width:10vw;"
clearable></el-input>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">客户姓名</el-text>
<el-input v-model="searchData.name" placeholder="请输入客户姓名" style="width:10vw;"
<el-text style="width: 4vw;">{{ t('common.customerName') }}</el-text>
<el-input v-model="searchData.name" :placeholder="t('common.customerNamePlaceholder')" style="width:10vw;"
clearable></el-input>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">所属地区</el-text>
<el-text style="width: 4vw;">{{ t('common.market') }}</el-text>
<!-- <el-select v-model="searchData.market" placeholder="请选择所属地区" style="width:10vw;" clearable>
<el-option v-for="item in market" :key="item" :label="item" :value="item" />
</el-select> -->
<el-cascader style="width: 9vw;" v-model="searchData.markets" :options="market"
placeholder="请选择所属地区" clearable @change="handleMarketChange" />
:placeholder="t('common.marketPlaceholder')" clearable @change="handleMarketChange" />
</div>
<!-- 地区财务固定显示付款币种删除客服的订单状态 -->
<div class="rowItem">
<el-text style="width: 4vw;">付款币种</el-text>
<el-select v-model="searchData.paymentCurrency" placeholder="请选择付款币种" style="width: 10vw;"
<el-text style="width: 4vw;">{{ t('common.payCurrency') }}</el-text>
<el-select v-model="searchData.paymentCurrency" :placeholder="t('common.payCurrencyPlaceholder')" style="width: 10vw;"
clearable>
<el-option v-for="item in customOptions" :key="item" :label="item" :value="item" />
</el-select>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">支付方式</el-text>
<el-select v-model="searchData.payType" placeholder="请选择支付方式" style="width: 10vw;" clearable>
<el-text style="width: 4vw;">{{ t('common.payModel') }}</el-text>
<el-select v-model="searchData.payType" :placeholder="t('common.payModelPlaceholder')" style="width: 10vw;" clearable>
<el-option v-for="item in paytypeList" :key="item" :label="item" :value="item" />
</el-select>
</div>
@ -39,32 +39,32 @@
<div class="row2" style="margin-top: 10px;">
<div class="left">
<div class="rowItem">
<el-text style="width: 4vw;">活动名称</el-text>
<el-select v-model="searchData.activity" placeholder="请选择活动方式" style="width: 10vw;"
<el-text style="width: 4vw;">{{ t('common.activityName') }}</el-text>
<el-select v-model="searchData.activity" :placeholder="t('common.activityNameChoose')" style="width: 10vw;"
clearable>
<el-option v-for="item in activityList" :key="item.id" :label="item.activityName"
:value="item.id" />
</el-select>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">产品名称</el-text>
<el-text style="width: 4vw;">{{ t('common.productName') }}</el-text>
<el-cascader v-model="searchData.goodsName" :options="productList" style="width: 10vw;"
clearable />
</div>
<div class="rowItem" style="width: 25vw">
<el-text style="width: 4vw; margin-left: 0.5vw;">付款时间</el-text>
<el-date-picker v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="width: 22vw; "
<el-text style="width: 4vw; margin-left: 0.5vw;">{{ t('common.payTime') }}</el-text>
<el-date-picker v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="width: 22vw; "
@change="handleDatePickerChange" :default-time="defaultTime"
:disabled-date="disabledDate" />
</div>
</div>
<el-button style="width: 3vw;" type="primary" @click="search">查询</el-button>
<el-button style="width: 3vw;" type="success" @click="reset">重置</el-button>
<el-button style="width: 3vw;" type="primary" @click="search">{{ t('common.search') }}</el-button>
<el-button style="width: 3vw;" type="success" @click="reset">{{ t('common.reset') }}</el-button>
<el-button v-if="activeTab == 'done'" style="width: 5vw;" type="warning"
@click="exportExcel()">导出excel</el-button>
@click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button v-if="activeTab == 'done'" style="width: 6vw;" type="primary"
@click="openExportList">查看导出列表</el-button>
@click="openExportList">{{ t('common.viewExportList') }}</el-button>
</div>
</el-card>
</div>
@ -78,18 +78,18 @@
<el-button class="btnItem"
:style="{ backgroundColor: activeTab === 'pass' ? '#2741DE' : '#E5EBFE', color: activeTab === 'pass' ? 'white' : '#666' }"
@click="navigateTo('pass')">
已通过
{{ t('common.passed') }}
</el-button>
<el-button class="btnItem"
:style="{ backgroundColor: activeTab === 'done' ? '#2741DE' : '#E5EBFE', color: activeTab === 'done' ? 'white' : '#666' }"
@click="navigateTo('done')">
已完成
{{ t('common.completed') }}
</el-button>
</el-button-group>
</div>
<div class="info-tooltip">
<el-popover placement="top" title="数据说明" :width="260" trigger="hover"
content="收款的所有页面:订单记录默认按照付款时间降序排列" popper-class="custom-popover" :show-arrow="false">
<el-popover placement="top" :title="t('cash.receiveCashDataTitle')" :width="260" trigger="hover"
:content="t('cash.receiveCashDataContent')" popper-class="custom-popover" :show-arrow="false">
<template #reference>
<el-icon class="service-icon">
<Warning />
@ -103,51 +103,51 @@
<el-table :data="tableData" style="width: 80vw;height:64vh;" @sort-change="handleSortChange"
:row-style="{ height: '60px' }" :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
<template #default="scope">
<span>{{ scope.$index + 1 + (pageInfo.pageNum - 1) * pageInfo.pageSize }}</span>
</template>
</el-table-column>
<el-table-column fixed="left" prop="jwcode" label="Homily ID" width="110px" />
<el-table-column fixed="left" prop="name" label="姓名" width="110px" />
<el-table-column prop="marketName" label="所属地区" width="80px" />
<el-table-column prop="activity" label="活动名称" width="120px" show-overflow-tooltip />
<el-table-column prop="goodsName" label="产品名称" width="120px" />
<el-table-column prop="goodNum" label="产品数量" width="130px">
<el-table-column fixed="left" prop="name" :label="t('common_list.name')" width="110px" />
<el-table-column prop="marketName" :label="t('common_list.market')" width="80px" />
<el-table-column prop="activity" :label="t('common_list.activity')" width="120px" show-overflow-tooltip />
<el-table-column prop="goodsName" :label="t('common_list.productName')" width="120px" />
<el-table-column prop="goodNum" :label="t('common_list.productNum')" width="130px">
<template #default="scope">
<span v-if="scope.row.goodsName == '金币充值'">{{ scope.row.permanentGold }}</span>
<span v-if="scope.row.goodsName == t('cash.coinRecharge')">{{ scope.row.permanentGold }}</span>
<span v-else>{{ scope.row.goodNum }}</span>
</template>
</el-table-column>
<el-table-column prop="paymentCurrency" label="付款币种" width="100px" />
<el-table-column prop="paymentAmount" label="付款金额" width="120px" />
<el-table-column prop="paymentCurrency" :label="t('common_list.payCurrency')" width="100px" />
<el-table-column prop="paymentAmount" :label="t('common_list.payAmount')" width="120px" />
<!-- 总部财务显示到账币种/金额/手续费已通过/已完成标签页 -->
<el-table-column prop="receivedCurrency" label="到账币种"
<el-table-column prop="receivedCurrency" :label="t('common_list.receiveCurrency')"
v-if="activeTab == 'pass' || activeTab == 'done'" width="150px"></el-table-column>
<el-table-column prop="receivedAmount" label="到账金额"
<el-table-column prop="receivedAmount" :label="t('common_list.receiveAmount')"
v-if="activeTab == 'pass' || activeTab == 'done'" width="150px">
<template #default="scope">
<div v-if="!scope.row.receivedAmount">
<text style="color: #FA5A1E;">待补充</text>
<text style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</text>
</div>
</template>
</el-table-column>
<el-table-column prop="handlingCharge" label="手续费"
<el-table-column prop="handlingCharge" :label="t('common_list.fee')"
v-if="activeTab == 'pass' || activeTab == 'done'" width="150px">
<template #default="scope">
<div v-if="scope.row.handlingCharge == null">
<text style="color: #FA5A1E;">待补充</text>
<text style="color: #FA5A1E;">{{ t('common_list.toSupply') }}</text>
</div>
</template>
</el-table-column>
<el-table-column prop="payType" label="支付方式" width="130px" />
<el-table-column prop="payTime" label="付款时间" width="180px" />
<el-table-column prop="voucher" label="转账凭证" width="110px">
<el-table-column prop="payType" :label="t('common_list.payModel')" width="130px" />
<el-table-column prop="payTime" :label="t('common_list.payTime')" width="180px" />
<el-table-column prop="voucher" :label="t('common_list.transferVoucher')" width="110px">
<template #default="scope">
<div v-if="scope.row.voucher"
style="display: flex; justify-content: center; align-items: center; cursor: pointer;"
@click="previewImage(scope.row.voucher)">
<img :src="scope.row.voucher" alt="支付凭证" style="width: auto; height: 40px;">
<img :src="scope.row.voucher" :alt="t('common_list.payVoucher')" style="width: auto; height: 40px;">
</div>
<div v-else
style="display: flex; justify-content: center; align-items: center; height: 40px;">
@ -155,26 +155,26 @@
</div>
</template>
</el-table-column>
<el-table-column prop="submitterName" label="提交人" width="150px"
<el-table-column prop="submitterName" :label="t('common_list.submitter')" width="150px"
show-overflow-tooltip></el-table-column>
<!-- 总部财务显示审核人已通过/已驳回/已完成标签页 -->
<el-table-column prop="auditName" label="审核人"
<el-table-column prop="auditName" :label="t('common_list.approver')"
v-if="activeTab == 'pass' || activeTab == 'reject' || activeTab == 'done'" width="150px"
show-overflow-tooltip></el-table-column>
<el-table-column prop="receivedTime" label="到账时间"
<el-table-column prop="receivedTime" :label="t('common_list.receiveTime')"
v-if="activeTab == 'pass' || activeTab == 'done'" width="180px" />
<el-table-column prop="remark" label="备注" v-if="activeTab != 'reject'" width="150px"
<el-table-column prop="remark" :label="t('common_list.remark')" v-if="activeTab != 'reject'" width="150px"
show-overflow-tooltip></el-table-column>
<el-table-column prop="status" fixed="right" label="订单状态" v-if="activeTab == 'done'"
<el-table-column prop="status" fixed="right" :label="t('common_list.orderStatus')" v-if="activeTab == 'done'"
width="150px" show-overflow-tooltip>
<template #default="scope">
<span style="color: rgb(242, 84, 83);" v-if="scope.row.status == 6">退款</span>
<span style="color: rgb(127,204,133);" v-else>正常</span>
<span style="color: rgb(242, 84, 83);" v-if="scope.row.status == 6">{{ t('common_list.refund') }}</span>
<span style="color: rgb(127,204,133);" v-else>{{ t('common_list.normal') }}</span>
</template>
</el-table-column>
<el-table-column prop="auditTime" label="驳回时间" v-if="activeTab == 'reject'" width="180px"
<el-table-column prop="auditTime" :label="t('common_list.rejectTime')" v-if="activeTab == 'reject'" width="180px"
show-overflow-tooltip></el-table-column>
<el-table-column prop="rejectReason" label="驳回理由" v-if="activeTab == 'reject'" width="150px">
<el-table-column prop="rejectReason" :label="t('common_list.rejectReason')" v-if="activeTab == 'reject'" width="150px">
<template #default="scope">
<div class="ellipsis-container"
@mouseenter="handleMouseEnter($event, scope.row.rejectReason)"
@ -193,19 +193,16 @@
</template>
</el-table-column>
<!-- 总部财务表格操作待审核审核已通过编辑 -->
<el-table-column fixed="right" label="操作" width="120px" v-if="activeTab != 'reject'">
<el-table-column fixed="right" :label="t('common_list.operation')" width="120px" v-if="activeTab != 'reject'">
<template #default=scope>
<el-link v-if="activeTab == 'wait'" style="color: #2741DE;"
@click="openAuditForm(scope.row)">审核
</el-link>
@click="openAuditForm(scope.row)">{{ t('common.audit') }}</el-link>
<el-link
v-else-if="activeTab == 'pass' && !(scope.row.status == 6 || scope.row.status == 4)"
style="color: #2741DE;" @click="openEditForm(scope.row)">编辑
</el-link>
style="color: #2741DE;" @click="openEditForm(scope.row)">{{ t('common.edit') }}</el-link>
<el-link
v-else-if="activeTab == 'done' && scope.row.status == 4 && startsWith(scope.row.orderCode, 'GOLDCOIN')"
style="color: rgb(242, 84, 83);" @click="openRefundConfirm(scope.row)">退款
</el-link>
style="color: rgb(242, 84, 83);" @click="openRefundConfirm(scope.row)">{{ t('common.refund') }}</el-link>
</template>
</el-table-column>
</el-table>
@ -221,16 +218,16 @@
<!-- 退款确认弹窗 -->
<div class="recallDialog" v-show="refundConfirmDialog">
<div class="close">
<button @click="closeConfirmRefund" class="Btn">关闭</button>
<button @click="closeConfirmRefund" class="Btn">{{ t('common.close') }}</button>
</div>
<div class="text">
<text class="txt">{{ textContent }}</text>
</div>
<div class="cancle">
<button @click="closeConfirmRefund" class="Btn">取消</button>
<button @click="closeConfirmRefund" class="Btn">{{ t('common.cancel') }}</button>
</div>
<div class="confirm">
<button @click="openRefundDialog" class="Btn">确定</button>
<button @click="openRefundDialog" class="Btn">{{ t('common.confirm') }}</button>
</div>
</div>
@ -239,67 +236,67 @@
<div class="content">
<div class="left">
<el-form class="editForm" label-width="4.5vw" label-position="left">
<el-form-item label="精网号">
<el-input disabled="true" v-model="editFormData.jwcode" placeholder="精网号" />
<el-form-item :label="t('common_add.jwcode')">
<el-input disabled="true" v-model="editFormData.jwcode" :placeholder="t('common_add.jwcode')" />
</el-form-item>
<el-form-item label="客户姓名">
<el-input disabled="true" v-model="editFormData.name" placeholder="客户姓名" />
<el-form-item :label="t('common_add.customerName')">
<el-input disabled="true" v-model="editFormData.name" :placeholder="t('common_add.customerName')" />
</el-form-item>
<el-form-item label="所属地区">
<el-input disabled="true" v-model="editFormData.marketName" placeholder="所属地区" />
<el-form-item :label="t('common_add.market')">
<el-input disabled="true" v-model="editFormData.marketName" :placeholder="t('common_add.market')" />
</el-form-item>
<el-form-item label="活动名称">
<el-input disabled="true" v-model="editFormData.activity" placeholder="活动名称" />
<el-form-item :label="t('common_add.activity')">
<el-input disabled="true" v-model="editFormData.activity" :placeholder="t('common_add.activity')" />
</el-form-item>
<el-form-item label="产品名称">
<el-select disabled="true" v-model="editFormData.goodsName" placeholder="产品名称"
<el-form-item :label="t('common_add.productName')">
<el-select disabled="true" v-model="editFormData.goodsName" :placeholder="t('common_add.productName')"
clearable></el-select>
</el-form-item>
<!-- 金币产品特殊显示 -->
<el-form-item v-show="!isEditGold" label="产品数量">
<el-form-item v-show="!isEditGold" :label="t('common_add.productNum')">
<div style="display: flex;">
<el-input disabled="true" style="padding-right: 30px; flex: 3;"
v-model="editFormData.goodNum" placeholder="请输入产品数量" />
v-model="editFormData.goodNum" :placeholder="t('common_add.productNumPlaceholder')" />
<CurrencySelect disabled="true" v-model="editFormData.numUnit" :items="numUnitList"
style="flex: 1.5;" placeholder="单位" />
style="flex: 1.5;" :placeholder="t('common_add.numUnit')" />
</div>
</el-form-item>
<div v-show="isEditGold" style="margin-bottom: 15px; display: flex;">
<div style=" display: flex; margin-right: 10px;">
<span
style="color: #999999; display: flex; white-space: nowrap;align-items: center;">永久金币</span>
style="color: #999999; display: flex; white-space: nowrap;align-items: center;">{{ t('common_add.permanentGold') }}</span>
<el-input disabled="true"
style="padding-right: 10px; padding-left: 10px; height: 30px; width: 110px;"
v-model="editFormData.permanentGold" />
</div>
<div style="padding-right: 5px; display: flex;">
<span
style="color: #999999; display: flex; white-space: nowrap;align-items: center;">免费金币</span>
style="color: #999999; display: flex; white-space: nowrap;align-items: center;">{{ t('common_add.freeGold') }}</span>
<el-input disabled="true"
style="padding-right: 10px; padding-left: 10px; height: 30px; width: 110px;"
v-model="editFormData.freeGold" />
</div>
</div>
<el-form-item label="付款币种">
<el-form-item :label="t('common_add.payCurrency')">
<CurrencySelect :disabled="!ifOnline" v-model="editFormData.paymentCurrency"
:items="customOptions" placeholder="付款币种" />
:items="customOptions" :placeholder="t('common_add.payCurrencyPlaceholder')" />
</el-form-item>
<el-form-item label="付款金额">
<el-input :disabled="!ifOnline" v-model="editFormData.paymentAmount" placeholder="付款金额" />
<el-form-item :label="t('common_add.payAmount')">
<el-input :disabled="!ifOnline" v-model="editFormData.paymentAmount" :placeholder="t('common_add.payAmountPlaceholder')" />
</el-form-item>
<el-form-item label="支付方式">
<el-select disabled="true" v-model="editFormData.payType" placeholder="支付方式"
<el-form-item :label="t('common_add.payMethod')">
<el-select disabled="true" v-model="editFormData.payType" :placeholder="t('common_add.payMethodPlaceholder')"
clearable></el-select>
</el-form-item>
<el-form-item label="到账地区">
<el-select disabled="true" v-model="editFormData.receivedMarket" placeholder="到账地区"
<el-form-item :label="t('common_add.receiveArea')">
<el-select disabled="true" v-model="editFormData.receivedMarket" :placeholder="t('common_add.receiveAreaPlaceholder')"
clearable></el-select>
</el-form-item>
<el-form-item label="付款时间">
<el-form-item :label="t('common_add.payTime')">
<el-date-picker disabled="true" type="datetime" v-model="editFormData.payTime"
placeholder="付款时间" />
:placeholder="t('common_add.payTimePlaceholder')" />
</el-form-item>
<el-form-item label="转账凭证">
<el-form-item :label="t('common_add.transferVoucher')">
<div class="pic">
<el-upload disabled="true" ref="uploadRef" class="uploader" :show-file-list="false"
list-type="picture-card" :auto-upload="false" :before-upload="beforeUpload"
@ -311,12 +308,12 @@
<Plus />
</el-icon>
</el-upload>
<el-text class="picText">仅支持.jpg .png格式文件 2 MB</el-text>
<el-text class="picText">{{ t('common_add.transferVoucherPlaceholder') }}</el-text>
</div>
</el-form-item>
<el-form-item label="备注">
<el-form-item :label="t('common_add.remark')">
<el-input disabled="true" v-model="editFormData.remark" type="textarea" :rows="4"
placeholder="备注" maxlength="100" show-word-limit />
:placeholder="t('common_add.remark')" maxlength="100" show-word-limit />
</el-form-item>
</el-form>
</div>
@ -324,26 +321,26 @@
<!-- 总部财务可编辑项仅到账相关信息 -->
<el-form ref="editFormRef" :rules="editFormRule" :model="editFormData" class="editFormRighrt"
label-width="4.5vw" label-position="left">
<el-form-item label="到账货币" required>
<el-form-item :label="t('common_add.receiveCurrency')" required>
<CurrencySelect v-model="editFormData.receivedCurrency" :items="customOptions"
placeholder="请选择到账货币" />
:placeholder="t('common_add.receiveCurrencyPlaceholder')" />
</el-form-item>
<el-form-item label="到账金额" prop="receivedAmount">
<el-input v-model="editFormData.receivedAmount" placeholder="请输入到账金额" type="number" />
<el-form-item :label="t('common_add.receiveAmount')" prop="receivedAmount">
<el-input v-model="editFormData.receivedAmount" :placeholder="t('common_add.receiveAmountPlaceholder')" type="number" />
</el-form-item>
<el-form-item label="手续费" prop="handlingCharge">
<el-input v-model="editFormData.handlingCharge" placeholder="请输入手续费" type="number" />
<el-form-item :label="t('common_add.fee')" prop="handlingCharge">
<el-input v-model="editFormData.handlingCharge" :placeholder="t('common_add.feePlaceholder')" type="number" />
</el-form-item>
<el-form-item label="到账时间" required>
<el-date-picker type="datetime" v-model="editFormData.receivedTime" placeholder="请选择到账时间" />
<el-form-item :label="t('common_add.receiveTime')" required>
<el-date-picker type="datetime" v-model="editFormData.receivedTime" :placeholder="t('common_add.receiveTimePlaceholder')" />
</el-form-item>
</el-form>
<span class="editBtns">
<button class="editBtn1" @click="closeEditForm">
<text class="txt">取消</text>
<text class="txt">{{ t('common.cancel') }}</text>
</button>
<button class="editBtn2" @click="throttledsubmitEditForm">
<text class="txt">提交</text>
<text class="txt">{{ t('common.submit') }}</text>
</button>
</span>
</div>
@ -351,68 +348,68 @@
</el-dialog>
<!-- 新增退款 -->
<el-dialog v-model="refundDialog" title="退款" class="refundDialog" overflow draggable style="width: 40vw;"
<el-dialog v-model="refundDialog" :title="t('common_add.refund')" class="refundDialog" overflow draggable style="width: 40vw;"
:before-close="closeRefundForm">
<div style="display: flex;">
<div class="left">
<div class="add-item">
<el-text style="width:4vw;">精网号</el-text>
<el-text style="width:4vw;">{{ t('common_add.jwcode') }}</el-text>
<el-input v-model="refundFormData.jwcode" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">客户姓名</el-text>
<el-text style="width:4vw;">{{ t('common_add.customerName') }}</el-text>
<el-input v-model="refundFormData.name" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">所属地区</el-text>
<el-text style="width:4vw;">{{ t('common_add.market') }}</el-text>
<el-input v-model="refundFormData.marketName" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">活动名称</el-text>
<el-text style="width:4vw;">{{ t('common_add.activity') }}</el-text>
<el-input v-model="refundFormData.activity" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">产品名称</el-text>
<el-text style="width:4vw;">{{ t('common_add.productName') }}</el-text>
<el-input v-model="refundFormData.goodsName" style="width:10vw;" disabled />
</div>
<div v-show="!isRefundGold" class="add-item">
<el-text style="width:4vw;">产品数量</el-text>
<el-text style="width:4vw;">{{ t('common_add.productNum') }}</el-text>
<el-input style="padding-right: 10px; width:6.5vw;" v-model="refundFormData.goodNum"
placeholder="请输入产品数量" disabled />
:placeholder="t('common_add.productNumPlaceholder')" disabled />
<CurrencySelect disabled="true" v-model="refundFormData.numUnit" :items="numUnitList"
style=" width: 3.5vw;" placeholder="单位" />
style=" width: 3.5vw;" :placeholder="t('common_add.numUnit')" />
</div>
<div v-show="isRefundGold" style="display: flex; margin-bottom: 10px;">
<div style=" display: flex; align-items: center;justify-content: center; ">
<span style="color: #999999; white-space: nowrap;">永久金币</span>
<span style="color: #999999; white-space: nowrap;">{{ t('common_add.permanentGold') }}</span>
<el-input style="padding-right: 10px; height: 30px; width: 70px;"
v-model="refundFormData.permanentGold" disabled />
</div>
<div style=" display: flex; align-items: center;justify-content: center; ">
<span style="color: #999999; white-space: nowrap;">免费金币</span>
<span style="color: #999999; white-space: nowrap;">{{ t('common_add.freeGold') }}</span>
<el-input style="padding-right: 10px; height: 30px; width: 70px;"
v-model="refundFormData.freeGold" disabled />
</div>
</div>
<div class="add-item">
<el-text style="width:4vw;">付款币种</el-text>
<el-text style="width:4vw;">{{ t('common_add.payCurrency') }}</el-text>
<el-input v-model="refundFormData.paymentCurrency" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">付款金额</el-text>
<el-text style="width:4vw;">{{ t('common_add.payAmount') }}</el-text>
<el-input v-model="refundFormData.paymentAmount" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">支付方式</el-text>
<el-text style="width:4vw;">{{ t('common_add.payMethod') }}</el-text>
<el-input v-model="refundFormData.payType" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">付款时间</el-text>
<el-text style="width:4vw;">{{ t('common_add.payTime') }}</el-text>
<el-date-picker v-model="refundFormData.payTime" type="datetime" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;" size="small">转账凭证</el-text>
<el-form-item :rules="{ required: true, message: '请上传图片', trigger: 'change' }">
<el-text style="width:4vw;" size="small">{{ t('common_add.transferVoucher') }}</el-text>
<el-form-item :rules="{ required: true, message: t('common_add.uploadPhoto'), trigger: 'change' }">
<el-upload ref="uploadRef" :auto-upload="false" list-type="picture-card"
:show-file-list="false">
<template #default>
@ -426,40 +423,40 @@
</el-form-item>
</div>
<div class="add-item">
<el-text style="width:4vw;">备注</el-text>
<el-text style="width:4vw;">{{ t('common_add.remark') }}</el-text>
<el-input v-model="refundFormData.remark" style="width:10vw;" :rows="2" type="textarea"
maxLength="100" disabled show-word-limit />
</div>
</div>
<div class="right">
<div class="add-item">
<el-text style="width:4vw;">退款模式</el-text>
<el-text style="width:4vw;">{{ t('common_add.refundModel') }}</el-text>
<el-radio-group v-model="refundFormData.refundModel">
<el-radio value="0">全部退款</el-radio>
<el-radio value="1">部分退款</el-radio>
<el-radio value="0">{{ t('common_add.refundModelAll') }}</el-radio>
<el-radio value="1">{{ t('common_add.refundModelPart') }}</el-radio>
</el-radio-group>
</div>
<div v-show="refundFormData.refundModel == '1'" style="display: flex; margin-bottom: 10px;">
<div style=" display: flex; align-items: center;justify-content: center; ">
<span style="color: #999999; white-space: nowrap;">永久金币</span>
<span style="color: #999999; white-space: nowrap;">{{ t('common_add.permanentGold') }}</span>
<el-input style="padding-right: 10px; height: 30px; width: 70px;"
v-model="refundFormData.partRefundGold" dsabled />
v-model="refundFormData.partRefundGold" disabled />
</div>
<div style=" display: flex; align-items: center;justify-content: center; ">
<span style="color: #999999; white-space: nowrap;">免费金币</span>
<span style="color: #999999; white-space: nowrap;">{{ t('common_add.freeGold') }}</span>
<el-input style="padding-right: 10px; height: 30px; width: 70px;"
v-model="refundFormData.partRefundFree" />
</div>
</div>
<div class="add-item">
<el-text style="width:4vw;">退款理由</el-text>
<el-text style="width:4vw;">{{ t('common_add.refundReason') }}</el-text>
<el-input v-model="refundFormData.refundReason" style="width:10vw;" :rows="5" maxlength="150"
show-word-limit type="textarea" />
</div>
<div>ps:请在退款理由表明用户的退款需求</div>
<div>{{ t('common_add.tip') }}</div>
<div style="display:flex;justify-content: center;margin-top: 5vh;">
<el-button type="default" @click="resetRefund">重置</el-button>
<el-button type="primary" @click="throttledsubmitRefund">提交</el-button>
<el-button type="default" @click="resetRefund">{{ t('common.reset') }}</el-button>
<el-button type="primary" @click="throttledsubmitRefund">{{ t('common.submit') }}</el-button>
</div>
</div>
</div>
@ -467,33 +464,33 @@
<!-- 导出列表 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="60vw">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="60vw">
<el-table :data="exportList" style="width: 100% ;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')" />
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -524,6 +521,10 @@ import { productList, MarketNameForId, CurrencyForId, marketList } from './utils
import { useAdminStore } from '@/store/index.js';
import { hasMenuPermission } from '@/utils/menuTreePermission.js';
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
// ===================== 1. =====================
const adminStore = useAdminStore();
const { menuTree } = storeToRefs(adminStore);
@ -580,7 +581,7 @@ const closeRefundForm = () => {
const isRefundGold = ref(false)
const ifRefundGold = () => {
if (refundFormData.value.goodsName === '金币充值') {
if (refundFormData.value.goodsName === t('cash.coinRecharge')) {
isRefundGold.value = true
refundFormData.value.goodNum = 0
} else {
@ -641,9 +642,9 @@ const exportExcel = async function () {
const res = await API({ url: '/export/exportCash', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
ElMessage.success(t('elmessage.exportSuccess'))
} else {
ElMessage.error(res.msg || '导出失败')
ElMessage.error(res.msg || t('elmessage.exportFailed'))
}
}
@ -664,11 +665,11 @@ const getExportList = async () => {
})
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -680,7 +681,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -701,32 +702,55 @@ const getTagType = (state) => {
//
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
case 1:
return '执行中';
case 2:
return '执行完成';
case 3:
return '执行出错';
default:
return '未知状态';
}
case 0:
return t('elmessage.pendingExecution');
case 1:
return t('elmessage.executing');
case 2:
return t('elmessage.executed');
case 3:
return t('elmessage.errorExecution');
default:
return t('elmessage.unknownStatus');
}
}
//
const adminData = ref({});
const activityList = ref([]);
const customOptions = ref(['美元(USD)', '港币(HKD)', '新币(SGD)', '马币(MYR)', '泰铢(THB)', '加币(CAD)', '越南盾(VDN)', '韩元(KRW)']);
const paytypeList = ["Stripe-链接收款", "PaymentAsia-链接收款", "Ipay88-链接收款", "银行转账", "刷卡", "现金", "支票", "Grabpay", "Nets", "E-Transfer", "Paypal"];
const paytypeOptions = ref([...paytypeList]);
//
const customOptions = ref([
t('cash.currency.usd'), // (USD)
t('cash.currency.hkd'), // (HKD)
t('cash.currency.sgd'), // (SGD)
t('cash.currency.myr'), // (MYR)
t('cash.currency.thb'), // (THB)
t('cash.currency.cad'), // (CAD)
t('cash.currency.vnd'), // (VDN)
t('cash.currency.krw') // (KRW)
])
// - 使cash.payMethods
const paytypeList = ref([
t('cash.payMethods.stripe'), // Stripe-
t('cash.payMethods.paymentAsia'), // PaymentAsia-
t('cash.payMethods.ipay88'), // Ipay88-
t('cash.payMethods.grabpay'), // Grabpay
t('cash.payMethods.nets'), // Nets
t('cash.payMethods.transfer'), // E-Transfer
t('cash.payMethods.paypal'), // PayPal
t('cash.payMethods.bankTransfer'),//
t('cash.payMethods.card'), //
t('cash.payMethods.cash'), //
t('cash.payMethods.check') //
])
const paytypeOptions = ref([...paytypeList.value]);
// ===================== 2. =====================
//退
const openRefundConfirm = (row) => {
textContent.value = '将要对该订单退款!'
textContent.value = t('common.willRefundOrder')
refundConfirmDialog.value = true
refundFormData.value = { ...row }
ifRefundGold()
@ -780,12 +804,12 @@ const getlist = async () => {
if (searchData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchData.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return;
}
// 8
if (searchData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
ElMessage.error(t('elmessage.limitJwcodeLength'))
return;
}
}
@ -817,11 +841,11 @@ const getlist = async () => {
tableData.value = result.data.list;
total.value = result.data.total;
} else {
ElMessage.error('订单数据加载失败');
ElMessage.error(t('elmessage.orderDataLoadFailed'));
}
} catch (error) {
console.error('总部财务订单列表请求异常:', error);
ElMessage.error('网络异常,请重试');
ElMessage.error(t('elmessage.inNetworkError'));
}
};
@ -833,23 +857,23 @@ const resetRefund = () => {
//退
const submitRefund = async () => {
try {
if (refundFormData.value.goodsName != '金币充值') {
return ElMessage.error('线上数据仅支持金币充值退款');
if (refundFormData.value.goodsName != t('cash.coinRecharge')) {
return ElMessage.error(t('elmessage.onlineDataSupport'));
}
if (!refundFormData.value.refundModel) {
return ElMessage.error('请选择退款方式');
return ElMessage.error(t('elmessage.selectRefundModel'));
}
if (!refundFormData.value.refundReason) {
return ElMessage.error('请输入退款原因');
return ElMessage.error(t('elmessage.refundReasonPlaceholder'));
}
//
if (refundFormData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(refundFormData.value.jwcode);
if (!isPositiveInteger) {
return ElMessage.error('精网号格式不正确,必须为正整数');
return ElMessage.error(t('elmessage.jwcodePositiveError'));
}
if (refundFormData.value.jwcode.length > 20) {
return ElMessage.error('精网号长度不能超过20位');
if (refundFormData.value.jwcode.length > 8) {
return ElMessage.error(t('elmessage.limitJwcodeLength'));
}
}
if (refundFormData.value.refundModel == 0) {
@ -876,7 +900,7 @@ const submitRefund = async () => {
}
})
if (result.code == 200) {
ElMessage.success('新增退款成功')
ElMessage.success(t('elmessage.addRefundSuccess'))
getlist()
closeRefundForm()
} else {
@ -937,15 +961,15 @@ const handelAudit = async () => {
});
if (result.code === 200) {
ElMessage.success('审核通过');
ElMessage.success(t('elmessage.approveSuccess'));
getlist();
closeAuditForm();
} else {
ElMessage.error(result.msg || '审核失败');
ElMessage.error(result.msg || t('elmessage.approveFailed'));
}
} catch (error) {
console.error('审核通过请求异常:', error);
ElMessage.error('网络异常,请重试');
ElMessage.error(t('elmessage.inNetworkError'));
}
};
@ -953,7 +977,7 @@ const handelAudit = async () => {
const isGold = ref(false)
const ifGold = (data) => {
console.log('data', data);
if (data.goodsName === '金币充值') {
if (data.goodsName === t('cash.coinRecharge')) {
isGold.value = true
} else {
isGold.value = false
@ -965,7 +989,7 @@ const ifGold = (data) => {
const openEditForm = (row) => {
editFormData.value = { ...row };
//
if (row.goodsName === '金币充值') isEditGold.value = true;
if (row.goodsName === t('cash.coinRecharge')) isEditGold.value = true;
else isEditGold.value = false;
// 线
if (row.status === 3) ifOnline.value = true;
@ -1006,15 +1030,15 @@ const submitEditForm = async () => {
});
if (result.code === 200) {
ElMessage.success('编辑提交成功');
ElMessage.success(t('elmessage.editSuccess'));
getlist();
closeEditForm();
} else {
ElMessage.error(result.msg || '提交失败');
ElMessage.error(result.msg || t('elmessage.editFailed'));
}
} catch (error) {
console.error('编辑提交请求异常:', error);
ElMessage.error('表单验证失败,请检查数据格式');
ElMessage.error(t('elmessage.formValidationFailed'));
}
};
@ -1069,7 +1093,7 @@ const getAdminData = async () => {
// }
} catch (error) {
console.error('管理员信息获取失败:', error);
ElMessage.error('管理员信息加载异常');
ElMessage.error(t('elmessage.adminInfoLoadFailed'));
}
};
@ -1080,11 +1104,11 @@ const getActivitys = async () => {
if (result.code === 200) {
activityList.value = result.data;
} else {
ElMessage.error('活动列表加载失败');
ElMessage.error(t('elmessage.activityLoadFailed'));
}
} catch (error) {
console.error('活动列表获取失败:', error);
ElMessage.error('活动数据加载异常');
ElMessage.error(t('elmessage.activityDataLoadFailed'));
}
};
@ -1103,8 +1127,8 @@ onMounted(async () => {
//
if (!hasMenuPermission(menuTree.value, 91)) {
ElMessageBox.alert(
'您暂无该页面操作权限,请联系管理员',
'权限提示',
t('elmessage.noPermissionText'),
t('elmessage.permissionPrompt'),
{ type: 'error' }
).then(() => {
window.history.back();

518
src/views/moneyManage/receiveDetail/receiveManage.vue
File diff suppressed because it is too large
View File

443
src/views/moneyManage/receiveDetail/receiveService.vue

@ -5,57 +5,60 @@
<el-card class="card1" style="margin-bottom: 0.5vh; min-height: 110px;">
<div class="row">
<div class="rowItem">
<el-text style="width: 4vw;">精网号</el-text>
<el-input v-model="searchData.jwcode" placeholder="请输入精网号" style="width:10vw;"
clearable></el-input>
<el-text style="width: 4vw;">{{ t('common.jwcode') }}</el-text>
<el-input v-model="searchData.jwcode" :placeholder="t('common.jwcodePlaceholder')"
style="width:10vw;" clearable></el-input>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">客户姓名</el-text>
<el-input v-model="searchData.name" placeholder="请输入客户姓名" style="width:10vw;"
clearable></el-input>
<el-text style="width: 4vw;">{{ t('common.customerName') }}</el-text>
<el-input v-model="searchData.name" :placeholder="t('common.customerNamePlaceholder')"
style="width:10vw;" clearable></el-input>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">所属地区</el-text>
<el-text style="width: 4vw;">{{ t('common.market') }}</el-text>
<el-cascader style="width: 9vw;" v-model="searchData.markets" :options="market"
placeholder="请选择所属地区" clearable @change="handleMarketChange" />
:placeholder="t('common.marketPlaceholder')" clearable @change="handleMarketChange" />
</div>
<div class="rowItem">
<el-text style="width: 4vw;">订单状态</el-text>
<el-select v-model="searchData.status" placeholder="请选择订单状态" style="width: 10vw;" clearable>
<el-text style="width: 4vw;">{{ t('common.orderStatus') }}</el-text>
<el-select v-model="searchData.status" :placeholder="t('common.orderStatusPlaceholder')"
style="width: 10vw;" clearable>
<el-option v-for="item in statusList" :key="item.name" :label="item.name"
:value="item.value" />
</el-select>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">支付方式</el-text>
<el-select v-model="searchData.payType" placeholder="请选择支付方式" style="width: 10vw;" clearable>
<el-text style="width: 4vw;">{{ t('common.payModel') }}</el-text>
<el-select v-model="searchData.payType" :placeholder="t('common.payModelPlaceholder')"
style="width: 10vw;" clearable>
<el-option v-for="item in paytypeList" :key="item" :label="item" :value="item" />
</el-select>
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="rowItem">
<el-text style="width: 4vw;">活动名称</el-text>
<el-select v-model="searchData.activity" placeholder="请选择活动方式" style="width: 10vw;" clearable>
<el-text style="width: 4vw;">{{ t('common.activityName') }}</el-text>
<el-select v-model="searchData.activity" :placeholder="t('common.activityNameChoose')"
style="width: 10vw;" clearable>
<el-option v-for="item in activityList" :key="item.id" :label="item.activityName"
:value="item.id" />
</el-select>
</div>
<div class="rowItem">
<el-text style="width: 4vw;">产品名称</el-text>
<el-text style="width: 4vw;">{{ t('common.productName') }}</el-text>
<el-cascader v-model="searchData.goodsName" :options="productList" style="width: 10vw;"
clearable />
</div>
<div class="rowItem" style="width: 30vw">
<el-text style="width: 4vw; margin-left: 0.5vw;">付款时间</el-text>
<el-date-picker v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="width: 22vw; "
@change="handleDatePickerChange" :default-time="defaultTime"
<el-text style="width: 4vw; margin-left: 0.5vw;">{{ t('common.payTime') }}</el-text>
<el-date-picker v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')"
style="width: 22vw; " @change="handleDatePickerChange" :default-time="defaultTime"
:disabled-date="disabledDate" />
</div>
<div class="buttons">
<el-button type="primary" @click="search">查询</el-button>
<el-button type="success" @click="reset">重置</el-button>
<el-button type="primary" @click="search">{{ t('common.search') }}</el-button>
<el-button type="success" @click="reset">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-card>
@ -66,11 +69,12 @@
<el-card class="card2">
<div class="btns">
<div class="btnAdd">
<el-button @click="openAddForm" type="success">添加收款</el-button>
<el-button @click="openAddForm" type="success">{{ t('common.addReceive') }}</el-button>
</div>
<div class="info-tooltip">
<el-popover placement="top" title="数据说明" :width="260" trigger="hover"
content="收款的所有页面:订单记录默认按照付款时间降序排列" popper-class="custom-popover" :show-arrow="false">
<el-popover placement="top" :title="t('cash.receiveCashDataTitle')" :width="260" trigger="hover"
:content="t('cash.receiveCashDataContent')" popper-class="custom-popover"
:show-arrow="false">
<template #reference>
<el-icon class="service-icon">
<Warning />
@ -84,32 +88,35 @@
<el-table :data="tableData" style="width: 80vw;height:64vh;" @sort-change="handleSortChange"
:row-style="{ height: '60px' }" :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
<template #default="scope">
<span>{{ scope.$index + 1 + (pageInfo.pageNum - 1) * pageInfo.pageSize }}</span>
</template>
</el-table-column>
<el-table-column fixed="left" prop="jwcode" label="Homily ID" width="110px" />
<el-table-column fixed="left" prop="name" label="姓名" width="110px" />
<el-table-column prop="marketName" label="所属地区" width="80px" />
<el-table-column prop="activity" label="活动名称" width="120px" show-overflow-tooltip />
<el-table-column prop="goodsName" label="产品名称" width="120px" />
<el-table-column prop="goodNum" label="产品数量" width="130px">
<el-table-column fixed="left" prop="name" :label="t('common_list.name')" width="110px" />
<el-table-column prop="marketName" :label="t('common_list.market')" width="80px" />
<el-table-column prop="activity" :label="t('common_list.activity')" width="120px"
show-overflow-tooltip />
<el-table-column prop="goodsName" :label="t('common_list.productName')" width="120px" />
<el-table-column prop="goodNum" :label="t('common_list.productNum')" width="130px">
<template #default="scope">
<span v-if="scope.row.goodsName == '金币充值'">{{ scope.row.permanentGold }}</span>
<span v-if="scope.row.goodsName == t('common_list.goldRecharge')">{{
scope.row.permanentGold }}</span>
<span v-else>{{ scope.row.goodNum }}</span>
</template>
</el-table-column>
<el-table-column prop="paymentCurrency" label="付款币种" width="100px" />
<el-table-column prop="paymentAmount" label="付款金额" width="120px" />
<el-table-column prop="payType" label="支付方式" width="130px" />
<el-table-column prop="payTime" label="付款时间" width="180px" />
<el-table-column prop="voucher" label="转账凭证" width="110px">
<el-table-column prop="paymentCurrency" :label="t('common_list.payCurrency')" width="100px" />
<el-table-column prop="paymentAmount" :label="t('common_list.payAmount')" width="120px" />
<el-table-column prop="payType" :label="t('common_list.payModel')" width="130px" />
<el-table-column prop="payTime" :label="t('common_list.payTime')" width="180px" />
<el-table-column prop="voucher" :label="t('common_list.transferVoucher')" width="110px">
<template #default="scope">
<div v-if="scope.row.voucher"
style="display: flex; justify-content: center; align-items: center; cursor: pointer;"
@click="previewImage(scope.row.voucher)">
<img :src="scope.row.voucher" alt="支付凭证" style="width: auto; height: 40px;">
<img :src="scope.row.voucher" :alt="t('common_list.payVoucher')"
style="width: auto; height: 40px;">
</div>
<div v-else
style="display: flex; justify-content: center; align-items: center; height: 40px;">
@ -117,30 +124,36 @@
</div>
</template>
</el-table-column>
<el-table-column prop="submitterName" label="提交人" width="150px" show-overflow-tooltip />
<el-table-column prop="remark" label="备注" width="150px" show-overflow-tooltip />
<el-table-column prop="submitterName" :label="t('common_list.submitter')" width="150px"
show-overflow-tooltip />
<el-table-column prop="remark" :label="t('common_list.remark')" width="150px"
show-overflow-tooltip />
<!-- 客服专属的订单状态列 -->
<el-table-column fixed="right" prop="status" label="订单状态" width="100px">
<el-table-column fixed="right" prop="status" :label="t('common_list.orderStatus')"
width="100px">
<template #default="scope">
<span v-if="scope.row.status == 0">待审核</span>
<span v-else-if="scope.row.status == 1 || scope.row.status == 4">已通过</span>
<span v-else-if="scope.row.status == 2">已驳回</span>
<span v-else-if="scope.row.status == 5">已撤回</span>
<span v-else-if="scope.row.status == 6">退款</span>
<span v-if="scope.row.status == 0">{{ t('common.pendingAudit') }}</span>
<span v-else-if="scope.row.status == 1 || scope.row.status == 4">{{ t('common.passed')
}}</span>
<span v-else-if="scope.row.status == 2">{{ t('common.rejected') }}</span>
<span v-else-if="scope.row.status == 5">{{ t('common.withdrawn') }}</span>
<span v-else-if="scope.row.status == 6">{{ t('common.refunded') }}</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="120px">
<el-table-column fixed="right" :label="t('common_list.operation')" width="120px">
<template #default=scope>
<el-link v-if="scope.row.status == 4" style="color: #FA5A1E;"
@click="openConfirm('refund', scope.row)">退款</el-link>
<el-link v-else-if="scope.row.status == 1" style="color: #2741DE;">待填写手续费</el-link>
@click="openConfirm('refund', scope.row)">{{ t('common.refund') }}</el-link>
<el-link v-else-if="scope.row.status == 1" style="color: #2741DE;">{{
t('common.pendingFee') }}</el-link>
<el-link v-else-if="scope.row.status == 5" style="color: #2741DE;"
@click="openAddForm(scope.row)">编辑</el-link>
@click="openAddForm(scope.row)">{{ t('common.edit') }}</el-link>
<el-link v-else-if="scope.row.status == 0" style="color: #FA5A1E;"
@click="openConfirm('recall', scope.row)">撤回</el-link>
@click="openConfirm('recall', scope.row)">{{ t('common.withdraw') }}</el-link>
<el-link v-else-if="scope.row.status == 2" style="color: #FA5A1E;"
@click="openRejectReason(scope.row.rejectReason)">查看驳回理由</el-link>
@click="openRejectReason(scope.row.rejectReason)">{{ t('common.viewRejectReason')
}}</el-link>
</template>
</el-table-column>
</el-table>
@ -158,32 +171,32 @@
<!-- 撤回确认弹窗 -->
<div class="recallDialog" v-show="recallDialog">
<div class="close">
<button @click="closeRecall" class="Btn">关闭</button>
<button @click="closeRecall" class="Btn">{{ t('common.close') }}</button>
</div>
<div class="text">
<text class="txt">{{ textContent }}</text>
</div>
<div class="cancle">
<button @click="closeRecall" class="Btn">取消</button>
<button @click="closeRecall" class="Btn">{{ t('common.cancel') }}</button>
</div>
<div class="confirm">
<button @click="handleRecall" class="Btn">确定</button>
<button @click="handleRecall" class="Btn">{{ t('common.confirm') }}</button>
</div>
</div>
<!-- 退款确认弹窗 -->
<div class="recallDialog" v-show="refundConfirmDialog">
<div class="close">
<button @click="closeConfirmRefund" class="Btn">关闭</button>
<button @click="closeConfirmRefund" class="Btn">{{ t('common.close') }}</button>
</div>
<div class="text">
<text class="txt">{{ textContent }}</text>
</div>
<div class="cancle">
<button @click="closeConfirmRefund" class="Btn">取消</button>
<button @click="closeConfirmRefund" class="Btn">{{ t('common.cancel') }}</button>
</div>
<div class="confirm">
<button @click="openRefundDialog" class="Btn">确定</button>
<button @click="openRefundDialog" class="Btn">{{ t('common.confirm') }}</button>
</div>
</div>
@ -191,70 +204,74 @@
<el-dialog class="adddialog" v-model="addFormisible" width="20vw" :before-close="closeAddForm">
<el-form class="addForm" ref="addFormRef" :rules="addFormRule" :model="addFormData" label-width="4vw"
label-position="left">
<el-form-item label="精网号" required prop="jwcode">
<el-input v-model="addFormData.jwcode" placeholder="请输入精网号" @blur="jwcodeSeachMarket" />
<el-form-item :label="t('common_add.jwcode')" required prop="jwcode">
<el-input v-model="addFormData.jwcode" :placeholder="t('common_add.jwcodePlaceholder')"
@blur="jwcodeSeachMarket" />
</el-form-item>
<el-form-item label="客户姓名" required prop="name">
<el-input disabled v-model="addFormData.name" placeholder="请输入客户姓名" />
<el-form-item :label="t('common_add.customerName')" required prop="name">
<el-input disabled v-model="addFormData.name"
:placeholder="t('common_add.customerNamePlaceholder')" />
</el-form-item>
<el-form-item label="所属地区" prop="market">
<el-input disabled v-model="addFormData.marketName" placeholder="请输入所属地区" />
<el-form-item :label="t('common_add.market')" prop="market">
<el-input disabled v-model="addFormData.marketName"
:placeholder="t('common_add.marketPlaceholder')" />
</el-form-item>
<el-form-item label="活动名称" required prop="activity">
<el-select v-model="addFormData.activity" placeholder="请选择活动方式" clearable>
<el-form-item :label="t('common_add.activity')" required prop="activity">
<el-select v-model="addFormData.activity" :placeholder="t('common_add.activityPlaceholder')"
clearable>
<el-option v-for="item in activityList" :key="item.id" :label="item.activityName"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="产品名称" required @change="ifGold" prop="goodsName">
<el-form-item :label="t('common_add.productName')" required @change="ifGold" prop="goodsName">
<ProductSelect ref="productSelectRef" v-model="addFormData.goodsName"></ProductSelect>
</el-form-item>
<el-form-item v-show="!isGold" label="产品数量" required>
<el-form-item v-show="!isGold" :label="t('common_add.productNum')" required>
<div style="display: flex;">
<el-input style="padding-right: 30px; flex: 3;" v-model="addFormData.goodNum"
placeholder="请输入产品数量" />
:placeholder="t('common_add.productNumPlaceholder')" />
<CurrencySelect v-model="addFormData.numUnit" :items="numUnitList" style="flex: 1.5;"
placeholder="单位" @change="handleCurrencyChange" />
:placeholder="t('common_add.numUnit')" @change="handleCurrencyChange" />
</div>
</el-form-item>
<div v-show="isGold" style="margin-bottom: 15px; display: flex;">
<div style=" display: flex; ">
<span
style="color: #999999; display: flex; white-space: nowrap;align-items: center;">永久金币</span>
<span style="color: #999999; display: flex; white-space: nowrap;align-items: center;">{{
t('common_add.permanentGold') }}</span>
<el-input placeholder="0"
style="padding-right: 10px; padding-left: 10px; height: 30px; width: 110px;"
v-model="addFormData.permanentGold" />
</div>
<div style="padding-right: 5px; display: flex;">
<span
style="color: #999999; display: flex; white-space: nowrap;align-items: center;">免费金币</span>
<span style="color: #999999; display: flex; white-space: nowrap;align-items: center;">{{
t('common_add.freeGold') }}</span>
<el-input placeholder="0"
style="padding-right: 10px; padding-left: 10px; height: 30px; width: 110px;"
v-model="addFormData.freeGold" />
</div>
</div>
<el-form-item label="付款币种" required prop="paymentCurrency">
<CurrencySelect v-model="addFormData.paymentCurrency" :items="customOptions" placeholder="请选择付款币种"
@change="handleCurrencyChange" />
<el-form-item :label="t('common_add.payCurrency')" required prop="paymentCurrency">
<CurrencySelect v-model="addFormData.paymentCurrency" :items="customOptions"
:placeholder="t('common_add.payCurrencyPlaceholder')" @change="handleCurrencyChange" />
</el-form-item>
<el-form-item label="付款金额" required prop="paymentAmount">
<el-input v-model="addFormData.paymentAmount" placeholder="请输入付款金额" />
<el-form-item :label="t('common_add.payAmount')" required prop="paymentAmount">
<el-input v-model="addFormData.paymentAmount" :placeholder="t('common_add.payAmountPlaceholder')" />
</el-form-item>
<el-form-item label="支付方式" required prop="payType">
<CurrencySelect v-model="addFormData.payType" :items="paytypeOptions" placeholder="请选择支付方式"
@change="ifGroup">
<el-form-item :label="t('common_add.payMethod')" required prop="payType">
<CurrencySelect v-model="addFormData.payType" :items="paytypeOptions"
:placeholder="t('common_add.payMethodPlaceholder')" @change="ifGroup">
</CurrencySelect>
</el-form-item>
<el-form-item label="到账地区" prop="receivedMarket">
<el-form-item :label="t('common_add.receiveArea')" prop="receivedMarket">
<CurrencySelect v-model="addFormData.receivedMarket" :items="MoneyAddressOptions"
:disabled="isGroup" placeholder="请选择到账地区">
:disabled="isGroup" :placeholder="t('common_add.receiveAreaPlaceholder')">
</CurrencySelect>
</el-form-item>
<el-form-item label="付款时间" required prop="payTime">
<el-form-item :label="t('common_add.payTime')" required prop="payTime">
<el-date-picker type="datetime" placement="right" v-model="addFormData.payTime"
placeholder="请选择付款时间" />
:placeholder="t('common_add.payTimePlaceholder')" />
</el-form-item>
<el-form-item label="转账凭证" prop="voucher">
<el-form-item :label="t('common_add.transferVoucher')" prop="voucher">
<div class="pic">
<el-upload ref="uploadRef" class="uploader" :show-file-list="false" list-type="picture-card"
:auto-upload="false" :before-upload="beforeUpload" :on-error="handelImgErr"
@ -267,87 +284,93 @@
</el-upload>
</div>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="addFormData.remark" type="textarea" :rows="4" placeholder="请输入备注" maxlength="100"
show-word-limit />
<el-form-item :label="t('common_add.remark')" prop="remark">
<el-input v-model="addFormData.remark" type="textarea" :rows="4" maxlength="100" show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button style="background-color: #7E91FF;" @click="closeAddForm">取消</el-button>
<el-button style="background-color: #7E91FF;" @click="closeAddForm">{{ t('common.cancel')
}}</el-button>
<el-button v-if="addOrEdit == 1" style="background-color: #2741DE; margin-left: 2.5vw;"
type="primary" @click="throttledhandleAddForm" :disabled="ifAddDone">确定</el-button>
type="primary" @click="throttledhandleAddForm" :disabled="ifAddDone">{{ t('common.confirm')
}}</el-button>
<el-button v-else-if="addOrEdit == 2" style="background-color: #2741DE; margin-left: 2.5vw;"
type="primary" @click="throttledhandleEditForm" :disabled="ifReAddDone">编辑</el-button>
type="primary" @click="throttledhandleEditForm" :disabled="ifReAddDone">{{ t('common.edit')
}}</el-button>
</span>
</template>
</el-dialog>
<!-- 客服新增退款弹窗 -->
<el-dialog v-model="refundDialog" title="退款" class="refundDialog" overflow draggable style="width: 40vw;"
:before-close="closeRefundForm">
<el-dialog v-model="refundDialog" :title="t('common_add.refund')" class="refundDialog" overflow draggable
style="width: 40vw;" :before-close="closeRefundForm">
<div style="display: flex;">
<div class="left">
<div class="add-item">
<el-text style="width:4vw;">精网号</el-text>
<el-text style="width:4vw;">{{ t('common_add.jwcode') }}</el-text>
<el-input v-model="refundFormData.jwcode" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">客户姓名</el-text>
<el-text style="width:4vw;">{{ t('common_add.customerName') }}</el-text>
<el-input v-model="refundFormData.name" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">所属地区</el-text>
<el-text style="width:4vw;">{{ t('common_add.market') }}</el-text>
<el-input v-model="refundFormData.marketName" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">活动名称</el-text>
<el-text style="width:4vw;">{{ t('common_add.activity') }}</el-text>
<el-input v-model="refundFormData.activity" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">产品名称</el-text>
<el-text style="width:4vw;">{{ t('common_add.productName') }}</el-text>
<el-input v-model="refundFormData.goodsName" style="width:10vw;" disabled />
</div>
<div v-show="!isRefundGold" class="add-item">
<el-text style="width:4vw;">产品数量</el-text>
<el-text style="width:4vw;">{{ t('common_add.productNum') }}</el-text>
<el-input style="padding-right: 10px; width:6.5vw;" v-model="refundFormData.goodNum"
placeholder="请输入产品数量" disabled />
:placeholder="t('common_add.productNumPlaceholder')" disabled />
<CurrencySelect disabled v-model="refundFormData.numUnit" :items="numUnitList"
style="width: 3.5vw;" placeholder="单位" @change="handleCurrencyChange" />
style="width: 3.5vw;" :placeholder="t('common_add.numUnit')"
@change="handleCurrencyChange" />
</div>
<div v-show="isRefundGold" style="margin-bottom: 15px; ">
<div style=" display: flex; ">
<span
style="color: #999999; display: flex; white-space: nowrap;align-items: center;width:4vw;">永久金币</span>
style="color: #999999; display: flex; white-space: nowrap;align-items: center;width:4vw;">{{
t('common_add.permanentGold') }}</span>
<el-input style="padding-right: 10px; height: 30px; width: 110px; margin-bottom: 10px"
v-model="refundFormData.permanentGold" disabled />
</div>
<div style="padding-right: 5px; display: flex;">
<span
style="color: #999999; display: flex; white-space: nowrap;align-items: center;width:4vw;">免费金币</span>
style="color: #999999; display: flex; white-space: nowrap;align-items: center;width:4vw;">{{
t('common_add.freeGold') }}</span>
<el-input style="padding-right: 10px; height: 30px; width: 110px;"
v-model="refundFormData.freeGold" disabled />
</div>
</div>
<div class="add-item">
<el-text style="width:4vw;">付款币种</el-text>
<el-text style="width:4vw;">{{ t('common_add.payCurrency') }}</el-text>
<el-input v-model="refundFormData.paymentCurrency" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">付款金额</el-text>
<el-text style="width:4vw;">{{ t('common_add.payAmount') }}</el-text>
<el-input v-model="refundFormData.paymentAmount" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">支付方式</el-text>
<el-text style="width:4vw;">{{ t('common_add.payMethod') }}</el-text>
<el-input v-model="refundFormData.payType" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;">付款时间</el-text>
<el-text style="width:4vw;">{{ t('common_add.payTime') }}</el-text>
<el-date-picker v-model="refundFormData.payTime" type="datetime" style="width:10vw;" disabled />
</div>
<div class="add-item">
<el-text style="width:4vw;" size="small">转账凭证</el-text>
<el-form-item :rules="{ required: true, message: '请上传图片', trigger: 'change' }">
<el-text style="width:4vw;" size="small">{{ t('common_add.transferVoucher') }}</el-text>
<el-form-item
:rules="{ required: true, message: t('common_add.uploadPhoto'), trigger: 'change' }">
<el-upload ref="uploadRef" :auto-upload="false" list-type="picture-card"
:show-file-list="false">
<template #default>
@ -361,51 +384,51 @@
</el-form-item>
</div>
<div class="add-item">
<el-text style="width:4vw;">备注</el-text>
<el-text style="width:4vw;">{{ t('common_add.remark') }}</el-text>
<el-input v-model="refundFormData.remark" style="width:10vw;" :rows="2" type="textarea"
maxLength="100" disabled show-word-limit />
</div>
</div>
<div class="right">
<div class="add-item">
<el-text style="width:4vw;">退款模式</el-text>
<el-text style="width:4vw;">{{ t('common_add.refundModel') }}</el-text>
<el-radio-group v-model="refundFormData.refundModel">
<el-radio value="0">全部退款</el-radio>
<el-radio value="1">部分退款</el-radio>
<el-radio value="0">{{ t('common_add.refundModelAll') }}</el-radio>
<el-radio value="1">{{ t('common_add.refundModelPart') }}</el-radio>
</el-radio-group>
</div>
<div class="add-item"
v-show="refundFormData.goodsName === '金币充值' && refundFormData.refundModel === '1'">
<el-text style="width:4vw;">永久金币</el-text>
v-show="refundFormData.goodsName === t('cash.coinRecharge') && refundFormData.refundModel === '1'">
<el-text style="width:4vw;">{{ t('common_add.permanentGold') }}</el-text>
<el-input v-model="refundFormData.partRefundGold" style="width:5vw;" />&nbsp;&nbsp;
</div>
<div class="add-item"
v-show="refundFormData.goodsName === '金币充值' && refundFormData.refundModel === '1'">
<el-text style="width:4vw;">免费金币</el-text>
v-show="refundFormData.goodsName === t('cash.coinRecharge') && refundFormData.refundModel === '1'">
<el-text style="width:4vw;">{{ t('common_add.freeGold') }}</el-text>
<el-input v-model="refundFormData.partRefundFree" style="width:5vw;" />&nbsp;&nbsp;
</div>
<div class="add-item">
<el-text style="width:4vw;">退款理由</el-text>
<el-text style="width:4vw;">{{ t('common_add.refundReason') }}</el-text>
<el-input v-model="refundFormData.refundReason" style="width:10vw;" :rows="5" maxlength="150"
show-word-limit type="textarea" />
</div>
<div>ps:请在退款理由表明用户的退款需求</div>
<div>{{ t('common_add.tip') }}</div>
<div style="display:flex;justify-content: center;margin-top: 5vh;">
<el-button type="default" @click="closeRefundForm">取消</el-button>
<el-button type="primary" @click="throttledsubmitRefund">提交</el-button>
<el-button type="default" @click="closeRefundForm">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="throttledsubmitRefund">{{ t('common.submit') }}</el-button>
</div>
</div>
</div>
</el-dialog>
<!-- 查看驳回理由 -->
<el-dialog title="驳回理由" v-model="rejectReasonVisible" width="50%" top="30vh"
<el-dialog :title="t('common_add.rejectReason')" v-model="rejectReasonVisible" width="50%" top="30vh"
style="min-width: 200px; max-width: 500px;" :before-close="closeRejectForm">
<div class="reject-reason-box">
{{ rejectReason }}
</div>
<div class="rejectBtn">
<el-button type="primary" @click="closeRejectForm">确定</el-button>
<el-button type="primary" @click="closeRejectForm">{{ t('common.confirm') }}</el-button>
</div>
</el-dialog>
</div>
@ -429,6 +452,10 @@ import { isNumber } from 'lodash'
import { addFormRule } from './utils/recriveFormRules.js'
import { productList, MarketNameForId, CurrencyForId, marketList, statusList } from './utils/staticData.js'
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
// ===================== =====================
const adminStore = useAdminStore();
const { menuTree } = storeToRefs(adminStore);
@ -436,7 +463,7 @@ const adminData = ref({}) // 管理员信息
const tableData = ref([]) //
const total = ref(0) //
const pageInfo = ref({ pageSize: 10, pageNum: 1 }) //
const numUnitList = ref(['年', '月'])
const numUnitList = ref([t('cash.year'), t('cash.month')])
//
const market = ref([])
@ -522,12 +549,12 @@ const getlist = async () => {
if (searchData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(searchData.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return;
}
//
if (searchData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
ElMessage.error(t('elmessage.limitJwcodeLength'))
return;
}
}
@ -558,7 +585,7 @@ const getlist = async () => {
tableData.value = result.data.list
total.value = result.data.total
} else {
ElMessage.error('数据异常')
ElMessage.error(t('elmessage.dataException'))
console.log(result.msg);
}
} catch (error) {
@ -587,24 +614,36 @@ const uploadRef = ref(null) // 上传组件引用
//
const ifGold = () => {
if (addFormData.value.goodsName === '金币充值') {
if (addFormData.value.goodsName === t('cash.coinRecharge')) {
isGold.value = true
addFormData.value.goodNum = 0
} else {
isGold.value = false
numUnitList.value = ['个', '年', '月']
const selectItems = ["AI机构追踪", "AI机构出击", "AI机构资金", "AI机构活跃度", "超级机构透视", "超级机构伏击", "超级机构猎杀", "超级机构脉搏", "超级机构罗盘", 'HC信息费', 'HC信息费', 'AI机构探测神器', '超级机构探测神器']
numUnitList.value = [t('cash.unit'), t('cash.year'), t('cash.month')]
const selectItems = ref([
t('cash.aiService.aiTracking'),
t('cash.aiService.aiAttack'),
t('cash.aiService.aiFunds'),
t('cash.aiService.aiActivity'),
t('cash.aiService.superPerspective'),
t('cash.aiService.superAmbush'),
t('cash.aiService.superHunting'),
t('cash.aiService.superPulse'),
t('cash.aiService.superCompass'),
t('cash.aiService.aiDetectionTool'),
t('cash.aiService.superDetectionTool')
])
if (selectItems.includes(addFormData.value.goodsName)) {
if (addOrEdit.value == 1) {
addFormData.value.numUnit = ''
}
numUnitList.value = ['年', '月']
} else if (addFormData.value.goodsName == '静态信息费') {
addFormData.value.numUnit = '年'
numUnitList.value = ['年']
numUnitList.value = [t('cash.year'), t('cash.month')]
} else if (addFormData.value.goodsName == t('cash.staticInfoFee')) {
addFormData.value.numUnit = t('cash.year')
numUnitList.value = [t('cash.year')]
} else {
addFormData.value.numUnit = '个'
numUnitList.value = ['个']
addFormData.value.numUnit = t('cash.unit')
numUnitList.value = [t('cash.unit')]
}
}
}
@ -612,18 +651,18 @@ const ifGold = () => {
//
const isGroup = ref(false)
const ifGroup = () => {
if (addFormData.value.payType === 'Stripe-链接收款' || addFormData.value.payType === 'PaymentAsia-链接收款') {
if (addFormData.value.payType === t('cash.payMethods.stripe') || addFormData.value.payType === t('cash.payMethods.paymentAsia')) {
isGroup.value = true
addFormData.value.receivedMarket = '香港'
} else if (addFormData.value.payType === 'Ipay88-链接收款') {
addFormData.value.receivedMarket = t('cash.markets.HongKong')
} else if (addFormData.value.payType === t('cash.payMethods.ipay88')) {
isGroup.value = true
addFormData.value.receivedMarket = '马来西亚'
} else if (addFormData.value.payType === 'E-Transfer') {
addFormData.value.receivedMarket = t('cash.markets.Malaysia')
} else if (addFormData.value.payType === t('cash.payMethods.transfer')) {
isGroup.value = true
addFormData.value.receivedMarket = '加拿大'
} else if (addFormData.value.payType === 'Grabpay' || addFormData.value.payType === 'Nets' || addFormData.value.payType === 'Paypal') {
addFormData.value.receivedMarket = t('cash.markets.Canada')
} else if (addFormData.value.payType === t('cash.payMethods.grabpay') || addFormData.value.payType === t('cash.payMethods.nets') || addFormData.value.payType === t('cash.payMethods.paypal')) {
isGroup.value = true
addFormData.value.receivedMarket = '新加坡'
addFormData.value.receivedMarket = t('cash.markets.Singapore')
} else {
isGroup.value = false
}
@ -637,12 +676,12 @@ const jwcodeSeachMarket = async () => {
data: addFormData.value.jwcode
})
if (result.code == 200) {
ElMessage.success('客户信息查询成功')
ElMessage.success(t('elmessage.customerSuccess'))
addFormData.value.market = result.data.market
addFormData.value.marketName = result.data.marketName
addFormData.value.name = result.data.name
} else {
ElMessage.error('客户不存在')
ElMessage.error(t('elmessage.customerNotExist'))
}
} catch (error) {
console.log(error);
@ -678,7 +717,7 @@ const closeAddForm = () => {
}
const testGold = () => {
//
if (addFormData.value.goodsName == '金币充值') {
if (addFormData.value.goodsName == t('cash.coinRecharge')) {
if (addFormData.value.permanentGold == null) {
addFormData.value.permanentGold = 0
}
@ -690,13 +729,13 @@ const testGold = () => {
// 0-9999990
const reg = /^[0-9]{1,6}$/;
if (!reg.test(permanentGold) || permanentGold < 0) {
return { valid: false, message: '请检查永久金币格式' };
return { valid: false, message: t('elmessage.checkPermanentFormat') };
}
if (!reg.test(freeNum) || freeNum < 0) {
return { valid: false, message: '请检查免费金币格式' };
return { valid: false, message: t('elmessage.checkFreeFormat') };
}
if (permanentGold == 0 && freeNum == 0) {
return { valid: false, message: '永久金币或免费金币不能同为0' };
return { valid: false, message: t('elmessage.permanentAndFreeNoZero') };
}
}
return { valid: true };
@ -712,18 +751,18 @@ const handleAddForm = async () => {
//
if (!isGold.value) {
if (!addFormData.value.goodNum) {
ElMessage.error('请输入产品数量');
ElMessage.error(t('elmessage.checkProductNum'));
return;
}
const positiveIntReg = /^[1-9]\d*$/;
if (!positiveIntReg.test(addFormData.value.goodNum)) {
ElMessage.error('产品数量必须为正整数');
ElMessage.error(t('elmessage.productNumError'));
return;
}
}
if (addFormData.value.numUnit == '') {
ElMessage.error('请选择产品数量单位');
ElMessage.error(t('elmessage.checkNumUnit'));
return;
}
//
@ -746,14 +785,14 @@ const handleAddForm = async () => {
}
})
if (result.code == 200) {
ElMessage.success('添加成功')
ElMessage.success(t('elmessage.addSuccess'))
getlist()
closeAddForm()
}
ifAddDone.value = false
} catch (error) {
console.log('新增报错:', error);
ElMessage.error('请完善表单信息后提交');
ElMessage.error(t('elmessage.checkFormInfoSubmit'));
ifAddDone.value = false
}
}
@ -774,17 +813,17 @@ const handleEditForm = async () => {
//
if (!isGold.value) {
if (!addFormData.value.goodNum) {
ElMessage.error('请输入产品数量');
ElMessage.error(t('elmessage.checkProductNum'));
return;
}
const positiveIntReg = /^[1-9]\d*$/;
if (!positiveIntReg.test(addFormData.value.goodNum)) {
ElMessage.error('产品数量必须为正整数');
ElMessage.error(t('elmessage.productNumError'));
return;
}
}
if (addFormData.value.numUnit == '') {
ElMessage.error('请选择产品数量单位');
ElMessage.error(t('elmessage.checkNumUnit'));
return;
}
//
@ -806,7 +845,7 @@ const handleEditForm = async () => {
}
})
if (result.code == 200) {
ElMessage.success('编辑成功')
ElMessage.success(t('elmessage.editSuccess'))
getlist()
closeAddForm()
}
@ -818,9 +857,38 @@ const handleEditForm = async () => {
}
//
const customOptions = ref(['美元(USD)', '港币(HKD)', '新币(SGD)', '马币(MYR)', '泰铢(THB)', '加币(CAD)', '越南盾(VDN)', '韩元(KRW)'])
const paytypeOptions = ref(["Stripe-链接收款", "PaymentAsia-链接收款", "Ipay88-链接收款", "Grabpay", "Nets", "E-Transfer", "Paypal", "银行转账", "刷卡", "现金", "支票"])
const MoneyAddressOptions = ref(['马来西亚', '香港', '新加坡', '泰国', '越南HCM', '加拿大'])
const customOptions = ref([
t('cash.currency.usd'), // (USD)
t('cash.currency.hkd'), // (HKD)
t('cash.currency.sgd'), // (SGD)
t('cash.currency.myr'), // (MYR)
t('cash.currency.thb'), // (THB)
t('cash.currency.cad'), // (CAD)
t('cash.currency.vnd'), // (VDN)
t('cash.currency.krw') // (KRW)
])
// - 使cash.payMethods
const paytypeOptions = ref([
t('cash.payMethods.stripe'), // Stripe-
t('cash.payMethods.paymentAsia'), // PaymentAsia-
t('cash.payMethods.ipay88'), // Ipay88-
t('cash.payMethods.grabpay'), // Grabpay
t('cash.payMethods.nets'), // Nets
t('cash.payMethods.transfer'), // E-Transfer
t('cash.payMethods.paypal'), // PayPal
t('cash.payMethods.bankTransfer'),//
t('cash.payMethods.card'), //
t('cash.payMethods.cash'), //
t('cash.payMethods.check') //
])
const MoneyAddressOptions = ref([
t('cash.markets.Malaysia'), // 西
t('cash.markets.HongKong'), //
t('cash.markets.Singapore'), //
t('cash.markets.Thailand'), //
t('cash.markets.VietnamHCM'), // HCM
t('cash.markets.Canada') //
])
const handleCurrencyChange = (option) => {
console.log('选中的币种:', option);
};
@ -830,20 +898,20 @@ const handleImgSuccess = (response) => {
try {
addFormData.value.voucher = response.data.url
} catch (error) {
ElMessage.error(response.msg || '图片上传失败')
ElMessage.error(response.msg || t('elmessage.uploadFailed'))
}
}
const handelImgErr = (err) => {
console.log(err);
addFormData.value.imageUrl = null
ElMessage.error("图片上传失败")
ElMessage.error(t('elmessage.uploadFailed'))
}
const beforeUpload = (rawFile) => {
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
ElMessage.error('图片必须是jpg或png类型!')
ElMessage.error(t('elmessage.photoFormatError'))
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('图片大小不能超过 2MB!')
ElMessage.error(t('elmessage.limitImageSize2MB'))
return false
}
return true
@ -863,14 +931,14 @@ const customUpload = async (options) => {
})
if (response.code === 200 && response.data) {
handleImgSuccess(response, options.file)
ElMessage.success('上传成功')
ElMessage.success(t('elmessage.uploadSuccess'))
} else {
options.onError(response)
ElMessage.error(response.msg || '上传失败')
ElMessage.error(response.msg || t('elmessage.uploadFailed'))
}
} catch (error) {
console.error('上传错误:', error)
ElMessage.error(`上传失败: ${error.msg || error.message || '网络异常'}`)
ElMessage.error(t('elmessage.uploadFailed') + `: ${error.msg || error.message || t('elmessage.inNetworkError')}`)
}
}
@ -913,7 +981,7 @@ const isRefundGold = ref(false) // 退款产品是否为金币
// 退
const ifRefundGold = () => {
if (refundFormData.value.goodsName === '金币充值') {
if (refundFormData.value.goodsName === t('cash.coinRecharge')) {
isRefundGold.value = true
refundFormData.value.goodNum = 0
} else {
@ -924,12 +992,12 @@ const ifRefundGold = () => {
// /退
const openConfirm = (val, row) => {
if (val === 'refund') {
textContent.value = '将要对该订单退款!'
textContent.value = t('common.willRefundOrder')
refundFormData.value = { ...row }
ifRefundGold()
refundConfirmDialog.value = true
} else if (val === 'recall') {
textContent.value = '将要撤回该信息!'
textContent.value = t('common.willRecallOrder')
recallDialog.value = true
RecallNum.value = row.orderCode
}
@ -950,7 +1018,7 @@ const handleRecall = async () => {
data: { orderCode: RecallNum.value }
})
if (result.code == 200) {
ElMessage.success('撤回成功')
ElMessage.success(t('common.withdrawSuccess'))
getlist()
closeRecall()
}
@ -985,20 +1053,20 @@ const submitRefund = async () => {
refundFormData.value.partRefundFree = refundFormData.value.freeGold
} else if (refundFormData.value.refundModel == 1) {
if (refundFormData.value.partRefundGold > refundFormData.value.permanentGold || refundFormData.value.partRefundFree > refundFormData.value.freeGold) {
ElMessage.error('退款金额不能大于订单金额')
ElMessage.error(t('elmessage.limitRefundAmount'))
return
}
}
//
if (refundFormData.value.jwcode) {
const isPositiveInteger = /^[1-9]\d*$/.test(refundFormData.value.jwcode);
if (!isPositiveInteger) {
ElMessage.error('请输入正确的精网号')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return;
}
if (refundFormData.value.jwcode.length > 8) {
ElMessage.error('精网号长度不能超过8位')
ElMessage.error(t('elmessage.limitJwcodeLength'))
return;
}
}
@ -1023,7 +1091,7 @@ const submitRefund = async () => {
}
})
if (result.code == 200) {
ElMessage.success('新增退款成功')
ElMessage.success(t('elmessage.addRefundSuccess'))
getlist()
closeRefundForm()
} else {
@ -1049,7 +1117,7 @@ const getActivitys = async () => {
if (result.code == 200) {
activityList.value = result.data
} else {
ElMessage.error('活动列表获取失败')
ElMessage.error(t('elmessage.activityLoadFailed'))
}
} catch (error) {
console.log('活动列表请求失败', error)
@ -1067,7 +1135,20 @@ const getAdminData = async () => {
}
//
const paytypeList = ["Stripe-链接收款", "PaymentAsia-链接收款", "Ipay88-链接收款", "银行转账", "刷卡", "现金", "支票", "Grabpay", "Nets", "E-Transfer", "Paypal"]
// - 使cash.payMethods
const paytypeList = ref([
t('cash.payMethods.stripe'), // Stripe-
t('cash.payMethods.paymentAsia'), // PaymentAsia-
t('cash.payMethods.ipay88'), // Ipay88-
t('cash.payMethods.bankTransfer'),//
t('cash.payMethods.card'), //
t('cash.payMethods.cash'), //
t('cash.payMethods.check'), //
t('cash.payMethods.grabpay'), // Grabpay
t('cash.payMethods.nets'), // Nets
t('cash.payMethods.transfer'), // E-Transfer
t('cash.payMethods.paypal') // PayPal
])
const getMarket = async function () {
try {
const result = await API({

165
src/views/moneyManage/receiveDetail/utils/recriveFormRules.js

@ -1,84 +1,89 @@
export const addFormRule = {
// 精网号:6-10位纯数字
jwcode: [
{ required: true, message: '请输入精网号', trigger: 'blur' },
{ pattern: /^\d{6,10}$/, message: '请检查精网号格式', trigger: 'blur' }
],
// 客户姓名:必填
name: [
{ required: true, message: '请输入客户姓名', trigger: 'blur' }
],
// 所属地区:必填
market: [
{ required: true, message: '请选择所属地区', trigger: 'blur' }
],
// 活动名称:必填 + 长度小于30
activity: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
],
// 产品名称:必填
goodsName: [
{ required: true, message: '请选择产品名称', trigger: 'change' }
],
// 产品数量:0-100纯数字
goodNum: [
{ required: true, message: '请输入产品数量', trigger: 'blur' },
],
// 付款币种:必填
paymentCurrency: [
{ required: true, message: '请选择付款币种', trigger: 'change' }
],
// 付款金额:小于8位纯数字 + 不为0
paymentAmount: [
{ required: true, message: '请输入付款金额', trigger: 'blur' },
{
validator: (rule, value, callback) => {
// 匹配非负数字(支持整数或最多2位小数)
const reg = /^\d+(\.\d{1,2})?$/;
if (!reg.test(value)) {
callback(new Error('请输入有效的金额(最多2位小数)'));
} else {
const num = Number(value);
if (num === 0) {
callback(new Error('付款金额不能为0'));
} else if (num > 9999999) { // 限制最大值为9999999(7位整数)
callback(new Error('付款金额不能超过9999999'));
export const addFormRule = (t) => {
return {
// 精网号:6-10位纯数字
jwcode: [
{ required: true, message: t('common_add.jwcodePlaceholder'), trigger: 'blur' },
{ pattern: /^\d{6,10}$/, message: t('elmessage.checkJwcodeFormat'), trigger: 'blur' }
],
// 客户姓名:必填
name: [
{ required: true, message: t('common_add.customerNamePlaceholder'), trigger: 'blur' }
],
// 所属地区:必填
market: [
{ required: true, message: t('common_add.marketPlaceholder'), trigger: 'blur' }
],
// 活动名称:必填
activity: [
{ required: true, message: t('common_add.activityPlaceholder'), trigger: 'blur' },
],
// 产品名称:必填
goodsName: [
{ required: true, message: t('common_add.productNamePlaceholder'), trigger: 'change' }
],
// 产品数量:必填
goodNum: [
{ required: true, message: t('common_add.productNumPlaceholder'), trigger: 'blur' },
],
// 付款币种:必填
paymentCurrency: [
{ required: true, message: t('common_add.payCurrencyPlaceholder'), trigger: 'change' }
],
// 付款金额:必填 + 验证
paymentAmount: [
{ required: true, message: t('common_add.payAmountPlaceholder'), trigger: 'blur' },
{
validator: (rule, value, callback) => {
// 匹配非负数字(支持整数或最多2位小数)
const reg = /^\d+(\.\d{1,2})?$/;
if (!reg.test(value)) {
callback(new Error(t('elmessage.limitPositiveNumber2')));
} else {
callback();
const num = Number(value);
if (num === 0) {
callback(new Error(t('elmessage.limitPayAmountZero')));
} else if (num > 9999999) { // 限制最大值为9999999(7位整数)
callback(new Error(t('elmessage.limitPayAmountMax')));
} else {
callback();
}
}
}
},
trigger: 'blur'
}
],
// 支付方式:必填
payType: [
{ required: true, message: '请选择支付方式', trigger: 'change' }
],
// 到账地区:必填
receivedMarket: [
{ required: true, message: '请选择到账地区', trigger: 'change' }
],
// 付款时间:必填
payTime: [
{ required: true, message: '请选择付款时间', trigger: 'change' }
]
},
trigger: 'blur'
}
],
// 支付方式:必填
payType: [
{ required: true, message: t('common_add.payMethodPlaceholder'), trigger: 'change' }
],
// 到账地区:必填
receivedMarket: [
{ required: true, message: t('common_add.receiveAreaPlaceholder'), trigger: 'change' }
],
// 付款时间:必填
payTime: [
{ required: true, message: t('common_add.payTimePlaceholder'), trigger: 'change' }
]
};
};
export const editFormRule = {
// 到账金额:正数,整数部分最多6位,小数部分最多2位(支持纯小数如 0.1、0.99)
receivedAmount: [
{
pattern: /^(0\.\d{1,2}|[1-9]\d{0,5}(\.\d{1,2})?)$/, // 修正:添加 / 包裹正则
message: '请检查到账金额格式',
trigger: 'blur'
}
],
// 手续费:正数,整数部分最多6位,小数部分最多2位(不支持纯0开头的小数如 0.1,需从1开始)
handlingCharge: [
{
pattern: /^\d{1,6}(\.\d{1,2})?$/, // 注意:此正则允许 0 开头(如 0123 不符合整数规范)
message: '整数部分最多6位,小数部分最多2位',
trigger: 'blur'
}
],
export const editFormRule = (t) => {
return {
// 到账金额:正数,整数部分最多6位,小数部分最多2位(支持纯小数如 0.1、0.99)
receivedAmount: [
{
pattern: /^(0\.\d{1,2}|[1-9]\d{0,5}(\.\d{1,2})?)$/, // 修正:添加 / 包裹正则
message: t('elmessage.checkPayAmountFormat'),
trigger: 'blur'
}
],
// 手续费:正数,整数部分最多6位,小数部分最多2位(不支持纯0开头的小数如 0.1,需从1开始)
handlingCharge: [
{
pattern: /^\d{1,6}(\.\d{1,2})?$/, // 注意:此正则允许 0 开头(如 0123 不符合整数规范)
message: t('elmessage.limitPayAmountFormat'),
trigger: 'blur'
}
],
};
};

182
src/views/moneyManage/receiveDetail/utils/staticData.js

@ -1,194 +1,197 @@
import i18n from '@/components/locales'
const t = i18n.global.t
export const productList = [
{
"value": "金币产品",
"label": "金币产品",
"label": t('cash.goldProduct'),
"children": [
{
"value": "金币充值",
"label": "金币充值"
"label": t('cash.coinRecharge')
}
]
},
{
"value": "软件产品",
"label": "软件产品",
"label": t('cash.softwareProduct'),
"children": [
{
"value": "软件",
"label": "软件",
"label": t('cash.software'),
"children": [
{
"value": "美股",
"label": "美股",
"label": t('cash.softwareMenu.usStock'),
"children": [
{ "value": "美股软件", "label": "美股软件" },
{ "value": "美股金卡", "label": "美股金卡" },
{ "value": "美股套餐", "label": "美股套餐" }
{ "value": "美股软件", "label": t('cash.softwareMenu.usStockSoftware') },
{ "value": "美股金卡", "label": t('cash.softwareMenu.usStockGoldCard') },
{ "value": "美股套餐", "label": t('cash.softwareMenu.usStockPackage') }
]
},
{
"value": "港股",
"label": "港股",
"label": t('cash.softwareMenu.hkStock'),
"children": [
{ "value": "港股软件", "label": "港股软件" },
{ "value": "港股金卡", "label": "港股金卡" },
{ "value": "港股套餐", "label": "港股套餐" }
{ "value": "港股软件", "label": t('cash.softwareMenu.hkStockSoftware') },
{ "value": "港股金卡", "label": t('cash.softwareMenu.hkStockGoldCard') },
{ "value": "港股套餐", "label": t('cash.softwareMenu.hkStockPackage') }
]
},
{
"value": "A股",
"label": "A股",
"label": t('cash.softwareMenu.aStock'),
"children": [
{ "value": "A股软件", "label": "A股软件" },
{ "value": "A股金卡", "label": "A股金卡" },
{ "value": "A股套餐", "label": "A股套餐" }
{ "value": "A股软件", "label": t('cash.softwareMenu.aStockSoftware') },
{ "value": "A股金卡", "label": t('cash.softwareMenu.aStockGoldCard') },
{ "value": "A股套餐", "label": t('cash.softwareMenu.aStockPackage') }
]
},
{
"value": "新加坡股",
"label": "新加坡股",
"label": t('cash.softwareMenu.singaporeStock'),
"children": [
{ "value": "新加坡股软件", "label": "新加坡股软件" },
{ "value": "新加坡股金卡", "label": "新加坡股金卡" },
{ "value": "新加坡股套餐", "label": "新加坡股套餐" }
{ "value": "新加坡股软件", "label": t('cash.softwareMenu.singaporeStockSoftware') },
{ "value": "新加坡股金卡", "label": t('cash.softwareMenu.singaporeStockGoldCard') },
{ "value": "新加坡股套餐", "label": t('cash.softwareMenu.singaporeStockPackage') }
]
},
{
"value": "马股",
"label": "马股",
"label": t('cash.softwareMenu.malaysiaStock'),
"children": [
{ "value": "马股软件", "label": "马股软件" },
{ "value": "马股金卡", "label": "马股金卡" },
{ "value": "马股套餐", "label": "马股套餐" }
{ "value": "马股软件", "label": t('cash.softwareMenu.malaysiaStockSoftware') },
{ "value": "马股金卡", "label": t('cash.softwareMenu.malaysiaStockGoldCard') },
{ "value": "马股套餐", "label": t('cash.softwareMenu.malaysiaStockPackage') }
]
},
{
"value": "日本股",
"label": "日本股",
"label": t('cash.softwareMenu.japanStock'),
"children": [
{ "value": "日本股软件", "label": "日本股软件" },
{ "value": "日本股金卡", "label": "日本股金卡" },
{ "value": "日本股套餐", "label": "日本股套餐" }
{ "value": "日本股软件", "label": t('cash.softwareMenu.japanStockSoftware') },
{ "value": "日本股金卡", "label": t('cash.softwareMenu.japanStockGoldCard') },
{ "value": "日本股套餐", "label": t('cash.softwareMenu.japanStockPackage') }
]
},
{
"value": "泰股",
"label": "泰股",
"label": t('cash.softwareMenu.thailandStock'),
"children": [
{ "value": "泰股软件", "label": "泰股软件" },
{ "value": "泰股金卡", "label": "泰股金卡" },
{ "value": "泰股套餐", "label": "泰股套餐" }
{ "value": "泰股软件", "label": t('cash.softwareMenu.thailandStockSoftware') },
{ "value": "泰股金卡", "label": t('cash.softwareMenu.thailandStockGoldCard') },
{ "value": "泰股套餐", "label": t('cash.softwareMenu.thailandStockPackage') }
]
},
{
"value": "越南股",
"label": "越南股",
"label": t('cash.softwareMenu.vietnamStock'),
"children": [
{ "value": "越南股软件", "label": "越南股软件" },
{ "value": "越南股金卡", "label": "越南股金卡" },
{ "value": "越南股套餐", "label": "越南股套餐" }
{ "value": "越南股软件", "label": t('cash.softwareMenu.vietnamStockSoftware') },
{ "value": "越南股金卡", "label": t('cash.softwareMenu.vietnamStockGoldCard') },
{ "value": "越南股套餐", "label": t('cash.softwareMenu.vietnamStockPackage') }
]
},
{
"value": "印尼股",
"label": "印尼股",
"label": t('cash.softwareMenu.indonesiaStock'),
"children": [
{ "value": "印尼股软件", "label": "印尼股软件" },
{ "value": "印尼股金卡", "label": "印尼股金卡" },
{ "value": "印尼股套餐", "label": "印尼股套餐" }
{ "value": "印尼股软件", "label": t('cash.softwareMenu.indonesiaStockSoftware') },
{ "value": "印尼股金卡", "label": t('cash.softwareMenu.indonesiaStockGoldCard') },
{ "value": "印尼股套餐", "label": t('cash.softwareMenu.indonesiaStockPackage') }
]
},
{
"value": "韩国股",
"label": "韩国股",
"label": t('cash.softwareMenu.koreaStock'),
"children": [
{ "value": "韩国股软件", "label": "韩国股软件" },
{ "value": "韩国股金卡", "label": "韩国股金卡" },
{ "value": "韩国股套餐", "label": "韩国股套餐" }
{ "value": "韩国股软件", "label": t('cash.softwareMenu.koreaStockSoftware') },
{ "value": "韩国股金卡", "label": t('cash.softwareMenu.koreaStockGoldCard') },
{ "value": "韩国股套餐", "label": t('cash.softwareMenu.koreaStockPackage') }
]
},
{
"value": "台湾股",
"label": "台湾股",
"label": t('cash.softwareMenu.taiwanStock'),
"children": [
{ "value": "台湾股软件", "label": "台湾股软件" },
{ "value": "台湾股金卡", "label": "台湾股金卡" },
{ "value": "台湾股套餐", "label": "台湾股套餐" }
{ "value": "台湾股软件", "label": t('cash.softwareMenu.taiwanStockSoftware') },
{ "value": "台湾股金卡", "label": t('cash.softwareMenu.taiwanStockGoldCard') },
{ "value": "台湾股套餐", "label": t('cash.softwareMenu.taiwanStockPackage') }
]
}
]
},
{
"value": "AI机构探测神器",
"label": "AI机构探测神器",
"label": t('cash.aiService.aiDetectionTool'),
"children": [
{
"value": "AI机构追踪",
"label": "AI机构追踪"
"label": t('cash.aiService.aiTracking')
},
{
"value": "AI机构出击",
"label": "AI机构出击"
"label": t('cash.aiService.aiAttack')
},
{
"value": "AI机构资金",
"label": "AI机构资金"
"label": t('cash.aiService.aiFunds')
},
{
"value": "AI机构活跃度",
"label": "AI机构活跃度"
"label": t('cash.aiService.aiActivity')
},
{
"value": "AI机构探测神器",
"label": "AI机构探测神器"
"label": t('cash.aiService.aiDetectionTool')
}
]
},
{
"value": "超级机构探测神器",
"label": "超级机构探测神器",
"label": t('cash.aiService.superDetectionTool'),
"children": [
{
"value": "超级机构透视",
"label": "超级机构透视"
"label": t('cash.aiService.superPerspective')
},
{
"value": "超级机构伏击",
"label": "超级机构伏击"
"label": t('cash.aiService.superAmbush')
},
{
"value": "超级机构猎杀",
"label": "超级机构猎杀"
"label": t('cash.aiService.superHunting')
},
{
"value": "超级机构脉博",
"label": "超级机构脉博"
"label": t('cash.aiService.superPulse')
},
{
"value": "超级机构罗盘",
"label": "超级机构罗盘"
"label": t('cash.aiService.superCompass')
},
{
"value": "超级机构探测神器",
"label": "超级机构探测神器"
"label": t('cash.aiService.superDetectionTool')
}
]
},
{
"value": "其他",
"label": "其他",
"label": t('cash.other'),
"children": [
{
"value": "静态信息费",
"label": "静态信息费"
"label": t('cash.staticInfoFee')
},
{
"value": "博股会员",
"label": "博股会员"
"label": t('cash.BGmember')
},
{
"value": "HC信息费",
"label": "HC信息费"
"label": t('cash.HC')
}
]
}
@ -198,65 +201,72 @@ export const productList = [
export const MarketNameForId = (name) => {
if (name == '新加坡') {
if (name == t('cash.markets.Singapore') || name == '新加坡' || name == 'Singapore') {
return 4
} else if (name == '加拿大') {
} else if (name == t('cash.markets.Canada') || name == '加拿大' || name == 'Canada') {
return 24016
} else if (name == '马来西亚') {
} else if (name == t('cash.markets.Malaysia') || name == '马来西亚' || name == 'Malaysia') {
return 5
} else if (name == '香港') {
} else if (name == t('cash.markets.HongKong') || name == '香港' || name == 'Hong Kong') {
return 13
} else if (name == '泰国') {
} else if (name == t('cash.markets.Thailand') || name == '泰国' || name == 'Thailand') {
return 24018
} else if (name == '越南HCM') {
} else if (name == t('cash.markets.VietnamHCM') || name == '越南HCM' || name == 'Vietnam HCM') {
return 24022
} else {
return name
}
}
export const CurrencyForId = (name) => {
if (name == '美元(USD)') {
if (name == t('cash.currency.usd') || name == '美元(USD)' || name == 'US Dollar(USD)') {
return 1
} else if (name == '港币(HKD)') {
} else if (name == t('cash.currency.hkd') || name == '港币(HKD)' || name == 'Hong Kong Dollar(HKD)') {
return 2
} else if (name == '新币(SGD)') {
} else if (name == t('cash.currency.sgd') || name == '新币(SGD)' || name == 'Singapore Dollar(SGD)') {
return 3
} else if (name == '马币(MYR)') {
} else if (name == t('cash.currency.myr') || name == '马币(MYR)' || name == 'Malaysian Ringgit(MYR)') {
return 4
} else if (name == '泰铢(THB)') {
} else if (name == t('cash.currency.thb') || name == '泰铢(THB)' || name == 'Thai Baht(THB)') {
return 5
} else if (name == '加币(CAD)') {
} else if (name == t('cash.currency.cad') || name == '加币(CAD)' || name == 'Canadian Dollar(CAD)') {
return 6
} else if (name == '越南盾(VDN)') {
} else if (name == t('cash.currency.vnd') || name == '越南盾(VDN)' || name == 'Vietnamese Dong(VDN)') {
return 7
} else if (name == '韩元(KRW)') {
} else if (name == t('cash.currency.krw') || name == '韩元(KRW)' || name == 'South Korean Won(KRW)') {
return 8
} else {
return name
}
}
export const marketList = ['马来西亚', '香港', '新加坡', '泰国', '越南HCM', '加拿大']
export const marketList = [
t('cash.markets.Malaysia'),
t('cash.markets.HongKong'),
t('cash.markets.Singapore'),
t('cash.markets.Thailand'),
t('cash.markets.VietnamHCM'),
t('cash.markets.Canada')
]
export const statusList = [
{
name: '待审核',
name: t('cash.statusList.pending'),
value: 0
},
{
name: '已通过',
name: t('cash.statusList.passed'),
value: 134
},
{
name: '已撤回',
name: t('cash.statusList.recalled'),
value: 5
}, {
name: '退款',
name: t('cash.statusList.refunded'),
value: 6
}, {
name: '已驳回',
name: t('cash.statusList.rejected'),
value: 2
},
]
export const numUnitList = ['个', '年', '月']
export const numUnitList = [t('cash.unit'), t('cash.year'), t('cash.month')]

120
src/views/permissions/rolePermission.vue

@ -11,9 +11,11 @@ const adminStore = useAdminStore();
const { adminData, menuTree } = storeToRefs(adminStore);
import { permissionMapping, findMenuById } from "@/utils/menuTreePermission.js"
import { tr } from 'element-plus/es/locales.mjs'
import { useI18n } from 'vue-i18n'
// ref
const Ref = ref(null)
const { t } = useI18n()
const roleData = ref([])
const roleTotal = ref(100)
const treeRef = ref(null)
@ -37,10 +39,10 @@ const addRole = ref({
market: ''
})
const addRoleMarket = ref([])
const channelList = ref(['全部'])
const channelList = ref([t('common.all')])
const getRoleList = async function (val) {
if (!findMenuById(menuTree.value, permissionMapping.view_role_information)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermissionText'))
return
}
try {
@ -173,7 +175,7 @@ function processTreeData(data) {
const handleAddRole = async function () {
if (!findMenuById(menuTree.value, permissionMapping.add_role_information)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermissionText'))
return
}
try {
@ -182,7 +184,7 @@ const handleAddRole = async function () {
if (valid) {
resolve(); //
} else {
reject(new Error('请检查并完善表单信息')); //
reject(new Error(t('elmessage.checkFormInfo'))); //
}
});
});
@ -203,7 +205,7 @@ const handleAddRole = async function () {
}
})
if (res.code === 200) {
ElMessage.success('角色' + addRole.value.roleName + '添加成功')
ElMessage.success(t('elmessage.roleAddSuccess', { roleName: addRole.value.roleName }))
console.log('成功了,看看addRole', addRole.value)
console.log('提交的权限ID列表:', finalCheckedKeys)
closePermissionAddVisible()
@ -262,7 +264,7 @@ const getLists = async function () {
addRole.value.market = ''
}
} else {
ElMessage.error('该上级角色无归属地区')
ElMessage.error(t('elmessage.noParentRoleMarket'))
console.log('该上级角色无归属地区')
}
@ -417,7 +419,7 @@ const showMenuTree = (treeData, roleName) => {
Rolecheckedkeys.value = collectIds(treeData)
console.log('Rolecheckedkeys', Rolecheckedkeys.value)
currentRoleName.value = roleName || '权限详情'
currentRoleName.value = roleName || t('common_add.permissionDetails')
menuTreeVisible.value = true;
}
@ -525,7 +527,7 @@ const permissionEditRoleInit = async function (row) {
//
const permissionEditRole = async function () {
if (!findMenuById(menuTree.value, permissionMapping.edit_role_information)) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
try {
@ -534,7 +536,7 @@ const permissionEditRole = async function () {
if (valid) {
resolve();
} else {
reject(new Error('请检查并完善表单信息'));
reject(new Error(t('elmessage.checkFormInfo')));
}
});
});
@ -562,13 +564,13 @@ const permissionEditRole = async function () {
console.log('提交的权限ID列表:', finalCheckedKeys);
permissionEditRoleVisible.value = false;
getRoleList();
ElMessage.success('编辑角色成功');
ElMessage.success(t('elmessage.editSuccess'));
} else if (res.code === 0) {
console.log('角色名重复', permissionEditRoleObj.value);
ElMessage.error('角色名重复');
ElMessage.error(t('elmessage.roleNameDuplicate'));
} else {
console.log('编辑角色失败', res);
ElMessage.error('编辑角色失败');
ElMessage.error(t('elmessage.editFailed'));
}
} catch (error) {
console.log('编辑角色失败', error);
@ -602,22 +604,22 @@ const selectParentNodesForSubmit = (treeData, nodeId, checkedKeys) => {
const Rolerules = reactive({
roleName: [
{ required: true, message: '请输入角色名称', trigger: 'blur' },
{ min: 2, max: 20, message: '角色名称长度应在2-20个字符之间', trigger: 'blur' }
{ required: true, message: t('elmessage.inputRoleName'), trigger: 'blur' },
{ min: 2, max: 20, message: t('elmessage.roleNameLengthLimit'), trigger: 'blur' }
],
market: [
{ required: true, message: '请选择归属地区', trigger: 'change' }
{ required: true, message: t('elmessage.selectMarket'), trigger: 'change' }
],
checkedKeys: [
{
required: true,
message: '请选择权限列表',
message: t('elmessage.selectPermissionList'),
trigger: 'change', //
validator: (rule, value, callback) => {
if (value && value.length > 0) {
callback(); //
} else {
callback(new Error('请选择权限列表')); //
callback(new Error(t('elmessage.selectPermissionList'))); //
}
}
}
@ -642,11 +644,11 @@ onMounted(async function () {
<div>
<el-card class="card1" style="margin-bottom: 1vh;">
<div style="display: flex;">
<el-text size="large">角色名称</el-text>
<el-input v-model="role.name" style="width: 240px" placeholder="请输入角色名称" clearable />
<el-text size="large">{{ t('common.roleName') }}</el-text>
<el-input v-model="role.name" style="width: 240px" :placeholder="t('common.roleNamePlaceholder')" clearable />
<div style="margin-left: auto;">
<el-button type="primary" @click="searchRole()" :disabled="!canLook" v-if="canLook">查询</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="searchRole()" :disabled="!canLook" v-if="canLook">{{ t('common.search') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-card>
@ -654,13 +656,13 @@ onMounted(async function () {
<el-card class="card2">
<div class="add-item">
<el-button style="color: #048efb; border: 1px solid #048efb" @click="permissionAddInit()" :disabled="!canAdd"
v-if="canAdd">新增角色
v-if="canAdd">{{ t('common.addRole') }}
</el-button>
</div>
<div>
<el-table :data="roleData" style="width: 82vw;height:71.3vh" show-overflow-tooltip
:row-style="{ height: '56px' }">
<el-table-column type="index" label="序号" width="100px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getRoleObj.pageNum - 1) * getRoleObj.pageSize
@ -668,24 +670,24 @@ onMounted(async function () {
</template>
</el-table-column>
<el-table-column prop="roleName" label="角色名称" />
<el-table-column prop="fatherName" label="上级角色">
<el-table-column prop="roleName" :label="t('common_list.roleName')" />
<el-table-column prop="fatherName" :label="t('common_list.parentRole')">
<template #default="scope">
{{ scope.row.fatherName || '-' }}
</template>
</el-table-column>
<el-table-column label="权限范围" show-overflow-tooltip>
<el-table-column :label="t('common_list.permissionScope')" show-overflow-tooltip>
<template #default="scope">
<div class="permission-cell" @click="showMenuTree(scope.row.tree, scope.row.roleName)">
{{ formatPermissions(scope.row.tree) }}
</div>
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" width="200px">
<el-table-column prop="operation" :label="t('common_list.operation')" width="200px">
<template #default="scope">
<el-button type="warning" text @click="permissionEditRoleInit(scope.row)"
:disabled="(scope.row.id === 2) || (scope.row.id === 1) || !canEdit" v-if="canEdit">
编辑
{{ t('common.edit') }}
</el-button>
</template>
</el-table-column>
@ -701,37 +703,37 @@ onMounted(async function () {
</div>
<!-- 角色菜单树展示 -->
<el-dialog v-model="menuTreeVisible" :title='`权限详情:${currentRoleName}`' width="600px">
<el-dialog v-model="menuTreeVisible" :title="`${t('common_add.permissionDetails')}:${currentRoleName}`" width="600px">
<el-tree :data="currentRoleMenuTree" node-key="id" :props="{ label: 'menuName', children: 'children' }"
show-checkbox check-strictly :expand-on-click-node="false"
:default-expanded-keys="currentRoleMenuTree.map(item => item.id)" :default-checked-keys="Rolecheckedkeys" />
<template #footer>
<el-button @click="menuTreeVisible = false" type="primary">关闭</el-button>
<el-button @click="menuTreeVisible = false" type="primary">{{ t('common.close') }}</el-button>
</template>
</el-dialog>
<!-- 新增角色 -->
<el-dialog v-model="permissionAddVisible" title="新增角色" width="800px" :close-on-click-modal="false"
<el-dialog v-model="permissionAddVisible" :title="t('common_add.addRole')" width="800px" :close-on-click-modal="false"
@close="handleDialogClose">
<template #footer>
<el-form ref="Ref" :rules="Rolerules" :model="addRole" label-width="auto"
style="max-width: 600px; align-items: center">
<el-form-item prop="roleName" label="角色名称:" required>
<el-input v-model="addRole.roleName" placeholder="请输入角色名称" style="width: 220px" />
<el-form-item prop="roleName" :label="t('common_add.roleName') + ':'" required>
<el-input v-model="addRole.roleName" :placeholder="t('common_add.roleNamePlaceholder')" style="width: 220px" />
</el-form-item>
<el-form-item prop="parentName" label="上级角色:">
<el-select v-model="addRole.parentId" placeholder="请选择上级角色" style="width: 220px" @change="getLists" clearable>
<el-form-item prop="parentName" :label="t('common_add.parentRole') + ':'">
<el-select v-model="addRole.parentId" :placeholder="t('common_add.parentRole')" style="width: 220px" @change="getLists" clearable>
<el-option v-for="item in permissionList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="market" label="归属地区:" required>
<el-select v-model="addRole.market" placeholder="请选择归属地区" style="width: 220px" clearable>
<el-form-item prop="market" :label="t('common.market') + ':'" required>
<el-select v-model="addRole.market" :placeholder="t('common.marketPlaceholder')" style="width: 220px" clearable>
<el-option v-for="item in addRoleMarket" :key="item" :label="item" :value="item" />
</el-select>
<text>(此地区无实际意义仅用于各分部负责人查看其地区角色)</text>
<text>{{ t('permission.roleRegionNote') || '' }}</text>
</el-form-item>
<el-form-item prop="checkedKeys" label="权限列表:" required>
<el-form-item prop="checkedKeys" :label="t('common_add.permissionList') + ':'" required>
<el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id"
:props="{ label: 'menuName', children: 'children' }" :checked-keys="addRole.checkedKeys"
:check-strictly="false" @check="handleCheckChange">
@ -740,44 +742,44 @@ onMounted(async function () {
</template>
</el-tree>
<div v-else style="display: flex; align-items: center; gap: 8px;">
<span style="color: #999;">暂无数据</span>
<span style="color: #999;">{{ t('common.noData') }}</span>
</div>
</el-form-item>
<el-form-item v-show="ifHasChannel" label="频道名称:" required>
<el-select v-model="addRole.channel" placeholder="请选择频道" style="width: 220px" filterable clearable>
<el-form-item v-show="ifHasChannel" :label="t('common_add.channelName') + ':'" required>
<el-select v-model="addRole.channel" :placeholder="t('common_add.channelPlaceholder')" style="width: 220px" filterable clearable>
<el-option v-for="item in channelList" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-form>
<div>
<el-button @click="closePermissionAddVisible()">取消</el-button>
<el-button @click="closePermissionAddVisible()">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="throttledHandleAddRole">
提交
{{ t('common.submit') }}
</el-button>
</div>
</template>
</el-dialog>
<!-- 編輯角色彈窗 -->
<el-dialog v-model="permissionEditRoleVisible" title="编辑角色" width="800px" :close-on-click-modal="false">
<el-dialog v-model="permissionEditRoleVisible" :title="t('common_add.editRole')" width="800px" :close-on-click-modal="false">
<template #footer>
<el-form ref="Ref" :rules="Rolerules" :model="permissionEditRoleObj" label-width="auto"
style="max-width: 600px; align-items: center">
<el-form-item prop="roleName" label="角色名称:" required>
<el-input v-model="permissionEditRoleObj.roleName" placeholder="请输入角色名称" style="width: 220px" />
<el-form-item prop="roleName" :label="t('common_add.roleName') + ':'" required>
<el-input v-model="permissionEditRoleObj.roleName" :placeholder="t('common_add.roleNamePlaceholder')" style="width: 220px" />
</el-form-item>
<el-form-item prop="parentName" label="上级角色:">
<el-input v-model="permissionEditRoleObj.parentName" placeholder="无上级角色" disabled style="width: 220px">
<el-form-item prop="parentName" :label="t('common_add.parentRole') + ':'">
<el-input v-model="permissionEditRoleObj.parentName" :placeholder="t('common_add.noParentRole')" disabled style="width: 220px">
<el-option v-for="item in permissionList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-input>
</el-form-item>
<el-form-item prop="market" label="归属地区" required>
<el-input v-model="permissionEditRoleObj.market" placeholder="请输入归属地区" style="width: 220px" disabled />
<text>(此地区无实际意义仅用于各分部负责人查看其地区角色)</text>
<el-form-item prop="market" :label="t('common.market')" required>
<el-input v-model="permissionEditRoleObj.market" :placeholder="t('common.marketPlaceholder')" style="width: 220px" disabled />
<text>{{ t('permission.roleRegionNote') || '' }}</text>
</el-form-item>
<el-form-item prop="checkedKeys" label="权限列表:" required>
<el-form-item prop="checkedKeys" :label="t('common_add.permissionList') + ':'" required>
<el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" ref="treeRef"
:props="{ label: 'menuName', children: 'children' }"
:default-checked-keys="permissionEditRoleObj.checkedKeys" :check-strictly="false"
@ -788,21 +790,21 @@ onMounted(async function () {
</template>
</el-tree>
<div v-else style="display: flex; align-items: center; gap: 8px;">
<span style="color: #999;">暂无数据</span>
<span style="color: #999;">{{ t('common.noData') }}</span>
</div>
</el-form-item>
<el-form-item v-show="ifHasChannel" label="频道名称:" required>
<el-select v-model="permissionEditRoleObj.channel" placeholder="请选择频道" style="width: 220px" clearable>
<el-form-item v-show="ifHasChannel" :label="t('common_add.channelName') + ':'" required>
<el-select v-model="permissionEditRoleObj.channel" :placeholder="t('common_add.channelPlaceholder')" style="width: 220px" clearable>
<el-option v-for="item in channelList" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-form>
<div>
<el-button @click="permissionEditRoleVisible = false">取消</el-button>
<el-button @click="permissionEditRoleVisible = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="permissionEditRole">
提交
{{ t('common.submit') }}
</el-button>
</div>
</template>
@ -855,4 +857,4 @@ onMounted(async function () {
color: #409eff;
/* 蓝色文字,提示可点击 */
}
</style>
</style>

275
src/views/permissions/userPermission.vue

@ -8,9 +8,11 @@ import API from '@/util/http'
import { useAdminStore } from "@/store/index.js"
import { storeToRefs } from "pinia"
import { findMenuById, permissionMapping } from "@/utils/menuTreePermission.js"
import { useI18n } from 'vue-i18n'
import BackGroundSvg from '@/assets/SvgIcons/promptBackground.svg'
const { t } = useI18n()
const adminStore = useAdminStore()
const { adminData, menuTree } = storeToRefs(adminStore)
@ -50,34 +52,34 @@ const showStatusConfirm = (row, targetStatus) => {
//
const addUserRules = {
account: [
{ required: true, message: '请输入OA号', trigger: 'blur' },
{ pattern: /^\d+$/, message: 'OA号必须为数字', trigger: 'blur' },
{ max: 20, message: '长度不能超过20位', trigger: 'blur' }
{ required: true, message: t('elmessage.inputAccount'), trigger: 'blur' },
{ pattern: /^\d+$/, message: t('elmessage.onlyDigits'), trigger: 'blur' },
{ max: 20, message: t('elmessage.lengthLimit20'), trigger: 'blur' }
],
name: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ max: 20, message: '长度不能超过20位', trigger: 'blur' }
{ required: true, message: t('elmessage.inputUserName'), trigger: 'blur' },
{ max: 20, message: t('elmessage.lengthLimit20'), trigger: 'blur' }
],
market: [
{ required: true, message: '请选择所属地区', trigger: 'change' }
{ required: true, message: t('elmessage.selectMarket'), trigger: 'change' }
],
permission: [
{ required: true, message: '请选择角色名称', trigger: 'change' }
{ required: true, message: t('elmessage.selectRoleName'), trigger: 'change' }
],
postiton: [
{ required: true, message: '请输入职位', trigger: 'blur' },
{ max: 20, message: '长度不能超过20位', trigger: 'blur' }
{ required: true, message: t('elmessage.inputPosition'), trigger: 'blur' },
{ max: 20, message: t('elmessage.lengthLimit20'), trigger: 'blur' }
],
machineIds: [
{
required: true,
message: '请至少输入一个机器码',
message: t('elmessage.inputAtLeastOneMachineCode'),
trigger: 'change',
validator: (rule, value, callback) => {
//
const hasValid = value.some(item => item.trim() !== '');
if (!hasValid) {
callback(new Error('请至少输入一个机器码'));
callback(new Error(t('elmessage.inputAtLeastOneMachineCode')));
} else {
callback();
}
@ -117,14 +119,14 @@ const permissionEditObj = ref({
})
const addMachineIdInput = function () {
if (addAdmin.value.machineIds.length >= 2) {
ElMessage.warning('设备数量已达上限')
ElMessage.warning(t('elmessage.deviceLimitReached'))
return
}
addAdmin.value.machineIds.push('')
}
const UseraddMachineIdInput = function () {
if (permissionEditObj.value.machineIds.length >= 2) {
ElMessage.warning('设备数量已达上限')
ElMessage.warning(t('elmessage.deviceLimitReached'))
return
}
permissionEditObj.value.machineIds.push('')
@ -149,7 +151,7 @@ const getPermission = async function (val) {
//
if (!numberRegex.test(admin.value.account)) {
ElMessage.error('请检查OA号格式')
ElMessage.error(t('elmessage.checkAccountFormat'))
//
return
}
@ -272,7 +274,7 @@ const userAddInit = function () {
//
const permissionAdd = async function () {
if (!canLook) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermissionText'))
return
}
try {
@ -281,7 +283,7 @@ const permissionAdd = async function () {
if (valid) {
resolve(); //
} else {
reject(new Error('请检查并完善表单信息')); //
reject(new Error(t('elmessage.checkFormInfo'))); //
}
});
});
@ -307,7 +309,7 @@ const permissionAdd = async function () {
console.log(addAdmin.value)
if (result.code === 200) {
ElMessage.success('添加成功')
ElMessage.success(t('elmessage.addSuccess'))
} else {
ElMessage.error(result.msg)
}
@ -319,7 +321,7 @@ const permissionAdd = async function () {
} catch (error) {
console.log('新增用户权限失败', error)
ElMessage.error('新增用户权限失败')
ElMessage.error(t('elmessage.addUserPermissionFailed'))
}
}
// ref
@ -441,19 +443,19 @@ const getUserLists = async function (selectedRoleId) {
permissionEditObj.value.parentName = '';
permissionEditObj.value.checkedKeys = [];
parentRoleTip.value = '';
const parentRes = await request({
url: '/role/selectFather',
data: { id: selectedRoleId } // ID
});
const parentId = parentRes.data.fatherId;
const parentName = parentRes.data.parentName;
permissionEditObj.value.parentId = parentId;
permissionEditObj.value.parentName = parentName;
if (parentId == null) {
//
parentRoleTip.value = '该角色无上级角色';
}
const parentRes = await request({
url: '/role/selectFather',
data: { id: selectedRoleId } // ID
});
const parentId = parentRes.data.fatherId;
const parentName = parentRes.data.parentName;
permissionEditObj.value.parentId = parentId;
permissionEditObj.value.parentName = parentName;
if (parentId == null) {
//
parentRoleTip.value = t('common_add.noParentRole');
}
let roleId = permissionEditObj.value.roleId
// if (permissionEditObj.value.parentId === null || permissionEditObj.value.parentId === undefined) {
@ -476,22 +478,22 @@ const getUserLists = async function (selectedRoleId) {
//
const editAdminRules = {
market: [
{ required: true, message: '请选择所属地区', trigger: 'change' }
{ required: true, message: t('elmessage.selectMarket'), trigger: 'change' }
],
postiton: [
{ required: true, message: '请输入职位', trigger: ['blur', 'change'] },
{ max: 20, message: '长度不能超过20位', trigger: ['blur', 'change'] }
{ required: true, message: t('elmessage.inputPosition'), trigger: ['blur', 'change'] },
{ max: 20, message: t('elmessage.lengthLimit20'), trigger: ['blur', 'change'] }
],
machineIds: [
{
required: true,
message: '请至少输入一个机器码',
message: t('elmessage.inputAtLeastOneMachineCode'),
trigger: 'change',
validator: (rule, value, callback) => {
//
const hasValid = value.some(item => item.trim() !== '');
if (!hasValid) {
callback(new Error('请至少输入一个机器码'));
callback(new Error(t('elmessage.inputAtLeastOneMachineCode')));
} else {
callback();
}
@ -502,33 +504,34 @@ const editAdminRules = {
//
const permissionEdit = async function () {
if (!canEdit) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermissionText'))
return
}
let { adminName: userName, roleName: oldRole, roleId: newRoleId } = permissionEditObj.value;
if (oldRole == null) {
oldRole = '暂未分配角色'
oldRole = t('elmessage.noRoleAssigned')
}
const newRole = permissionList.value.find(item => item.value === newRoleId)?.label || '未知角色';
const newRole = permissionList.value.find(item => item.value === newRoleId)?.label || t('elmessage.unknownRole');
const confirmContent = `${t('permission.changeRoleConfirmContent1')}${userName}${t('permission.changeRoleConfirmContent2')}${oldRole}${t('permission.changeRoleConfirmContent3')}${newRole}${t('permission.changeRoleConfirmContent4')}`
try {
await new Promise((resolve, reject) => {
Ref.value.validate((valid) => {
if (valid) {
resolve(); //
} else {
reject(new Error('请检查并完善表单信息')); //
reject(new Error(t('elmessage.checkFormInfo'))); //
}
});
});
await ElMessageBox.confirm(
`确认修改权限角色?<br>您正在将【${userName}】的权限角色从【${oldRole}】修改为【${newRole}】<br>变更后,该用户的可操作权限将同步更新为新角色配置,涉及数据访问、功能操作等权限变化,请谨慎确认。`,
'警告',
confirmContent,
t('permission.warning'),
{
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
type: "warning",
lockScroll: false,
dangerouslyUseHTMLString: true // HTML
dangerouslyUseHTMLString: true
}
)
const result = await request({
@ -548,11 +551,11 @@ const permissionEdit = async function () {
console.log('编辑最后提交数据', permissionEditObj.value);
if (result.code === 200) {
await ElMessageBox.alert(
`用户${userName}的权限角色已更改为【${newRole}`,
'成功',
`${t('permission.changeRoleSuccessContent1')}${userName}${t('permission.changeRoleSuccessContent2')}${newRole}`,
t('elmessage.success'),
{
confirmButtonText: '确定',
type: 'success' // success
confirmButtonText: t('common.confirm'),
type: 'success'
}
);
getPermission();
@ -563,7 +566,7 @@ const permissionEdit = async function () {
} catch (error) {
console.log('编辑用户权限失败', error)
ElMessage.error('编辑用户权限失败')
ElMessage.error(t('elmessage.editFailed') || t('elmessage.operationFailed'))
}
}
@ -578,7 +581,7 @@ const del = function (row) {
//
const delConfirm = async function () {
if (!canDel) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermissionText'))
return
}
try {
@ -589,18 +592,18 @@ const delConfirm = async function () {
console.log('看看删除对象', delObj.value)
console.log('请求成功1', result)
ElMessage.success('删除权限成功')
ElMessage.success(t('elmessage.deleteSuccess'))
delObj.value = {}
getPermission()
} catch (error) {
console.log('删除权限失败', error)
ElMessage.error('删除权限失败')
ElMessage.error(t('elmessage.operationFailed'))
}
}
//
const editStatus = async function (row) {
if (!change) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermissionText'))
return
}
const { id, account, targetStatus, ...restRow } = currentStatusRow.value
@ -622,7 +625,7 @@ const editStatus = async function (row) {
console.log('请求成功2', result)
if (result.code === 200) {
ElMessage.success(
permissionEditObj.value.adminStatus === 1 ? '启用成功' : '禁用成功'
permissionEditObj.value.adminStatus === 1 ? t('elmessage.enableSuccess') : t('elmessage.disableSuccess')
)
statusLoading.value[id] = false
}
@ -681,11 +684,11 @@ const handleMarketChangeAddUser = (value) => {
.filter(Boolean);
//
const hasHeadquarters = selectedMarkets.includes('总部');
const hasHeadquarters = selectedMarkets.includes(t('common.markets.headquarters'));
if (hasHeadquarters) {
//
addAdmin.value.market = ['总部'];
addAdmin.value.market = [t('common.markets.headquarters')];
} else {
//
addAdmin.value.market = selectedMarkets;
@ -705,11 +708,11 @@ const handleMarketChangeEditUser = (value) => {
.filter(Boolean);
//
const hasHeadquarters = selectedMarkets.includes('总部');
const hasHeadquarters = selectedMarkets.includes(t('common.markets.headquarters'));
if (hasHeadquarters) {
//
permissionEditObj.value.market = ['总部'];
permissionEditObj.value.market = [t('common.markets.headquarters')];
} else {
//
permissionEditObj.value.market = selectedMarkets;
@ -793,7 +796,7 @@ const resetPassword = function (row) {
//
const confirmResetPassword = async function () {
if (!canEdit) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return
}
console.log('adminData', adminData.value)
@ -810,9 +813,9 @@ const confirmResetPassword = async function () {
//
if (adminData.value.markets.includes(currentRow.value.market) || adminData.value.markets[0] === '总部' || adminData.value.markets[0] === '研发部' || adminData.value.markets[0] === 'headquarters' || adminData.value.markets[0] === 'R&D Department') {
if (adminData.value.markets.includes(currentRow.value.market) || adminData.value.markets[0] === '总部' || adminData.value.markets[0] === '研发部' || adminData.value.markets[0] === 'Headquarters' || adminData.value.markets[0] === 'R&D Department') {
console.log('符合条件,可以操作', adminData.value.markets.includes(currentRow.value.market) || adminData.value.markets[0] === '总部' || adminData.value.markets[0] === '研发部' || adminData.value.markets[0] === 'headquarters' || adminData.value.markets[0] === 'R&D Department');
console.log('符合条件,可以操作', adminData.value.markets.includes(currentRow.value.market) || adminData.value.markets[0] === '总部' || adminData.value.markets[0] === '研发部' || adminData.value.markets[0] === 'Headquarters' || adminData.value.markets[0] === 'R&D Department');
const params = {
account: currentRow.value.account,
}
@ -827,20 +830,20 @@ const confirmResetPassword = async function () {
});
if (result.code === 200) { // 使
ElMessage.success('重置密码成功');
ElMessage.success(t('elmessage.resetPasswordSuccess'));
resetConfirmVisible.value = false; //
await getPermission()
} else {
ElMessage.error(result.message || '重置密码失败');
ElMessage.error(result.message || t('elmessage.resetPasswordFailed'));
}
} catch (error) {
ElMessage.error('重置密码失败');
ElMessage.error(t('elmessage.resetPasswordFailed'));
console.error('请求错误:', error);
}
} else {
// console.log("",adminData.value.markets)
ElMessage.error('您没有修改' + currentRow.value.market + '地区的用户密码的权限');
ElMessage.error(t('elmessage.noPermissionResetMarket1') + currentRow.value.market + t('elmessage.noPermissionResetMarket2'));
resetConfirmVisible.value = false; //
}
@ -918,25 +921,25 @@ onMounted(async function () {
<el-card class="card1" style="margin-bottom: 1vh;">
<div class="head-card">
<div class="head-card-element">
<el-text class="mx-1" size="large">OA号</el-text>
<el-input v-model="admin.account" style="width: 240px" placeholder="请输入OA号" clearable />
<el-text class="mx-1" size="large">{{ t('common.account') }}</el-text>
<el-input v-model="admin.account" style="width: 240px" :placeholder="t('common.accountPlaceholder')" clearable />
</div>
<div class="head-card-element" style="margin-left: 50px">
<el-text class="mx-1" size="large">所属地区</el-text>
<el-cascader v-model="admin.market" :options="marketsTree" placeholder="请选择所属地区" clearable style="width:180px"
<el-text class="mx-1" size="large">{{ t('common.market') }}</el-text>
<el-cascader v-model="admin.market" :options="marketsTree" :placeholder="t('common.marketPlaceholder')" clearable style="width:180px"
@change="handleMarketChange" />
</div>
<div class="head-card-element" style="margin-left: 50px">
<el-text class="mx-1" size="large">职位名称</el-text>
<el-select v-model="admin.postiton" placeholder="请选择职位名称" style="width: 240px" clearable>
<el-text class="mx-1" size="large">{{ t('common.position') }}</el-text>
<el-select v-model="admin.postiton" :placeholder="t('common.positionPlaceholder')" style="width: 240px" clearable>
<el-option v-for="item in postiton" :key="item" :label="item" :value="item" />
</el-select>
</div>
<div class="head-card-btn">
<el-button type="primary" @click="search()" v-if="canLook">查询</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()" v-if="canLook">{{ t('common.search') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-card>
@ -944,14 +947,14 @@ onMounted(async function () {
<!-- 展示表单 -->
<div class="add-item">
<el-button style="color: #048efb; border: 1px solid #048efb" :disabled="!canAdd" v-if="canAdd"
@click="userAddInit()">新增用户
@click="userAddInit()">{{ t('common.addUser') }}
</el-button>
</div>
<div>
<el-table :data="tableData" style="width: 82vw;height:71.3vh" show-overflow-tooltip
>
<el-table-column type="index" label="序号" width="100px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -959,39 +962,39 @@ onMounted(async function () {
</template>
</el-table-column>
<el-table-column prop="account" label="OA号" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="market" label="所属地区" />
<el-table-column prop="postiton" label="职位" />
<el-table-column prop="roleName" label="部门权限">
<el-table-column prop="account" :label="t('common_list.account')" />
<el-table-column prop="name" :label="t('common_list.name')" />
<el-table-column prop="market" :label="t('common_list.market')" />
<el-table-column prop="postiton" :label="t('common_list.position')" />
<el-table-column prop="roleName" :label="t('common_list.departmentPermission')">
</el-table-column>
<el-table-column prop="remark" label="备注" />
<el-table-column prop="operation" label="操作" width="280px">
<el-table-column prop="remark" :label="t('common_list.remark')" />
<el-table-column prop="operation" :label="t('common_list.operation')" align="center" width="380px">
<template #default="scope">
<el-button type="warning" text :disabled="!canReset" @click="resetPassword(scope.row)" v-if="canReset">
重置密码
{{ t('common.resetPassword') }}
</el-button>
<el-button type="primary" text @click="permissionEditInit(scope.row)" v-if="canEdit"
:disabled="!canEdit || scope.row.adminStatus === 0 || scope.row.account === adminData.account">
修改权限
{{ t('common.editPermission') }}
</el-button>
<el-popconfirm title="确定将此用户删除吗?" @confirm="delConfirm">
<el-popconfirm :title="t('elmessage.confirmDeleteUser')" @confirm="delConfirm">
<template #reference>
<el-button type="danger" text @click="del(scope.row)" v-if="canDel"
:disabled="!canDel || scope.row.adminStatus === 0 || scope.row.account === adminData.account">
删除
{{ t('common.delete') }}
</el-button>
</template>
<template #actions="{ confirm, cancel }">
<el-button size="small" @click="cancel">取消</el-button>
<el-button size="small" @click="cancel">{{ t('common.cancel') }}</el-button>
<el-button type="primary" size="small" @click="confirm">
确定
{{ t('common.confirm') }}
</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
<el-table-column prop="adminStatus" label="状态">
<el-table-column prop="adminStatus" :label="t('common_list.status')">
<template #default="scope">
<el-switch :model-value="scope.row.adminStatus" :active-value="1" :inactive-value="0" size="large"
v-if="change"
@ -999,7 +1002,7 @@ onMounted(async function () {
@change="(targetStatus) => showStatusConfirm(scope.row, targetStatus)" style="
--el-switch-on-color: #13ce66;
--el-switch-off-color: #ff4949;
" active-text="启用" inactive-text="禁用" inline-prompt />
" :active-text="t('common_list.enable')" :inactive-text="t('common_list.disable')" inline-prompt />
</template>
</el-table-column>
</el-table>
@ -1013,106 +1016,106 @@ onMounted(async function () {
</div>
<!-- 新增用户权限 -->
<el-dialog v-model="userAddVisible" title="新增用户权限" width="800px" :close-on-click-modal="false"
<el-dialog v-model="userAddVisible" :title="t('common_add.addUserPermission')" width="800px" :close-on-click-modal="false"
@close="handleDialogClose">
<template #footer>
<el-form ref="Ref" :rules="addUserRules" :model="addAdmin" label-width="auto"
style="max-width: 600px; align-items: center">
<el-form-item prop="account" label="OA号:" required clearable>
<el-input v-model="addAdmin.account" placeholder="请输入OA号" style="width: 220px" />
<el-form-item prop="account" :label="t('common_add.account') + ':'" required clearable>
<el-input v-model="addAdmin.account" :placeholder="t('common_add.accountPlaceholder')" style="width: 220px" />
</el-form-item>
<el-form-item prop="name" label="用户名:" required clearable>
<el-input v-model="addAdmin.name" placeholder="请输入用户名" style="width: 220px" />
<el-form-item prop="name" :label="t('common_add.userName') + ':'" required clearable>
<el-input v-model="addAdmin.name" :placeholder="t('common_add.userNamePlaceholder')" style="width: 220px" />
</el-form-item>
<el-form-item prop="market" label="所属地区:" required clearable>
<el-cascader v-model="addAdmin.market" :options="marketsTree" placeholder="请选择所属地区" clearable collapse-tags
<el-form-item prop="market" :label="t('common.market') + ':'" required clearable>
<el-cascader v-model="addAdmin.market" :options="marketsTree" :placeholder="t('common.marketPlaceholder')" clearable collapse-tags
collapse-tags-tooltip style="width:220px" @change="handleMarketChangeAddUser" :max-collapse-tags="2"
:props="addUserProps" />
</el-form-item>
<el-form-item prop="permission" label="角色名称:" required>
<el-select v-model="addAdmin.permission" placeholder="请选择角色名称" style="width: 220px" clearable>
<el-form-item prop="permission" :label="t('common_add.roleName') + ':'" required>
<el-select v-model="addAdmin.permission" :placeholder="t('common_add.roleNamePlaceholder')" style="width: 220px" clearable>
<el-option v-for="item in permissionList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="postiton" label="职位:" required>
<el-input v-model="addAdmin.postiton" placeholder="请输入职位" style="width: 220px" clearable />
<el-form-item prop="postiton" :label="t('common.position') + ':'" required>
<el-input v-model="addAdmin.postiton" :placeholder="t('common.positionPlaceholder')" style="width: 220px" clearable />
</el-form-item>
<el-form-item prop="machineIds" label="机器码:" required>
<el-form-item prop="machineIds" :label="t('common_add.machineCode') + ':'" required>
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px;">
<!-- 动态添加的机器码输入框 -->
<div v-for="(item, index) in addAdmin.machineIds" :key="index">
<el-input v-model="addAdmin.machineIds[index]" placeholder="请输入机器码"
<el-input v-model="addAdmin.machineIds[index]" :placeholder="t('common_add.machineCodePlaceholder')"
style="width: 220px; margin-right: 10px;" />
</div>
<el-button type="primary" @click="addMachineIdInput">添加</el-button>
<el-button type="primary" @click="addMachineIdInput">{{ t('common.add') }}</el-button>
</div>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-form-item prop="remark" :label="t('common_add.remark')">
<el-input v-model="addAdmin.remark" style="width: 300px" :rows="2" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
</el-form>
<div>
<el-button @click="closeUserAddVisible()">取消</el-button>
<el-button @click="closeUserAddVisible()">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="throttledPermissionAdd()">
提交
{{ t('common.submit') }}
</el-button>
</div>
</template>
</el-dialog>
<!-- 这是编辑用户权限弹窗 -->
<el-dialog v-model="userEditVisible" title="编辑用户权限" width="800px" :close-on-click-modal="false">
<el-dialog v-model="userEditVisible" :title="t('common_add.editUserPermission')" width="800px" :close-on-click-modal="false">
<el-form ref="Ref" :rules="editAdminRules" :model="permissionEditObj" label-width="auto"
style="max-width: 600px; align-items: center">
<el-form-item prop="account" label="用户账号:" clearable>
<el-input v-model="permissionEditObj.account" placeholder="请输入OA号" style="width: 220px" disabled />
<el-form-item prop="account" :label="t('common.account') + ':'" clearable>
<el-input v-model="permissionEditObj.account" :placeholder="t('common.accountPlaceholder')" style="width: 220px" disabled />
</el-form-item>
<el-form-item prop="name" label="用户名称:">
<el-input v-model="permissionEditObj.adminName" placeholder="请输入用户名" style="width: 220px" disabled />
<el-form-item prop="name" :label="t('common_add.userName') + ':'">
<el-input v-model="permissionEditObj.adminName" :placeholder="t('common_add.userNamePlaceholder')" style="width: 220px" disabled />
</el-form-item>
<el-form-item prop="market" label="所属地区:" clearable>
<el-cascader v-model="permissionEditObj.market" :options="marketsTree" placeholder="请选择所属地区" clearable
<el-form-item prop="market" :label="t('common.market') + ':'" clearable>
<el-cascader v-model="permissionEditObj.market" :options="marketsTree" :placeholder="t('common.marketPlaceholder')" clearable
collapse-tags collapse-tags-tooltip style="width:220px" @change="handleMarketChangeEditUser"
:max-collapse-tags="2" :props="editUserProps" />
</el-form-item>
<el-form-item prop="postiton" label="职位:">
<el-input v-model="permissionEditObj.postiton" placeholder="请输入职位" style="width: 220px" clearable />
<el-form-item prop="postiton" :label="t('common.position') + ':'">
<el-input v-model="permissionEditObj.postiton" :placeholder="t('common.positionPlaceholder')" style="width: 220px" clearable />
</el-form-item>
<el-form-item prop="roleName" label="角色名称:">
<el-select v-model="permissionEditObj.roleId" placeholder="请选择角色" style="width: 220px" @change="getUserLists">
<el-form-item prop="roleName" :label="t('common_add.roleName') + ':'">
<el-select v-model="permissionEditObj.roleId" :placeholder="t('common_add.roleNamePlaceholder')" style="width: 220px" @change="getUserLists">
<el-option v-for="item in permissionList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="parentName" label="上级角色:">
<el-select v-model="permissionEditObj.parentId" placeholder="无上级角色" :disabled="!!parentRoleTip"
<el-form-item prop="parentName" :label="t('common_add.parentRole') + ':'">
<el-select v-model="permissionEditObj.parentId" :placeholder="t('common_add.noParentRole')" :disabled="!!parentRoleTip"
style="width: 220px">
<el-option v-if="parentRoleTip" :key="0" :label="parentRoleTip" :value="null" disabled />
<el-option v-else v-for="item in permissionList" :key="item.value" :label="item.label" disabled
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="permissionSelect" label="权限列表:">
<el-form-item prop="permissionSelect" :label="t('common_add.permissionList') + ':'">
<el-tree v-if="data.length > 0" :data="data" :disabled="true" show-checkbox node-key="id"
:props="{ label: 'menuName', children: 'children' }" :default-checked-keys="permissionEditObj.checkedKeys">
</el-tree>
<div v-else style="display: flex; align-items: center; gap: 8px;">
<span style="color: #999;">暂无数据</span>
<span style="color: #999;">{{ t('common.noData') }}</span>
</div>
</el-form-item>
<el-form-item prop="machineIds" label="机器码:">
<el-form-item prop="machineIds" :label="t('common_add.machineCode') + ':'">
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px;">
<!-- 动态添加的机器码输入框 -->
<div v-for="(item, index) in permissionEditObj.machineIds" :key="index">
<el-input v-model="permissionEditObj.machineIds[index]" placeholder=""
style="width: 220px; margin-right: 10px;" />
</div>
<el-button type="primary" @click="UseraddMachineIdInput">添加</el-button>
<el-button type="primary" @click="UseraddMachineIdInput">{{ t('common.add') }}</el-button>
</div>
</el-form-item>
</el-form>
@ -1120,9 +1123,9 @@ onMounted(async function () {
</div>
<template #footer>
<div>
<el-button @click="closeUserEditVisible()">取消</el-button>
<el-button @click="closeUserEditVisible()">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="throttledPermissionEdit">
提交
{{ t('common.submit') }}
</el-button>
</div>
</template>
@ -1138,15 +1141,15 @@ onMounted(async function () {
</el-icon>
</el-col>
<el-col :span="20">
<h3>提示</h3>
<p class="dialog-title">确认重置该账号密码</p>
<p class="dialog-desc">重置后密码为: 123456请通知用户及时修改</p>
<h3>{{ t('elmessage.prompt') }}</h3>
<p class="dialog-title">{{ t('elmessage.resetPasswordConfirm') }}</p>
<p class="dialog-desc">{{ t('elmessage.resetPasswordDefault') }}</p>
</el-col>
</el-row>
<template #footer>
<div style="display: flex; justify-content: center; gap: 30px">
<el-button @click="cancelResetPassword">取消</el-button>
<el-button type="primary" @click="confirmResetPassword">确定</el-button>
<el-button @click="cancelResetPassword">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="confirmResetPassword">{{ t('common.confirm') }}</el-button>
</div>
</template>
</el-dialog>
@ -1159,7 +1162,7 @@ onMounted(async function () {
}"
@close="() => { if (currentStatusRow) currentStatusRow.adminStatus = currentStatusRow.adminStatus === 1 ? 0 : 1 }">
<div class="status-confirm-content">
将要{{ currentStatusRow?.adminStatus === 1 ? '禁用' : '启用' }}该用户
{{ t('common.will') }}{{ currentStatusRow?.adminStatus === 1 ? t('common_list.disable') : t('common_list.enable') }}{{ t('permission.user') }}
<br>
</div>
<template #footer>
@ -1168,13 +1171,13 @@ onMounted(async function () {
currentStatusRow.adminStatus = currentStatusRow.adminStatus === 1 ? 0 : 1
ackVisible = false
}">
取消
{{ t('common.cancel') }}
</el-button>
<el-button round size="large" type="primary" @click="() => {
editStatus(currentStatusRow)
ackVisible = false
}">
确认
{{ t('common.confirm') }}
</el-button>
</div>
</template>
@ -1241,4 +1244,4 @@ onMounted(async function () {
margin-bottom: 30px;
font-size: 48px;
}
</style>
</style>

77
src/views/recharge/bean/addBeanRecharge.vue

@ -14,12 +14,15 @@ import throttle from 'lodash/throttle'
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
import _ from 'lodash';
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const user = ref({})
const getUser = async function (jwcode) {
if (addForm.value.jwcode) {
addForm.value.jwcode = addForm.value.jwcode.replace(/\s/g, '');
} else {
ElMessage.error('请先输入精网号')
ElMessage.error(t('elmessage.checkJwcode'))
return false
}
try {
@ -32,15 +35,15 @@ const getUser = async function (jwcode) {
if (result.code === 0) {
ElMessage.error(result.msg);
} else if (result.data === null) {
ElMessage.error("用户不存在");
ElMessage.error(t('elmessage.noUser'));
} else {
user.value = result.data;
console.log("用户信息", user.value.name);
ElMessage.success("查询成功");
ElMessage.success(t('elmessage.searchSuccess'));
}
} catch (error) {
console.log("请求失败", error);
ElMessage.error("精网号错误");
ElMessage.error(t('elmessage.jwcodeError'));
}
}
//
@ -58,22 +61,22 @@ const adminStore = useAdminStore()
const { adminData } = storeToRefs(adminStore)
const rules = reactive({
jwcode: [
{ required: true, message: '请输入精网号', trigger: 'blur' },
{ required: true, message: t('elmessage.checkJwcode'), trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('精网号不能为空'));
callback(new Error(t('elmessage.noEmptyJwcode')));
return;
}
if (/[^0-9]/.test(value)) {
callback(new Error('精网号只能包含数字'));
callback(new Error(t('elmessage.limitDigitJwcode')));
return;
}
callback();
}, trigger: 'blur'
}],
permanentBean: [
{ required: true, message: '请输入付费金豆数', trigger: 'change' },
{ required: true, message: t('elmessage.checkPayBean'), trigger: 'change' },
{
validator: (rule, value, callback) => {
if (!value) {
@ -81,13 +84,13 @@ const rules = reactive({
}
//
if (!/^\d+$/.test(value)) {
callback(new Error('请输入非负整数'));
callback(new Error(t('elmessage.checkNonNegative')));
return;
}
//
if (value.length > 6) {
callback(new Error('整数位数不能超过6位'));
callback(new Error(t('elmessage.limitSix')));
return;
}
callback();
@ -97,7 +100,7 @@ const rules = reactive({
}
],
freeBean: [
{ required: true, message: '请输入免费金豆数', trigger: 'change' },
{ required: true, message: t('elmessage.checkFreeBean'), trigger: 'change' },
{
validator: (rule, value, callback) => {
if (!value) {
@ -105,13 +108,13 @@ const rules = reactive({
}
//
if (!/^\d+$/.test(value)) {
callback(new Error('请输入非负整数'));
callback(new Error(t('elmessage.checkNonNegative')));
return;
}
//
if (value.length > 6) {
callback(new Error('整数位数不能超过6位'));
callback(new Error(t('elmessage.limitSix')));
return;
}
callback();
@ -120,7 +123,7 @@ const rules = reactive({
}
],
remark: [
{ required: true, message: '请输入备注', trigger: 'blur' }
{ required: true, message: t('elmessage.checkRemark'), trigger: 'blur' }
]
});
@ -141,22 +144,22 @@ const handleAddForm = async () => {
formRef.value.validate((valid) => {
if (valid) {
if (Number(addForm.value.permanentBean) === 0 && Number(addForm.value.freeBean) === 0) {
reject(new Error('付费金豆和免费金豆不能同时为0'));
reject(new Error(t('elmessage.noPayBeanFreeBeanZero')));
}
resolve(); //
} else {
reject(new Error('请检查并完善表单信息')); //
reject(new Error(t('elmessage.checkFormInfo'))); //
}
});
});
console.log('adminData', adminData.value);
await ElMessageBox.confirm(
'确认充值吗?',
'提示',
t('recharge.confirmRecharge'),
t('recharge.prompt'),
{
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
type: "primary",
lockScroll: false,
}
@ -174,7 +177,7 @@ const handleAddForm = async () => {
})
addDisabled.value = false
if (result.code == 200) {
ElMessage.success('新增成功')
ElMessage.success(t('elmessage.addsuccess'))
deleteAddForm()
user.value = {}
} else {
@ -182,7 +185,7 @@ const handleAddForm = async () => {
}
} catch (error) {
console.log('金豆新增充值失败');
ElMessage.error(error.message || '操作取消');
ElMessage.error(error.message || t('elmessage.cancelOperation'));
}
}
</script>
@ -191,22 +194,22 @@ const handleAddForm = async () => {
<div class="left">
<el-form :model="addForm" :rules="rules" ref="formRef" label-width="auto" style="max-width: 600px"
class="add-form">
<el-form-item prop="jwcode" label="精网号" label-position="left">
<el-form-item prop="jwcode" :label="t('common.jwcode')" label-position="left">
<el-input v-model="addForm.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(addForm.jwcode)" style="margin-left: 20px">查询</el-button>
<el-button type="primary" @click="getUser(addForm.jwcode)" style="margin-left: 20px">{{ t('common.search') }}</el-button>
</el-form-item>
<el-form-item prop="permanentBean" label="付费金豆" label-position="left">
<el-form-item prop="permanentBean" :label="t('recharge.permanentBean')" label-position="left">
<el-input v-model="addForm.permanentBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="freeBean" label="免费金豆" label-position="left">
<el-form-item prop="freeBean" :label="t('recharge.freeBean')" label-position="left">
<el-input v-model="addForm.freeBean" placeholder="0" style="width: 100px" />
</el-form-item>
<el-form-item prop="remark" label="备注" label-position="left">
<el-form-item prop="remark" :label="t('common_add.remark')" label-position="left">
<el-input v-model="addForm.remark" style="width: 300px" :rows="5" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-button @click="deleteAddForm" style="margin-left: 8.5vw;margin-top:1vw" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleAddForm" style="margin-top:1vw"> 提交
<el-button @click="deleteAddForm" style="margin-left: 8.5vw;margin-top:1vw" type="success">{{ t('common.reset') }}</el-button>
<el-button type="primary" :disabled="addDisabled" @click="handleAddForm" style="margin-top:1vw"> {{ t('common.submit') }}
</el-button>
</el-form>
</div>
@ -215,12 +218,12 @@ const handleAddForm = async () => {
<div class="right">
<el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" label-position="left">
<el-text size="large" style="margin-left: 7vw">客户信息</el-text>
<el-text size="large" style="margin-left: 7vw">{{ t('common_add_user.customerInfo') }}</el-text>
<!-- 第一行姓名 + 当前付费金豆 -->
<div style="margin-top: 0.5vw;display:flex;">
<p style="width:6vw;">姓名:</p>
<p style="width:5vw;">{{ t('common_add_user.name') }}:</p>
<p style="color: #2fa1ff;width:6vw;">{{ user.name }}</p>
<p style="width:7vw;">当前付费金豆:</p>
<p style="width:7vw;">{{ t('common_add_user.currentPayableBean') }}:</p>
<p v-if="!isNaN(Number(user.permanentBean))" style="color: #2fa1ff;">{{ Number(user.permanentBean) }}</p>
<!-- 如果不是有效的数字显示默认值 -->
<p v-else></p>
@ -228,17 +231,17 @@ const handleAddForm = async () => {
<!-- 第二行精网号 + 免费金豆 -->
<div style="display:flex">
<p style="width:6vw;">精网号:</p>
<p style="width:5vw;">{{ t('common.jwcode') }}:</p>
<p style="color: #2fa1ff;width:6vw;">{{ user.jwcode }}</p>
<p style="width:7vw;">当前免费金豆:</p>
<p style="width:7vw;">{{ t('common_add_user.currentFreeBean') }}:</p>
<p v-if="user.freeBean !== undefined" style="color: #2fa1ff;">{{ user.freeBean }}</p>
</div>
<!-- 第三行消费次数 + 所属门店 -->
<div style="display:flex">
<p style="width:6vw;">所属门店:</p>
<p style="width:5vw;">{{ t('common_add_user.store') }}:</p>
<p style="color: #2fa1ff;width:6vw;">{{ user.market }}</p>
<p style="width:7vw;">消耗金豆总数:</p>
<p style="width:7vw;">{{ t('common_add_user.consumeTotalBean') }}:</p>
<p style="color: #2fa1ff;" v-if="user.consumeSum != null">{{ user.consumeSum }}</p>
<p style="color: #2fa1ff;" v-else>{{ 0 }}</p>
</div>
@ -273,7 +276,7 @@ const handleAddForm = async () => {
width: 35vw;
height: 28vh;
margin-top: 5vh;
display: flex;
// display: flex;
justify-content: center;
}
}

96
src/views/recharge/bean/beanOnlineRecharge.vue

@ -6,6 +6,8 @@ import { AiFillRead } from 'vue-icons-plus/ai'
import axios from 'axios'
import moment from 'moment'
import API from '@/util/http.js'
import {useI18n} from 'vue-i18n'
const { t } = useI18n()
const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0),
@ -73,7 +75,7 @@ const getArea = async () => {
market.value = result.data
console.log('线上充值地区获取成功', market.value)
} else {
ElMessage.error('线上充值地区获取失败')
ElMessage.error(t('elmessage.onlineRechargeAreaError'))
}
}
//
@ -156,7 +158,7 @@ const search = () => {
if (selectData.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(selectData.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
@ -205,7 +207,7 @@ const platform = [
},
{
value: 2,
label: '手机'
label: t('recharge.mobile')
}
]
//
@ -258,13 +260,13 @@ const exportExcel = async () => {
try {
const res = await API({ url: '/export/exportol', data: params })
if (res.code === 200) {
ElMessage.success('导出成功')
ElMessage.success(t('elmessage.exportSuccess'))
} else {
ElMessage.error(res.message || '导出失败,请稍后重试')
ElMessage.error(res.message || t('elmessage.exportFailed'))
}
} catch (error) {
console.log('请求失败', error)
ElMessage.error('导出失败,请稍后重试')
ElMessage.error(t('elmessage.exportFailed'))
}
}
const exportListVisible = ref(false)
@ -294,7 +296,7 @@ const getExportList = async () => {
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -307,7 +309,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -329,15 +331,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
const format3 = (num) => {
@ -355,22 +357,22 @@ onMounted(async function () {
<el-col style="margin-bottom: 1vh">
<div class="select">
<div class="selectRow">
<el-text class="text" size="large">精网号</el-text>
<el-input class="selectContent" v-model="selectData.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text" size="large">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="selectData.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable />
</div>
<div class="selectRow">
<el-text class="text" size="large">所属地区</el-text>
<el-select class="selectContent" v-model="selectData.market" placeholder="请选择所属地区" clearable>
<el-text class="text" size="large">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="selectData.market" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="item in market" :key="item" :label="item" :value="item" />
</el-select>
</div>
<div class="selectRow" style="width: 15vw;">
<el-text class="text" size="large">订单号</el-text>
<el-input class="selectContent" v-model="selectData.orderNo" placeholder="请输入订单" clearable />
<el-text class="text" size="large">{{ t('common.orderNo') }}</el-text>
<el-input class="selectContent" v-model="selectData.orderNo" :placeholder="t('common.orderNoPlaceholder')" clearable />
</div>
<div class="selectRow" style="width: 15vw;">
<el-text class="text" size="large">充值平台</el-text>
<el-select class="selectContent" v-model="selectData.platform" placeholder="请选择充值平台" clearable>
<el-text class="text" size="large">{{ t('common.rechargePlatform') }}</el-text>
<el-select class="selectContent" v-model="selectData.platform" :placeholder="t('common.rechargePlatformPlaceholder')" clearable>
<el-option v-for="item in platform" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
@ -379,9 +381,9 @@ onMounted(async function () {
<el-col>
<div class="select">
<div class="selectRow" style="width: 36vw;">
<el-text class="text" size="large">充值时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:25vw"
<el-text class="text" size="large">{{ t('common.rechargeTime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="margin-right:1vw;width:25vw"
@change="handleDatePickerChange" :default-time="defaultTime" />
<div v-if="false">
<el-button @click="getToday()" style="margin-left: 10px"
@ -397,43 +399,43 @@ onMounted(async function () {
</div>
</div>
<div class="selectRow" style="justify-content: flex-start;">
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
充值金豆数{{ format3(num) }}&nbsp;&nbsp;&nbsp;&nbsp;合计新币数{{ format3(money) }}
{{ t('common.rechargeGoldBean') }}{{ format3(num) }}&nbsp;&nbsp;&nbsp;&nbsp;{{ t('common.totalRechargeSGD') }}{{ format3(money) }}
</div>
<!-- 设置表格容器的高度和滚动样式 -->
<div>
<el-table :data="tableData" style="width:80vw;" height="65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
</template>
</el-table-column>
<el-table-column fixed="left" prop="name" label="姓名" min-width="120" show-overflow-tooltip />
<el-table-column fixed="left" prop="jwcode" label="精网号" min-width="110px" />
<el-table-column prop="market" label="所属地区" min-width="100px" />
<el-table-column prop="orderNo" header-align="center" align="center" label="订单号" min-width="210px" />
<el-table-column prop="num" label="数量" sortable="custom" min-width="110px" />
<el-table-column prop="money" label="金额" sortable="custom" min-width="150px" />
<el-table-column prop="platform" label="充值平台" min-width="150px" show-overflow-tooltip>
<el-table-column fixed="left" prop="name" :label="t('common_list.name')" min-width="120" show-overflow-tooltip />
<el-table-column fixed="left" prop="jwcode" :label="t('common_list.jwcode')" min-width="110px" />
<el-table-column prop="market" :label="t('common_list.market')" min-width="100px" />
<el-table-column prop="orderNo" header-align="center" align="center" :label="t('common_list.orderNo')" min-width="210px" />
<el-table-column prop="num" :label="t('common_list.number')" sortable="custom" min-width="110px" />
<el-table-column prop="money" :label="t('common_list.money')" sortable="custom" min-width="150px" />
<el-table-column prop="platform" :label="t('common_list.rechargePlatform')" min-width="150px" show-overflow-tooltip>
<template #default=scope>
<span v-if="scope.row.platform == 1">PC</span>
<span v-else-if="scope.row.platform == 2">手机</span>
<span v-else>其他</span>
<span v-else-if="scope.row.platform == 2">{{ t('common_list.mobile') }}</span>
<span v-else>{{ t('common_list.other') }}</span>
</template>
</el-table-column>
<el-table-column prop="rechargeTime" label="充值时间" min-width="200px">
<el-table-column prop="rechargeTime" :label="t('common_list.rechargeTime')" min-width="200px">
<template #default="scope">
{{ moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
@ -449,33 +451,33 @@ onMounted(async function () {
</div>
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80vw" class="custom-height-dialog">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80vw" class="custom-height-dialog">
<el-table :data="exportList" style="width:80vw;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')" />
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>

15
src/views/recharge/bean/beanRecharge.vue

@ -6,24 +6,24 @@
:class="{ 'active-btn': activeTab === 'addBeanRecharge' }"
@click="navigateTo('addBeanRecharge')"
v-if="hasAdd"
style="width: 6.5vw">
新增充值
style="min-width: 6.5vw">
{{ t('recharge.addBeanRecharge') }}
</el-button>
<el-button
class="no-active-btn"
:class="{ 'active-btn': activeTab === 'beanSystemRecharge' }"
@click="navigateTo('beanSystemRecharge')"
v-if="hasSystem"
style="width: 6.5vw;">
系统充值
style="min-width: 6.5vw">
{{ t('recharge.systemRecharge') }}
</el-button>
<el-button
class="no-active-btn"
:class="{ 'active-btn': activeTab === 'beanOnlineRecharge' }"
@click="navigateTo('beanOnlineRecharge')"
v-if="hasOnline"
style="width: 6.5vw;">
线上充值
style="min-width: 6.5vw;">
{{ t('recharge.onlineRecharge') }}
</el-button>
</el-button-group>
</div>
@ -37,6 +37,9 @@ import {useRouter, useRoute} from 'vue-router';
import {storeToRefs} from 'pinia';
import {useAdminStore} from '@/store/index.js';
import {hasMenuPermission, permissionMapping} from "@/utils/menuTreePermission.js";
import {useI18n} from 'vue-i18n';
const { t } = useI18n();
const router = useRouter();
const route = useRoute();

86
src/views/recharge/bean/beanSystemRecharge.vue

@ -10,6 +10,8 @@ import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
const adminStore = useAdminStore();
const { adminData, menuTree,flag } = storeToRefs(adminStore);
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
// flag
watch(flag, (newFlag, oldFlag) => {
@ -87,7 +89,7 @@ const getArea = async () => {
market.value = result.data
console.log('系统充值地区获取成功', market.value)
} else {
ElMessage.error('系统充值地区获取失败')
ElMessage.error(t('elmessage.systemRechargeAreaError'))
}
}
//
@ -169,7 +171,7 @@ const search = () => {
if (selectData.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(selectData.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}
@ -262,13 +264,13 @@ const exportExcel = async () => {
console.log('系统充值导出的参数为:', params);
if (res.code === 200) {
ElMessage.success('导出成功')
ElMessage.success(t('elmessage.exportSuccess'))
} else {
ElMessage.error(res.message || '导出失败,请稍后重试')
ElMessage.error(res.message || t('elmessage.exportFailed'))
}
} catch (error) {
console.log('请求失败', error)
ElMessage.error('导出失败,请稍后重试')
ElMessage.error(t('elmessage.exportFailed'))
}
}
const exportListVisible = ref(false)
@ -294,11 +296,11 @@ const getExportList = async () => {
});
exportList.value = filteredData
} else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
}
} catch (error) {
console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally {
exportListLoading.value = false
}
@ -311,7 +313,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName
link.click()
} else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
}
}
//
@ -333,15 +335,15 @@ const getTagType = (state) => {
const getTagText = (state) => {
switch (state) {
case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1:
return '执行中';
return t('elmessage.executing');
case 2:
return '执行完成';
return t('elmessage.executed');
case 3:
return '执行出错';
return t('elmessage.errorExecution');
default:
return '未知状态';
return t('elmessage.unknownStatus');
}
}
const format3 = (num) => {
@ -359,12 +361,12 @@ onMounted(async function () {
<el-col style="margin-bottom: 1vh">
<div class="select">
<div class="selectRow">
<el-text class="text" size="large">精网号</el-text>
<el-input class="selectContent" v-model="selectData.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text" size="large">{{ t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="selectData.jwcode" :placeholder="t('common.jwcodePlaceholder')" clearable />
</div>
<div class="selectRow">
<el-text class="text" size="large">所属地区</el-text>
<el-select class="selectContent" v-model="selectData.market" placeholder="请选择所属地区" clearable>
<el-text class="text" size="large">{{ t('common.market') }}</el-text>
<el-select class="selectContent" v-model="selectData.market" :placeholder="t('common.marketPlaceholder')" clearable>
<el-option v-for="item in market" :key="item" :label="item" :value="item" />
</el-select>
</div>
@ -373,9 +375,9 @@ onMounted(async function () {
<el-col>
<div class="select">
<div class="selectRow" style="width: 36vw;">
<el-text class="text" size="large">充值时间</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" range-separator=""
start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:25vw"
<el-text class="text" size="large">{{ t('common.rechargeTime') }}</el-text>
<el-date-picker class="selectContent" v-model="getTime" type="datetimerange" :range-separator="t('common.to')"
:start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')" style="margin-right:1vw;width:25vw"
@change="handleDatePickerChange" :default-time="defaultTime" />
<div v-if="false">
<el-button @click="getToday()" style="margin-left: 10px"
@ -390,36 +392,36 @@ onMounted(async function () {
</el-button>
</div>
</div>
<el-button type="primary" @click="search()">查询</el-button>
<el-button type="primary" style="width: 80px;" @click="exportExcel()">导出Excel</el-button>
<el-button type="primary" style="width: 95px;" @click="openExportList">查看导出列表</el-button>
<el-button type="success" @click="reset()">重置</el-button>
<el-button type="primary" @click="search()">{{ t('common.search') }}</el-button>
<el-button type="primary" @click="exportExcel()">{{ t('common.exportExcel') }}</el-button>
<el-button type="primary" @click="openExportList">{{ t('common.viewExportList') }}</el-button>
<el-button type="success" @click="reset()">{{ t('common.reset') }}</el-button>
</div>
</el-col>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
金豆总数{{ format3(beanNum) }}&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(permanentBeans) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(freeBean) }}
{{ t('common.totalGoldBean') }}{{ format3(beanNum) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(permanentBeans) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(freeBean) }}
</div>
<div>
<el-table :data="tableData" style="width: 82vw;height:65vh;" @sort-change="handleSortChange"
:row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span>
</template>
</el-table-column>
<el-table-column fixed="left" prop="name" label="姓名" min-width="100" show-overflow-tooltip />
<el-table-column fixed="left" prop="jwcode" label="精网号" min-width="110px" />
<el-table-column prop="market" label="所属地区" min-width="100px" />
<el-table-column prop="permanentBean" label="付费金豆" sortable="custom" min-width="110px" />
<el-table-column prop="freeBean" label="免费金豆" sortable="custom" min-width="110px" />
<el-table-column prop="remark" label="备注" min-width="150px" show-overflow-tooltip />
<el-table-column prop="rechargeTime" label="充值时间" min-width="200px">
<el-table-column fixed="left" prop="name" :label="t('common_list.name')" min-width="100" show-overflow-tooltip />
<el-table-column fixed="left" prop="jwcode" :label="t('common_list.jwcode')" min-width="110px" />
<el-table-column prop="market" :label="t('common_list.market')" min-width="100px" />
<el-table-column prop="permanentBean" :label="t('common_list.permanentBean')" sortable="custom" min-width="110px" />
<el-table-column prop="freeBean" :label="t('common_list.freeBean')" sortable="custom" min-width="110px" />
<el-table-column prop="remark" :label="t('common_list.remark')" min-width="150px" show-overflow-tooltip />
<el-table-column prop="rechargeTime" :label="t('common_list.rechargeTime')" min-width="200px">
<template #default="scope">
{{ moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
@ -435,33 +437,33 @@ onMounted(async function () {
</div>
</el-card>
<!-- 导出弹窗 -->
<el-dialog v-model="exportListVisible" title="导出列表" width="80vw">
<el-dialog v-model="exportListVisible" :title="t('common_export.exportList')" width="80vw">
<el-table :data="exportList" style="width: 80vw;height: 60vh;" :loading="exportListLoading">
<el-table-column prop="fileName" label="文件名" />
<el-table-column prop="state" label="状态">
<el-table-column prop="fileName" :label="t('common_export.fileName')" />
<el-table-column prop="state" :label="t('common_export.status')">
<template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="t('common_export.createTime')">
<template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column :label="t('common_export.operation')">
<template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)"
:disabled="scope.row.state !== 2">
下载
{{ t('common_export.download') }}
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button text @click="exportListVisible = false">关闭</el-button>
<el-button text @click="exportListVisible = false">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>

2
src/views/refund/gold/addCoinRefund.vue

@ -64,7 +64,7 @@ const cancel = function () {
const getRefund = async function () {
if (!addRefund.value.jwcode) {
ElMessage.error(t('elmessage.checkJwCode'))
ElMessage.error(t('elmessage.checkJwcode'))
return
}
addRefund.value.orderCode = ''

42
src/views/usergold/bean/userbean.vue

@ -1,40 +1,40 @@
<template>
<el-card class="card1" style="margin-bottom: 1vh;">
<el-text size="large">精网号</el-text>
<el-input v-model="searchObj.jwcode" placeholder="请输入精网号" style="width: 240px" clearable />
<el-text size="large" style="margin-left:20px">地区</el-text>
<el-select v-model="searchObj.dept" placeholder="请选择地区" style="width: 240px" clearable>
<el-text size="large">{{ t('common.jwcode') }}</el-text>
<el-input v-model="searchObj.jwcode" :placeholder="t('common.jwcodePlaceholder')" style="width: 240px" clearable />
<el-text size="large" style="margin-left:20px">{{ t('common.market') }}</el-text>
<el-select v-model="searchObj.dept" :placeholder="t('common.marketPlaceholder')" style="width: 240px" clearable>
<el-option v-for="item in marketOptions" :key="item" :label="item" :value="item" />
</el-select>
<div style="float: right;">
<el-button type="primary" @click="search">查询</el-button>
<el-button type="success" @click="reset">重置</el-button>
<el-button type="primary" @click="search">{{ t('common.search') }}</el-button>
<el-button type="success" @click="reset">{{ t('common.reset') }}</el-button>
</div>
</el-card>
<el-card class="card2">
<div class="goldStatistics">
现有金豆数{{ format3(stats.sumBean) }}金豆&nbsp;&nbsp;&nbsp;&nbsp;
付费金豆数{{ format3(stats.permanentBean) }}金豆&nbsp;&nbsp;&nbsp;&nbsp;
免费金豆数{{ format3(stats.freeBean) }}金豆&nbsp;&nbsp;&nbsp;&nbsp;
消费金豆总数{{ format3(stats.consumeSum) }}金豆&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.nowGoldBeanNum') }}{{ format3(stats.sumBean) }}{{ t('common.goldBean') }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.payGoldBean') }}{{ format3(stats.permanentBean) }}{{ t('common.goldBean') }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.freeGoldBean') }}{{ format3(stats.freeBean) }}{{ t('common.goldBean') }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ t('common.consumeGoldBean') }}{{ format3(stats.consumeSum) }}{{ t('common.goldBean') }}&nbsp;&nbsp;&nbsp;&nbsp;
</div>
<el-table :data="tableData" height="73vh" @sort-change="handleSortChange" :row-style="{ height: '50px' }">
<el-table-column type="index" label="序号" width="80px" fixed="left">
<el-table-column type="index" :label="t('common_list.id')" width="80px" fixed="left">
<template #default="scope">
<span>{{
scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize
}}</span>
</template>
</el-table-column>
<el-table-column label="姓名" style="width: 120px;" prop="name" show-overflow-tooltip />
<el-table-column label="精网号" style="width: 110px;" prop="jwcode" />
<el-table-column label="所属地区" style="width: 120px;" prop="dept" />
<el-table-column label="现有金豆" style="width: 120px;" prop="beanNum" sortable="custom" />
<el-table-column label="免费金豆" style="width: 120px;" prop="freeBean" sortable="custom" />
<el-table-column label="付费金豆" style="width: 120px;" prop="buyBean" sortable="custom" />
<el-table-column label="历史消费" style="width: 120px;" prop="totalCostBean" sortable="custom" />
<el-table-column :label="t('common_list.name')" style="width: 120px;" prop="name" show-overflow-tooltip />
<el-table-column :label="t('common_list.jwcode')" style="width: 110px;" prop="jwcode" />
<el-table-column :label="t('common_list.market')" style="width: 120px;" prop="dept" />
<el-table-column :label="t('common_list.currentGoldBean')" style="width: 120px;" prop="beanNum" sortable="custom" />
<el-table-column :label="t('common_list.freeBean')" style="width: 120px;" prop="freeBean" sortable="custom" />
<el-table-column :label="t('common_list.permanentBean')" style="width: 120px;" prop="buyBean" sortable="custom" />
<el-table-column :label="t('common_list.historyConsumption')" style="width: 120px;" prop="totalCostBean" sortable="custom" />
</el-table>
@ -56,7 +56,9 @@ const adminStore = useAdminStore();
const { adminData, menuTree, flag } = storeToRefs(adminStore);
import { permissionMapping, findMenuById } from "@/utils/menuTreePermission.js"
import { ElMessage } from 'element-plus';
//
import {useI18n} from 'vue-i18n'
const {t} = useI18n()
// flag
watch(flag, (newFlag, oldFlag) => {
// flag
@ -96,7 +98,7 @@ const get = async function () {
if (searchObj.value.jwcode) {
const numRef = /^\d{1,9}$/;
if (!numRef.test(searchObj.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return
}
}

9
src/views/workspace/index.vue

@ -1,7 +1,7 @@
<template>
<!-- 头部 -->
<el-header class="header">
<div class="title">数据总览</div>
<div class="title">{{ t('workbench.dataOverview') }}</div>
</el-header>
<div style="height: 100vh;">
<el-row class="cards">
@ -15,7 +15,7 @@
</el-row>
<el-row class="graphs">
<el-col :span="24">
<div v-if="loading">加载中...</div>
<div v-if="loading">{{ t('workbench.loading') }}</div>
<GoldGraphMarkets v-else-if="GraphFlag" />
<GoldGraph v-else />
</el-col>
@ -30,6 +30,9 @@ import GoldGraphMarkets from "@/components/workspace/GoldGraphMarkets.vue";
import API from "@/util/http.js";
import {onMounted, ref} from "vue";
import GoldGraph from "@/components/workspace/GoldGraph.vue";
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const GraphFlag = ref();
const loading = ref(true); //
@ -39,7 +42,7 @@ const getAdminData = async function () {
loading.value = true; //
const result = await API({url: '/admin/userinfo', data: {}});
GraphFlag.value = result.markets !== '总部' && result.markets !== '研发部'
&& result.markets !== 'headquarters' && result.markets !== 'R&D Department'
&& result.markets !== 'Headquarters' && result.markets !== 'R&D Department'
;

Loading…
Cancel
Save