Browse Source

feat: 金币充值消耗二次检查

lihui/feature-20250815155204-金币优化
lihui 15 hours ago
parent
commit
7c33282cdf
  1. 313
      src/views/consume/gold/addCoinConsume.vue
  2. 13
      src/views/recharge/gold/addCoinRecharge.vue

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

@ -1,8 +1,12 @@
<script setup>
import { onMounted, reactive, ref, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {onMounted, reactive, ref, watch} from "vue";
import {ElIcon, ElMessage, ElMessageBox} from "element-plus";
import {Plus, WarnTriangleFilled} from '@element-plus/icons-vue'
import moment from "moment";
import request from "@/util/http.js"
import Cookies from 'js-cookie';
import dayjs from "dayjs";
//
const trimJwCode = () => {
if (addConsume.value.jwcode) {
@ -62,12 +66,12 @@ const Ref = ref(null);
//
const rules = reactive({
jwcode: [
{ required: true, message: "请输入精网号", trigger: "blur" },
{required: true, message: "请输入精网号", trigger: "blur"},
// { type: 'number', message: "", trigger: "blur" }
],
goodsName: [{ required: true, message: "请选择商品", trigger: "blur" }],
goodsName: [{required: true, message: "请选择商品", trigger: "blur"}],
sumGold: [
{ required: true, message: "消耗金币总数不能为空", trigger: "blur" },
{required: true, message: "消耗金币总数不能为空", trigger: "blur"},
{
validator: (rule, value, callback) => {
// 00.10
@ -177,7 +181,6 @@ function validateInput() {
}
//
const totalAvailableGold = (user.value.nowSumGold)
if (user.value.jwcode && sumGold > totalAvailableGold) {
@ -195,10 +198,10 @@ function calculateCoins(sumGold) {
console.log("消耗金币计算函数:计算金币", sumGold);
const parsedSumGold = parseFloat(sumGold);
if (isNaN(parsedSumGold) || parsedSumGold <= 0 || !user.value.jwcode) {
return { free: 0, permanent: 0, task: 0 };
return {free: 0, permanent: 0, task: 0};
}
const { nowFreeGold, nowPermanentGold, nowTaskGold } = user.value;
const {nowFreeGold, nowPermanentGold, nowTaskGold} = user.value;
let remaining = parsedSumGold;
let freeUsed = 0, permanentUsed = 0, taskUsed = 0;
@ -224,9 +227,18 @@ function calculateCoins(sumGold) {
addConsume.value.permanentGold = permanentUsed;
addConsume.value.taskGold = taskUsed;
return { free: freeUsed, permanent: permanentUsed, task: taskUsed };
return {free: freeUsed, permanent: permanentUsed, task: taskUsed};
}
// cookie key
const WriteCookies = ref(null)
// cookie value
const WriteCookiesTime = ref(null)
// cookie key
const ReadCookies = ref(null)
// cookie value
const ReadCookiesTime = ref(null)
//
const add = async function () {
try {
@ -238,6 +250,14 @@ const add = async function () {
calculateCoins(addConsume.value.sumGold);
console.log("addConsume.value", addConsume.value)
// jwcode
// jwcode:permanentGold:freeGold
WriteCookies.value = `coinConsume:${addConsume.value.jwcode}:${addConsume.value.goodsName}}`
//value
WriteCookiesTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
// cookies,jwcodekeyvaluejwcode1
Cookies.set(WriteCookies.value, WriteCookiesTime.value, {expires: 1, path: '/'});
// POST
addDisabled.value = true
const result = await request({
@ -316,29 +336,66 @@ function resetForm() {
}
}
//
const ConsumeDialogVisible = ref(false);
//
const ConsumeDialogVisiblehandleClose = () => {
ConsumeDialogVisible.value = false;
//
resetForm()
user.value = {}
};
// 使cookie
const ConsumeDialogVisibleContinue = () => {
ConsumeDialogVisible.value = false;
add();
};
const ConsumeDialogVisibleCancel = () => {
ConsumeDialogVisible.value = false
//todo
/* resetForm()
user.value = {}*/
};
//
const proceedWithConsume = () => {
ElMessageBox.confirm('确认充值?')
.then(() => {
add();
console.log('添加成功');
})
.catch(() => {
console.log('取消添加');
});
};
//
const addBefore = () => {
Ref.value.validate(async (valid) => {
if (valid) {
ElMessageBox.confirm("确认添加?")
.then(() => {
console.log("这里是jwcode", addConsume.value.jwcode)
add();
console.log("添加成功",);
addConsume.value = {};
})
.catch(() => {
console.log("取消添加");
});
} else {
//
// cookie
if (!valid) {
ElMessage({
type: "error",
message: "请检查输入内容",
type: 'error',
message: '请检查输入内容'
});
return;
}
ReadCookies.value = `coinConsume:${addConsume.value.jwcode}:${addConsume.value.goodsName}}`
// cookie
const cookie = Cookies.get(ReadCookies.value)
console.log("time", WriteCookiesTime.value)
//
ReadCookiesTime.value = moment(cookie).format('YYYY-MM-DD HH:mm:ss')
if (cookie) {
ConsumeDialogVisible.value = true;
} else {
proceedWithConsume();
}
});
};
//
const getUser = async function (jwcode) {
try {
@ -358,7 +415,7 @@ const getUser = async function (jwcode) {
// POST
const result = await request({
url: "/user/selectUser",
data: { jwcode }
data: {jwcode}
});
console.log("请求成功", result);
@ -385,7 +442,7 @@ const getUser = async function (jwcode) {
if (addConsume.value.sumGold) {
const parsedSumGold = parseFloat(addConsume.value.sumGold);
if (!isNaN(parsedSumGold) && parsedSumGold > 0) {
const { free, permanent, task } = calculateCoins(parsedSumGold);
const {free, permanent, task} = calculateCoins(parsedSumGold);
addConsume.value.freeGold = free;
addConsume.value.permanentGold = permanent;
addConsume.value.taskGold = task;
@ -437,20 +494,20 @@ const getGoods = async function () {
//
watch(
() => addConsume.value.sumGold,
(newValue) => {
const parsedNewValue = parseFloat(newValue);
if (!isNaN(parsedNewValue) && parsedNewValue > 0) {
const { free, permanent, task } = calculateCoins(parsedNewValue);
addConsume.value.freeGold = free;
addConsume.value.permanentGold = permanent;
addConsume.value.taskGold = task;
} else {
addConsume.value.freeGold = null;
addConsume.value.permanentGold = null;
addConsume.value.taskGold = null;
() => addConsume.value.sumGold,
(newValue) => {
const parsedNewValue = parseFloat(newValue);
if (!isNaN(parsedNewValue) && parsedNewValue > 0) {
const {free, permanent, task} = calculateCoins(parsedNewValue);
addConsume.value.freeGold = free;
addConsume.value.permanentGold = permanent;
addConsume.value.taskGold = task;
} else {
addConsume.value.freeGold = null;
addConsume.value.permanentGold = null;
addConsume.value.taskGold = null;
}
}
}
);
/*
@ -466,41 +523,42 @@ onMounted(async function () {
<template>
<div>
<el-form :model="addConsume" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px;" label-position="right" class="add-form">
<el-form-item prop="jwcode" label="精网号" >
<el-input v-model="addConsume.jwcode" style="width: 200px" />
<el-form :model="addConsume" ref="Ref" :rules="rules" label-width="auto" style="max-width: 600px;"
label-position="right" class="add-form">
<el-form-item prop="jwcode" label="精网号">
<el-input v-model="addConsume.jwcode" style="width: 200px"/>
<el-button type="primary" @click="getUser(addConsume.jwcode)" style="margin-left: 10px">查询
</el-button>
</el-form-item>
<el-form-item prop="goodsName" label="商品名称">
<el-select v-model="addConsume.goodsName" placeholder="请选择商品" style="width: 200px">
<el-option v-for="item in goods" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="sumGold" label="消耗金币总数">
<el-input v-model="addConsume.sumGold" style="width: 100px" @input="validateInput()"
@change="calculateCoins(addConsume.sumGold)" />
</el-form-item>
<el-form-item prop="goodsName" label="商品名称">
<el-select v-model="addConsume.goodsName" placeholder="请选择商品" style="width: 200px">
<el-option v-for="item in goods" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item prop="sumGold" label="消耗金币总数">
<el-input v-model="addConsume.sumGold" style="width: 100px" @input="validateInput()"
@change="calculateCoins(addConsume.sumGold)"/>
</el-form-item>
<!-- 三类金币自动计算禁用状态不可编辑 -->
<el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="addConsume.permanentGold" disabled style="width: 100px">
<template #default="scope">{{ scope.row.permanentGold }}</template>
</el-input>
<p style="margin-right: 0px">&nbsp;&nbsp;</p>
</el-form-item>
<el-form-item prop="freeCoin" label="免费金币">
<el-input disabled v-model="addConsume.freeGold" style="width: 100px" />
<p style="margin-right: 0px">&nbsp;&nbsp;</p>
</el-form-item>
<el-form-item prop="taskGold" label="任务金币">
<el-input disabled v-model="addConsume.taskGold" style="width: 100px" />
<p style="margin-right: 20px">&nbsp;&nbsp;</p>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-input v-model="addConsume.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
type="textarea" />
</el-form-item>
<el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="addConsume.permanentGold" disabled style="width: 100px">
<template #default="scope">{{ scope.row.permanentGold }}</template>
</el-input>
<p style="margin-right: 0px">&nbsp;&nbsp;</p>
</el-form-item>
<el-form-item prop="freeCoin" label="免费金币">
<el-input disabled v-model="addConsume.freeGold" style="width: 100px"/>
<p style="margin-right: 0px">&nbsp;&nbsp;</p>
</el-form-item>
<el-form-item prop="taskGold" label="任务金币">
<el-input disabled v-model="addConsume.taskGold" style="width: 100px"/>
<p style="margin-right: 20px">&nbsp;&nbsp;</p>
</el-form-item>
<el-form-item prop="remark" label="备注">
<el-input v-model="addConsume.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
type="textarea"/>
</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-form>
@ -529,7 +587,7 @@ onMounted(async function () {
</el-form-item>
<el-form-item style="margin-top: -23px">
<span style="display: inline; white-space: nowrap; color: #b1b1b1"
v-if="user.historyPermanentGold !== undefined">(永久金币:{{ user.historyPermanentGold }};免费金币:{{
v-if="user.historyPermanentGold !== undefined">(永久金币:{{ user.historyPermanentGold }};免费金币:{{
(user.historyFreeGold)
}};任务金币:{{ user.historyTaskGold }})</span>
</el-form-item>
@ -545,13 +603,15 @@ onMounted(async function () {
</el-col>
<el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ user.nowSumGold
}}</span>
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
user.nowSumGold
}}</span>
</el-form-item>
<!-- 金币详情独立显示 -->
<el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
<span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold }};
user.nowPermanentGold
}};
免费金币:{{ user.nowFreeGold }};
任务金币:{{ user.nowTaskGold }})</span>
</el-form-item>
@ -590,6 +650,80 @@ onMounted(async function () {
</el-form>
</el-card>
<el-dialog
v-model="ConsumeDialogVisible"
title="操作确认"
:before-close="ConsumeDialogVisiblehandleClose"
:close-on-click-modal="false"
width="480px"
>
<!-- 内容整体居中且收窄 -->
<div class="confirm-body">
<!-- 用户信息 -->
<div>
<div class="field-label">用户信息</div>
<el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled/>
</div>
<!-- 活动名称 -->
<div class="field">
<div class="field-label">商品名称</div>
<el-input v-model="addConsume.goodsName" disabled/>
</div>
<!--金币总数 -->
<div class="field">
<div class="field-label">金币总数</div>
<el-input v-model="addConsume.sumGold" disabled/>
</div>
<!-- 金币详细信息同一行左右排列 -->
<el-row :gutter="20" class="coins-row">
<el-col :span="8">
<div class="field">
<div class="field-label">永久金币</div>
<el-input v-model="addConsume.permanentGold" disabled/>
</div>
</el-col>
<el-col :span="8">
<div class="field">
<div class="field-label">免费金币</div>
<el-input v-model="addConsume.freeGold" disabled/>
</div>
</el-col>
<el-col :span="8">
<div class="field">
<div class="field-label">任务金币</div>
<el-input v-model="addConsume.taskGold" disabled/>
</div>
</el-col>
</el-row>
<!-- 风险提示 -->
<div style="display: flex; align-items: center; margin-top: 20px;">
<el-icon :size="24" color="#FFD700">
<WarnTriangleFilled/>
</el-icon>
<p>重复购买风险提示</p>
</div>
<!-- 记录 + 虚线分隔 -->
<div>
<el-divider border-style="dashed"/>
<p>检测到该用户近期有相似消费记录</p>
· {{ ReadCookiesTime }} 购买 {{ addConsume.goodsName }}(操作人: {{ adminData.adminName }})
</div>
<div style="margin-top: 10px">
<p>是否继续操作</p>
</div>
</div>
<!-- 底部按钮居中 -->
<template #footer>
<div class="dialog-footer-center">
<el-button @click="ConsumeDialogVisibleCancel"> </el-button>
<el-button type="primary" @click="ConsumeDialogVisibleContinue">确认充值</el-button>
</div>
</template>
</el-dialog>
</div>
<!-- 金币消耗明细的布局------------------------------------------------------- -->
@ -605,11 +739,13 @@ onMounted(async function () {
p {
margin: 0px;
}
.add-form {
margin-top: 50px;
max-width: 50%;
float: left;
}
.el-form-item {
margin-left: 50px;
}
@ -620,10 +756,41 @@ p {
height: 50px;
display: block;
}
.customer-info {
max-width: 60%;
}
</style>
<style>
/* 标题居中 */
.el-dialog__header {
text-align: center;
}
.confirm-body {
width: 420px;
margin: 0 auto;
}
/* 字段块与标签样式 */
.field {
margin-bottom: 14px;
}
.field-label {
font-size: 14px;
color: #606266;
margin-bottom: 6px;
}
/* 金币行紧凑 */
.coins-row .field {
margin-bottom: 0;
}
/* 底部按钮居中 */
.dialog-footer-center {
display: flex;
justify-content: center;
gap: 12px;
}
</style>

13
src/views/recharge/gold/addCoinRecharge.vue

@ -6,7 +6,6 @@ import axios from 'axios'
import API from '@/util/http.js'
import moment from 'moment'
import Cookies from 'js-cookie';
import dayjs from "dayjs";
// fixedAdminId
// const fixedAdminId = 1;
@ -105,7 +104,7 @@ const add = async function () {
console.log('开始添加充值信息', recharge.value)
// jwcode
// jwcode:permanentGold:freeGold
WriteCookies.value = `${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
WriteCookies.value = `coinRecharge:${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
//value
WriteCookiesTime.value = recharge.value.payTime
// cookies,jwcodekeyvaluejwcode1
@ -231,7 +230,7 @@ const addBefore = () => {
// cookie
// jwcode:permanentGold:freeGold
ReadCookies.value = `${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
ReadCookies.value = `coinRecharge:${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
// cookie
const cookie = Cookies.get(ReadCookies.value)
@ -809,14 +808,14 @@ onMounted(() => {
title="操作确认"
:before-close="RechargeDialogVisiblehandleClose"
:close-on-click-modal="false"
width="600px"
width="480px"
>
<!-- 内容整体居中且收窄 -->
<div class="confirm-body">
<!-- 用户信息 -->
<div>
<div class="field-label">用户信息</div>
<el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled/>
</div>
<!-- 活动名称 -->
<div class="field">
@ -940,13 +939,13 @@ p {
.confirm-body {
width: 500px;
width: 420px;
margin: 0 auto;
}
/* 字段块与标签样式 */
.field {
margin-bottom: 14px;
margin-top: 10px;
}
.field-label {

Loading…
Cancel
Save