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.

971 lines
29 KiB

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