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.

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