Browse Source

Merge branch 'milestone-20250815-金币优化' of http://39.101.133.168:8807/huangqizhen/gold-vue into zhangyong/feature-20250815160302-金币优化

youhua/chongzhi
ZhangYong 2 months ago
parent
commit
a18609e79a
  1. 10
      package-lock.json
  2. 1
      package.json
  3. 12
      src/router/index.js
  4. 2
      src/views/audit/bean/beanAudit.vue
  5. 236
      src/views/consume/gold/addCoinConsume.vue
  6. 25
      src/views/consume/gold/coinConsumeDetail.vue
  7. 13
      src/views/permissions/rolePermission.vue
  8. 6
      src/views/recharge/bean/addBeanRecharge.vue
  9. 2
      src/views/recharge/bean/beanOnlineRecharge.vue
  10. 0
      src/views/recharge/bean/beanRecharge.vue
  11. 2
      src/views/recharge/bean/beanSystemRecharge.vue
  12. 313
      src/views/recharge/gold/addCoinRecharge.vue
  13. 37
      src/views/recharge/gold/coinRechargeDetail.vue
  14. 0
      src/views/refund/bean/beanRefund.vue
  15. 21
      src/views/refund/gold/coinRefundDetail.vue
  16. 2
      src/views/usergold/bean/userbean.vue
  17. 16
      src/views/usergold/gold/clientCountBalance.vue
  18. 22
      src/views/usergold/gold/clientCountDetail.vue

10
package-lock.json

@ -19,6 +19,7 @@
"dayjs-plugin-utc": "^0.1.2", "dayjs-plugin-utc": "^0.1.2",
"echarts": "^5.5.1", "echarts": "^5.5.1",
"element-plus": "^2.8.8", "element-plus": "^2.8.8",
"js-cookie": "^3.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mathjs": "^14.0.1", "mathjs": "^14.0.1",
"moment": "^2.30.1", "moment": "^2.30.1",
@ -4004,6 +4005,15 @@
"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",

1
package.json

@ -23,6 +23,7 @@
"dayjs-plugin-utc": "^0.1.2", "dayjs-plugin-utc": "^0.1.2",
"echarts": "^5.5.1", "echarts": "^5.5.1",
"element-plus": "^2.8.8", "element-plus": "^2.8.8",
"js-cookie": "^3.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mathjs": "^14.0.1", "mathjs": "^14.0.1",
"moment": "^2.30.1", "moment": "^2.30.1",

12
src/router/index.js

@ -55,7 +55,7 @@ const routes = [
},{ },{
path: 'beanAudit', path: 'beanAudit',
name: "beanAudit", name: "beanAudit",
component: () => import("../views/audit/beanAudit.vue"),
component: () => import("../views/audit/bean/beanAudit.vue"),
meta: {permissionId: [54,55]} meta: {permissionId: [54,55]}
}, },
@ -158,28 +158,28 @@ const routes = [
{ {
path: '/beanRecharge', path: '/beanRecharge',
name: "beanRecharge", name: "beanRecharge",
component: () => import("../views/recharge/beanRecharge.vue"),
component: () => import("../views/recharge/bean/beanRecharge.vue"),
// redirect: '/coinRecharge/add', // redirect: '/coinRecharge/add',
children: [ children: [
// 金豆新增充值 // 金豆新增充值
{ {
path: 'add', path: 'add',
name: "addBeanRecharge", name: "addBeanRecharge",
component: () => import("../views/recharge/addBeanRecharge.vue"),
component: () => import("../views/recharge/bean/addBeanRecharge.vue"),
meta: {permissionId: 46} // 对应"提交金豆充值"id=46 meta: {permissionId: 46} // 对应"提交金豆充值"id=46
}, },
// 金豆系统充值 // 金豆系统充值
{ {
path: 'system', path: 'system',
name: "beanSystemRecharge", name: "beanSystemRecharge",
component: () => import("../views/recharge/beanSystemRecharge.vue"),
component: () => import("../views/recharge/bean/beanSystemRecharge.vue"),
meta: {permissionId: 47} // 对应"查看金豆系统充值明细"id=47 meta: {permissionId: 47} // 对应"查看金豆系统充值明细"id=47
}, },
// 金豆线上充值 // 金豆线上充值
{ {
path: 'online', path: 'online',
name: "beanOnlineRecharge", name: "beanOnlineRecharge",
component: () => import("../views/recharge/beanOnlineRecharge.vue"),
component: () => import("../views/recharge/bean/beanOnlineRecharge.vue"),
meta: {permissionId: 48} // 对应"查看金豆线上充值明细"id=48 meta: {permissionId: 48} // 对应"查看金豆线上充值明细"id=48
} }
] ]
@ -237,7 +237,7 @@ const routes = [
{ {
path: 'userbean', path: 'userbean',
name: "userbean", name: "userbean",
component: () => import("../views/usergold/userbean.vue"),
component: () => import("../views/usergold/bean/userbean.vue"),
meta:{ permissionId: 45 } meta:{ permissionId: 45 }
}, },

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

@ -96,7 +96,7 @@
<script setup> <script setup>
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import API from '@/util/http'
import API from '@/util/http.js'
import moment from 'moment' import moment from 'moment'
import { useAdminStore } from "@/store/index.js"; import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";

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

@ -1,8 +1,12 @@
<script setup> <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 moment from "moment";
import request from "@/util/http.js" import request from "@/util/http.js"
import Cookies from 'js-cookie';
import dayjs from "dayjs";
// //
const trimJwCode = () => { const trimJwCode = () => {
if (addConsume.value.jwcode) { if (addConsume.value.jwcode) {
@ -62,12 +66,12 @@ const Ref = ref(null);
// //
const rules = reactive({ const rules = reactive({
jwcode: [ jwcode: [
{ required: true, message: "请输入精网号", trigger: "blur" },
{required: true, message: "请输入精网号", trigger: "blur"},
// { type: 'number', message: "", trigger: "blur" } // { type: 'number', message: "", trigger: "blur" }
], ],
goodsName: [{ required: true, message: "请选择商品", trigger: "blur" }],
goodsName: [{required: true, message: "请选择商品", trigger: "blur"}],
sumGold: [ sumGold: [
{ required: true, message: "消耗金币总数不能为空", trigger: "blur" },
{required: true, message: "消耗金币总数不能为空", trigger: "blur"},
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
// 00.10 // 00.10
@ -177,7 +181,6 @@ function validateInput() {
} }
// //
const totalAvailableGold = (user.value.nowSumGold) const totalAvailableGold = (user.value.nowSumGold)
if (user.value.jwcode && sumGold > totalAvailableGold) { if (user.value.jwcode && sumGold > totalAvailableGold) {
@ -195,10 +198,10 @@ function calculateCoins(sumGold) {
console.log("消耗金币计算函数:计算金币", sumGold); console.log("消耗金币计算函数:计算金币", sumGold);
const parsedSumGold = parseFloat(sumGold); const parsedSumGold = parseFloat(sumGold);
if (isNaN(parsedSumGold) || parsedSumGold <= 0 || !user.value.jwcode) { 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 remaining = parsedSumGold;
let freeUsed = 0, permanentUsed = 0, taskUsed = 0; let freeUsed = 0, permanentUsed = 0, taskUsed = 0;
@ -224,9 +227,18 @@ function calculateCoins(sumGold) {
addConsume.value.permanentGold = permanentUsed; addConsume.value.permanentGold = permanentUsed;
addConsume.value.taskGold = taskUsed; 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 () { const add = async function () {
try { try {
@ -238,6 +250,14 @@ const add = async function () {
calculateCoins(addConsume.value.sumGold); calculateCoins(addConsume.value.sumGold);
console.log("addConsume.value", addConsume.value) 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 // POST
addDisabled.value = true addDisabled.value = true
const result = await request({ const result = await request({
@ -316,29 +336,65 @@ function resetForm() {
} }
} }
//
const addBefore = () => {
Ref.value.validate(async (valid) => {
if (valid) {
ElMessageBox.confirm("确认添加?")
//
const ConsumeDialogVisible = ref(false);
//
const ConsumeDialogVisiblehandleClose = () => {
ConsumeDialogVisible.value = false;
//
resetForm()
user.value = {}
};
// 使cookie
const ConsumeDialogVisibleContinue = () => {
ConsumeDialogVisible.value = false;
add();
};
const ConsumeDialogVisibleCancel = () => {
ConsumeDialogVisible.value = false
resetForm()
user.value = {}
};
//
const proceedWithConsume = () => {
ElMessageBox.confirm('确认充值?')
.then(() => { .then(() => {
console.log("这里是jwcode", addConsume.value.jwcode)
add(); add();
console.log("添加成功",);
addConsume.value = {};
console.log('添加成功');
}) })
.catch(() => { .catch(() => {
console.log("取消添加");
console.log('取消添加');
}); });
} else {
//
};
//
const addBefore = () => {
Ref.value.validate(async (valid) => {
// cookie
if (!valid) {
ElMessage({ 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) { const getUser = async function (jwcode) {
try { try {
@ -358,7 +414,7 @@ const getUser = async function (jwcode) {
// POST // POST
const result = await request({ const result = await request({
url: "/user/selectUser", url: "/user/selectUser",
data: { jwcode }
data: {jwcode}
}); });
console.log("请求成功", result); console.log("请求成功", result);
@ -385,7 +441,7 @@ const getUser = async function (jwcode) {
if (addConsume.value.sumGold) { if (addConsume.value.sumGold) {
const parsedSumGold = parseFloat(addConsume.value.sumGold); const parsedSumGold = parseFloat(addConsume.value.sumGold);
if (!isNaN(parsedSumGold) && parsedSumGold > 0) { if (!isNaN(parsedSumGold) && parsedSumGold > 0) {
const { free, permanent, task } = calculateCoins(parsedSumGold);
const {free, permanent, task} = calculateCoins(parsedSumGold);
addConsume.value.freeGold = free; addConsume.value.freeGold = free;
addConsume.value.permanentGold = permanent; addConsume.value.permanentGold = permanent;
addConsume.value.taskGold = task; addConsume.value.taskGold = task;
@ -441,7 +497,7 @@ watch(
(newValue) => { (newValue) => {
const parsedNewValue = parseFloat(newValue); const parsedNewValue = parseFloat(newValue);
if (!isNaN(parsedNewValue) && parsedNewValue > 0) { if (!isNaN(parsedNewValue) && parsedNewValue > 0) {
const { free, permanent, task } = calculateCoins(parsedNewValue);
const {free, permanent, task} = calculateCoins(parsedNewValue);
addConsume.value.freeGold = free; addConsume.value.freeGold = free;
addConsume.value.permanentGold = permanent; addConsume.value.permanentGold = permanent;
addConsume.value.taskGold = task; addConsume.value.taskGold = task;
@ -466,20 +522,21 @@ onMounted(async function () {
<template> <template>
<div> <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 type="primary" @click="getUser(addConsume.jwcode)" style="margin-left: 10px">查询
</el-button> </el-button>
</el-form-item> </el-form-item>
<el-form-item prop="goodsName" label="商品名称"> <el-form-item prop="goodsName" label="商品名称">
<el-select v-model="addConsume.goodsName" placeholder="请选择商品" style="width: 200px"> <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-option v-for="item in goods" :key="item.value" :label="item.label" :value="item.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="sumGold" label="消耗金币总数"> <el-form-item prop="sumGold" label="消耗金币总数">
<el-input v-model="addConsume.sumGold" style="width: 100px" @input="validateInput()" <el-input v-model="addConsume.sumGold" style="width: 100px" @input="validateInput()"
@change="calculateCoins(addConsume.sumGold)" />
@change="calculateCoins(addConsume.sumGold)"/>
</el-form-item> </el-form-item>
<!-- 三类金币自动计算禁用状态不可编辑 --> <!-- 三类金币自动计算禁用状态不可编辑 -->
@ -490,16 +547,16 @@ onMounted(async function () {
<p style="margin-right: 0px">&nbsp;&nbsp;</p> <p style="margin-right: 0px">&nbsp;&nbsp;</p>
</el-form-item> </el-form-item>
<el-form-item prop="freeCoin" label="免费金币"> <el-form-item prop="freeCoin" label="免费金币">
<el-input disabled v-model="addConsume.freeGold" style="width: 100px" />
<el-input disabled v-model="addConsume.freeGold" style="width: 100px"/>
<p style="margin-right: 0px">&nbsp;&nbsp;</p> <p style="margin-right: 0px">&nbsp;&nbsp;</p>
</el-form-item> </el-form-item>
<el-form-item prop="taskGold" label="任务金币"> <el-form-item prop="taskGold" label="任务金币">
<el-input disabled v-model="addConsume.taskGold" style="width: 100px" />
<el-input disabled v-model="addConsume.taskGold" style="width: 100px"/>
<p style="margin-right: 20px">&nbsp;&nbsp;</p> <p style="margin-right: 20px">&nbsp;&nbsp;</p>
</el-form-item> </el-form-item>
<el-form-item prop="remark" label="备注"> <el-form-item prop="remark" label="备注">
<el-input v-model="addConsume.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit <el-input v-model="addConsume.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
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="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="primary" :disabled="addDisabled" @click="addBefore" style="margin-top:10px"> 提交</el-button>
@ -545,13 +602,15 @@ onMounted(async function () {
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px"> <el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ user.nowSumGold
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
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">(永久金币:{{ <span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold }};
user.nowPermanentGold
}};
免费金币:{{ user.nowFreeGold }}; 免费金币:{{ user.nowFreeGold }};
任务金币:{{ user.nowTaskGold }})</span> 任务金币:{{ user.nowTaskGold }})</span>
</el-form-item> </el-form-item>
@ -590,6 +649,80 @@ onMounted(async function () {
</el-form> </el-form>
</el-card> </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> </div>
<!-- 金币消耗明细的布局------------------------------------------------------- --> <!-- 金币消耗明细的布局------------------------------------------------------- -->
@ -605,11 +738,13 @@ onMounted(async function () {
p { p {
margin: 0px; margin: 0px;
} }
.add-form { .add-form {
margin-top: 50px; margin-top: 50px;
max-width: 50%; max-width: 50%;
float: left; float: left;
} }
.el-form-item { .el-form-item {
margin-left: 50px; margin-left: 50px;
} }
@ -620,10 +755,41 @@ p {
height: 50px; height: 50px;
display: block; display: block;
} }
.customer-info { .customer-info {
max-width: 60%; max-width: 60%;
} }
</style> </style>
<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> </style>

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

@ -36,6 +36,10 @@ const defaultTime = [
/* /*
====================数据================================= ====================数据=================================
*/ */
//
const showEmployeeData = ref(false)
// //
const adminData = ref({}) const adminData = ref({})
// //
@ -205,7 +209,8 @@ const ConsumeSelectBy = async function (val) {
consumeUser: { consumeUser: {
...consumeUser.value, ...consumeUser.value,
sortField: sortField.value, sortField: sortField.value,
sortOrder: sortOrder.value
sortOrder: sortOrder.value,
flag: showEmployeeData.value ? 0 : 1 // flag
} }
} }
}) })
@ -214,7 +219,7 @@ const ConsumeSelectBy = async function (val) {
// //
// detail.value // detail.value
const detailWithoutSort = {...consumeUser.value}
const detailWithoutSort = {...consumeUser.value,flag: showEmployeeData.value ? 0 : 1}
delete detailWithoutSort.sortField delete detailWithoutSort.sortField
delete detailWithoutSort.sortOrder delete detailWithoutSort.sortOrder
@ -226,6 +231,7 @@ const ConsumeSelectBy = async function (val) {
totalGoldSearch.value.market = consumeUser.value.market totalGoldSearch.value.market = consumeUser.value.market
totalGoldSearch.value.goodsName = consumeUser.value.goodsName totalGoldSearch.value.goodsName = consumeUser.value.goodsName
totalGoldSearch.value.jwcode = consumeUser.value.jwcode totalGoldSearch.value.jwcode = consumeUser.value.jwcode
totalGoldSearch.value.flag = showEmployeeData.value ? 1 : 0 // flag
// //
const resultTotalGold = await request({ const resultTotalGold = await request({
// url: '/consume/statsGold', // url: '/consume/statsGold',
@ -431,7 +437,9 @@ const exportExcel = async function () {
endTime: consumeUser.value.endTime || '', endTime: consumeUser.value.endTime || '',
goodsName: consumeUser.value.goodsName || '', goodsName: consumeUser.value.goodsName || '',
sortField: sortField.value || '', sortField: sortField.value || '',
sortOrder: sortOrder.value || ''
sortOrder: sortOrder.value || '',
flag: showEmployeeData.value ? 0 : 1 // flag
} }
} }
const res = await API({url: '/export/exportConsume', data: params}) const res = await API({url: '/export/exportConsume', data: params})
@ -572,7 +580,7 @@ const getMarket = async function () {
<el-input v-model="consumeUser.jwcode" placeholder="请输入精网号" style="width: 150px" clearable/> <el-input v-model="consumeUser.jwcode" placeholder="请输入精网号" style="width: 150px" clearable/>
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">商品名称</el-text> <el-text class="mx-1" size="large">商品名称</el-text>
<el-select v-model="consumeUser.goodsName" placeholder="请选择商品名称" style="width: 180px" <el-select v-model="consumeUser.goodsName" placeholder="请选择商品名称" style="width: 180px"
@ -582,7 +590,7 @@ const getMarket = async function () {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<el-text class="mx-1" size="large">所属地区</el-text> <el-text class="mx-1" size="large">所属地区</el-text>
<el-cascader <el-cascader
v-model="selectedMarketPath" v-model="selectedMarketPath"
@ -593,7 +601,7 @@ const getMarket = async function () {
@change="handleMarketChange" @change="handleMarketChange"
/> />
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">消耗平台</el-text> <el-text class="mx-1" size="large">消耗平台</el-text>
<el-select v-model="consumeUser.payPlatform" placeholder="请选择消耗平台" <el-select v-model="consumeUser.payPlatform" placeholder="请选择消耗平台"
@ -603,6 +611,11 @@ const getMarket = async function () {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="3">
<div class="head-card-element">
<el-checkbox v-model="showEmployeeData" @click="search()">员工数据</el-checkbox>
</div>
</el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">

13
src/views/permissions/rolePermission.vue

@ -347,8 +347,8 @@ const getLists = async function () {
addRole.value.market = '' addRole.value.market = ''
} }
} else { } else {
ElMessage.error('该上级角色无属地区')
console.log('该上级角色无属地区');
ElMessage.error('该上级角色无属地区')
console.log('该上级角色无属地区');
} }
console.log('addRoleMarket.value', addRoleMarket.value); console.log('addRoleMarket.value', addRoleMarket.value);
@ -629,7 +629,7 @@ const Rolerules = reactive({
{min: 2, max: 20, message: '角色名称长度应在2-20个字符之间', trigger: 'blur'} {min: 2, max: 20, message: '角色名称长度应在2-20个字符之间', trigger: 'blur'}
], ],
market: [ market: [
{required: true, message: '请选择属地区', trigger: 'change'}
{required: true, message: '请选择属地区', trigger: 'change'}
], ],
grade: [ grade: [
{required: true, message: '请输入优先级', trigger: 'blur'}, {required: true, message: '请输入优先级', trigger: 'blur'},
@ -768,10 +768,11 @@ onMounted(async function () {
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="market" label="属地区:" required>
<el-select v-model="addRole.market" placeholder="请选择属地区" style="width: 220px" clearable >
<el-form-item prop="market" label="属地区:" required>
<el-select v-model="addRole.market" placeholder="请选择属地区" style="width: 220px" clearable >
<el-option v-for="item in addRoleMarket" :key="item" :label="item" :value="item"/> <el-option v-for="item in addRoleMarket" :key="item" :label="item" :value="item"/>
</el-select> </el-select>
<text>(此地区无实际意义仅用于各分部负责人查看其地区角色)</text>
</el-form-item> </el-form-item>
<el-form-item prop="checkedKeys" label="权限列表:" required> <el-form-item prop="checkedKeys" label="权限列表:" required>
<el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" <el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id"
@ -814,7 +815,7 @@ onMounted(async function () {
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="market" label="地区" required> <el-form-item prop="market" label="地区" required>
<el-input v-model="permissionEditRoleObj.market" placeholder="请输入属地区" style="width: 220px" disabled/>
<el-input v-model="permissionEditRoleObj.market" placeholder="请输入属地区" style="width: 220px" disabled/>
</el-form-item> </el-form-item>
<el-form-item prop="checkedKeys" label="权限列表:" required> <el-form-item prop="checkedKeys" label="权限列表:" required>
<el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" ref="treeRef" <el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" ref="treeRef"

6
src/views/recharge/addBeanRecharge.vue → src/views/recharge/bean/addBeanRecharge.vue

@ -4,9 +4,9 @@ import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue' import { Plus } from '@element-plus/icons-vue'
import axios from 'axios' import axios from 'axios'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import API from '@/util/http'
import { uploadFile } from '@/util/request';
import request from '@/util/http'
import API from '@/util/http.js'
import { uploadFile } from '@/util/request.js';
import request from '@/util/http.js'
import moment from 'moment' import moment from 'moment'
import { e, range, re } from 'mathjs' import { e, range, re } from 'mathjs'
import { utils, read } from 'xlsx' import { utils, read } from 'xlsx'

2
src/views/recharge/beanOnlineRecharge.vue → src/views/recharge/bean/beanOnlineRecharge.vue

@ -5,7 +5,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { AiFillRead } from 'vue-icons-plus/ai' import { AiFillRead } from 'vue-icons-plus/ai'
import axios from 'axios' import axios from 'axios'
import moment from 'moment' import moment from 'moment'
import API from '@/util/http'
import API from '@/util/http.js'
const defaultTime = [ const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 2, 1, 23, 59, 59), new Date(2000, 2, 1, 23, 59, 59),

0
src/views/recharge/beanRecharge.vue → src/views/recharge/bean/beanRecharge.vue

2
src/views/recharge/beanSystemRecharge.vue → src/views/recharge/bean/beanSystemRecharge.vue

@ -5,7 +5,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { AiFillRead } from 'vue-icons-plus/ai' import { AiFillRead } from 'vue-icons-plus/ai'
import axios from 'axios' import axios from 'axios'
import moment from 'moment' import moment from 'moment'
import API from '@/util/http'
import API from '@/util/http.js'
const selectData = ref({ const selectData = ref({
jwcode: '', jwcode: '',

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

@ -1,15 +1,11 @@
<script setup> <script setup>
import { ref, onMounted, reactive, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import {onMounted, reactive, ref} from 'vue'
import {ElIcon, ElMessage, ElMessageBox} from 'element-plus'
import {Plus, WarnTriangleFilled} from '@element-plus/icons-vue'
import axios from 'axios' import axios from 'axios'
import { ElMessageBox } from 'element-plus'
import API from '@/util/http.js' import API from '@/util/http.js'
import { uploadFile } from '@/util/request.js';
import moment from 'moment' import moment from 'moment'
import { range, re } from 'mathjs'
import { utils, read } from 'xlsx'
import throttle from 'lodash/throttle'
import Cookies from 'js-cookie';
// fixedAdminId // fixedAdminId
// const fixedAdminId = 1; // const fixedAdminId = 1;
@ -74,11 +70,19 @@ const recharge = ref({
remark: '', // remark remark: '', // remark
rechargeRatio: '' rechargeRatio: ''
}) })
// 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 () { const add = async function () {
try { try {
const formattedRecharge = { ...recharge.value }
const formattedRecharge = {...recharge.value}
// 100 // 100
if (formattedRecharge.permanentGold) { if (formattedRecharge.permanentGold) {
@ -98,7 +102,15 @@ const add = async function () {
} }
console.log('开始添加充值信息', recharge.value) console.log('开始添加充值信息', recharge.value)
// jwcode
// jwcode:permanentGold:freeGold
WriteCookies.value = `coinRecharge:${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
//value
WriteCookiesTime.value = recharge.value.payTime
// cookies,jwcodekeyvaluejwcode1
Cookies.set(WriteCookies.value, WriteCookiesTime.value, {expires: 1, path: '/'});
// POST // POST
addDisabled.value = true
const result = await API({ const result = await API({
url: '/recharge/add', url: '/recharge/add',
data: formattedRecharge data: formattedRecharge
@ -121,61 +133,118 @@ const add = async function () {
} }
} }
//
//
const RechargeDialogVisible = ref(false);
//
const RechargeDialogVisiblehandleClose = () => {
RechargeDialogVisible.value = false;
//
deleteRecharge()
user.value = {}
};
// 使cookie
const RechargeDialogVisibleContinue = () => {
RechargeDialogVisible.value = false;
add();
};
const RechargeDialogVisibleCancel = () => {
RechargeDialogVisible.value = false
deleteRecharge()
user.value = {}
};
//
const proceedWithRecharge = () => {
ElMessageBox.confirm('确认充值?')
.then(() => {
add();
console.log('充值成功');
})
.catch(() => {
console.log('取消充值');
});
};
//
const addBefore = () => { const addBefore = () => {
if(!recharge.value.permanentGold){
recharge.value.permanentGold ='0'
//
if (!recharge.value.permanentGold) {
recharge.value.permanentGold = '0';
} }
if(!recharge.value.freeGold){
recharge.value.freeGold ='0'
if (!recharge.value.freeGold) {
recharge.value.freeGold = '0';
} }
//
Ref.value.validate(async (valid) => { Ref.value.validate(async (valid) => {
if (valid) {
if (!valid) {
ElMessage({
type: 'error',
message: '请检查输入内容'
});
return;
}
// 0
if (Number(recharge.value.permanentGold) === 0 && Number(recharge.value.freeGold) === 0) { if (Number(recharge.value.permanentGold) === 0 && Number(recharge.value.freeGold) === 0) {
ElMessage({ ElMessage({
type: 'error', type: 'error',
message: '永久金币和免费金币不能同时为0' message: '永久金币和免费金币不能同时为0'
})
return
});
return;
} }
if (recharge.value.rateName == null || recharge.value.rateName == '' || recharge.value.rateName == undefined) {
//
if (!recharge.value.rateName) {
ElMessage({ ElMessage({
type: 'error', type: 'error',
message: '请选择币种' message: '请选择币种'
})
return
});
return;
} }
if (recharge.value.money == null || recharge.value.money == '' || recharge.value.money == undefined) {
//
if (!recharge.value.money) {
ElMessage({ ElMessage({
type: 'error', type: 'error',
message: '请输入充值金额' message: '请输入充值金额'
})
return
});
return;
} }
// rateId
const selectedRate = rateName.find(item => item.value === recharge.value.rateName)
// rateId
const selectedRate = rateName.find(item => item.value === recharge.value.rateName);
if (selectedRate) { if (selectedRate) {
recharge.value.rateId = selectedRate.rateId
recharge.value.rateId = selectedRate.rateId;
} }
ElMessageBox.confirm('确认充值?')
.then(() => {
addDisabled.value = true
add()
console.log('充值成功')
})
.catch(() => {
console.log('取消充值')
})
//
if (!user.value.jwcode) {
ElMessage.warning('请先查询用户信息')
return
}
// cookie
// jwcode:permanentGold:freeGold
ReadCookies.value = `coinRecharge:${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
// cookie
const cookie = Cookies.get(ReadCookies.value)
console.log("time", WriteCookiesTime.value)
//
ReadCookiesTime.value = moment(cookie).format('YYYY-MM-DD HH:mm:ss')
console.log('cookie', cookie)
// cookie
if (cookie) {
RechargeDialogVisible.value = true;
} else { } else {
//
ElMessage({
type: 'error',
message: '请检查输入内容'
})
proceedWithRecharge();
} }
})
}
});
};
// //
// //
@ -194,12 +263,12 @@ const rules = reactive({
callback(); callback();
}, trigger: 'blur' }, trigger: 'blur'
}], }],
activity: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
activity: [{required: true, message: '请选择活动名称', trigger: 'blur'}],
permanentGold: [ permanentGold: [
{ required: true, message: '请输入永久金币数', trigger: 'change' },
{required: true, message: '请输入永久金币数', trigger: 'change'},
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
if(!value){
if (!value) {
value = '0' value = '0'
} }
// //
@ -237,10 +306,10 @@ const rules = reactive({
} }
], ],
freeGold: [ freeGold: [
{ required: true, message: '请输入免费金币数', trigger: 'change' },
{required: true, message: '请输入免费金币数', trigger: 'change'},
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
if(!value){
if (!value) {
value = '0' value = '0'
} }
// //
@ -284,7 +353,7 @@ const rules = reactive({
}], }],
money: [ money: [
{ required: true, message: '请输入充值金额', trigger: 'blur' },
{required: true, message: '请输入充值金额', trigger: 'blur'},
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
// //
@ -321,8 +390,8 @@ const rules = reactive({
trigger: 'blur' trigger: 'blur'
} }
], ],
payModel: [{ required: true, message: '请选择付款方式', trigger: 'blur' }],
payTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }]
payModel: [{required: true, message: '请选择付款方式', trigger: 'blur'}],
payTime: [{required: true, message: '请选择交款时间', trigger: 'blur'}]
}); });
// //
@ -351,7 +420,6 @@ 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) {
@ -391,7 +459,6 @@ const activity = ref([])
// } // }
// //
const rateName = [ const rateName = [
{ {
@ -549,9 +616,10 @@ onMounted(() => {
<template> <template>
<div> <div>
<el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" label-position="right" style="max-width: 600px" class="add-form">
<el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" label-position="right"
style="max-width: 600px" class="add-form">
<el-form-item prop="jwcode" label="精网号"> <el-form-item prop="jwcode" label="精网号">
<el-input v-model="recharge.jwcode" style="width: 220px" />
<el-input v-model="recharge.jwcode" style="width: 220px"/>
<el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button> <el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button>
</el-form-item> </el-form-item>
<!-- <el-form-item prop="activity" label="活动名称"> <!-- <el-form-item prop="activity" label="活动名称">
@ -570,16 +638,16 @@ onMounted(() => {
</el-select> </el-select>
</el-form-item> --> </el-form-item> -->
<el-form-item prop="activity" label="活动名称"> <el-form-item prop="activity" label="活动名称">
<el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px" />
<el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px"/>
</el-form-item> </el-form-item>
<el-form-item prop="permanentGold" label="永久金币"> <el-form-item prop="permanentGold" label="永久金币">
<el-input v-model="recharge.permanentGold" placeholder="0" style="width: 100px" />
<el-input v-model="recharge.permanentGold" placeholder="0" style="width: 100px"/>
<p></p> <p></p>
</el-form-item> </el-form-item>
<el-form-item prop="freeGold" label="免费金币"> <el-form-item prop="freeGold" label="免费金币">
<el-input v-model="recharge.freeGold" placeholder="0" style="width: 100px" />
<el-input v-model="recharge.freeGold" placeholder="0" style="width: 100px"/>
<p></p> <p></p>
</el-form-item> </el-form-item>
<!-- <el-form-item label="充值金额"> <!-- <el-form-item label="充值金额">
@ -604,31 +672,31 @@ onMounted(() => {
<!-- 货币名称 --> <!-- 货币名称 -->
<el-form-item prop="rateName" style="display: inline-block; margin-left:0;"> <el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
<el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px"> <el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px">
<el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 充值金额 --> <!-- 充值金额 -->
<el-form-item prop="money" style="display: inline-block; margin-left:10px;"> <el-form-item prop="money" style="display: inline-block; margin-left:10px;">
<el-input v-model="recharge.money" style="width: 190px" />
<el-input v-model="recharge.money" style="width: 190px"/>
</el-form-item> </el-form-item>
</el-form-item> </el-form-item>
<el-form-item prop="payModel" label="收款方式"> <el-form-item prop="payModel" label="收款方式">
<el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px"> <el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px">
<el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="payTime" label="交款时间"> <el-form-item prop="payTime" label="交款时间">
<!-- 修改 type 属性为 datetime 以支持时分秒选择 --> <!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
<el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px" />
<el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px"/>
</el-form-item> </el-form-item>
<el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px"> <el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px">
<el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false" <el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false"
:before-upload="beforeAvatarUpload" style="width: 100px; height: 115px"> :before-upload="beforeAvatarUpload" style="width: 100px; height: 115px">
<img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px" />
<img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px"/>
<el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px"> <el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px">
<Plus />
<Plus/>
</el-icon> </el-icon>
</el-upload> </el-upload>
<p style="margin-left: 10px; color: rgb(177, 176, 176)"> <p style="margin-left: 10px; color: rgb(177, 176, 176)">
@ -637,11 +705,11 @@ onMounted(() => {
</el-form-item> </el-form-item>
<el-form-item prop="remark" label="备注"> <el-form-item prop="remark" label="备注">
<el-input v-model="recharge.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit <el-input v-model="recharge.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
type="textarea" />
type="textarea"/>
</el-form-item> </el-form-item>
<el-button @click="deleteRecharge" style="margin-left: 280px" type="success">重置</el-button> <el-button @click="deleteRecharge" style="margin-left: 280px" type="success">重置</el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore"> 提交 </el-button>
<el-button type="primary" :disabled="addDisabled" @click="addBefore"> 提交</el-button>
</el-form> </el-form>
<!-- 客户信息栏 --> <!-- 客户信息栏 -->
@ -668,7 +736,9 @@ onMounted(() => {
</el-form-item> </el-form-item>
<el-form-item style="margin-top: -23px"> <el-form-item style="margin-top: -23px">
<span style="display: inline; white-space: nowrap; color: #b1b1b1" <span style="display: inline; white-space: nowrap; color: #b1b1b1"
v-if="user.historyPermanentGold !== undefined">(永久金币:{{ user.historyPermanentGold / 100 }};免费金币:{{
v-if="user.historyPermanentGold !== undefined">(永久金币:{{
user.historyPermanentGold / 100
}};免费金币:{{
(user.historyFreeGold) / 100 (user.historyFreeGold) / 100
}};任务金币:{{ user.historyTaskGold / 100 }})</span> }};任务金币:{{ user.historyTaskGold / 100 }})</span>
</el-form-item> </el-form-item>
@ -684,13 +754,16 @@ onMounted(() => {
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<el-form-item label="当前金币总数" style="width: 500px"> <el-form-item label="当前金币总数" style="width: 500px">
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{ user.nowSumGold
/100}}</span>
<span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
user.nowSumGold
/ 100
}}</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">(永久金币:{{ <span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
user.nowPermanentGold /100}};
user.nowPermanentGold / 100
}};
免费金币:{{ user.nowFreeGold / 100 }}; 免费金币:{{ user.nowFreeGold / 100 }};
任务金币:{{ user.nowTaskGold / 100 }})</span> 任务金币:{{ user.nowTaskGold / 100 }})</span>
</el-form-item> </el-form-item>
@ -729,6 +802,68 @@ onMounted(() => {
</el-form> </el-form>
</el-card> </el-card>
<el-dialog
v-model="RechargeDialogVisible"
title="操作确认"
:before-close="RechargeDialogVisiblehandleClose"
: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="recharge.activity" disabled/>
</div>
<!-- 金币信息同一行左右排列 -->
<el-row :gutter="20" class="coins-row">
<el-col :span="12">
<div class="field">
<div class="field-label">永久金币</div>
<el-input v-model="recharge.permanentGold" disabled/>
</div>
</el-col>
<el-col :span="12">
<div class="field">
<div class="field-label">免费金币</div>
<el-input v-model="recharge.freeGold" 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 }} 充值永久金币: {{ recharge.permanentGold }}
免费金币: {{ recharge.freeGold }}(操作人{{ adminData.adminName }})
</div>
<div style="margin-top: 10px">
<p>是否继续操作</p>
</div>
</div>
<!-- 底部按钮居中 -->
<template #footer>
<div class="dialog-footer-center">
<el-button @click="RechargeDialogVisibleCancel"> </el-button>
<el-button type="primary" @click="RechargeDialogVisibleContinue">确认充值</el-button>
</div>
</template>
</el-dialog>
</div> </div>
</template> </template>
@ -753,6 +888,9 @@ p {
height: 50px; height: 50px;
display: block; display: block;
} }
</style>
<style>
.error-message { .error-message {
color: red; color: red;
font-size: 8px; font-size: 8px;
@ -792,5 +930,40 @@ p {
.customer-info { .customer-info {
max-width: 60%; max-width: 60%;
} }
</style>
/* 标题居中 */
.el-dialog__header {
text-align: center;
}
.confirm-body {
width: 420px;
margin: 0 auto;
}
/* 字段块与标签样式 */
.field {
margin-top: 10px;
}
.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>

37
src/views/recharge/gold/coinRechargeDetail.vue

@ -6,6 +6,9 @@ import API from '@/util/http.js'
import { reverseMarketMapping } from '@/utils/marketMap.js'; import { reverseMarketMapping } from '@/utils/marketMap.js';
import dayjs from "dayjs"; import dayjs from "dayjs";
//
const showEmployeeData = ref(false)
const trimJwCode = () => { const trimJwCode = () => {
if (rechargeUser.value.jwcode) { if (rechargeUser.value.jwcode) {
rechargeUser.value.jwcode = rechargeUser.value.jwcode.replace(/\s/g, ''); rechargeUser.value.jwcode = rechargeUser.value.jwcode.replace(/\s/g, '');
@ -333,19 +336,15 @@ const get = async function (val) {
url: '/recharge/selectBy', url: '/recharge/selectBy',
data: { data: {
...getObj.value, ...getObj.value,
rechargeUser: { ...rechargeUser.value }
rechargeUser: { ...rechargeUser.value, flag: showEmployeeData.value ? 0 : 1 }//flag
} }
}) })
// rechargeUser.value // rechargeUser.value
const detailWithoutSort = ref({ const detailWithoutSort = ref({
market: rechargeUser.value.market,
activity: rechargeUser.value.activity,
adminId: rechargeUser.value.adminId,
startTime: rechargeUser.value.startTime,
endTime: rechargeUser.value.endTime,
jwcode: rechargeUser.value.jwcode,
goodsName: rechargeUser.value.goodsName,
payPlatform: rechargeUser.value.payPlatform
...rechargeUser.value,
sortField: undefined,
sortOrder: undefined,
flag: showEmployeeData.value ? 1 : 0 // flag
}) })
const resultTotalGold = await API({ const resultTotalGold = await API({
url: '/recharge/statsGold', url: '/recharge/statsGold',
@ -490,12 +489,8 @@ const handleSortChange = (column) => {
const exportExcel = async function () { const exportExcel = async function () {
const params = { const params = {
rechargeUser: { rechargeUser: {
jwcode: rechargeUser.value.jwcode || '',
market: rechargeUser.value.market || '',
payPlatform: rechargeUser.value.payPlatform || '',
activity: rechargeUser.value.activity || '',
startTime: rechargeUser.value.startTime || '',
endTime: rechargeUser.value.endTime || ''
...rechargeUser.value,
flag: showEmployeeData.value ? 0 : 1
}, },
page: getObj.value.pageNum, page: getObj.value.pageNum,
size: total.value size: total.value
@ -601,7 +596,7 @@ const getTagText = (state) => {
<el-input v-model="rechargeUser.jwcode" placeholder="请输入精网号" style="width: 150px" clearable /> <el-input v-model="rechargeUser.jwcode" placeholder="请输入精网号" style="width: 150px" clearable />
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">活动名称</el-text> <el-text class="mx-1" size="large">活动名称</el-text>
<el-select v-model="rechargeUser.activity" placeholder="请选择活动名称" style="width: 180px" clearable> <el-select v-model="rechargeUser.activity" placeholder="请选择活动名称" style="width: 180px" clearable>
@ -609,14 +604,14 @@ const getTagText = (state) => {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">所属地区</el-text> <el-text class="mx-1" size="large">所属地区</el-text>
<el-cascader v-model="selectedMarketPath" :options="market" placeholder="请选择所属地区" clearable <el-cascader v-model="selectedMarketPath" :options="market" placeholder="请选择所属地区" clearable
style="width:180px" @change="handleMarketChange" /> style="width:180px" @change="handleMarketChange" />
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">充值方式</el-text> <el-text class="mx-1" size="large">充值方式</el-text>
<el-select v-model="rechargeUser.payPlatform" placeholder="请选择充值方式" style="width: 180px" clearable> <el-select v-model="rechargeUser.payPlatform" placeholder="请选择充值方式" style="width: 180px" clearable>
@ -624,7 +619,11 @@ const getTagText = (state) => {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="3">
<div class="head-card-element">
<el-checkbox v-model="showEmployeeData" @click="search()">员工数据</el-checkbox>
</div>
</el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">

0
src/views/refund/beanRefund.vue → src/views/refund/bean/beanRefund.vue

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

@ -8,6 +8,9 @@ import request from '@/util/http.js'
import { reverseMarketMapping } from "@/utils/marketMap.js"; import { reverseMarketMapping } from "@/utils/marketMap.js";
import dayjs from "dayjs"; import dayjs from "dayjs";
const showEmployeeData = ref(false)
const defaultTime = [ const defaultTime = [
new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 2, 1, 23, 59, 59), new Date(2000, 2, 1, 23, 59, 59),
@ -157,11 +160,13 @@ const getSelectBy = async function (val) {
url: '/refund/selectBy', url: '/refund/selectBy',
data: { data: {
...getObj.value, ...getObj.value,
refundUser: { ...refundUser.value }
refundUser: { ...refundUser.value, flag: showEmployeeData.value ? 0 : 1 }
} }
}) })
// refundUser.value // refundUser.value
const detailWithoutSort = { ...refundUser.value }
const detailWithoutSort = { ...refundUser.value,
flag: showEmployeeData.value ? 1 : 0
}
delete detailWithoutSort.sortField delete detailWithoutSort.sortField
delete detailWithoutSort.sortOrder delete detailWithoutSort.sortOrder
@ -368,6 +373,7 @@ const exportExcel = async function () {
startTime: refundUser.value.startTime || '', startTime: refundUser.value.startTime || '',
endTime: refundUser.value.endTime || '', endTime: refundUser.value.endTime || '',
goodsName: refundUser.value.goodsName || '', goodsName: refundUser.value.goodsName || '',
flag: showEmployeeData.value ? 0 : 1
}, },
page: getObj.pageNum, page: getObj.pageNum,
size: total.value size: total.value
@ -520,7 +526,7 @@ const getMarket = async function () {
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1">商品名称</el-text> <el-text class="mx-1">商品名称</el-text>
<el-select v-model="refundUser.goodsName" placeholder="请选择商品名称" style="width: 180px" clearable> <el-select v-model="refundUser.goodsName" placeholder="请选择商品名称" style="width: 180px" clearable>
@ -528,12 +534,12 @@ const getMarket = async function () {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<el-text class="mx-1" size="large">所属地区</el-text> <el-text class="mx-1" size="large">所属地区</el-text>
<el-cascader v-model="selectedMarketPath" :options="market" placeholder="请选择所属地区" clearable <el-cascader v-model="selectedMarketPath" :options="market" placeholder="请选择所属地区" clearable
style="width:180px" @change="handleMarketChange" /> style="width:180px" @change="handleMarketChange" />
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1">退款类型</el-text> <el-text class="mx-1">退款类型</el-text>
<el-select v-model="refundUser.refundType" placeholder="请选择退款类型" style="width: 180px" clearable> <el-select v-model="refundUser.refundType" placeholder="请选择退款类型" style="width: 180px" clearable>
@ -542,6 +548,11 @@ const getMarket = async function () {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="3">
<div class="head-card-element">
<el-checkbox v-model="showEmployeeData" @click="search()">员工数据</el-checkbox>
</div>
</el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">

2
src/views/usergold/userbean.vue → src/views/usergold/bean/userbean.vue

@ -46,7 +46,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import API from '@/util/http'
import API from '@/util/http.js'
import { useAdminStore } from "@/store/index.js"; import { useAdminStore } from "@/store/index.js";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const adminStore = useAdminStore(); const adminStore = useAdminStore();

16
src/views/usergold/gold/clientCountBalance.vue

@ -6,6 +6,10 @@ import moment from 'moment'
import API from '@/util/http.js' import API from '@/util/http.js'
import {reverseMarketMapping} from "@/utils/marketMap.js"; import {reverseMarketMapping} from "@/utils/marketMap.js";
//
const showEmployeeData = ref(false)
// //
// //
const adminData = ref({}) const adminData = ref({})
@ -104,7 +108,7 @@ const get = async function (val) {
const result = await API({ const result = await API({
url: '/goldDetail/getGold', url: '/goldDetail/getGold',
method: 'post', method: 'post',
data: {...getObj.value, user: {...user.value}}
data: {...getObj.value, user: {...user.value, UserFlag: showEmployeeData.value? 0 : 1}}
}) })
console.log('响应数据', result) console.log('响应数据', result)
tableData.value = result.data.list tableData.value = result.data.list
@ -116,7 +120,8 @@ const get = async function (val) {
url: '/goldDetail/goldTotal', url: '/goldDetail/goldTotal',
data: { data: {
jwcode: user.value.jwcode, jwcode: user.value.jwcode,
markets: user.value.markets
markets: user.value.markets,
UserFlag: showEmployeeData.value? 1 : 0
} }
}) })
// result.data.list // result.data.list
@ -244,8 +249,10 @@ const exportExcel = async function () {
const params = { const params = {
user: { user: {
jwcode: user.value.jwcode || '', jwcode: user.value.jwcode || '',
markets: user.value.markets || []
markets: user.value.markets || [],
UserFlag: showEmployeeData.value? 0 : 1
} }
} }
const res = await API({url: '/goldDetail/exportGold', data: params}) const res = await API({url: '/goldDetail/exportGold', data: params})
if (res.code === 200) { if (res.code === 200) {
@ -402,6 +409,9 @@ const format3 = (num) => {
@change="handleMarketChange" @change="handleMarketChange"
/> />
</div> </div>
<div class="head-card-element">
<el-checkbox v-model="showEmployeeData" @click="search()">员工数据</el-checkbox>
</div>
<el-button type="primary" @click="search()">查询</el-button> <el-button type="primary" @click="search()">查询</el-button>
<el-button @click="reset" type="success">重置</el-button> <el-button @click="reset" type="success">重置</el-button>

22
src/views/usergold/gold/clientCountDetail.vue

@ -7,6 +7,10 @@ import API from '@/util/http.js'
import {reverseMarketMapping} from "../../../utils/marketMap.js"; import {reverseMarketMapping} from "../../../utils/marketMap.js";
import dayjs from "dayjs"; import dayjs from "dayjs";
//
const showEmployeeData = ref(false)
// //
const activeTimeRange = ref('') const activeTimeRange = ref('')
const defaultTime = [ const defaultTime = [
@ -166,7 +170,7 @@ const get = async function (val) {
const result = await API({ const result = await API({
url: '/goldDetail/getGoldDetail', url: '/goldDetail/getGoldDetail',
method: 'post', method: 'post',
data: {...getObj.value, goldDetail: {...goldDetail.value}}
data: {...getObj.value, goldDetail: {...goldDetail.value, UserFlag: showEmployeeData.value? 0 : 1}}
}) })
console.log('响应数据', result) console.log('响应数据', result)
tableData.value = result.data.list tableData.value = result.data.list
@ -187,7 +191,7 @@ const get = async function (val) {
url: '/goldDetail/getTotal', url: '/goldDetail/getTotal',
method: 'post', method: 'post',
data: { data: {
goldDetail: {...goldDetail.value},
goldDetail: {...goldDetail.value, UserFlag: showEmployeeData.value? 1 : 0},
/* jwcode: goldDetail.value.jwcode || '', /* jwcode: goldDetail.value.jwcode || '',
payPlatform: goldDetail.value.payPlatform || '', payPlatform: goldDetail.value.payPlatform || '',
type: goldDetail.value.type || '', type: goldDetail.value.type || '',
@ -328,7 +332,8 @@ const exportExcel = async function () {
startTime: goldDetail.value.startTime || '', startTime: goldDetail.value.startTime || '',
endTime: goldDetail.value.endTime || '', endTime: goldDetail.value.endTime || '',
sortField: goldDetail.value.sortField || '', sortField: goldDetail.value.sortField || '',
sortOrder: goldDetail.value.sortOrder || ''
sortOrder: goldDetail.value.sortOrder || '',
UserFlag: showEmployeeData.value ? 0 : 1 // UserFlag
}, },
} }
@ -500,7 +505,7 @@ const format3 = (num) => {
<el-input v-model="goldDetail.jwcode" style="width: 150px" placeholder="请输入精网号" clearable/> <el-input v-model="goldDetail.jwcode" style="width: 150px" placeholder="请输入精网号" clearable/>
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">平台信息</el-text> <el-text class="mx-1" size="large">平台信息</el-text>
<el-select v-model="goldDetail.payPlatform" placeholder="请选择平台信息" style="width: 160px" clearable <el-select v-model="goldDetail.payPlatform" placeholder="请选择平台信息" style="width: 160px" clearable
@ -509,7 +514,7 @@ const format3 = (num) => {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="7">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">数量更新类型</el-text> <el-text class="mx-1" size="large">数量更新类型</el-text>
<el-select v-model="goldDetail.type" placeholder="请选择更新类型" style="width: 160px" clearable> <el-select v-model="goldDetail.type" placeholder="请选择更新类型" style="width: 160px" clearable>
@ -517,7 +522,7 @@ const format3 = (num) => {
</el-select> </el-select>
</div> </div>
</el-col> </el-col>
<el-col :span="6">
<el-col :span="5">
<div class="head-card-element"> <div class="head-card-element">
<el-text class="mx-1" size="large">所属地区</el-text> <el-text class="mx-1" size="large">所属地区</el-text>
<el-cascader <el-cascader
@ -530,6 +535,11 @@ const format3 = (num) => {
/> />
</div> </div>
</el-col> </el-col>
<el-col :span="3">
<div class="head-card-element">
<el-checkbox v-model="showEmployeeData" @click="search()">员工数据</el-checkbox>
</div>
</el-col>
</el-row> </el-row>
<div class="head-card-element"> <div class="head-card-element">

Loading…
Cancel
Save