2 Commits

  1. 118
      src/components/locales/lang/zh-CN.js
  2. 165
      src/views/consume/gold/addCoinConsume.vue
  3. 5
      src/views/consume/gold/coinConsume.vue
  4. 127
      src/views/consume/gold/coinConsumeDetail.vue
  5. 138
      src/views/refund/gold/addCoinRefund.vue
  6. 5
      src/views/refund/gold/coinRefund.vue
  7. 114
      src/views/refund/gold/coinRefundDetail.vue

118
src/components/locales/lang/zh-CN.js

@ -1,7 +1,7 @@
import { UploadFilled } from "@element-plus/icons-vue"; import { UploadFilled } from "@element-plus/icons-vue";
export default { export default {
// 通用组
// 通用组 (筛选,按钮,币种计量)
common: { common: {
// 筛选 // 筛选
jwcode: '精网号', jwcode: '精网号',
@ -16,9 +16,13 @@ export default {
refundTypePlaceholder: '请选择退款类型', refundTypePlaceholder: '请选择退款类型',
market: '所属地区', market: '所属地区',
marketPlaceholder: '请选择所属地区', marketPlaceholder: '请选择所属地区',
consumePlatform: '消耗平台',
consumePlatformPlaceholder: '请选择消耗平台',
rechargePlatform: '充值平台', rechargePlatform: '充值平台',
rechargePlatformPlaceholder: '请选择充值平台', rechargePlatformPlaceholder: '请选择充值平台',
consumeTime: '消耗时间',
rechargeTime: '充值时间', rechargeTime: '充值时间',
refundTime: '退款时间',
submitTime: '提交时间', submitTime: '提交时间',
auditTime: '审核时间', auditTime: '审核时间',
startTime: '起始时间', startTime: '起始时间',
@ -34,9 +38,16 @@ export default {
reject: '驳回', reject: '驳回',
cancel: '取消', cancel: '取消',
confirm: '确认', confirm: '确认',
submit: '提交',
confrimRecharge: '确认充值', confrimRecharge: '确认充值',
// 按钮组-日期
today: '今',
yesterday: '昨',
last7Days: '近7天',
// 币种计量单位类型 // 币种计量单位类型
rechargeSGD: '充值新币', rechargeSGD: '充值新币',
consumeSGD: '消耗新币',
refundGoldCoin: '退款金币总数',
totalGoldCoin: '总金币数', totalGoldCoin: '总金币数',
permanentGold: '永久金币', permanentGold: '永久金币',
freeGold: '免费金币', freeGold: '免费金币',
@ -44,6 +55,7 @@ export default {
SGD: '新币', SGD: '新币',
goldCoin: '金币', goldCoin: '金币',
: '条', : '条',
: '个',
goldBean: '金豆', goldBean: '金豆',
// 对话框标题 // 对话框标题
will: '将要', will: '将要',
@ -53,28 +65,49 @@ export default {
// 通用 // 通用
addSuccess: '添加成功', addSuccess: '添加成功',
searchSuccess: '查询成功', searchSuccess: '查询成功',
requestFailed: '请求失败',
jwcodeError: '精网号错误', jwcodeError: '精网号错误',
addFailedUnknown: '添加失败,未知错误',
addFailed: '添加失败,请检查网络连接或联系管理员',
queryFailed: '查询失败,请检查网络连接或精网号是否正确',
refundTypeError: '退款类型数据格式错误,请联系管理员',
confirmRefund: '确认退款?',
// 校验精网号,充值等输入 // 校验精网号,充值等输入
checkInputContent: '请检查输入内容', checkInputContent: '请检查输入内容',
permanentAndFreeNoZero: '永久金币和免费金币不能同时为0', permanentAndFreeNoZero: '永久金币和免费金币不能同时为0',
checkRate: '请选择币种名称', checkRate: '请选择币种名称',
checkMoney: '请输入充值金额', checkMoney: '请输入充值金额',
checkJwcode: '请输入精网号',
checkGoodsName: '请选择商品',
checkUserInfo: '请先查询用户信息', checkUserInfo: '请先查询用户信息',
checkActivity: '请输入活动名称', checkActivity: '请输入活动名称',
checkPermanentGold: '请输入永久金币数', checkPermanentGold: '请输入永久金币数',
checkFreeGold: '请输入免费金币数', checkFreeGold: '请输入免费金币数',
checkTaskGold: '请输入任务金币数',
checkNumber: '请输入有效的数字', checkNumber: '请输入有效的数字',
checkPayModel: '请选择付款方式', checkPayModel: '请选择付款方式',
checkPayTime: '请选择交款时间', checkPayTime: '请选择交款时间',
checkQueryParams: '请检查查询参数',
checkRefundType: '请选择退款类型',
checkRefundGoods: '请选择退款商品',
checkOrderNo: '请输入订单号',
// 校验提示(error) // 校验提示(error)
noEmptyJwcode: '精网号不能为空', noEmptyJwcode: '精网号不能为空',
noEmptySumGold: '消耗金币总数不能为空',
noUser: '用户不存在', noUser: '用户不存在',
noOrder: '未查询到相关订单',
noTotalGoldZero: '总金币数不能为0',
noNegativeNumber: '不能输入负数',
limitDigitJwcode: '精网号只能包含数字', limitDigitJwcode: '精网号只能包含数字',
limitNoSpecialChar: '不能包含特殊符号或负数', limitNoSpecialChar: '不能包含特殊符号或负数',
limitNegativeNumber: '消耗金币总数不能为负数',
limitExceeded: '消耗金币总数超过可用金币总和',
limitSix: '整数位数不能超过6位', limitSix: '整数位数不能超过6位',
limitTwoDecimal: '小数位数不能超过两位', limitTwoDecimal: '小数位数不能超过两位',
limitZero: '输入金额不能小于0', limitZero: '输入金额不能小于0',
limitPositiveNumber: '请输入大于0的正数(可包含最多两位小数)',
limitJwcodeNine: '精网号必须为数字且不超过九位', limitJwcodeNine: '精网号必须为数字且不超过九位',
limitBalance: '所填金额大于该类金币余额',
// 图片上传 // 图片上传
onlyUploadJPGPNG: '只能上传 JPG/PNG 图片!', onlyUploadJPGPNG: '只能上传 JPG/PNG 图片!',
limitImageSize: '图片大小不能超过 1MB!', limitImageSize: '图片大小不能超过 1MB!',
@ -111,19 +144,30 @@ export default {
name: '姓名', name: '姓名',
jwcode: '精网号', jwcode: '精网号',
market: '所属地区', market: '所属地区',
orderNo: '订单号',
goodsName: '商品名称',
refundType: '退款类型',
refundModel: '退款方式',
refundModelAll: '全部退款',
refundModelPart: '部分退款',
refundGoldCoin: '退款金币总数',
activity: '活动名称', activity: '活动名称',
rateName: '货币名称', rateName: '货币名称',
rechargeAmount: '充值金额', rechargeAmount: '充值金额',
permanentGold: '永久金币', permanentGold: '永久金币',
freeGold: '免费金币', freeGold: '免费金币',
taskGold: '任务金币',
rechargePlatform: '充值平台', rechargePlatform: '充值平台',
consumePlatform: '消耗平台',
consumeTotalGold: '消耗金币总数',
payModel: '支付方式', payModel: '支付方式',
remark: '备注', remark: '备注',
orderStatus: '订单状态', orderStatus: '订单状态',
submitter: '提交人', submitter: '提交人',
rechargeTime: '充值时间', rechargeTime: '充值时间',
consumeTime: '消耗时间',
refundTime: '退款时间',
}, },
// 通用导出字段组 // 通用导出字段组
common_export: { common_export: {
exportList: '导出列表', exportList: '导出列表',
@ -142,10 +186,23 @@ export default {
activityPlaceholder: '请输入活动名称', activityPlaceholder: '请输入活动名称',
permanentGold: '永久金币', permanentGold: '永久金币',
freeGold: '免费金币', freeGold: '免费金币',
taskGold: '任务金币',
rechargeAmount: '充值金额', rechargeAmount: '充值金额',
currencyName: '货币名称', currencyName: '货币名称',
goodsName: '商品名称',
goodsNamePlaceholder: '请选择商品',
payModel: '收款方式', payModel: '收款方式',
refundType: '退款类型',
refundTypePlaceholder: '请选择退款类型',
orderNo: '订单号',
orderNoPlaceholder: '请选择订单号',
refundModel: '退款方式',
refundModelAll: '全部退款',
refundModelPart: '部分退款',
refundGoldCoin: '退款金币总数',
payModelPlaceholder: '请选择收款方式', payModelPlaceholder: '请选择收款方式',
consumeTotalGold: '消耗金币总数',
totalGold: '金币总数',
paymentTime: '交款时间', paymentTime: '交款时间',
paymentVoucher: '交款凭证', paymentVoucher: '交款凭证',
paymentVoucherPlaceholder: '仅支持.jpg .png格式,文件≤1MB', paymentVoucherPlaceholder: '仅支持.jpg .png格式,文件≤1MB',
@ -156,6 +213,7 @@ export default {
prompt: '重复充值风险提示', prompt: '重复充值风险提示',
similarRechargeRecords: '检测到该用户近期有相似充值记录', similarRechargeRecords: '检测到该用户近期有相似充值记录',
rechargePermanentGold: '充值永久金币', rechargePermanentGold: '充值永久金币',
buy: '购买',
operator: '操作人', operator: '操作人',
continueOperation: '是否继续操作', continueOperation: '是否继续操作',
}, },
@ -246,6 +304,7 @@ export default {
passRecord: '通过该记录!', passRecord: '通过该记录!',
}, },
// 充值组
recharge: { recharge: {
// 金币充值明细 --------------------------------- // 金币充值明细 ---------------------------------
coinRechargeDetail: '金币充值明细', coinRechargeDetail: '金币充值明细',
@ -271,4 +330,59 @@ export default {
other: '其他' other: '其他'
}, },
}, },
// 消耗组
consume: {
// 金币消耗明细 ---------------------------------
coinConsumeDetail: '金币消耗明细',
// 订单状态
normal: '正常',
refunded: '已退款',
unknown: '未知状态',
// 消费平台选项
consumePlatforms: {
goldSystem: '金币系统',
HomilyChart: 'HomilyChart',
HomilyLink: 'HomilyLink',
ERP: 'ERP',
other: '其他',
initGold: '初始化金币',
},
// 新增消耗
addCoinConsume: '新增消耗',
},
//退款组
refund: {
// 金币退款明细 ---------------------------------
coinRefundDetail: '金币退款明细',
// 订单状态
normal: '正常',
refunded: '已退款',
unknown: '未知状态',
// 退款方式选项
refundMethods: {
allRefund: '全部退款',
partialRefund: '部分退款',
},
// 新增退款
refundTypeOptions: {
'商品退款': '商品退款',
'金币退款': '金币退款',
},
addCoinRefund: '新增退款',
// 新增退款的用户表单
id: '序号',
type: '类型',
recharge: '充值',
consume: '消费',
productName: '商品名称',
orderCode: '订单号',
permanentGold: '永久金币',
freeGold: '免费金币',
taskGold: '任务金币',
isRefund: '允许退款',
no: '否',
yes: '是',
},
} }

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

@ -1,13 +1,16 @@
<script setup> <script setup>
import {onMounted, reactive, ref, watch} from "vue";
import {ElIcon, ElMessage} from "element-plus";
import { onMounted, reactive, ref, watch } from "vue";
import { ElIcon, ElMessage } from "element-plus";
import moment from "moment"; import moment from "moment";
import request from "@/util/http.js" import request from "@/util/http.js"
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import {useAdminStore} from "@/store/index.js";
import {storeToRefs} from "pinia";
import {WarnTriangleFilled} from "@element-plus/icons-vue";
import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia";
import { WarnTriangleFilled } from "@element-plus/icons-vue";
import dayjs from "dayjs"; import dayjs from "dayjs";
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const adminStore = useAdminStore(); const adminStore = useAdminStore();
const { adminData, menuTree } = storeToRefs(adminStore); const { adminData, menuTree } = storeToRefs(adminStore);
@ -22,7 +25,7 @@ const trimJwCode = () => {
if (!isNaN(numeric)) { if (!isNaN(numeric)) {
addConsume.value.jwcode = numeric addConsume.value.jwcode = numeric
} else { } else {
ElMessage.error("精网号格式不正确,请输入数字")
ElMessage.error(t('elmessage.limitDigitJwcode'))
} }
} }
} }
@ -64,18 +67,18 @@ const addConsume = ref({
const Ref = ref(null) const Ref = ref(null)
const rules = reactive({ const rules = reactive({
jwcode: [ jwcode: [
{ required: true, message: "请输入精网号", trigger: "blur" },
{ required: true, message: t('elmessage.checkJwcode'), trigger: "blur" },
], ],
goodsName: [{ required: true, message: "请选择商品", trigger: "change" }],
goodsName: [{ required: true, message: t('elmessage.checkGoodsName'), trigger: "change" }],
sumGold: [ sumGold: [
{ required: true, message: "消耗金币总数不能为空", trigger: "blur" },
{ required: true, message: t('elmessage.noEmptySumGold'), trigger: "blur" },
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
// 00.10 // 00.10
const isValid = /^(0\.\d{1,2})|([1-9]\d*(\.\d{1,2})?)$/.test(value); const isValid = /^(0\.\d{1,2})|([1-9]\d*(\.\d{1,2})?)$/.test(value);
if (!isValid) { if (!isValid) {
callback(new Error("请输入大于0的正数(可包含最多两位小数)"));
callback(new Error(t('elmessage.limitPositiveNumber')));
} else { } else {
callback(); callback();
} }
@ -93,7 +96,7 @@ function validateInput() {
trimJwCode(); trimJwCode();
if (user.value.jwcode == null) { if (user.value.jwcode == null) {
ElMessage.warning("请先查询用户信息");
ElMessage.warning(t('elmessage.checkUserInfo'));
addConsume.value.sumGold = null; addConsume.value.sumGold = null;
user.value = {}; user.value = {};
return false; return false;
@ -115,7 +118,7 @@ function validateInput() {
} }
// //
if (sumGold < 0) { if (sumGold < 0) {
ElMessage.warning("消耗金币总数不能为负数");
ElMessage.warning(t('elmessage.limitNegativeNumber'));
addConsume.value.sumGold = null; addConsume.value.sumGold = null;
return false; return false;
} }
@ -131,14 +134,14 @@ function validateInput() {
// 6 // 6
const truncatedInteger = integerPart.slice(0, 6); const truncatedInteger = integerPart.slice(0, 6);
addConsume.value.sumGold = parseFloat(truncatedInteger); addConsume.value.sumGold = parseFloat(truncatedInteger);
ElMessage.info('整数部分最多允许6位');
ElMessage.info(t('elmessage.limitSix'));
return; // return; //
} }
} else { } else {
// //
if (sumGoldStr.length > 6) { if (sumGoldStr.length > 6) {
addConsume.value.sumGold = parseFloat(sumGoldStr.slice(0, 6)); addConsume.value.sumGold = parseFloat(sumGoldStr.slice(0, 6));
ElMessage.info('整数部分最多允许6位');
ElMessage.info(t('elmessage.limitSix'));
return; return;
} }
} }
@ -150,7 +153,7 @@ function validateInput() {
// //
const truncatedValue = parseFloat(sumGoldStr.slice(0, sumGoldStr.indexOf('.') + 3)); const truncatedValue = parseFloat(sumGoldStr.slice(0, sumGoldStr.indexOf('.') + 3));
addConsume.value.sumGold = truncatedValue; addConsume.value.sumGold = truncatedValue;
ElMessage.info('最多允许输入两位小数');
ElMessage.info(t('elmessage.limitTwoDecimal'));
} }
} }
} }
@ -159,7 +162,7 @@ function validateInput() {
// //
const totalAvailableGold = (user.value.nowSumGold) const totalAvailableGold = (user.value.nowSumGold)
if (user.value.jwcode && sumGold > totalAvailableGold) { if (user.value.jwcode && sumGold > totalAvailableGold) {
ElMessage.error("消耗金币总数超过可用金币总和");
ElMessage.error(t('elmessage.limitExceeded'));
// sumGoldnull // sumGoldnull
addConsume.value.sumGold = null; addConsume.value.sumGold = null;
return false; return false;
@ -255,7 +258,7 @@ const add = async function () {
} catch (error) { } catch (error) {
console.error("请求失败", error); console.error("请求失败", error);
ElMessage.error("添加失败,请检查网络连接或联系管理员");
ElMessage.error(t('elmessage.addFailed'));
} }
}; };
@ -273,10 +276,10 @@ function handleResponse(result) {
expires: expires:
1, path: '/' 1, path: '/'
}); });
ElMessage.success("添加成功");
ElMessage.success(t('elmessage.addSuccess'));
console.log("请求成功", result); console.log("请求成功", result);
} else { } else {
ElMessage.error(result.msg || "添加失败,未知错误");
ElMessage.error(result.msg || t('elmessage.addFailedUnknown'));
} }
} }
@ -385,7 +388,7 @@ const addBefore = () => {
if (!valid) { if (!valid) {
ElMessage({ ElMessage({
type: 'error', type: 'error',
message: '请检查输入内容'
message: t('elmessage.checkInputContent')
}); });
return; return;
} }
@ -409,13 +412,13 @@ const getUser = async function (jwcode) {
try { try {
// //
if (!jwcode) { if (!jwcode) {
ElMessage.warning('精网号不能为空');
ElMessage.warning(t('elmessage.noEmptyJwcode'));
return; return;
} }
// //
if (!/^\d{1,9}$/.test(jwcode)) { if (!/^\d{1,9}$/.test(jwcode)) {
ElMessage.warning('精网号必须为数字且不超过九位');
ElMessage.warning(t('elmessage.limitJwcodeNine'));
resetForm() resetForm()
return; return;
} }
@ -445,7 +448,7 @@ const getUser = async function (jwcode) {
historyTaskGold: result.data.historyTaskGold historyTaskGold: result.data.historyTaskGold
}; };
ElMessage.success("查询成功");
ElMessage.success(t('elmessage.searchSuccess'));
// sumGold // sumGold
if (addConsume.value.sumGold) { if (addConsume.value.sumGold) {
const parsedSumGold = parseFloat(addConsume.value.sumGold); const parsedSumGold = parseFloat(addConsume.value.sumGold);
@ -461,16 +464,16 @@ const getUser = async function (jwcode) {
} else if (!result.data) { } else if (!result.data) {
ElMessage.warning("用户不存在");
ElMessage.warning(t('elmessage.noUser'));
user.value.jwcode = null user.value.jwcode = null
addConsume.value.jwcode = null addConsume.value.jwcode = null
// resetForm(); // // resetForm(); //
} else { } else {
ElMessage.warning(result.msg || "请检查查询参数");
ElMessage.warning(result.msg || t('elmessage.checkQueryParams'));
} }
} catch (error) { } catch (error) {
console.error("请求失败", error); console.error("请求失败", error);
ElMessage.error("查询失败,请检查网络连接或精网号是否正确");
ElMessage.error(t('elmessage.queryFailed'));
resetForm(); // resetForm(); //
} }
}; };
@ -534,20 +537,22 @@ onMounted(async function () {
<div class="left"> <div class="left">
<el-form :model="addConsume" ref="Ref" :rules="rules" style="min-width: 420px;" class="add-form" <el-form :model="addConsume" ref="Ref" :rules="rules" style="min-width: 420px;" class="add-form"
label-width="auto" label-position="right"> label-width="auto" label-position="right">
<el-form-item prop="jwcode" label="精网号" style="margin-top: 50px">
<el-form-item prop="jwcode" :label="t('common_add.jwcode')" style="margin-top: 50px">
<el-input v-model="addConsume.jwcode" style="width: 200px;" /> <el-input v-model="addConsume.jwcode" style="width: 200px;" />
<el-button type="primary" @click="getUser(addConsume.jwcode)" style="margin-left: 20px">查询
<el-button type="primary" @click="getUser(addConsume.jwcode)" style="margin-left: 20px">
{{ t('common.search') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<el-form-item prop="goodsName" label="商品名称">
<el-select v-model="addConsume.goodsName" placeholder="请选择商品" style="width: 200px" clearable filterable>
<el-form-item prop="goodsName" :label="t('common_add.goodsName')">
<el-select v-model="addConsume.goodsName" :placeholder="t('common_add.goodsNamePlaceholder')"
style="width: 200px" clearable filterable>
<el-option v-for="(item, index) in goods" :key="index" :label="item.label" :value="item" /> <el-option v-for="(item, index) in goods" :key="index" :label="item.label" :value="item" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="sumGold" label="消耗金币总数">
<el-form-item prop="sumGold" :label="t('common_add.consumeTotalGold')">
<el-input v-model="addConsume.sumGold" style="width: 120px" @input="validateInput()" <el-input v-model="addConsume.sumGold" style="width: 120px" @input="validateInput()"
@change="calculateCoins(addConsume.sumGold)" /> @change="calculateCoins(addConsume.sumGold)" />
</el-form-item> </el-form-item>
@ -555,21 +560,21 @@ onMounted(async function () {
<!-- 三类金币自动计算禁用状态不可编辑 --> <!-- 三类金币自动计算禁用状态不可编辑 -->
<el-form-item prop="permanentGold" label="永久金币">
<el-form-item prop="permanentGold" :label="t('common_add.permanentGold')">
<el-input v-model="addConsume.permanentGold" disabled style="width: 120px"> <el-input v-model="addConsume.permanentGold" disabled style="width: 120px">
<template #default="scope">{{ scope.row.permanentGold }}</template> <template #default="scope">{{ scope.row.permanentGold }}</template>
</el-input> </el-input>
<p style="margin-right: 0px">&nbsp;&nbsp;</p>
<p style="margin-right: 0px">&nbsp;&nbsp;{{ $t('common.') }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="freeCoin" label="免费金币">
<el-form-item prop="freeCoin" :label="t('common_add.freeGold')">
<el-input disabled v-model="addConsume.freeGold" style="width: 120px" /> <el-input disabled v-model="addConsume.freeGold" style="width: 120px" />
<p style="margin-right: 0px">&nbsp;&nbsp;</p>
<p style="margin-right: 0px">&nbsp;&nbsp;{{ $t('common.') }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="taskGold" label="任务金币">
<el-form-item prop="taskGold" :label="t('common_add.taskGold')">
<el-input disabled v-model="addConsume.taskGold" style="width: 120px" /> <el-input disabled v-model="addConsume.taskGold" style="width: 120px" />
<p style="margin-right: 20px">&nbsp;&nbsp;</p>
<p style="margin-right: 20px">&nbsp;&nbsp;{{ $t('common.') }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="remark" label="备注"> <el-form-item prop="remark" label="备注">
@ -577,8 +582,11 @@ onMounted(async function () {
type="textarea" /> type="textarea" />
</el-form-item> </el-form-item>
<el-button type="success" @click="resetForm()" style="margin-left: 200px;margin-top:10px">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore" style="margin-top:10px"> 提交</el-button>
<el-button type="success" @click="resetForm()" style="margin-left: 200px;margin-top:10px">{{ t('common.reset')
}}</el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore" style="margin-top:10px">{{
t('common.submit')
}}</el-button>
</el-form> </el-form>
</div> </div>
@ -586,28 +594,29 @@ onMounted(async function () {
<!-- 客户信息栏 --> <!-- 客户信息栏 -->
<el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info"> <el-card v-if="user.jwcode" style="width: 800px; float: right" class="customer-info">
<el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left"> <el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left">
<el-text size="large" style="margin-left: 20px">客户信息</el-text>
<el-text size="large" style="margin-left: 20px">{{ $t('common_add_user.customerInfo') }}</el-text>
<!-- 第一行姓名 + 历史金币 --> <!-- 第一行姓名 + 历史金币 -->
<el-row style="margin-top: 20px"> <el-row style="margin-top: 20px">
<el-col :span="9"> <el-col :span="9">
<el-form-item label="姓名">
<el-form-item :label="$t('common_add_user.name')">
<p>{{ user.name }}</p> <p>{{ user.name }}</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<el-form-item :label="$t('common_add_user.currentGoldCoinTotal')" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ <span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
user.nowSumGold user.nowSumGold
}}</span> }}</span>
</el-form-item> </el-form-item>
<!-- 金币详情独立显示 --> <!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 --> <el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold
}};
免费金币:{{ user.nowFreeGold }};
任务金币:{{ user.nowTaskGold }})</span>
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">({{
$t('common_add_user.permanentGold') }}:{{
user.nowPermanentGold
}};
{{ $t('common_add_user.freeGold') }}:{{ user.nowFreeGold }};
{{ $t('common_add_user.taskGold') }}:{{ user.nowTaskGold }})</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -615,16 +624,18 @@ onMounted(async function () {
<!-- 第二行精网号 + 当前金币独立行 --> <!-- 第二行精网号 + 当前金币独立行 -->
<el-row> <el-row>
<el-col :span="9"> <el-col :span="9">
<el-form-item label="精网号">
<el-form-item :label="$t('common_add_user.jwcode')">
<p>{{ user.jwcode }}</p> <p>{{ user.jwcode }}</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<el-form-item label="消费次数">
<el-form-item :label="$t('common_add_user.consumptionTimes')">
<p style="color: #2fa1ff">{{ user.consumeNum }} </p> <p style="color: #2fa1ff">{{ user.consumeNum }} </p>
</el-form-item> </el-form-item>
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 --> <el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<p style="font-size: small; color: #b1b1b1">(仅统计2025-01-01后的数据)</p>
<p style="font-size: small; color: #b1b1b1">({{ $t('common_add_user.onlyStatisticsDataAfter20250101')
}})
</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -644,7 +655,7 @@ onMounted(async function () {
<!-- 第四行消费次数 + 所属门店 --> <!-- 第四行消费次数 + 所属门店 -->
<el-row> <el-row>
<el-col :span="9"> <el-col :span="9">
<el-form-item label="所属门店">
<el-form-item :label="$t('common_add_user.store')">
<p>{{ user.market }}</p> <p>{{ user.market }}</p>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -653,42 +664,42 @@ onMounted(async function () {
</el-card> </el-card>
<el-dialog v-model="FirstConsumeDialogVisible" title="操作确认" :before-close="FirstConsumeDialogVisiblehandleClose"
:close-on-click-modal="false" width="480px">
<el-dialog v-model="FirstConsumeDialogVisible" :title="$t('common_add.operationConfirm')"
:before-close="FirstConsumeDialogVisiblehandleClose" :close-on-click-modal="false" width="480px">
<!-- 内容整体居中且收窄 --> <!-- 内容整体居中且收窄 -->
<div class="confirm-body"> <div class="confirm-body">
<!-- 用户信息 --> <!-- 用户信息 -->
<div> <div>
<div class="field-label">用户信息</div>
<div class="field-label">{{ $t('common_add.userInfo') }}</div>
<el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled /> <el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled />
</div> </div>
<!-- 活动名称 -->
<!-- 商品名称 -->
<div class="field"> <div class="field">
<div class="field-label">商品名称</div>
<div class="field-label">{{ $t('common_add.goodsName') }}</div>
<el-input v-model="addConsume.goodsName.value" disabled /> <el-input v-model="addConsume.goodsName.value" disabled />
</div> </div>
<!--金币总数 --> <!--金币总数 -->
<div class="field"> <div class="field">
<div class="field-label">金币总数</div>
<div class="field-label">{{ $t('common_add.totalGold') }}</div>
<el-input v-model="addConsume.sumGold" disabled /> <el-input v-model="addConsume.sumGold" disabled />
</div> </div>
<!-- 金币详细信息同一行左右排列 --> <!-- 金币详细信息同一行左右排列 -->
<el-row :gutter="20" class="coins-row"> <el-row :gutter="20" class="coins-row">
<el-col :span="8"> <el-col :span="8">
<div class="field"> <div class="field">
<div class="field-label">永久金币</div>
<div class="field-label">{{ $t('common_add.permanentGold') }}</div>
<el-input v-model="addConsume.permanentGold" disabled /> <el-input v-model="addConsume.permanentGold" disabled />
</div> </div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="field"> <div class="field">
<div class="field-label">免费金币</div>
<div class="field-label">{{ $t('common_add.freeGold') }}</div>
<el-input v-model="addConsume.freeGold" disabled /> <el-input v-model="addConsume.freeGold" disabled />
</div> </div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="field"> <div class="field">
<div class="field-label">任务金币</div>
<div class="field-label">{{ $t('common_add.taskGold') }}</div>
<el-input v-model="addConsume.taskGold" disabled /> <el-input v-model="addConsume.taskGold" disabled />
</div> </div>
</el-col> </el-col>
@ -696,7 +707,7 @@ onMounted(async function () {
</el-row> </el-row>
<div class="field"> <div class="field">
<div class="field-label">备注</div>
<div class="field-label">{{ $t('common_add.remark') }}</div>
<el-input v-model="addConsume.remark" disabled /> <el-input v-model="addConsume.remark" disabled />
</div> </div>
</div> </div>
@ -704,49 +715,49 @@ onMounted(async function () {
<!-- 底部按钮居中 --> <!-- 底部按钮居中 -->
<template #footer> <template #footer>
<div class="dialog-footer-center"> <div class="dialog-footer-center">
<el-button @click="FirstConsumeDialogVisibleCancel"> </el-button>
<el-button type="primary" @click="FirstConsumeDialogVisibleContinue">确认购买</el-button>
<el-button @click="FirstConsumeDialogVisibleCancel">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="FirstConsumeDialogVisibleContinue">{{ $t('common.confirm') }}</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog v-model="ConsumeDialogVisible" title="操作确认" :before-close="ConsumeDialogVisiblehandleClose"
<el-dialog v-model="ConsumeDialogVisible" :title="$t('common_add.operationConfirm')" :before-close="ConsumeDialogVisiblehandleClose"
:close-on-click-modal="false" width="480px"> :close-on-click-modal="false" width="480px">
<!-- 内容整体居中且收窄 --> <!-- 内容整体居中且收窄 -->
<div class="confirm-body"> <div class="confirm-body">
<!-- 用户信息 --> <!-- 用户信息 -->
<div> <div>
<div class="field-label">用户信息</div>
<div class="field-label">{{ $t('common_add.userInfo') }}</div>
<el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled /> <el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled />
</div> </div>
<!-- 活动名称 -->
<!-- 商品名称 -->
<div class="field"> <div class="field">
<div class="field-label">商品名称</div>
<div class="field-label">{{ $t('common_add.goodsName') }}</div>
<el-input v-model="addConsume.goodsName.value" disabled /> <el-input v-model="addConsume.goodsName.value" disabled />
</div> </div>
<!--金币总数 --> <!--金币总数 -->
<div class="field"> <div class="field">
<div class="field-label">金币总数</div>
<div class="field-label">{{ $t('common_add.totalGold') }}</div>
<el-input v-model="addConsume.sumGold" disabled /> <el-input v-model="addConsume.sumGold" disabled />
</div> </div>
<!-- 金币详细信息同一行左右排列 --> <!-- 金币详细信息同一行左右排列 -->
<el-row :gutter="20" class="coins-row"> <el-row :gutter="20" class="coins-row">
<el-col :span="8"> <el-col :span="8">
<div class="field"> <div class="field">
<div class="field-label">永久金币</div>
<div class="field-label">{{ $t('common_add.permanentGold') }}</div>
<el-input v-model="addConsume.permanentGold" disabled /> <el-input v-model="addConsume.permanentGold" disabled />
</div> </div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="field"> <div class="field">
<div class="field-label">免费金币</div>
<div class="field-label">{{ $t('common_add.freeGold') }}</div>
<el-input v-model="addConsume.freeGold" disabled /> <el-input v-model="addConsume.freeGold" disabled />
</div> </div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="field"> <div class="field">
<div class="field-label">任务金币</div>
<div class="field-label">{{ $t('common_add.taskGold') }}</div>
<el-input v-model="addConsume.taskGold" disabled /> <el-input v-model="addConsume.taskGold" disabled />
</div> </div>
</el-col> </el-col>
@ -757,16 +768,16 @@ onMounted(async function () {
<el-icon :size="24" color="#FFD700"> <el-icon :size="24" color="#FFD700">
<WarnTriangleFilled /> <WarnTriangleFilled />
</el-icon> </el-icon>
<p>重复购买风险提示</p>
<p>{{ $t('common_add.prompt') }}</p>
</div> </div>
<!-- 记录 + 虚线分隔 --> <!-- 记录 + 虚线分隔 -->
<div> <div>
<el-divider border-style="dashed" /> <el-divider border-style="dashed" />
<p>检测到该用户近期有相似消费记录</p>
· {{ ReadCookiesTime }} 购买 {{ addConsume.goodsName.value }}(操作人: {{ adminData.adminName }})
<p>{{ $t('common_add.similarRechargeRecords') }}</p>
· {{ ReadCookiesTime }} {{ $t('common_add.buy') }} {{ addConsume.goodsName.value }}({{ $t('common_add.operator') }}: {{ adminData.adminName }})
</div> </div>
<div style="margin-top: 10px"> <div style="margin-top: 10px">
<p>是否继续操作</p>
<p>{{ $t('common_add.continueOperation') }}</p>
</div> </div>
</div> </div>
@ -774,8 +785,8 @@ onMounted(async function () {
<!-- 底部按钮居中 --> <!-- 底部按钮居中 -->
<template #footer> <template #footer>
<div class="dialog-footer-center"> <div class="dialog-footer-center">
<el-button @click="ConsumeDialogVisibleCancel"> </el-button>
<el-button type="primary" @click="ConsumeDialogVisibleContinue">确认购买</el-button>
<el-button @click="ConsumeDialogVisibleCancel">{{ $t('common.cancel') }}</el-button>
<el-button type="primary" @click="ConsumeDialogVisibleContinue">{{ $t('common.confirm') }}</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>

5
src/views/consume/gold/coinConsume.vue

@ -9,7 +9,7 @@
@click="navigateTo('coinConsumeDetail')" @click="navigateTo('coinConsumeDetail')"
v-if="hasDetail" v-if="hasDetail"
> >
金币消耗明细
{{ $t('consume.coinConsumeDetail') }}
</el-button> </el-button>
<el-button <el-button
@ -18,7 +18,7 @@
@click="navigateTo('addCoinConsume')" @click="navigateTo('addCoinConsume')"
v-if="hasAdd" v-if="hasAdd"
> >
新增消耗
{{ $t('consume.addCoinConsume') }}
</el-button> </el-button>
</el-button-group> </el-button-group>
</div> </div>
@ -33,6 +33,7 @@ import { useRoute, useRouter } from 'vue-router';
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useAdminStore } from "@/store/index.js"; import { useAdminStore } from "@/store/index.js";
import { hasMenuPermission, permissionMapping } from "@/utils/menuTreePermission.js"; import { hasMenuPermission, permissionMapping } from "@/utils/menuTreePermission.js";
import { useI18n } from 'vue-i18n';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();

127
src/views/consume/gold/coinConsumeDetail.vue

@ -9,6 +9,9 @@ import { storeToRefs } from 'pinia'
import { useAdminStore } from '@/store/index.js' import { useAdminStore } from '@/store/index.js'
const adminStore = useAdminStore() const adminStore = useAdminStore()
const { menuTree, flag } = storeToRefs(adminStore) const { menuTree, flag } = storeToRefs(adminStore)
//
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// //
// flag // flag
@ -104,28 +107,28 @@ const sortOrder = ref('')
const consumePlatform = [ const consumePlatform = [
{ {
value: '金币系统', value: '金币系统',
label: '金币系统'
label: t('consume.consumePlatforms.goldSystem')
}, },
{ {
value: 'HomilyChart', value: 'HomilyChart',
label: 'HomilyChart'
label: t('consume.consumePlatforms.HomilyChart')
}, },
{ {
value: 'HomilyLink', value: 'HomilyLink',
label: 'HomilyLink'
label: t('consume.consumePlatforms.HomilyLink')
}, },
{ {
value: 'ERP', value: 'ERP',
label: 'ERP'
label: t('consume.consumePlatforms.ERP')
}, },
{ {
value: '其他', value: '其他',
label: '其他'
label: t('consume.consumePlatforms.other')
}, },
{ {
value: '初始化金币', value: '初始化金币',
label: '初始化金币'
label: t('consume.consumePlatforms.initGold')
}, },
] ]
@ -211,7 +214,7 @@ const ConsumeSelectBy = async function (val) {
// //
if (!numberRegex.test(consumeUser.value.jwcode)) { if (!numberRegex.test(consumeUser.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t('elmessage.checkJwcodeFormat'))
return return
} }
} }
@ -453,7 +456,7 @@ const exportExcel = async function () {
} }
const res = await API({ url: '/export/exportConsume', data: params }) const res = await API({ url: '/export/exportConsume', data: params })
if (res.code === 200) { if (res.code === 200) {
ElMessage.success('导出成功')
ElMessage.success(t('elmessage.exportSuccess'))
} }
} }
const exportListVisible = ref(false) const exportListVisible = ref(false)
@ -479,11 +482,11 @@ const getExportList = async () => {
}); });
exportList.value = filteredData exportList.value = filteredData
} else { } else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t('elmessage.getExportListError'))
} }
} catch (error) { } catch (error) {
console.error('获取导出列表出错:', error) console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t('elmessage.getExportListError'))
} finally { } finally {
exportListLoading.value = false exportListLoading.value = false
} }
@ -496,7 +499,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName link.download = item.fileName
link.click() link.click()
} else { } else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t('elmessage.exportingInProgress'))
} }
} }
// //
@ -518,15 +521,15 @@ const getTagType = (state) => {
const getTagText = (state) => { const getTagText = (state) => {
switch (state) { switch (state) {
case 0: case 0:
return '待执行';
return t('elmessage.pendingExecution');
case 1: case 1:
return '执行中';
return t('elmessage.executing');
case 2: case 2:
return '执行完成';
return t('elmessage.executed');
case 3: case 3:
return '执行出错';
return t('elmessage.errorExecution');
default: default:
return '未知状态';
return t('elmessage.unknownStatus');
} }
} }
// //
@ -583,24 +586,24 @@ const getMarket = async function () {
<el-col style="margin-bottom: 1vh"> <el-col style="margin-bottom: 1vh">
<div class="select"> <div class="select">
<div class="selectRow"> <div class="selectRow">
<el-text class="text" size="large">精网号</el-text>
<el-input class="selectContent" v-model="consumeUser.jwcode" placeholder="请输入精网号" clearable />
<el-text class="text" size="large">{{ $t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="consumeUser.jwcode" :placeholder="$t('common.jwcodePlaceholder')" clearable />
</div> </div>
<div class="selectRow"> <div class="selectRow">
<el-text class="text" size="large">商品名称</el-text>
<el-select class="selectContent" v-model="consumeUser.goodsName" placeholder="请选择商品名称" clearable filterable>
<el-text class="text" size="large">{{ $t('common.goodsName') }}</el-text>
<el-select class="selectContent" v-model="consumeUser.goodsName" :placeholder="$t('common.goodsNamePlaceholder')" clearable filterable>
<el-option v-for="(item, index) in goods" :key="index" :label="item.label" :value="item" /> <el-option v-for="(item, index) in goods" :key="index" :label="item.label" :value="item" />
</el-select> </el-select>
</div> </div>
<div class="selectRow" style="width: 15vw;"> <div class="selectRow" style="width: 15vw;">
<el-text size="large">所属地区</el-text>
<el-cascader class="selectContent" style="width: 8vw;" v-model="selectedMarketPath" :options="market" placeholder="请选择所属地区"
<el-text size="large">{{ $t('common.market') }}</el-text>
<el-cascader class="selectContent" style="width: 8vw;" v-model="selectedMarketPath" :options="market" :placeholder="$t('common.marketPlaceholder')"
clearable @change="handleMarketChange" /> clearable @change="handleMarketChange" />
</div> </div>
<div class="selectRow" style="width: 15vw;"> <div class="selectRow" style="width: 15vw;">
<el-text size="large">消耗平台</el-text>
<el-select class="selectContent" v-model="consumeUser.payPlatform" placeholder="请选择消耗平台" clearable>
<el-text size="large">{{ $t('common.consumePlatform') }}</el-text>
<el-select class="selectContent" v-model="consumeUser.payPlatform" :placeholder="$t('common.consumePlatformPlaceholder')" clearable>
<el-option v-for="item in consumePlatform" :key="item.id" :label="item.label" :value="item.value" /> <el-option v-for="item in consumePlatform" :key="item.id" :label="item.label" :value="item.value" />
</el-select> </el-select>
</div> </div>
@ -612,9 +615,9 @@ const getMarket = async function () {
<el-col> <el-col>
<div class="select"> <div class="select">
<div class="selectRow" style="width: 36vw;"> <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" :default-time="defaultTime" :disabled-date="disabledDate" /> @change="handleDatePickerChange" :default-time="defaultTime" :disabled-date="disabledDate" />
<div v-if="false"> <div v-if="false">
@ -632,44 +635,44 @@ const getMarket = async function () {
</div> </div>
</div> </div>
<div class="selectRow" style="justify-content: flex-start;"> <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>
</div> </div>
</el-col> </el-col>
</el-card> </el-card>
<el-card class="card2"> <el-card class="card2">
<div class="goldStatistics"> <div class="goldStatistics">
消耗新币{{ format3(Math.abs(permanentGolds)) }}新币&nbsp;&nbsp;&nbsp;&nbsp;
总金币数{{ format3(Math.abs(permanentGolds + freeGolds + taskGolds)) }}&nbsp;&nbsp;&nbsp;&nbsp;
永久金币{{ format3(Math.abs(permanentGolds)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金币{{ format3(Math.abs(freeGolds)) }}&nbsp;&nbsp;&nbsp;&nbsp;
任务金币{{ format3(Math.abs(taskGolds)) }}
{{ $t('common.consumeSGD') }}{{ format3(Math.abs(permanentGolds)) }} {{ $t('common.SGD') }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.totalGoldCoin') }}{{ format3(Math.abs(permanentGolds + freeGolds + taskGolds)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.permanentGold') }}{{ format3(Math.abs(permanentGolds)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.freeGold') }}{{ format3(Math.abs(freeGolds)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.taskGold') }}{{ format3(Math.abs(taskGolds)) }}
</div> </div>
<div style="height: 65vh;"> <div style="height: 65vh;">
<el-table :data="tableData" style="height: 65vh" @sort-change="handleSortChange" <el-table :data="tableData" style="height: 65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }"> :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"> <template #default="scope">
<span>{{ <span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="姓名" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="jwcode" label="精网号" width="110px" fixed="left" />
<el-table-column prop="market" label="所属地区" width="110px" />
<el-table-column prop="orderCode" label="订单号" width="260px" show-overflow-tooltip />
<el-table-column prop="goodsName" label="商品名称" width="160px" show-overflow-tooltip />
<el-table-column prop="payPlatform" label="消耗平台" width="120px">
<el-table-column prop="name" :label="$t('common_list.name')" width="150px" fixed="left" show-overflow-tooltip />
<el-table-column prop="jwcode" :label="$t('common_list.jwcode')" width="110px" fixed="left" />
<el-table-column prop="market" :label="$t('common_list.market')" width="110px" />
<el-table-column prop="orderCode" :label="$t('common_list.orderNo')" width="260px" show-overflow-tooltip />
_list
<el-table-column prop="goodsName" :label="$t('common_list.goodsName')" width="160px" show-overflow-tooltip />
<el-table-column prop="payPlatform" :label="$t('common_list.consumePlatform')" width="120px">
<template #default="scope"> <template #default="scope">
{{ scope.row.payPlatform }} {{ scope.row.payPlatform }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="sumGold" label="消耗金币总数" width="120px">
<el-table-column prop="sumGold" :label="$t('common_list.consumeTotalGold')" width="120px">
<template #default="scope"> <template #default="scope">
{{ {{
(scope.row.taskGold + (scope.row.taskGold +
@ -679,32 +682,32 @@ const getMarket = async function () {
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="permanentGold" label="永久金币" sortable="“custom”" width="110px">
<el-table-column prop="permanentGold" :label="$t('common_list.permanentGold')" sortable="“custom”" width="110px">
<template #default="scope"> <template #default="scope">
{{ scope.row.permanentGold }} {{ scope.row.permanentGold }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="freeGold" label="免费金币" sortable="“custom”" width="110px">
<el-table-column prop="freeGold" :label="$t('common_list.freeGold')" sortable="“custom”" width="110px">
<template #default="scope"> <template #default="scope">
{{ scope.row.freeGold }} {{ scope.row.freeGold }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="taskGold" label="任务金币" sortable="“custom”" width="110px">
<el-table-column prop="taskGold" :label="$t('common_list.taskGold')" sortable="“custom”" width="110px">
<template #default="scope"> <template #default="scope">
{{ scope.row.taskGold }} {{ scope.row.taskGold }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" label="备注" width="200px" show-overflow-tooltip />
<el-table-column prop="isRefund" label="订单状态" width="200px" show-overflow-tooltip>
<el-table-column prop="remark" :label="$t('common_list.remark')" width="200px" show-overflow-tooltip />
<el-table-column prop="isRefund" :label="$t('common_list.orderStatus')" width="200px" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.isRefund == 0">正常</span>
<span v-else-if="scope.row.isRefund == 1">已退款</span>
<span v-else>未知状态</span>
<span v-if="scope.row.isRefund == 0">{{ $t('consume.normal') }}</span>
<span v-else-if="scope.row.isRefund == 1">{{ $t('consume.refunded') }}</span>
<span v-else>{{ $t('consume.unknown') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="adminName" label="提交人" width="110px" />
<el-table-column prop="createTime" label="消耗时间" sortable="custom" width="180px" />
<el-table-column prop="adminName" :label="$t('common_list.submitter')" width="110px" />
<el-table-column prop="createTime" :label="$t('common_list.consumeTime')" sortable="custom" width="180px" />
</el-table> </el-table>
</div> </div>
@ -717,33 +720,33 @@ const getMarket = async function () {
</el-card> </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 :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"> <template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'"> <el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }} {{ getTagText(scope.row.state) }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间">
<el-table-column prop="createTime" :label="$t('common_export.createTime')">
<template #default="scope"> <template #default="scope">
{{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }} {{ moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作">
<el-table-column :label="$t('common_export.operation')">
<template #default="scope"> <template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)" <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> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<template #footer> <template #footer>
<div class="dialog-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> </div>
</template> </template>
</el-dialog> </el-dialog>

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

@ -9,6 +9,10 @@ import { e } from 'mathjs';
const adminStore = useAdminStore(); const adminStore = useAdminStore();
const { adminData, menuTree } = storeToRefs(adminStore); const { adminData, menuTree } = storeToRefs(adminStore);
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const tableData = ref([]) const tableData = ref([])
const pagination = ref({ const pagination = ref({
@ -60,7 +64,7 @@ const cancel = function () {
const getRefund = async function () { const getRefund = async function () {
if (!addRefund.value.jwcode) { if (!addRefund.value.jwcode) {
ElMessage.error('请输入精网号')
ElMessage.error(t('elmessage.checkJwCode'))
return return
} }
addRefund.value.orderCode = '' addRefund.value.orderCode = ''
@ -69,7 +73,7 @@ const getRefund = async function () {
addRefund.value.freeGold = '' addRefund.value.freeGold = ''
addRefund.value.taskGold = '' addRefund.value.taskGold = ''
let type = null let type = null
if (addRefund.value.refundType === '商品退款') {
if (addRefund.value.refundType === t('refund.refundTypeOptions.商品退款')) {
type = 1 type = 1
} else { } else {
type = 0 type = 0
@ -100,11 +104,11 @@ const getRefund = async function () {
})) }))
console.log("看看订单号们", orderCodes.value) console.log("看看订单号们", orderCodes.value)
} else { } else {
ElMessage.info("未查询到相关订单")
ElMessage.info(t('elmessage.noOrder'))
} }
} catch (error) { } catch (error) {
console.log('goldDetail有错误', error) console.log('goldDetail有错误', error)
ElMessage.error('请求失败')
ElMessage.error(t('elmessage.requestFailed'))
tableData.value = [] tableData.value = []
pagination.value.total = 0 pagination.value.total = 0
} }
@ -113,11 +117,11 @@ const getRefund = async function () {
const add = async function () { const add = async function () {
// //
if (!canAdd.value) { if (!canAdd.value) {
ElMessage.error('无此权限')
ElMessage.error(t('elmessage.noPermission'))
return return
} }
try { try {
if (addRefund.value.refundType === '商品退款') {
if (addRefund.value.refundType === t('refund.refundTypeOptions.商品退款')) {
addRefund.value.type = 1 addRefund.value.type = 1
} else { } else {
addRefund.value.type = 0 addRefund.value.type = 0
@ -144,7 +148,7 @@ const add = async function () {
return return
} }
console.log('请求成功', result) console.log('请求成功', result)
ElMessage.success('添加成功')
ElMessage.success(t('elmessage.addSuccess'))
// //
cancel() cancel()
} catch (error) { } catch (error) {
@ -161,7 +165,7 @@ const addDisabled = ref(false)
const addBefore = () => { const addBefore = () => {
Ref.value.validate(async (valid) => { Ref.value.validate(async (valid) => {
if (valid) { if (valid) {
ElMessageBox.confirm('确认退款?')
ElMessageBox.confirm(t('elmessage.confirmRefund'))
.then(() => { .then(() => {
add() add()
}) })
@ -172,7 +176,7 @@ const addBefore = () => {
// //
ElMessage({ ElMessage({
type: 'error', type: 'error',
message: '请检查输入内容'
message: t('elmessage.checkInputContent')
}) })
} }
}) })
@ -182,32 +186,32 @@ const addBefore = () => {
const Ref = ref(null) const Ref = ref(null)
const validateJwCode = (rule, value, callback) => { const validateJwCode = (rule, value, callback) => {
if (!value) { if (!value) {
callback(new Error('精网号不能为空'));
callback(new Error(t('elmessage.noEmptyJwcode')));
return; return;
} }
if (/[^0-9]/.test(value)) { if (/[^0-9]/.test(value)) {
callback(new Error('精网号只能包含数字'));
callback(new Error(t('elmessage.limitDigitJwcode')));
return; return;
} }
callback(); callback();
}; };
const rules = reactive({ const rules = reactive({
jwcode: [{ required: true, validator: validateJwCode, trigger: 'blur' }], jwcode: [{ required: true, validator: validateJwCode, trigger: 'blur' }],
refundType: [{ required: true, message: '请选择退款类型', trigger: 'blur' }],
goodsName: [{ required: false, message: '请选择退款商品', trigger: 'blur' }],
refundType: [{ required: true, message: t('elmessage.checkRefundType'), trigger: 'blur' }],
goodsName: [{ required: false, message: t('elmessage.checkRefundGoods'), trigger: 'blur' }],
// //
orderCode: [{ required: true, message: '请输入订单号', trigger: 'blur' }],
taskGold: [{ required: true, message: '请输入任务金币', trigger: 'blur' }],
freeGold: [{ required: true, message: '请输入免费金币', trigger: 'blur' }],
orderCode: [{ required: true, message: t('elmessage.checkOrderNo'), trigger: 'blur' }],
taskGold: [{ required: true, message: t('elmessage.checkTaskGold'), trigger: 'blur' }],
freeGold: [{ required: true, message: t('elmessage.checkFreeGold'), trigger: 'blur' }],
permanentGold: [ permanentGold: [
{ required: true, message: '请输入永久金币', trigger: 'blur' }
{ required: true, message: t('elmessage.checkPermanentGold'), trigger: 'blur' }
], ],
sumGold: [ sumGold: [
{ required: true, message: '请选择付款方式', trigger: 'blur' },
{ required: true, message: t('elmessage.checkPayModel'), trigger: 'blur' },
{ {
validator: (rule, value) => { validator: (rule, value) => {
if (value === 0) { if (value === 0) {
return Promise.reject(new Error('总金币不能为0'))
return Promise.reject(new Error(t('elmessage.noTotalGoldZero')))
} }
return Promise.resolve() return Promise.resolve()
}, },
@ -223,7 +227,7 @@ const getUser = async function (jwcode) {
trimJwCode(); trimJwCode();
// //
if (!jwcode) { if (!jwcode) {
ElMessage.warning('精网号不能为空');
ElMessage.warning(t('elmessage.noEmptyJwcode'));
return; return;
} }
@ -248,7 +252,7 @@ const getUser = async function (jwcode) {
if (result.code === 0) { if (result.code === 0) {
ElMessage.error(result.msg); ElMessage.error(result.msg);
} else if (result.data === null) { } else if (result.data === null) {
ElMessage.error("用户不存在");
ElMessage.error(t('elmessage.noUser'));
} else { } else {
// 100 // 100
const processedData = { const processedData = {
@ -267,15 +271,15 @@ const getUser = async function (jwcode) {
} }
} catch (error) { } catch (error) {
console.log("请求失败", error); console.log("请求失败", error);
ElMessage.error("精网号错误");
ElMessage.error(t('elmessage.jwcodeError'));
} }
} }
// 退退 // 退退
const refundType = ref([ const refundType = ref([
{ value: '商品退款', label: '商品退款' },
{ value: '金币退款', label: '金币退款' }
{ value: '商品退款', label: t('refund.refundTypeOptions.商品退款') },
{ value: '金币退款', label: t('refund.refundTypeOptions.金币退款') }
]) ])
// //
@ -292,7 +296,7 @@ const handleOrderChange = (orderCode) => {
const order = tableData.value.find(item => item.orderCode === orderCode) const order = tableData.value.find(item => item.orderCode === orderCode)
if (order) { if (order) {
addRefund.value.goodsName = order.goodsName addRefund.value.goodsName = order.goodsName
if (addRefund.value.refundType === '金币退款') {
if (addRefund.value.refundType === t('refund.refundTypeOptions.金币退款')) {
selectedGoodsGold.value = { selectedGoodsGold.value = {
permanentGold: Number(order.permanentGold) || 0, permanentGold: Number(order.permanentGold) || 0,
freeGold: Number(order.freeGold) || 0, freeGold: Number(order.freeGold) || 0,
@ -391,13 +395,13 @@ const handleGoldInput = (type, value) => {
// //
const correctedValue = maxValue.toFixed(2); const correctedValue = maxValue.toFixed(2);
addRefund.value[type] = correctedValue; addRefund.value[type] = correctedValue;
ElMessage.warning('所填金额大于该类金币余额');
ElMessage.warning(t('elmessage.limitBalance'));
} }
if (inputValue < 0) { if (inputValue < 0) {
// 0 // 0
addRefund.value[type] = '0'; addRefund.value[type] = '0';
ElMessage.warning('不能输入负数');
ElMessage.warning(t('elmessage.noNegativeNumber'));
} }
} }
@ -436,73 +440,73 @@ onMounted(() =>{
<div class="left"> <div class="left">
<el-form :model="addRefund" ref="Ref" :rules="rules" label-width="auto" label-position="right" <el-form :model="addRefund" ref="Ref" :rules="rules" label-width="auto" label-position="right"
style="min-width: 420px" class="add-form"> style="min-width: 420px" class="add-form">
<el-form-item prop="jwcode" label="精网号">
<el-form-item prop="jwcode" :label="$t('common_add.jwcode')">
<el-input v-model="addRefund.jwcode" style="width: 220px" /> <el-input v-model="addRefund.jwcode" style="width: 220px" />
<el-button type="primary" @click="getUser(addRefund.jwcode)" style="margin-left: 20px">查询
<el-button type="primary" @click="getUser(addRefund.jwcode)" style="margin-left: 20px">{{ $t('common.search') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<el-form-item prop="refundType" label="退款类型">
<el-select v-model="addRefund.refundType" placeholder="请选择" style="width: 220px"
<el-form-item prop="refundType" :label="$t('common_add.refundType')">
<el-select v-model="addRefund.refundType" :placeholder="$t('common_add.refundTypePlaceholder')" style="width: 220px"
@change="getRefund(addRefund.jwcode)"> @change="getRefund(addRefund.jwcode)">
<el-option v-for="item in refundType" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in refundType" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="orderCode" label="订单号">
<el-select v-model="addRefund.orderCode" placeholder="请选择订单号" style="width: 220px;" clearable filterable
<el-form-item prop="orderCode" :label="$t('common_add.orderNo')">
<el-select v-model="addRefund.orderCode" :placeholder="$t('common_add.orderNoPlaceholder')" style="width: 220px;" clearable filterable
@change="handleOrderChange"> @change="handleOrderChange">
<el-option v-for="(item, index) in orderCodes" :key="index" :label="item.label" :value="item.value" /> <el-option v-for="(item, index) in orderCodes" :key="index" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="goodsName" label="商品名">
<el-form-item prop="goodsName" :label="$t('common_add.goodsName')">
<el-input v-model="addRefund.goodsName" style="width: 220px" disabled /> <el-input v-model="addRefund.goodsName" style="width: 220px" disabled />
</el-form-item> </el-form-item>
<el-form-item prop="refundModel" label="退款方式:">
<el-form-item prop="refundModel" :label="$t('common_add.refundModel')">
<el-radio-group v-model="addRefund.refundModel" @change="handleRefundModelChange"> <el-radio-group v-model="addRefund.refundModel" @change="handleRefundModelChange">
<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> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item prop="permanentGold" label="永久金币">
<el-form-item prop="permanentGold" :label="$t('common_add.permanentGold')">
<el-input v-model="addRefund.permanentGold" style="width: 220px" :disabled="addRefund.refundModel === 0" <el-input v-model="addRefund.permanentGold" style="width: 220px" :disabled="addRefund.refundModel === 0"
@input="handlePermanentGoldInput($event)" type="number"> @input="handlePermanentGoldInput($event)" type="number">
</el-input>&nbsp;&nbsp;
</el-input>&nbsp;&nbsp;{{ $t('common.') }}
<template> <template>
</template> </template>
</el-form-item> </el-form-item>
<el-form-item prop="freeGold" label="免费金币">
<el-form-item prop="freeGold" :label="$t('common_add.freeGold')">
<el-input v-model="addRefund.freeGold" style="float: left; width: 220px" <el-input v-model="addRefund.freeGold" style="float: left; width: 220px"
:disabled="addRefund.refundModel === 0" @input="handleFreeGoldInput($event)" type="number" /> :disabled="addRefund.refundModel === 0" @input="handleFreeGoldInput($event)" type="number" />
&nbsp;&nbsp;
&nbsp;&nbsp;{{ $t('common.') }}
</el-form-item> </el-form-item>
<div> <div>
<el-form-item prop="taskGold" label="任务金币">
<el-form-item prop="taskGold" :label="$t('common_add.taskGold')">
<el-input v-model="addRefund.taskGold" style="float: left; width: 220px" <el-input v-model="addRefund.taskGold" style="float: left; width: 220px"
:disabled="addRefund.refundModel === 0" @input="handleTaskGoldInput($event)" type="number" /> :disabled="addRefund.refundModel === 0" @input="handleTaskGoldInput($event)" type="number" />
&nbsp;&nbsp;
&nbsp;&nbsp;{{ $t('common.') }}
</el-form-item> </el-form-item>
</div> </div>
<div> <div>
<el-form-item prop="sumGold" label="退款金币总数">
<el-form-item prop="sumGold" :label="$t('common_add.refundGoldCoin')">
<el-input disabled v-model="addRefund.sumGold" style="width: 220px"> <el-input disabled v-model="addRefund.sumGold" style="width: 220px">
</el-input> </el-input>
</el-form-item> </el-form-item>
</div> </div>
<div> <div>
<el-form-item prop="remark" label="备注">
<el-form-item prop="remark" :label="$t('common_add.remark')">
<el-input v-model="addRefund.remark" style="width: 220px" :rows="3" maxlength="100" show-word-limit <el-input v-model="addRefund.remark" style="width: 220px" :rows="3" maxlength="100" show-word-limit
type="textarea" /> type="textarea" />
</el-form-item> </el-form-item>
</div> </div>
<el-button type="success" @click="cancel()" style="margin-left: 200px">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore" v-if="canAdd"> 提交</el-button>
<el-button type="success" @click="cancel()" style="margin-left: 200px">{{ $t('common.reset') }}</el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore" v-if="canAdd"> {{ $t('common.submit') }}</el-button>
</el-form> </el-form>
</div> </div>
</div> </div>
@ -512,13 +516,13 @@ onMounted(() =>{
<!-- 客户信息栏 --> <!-- 客户信息栏 -->
<el-card v-if="user.jwcode" class="customer-info"> <el-card v-if="user.jwcode" class="customer-info">
<el-form :model="user" label-width="auto" label-position="left"> <el-form :model="user" label-width="auto" label-position="left">
<span style="margin-left: 30%;font-size: larger;">客户信息</span>
<span style="margin-left: 30%;font-size: larger;">{{ $t('common_add_user.customerInfo') }}</span>
<el-row style="margin-top: 1vh;"> <el-row style="margin-top: 1vh;">
<div class="line"> <div class="line">
<span style="width:5vw;">姓名</span>
<span style="width:5vw;">{{ $t('common_add_user.name') }}</span>
<span style="width:10vw;">{{ user.name }}</span> <span style="width:10vw;">{{ user.name }}</span>
<span style="width:10vw;">当前金币总数</span>
<span style="width:10vw;">{{ $t('common_add_user.currentGoldCoinTotal') }}</span>
<span style="color: #2fa1ff;width: 25vw;" v-if="user.nowSumGold !== undefined">{{ <span style="color: #2fa1ff;width: 25vw;" v-if="user.nowSumGold !== undefined">{{
user.nowSumGold user.nowSumGold
}}</span> }}</span>
@ -526,30 +530,30 @@ onMounted(() =>{
</el-row> </el-row>
<el-row style="height: 3vh;width: 100%;"> <el-row style="height: 3vh;width: 100%;">
<span style="height:3vh;color: #b1b1b1;font-size: small;margin-left:50%;" <span style="height:3vh;color: #b1b1b1;font-size: small;margin-left:50%;"
v-if="user.nowPermanentGold !== undefined">(永久金币:{{
v-if="user.nowPermanentGold !== undefined">({{ $t('common_add_user.permanentGold') }}:{{
user.nowPermanentGold user.nowPermanentGold
}}; }};
免费金币:{{ user.nowFreeGold }};
任务金币:{{ user.nowTaskGold }})</span>
{{ $t('common_add_user.freeGold') }}:{{ user.nowFreeGold }};
{{ $t('common_add_user.taskGold') }}:{{ user.nowTaskGold }})</span>
</el-row> </el-row>
<el-row> <el-row>
<!-- 第二行精网号 + 消费次数 --> <!-- 第二行精网号 + 消费次数 -->
<div class="line"> <div class="line">
<span style="width:5vw;">精网号</span>
<span style="width:5vw;">{{ $t('common_add_user.jwcode') }}</span>
<span style="width: 10vw;">{{ user.jwcode }}</span> <span style="width: 10vw;">{{ user.jwcode }}</span>
<span style="width:10vw;">消费次数</span>
<span style="width:10vw;">{{ $t('common_add_user.consumptionTimes') }}</span>
<span style="width: 10vw;color: #2fa1ff;">{{ user.consumeNum }}</span> <span style="width: 10vw;color: #2fa1ff;">{{ user.consumeNum }}</span>
</div> </div>
</el-row> </el-row>
<el-row> <el-row>
<span style="height:3vh;color: #b1b1b1;font-size: small;margin-left:50%;">(仅统计2025-01-01后的数据)</span>
<span style="height:3vh;color: #b1b1b1;font-size: small;margin-left:50%;">({{ $t('common_add_user.onlyStatisticsDataAfter20250101') }}2025-01-01)</span>
</el-row> </el-row>
<!-- 第四行所属门店 --> <!-- 第四行所属门店 -->
<el-row> <el-row>
<div class="line"> <div class="line">
<span style="width:5vw;">所属门店</span>
<span style="width:5vw;">{{ $t('common_add_user.store') }}</span>
<span style="width: 10vw;">{{ user.market }}</span> <span style="width: 10vw;">{{ user.market }}</span>
</div> </div>
</el-row> </el-row>
@ -560,38 +564,38 @@ onMounted(() =>{
<div> <div>
<el-card class="card" v-if="tableData.length > 0"> <el-card class="card" v-if="tableData.length > 0">
<el-table :data="tableData" style="height:43vh;width:50vw"> <el-table :data="tableData" style="height:43vh;width:50vw">
<el-table-column type="index" label="序号" width="80">
<el-table-column type="index" :label="$t('refund.id')" width="80">
<template #default="scope"> <template #default="scope">
<span>{{ <span>{{
scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="type" label="类型" width="100">
<el-table-column prop="type" :label="$t('refund.type')" width="100">
<template #default="{ row }"> <template #default="{ row }">
{{ row.type === 0 ? '充值' : '消费' }}
{{ row.type === 0 ? $t('refund.recharge') : $t('refund.consume') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="goodsName" label="商品名称" width="120" show-overflow-tooltip />
<el-table-column prop="orderCode" label="订单号" width="200px" show-overflow-tooltip />
<el-table-column prop="permanentGold" label="永久金币" width="120">
<el-table-column prop="goodsName" :label="$t('refund.productName')" width="120" show-overflow-tooltip />
<el-table-column prop="orderCode" :label="$t('refund.orderCode')" width="200px" show-overflow-tooltip />
<el-table-column prop="permanentGold" :label="$t('refund.permanentGold')" width="120">
<template #default="{ row }"> <template #default="{ row }">
{{ row.permanentGold }} {{ row.permanentGold }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="freeGold" label="免费金币" width="120">
<el-table-column prop="freeGold" :label="$t('refund.freeGold')" width="120">
<template #default="{ row }"> <template #default="{ row }">
{{ row.freeGold }} {{ row.freeGold }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="taskGold" label="任务金币" width="120">
<el-table-column prop="taskGold" :label="$t('refund.taskGold')" width="120">
<template #default="{ row }"> <template #default="{ row }">
{{ row.taskGold }} {{ row.taskGold }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="isRefund" label="允许退款" width="120">
<el-table-column prop="isRefund" :label="$t('refund.isRefund')" width="120">
<template #default="{ row }"> <template #default="{ row }">
{{ row.isRefund === 1 ? '否' : '是' }}
{{ row.isRefund === 1 ? $t('refund.no') : $t('refund.yes') }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

5
src/views/refund/gold/coinRefund.vue

@ -8,7 +8,7 @@
@click="navigateTo('coinRefundDetail')" @click="navigateTo('coinRefundDetail')"
:disabled="!hasDetail" :disabled="!hasDetail"
v-if="hasDetail"> v-if="hasDetail">
金币退款明细
{{ $t('refund.coinRefundDetail') }}
</el-button> </el-button>
<!-- 切换后状态显示 primary 样式否则是默认样式 --> <!-- 切换后状态显示 primary 样式否则是默认样式 -->
<el-button <el-button
@ -17,7 +17,7 @@
@click="navigateTo('addCoinRefund')" @click="navigateTo('addCoinRefund')"
:disabled="!hasAdd" :disabled="!hasAdd"
v-if="hasAdd"> v-if="hasAdd">
新增退款
{{ $t('refund.addCoinRefund') }}
</el-button> </el-button>
</el-button-group> </el-button-group>
<!-- 渲染子路由组件 --> <!-- 渲染子路由组件 -->
@ -33,6 +33,7 @@ import {useRoute, useRouter} from 'vue-router';
import {storeToRefs} from "pinia"; import {storeToRefs} from "pinia";
import {useAdminStore} from "@/store/index.js"; import {useAdminStore} from "@/store/index.js";
import {hasMenuPermission, permissionMapping} from "@/utils/menuTreePermission.js"; import {hasMenuPermission, permissionMapping} from "@/utils/menuTreePermission.js";
import { useI18n } from 'vue-i18n';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();

114
src/views/refund/gold/coinRefundDetail.vue

@ -10,6 +10,9 @@ import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { findMenuById, permissionMapping } from "@/utils/menuTreePermission.js" import { findMenuById, permissionMapping } from "@/utils/menuTreePermission.js"
import dayjs from "dayjs"; import dayjs from "dayjs";
//
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const adminStore = useAdminStore(); const adminStore = useAdminStore();
const { adminData, menuTree, flag } = storeToRefs(adminStore); const { adminData, menuTree, flag } = storeToRefs(adminStore);
@ -49,7 +52,7 @@ const trimJwCode = () => {
if (!isNaN(numeric)) { if (!isNaN(numeric)) {
refundUser.value.jwcode = numeric; refundUser.value.jwcode = numeric;
} else { } else {
ElMessage.error("精网号格式不正确,请输入数字");
ElMessage.error(t("elmessage.limitDigitJwcode"));
} }
} }
} }
@ -112,7 +115,7 @@ const getRefundTypes = async function () {
refundType.value = result.data.map(item => ({ value: item, label: item })); refundType.value = result.data.map(item => ({ value: item, label: item }));
} else { } else {
console.error('退款类型数据格式错误', result) console.error('退款类型数据格式错误', result)
ElMessage.error('退款类型数据格式错误,请联系管理员')
ElMessage.error(t("elmessage.refundTypeError"))
} }
console.log('退款类型', refundType.value) console.log('退款类型', refundType.value)
} catch (error) { } catch (error) {
@ -125,7 +128,7 @@ const getRefundTypes = async function () {
const getSelectBy = async function (val) { const getSelectBy = async function (val) {
if (!canLook.value) { if (!canLook.value) {
console.log('无此权限', canLook.value) console.log('无此权限', canLook.value)
ElMessage.error('无此权限')
ElMessage.error(t("elmessage.noPermission"))
return return
} }
try { try {
@ -159,7 +162,7 @@ const getSelectBy = async function (val) {
// //
if (!numberRegex.test(refundUser.value.jwcode)) { if (!numberRegex.test(refundUser.value.jwcode)) {
ElMessage.error('请检查精网号格式')
ElMessage.error(t("elmessage.checkJwcodeFormat"))
// //
return return
} }
@ -378,13 +381,13 @@ const exportExcel = async function () {
try { try {
const res = await API({ url: '/export/exportRefund', data: params }) const res = await API({ url: '/export/exportRefund', data: params })
if (res.code === 200) { if (res.code === 200) {
ElMessage.success('导出成功')
ElMessage.success(t("elmessage.exportSuccess"))
} else { } else {
ElMessage.error(res.message || '导出失败,请稍后重试')
ElMessage.error(res.message || t("elmessage.exportFailed"))
} }
} catch (error) { } catch (error) {
console.log('请求失败', error) console.log('请求失败', error)
ElMessage.error('导出失败,请稍后重试')
ElMessage.error(t("elmessage.exportFailed"))
} }
} }
@ -411,11 +414,11 @@ const getExportList = async () => {
}); });
exportList.value = filteredData exportList.value = filteredData
} else { } else {
ElMessage.error(result.msg || '获取导出列表失败')
ElMessage.error(result.msg || t("elmessage.getExportListError"))
} }
} catch (error) { } catch (error) {
console.error('获取导出列表出错:', error) console.error('获取导出列表出错:', error)
ElMessage.error('获取导出列表失败,请稍后重试')
ElMessage.error(t("elmessage.getExportListFailed"))
} finally { } finally {
exportListLoading.value = false exportListLoading.value = false
} }
@ -428,7 +431,7 @@ const downloadExportFile = (item) => {
link.download = item.fileName link.download = item.fileName
link.click() link.click()
} else { } else {
ElMessage.warning('文件还在导出中,请稍后再试')
ElMessage.warning(t("elmessage.exportingInProgress"))
} }
} }
// //
@ -515,25 +518,25 @@ const getMarket = async function () {
<el-col style="margin-bottom: 1vh;"> <el-col style="margin-bottom: 1vh;">
<div class="select"> <div class="select">
<div class="selectRow"> <div class="selectRow">
<el-text class="text" size="large">精网号</el-text>
<el-input class="selectContent" v-model="refundUser.jwcode" placeholder="请输入精网号" style="width: 10vw;"
<el-text class="text" size="large">{{ $t('common.jwcode') }}</el-text>
<el-input class="selectContent" v-model="refundUser.jwcode" :placeholder="$t('common.jwcodePlaceholder')" style="width: 10vw;"
clearable /> clearable />
</div> </div>
<div class="selectRow"> <div class="selectRow">
<el-text class="text" size="large">商品名称</el-text>
<el-select class="selectContent" v-model="refundUser.goodsName" placeholder="请选择商品名称" style="width: 10vw;"
<el-text class="text" size="large">{{ $t('common.goodsName') }}</el-text>
<el-select class="selectContent" v-model="refundUser.goodsName" :placeholder="$t('common.goodsNamePlaceholder')" style="width: 10vw;"
clearable filterable> clearable filterable>
<el-option v-for="item in goods" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in goods" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</div> </div>
<div class="selectRow"> <div class="selectRow">
<el-text class="text" size="large">所属地区</el-text>
<el-cascader class="selectContent" v-model="selectedMarketPath" :options="market" placeholder="请选择所属地区"
<el-text class="text" size="large">{{ $t('common.market') }}</el-text>
<el-cascader class="selectContent" v-model="selectedMarketPath" :options="market" :placeholder="$t('common.marketPlaceholder')"
clearable style="width:10vw" @change="handleMarketChange" /> clearable style="width:10vw" @change="handleMarketChange" />
</div> </div>
<div class="selectRow" style="width: 12vw;"> <div class="selectRow" style="width: 12vw;">
<el-text size="large">退款类型</el-text>
<el-select class="selectContent" v-model="refundUser.refundType" placeholder="请选择退款类型" style="width: 10vw"
<el-text size="large">{{ $t('common.refundType') }}</el-text>
<el-select class="selectContent" v-model="refundUser.refundType" :placeholder="$t('common.refundTypePlaceholder')" style="width: 10vw"
clearable> clearable>
<el-option v-for="item in refundType" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in refundType" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
@ -544,27 +547,28 @@ const getMarket = async function () {
<el-col> <el-col>
<div class="select"> <div class="select">
<div class="selectRow" style="width: 35vw"> <div class="selectRow" style="width: 35vw">
<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: 20vw;" @change="handleDatePickerChange"
<el-text class="text" size="large">{{ $t('common.refundTime') }}</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: 20vw;" @change="handleDatePickerChange"
:default-time="defaultTime" :disabled-date="disabledDate" /> :default-time="defaultTime" :disabled-date="disabledDate" />
<el-button @click="getToday()" style="margin-left: 0.3vw" <el-button @click="getToday()" style="margin-left: 0.3vw"
:type="activeTimeRange === 'today' ? 'primary' : ''"> :type="activeTimeRange === 'today' ? 'primary' : ''">
{{ $t('common.today') }}
</el-button> </el-button>
<el-button @click="getYesterday()" style="margin-left: 0.3vw" <el-button @click="getYesterday()" style="margin-left: 0.3vw"
:type="activeTimeRange === 'yesterday' ? 'primary' : ''">
:type="activeTimeRange === 'yesterday' ? 'primary' : ''">
{{ $t('common.yesterday') }}
</el-button> </el-button>
<el-button @click="get7Days()" style="margin-left: 0.3vw" <el-button @click="get7Days()" style="margin-left: 0.3vw"
:type="activeTimeRange === '7days' ? 'primary' : ''"> :type="activeTimeRange === '7days' ? 'primary' : ''">
近7天
{{ $t('common.last7Days') }}
</el-button> </el-button>
</div> </div>
<div class="selectRow" style="justify-content: flex-start;"> <div class="selectRow" style="justify-content: flex-start;">
<el-button type="primary" @click="search()" v-if="canLook">查询</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()" v-if="canLook">{{ $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>
</div> </div>
</el-col> </el-col>
@ -572,16 +576,16 @@ const getMarket = async function () {
<el-card class="card2"> <el-card class="card2">
<div class="goldStatistics"> <div class="goldStatistics">
退款金币总数{{ format3(Math.abs(sumGolds).toFixed(2)) }}&nbsp;&nbsp;&nbsp;&nbsp;
永久金币{{ format3(Math.abs(permanentGolds).toFixed(2)) }}&nbsp;&nbsp;&nbsp;&nbsp;
免费金币{{ format3(Math.abs(freeGolds).toFixed(2)) }}&nbsp;&nbsp;&nbsp;&nbsp;
任务金币{{ format3(Math.abs(taskGolds).toFixed(2)) }}
{{ $t('common.refundGoldCoin') }}{{ format3(Math.abs(sumGolds).toFixed(2)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.permanentGold') }}{{ format3(Math.abs(permanentGolds).toFixed(2)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.freeGold') }}{{ format3(Math.abs(freeGolds).toFixed(2)) }}&nbsp;&nbsp;&nbsp;&nbsp;
{{ $t('common.taskGold') }}{{ format3(Math.abs(taskGolds).toFixed(2)) }}
</div> </div>
<!-- 设置表格容器的高度和滚动样式 --> <!-- 设置表格容器的高度和滚动样式 -->
<div style="height: 65vh; "> <div style="height: 65vh; ">
<el-table :data="tableData" style="height: 65vh" @sort-change="handleSortChange" <el-table :data="tableData" style="height: 65vh" @sort-change="handleSortChange"
:row-style="{ height: '50px' }"> :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"> <template #default="scope">
<span>{{ <span>{{
scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
@ -589,24 +593,24 @@ const getMarket = async function () {
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="姓名" fixed="left" width="130px" show-overflow-tooltip />
<el-table-column prop="jwcode" label="精网号" fixed="left" width="110px" />
<el-table-column prop="market" label="所属地区" width="110px" />
<el-table-column prop="orderCode" label="订单号" width="260px" show-overflow-tooltip />
<el-table-column prop="goodsName" label="商品名称" width="110px" show-overflow-tooltip />
<el-table-column prop="refundType" label="退款类型" width="100px" />
<el-table-column prop="refundModel" label="退款方式" width="110px">
<el-table-column prop="name" :label="$t('common_list.name')" fixed="left" width="130px" show-overflow-tooltip />
<el-table-column prop="jwcode" :label="$t('common_list.jwcode')" fixed="left" width="110px" />
<el-table-column prop="market" :label="$t('common_list.market')" width="110px" />
<el-table-column prop="orderCode" :label="$t('common_list.orderNo')" width="260px" show-overflow-tooltip />
<el-table-column prop="goodsName" :label="$t('common_list.goodsName')" width="110px" show-overflow-tooltip />
<el-table-column prop="refundType" :label="$t('common_list.refundType')" width="100px" />
<el-table-column prop="refundModel" :label="$t('common_list.refundModel')" width="110px">
<template #default="scope"> <template #default="scope">
{{ scope.row.refundModel === 0 ? '全部退款' : scope.row.refundModel === 1 ? '部分退款' : '' }}
{{ scope.row.refundModel === 0 ? $t('common_list.refundModelAll') : scope.row.refundModel === 1 ? $t('common_list.refundModelPart') : '' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="sumGold" label="退款金币总数" width="150px" sortable="custom" />
<el-table-column prop="permanentGold" label="永久金币" width="110px" sortable="custom" />
<el-table-column prop="freeGold" sortable="custom" label="免费金币" width="110px" />
<el-table-column prop="taskGold" sortable="custom" label="任务金币" width="110px" />
<el-table-column prop="remark" label="退款原因" width="160px" show-overflow-tooltip />
<el-table-column prop="adminName" label="提交人" width="100px" />
<el-table-column prop="auditTime" sortable="custom" label="退款时间" width="180px">
<el-table-column prop="sumGold" :label="$t('common_list.refundGoldCoin')" width="150px" sortable="custom" />
<el-table-column prop="permanentGold" :label="$t('common_list.permanentGold')" width="110px" sortable="custom" />
<el-table-column prop="freeGold" :label="$t('common_list.freeGold')" width="110px" sortable="custom" />
<el-table-column prop="taskGold" :label="$t('common_list.taskGold')" width="110px" sortable="custom" />
<el-table-column prop="remark" :label="$t('common_list.remark')" width="160px" show-overflow-tooltip />
<el-table-column prop="adminName" :label="$t('common_list.submitter')" width="100px" />
<el-table-column prop="auditTime" :label="$t('common_list.refundTime')" width="180px" sortable="custom">
<template #default="scope"> <template #default="scope">
{{ moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') }} {{ moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
@ -623,33 +627,33 @@ const getMarket = async function () {
</el-card> </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 :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"> <template #default="scope">
<el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'"> <el-tag :type="getTagType(scope.row.state)" :effect="scope.row.state === 3 ? 'light' : 'plain'">
{{ getTagText(scope.row.state) }} {{ getTagText(scope.row.state) }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="auditTime" label="创建时间">
<el-table-column prop="auditTime" :label="$t('common_export.createTime')">
<template #default="scope"> <template #default="scope">
{{ moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') }} {{ moment(scope.row.auditTime).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作">
<el-table-column :label="$t('common_export.operation')">
<template #default="scope"> <template #default="scope">
<el-button type="primary" size="small" @click="downloadExportFile(scope.row)" <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> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<template #footer> <template #footer>
<div class="dialog-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> </div>
</template> </template>
</el-dialog> </el-dialog>

Loading…
Cancel
Save