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.

690 lines
17 KiB

  1. <script setup>
  2. import { ref, onMounted, reactive, computed, watch, nextTick } from 'vue'
  3. import { ElMessage } from 'element-plus'
  4. import { Plus } from '@element-plus/icons-vue'
  5. import axios from 'axios'
  6. import { ElMessageBox } from 'element-plus'
  7. import API from '@/util/http'
  8. import moment from 'moment'
  9. import { range, re } from 'mathjs'
  10. import { utils, read } from 'xlsx'
  11. import throttle from 'lodash/throttle'
  12. // 定义 fixedAdminId
  13. const fixedAdminId = 1;
  14. // 精网号去空格
  15. const trimJwCode = () => {
  16. if (recharge.value.jwcode) {
  17. recharge.value.jwcode = recharge.value.jwcode.replace(/\s/g, '');
  18. }
  19. }
  20. // 上传图片前的验证函数
  21. const beforeAvatarUpload = (file) => {
  22. const isJPG = file.type === 'image/jpeg'
  23. const isPNG = file.type === 'image/png'
  24. const isLt2M = file.size / 1024 / 1024 < 2
  25. if (!isJPG && !isPNG) {
  26. ElMessage.error('上传头像图片只能是 JPG 或 PNG 格式!')
  27. }
  28. if (!isLt2M) {
  29. ElMessage.error('上传头像图片大小不能超过 2MB!')
  30. }
  31. return (isJPG || isPNG) && isLt2M
  32. }
  33. // 这是添加上传图片的接口
  34. const imageUrl = ref('')
  35. const voucher = ref('')
  36. const Rate = ref()
  37. const adminData = ref({})
  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.adminId
  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 recharge = ref({
  55. jwcode: '', // jwcode 字段
  56. activity: '', // activity 字段
  57. voucher: '',
  58. rechargeWay: '客服充值',
  59. freeGold: '',
  60. money: null,
  61. permanentGold: '',
  62. Rate: null,
  63. rateId: null,
  64. payModel: '', // payModel 字段
  65. payTime: null, // payTime 字段
  66. remark: '', // remark 字段
  67. rechargeRatio: ''
  68. })
  69. // 这是添加充值信息的接口
  70. const add = async function () {
  71. try {
  72. const formattedRecharge = { ...recharge.value,
  73. // 添加固定的 adminId
  74. adminId: fixedAdminId
  75. }
  76. // 将永久金币数、免费金币数和充值金额数乘以 100
  77. if (formattedRecharge.permanentGold) {
  78. formattedRecharge.permanentGold = Number(formattedRecharge.permanentGold) * 100;
  79. }
  80. if (formattedRecharge.freeGold) {
  81. formattedRecharge.freeGold = Number(formattedRecharge.freeGold) * 100;
  82. }
  83. if (formattedRecharge.money) {
  84. formattedRecharge.money = Number(formattedRecharge.money) * 100;
  85. }
  86. if (formattedRecharge.payTime) {
  87. // 使用 moment.js 格式化 payTime
  88. formattedRecharge.payTime = moment(formattedRecharge.payTime).format('YYYY-MM-DD HH:mm:ss')
  89. }
  90. console.log('开始添加充值信息', recharge.value)
  91. // 发送POST请求
  92. const result = await API({
  93. url: '/recharge/add',
  94. data: formattedRecharge
  95. })
  96. if (result.code === 0) {
  97. ElMessage.error(result.msg)
  98. return
  99. }
  100. // 将响应结果存储到响应式数据中
  101. console.log('请求成功', result)
  102. // 显示成功消息
  103. ElMessage.success('添加成功')
  104. // 重置表单
  105. recharge.value = {}
  106. recharge.value.adminId = adminData.value.adminId
  107. recharge.value.market = adminData.value.market
  108. recharge.value.voucher = ''
  109. recharge.value.rechargeWay = '客服充值'
  110. recharge.value.freeGold = ''
  111. recharge.value.money = null
  112. recharge.value.permanentGold = ''
  113. recharge.value.rateId = null
  114. imageUrl.value = ''
  115. Rate.value = null
  116. user.value = {}
  117. } catch (error) {
  118. console.log('请求失败', error)
  119. // 在这里可以处理错误逻辑,比如显示错误提示等
  120. }
  121. }
  122. //添加充值信息前的按钮点击事件,进行表单验证和用户确认操作
  123. const addBefore = () => {
  124. Ref.value.validate(async (valid) => {
  125. if (valid) {
  126. if (Rate.value == null || Rate.value == '' || Rate.value == undefined) {
  127. ElMessage({
  128. type: 'error',
  129. message: '请选择币种'
  130. })
  131. return
  132. }
  133. if(recharge.value.money == null || recharge.value.money == '' || recharge.value.money == undefined){
  134. ElMessage({
  135. type: 'error',
  136. message: '请输入充值金额'
  137. })
  138. return
  139. }
  140. // 根据选择的货币名称找到对应的 rateId
  141. const selectedRate = rateName.find(item => item.value === Rate.value)
  142. if (selectedRate) {
  143. recharge.value.rateId = selectedRate.rateId
  144. }
  145. ElMessageBox.confirm('确认添加?')
  146. .then(() => {
  147. add()
  148. console.log('添加成功')
  149. })
  150. .catch(() => {
  151. console.log('取消添加')
  152. })
  153. } else {
  154. //提示
  155. ElMessage({
  156. type: 'error',
  157. message: '请检查输入内容'
  158. })
  159. }
  160. })
  161. }
  162. // 表单验证
  163. // 开始时间改变时,重新验证结束时间
  164. const Ref = ref(null)
  165. const rules = reactive({
  166. jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }],
  167. activity: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
  168. permanentGold: [{ required: true, message: '请输入永久金币数', trigger: 'blur' },
  169. {validator: (rule, value, callback) => {
  170. if (value >= 0) {
  171. callback()
  172. } else {
  173. callback(new Error('输入金额至少为0'))
  174. }}}],
  175. freeGold: [{required: true, message: '请输入免费金币数', trigger: 'blur' },
  176. {
  177. validator: (rule, value, callback) => {
  178. // 将值转换为数字(可行吗??)
  179. // 好的不可行
  180. const numValue = Number(value);
  181. if (isNaN(numValue)) {
  182. callback(new Error('请输入有效的数字'));
  183. } else if (numValue >= 0) {
  184. callback();
  185. } else {
  186. callback(new Error('输入金额至少为 0'));
  187. }
  188. },
  189. trigger: 'blur'
  190. }
  191. ],
  192. money: [
  193. {
  194. required: true,
  195. message: '请选择货币名称',
  196. trigger: 'blur'
  197. }
  198. ],
  199. 'recharge.money': [
  200. {
  201. required: true,
  202. message: '请输入充值金额',
  203. trigger: 'blur'
  204. }
  205. ],
  206. payModel: [{ required: true, message: '请选择付款方式', trigger: 'blur' }],
  207. payTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }]
  208. })
  209. // 查找客户信息的方法
  210. const user = ref({})
  211. const getUser = async function (jwcode) {
  212. trimJwCode();
  213. try {
  214. // 发送POST请求
  215. const result = await API({
  216. url: '/user/selectUser',
  217. data: {
  218. jwcode: recharge.value.jwcode
  219. }
  220. })
  221. console.log('请求成功', result)
  222. if (result.code === 0) {
  223. ElMessage.error(result.msg);
  224. } else if (result.data === null) {
  225. ElMessage.error("用户不存在");
  226. } else {
  227. user.value = result.data;
  228. console.log("用户信息", user.value);
  229. ElMessage.success(result.msg);
  230. }
  231. } catch (error) {
  232. console.log("请求失败", error);
  233. ElMessage.error("查询失败,请检查精网号是否正确");
  234. // 在这里可以处理错误逻辑,比如显示错误提示等
  235. }
  236. }
  237. // 这是查询活动的接口
  238. const activity = ref([])
  239. const getActivity = async function () {
  240. try {
  241. // 发送POST请求
  242. const result = await API({
  243. url: '/general/activity',
  244. data: {
  245. }
  246. })
  247. // 将响应结果存储到响应式数据中
  248. console.log('请求成功', result)
  249. // 存储表格数据
  250. activity.value = result.data
  251. console.log('活动信息', activity.value)
  252. } catch (error) {
  253. console.log('activity请求失败', error)
  254. // 在这里可以处理错误逻辑,比如显示错误提示等
  255. }
  256. }
  257. //货币条目
  258. const rateName = [
  259. {
  260. value: 'USD',
  261. label: 'USD',
  262. rateId: 1
  263. },
  264. {
  265. value: 'HKD',
  266. label: 'HKD',
  267. rateId: 2
  268. },
  269. {
  270. value: 'THB',
  271. label: 'THB',
  272. rateId: 3
  273. },
  274. {
  275. value: 'VND',
  276. label: 'VND',
  277. rateId: 4
  278. },
  279. {
  280. value: 'CAD',
  281. label: 'CAD',
  282. rateId: 5
  283. },
  284. {
  285. value: 'MYR',
  286. label: 'MYR',
  287. rateId: 6
  288. },
  289. {
  290. value: 'KRW',
  291. label: 'KRW',
  292. rateId: 7
  293. },
  294. {
  295. value: 'JPY',
  296. label: 'JPY',
  297. rateId: 8
  298. },
  299. {
  300. value: 'CNY',
  301. label: 'CNY',
  302. rateId: 9
  303. }
  304. ]
  305. // 上传图片成功的回调函数
  306. const handleAvatarSuccess = (response, uploadFile) => {
  307. imageUrl.value = URL.createObjectURL(uploadFile.raw)
  308. console.log('图片上传成功', response, uploadFile)
  309. recharge.value.voucher = `http://39.101.133.168:8828/hljw/api/aws/upload`
  310. console.log('图片名称', recharge.value.voucher)
  311. }
  312. //充值方式条目
  313. const payModel = [
  314. {
  315. value: '现金',
  316. label: '现金'
  317. },
  318. {
  319. value: '支票',
  320. label: '支票'
  321. },
  322. {
  323. value: '刷卡',
  324. label: '刷卡'
  325. },
  326. {
  327. value: '其他(各地区电子支付)',
  328. label: '其他(各地区电子支付)'
  329. }
  330. ]
  331. // }
  332. function handleActivityChange(value) {
  333. // 在这里执行你的逻辑,例如获取选中的值
  334. console.log('选中的值:', value)
  335. getActivityById(value)
  336. console.log('看看', recharge.value)
  337. }
  338. //这是重置重置表单的方法
  339. const deleteRecharge = function () {
  340. recharge.value = {
  341. // adminId: adminData.value.adminId,
  342. adminId: fixedAdminId,
  343. market: adminData.value.market,
  344. voucher: '',
  345. rechargeWay: '客服充值',
  346. freeGold: Number(),
  347. money: null,
  348. permanentGold: Number(),
  349. rateId: null
  350. }
  351. imageUrl.value = ''
  352. Rate.value = ''
  353. }
  354. onMounted(async function () {
  355. await getAdminData()
  356. // await getCurrency()
  357. await getActivity()
  358. })
  359. </script>
  360. <template>
  361. <div>
  362. <el-form
  363. :model="recharge"
  364. ref="Ref"
  365. :rules="rules"
  366. label-width="auto"
  367. style="max-width: 600px"
  368. class="add-form"
  369. >
  370. <el-form-item prop="jwcode" label="精网号">
  371. <el-input v-model="recharge.jwcode" style="width: 220px" />
  372. <el-button
  373. type="primary"
  374. @click="getUser(recharge.jwcode)"
  375. style="margin-left: 20px"
  376. >查询</el-button
  377. >
  378. </el-form-item>
  379. <el-form-item prop="activity" label="活动名称">
  380. <el-select
  381. v-model="recharge.activity"
  382. placeholder="请选择"
  383. style="width: 300px"
  384. @change="handleActivityChange"
  385. >
  386. <el-option
  387. v-for="(item, index) in activity"
  388. :key="index"
  389. :label="item"
  390. :value="item"
  391. />
  392. </el-select>
  393. </el-form-item>
  394. <el-form-item prop="permanentGold" label="永久金币">
  395. <el-input v-model="recharge.permanentGold" style="width: 100px" />
  396. <p style="margin-right: 20px"></p>
  397. <p>免费金币</p>
  398. <el-input v-model="recharge.freeGold" style="width: 100px" />
  399. <p></p>
  400. </el-form-item>
  401. <el-form-item label="充值金额">
  402. <el-select
  403. prop="money"
  404. v-model="Rate"
  405. placeholder="货币名称"
  406. style="width: 95px; margin-right: 5px"
  407. aria-required="true"
  408. >
  409. <el-option
  410. v-for="item in rateName"
  411. :key="item.value"
  412. :label="item.label"
  413. :value="item.value"
  414. />
  415. </el-select>
  416. <el-input prop="recharge.money" v-model="recharge.money" style="width: 200px" aria-required="true"/>
  417. </el-form-item>
  418. <el-form-item prop="payModel" label="收款方式">
  419. <el-select
  420. v-model="recharge.payModel"
  421. placeholder="请选择"
  422. style="width: 300px"
  423. >
  424. <el-option
  425. v-for="item in payModel"
  426. :key="item.value"
  427. :label="item.label"
  428. :value="item.value"
  429. />
  430. </el-select>
  431. </el-form-item>
  432. <el-form-item prop="payTime" label="交款时间">
  433. <!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
  434. <el-date-picker
  435. v-model="recharge.payTime"
  436. type="datetime"
  437. style="width: 300px"
  438. />
  439. </el-form-item>
  440. <el-form-item
  441. prop="voucher"
  442. label="交款凭证"
  443. style="margin-bottom: 5px"
  444. >
  445. <el-upload
  446. action="http://39.101.133.168:8828/hljw/api/aws/upload"
  447. class="avatar-uploader"
  448. :show-file-list="false"
  449. :on-success="handleAvatarSuccess"
  450. :before-upload="beforeAvatarUpload"
  451. style="width: 100px; height: 115px"
  452. >
  453. <img
  454. v-if="imageUrl"
  455. :src="imageUrl"
  456. class="avatar"
  457. style="width: 100px; height: 115px"
  458. />
  459. <el-icon
  460. v-else
  461. class="avatar-uploader-icon"
  462. style="width: 100px; height: 100px"
  463. >
  464. <Plus />
  465. </el-icon>
  466. </el-upload>
  467. <p style="margin-left: 10px; color: rgb(177, 176, 176)">
  468. 仅支持.jpg .png格式文件1MB
  469. </p>
  470. </el-form-item>
  471. <el-form-item prop="remark" label="备注">
  472. <el-input
  473. v-model="recharge.remark"
  474. style="width: 300px"
  475. :rows="2"
  476. maxlength="100"
  477. show-word-limit
  478. type="textarea"
  479. />
  480. </el-form-item>
  481. <el-form-item prop="adminId" label="提交人">
  482. <el-input
  483. style="width: 300px"
  484. :value="adminData.adminId"
  485. disabled
  486. placeholder="提交人姓名"
  487. />
  488. </el-form-item>
  489. <el-button @click="deleteRecharge" style="margin-left: 280px" type="success"
  490. >重置</el-button
  491. >
  492. <el-button type="primary" @click="addBefore"> 提交 </el-button>
  493. </el-form>
  494. <!-- 客户信息栏 -->
  495. <el-card v-if="user.jwcode"
  496. style="width: 1200px; float: right"
  497. class="customer-info"
  498. width="3000px"
  499. >
  500. <el-form
  501. :model="user"
  502. label-width="auto"
  503. style="max-width: 1200px"
  504. label-position="left"
  505. >
  506. <el-text size="large" style="margin-left: 20px">客户信息</el-text>
  507. <el-row style="margin-top: 20px">
  508. <el-col :span="10">
  509. <el-form-item label="姓名:">
  510. <p>{{ user.name }}</p>
  511. </el-form-item>
  512. </el-col>
  513. <el-col :span="14">
  514. <el-form-item label="历史金币总数">
  515. <!-- 检查 user.historySumGold 是否为有效的数字 -->
  516. <p style="color: #2fa1ff; margin-right: 5px" v-if="!isNaN(Number(user.historySumGold))">
  517. {{ Number(user.historySumGold ) }}
  518. </p>
  519. <span
  520. style="display: inline; white-space: nowrap; color: #b1b1b1"
  521. v-if="user.historyPermanentGold !== undefined"
  522. >(永久金币:{{ user.historyPermanentGold }};免费金币:{{
  523. (user.historyFreeGold)
  524. }};任务金币:{{ user.historyTaskGold }})</span>
  525. <!-- 如果不是有效的数字显示默认值 -->
  526. <p v-else></p>
  527. </el-form-item>
  528. </el-col>
  529. <el-col :span="10">
  530. <el-form-item label="精网号">
  531. <p>{{ user.jwcode }}</p>
  532. </el-form-item>
  533. </el-col>
  534. <el-col :span="14">
  535. <el-form-item label="当前金币总数" style="width: 500px">
  536. <span
  537. style="color: #2fa1ff; margin-right: 5px"
  538. v-if="user.nowPermanentGold !== undefined"
  539. >{{
  540. (user.nowSumGold)
  541. }}</span
  542. >
  543. <span
  544. style="display: inline; white-space: nowrap; color: #b1b1b1"
  545. v-if="user.nowPermanentGold !== undefined"
  546. >(永久金币:{{ user.nowPermanentGold}};免费金币:{{
  547. (user.nowFreeGold)
  548. }};任务金币:{{ user.nowTaskGold }})</span
  549. >
  550. </el-form-item>
  551. </el-col>
  552. <el-col :span="10">
  553. <el-form-item label="首次充值日期">
  554. <p v-if="user.firstRecharge">
  555. {{ moment(user.firstRecharge).format('YYYY-MM-DD HH:mm:ss') }}
  556. </p>
  557. </el-form-item>
  558. </el-col>
  559. <el-col :span="14">
  560. <el-form-item label="充值次数">
  561. <p style="color: #2fa1ff">{{ user.rechargeNum }}</p>
  562. </el-form-item>
  563. </el-col>
  564. <!-- <el-col :span="10">
  565. <el-form-item label="负责客服">
  566. <p>{{ adminData.name }}</p>
  567. </el-form-item>
  568. </el-col> -->
  569. <el-col :span="10">
  570. <el-form-item label="消费次数">
  571. <p style="color: #2fa1ff">{{ user.consumeNum }}</p>
  572. </el-form-item>
  573. </el-col>
  574. <el-col :span="10">
  575. <el-form-item label="所属门店">
  576. <p>{{ user.market }}</p>
  577. </el-form-item>
  578. </el-col>
  579. <el-col :span="14">
  580. <!-- <el-form-item label="待审核">
  581. <p style="color: #2fa1ff">
  582. {{ user.A }}
  583. </p>
  584. </el-form-item> -->
  585. </el-col>
  586. </el-row>
  587. </el-form>
  588. </el-card>
  589. </div>
  590. </template>
  591. <style scoped>
  592. p {
  593. margin: 0px;
  594. }
  595. .batch-btn {
  596. margin-top: 20px;
  597. margin-left: auto;
  598. }
  599. .el-form-item {
  600. margin-left: 50px;
  601. }
  602. /* 上传图片的格式 */
  603. .avatar-uploader .avatar {
  604. width: 50px;
  605. height: 50px;
  606. display: block;
  607. }
  608. </style>
  609. <style>
  610. .error-message {
  611. color: red;
  612. font-size: 8px;
  613. }
  614. .is-invalid .el-input__inner {
  615. border-color: red;
  616. }
  617. .avatar-uploader .el-upload {
  618. border: 1px dashed var(--el-border-color);
  619. border-radius: 6px;
  620. cursor: pointer;
  621. position: relative;
  622. overflow: hidden;
  623. transition: var(--el-transition-duration-fast);
  624. }
  625. .avatar-uploader .el-upload:hover {
  626. border-color: var(--el-color-primary);
  627. }
  628. .el-icon.avatar-uploader-icon {
  629. font-size: 28px;
  630. color: #8c939d;
  631. width: 50px;
  632. height: 50px;
  633. text-align: center;
  634. }
  635. .add-form {
  636. margin-top: 50px;
  637. max-width: 50%;
  638. float: left;
  639. }
  640. .customer-info {
  641. max-width: 60%;
  642. }
  643. </style>