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.

985 lines
28 KiB

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