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.

1032 lines
31 KiB

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