You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

888 lines
26 KiB

3 months ago
3 months ago
3 months ago
3 months ago
2 months ago
2 months ago
3 months ago
2 months ago
2 months ago
  1. <script setup>
  2. import { onMounted, reactive, ref } from 'vue'
  3. import { ElIcon, ElMessage, ElMessageBox } from 'element-plus'
  4. import { Plus, WarnTriangleFilled } from '@element-plus/icons-vue'
  5. import axios from 'axios'
  6. import API from '@/util/http.js'
  7. import moment from 'moment'
  8. import Cookies from 'js-cookie';
  9. // 定义 fixedAdminId
  10. // const fixedAdminId = 1;
  11. // 精网号去空格
  12. const trimJwCode = () => {
  13. if (recharge.value.jwcode) {
  14. recharge.value.jwcode = recharge.value.jwcode.replace(/\s/g, '');
  15. }
  16. }
  17. // 上传图片前的验证函数
  18. const beforeAvatarUpload = (file) => {
  19. const validTypes = ['image/jpeg', 'image/png'];
  20. const isImage = validTypes.includes(file.type);
  21. const isLt1M = file.size / 1024 / 1024 < 1;
  22. if (!isImage) {
  23. ElMessage.error('只能上传 JPG/PNG 图片!');
  24. return false;
  25. }
  26. if (!isLt1M) {
  27. ElMessage.error('图片大小不能超过 1MB!');
  28. return false;
  29. }
  30. return true;
  31. };
  32. // 这是添加上传图片的接口
  33. const imageUrl = ref('')
  34. const voucher = ref('')
  35. // const rateName = ref()
  36. const adminData = ref({})
  37. // 获取管理员信息
  38. const getAdminData = async function () {
  39. try {
  40. const result = await API({
  41. url: '/admin/userinfo',
  42. data: {}
  43. })
  44. adminData.value = result
  45. recharge.value.adminId = adminData.value.id
  46. recharge.value.market = adminData.value.market
  47. console.log('请求成功', result)
  48. console.log('用户信息', user.value)
  49. } catch (error) {
  50. console.log('请求失败', error)
  51. }
  52. }
  53. //提交禁止重复点击
  54. const addDisabled = ref(false)
  55. // 这是添加充值信息的表单
  56. const recharge = ref({
  57. jwcode: '', // jwcode 字段
  58. activity: '', // activity 字段
  59. voucher: '',
  60. rechargeWay: '客服充值',
  61. freeGold: "",
  62. money: null,
  63. permanentGold: "",
  64. rateName: null,
  65. rateId: null,
  66. payModel: '', // payModel 字段
  67. payTime: null, // payTime 字段
  68. remark: '', // remark 字段
  69. rechargeRatio: ''
  70. })
  71. // 用来写的 cookie 的 key
  72. const WriteCookies = ref(null)
  73. // 用来写的 cookie 的 value
  74. const WriteCookiesTime = ref(null)
  75. // 用来读的 cookie 的 key
  76. const ReadCookies = ref(null)
  77. // 用来读的 cookie 的 value
  78. const ReadCookiesTime = ref(null)
  79. // 这是添加充值信息的接口
  80. const add = async function () {
  81. try {
  82. const formattedRecharge = { ...recharge.value }
  83. // 将永久金币数、免费金币数和充值金额数乘以 100
  84. if (formattedRecharge.permanentGold) {
  85. formattedRecharge.permanentGold = Number(formattedRecharge.permanentGold) * 100;
  86. }
  87. if (formattedRecharge.freeGold) {
  88. formattedRecharge.freeGold = Number(formattedRecharge.freeGold) * 100;
  89. }
  90. if (formattedRecharge.money) {
  91. formattedRecharge.money = Number(formattedRecharge.money) * 100;
  92. }
  93. if (formattedRecharge.payTime) {
  94. // 使用 moment.js 格式化 payTime
  95. formattedRecharge.payTime = moment(formattedRecharge.payTime).format('YYYY-MM-DD HH:mm:ss')
  96. }
  97. console.log('开始添加充值信息', recharge.value)
  98. //存一下 用户的jwcode
  99. // 拼接 jwcode:permanentGold:freeGold
  100. WriteCookies.value = `coinRecharge:${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
  101. //value 为充值时间
  102. WriteCookiesTime.value = recharge.value.payTime
  103. // 设置cookies,用户jwcode为key,value也是jwcode,过期时间为1天
  104. Cookies.set(WriteCookies.value, WriteCookiesTime.value, { expires: 1, path: '/' });
  105. // 发送POST请求
  106. addDisabled.value = true
  107. const result = await API({
  108. url: '/recharge/add',
  109. data: formattedRecharge
  110. })
  111. addDisabled.value = false
  112. if (result.code === 0) {
  113. ElMessage.error(result.msg)
  114. return
  115. }
  116. // 将响应结果存储到响应式数据中
  117. console.log('请求成功', result)
  118. // 显示成功消息
  119. ElMessage.success('添加成功')
  120. // 重置表单
  121. deleteRecharge()
  122. user.value = {}
  123. } catch (error) {
  124. console.log('请求失败', error)
  125. // 在这里可以处理错误逻辑,比如显示错误提示等
  126. }
  127. }
  128. // 充值对话框显示状态
  129. const RechargeDialogVisible = ref(false);
  130. // 关闭对话框
  131. const RechargeDialogVisiblehandleClose = () => {
  132. RechargeDialogVisible.value = false;
  133. // 重置表单数据
  134. deleteRecharge()
  135. user.value = {}
  136. };
  137. // 确认使用cookie继续充值
  138. const RechargeDialogVisibleContinue = () => {
  139. RechargeDialogVisible.value = false;
  140. add();
  141. };
  142. const RechargeDialogVisibleCancel = () => {
  143. RechargeDialogVisible.value = false
  144. deleteRecharge()
  145. user.value = {}
  146. };
  147. // 实际执行充值操作
  148. const proceedWithRecharge = () => {
  149. ElMessageBox.confirm('确认充值?')
  150. .then(() => {
  151. add();
  152. console.log('充值成功');
  153. })
  154. .catch(() => {
  155. console.log('取消充值');
  156. });
  157. };
  158. // 添加充值信息前的按钮点击事件,进行表单验证和用户确认操作
  159. const addBefore = () => {
  160. // 为未输入的金币字段设置默认值
  161. if (!recharge.value.permanentGold) {
  162. recharge.value.permanentGold = '0';
  163. }
  164. if (!recharge.value.freeGold) {
  165. recharge.value.freeGold = '0';
  166. }
  167. // 表单验证
  168. Ref.value.validate(async (valid) => {
  169. if (!valid) {
  170. ElMessage({
  171. type: 'error',
  172. message: '请检查输入内容'
  173. });
  174. return;
  175. }
  176. // 验证金币不能同时为0
  177. if (Number(recharge.value.permanentGold) === 0 && Number(recharge.value.freeGold) === 0) {
  178. ElMessage({
  179. type: 'error',
  180. message: '永久金币和免费金币不能同时为0'
  181. });
  182. return;
  183. }
  184. // 验证币种选择
  185. if (!recharge.value.rateName) {
  186. ElMessage({
  187. type: 'error',
  188. message: '请选择币种'
  189. });
  190. return;
  191. }
  192. // 验证充值金额
  193. if (!recharge.value.money) {
  194. ElMessage({
  195. type: 'error',
  196. message: '请输入充值金额'
  197. });
  198. return;
  199. }
  200. // 设置对应的rateId
  201. const selectedRate = rateName.find(item => item.value === recharge.value.rateName);
  202. if (selectedRate) {
  203. recharge.value.rateId = selectedRate.rateId;
  204. }
  205. // 检查是否有用户信息
  206. if (!user.value.jwcode) {
  207. ElMessage.warning('请先查询用户信息')
  208. return
  209. }
  210. // 检查cookie
  211. // 拼接 jwcode:permanentGold:freeGold
  212. ReadCookies.value = `coinRecharge:${recharge.value.jwcode}:${recharge.value.permanentGold}:${recharge.value.freeGold}`
  213. // 获取cookie
  214. const cookie = Cookies.get(ReadCookies.value)
  215. console.log("time", WriteCookiesTime.value)
  216. // 格式化时间
  217. ReadCookiesTime.value = moment(cookie).format('YYYY-MM-DD HH:mm:ss')
  218. console.log('cookie', cookie)
  219. // 如果存在cookie,显示确认对话框;否则直接进入充值确认
  220. if (cookie) {
  221. RechargeDialogVisible.value = true;
  222. } else {
  223. proceedWithRecharge();
  224. }
  225. });
  226. };
  227. // 表单验证
  228. // 开始时间改变时,重新验证结束时间
  229. const Ref = ref(null)
  230. const rules = reactive({
  231. jwcode: [{
  232. required: true, validator: (rule, value, callback) => {
  233. if (!value) {
  234. callback(new Error('精网号不能为空'));
  235. return;
  236. }
  237. if (/[^0-9]/.test(value)) {
  238. callback(new Error('精网号只能包含数字'));
  239. return;
  240. }
  241. callback();
  242. }, trigger: 'blur'
  243. }],
  244. activity: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
  245. permanentGold: [
  246. { required: true, message: '请输入永久金币数', trigger: 'change' },
  247. {
  248. validator: (rule, value, callback) => {
  249. if (!value) {
  250. value = '0'
  251. }
  252. // 检查是否包含特殊符号
  253. if (/[^0-9.]/.test(value)) {
  254. callback(new Error('不能包含特殊符号或负数'));
  255. return;
  256. }
  257. // 检查整数位数
  258. const integerPart = value.split('.')[0];
  259. if (integerPart.length > 6) {
  260. callback(new Error('整数位数不能超过6位'));
  261. return;
  262. }
  263. // 检查小数位数
  264. if (value.includes('.')) {
  265. const decimalPart = value.split('.')[1];
  266. if (decimalPart.length > 2) {
  267. callback(new Error('小数位数不能超过两位'));
  268. return;
  269. }
  270. }
  271. const numValue = Number(value);
  272. if (isNaN(numValue)) {
  273. callback(new Error('请输入有效的数字'));
  274. } else if (numValue < 0) {
  275. callback(new Error('输入金额不能小于0'));
  276. } else {
  277. callback();
  278. }
  279. },
  280. trigger: 'blur'
  281. }
  282. ],
  283. freeGold: [
  284. { required: true, message: '请输入免费金币数', trigger: 'change' },
  285. {
  286. validator: (rule, value, callback) => {
  287. if (!value) {
  288. value = '0'
  289. }
  290. // 检查是否包含特殊符号
  291. if (/[^0-9.]/.test(value)) {
  292. callback(new Error('不能包含特殊符号或负数'));
  293. return;
  294. }
  295. // 检查整数位数
  296. const integerPart = value.split('.')[0];
  297. if (integerPart.length > 6) {
  298. callback(new Error('整数位数不能超过6位'));
  299. return;
  300. }
  301. // 检查小数位数
  302. if (value.includes('.')) {
  303. const decimalPart = value.split('.')[1];
  304. if (decimalPart.length > 2) {
  305. callback(new Error('小数位数不能超过两位'));
  306. return;
  307. }
  308. }
  309. const numValue = Number(value);
  310. if (isNaN(numValue)) {
  311. callback(new Error('请输入有效的数字'));
  312. } else if (numValue < 0) {
  313. callback(new Error('输入金额不能小于0'));
  314. } else {
  315. callback();
  316. }
  317. },
  318. trigger: 'blur'
  319. }
  320. ],
  321. rateName: [{
  322. required: true,
  323. message: '请选择货币名称',
  324. trigger: 'blur'
  325. }],
  326. money: [
  327. { required: true, message: '请输入充值金额', trigger: 'blur' },
  328. {
  329. validator: (rule, value, callback) => {
  330. // 检查是否包含特殊符号
  331. if (/[^0-9.]/.test(value)) {
  332. callback(new Error('不能包含特殊符号或负数'));
  333. return;
  334. }
  335. // 检查整数位数
  336. const integerPart = value.split('.')[0];
  337. if (integerPart.length > 6) {
  338. callback(new Error('整数位数不能超过6位'));
  339. return;
  340. }
  341. // 检查小数位数
  342. if (value.includes('.')) {
  343. const decimalPart = value.split('.')[1];
  344. if (decimalPart.length > 2) {
  345. callback(new Error('小数位数不能超过两位'));
  346. return;
  347. }
  348. }
  349. const numValue = Number(value);
  350. if (isNaN(numValue)) {
  351. callback(new Error('请输入有效的数字'));
  352. } else if (numValue < 0) {
  353. callback(new Error('输入金额不能小于0'));
  354. } else {
  355. callback();
  356. }
  357. },
  358. trigger: 'blur'
  359. }
  360. ],
  361. payModel: [{ required: true, message: '请选择付款方式', trigger: 'blur' }],
  362. payTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }]
  363. });
  364. // 查找客户信息的方法
  365. const user = ref({})
  366. const getUser = async function (jwcode) {
  367. trimJwCode();
  368. // 验证精网号
  369. if (!jwcode) {
  370. ElMessage.warning('精网号不能为空');
  371. return;
  372. }
  373. // 验证精网号是否为数字
  374. if (!/^\d{1,9}$/.test(jwcode)) {
  375. ElMessage.warning('精网号必须为数字且不超过九位');
  376. deleteRecharge()
  377. return;
  378. }
  379. try {
  380. const result = await API({
  381. url: '/user/selectUser',
  382. data: {
  383. jwcode: recharge.value.jwcode
  384. }
  385. })
  386. if (result.code === 0) {
  387. ElMessage.error(result.msg);
  388. } else if (result.data === null) {
  389. ElMessage.error("用户不存在");
  390. } else {
  391. user.value = result.data;
  392. console.log("用户信息", user.value);
  393. ElMessage.success("查询成功");
  394. }
  395. } catch (error) {
  396. console.log("请求失败", error);
  397. ElMessage.error("精网号错误");
  398. }
  399. }
  400. // 这是查询活动的接口,一期没有调用这个接口
  401. const activity = ref([])
  402. // const getActivity = async function () {
  403. // try {
  404. // // 发送POST请求
  405. // const result = await API({
  406. // url: '/general/activity',
  407. // data: {
  408. // }
  409. // })
  410. // // 将响应结果存储到响应式数据中
  411. // console.log('请求成功', result)
  412. // // 存储表格数据
  413. // activity.value = result.data
  414. // console.log('活动信息', activity.value)
  415. // } catch (error) {
  416. // console.log('activity请求失败', error)
  417. // // 在这里可以处理错误逻辑,比如显示错误提示等
  418. // }
  419. // }
  420. //货币条目
  421. const rateName = [
  422. {
  423. value: 'USD',
  424. label: 'USD',
  425. rateId: 1
  426. },
  427. {
  428. value: 'HKD',
  429. label: 'HKD',
  430. rateId: 2
  431. },
  432. {
  433. value: 'THB',
  434. label: 'THB',
  435. rateId: 3
  436. },
  437. {
  438. value: 'VND',
  439. label: 'VND',
  440. rateId: 4
  441. },
  442. {
  443. value: 'CAD',
  444. label: 'CAD',
  445. rateId: 5
  446. },
  447. {
  448. value: 'MYR',
  449. label: 'MYR',
  450. rateId: 6
  451. },
  452. {
  453. value: 'KRW',
  454. label: 'KRW',
  455. rateId: 7
  456. },
  457. {
  458. value: 'JPY',
  459. label: 'JPY',
  460. rateId: 8
  461. },
  462. {
  463. value: 'CNY',
  464. label: 'CNY',
  465. rateId: 9
  466. }
  467. ]
  468. // 修改上传处理
  469. const customUpload = async (options) => {
  470. try {
  471. const formData = new FormData();
  472. formData.append('file', options.file);
  473. const response = await axios.post(import.meta.env.VITE_UPLOAD_URL, formData, {
  474. headers: {
  475. 'Content-Type': 'multipart/form-data',
  476. 'Authorization': `Bearer ${localStorage.getItem('token')}`
  477. }
  478. });
  479. if (response.data.code === 200 && response.data.data) {
  480. // 传递原始文件对象和响应数据
  481. handleAvatarSuccess(response.data, options.file);
  482. ElMessage.success('上传成功');
  483. } else {
  484. ElMessage.error(response.data.msg || '上传失败');
  485. }
  486. } catch (error) {
  487. console.error('上传错误:', error);
  488. ElMessage.error(`上传失败: ${error.response?.data?.message || error.message}`);
  489. }
  490. };
  491. // 获取环境变量
  492. // const uploadUrl = import.meta.env.VITE_UPLOAD_URL;
  493. // 上传图片成功的回调函数
  494. const handleAvatarSuccess = (response, file) => {
  495. // 直接使用 file 对象创建 Object URL
  496. imageUrl.value = URL.createObjectURL(file);
  497. // 使用服务器返回的文件路径(根据实际响应结构调整)
  498. if (response && response.filePath) {
  499. recharge.value.voucher = response.filePath;
  500. } else if (response && response.url) {
  501. recharge.value.voucher = response.url;
  502. } else if (response && response.data) {
  503. // 假设响应结构为 { code: 200, data: { filePath: ... } }
  504. recharge.value.voucher = response.data.filePath || response.data.url;
  505. } else {
  506. // 后备方案:使用环境变量中的上传URL
  507. recharge.value.voucher = import.meta.env.VITE_UPLOAD_URL;
  508. }
  509. }
  510. //支付方式条目
  511. const payModel = [
  512. {
  513. value: '银行转账',
  514. label: '银行转账'
  515. },
  516. {
  517. value: '现金',
  518. label: '现金'
  519. },
  520. {
  521. value: '支票',
  522. label: '支票'
  523. },
  524. {
  525. value: '刷卡',
  526. label: '刷卡'
  527. },
  528. {
  529. value: 'Grabpay',
  530. label: 'Grabpay'
  531. },
  532. {
  533. value: 'Nets',
  534. label: 'Nets'
  535. },
  536. {
  537. value: 'PayPal',
  538. label: 'PayPal'
  539. },
  540. {
  541. value: 'Stripe-链接收款',
  542. label: 'Stripe-链接收款'
  543. },
  544. {
  545. value: 'Ipay88-链接收款',
  546. label: 'Ipay88-链接收款'
  547. },
  548. {
  549. value: 'PaymentAsia-链接收款',
  550. label: 'PaymentAsia-链接收款'
  551. },
  552. {
  553. value: '其他',
  554. label: '其他'
  555. }
  556. ]
  557. // }
  558. function handleActivityChange(value) {
  559. // 在这里执行你的逻辑,例如获取选中的值
  560. console.log('选中的值:', value)
  561. // getActivityById(value)
  562. console.log('看看', recharge.value)
  563. }
  564. //这是重置重置表单的方法
  565. const deleteRecharge = function () {
  566. Ref.value.resetFields();
  567. recharge.value = {
  568. adminId: adminData.value.id,
  569. //adminId: fixedAdminId,
  570. market: adminData.value.market,
  571. voucher: '',
  572. rechargeWay: '客服充值',
  573. freeGold: '',
  574. money: null,
  575. permanentGold: '',
  576. rateId: null
  577. }
  578. imageUrl.value = ''
  579. recharge.value.rateName = ''
  580. }
  581. onMounted(async function () {
  582. await getAdminData()
  583. // await getCurrency()
  584. // await getActivity()// 现在的活动就是文字输入框,不需要请求接口,具体等后续需求
  585. })
  586. onMounted(() => {
  587. console.log('上传URL:', import.meta.env.VITE_UPLOAD_URL);
  588. });
  589. </script>
  590. <template>
  591. <div>
  592. <el-form :model="recharge" ref="Ref" :rules="rules" label-width="auto" label-position="right"
  593. style="max-width: 600px" class="add-form">
  594. <el-form-item prop="jwcode" label="精网号">
  595. <el-input v-model="recharge.jwcode" style="width: 220px" />
  596. <el-button type="primary" @click="getUser(recharge.jwcode)" style="margin-left: 20px">查询</el-button>
  597. </el-form-item>
  598. <el-form-item prop="activity" label="活动名称">
  599. <el-input v-model="recharge.activity" placeholder="请输入活动名称" style="width: 300px" />
  600. </el-form-item>
  601. <el-form-item prop="permanentGold" label="永久金币">
  602. <el-input v-model="recharge.permanentGold" placeholder="0" style="width: 100px" />
  603. <p>&nbsp;</p>
  604. </el-form-item>
  605. <el-form-item prop="freeGold" label="免费金币">
  606. <el-input v-model="recharge.freeGold" placeholder="0" style="width: 100px" />
  607. <p>&nbsp;</p>
  608. </el-form-item>
  609. <el-form-item label="充值金额" required>
  610. <el-form-item prop="rateName" style="display: inline-block; margin-left:0;">
  611. <el-select v-model="recharge.rateName" placeholder="货币名称" style="width: 100px">
  612. <el-option v-for="item in rateName" :key="item.value" :label="item.label" :value="item.value" />
  613. </el-select>
  614. </el-form-item>
  615. <el-form-item prop="money" style="display: inline-block; margin-left:10px;">
  616. <el-input v-model="recharge.money" style="width: 190px" />
  617. </el-form-item>
  618. </el-form-item>
  619. <el-form-item prop="payModel" label="收款方式">
  620. <el-select v-model="recharge.payModel" placeholder="请选择" style="width: 300px">
  621. <el-option v-for="item in payModel" :key="item.value" :label="item.label" :value="item.value" />
  622. </el-select>
  623. </el-form-item>
  624. <el-form-item prop="payTime" label="交款时间">
  625. <!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
  626. <el-date-picker v-model="recharge.payTime" type="datetime" style="width: 300px" />
  627. </el-form-item>
  628. <el-form-item prop="voucher" label="交款凭证" style="margin-bottom: 5px">
  629. <el-upload :http-request="customUpload" class="avatar-uploader" :show-file-list="false"
  630. :before-upload="beforeAvatarUpload" style="width: 100px; height: 115px">
  631. <img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 115px" />
  632. <el-icon v-else class="avatar-uploader-icon" style="width: 100px; height: 100px">
  633. <Plus />
  634. </el-icon>
  635. </el-upload>
  636. <p style="margin-left: 10px; color: rgb(177, 176, 176)">
  637. 仅支持.jpg .png格式文件1MB
  638. </p>
  639. </el-form-item>
  640. <el-form-item prop="remark" label="备注">
  641. <el-input v-model="recharge.remark" style="width: 300px" :rows="4" maxlength="100" show-word-limit
  642. type="textarea" />
  643. </el-form-item>
  644. <el-button @click="deleteRecharge" style="margin-left: 220px;margin-top:20px" type="success">重置</el-button>
  645. <el-button type="primary" style="margin-top:20px" :disabled="addDisabled" @click="addBefore"> 提交</el-button>
  646. </el-form>
  647. <!-- 客户信息栏 -->
  648. <el-card v-if="user.jwcode" class="beautiful">
  649. <el-form :model="user" label-width="auto" style="max-width: 1000px" label-position="left">
  650. <el-text size="large" style="margin-left: 20px">客户信息</el-text>
  651. <!-- 第一行姓名 + 历史金币 -->
  652. <el-row style="margin-top: 20px">
  653. <el-col :span="9">
  654. <el-form-item label="姓名:">
  655. <p>{{ user.name }}</p>
  656. </el-form-item>
  657. </el-col>
  658. <el-col :span="14">
  659. <el-form-item label="历史金币总数">
  660. <!-- 检查 user.historySumGold 是否为有效的数字 -->
  661. <p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.historySumGold))">
  662. {{ Number(user.historySumGold) / 100 }}
  663. </p>
  664. <!-- 如果不是有效的数字显示默认值 -->
  665. <p v-else></p>
  666. </el-form-item>
  667. <el-form-item style="margin-top: -23px">
  668. <span style="display: inline; white-space: nowrap; color: #b1b1b1"
  669. v-if="user.historyPermanentGold !== undefined">(永久金币:{{
  670. user.historyPermanentGold / 100
  671. }};免费金币:{{
  672. (user.historyFreeGold) / 100
  673. }};任务金币:{{ user.historyTaskGold / 100 }})</span>
  674. </el-form-item>
  675. </el-col>
  676. </el-row>
  677. <!-- 第二行精网号 + 当前金币独立行 -->
  678. <el-row style="margin-top:-23px">
  679. <el-col :span="9">
  680. <el-form-item label="精网号">
  681. <p>{{ user.jwcode }}</p>
  682. </el-form-item>
  683. </el-col>
  684. <el-col :span="14">
  685. <el-form-item label="当前金币总数" style="width: 500px">
  686. <span style="color: #2fa1ff; margin-right: 5px" v-if="user.nowSumGold !== undefined">{{
  687. user.nowSumGold
  688. / 100
  689. }}</span>
  690. </el-form-item>
  691. <!-- 金币详情独立显示 -->
  692. <el-form-item style="margin-top: -23px"> <!-- 负边距减少间距 -->
  693. <span style="color: #b1b1b1; margin-left: 0px" v-if="user.nowPermanentGold !== undefined">(永久金币:{{
  694. user.nowPermanentGold / 100
  695. }};
  696. 免费金币:{{ user.nowFreeGold / 100 }};
  697. 任务金币:{{ user.nowTaskGold / 100 }})</span>
  698. </el-form-item>
  699. </el-col>
  700. </el-row>
  701. <!-- 第三行首次充值日期 + 充值次数 -->
  702. <el-row style="margin-top:-23px">
  703. <el-col :span="9">
  704. <el-form-item label="首次充值日期">
  705. <p v-if="user.firstRecharge">
  706. {{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
  707. </p>
  708. </el-form-item>
  709. </el-col>
  710. <el-col :span="14">
  711. <el-form-item label="充值次数">
  712. <p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
  713. </el-form-item>
  714. </el-col>
  715. </el-row>
  716. <!-- 第四行消费次数 + 所属门店 -->
  717. <el-row>
  718. <el-col :span="9">
  719. <el-form-item label="消费次数">
  720. <p style="color: #2fa1ff">{{ user.consumeNum }}</p>
  721. </el-form-item>
  722. </el-col>
  723. <el-col :span="9">
  724. <el-form-item label="所属门店">
  725. <p>{{ user.market }}</p>
  726. </el-form-item>
  727. </el-col>
  728. </el-row>
  729. </el-form>
  730. </el-card>
  731. <el-dialog v-model="RechargeDialogVisible" title="操作确认" :before-close="RechargeDialogVisiblehandleClose"
  732. :close-on-click-modal="false" width="480px">
  733. <!-- 内容整体居中且收窄 -->
  734. <div class="confirm-body">
  735. <!-- 用户信息 -->
  736. <div>
  737. <div class="field-label">用户信息</div>
  738. <el-input :model-value="user.jwcode + (user.name ? '' + user.name + '' : '')" disabled />
  739. </div>
  740. <!-- 活动名称 -->
  741. <div class="field">
  742. <div class="field-label">活动名称</div>
  743. <el-input v-model="recharge.activity" disabled />
  744. </div>
  745. <!-- 金币信息同一行左右排列 -->
  746. <el-row :gutter="20" class="coins-row">
  747. <el-col :span="12">
  748. <div class="field">
  749. <div class="field-label">永久金币</div>
  750. <el-input v-model="recharge.permanentGold" disabled />
  751. </div>
  752. </el-col>
  753. <el-col :span="12">
  754. <div class="field">
  755. <div class="field-label">免费金币</div>
  756. <el-input v-model="recharge.freeGold" disabled />
  757. </div>
  758. </el-col>
  759. </el-row>
  760. <!-- 风险提示 -->
  761. <div style="display: flex; align-items: center; margin-top: 20px;">
  762. <el-icon :size="24" color="#FFD700">
  763. <WarnTriangleFilled />
  764. </el-icon>
  765. <p>重复充值风险提示</p>
  766. </div>
  767. <!-- 记录 + 虚线分隔 -->
  768. <div>
  769. <el-divider border-style="dashed" />
  770. <p>检测到该用户近期有相似充值记录</p>
  771. · {{ ReadCookiesTime }} 充值永久金币: {{ recharge.permanentGold }}
  772. 免费金币: {{ recharge.freeGold }}(操作人{{ adminData.adminName }})
  773. </div>
  774. <div style="margin-top: 10px">
  775. <p>是否继续操作</p>
  776. </div>
  777. </div>
  778. <!-- 底部按钮居中 -->
  779. <template #footer>
  780. <div class="dialog-footer-center">
  781. <el-button @click="RechargeDialogVisibleCancel"> </el-button>
  782. <el-button type="primary" @click="RechargeDialogVisibleContinue">确认充值</el-button>
  783. </div>
  784. </template>
  785. </el-dialog>
  786. </div>
  787. </template>
  788. <style scoped>
  789. p {
  790. margin: 0px;
  791. }
  792. .batch-btn {
  793. margin-top: 20px;
  794. margin-left: auto;
  795. }
  796. .el-form-item {
  797. margin-left: 50px;
  798. }
  799. /* 上传图片的格式 */
  800. .avatar-uploader .avatar {
  801. width: 50px;
  802. height: 50px;
  803. display: block;
  804. }
  805. .add-form {
  806. margin-top: 50px;
  807. max-width: 50%;
  808. float: left;
  809. }
  810. .beautiful {
  811. width: 700px;
  812. float: right;
  813. margin-right: 300px;
  814. margin-top: 150px;
  815. }
  816. </style>