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.

2212 lines
64 KiB

3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
  1. <script setup>
  2. import { ref, onMounted, reactive, computed, watch, nextTick } from 'vue'
  3. import ElementPlus from 'element-plus'
  4. import { ElMessage,ElMessageBox } from 'element-plus'
  5. import { AiFillRead } from 'vue-icons-plus/ai'
  6. import { Plus } from '@element-plus/icons-vue'
  7. import axios from 'axios'
  8. import API from '@/util/http'
  9. import request from '@/util/http'
  10. import moment from 'moment'
  11. import { range, re } from 'mathjs'
  12. import { utils, read } from 'xlsx'
  13. import throttle from 'lodash/throttle'
  14. //新增充值------------------------------------------------------------------------------
  15. // 精网号去空格
  16. const trimJwCode = () => {
  17. if (addRecharge.value.jwcode) {
  18. addRecharge.value.jwcode = addRecharge.value.jwcode.replace(/\s/g, '');
  19. }
  20. }
  21. // 上传图片前的验证函数
  22. const beforeAvatarUpload = (file) => {
  23. const isJPG = file.type === 'image/jpeg'
  24. const isPNG = file.type === 'image/png'
  25. const isLt2M = file.size / 1024 / 1024 < 2
  26. if (!isJPG && !isPNG) {
  27. ElMessage.error('上传头像图片只能是 JPG 或 PNG 格式!')
  28. }
  29. if (!isLt2M) {
  30. ElMessage.error('上传头像图片大小不能超过 2MB!')
  31. }
  32. return (isJPG || isPNG) && isLt2M
  33. }
  34. const imageUrl = ref('')//上传图片的url
  35. const rechargeVoucher = ref('')//充值凭证
  36. const Rate = ref()//汇率
  37. //请求管理员的接口,充值明细也需要获取到
  38. const adminData = ref({})//管理员信息
  39. const getAdminData = async function () {
  40. try {
  41. const result = await API({
  42. url: '/admin/userinfo',
  43. data: {}
  44. })
  45. adminData.value = result
  46. addRecharge.value.adminId = adminData.value.adminId
  47. addRecharge.value.area = adminData.value.area
  48. console.log('管理员信息请求成功', result)
  49. // console.log('用户信息', user.value),user.value打印的没有什么意义
  50. } catch (error) {
  51. console.log('请求失败', error)
  52. }
  53. }
  54. // 这是添加充值信息的表单
  55. const addRecharge = ref({
  56. rechargeVoucher: '',
  57. rechargeWay: '客服充值',
  58. freeGold: '',
  59. rechargeGold: null,
  60. paidGold: '',
  61. Rate: null,
  62. rechargeRatio: ''
  63. })
  64. // 这是添加充值信息的接口
  65. const add = async function () {
  66. try {
  67. console.log('开始添加充值信息', addRecharge.value)
  68. // 发送POST请求
  69. const result = await API({
  70. url: '/recharge/recharge/add',
  71. data: addRecharge.value
  72. })
  73. if (result.code === 0) {
  74. ElMessage.error(result.msg)
  75. return
  76. }
  77. // 将响应结果存储到响应式数据中
  78. console.log('/recharge/recharge/add请求成功', result)
  79. // 显示成功消息
  80. ElMessage.success('添加成功')
  81. // 重置表单
  82. addRecharge.value = {}
  83. addRecharge.value.adminId = adminData.value.adminId
  84. addRecharge.value.area = adminData.value.area
  85. addRecharge.value.rechargeVoucher = ''
  86. addRecharge.value.rechargeWay = '客服充值'
  87. addRecharge.value.freeGold = ''
  88. addRecharge.value.rechargeGold = null
  89. addRecharge.value.paidGold = ''
  90. imageUrl.value = ''
  91. Rate.value = null
  92. user.value = {}
  93. } catch (error) {
  94. console.log('请求失败', error)
  95. // 在这里可以处理错误逻辑,比如显示错误提示等
  96. }
  97. }
  98. const addBefore = () => {
  99. Ref.value.validate(async (valid) => {
  100. if (valid) {
  101. if (Rate.value == null || Rate.value == '' || Rate.value == undefined) {
  102. ElMessage({
  103. type: 'error',
  104. message: '请选择币种'
  105. })
  106. return
  107. }
  108. if(addRecharge.value.rechargeGold == null || addRecharge.value.rechargeGold == '' || addRecharge.value.rechargeGold == undefined){
  109. ElMessage({
  110. type: 'error',
  111. message: '请输入充值金额'
  112. })
  113. return
  114. }
  115. ElMessageBox.confirm('确认添加?')
  116. .then(() => {
  117. add()
  118. console.log('添加成功')
  119. })
  120. .catch(() => {
  121. console.log('取消添加')
  122. })
  123. } else {
  124. //提示
  125. ElMessage({
  126. type: 'error',
  127. message: '请检查输入内容'
  128. })
  129. }
  130. })
  131. }
  132. // 表单验证
  133. // 开始时间改变时,重新验证结束时间
  134. const Ref = ref(null)
  135. const rules = reactive({
  136. jwcode: [{ required: true, message: '请输入精网号', trigger: 'blur' }],
  137. activityId: [{ required: true, message: '请选择活动名称', trigger: 'blur' }],
  138. paidGold: [
  139. { required: true, message: '请输入永久金币数', trigger: 'blur' },
  140. {
  141. validator: (rule, value, callback) => {
  142. if (value >= 0) {
  143. callback()
  144. } else {
  145. callback(new Error('输入金额至少为0'))
  146. }
  147. }
  148. }
  149. ],
  150. freeGold: [
  151. {
  152. required: true,
  153. message: '请输入免费金币数',
  154. trigger: 'blur'
  155. },
  156. {
  157. validator: (rule, value, callback) => {
  158. if (value == 0) {
  159. callback(new Error('输入金额不可为0'))
  160. } else {
  161. callback()
  162. }
  163. }
  164. }
  165. ],
  166. rechargeGold: [
  167. {
  168. required: true,
  169. message: '请选择货币名称',
  170. trigger: 'blur'
  171. }
  172. ],
  173. 'addRecharge.rechargeGold': [
  174. {
  175. required: true,
  176. message: '请输入充值金额',
  177. trigger: 'blur'
  178. }
  179. ],
  180. payWay: [{ required: true, message: '请选择付款方式', trigger: 'blur' }],
  181. rechargeTime: [{ required: true, message: '请选择交款时间', trigger: 'blur' }]
  182. })
  183. // 查找客户信息的方法
  184. const user = ref({})
  185. const getUser = async function (jwcode) {
  186. trimJwCode();
  187. try {
  188. // 发送POST请求
  189. const result = await API({
  190. url: '/recharge/user',
  191. data: {
  192. jwcode: addRecharge.value.jwcode,
  193. area: adminData.value.area
  194. }
  195. })
  196. console.log('请求成功', result)
  197. if (result.code === 0) {
  198. ElMessage.error(result.msg)
  199. } else {
  200. user.value = result.data
  201. user.value.A =
  202. Number(user.value.pendingRechargeTimes) +
  203. Number(user.value.pendingSpendTimes)
  204. console.log('用户信息', user.value)
  205. ElMessage.success(result.msg)
  206. }
  207. } catch (error) {
  208. console.log('请求失败', error)
  209. ElMessage.error('查询失败,请检查精网号是否正确')
  210. // 在这里可以处理错误逻辑,比如显示错误提示等
  211. }
  212. }
  213. // 这是查询活动的接口
  214. const activity = ref([])
  215. const getActivity = async function () {
  216. try {
  217. // 发送POST请求
  218. const result = await API({
  219. url: '/recharge/activity/select',
  220. data: {
  221. activity: { status: 1 }
  222. }
  223. })
  224. // 将响应结果存储到响应式数据中
  225. console.log('请求成功activity', result)
  226. // 存储表格数据
  227. activity.value = result.data
  228. console.log('活动信息', activity.value)
  229. } catch (error) {
  230. console.log('请求失败', error)
  231. // 在这里可以处理错误逻辑,比如显示错误提示等
  232. }
  233. }
  234. // 这是查询货币的接口
  235. const currency = ref([])
  236. const getCurrency = async function () {
  237. try {
  238. // 发送POST请求
  239. const result = await API({
  240. url: '/rates/status',
  241. data: {}
  242. })
  243. // 将响应结果存储到响应式数据中
  244. console.log('货币请求成功', result)
  245. // 存储表格数据
  246. currency.value = result.data
  247. console.log('currency', currency.value)
  248. // 在这里可以根据需求进一步处理成功后的逻辑,比如更新UI显示成功消息等
  249. } catch (error) {
  250. console.log('请求失败', error)
  251. // 在这里可以处理错误逻辑,比如显示错误提示等
  252. }
  253. }
  254. // 上传图片成功的回调函数
  255. const handleAvatarSuccess = (response, uploadFile) => {
  256. imageUrl.value = URL.createObjectURL(uploadFile.raw)
  257. console.log('图片上传成功', response, uploadFile)
  258. addRecharge.value.rechargeVoucher = `http://54.251.137.151:10704/upload/${response.data}`
  259. console.log('图片名称', addRecharge.value.rechargeVoucher)
  260. }
  261. //充值方式条目
  262. const options = [
  263. {
  264. value: '现金',
  265. label: '现金'
  266. },
  267. {
  268. value: '支票',
  269. label: '支票'
  270. },
  271. {
  272. value: '刷卡',
  273. label: '刷卡'
  274. },
  275. {
  276. value: '其他(各地区电子支付)',
  277. label: '其他(各地区电子支付)'
  278. }
  279. ]
  280. //根据活动id获取汇率
  281. const getActivityById = async function (row) {
  282. try {
  283. // 发送POST请求
  284. const result = await API({
  285. url: '/recharge/activity/select',
  286. data: {
  287. activity: { activityId: row }
  288. }
  289. })
  290. addRecharge.value.rechargeRatio = result.data[0].rechargeRatio
  291. console.log('看看有了吗', addRecharge.value.rechargeRatio)
  292. } catch (error) {
  293. console.log('请求失败', error)
  294. }
  295. }
  296. function handleActivityChange(value) {
  297. // 在这里执行你的逻辑,例如获取选中的值
  298. console.log('选中的值:', value)
  299. getActivityById(value)
  300. console.log('看看', addRecharge.value)
  301. }
  302. //这是重置重置表单的方法
  303. const deleteRecharge = function () {
  304. addRecharge.value = {
  305. adminId: adminData.value.adminId,
  306. area: adminData.value.area,
  307. rechargeVoucher: '',
  308. rechargeWay: '客服充值',
  309. freeGold: Number(),
  310. rechargeGold: null,
  311. paidGold: Number()
  312. }
  313. imageUrl.value = ''
  314. Rate.value = ''
  315. }
  316. // 批量充值
  317. // jwcode列表
  318. const jwcodeList = ref([])
  319. let jwcodeSet
  320. // 获取jwcode列表
  321. const getJwcodeList = async function () {
  322. try {
  323. // 发送POST请求
  324. const result = await API({
  325. url: '/recharge/user/jwcode',
  326. data: {
  327. jwcode: jwcode,
  328. area: adminData.value.area
  329. }
  330. })
  331. // 将响应结果存储到响应式数据中
  332. console.log('请求成功', result)
  333. // 存储表格数据
  334. jwcodeList.value = result.data
  335. console.log('精网号', jwcodeList.value)
  336. // 将数组转换为set
  337. jwcodeSet = new Set(jwcodeList.value)
  338. console.log('精网号set', jwcodeSet)
  339. } catch (error) {
  340. console.log('请求失败jwcodelist', error)
  341. // 在这里可以处理错误逻辑,比如显示错误提示等
  342. }
  343. }
  344. // 校验精网号
  345. // 精网号错误对象
  346. const errorCount = ref(0)
  347. // 校验规则
  348. const validateInput = function (row, index) {
  349. console.log(jwcodeSet.has(row.jwcode), 'has')
  350. if (!jwcodeSet.has(row.jwcode) && row.jwcode != '' && row.jwcode != null) {
  351. row.isInputInvalid = true
  352. row.inputErrorMessage = '精网号不存在'
  353. errorCount.value++
  354. return
  355. } else {
  356. row.isInputInvalid = false
  357. row.inputErrorMessage = ''
  358. errorCount.value--
  359. }
  360. }
  361. // 批量充值弹窗
  362. const batchRechargeVisible = ref(false)
  363. const i = ref(1)
  364. const batchDelObj = ref([])
  365. const resetObj = ref({})
  366. // 批量充值表格数据
  367. const batchData = ref([
  368. {
  369. line: 1,
  370. showInput: true,
  371. isInputInvalid: false,
  372. inputErrorMessage: '',
  373. freeGold: '0',
  374. rechargeGold: '0',
  375. paidGold: '0'
  376. }
  377. ])
  378. // 打开批量充值弹窗
  379. const openBatchRechargeVisible = function () {
  380. batchRechargeVisible.value = true
  381. }
  382. // 关闭批量充值弹窗
  383. const closeBatchRechargeVisible = function () {
  384. batchRechargeVisible.value = false
  385. }
  386. // 批量充值初始化
  387. const batchInit = function () {
  388. openBatchRechargeVisible()
  389. }
  390. // 添加行数对象
  391. const addLineObj = ref(0)
  392. //添加一行
  393. const addLine = function () {
  394. batchData.value.unshift({
  395. line: ++i.value,
  396. showInput: true,
  397. isInputInvalid: false,
  398. inputErrorMessage: '',
  399. freeGold: '0',
  400. rechargeGold: '0',
  401. paidGold: '0'
  402. })
  403. }
  404. const loading = ref(false)
  405. // 添加多行
  406. const addLines = async function () {
  407. try {
  408. loading.value = true // 操作开始前,将loading设为true,显示加载动画
  409. console.log(loading.value, 'loading.value')
  410. await new Promise((resolve) => setTimeout(resolve, 100)) // 人为创建一个小延迟
  411. for (let j = 0; j < addLineObj.value; j++) {
  412. batchData.value.unshift({
  413. line: ++i.value,
  414. showInput: true,
  415. isInputInvalid: false,
  416. inputErrorMessage: '',
  417. freeGold: '0',
  418. rechargeGold: '0',
  419. paidGold: '0'
  420. })
  421. }
  422. ElMessage.success('添加成功')
  423. console.log(batchData.value, 'batchData.value')
  424. } catch (error) {
  425. console.log('添加失败', error)
  426. ElMessage.error('添加失败')
  427. } finally {
  428. loading.value = false
  429. console.log(loading.value, 'loading.value')
  430. }
  431. }
  432. // 添加多行点击按钮
  433. // const addLines = async function () {
  434. // try {
  435. // loading.value = true; // 操作开始前,将loading设为true,显示加载动画
  436. // console.log(loading.value, "loading.value")
  437. // await new Promise(resolve => setTimeout(resolve, 100)); // 人为创建一个小延迟
  438. // const newItems = Array.from({ length: addLineObj.value }, (_, index) => reactive({
  439. // line: ++i.value,
  440. // showInput: true,
  441. // isInputInvalid: false,
  442. // inputErrorMessage: '',
  443. // freeGold: "0",
  444. // rechargeGold: "0",
  445. // paidGold: "0",
  446. // }));
  447. // batchData.value = [...newItems, ...batchData.value];
  448. // ElMessage.success("添加成功");
  449. // console.log(batchData.value, "batchData.value");
  450. // loading.value = false;
  451. // console.log(loading.value, "loading.value")
  452. // } catch (error) {
  453. // console.log("添加失败", error);
  454. // ElMessage.error("添加失败");
  455. // // 如果出现异常,也要确保关闭加载动画
  456. // loading.value = false;
  457. // }
  458. // };
  459. // 使用 _.throttle 并设置 trailing 为 false 实现严格节流,只执行一次
  460. const throttledAddLines = throttle(addLines, 500, { trailing: false })
  461. // 导入excel按钮的ref
  462. const uploadRefMap = ref({})
  463. // 获取excel数据
  464. const excelList = ref([])
  465. // 动态设置upload Ref
  466. const handleSetUploadRefMap = (el) => {
  467. if (el) {
  468. uploadRefMap.value[`Upload_Ref`] = el
  469. }
  470. }
  471. // 文件上传自定义
  472. const httpExcelRequest = async (op) => {
  473. // 获取除文件之外的参数,具体根据实际业务需求来
  474. console.log(op.data)
  475. // 获取上传的excel 并解析数据
  476. let file = op.file
  477. let dataBinary = await readFile(file)
  478. let workBook = read(dataBinary, { type: 'binary', cellDates: true })
  479. let workSheet = workBook.Sheets[workBook.SheetNames[0]]
  480. const excelData = utils.sheet_to_json(workSheet, { header: 1 })
  481. excelList.value = excelData
  482. console.log(excelData)
  483. }
  484. const readFile = (file) => {
  485. return new Promise((resolve) => {
  486. let reader = new FileReader()
  487. reader.readAsBinaryString(file)
  488. reader.onload = (ev) => {
  489. resolve(ev.target?.result)
  490. }
  491. })
  492. }
  493. //获取批量删除的数组
  494. const handleSelectionChangebatch = function (val) {
  495. console.log('val===', val)
  496. batchDelObj.value = val
  497. }
  498. //批量删除
  499. const batchDel = function () {
  500. ElMessageBox.confirm('确认批量删除吗?', '批量删除', {
  501. confirmButtonText: '确定',
  502. cancelButtonText: '取消',
  503. type: 'warning'
  504. })
  505. .then(() => {
  506. console.log('batchDel===', batchDelObj.value)
  507. batchData.value = batchData.value.filter((itemA) => {
  508. return !batchDelObj.value.some((itemB) => itemB.line == itemA.line)
  509. })
  510. console.log('batchData===', batchData.value)
  511. ElMessage({
  512. type: 'success',
  513. message: '操作成功'
  514. })
  515. })
  516. .catch(() => {
  517. ElMessage({
  518. type: 'info',
  519. message: '操作撤销'
  520. })
  521. })
  522. }
  523. //监听改变活动时的操作
  524. const changeActivity = function (row) {
  525. console.log('row===', row)
  526. let ratio = 0
  527. for (let i = 0; i < activity.value.length; i++) {
  528. if (activity.value[i].activityId == row.activityId) {
  529. ratio = activity.value[i].rechargeRatio
  530. break
  531. }
  532. }
  533. console.log('ratio===', ratio)
  534. if (row.paidGold == null || row.paidGold == '') {
  535. row.freeGold = 0
  536. } else {
  537. if (ratio == 0) {
  538. row.freeGold = 0
  539. } else {
  540. row.freeGold = Math.ceil(row.paidGold / ratio)
  541. }
  542. }
  543. }
  544. // //监听改变永久金币时的操作
  545. // const changePaidGold = function (row) {
  546. // console.log('row===', row)
  547. // let ratio = 0
  548. // if (row.activityId == null || row.activityId == '') {
  549. // row.freeGold = 0
  550. // } else {
  551. // for (let i = 0; i < activity.value.length; i++) {
  552. // if (activity.value[i].activityId == row.activityId) {
  553. // ratio = activity.value[i].rechargeRatio
  554. // break
  555. // }
  556. // }
  557. // if (ratio == 0) {
  558. // row.freeGold = 0
  559. // } else {
  560. // row.freeGold = Math.ceil(Number(row.paidGold) / ratio)
  561. // }
  562. // }
  563. // let rate = row.rate
  564. // if (rate == null || rate == '') {
  565. // row.rechargeGold = 0
  566. // } else {
  567. // if (row.paidGold == null || row.paidGold == '') {
  568. // row.rechargeGold = 0
  569. // } else {
  570. // row.rechargeGold = Math.ceil(Number(row.paidGold) * rate)
  571. // }
  572. // }
  573. // }
  574. // 监听改变币种时的操作
  575. const changeRate = function (row) {
  576. console.log('row===', row)
  577. let rate = row.rate
  578. if (rate == null || rate == '') {
  579. row.rechargeGold = 0
  580. } else {
  581. if (row.paidGold == null || row.paidGold == '') {
  582. row.rechargeGold = 0
  583. } else {
  584. row.rechargeGold = Math.ceil(Number(row.paidGold) * rate)
  585. }
  586. }
  587. }
  588. //监听改变凭证时的操作
  589. const changeVoucher = function (row) {
  590. if (
  591. (imageUrl.value != '' && rechargeVoucher.value != '') ||
  592. (imageUrl.value != null && rechargeVoucher.value != null)
  593. ) {
  594. console.log('row===', row)
  595. row.imageUrl = imageUrl.value
  596. row.rechargeVoucher = rechargeVoucher.value
  597. console.log('row===', row)
  598. imageUrl.value = ''
  599. rechargeVoucher.value = ''
  600. }
  601. }
  602. // 上传图片成功的回调函数
  603. const handleBatchAvatarSuccess = (response, uploadFile) => {
  604. imageUrl.value = URL.createObjectURL(uploadFile.raw)
  605. console.log('图片上传成功', response, uploadFile)
  606. rechargeVoucher.value = `http://54.251.137.151:10704/upload/${response.data}`
  607. console.log('图片名称', rechargeVoucher.value)
  608. }
  609. //批量充值确认按钮
  610. const batchAdd = async function () {
  611. try {
  612. console.log('batchData===', batchData.value)
  613. let msg = ''
  614. if (batchData.value.length == 0) {
  615. ElMessage({
  616. type: 'error',
  617. message: '至少需要输入一条数据!'
  618. })
  619. return
  620. }
  621. if (errorCount.value > 0) {
  622. console.log('errorCount.value', errorCount.value)
  623. ElMessage({
  624. type: 'error',
  625. message: '请检查输入的精网号是否正确!'
  626. })
  627. return
  628. }
  629. for (let i = 0; i < batchData.value.length; i++) {
  630. batchData.value[i].adminId = adminData.value.adminId
  631. batchData.value[i].area = adminData.value.area
  632. batchData.value[i].rechargeWay = '客服充值'
  633. if (
  634. batchData.value[i].jwcode == '' ||
  635. batchData.value[i].jwcode == null
  636. ) {
  637. msg += `精网号不能为空! <br/>`
  638. }
  639. if (
  640. batchData.value[i].activityId == '' ||
  641. batchData.value[i].activityId == null
  642. ) {
  643. msg += `活动不能为空! <br/>`
  644. }
  645. if (
  646. batchData.value[i].paidGold == '' ||
  647. batchData.value[i].paidGold == null
  648. ) {
  649. msg += `永久金币不能为空! <br/>`
  650. }
  651. if (
  652. batchData.value[i].freeGold == '' ||
  653. batchData.value[i].freeGold == null
  654. ) {
  655. msg += `免费金币不能为空! <br/>`
  656. }
  657. if (
  658. batchData.value[i].rechargeGold == '' ||
  659. batchData.value[i].rechargeGold == null
  660. ) {
  661. msg += `充值金额不能为空! <br/>`
  662. }
  663. if (
  664. batchData.value[i].payWay == '' ||
  665. batchData.value[i].payWay == null
  666. ) {
  667. msg += `收款方式不能为空! <br/>`
  668. }
  669. if (
  670. batchData.value[i].rechargeTime == '' ||
  671. batchData.value[i].rechargeTime == null
  672. ) {
  673. msg += `交款时间不能为空! <br/>`
  674. }
  675. if (msg != '' && msg != null) {
  676. console.log(batchData.value[i])
  677. ElMessage({
  678. dangerouslyUseHTMLString: true,
  679. type: 'error',
  680. message: msg
  681. })
  682. return
  683. }
  684. }
  685. console.log('batchData===', batchData.value)
  686. const result = await API({
  687. url: '/recharge/recharge/addmore',
  688. data: {
  689. ...batchData.value
  690. }
  691. })
  692. if (result.code === 0) {
  693. ElMessage.error('添加失败')
  694. return
  695. }
  696. ElMessage({
  697. type: 'success',
  698. message: '添加成功!'
  699. })
  700. closeBatchRechargeVisible()
  701. } catch (error) {
  702. console.log('error===', error)
  703. ElMessage.error('添加失败')
  704. return
  705. }
  706. }
  707. // 使用 _.throttle 并设置 trailing 为 false 实现严格节流,只执行一次
  708. const throttledBatchAdd = throttle(batchAdd, 2000, { trailing: false })
  709. // 批量设置的对象
  710. const batchSettingObj = ref({
  711. rechargeGold: '0',
  712. paidGold: '0',
  713. freeGold: '0'
  714. })
  715. // 批量充值弹窗
  716. const batchSettingVisible = ref(false)
  717. // 打开批量充值弹窗
  718. const openBatchSettingVisible = function () {
  719. batchSettingVisible.value = true
  720. }
  721. // 关闭批量充值弹窗
  722. const closeBatchSettingVisible = function () {
  723. batchSettingVisible.value = false
  724. }
  725. // 批量设置初始化
  726. const batchSettingInit = function () {
  727. openBatchSettingVisible()
  728. }
  729. // 上传图片成功的回调函数
  730. const batchSettingHandleAvatarSuccess = (response, uploadFile) => {
  731. batchSettingObj.value.imageUrl = URL.createObjectURL(uploadFile.raw)
  732. console.log('图片上传成功', response, uploadFile)
  733. batchSettingObj.value.rechargeVoucher = `http://54.251.137.151:10704/upload/${response.data}`
  734. console.log('图片名称', batchSettingObj.value.rechargeVoucher)
  735. }
  736. // 批量设置取消按钮
  737. const cancelBatchSetting = function () {
  738. batchSettingObj.value = {
  739. rechargeGold: '0',
  740. paidGold: '0',
  741. freeGold: '0'
  742. }
  743. closeBatchSettingVisible()
  744. }
  745. // 批量设置确认按钮
  746. const batchSettingConfirm = function () {
  747. for (let i = 0; i < batchData.value.length; i++) {
  748. if (
  749. batchSettingObj.value.jwcode != '' &&
  750. batchSettingObj.value.jwcode != null
  751. ) {
  752. batchData.value[i].jwcode = batchSettingObj.value.jwcode
  753. }
  754. if (
  755. batchSettingObj.value.activityId != '' &&
  756. batchSettingObj.value.activityId != null
  757. ) {
  758. batchData.value[i].activityId = batchSettingObj.value.activityId
  759. }
  760. if (
  761. batchSettingObj.value.paidGold != '' &&
  762. batchSettingObj.value.paidGold != null
  763. ) {
  764. batchData.value[i].paidGold = batchSettingObj.value.paidGold
  765. }
  766. if (
  767. batchSettingObj.value.freeGold != '' &&
  768. batchSettingObj.value.freeGold != null
  769. ) {
  770. batchData.value[i].freeGold = batchSettingObj.value.freeGold
  771. }
  772. if (
  773. batchSettingObj.value.rate != '' &&
  774. batchSettingObj.value.rate != null
  775. ) {
  776. batchData.value[i].rate = batchSettingObj.value.rate
  777. }
  778. if (
  779. batchSettingObj.value.rechargeGold != '' &&
  780. batchSettingObj.value.rechargeGold != null
  781. ) {
  782. batchData.value[i].rechargeGold = batchSettingObj.value.rechargeGold
  783. }
  784. if (
  785. batchSettingObj.value.payWay != '' &&
  786. batchSettingObj.value.payWay != null
  787. ) {
  788. batchData.value[i].payWay = batchSettingObj.value.payWay
  789. }
  790. if (
  791. batchSettingObj.value.rechargeTime != '' &&
  792. batchSettingObj.value.rechargeTime != null
  793. ) {
  794. batchData.value[i].rechargeTime = batchSettingObj.value.rechargeTime
  795. }
  796. if (
  797. batchSettingObj.value.imageUrl != '' &&
  798. batchSettingObj.value.imageUrl != null
  799. ) {
  800. batchData.value[i].imageUrl = batchSettingObj.value.imageUrl
  801. }
  802. if (
  803. batchSettingObj.value.rechargeVoucher != '' &&
  804. batchSettingObj.value.rechargeVoucher != null
  805. ) {
  806. batchData.value[i].rechargeVoucher = batchSettingObj.value.rechargeVoucher
  807. }
  808. if (
  809. batchSettingObj.value.remark != '' &&
  810. batchSettingObj.value.remark != null
  811. ) {
  812. batchData.value[i].remark = batchSettingObj.value.remark
  813. }
  814. }
  815. batchSettingObj.value = {
  816. rechargeGold: '0',
  817. paidGold: '0',
  818. freeGold: '0'
  819. }
  820. closeBatchSettingVisible()
  821. }
  822. //充值明细表单-------------------------------------------------------------------------------
  823. //获取管理员用户信息的接口*
  824. //变量
  825. //充值明细表格
  826. const tableData = ref([])
  827. //搜索=========================================
  828. //搜索recharge
  829. const rechargeVo = ref({
  830. adminId: adminData.value.adminId
  831. })
  832. //搜索对象
  833. const getObj = ref({
  834. pageNum: 1,
  835. pageSize: 50
  836. })
  837. //分页总条目
  838. const total = ref(100)
  839. // 搜索对象时间
  840. const getTime = ref([])
  841. // 搜索活动列表*
  842. // 所有信息
  843. const allData = ref([])
  844. // 搜索地区列表
  845. const area = ref([])
  846. //标签页默认高亮选项
  847. const activeName = ref('all')
  848. //充值方式选项
  849. const rechargeWay = [
  850. {
  851. value: '客户储值',
  852. label: '客户储值'
  853. },
  854. {
  855. value: '平台充值',
  856. label: '平台充值'
  857. }
  858. ]
  859. // 支付方式选项
  860. const payWay = [
  861. {
  862. value: '现金',
  863. label: '现金'
  864. },
  865. {
  866. value: '支票',
  867. label: '支票'
  868. },
  869. {
  870. value: '刷卡',
  871. label: '刷卡'
  872. },
  873. {
  874. value: '其他(各地区电子支付)',
  875. label: '其他(各地区电子支付)'
  876. }
  877. ]
  878. // 删除==========================================================
  879. // 删除对象
  880. const delObj = ref({})
  881. // 方法
  882. // 合计数存储
  883. const trueGold = ref(0)
  884. const trueRGold = ref(0)
  885. const trueFGold = ref(0)
  886. // 搜索===========================================================================
  887. // 搜索方法
  888. const get = async function (val) {
  889. try {
  890. // 地区赋值
  891. if (adminData.value.area === '泰国') {
  892. rechargeVo.value.areas = ['泰国', '越南']
  893. } else if (adminData.value.area !== '总部') {
  894. rechargeVo.value.area = adminData.value.area
  895. }
  896. // 搜索参数页码赋值
  897. if (typeof val === 'number') {
  898. getObj.value.pageNum = val
  899. }
  900. // 搜索参数时间赋值
  901. if (getTime.value != null) {
  902. if (getTime.value.startDate != '' && getTime.value.endDate != '') {
  903. rechargeVo.value.startDate = getTime.value[0]
  904. rechargeVo.value.endDate = getTime.value[1]
  905. }
  906. } else {
  907. rechargeVo.value.startDate = ''
  908. rechargeVo.value.endDate = ''
  909. }
  910. // 搜索参数赋值
  911. rechargeVo.value.sortField = sortField.value
  912. rechargeVo.value.sortOrder = sortOrder.value
  913. console.log('搜索参数', getObj.value)
  914. // 发送POST请求
  915. const result = await API({
  916. url: '/recharge/recharge',
  917. data: { ...getObj.value, rechargeVo: { ...rechargeVo.value } }
  918. })
  919. console.log('请求成功get',result)
  920. // 计算充值金额、永久金币、免费金币总和
  921. trueGold.value = 0
  922. trueRGold.value = 0
  923. trueFGold.value = 0
  924. if (result.data && result.data.list) {
  925. result.data.list.forEach((item) => {
  926. trueGold.value += item.paidGold || 0
  927. trueRGold.value += item.paidGold || 0
  928. trueFGold.value += item.freeGold || 0
  929. })
  930. }
  931. // 将响应结果存储到响应式数据中
  932. console.log('请求成功', result)
  933. // 存储表格数据
  934. tableData.value = result.data.list
  935. console.log('tableData', tableData.value)
  936. // 存储分页总数
  937. total.value = result.data.total
  938. console.log('total', total.value)
  939. } catch (error) {
  940. console.log('请求失败get', error)
  941. // 在这里可以处理错误逻辑,比如显示错误提示等
  942. }
  943. }
  944. // 搜索
  945. const search = function () {
  946. getObj.value.pageNum = 1
  947. get()
  948. }
  949. // 重置
  950. const reset = function () {
  951. delete rechargeVo.value.jwcode
  952. delete rechargeVo.value.activityId
  953. delete rechargeVo.value.rechargeWay
  954. delete rechargeVo.value.area
  955. delete rechargeVo.value.startDate
  956. delete rechargeVo.value.endDate
  957. delete sortField.value
  958. delete sortOrder.value
  959. getTime.value = []
  960. }
  961. // 新增排序字段和排序方式
  962. const sortField = ref('')
  963. const sortOrder = ref('')
  964. // 处理排序事件
  965. const handleSortChange = (column) => {
  966. get()
  967. console.log('排序字段:', column.prop)
  968. console.log('排序方式:', column.order)
  969. if (column.prop === 'paidGold') {
  970. sortField.value = 'recharge_gold'
  971. } else if (column.prop === 'freeGold') {
  972. sortField.value = 'free_gold'
  973. } else if (column.prop === 'rechargeTime') {
  974. sortField.value = 'recharge_time'
  975. } else if (column.prop === 'createTime') {
  976. sortField.value = 'create_time'
  977. }
  978. sortOrder.value = column.order === 'ascending' ? 'ASC' : 'DESC'
  979. console.log('传递给后端的排序字段:', sortField.value)
  980. console.log('传递给后端的排序方式:', sortOrder.value)
  981. get()
  982. }
  983. // 今天
  984. const getToday = function () {
  985. const today = new Date()
  986. const startDate = new Date(
  987. today.getFullYear(),
  988. today.getMonth(),
  989. today.getDate()
  990. )
  991. const endDate = new Date(
  992. today.getFullYear(),
  993. today.getMonth(),
  994. today.getDate() + 1
  995. )
  996. getTime.value = [startDate, endDate]
  997. console.log('getTime', getTime.value)
  998. get()
  999. }
  1000. const handlePageSizeChange = function (val) {
  1001. getObj.value.pageSize = val
  1002. get()
  1003. }
  1004. const handleCurrentChange = function (val) {
  1005. getObj.value.pageNum = val
  1006. get()
  1007. }
  1008. // 昨天
  1009. const getYesterday = function () {
  1010. const yesterday = new Date()
  1011. yesterday.setDate(yesterday.getDate() - 1)
  1012. const startDate = new Date(
  1013. yesterday.getFullYear(),
  1014. yesterday.getMonth(),
  1015. yesterday.getDate()
  1016. )
  1017. const endDate = new Date(
  1018. yesterday.getFullYear(),
  1019. yesterday.getMonth(),
  1020. yesterday.getDate() + 1
  1021. )
  1022. getTime.value = [startDate, endDate]
  1023. console.log('getTime', getTime.value)
  1024. get()
  1025. }
  1026. // 近7天
  1027. const get7Days = function () {
  1028. const today = new Date()
  1029. const startDate = new Date(
  1030. today.getFullYear(),
  1031. today.getMonth(),
  1032. today.getDate() - 6
  1033. )
  1034. const endDate = new Date(
  1035. today.getFullYear(),
  1036. today.getMonth(),
  1037. today.getDate() + 1
  1038. )
  1039. getTime.value = [startDate, endDate]
  1040. console.log('getTime', getTime.value)
  1041. get()
  1042. }
  1043. //获取活动名称*
  1044. //获取地区
  1045. const getArea = async function () {
  1046. try {
  1047. const result = await request({
  1048. url: '/recharge/user/search',
  1049. data: {}
  1050. })
  1051. //将响应结果存储到响应式数据中
  1052. console.log('area请求成功',result)
  1053. //存储地区信息
  1054. area.value = result.data
  1055. console.log('area',area.value)
  1056. } catch (error) {
  1057. console.log('area请求失败',error)
  1058. ElMessage.error('获取地区数据失败')
  1059. }
  1060. }
  1061. // 删除=================================
  1062. // 点击删除按钮
  1063. const del = function (row) {
  1064. delObj.value.rechargeId = row.rechargeId
  1065. console.log('delObj1', delObj.value)
  1066. }
  1067. // 确认删除按钮
  1068. const delConfirm = async function () {
  1069. try {
  1070. console.log('delObj2', delObj.value)
  1071. const result = await API({
  1072. url: '/recharge/recharge/edit',
  1073. data: delObj.value
  1074. })
  1075. console.log('删除成功', result)
  1076. // 刷新表格数据
  1077. get()
  1078. } catch (error) {
  1079. console.log('请求失败', error)
  1080. // 在这里可以处理错误逻辑,比如显示错误提示等
  1081. }
  1082. }
  1083. // 验证跳转输入框的数字是否合法
  1084. const checkNumber = function () {
  1085. if (typeof !isNaN(parseInt(getObj.value.pageNum)) === 'number') {
  1086. console.log('总共有多少页' + Math.ceil(total.value / getObj.value.pageSize))
  1087. if (
  1088. getObj.value.pageNum > 0 &&
  1089. getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
  1090. ) {
  1091. getObj.value.pageNum = parseInt(getObj.value.pageNum)
  1092. console.log('输入的数字合法')
  1093. get()
  1094. } else {
  1095. //提示
  1096. ElMessage({
  1097. type: 'error',
  1098. message: '请检查输入内容'
  1099. })
  1100. }
  1101. } else {
  1102. //提示
  1103. ElMessage({
  1104. type: 'error',
  1105. message: '输入内容非数字'
  1106. })
  1107. }
  1108. }
  1109. //新增充值和充值明细-------------------------------------------------------------------------
  1110. // 用于控制显示内容的变量
  1111. const activeTab = ref('addRecharge')
  1112. // 切换标签页的方法
  1113. const changeTab = async (tabName) => {
  1114. activeTab.value = tabName
  1115. if(tabName === 'detail'){
  1116. //切换至明细标签时调用get方法
  1117. await get()
  1118. }
  1119. }
  1120. // 挂载
  1121. onMounted(async function () {
  1122. await getAdminData()
  1123. await getCurrency()
  1124. await getActivity()
  1125. await getArea()
  1126. await getJwcodeList()
  1127. //调用get方法获取明细数据
  1128. //await get()
  1129. })
  1130. </script>
  1131. <template>
  1132. <div>
  1133. <el-button-group>
  1134. <!-- 切换后状态显示样式否则是默认样式 -->
  1135. <el-button
  1136. :type="activeTab === 'addRecharge' ? 'primary' : 'default'"
  1137. @click="changeTab('addRecharge')"
  1138. >
  1139. 新增充值
  1140. </el-button>
  1141. <el-button
  1142. :type="activeTab === 'detail' ? 'primary' : 'default'"
  1143. @click="changeTab('detail')"
  1144. >
  1145. 金币充值明细
  1146. </el-button>
  1147. </el-button-group>
  1148. <!-- 根据activeTab切换显示内容 -->
  1149. <!-- 新增充值的布局------------------------------------------------------------------- -->
  1150. <div v-if="activeTab === 'addRecharge'">
  1151. <!-- <div style="display: flex">
  1152. <div style="margin-right: 20px">新增充值</div>
  1153. </div> -->
  1154. <el-form
  1155. :model="addRecharge"
  1156. ref="Ref"
  1157. :rules="rules"
  1158. label-width="auto"
  1159. style="max-width: 600px"
  1160. class="add-form"
  1161. >
  1162. <el-form-item prop="jwcode" label="精网号">
  1163. <el-input v-model="addRecharge.jwcode" style="width: 220px" />
  1164. <el-button
  1165. type="primary"
  1166. @click="getUser(addRecharge.jwcode)"
  1167. style="margin-left: 20px"
  1168. >查询</el-button
  1169. >
  1170. </el-form-item>
  1171. <el-form-item prop="activityId" label="活动名称">
  1172. <el-select
  1173. v-model="addRecharge.activityId"
  1174. placeholder="请选择"
  1175. style="width: 300px"
  1176. @change="handleActivityChange"
  1177. >
  1178. <el-option
  1179. v-for="item in activity"
  1180. :key="item.value"
  1181. :label="item.activityName"
  1182. :value="item.activityId"
  1183. />
  1184. </el-select>
  1185. </el-form-item>
  1186. <el-col>
  1187. <el-form-item prop="paidGold" label="永久金币">
  1188. <el-input v-model="addRecharge.paidGold" style="width: 100px" />
  1189. <p style="margin-right: 20px"></p>
  1190. </el-form-item>
  1191. <el-form-item prop="freeGold" label="免费金币">
  1192. <el-input v-model="addRecharge.freeGold" style="width: 100px" />
  1193. <p></p>
  1194. </el-form-item>
  1195. </el-col>
  1196. <el-form-item label="充值金额">
  1197. <el-select
  1198. prop="rechargeGold"
  1199. v-model="Rate"
  1200. placeholder="货币名称"
  1201. style="width: 95px; margin-right: 5px"
  1202. aria-required="true"
  1203. >
  1204. <el-option
  1205. v-for="item in currency"
  1206. :key="item.value"
  1207. :label="item.currency"
  1208. :value="item.exchangeRate"
  1209. />
  1210. </el-select>
  1211. <el-input prop="addRecharge.rechargeGold" v-model="addRecharge.rechargeGold" style="width: 200px" aria-required="true"/>
  1212. </el-form-item>
  1213. <el-form-item prop="payWay" label="收款方式">
  1214. <el-select
  1215. v-model="addRecharge.payWay"
  1216. placeholder="请选择"
  1217. style="width: 300px"
  1218. >
  1219. <el-option
  1220. v-for="item in options"
  1221. :key="item.value"
  1222. :label="item.label"
  1223. :value="item.value"
  1224. />
  1225. </el-select>
  1226. </el-form-item>
  1227. <el-form-item prop="rechargeTime" label="交款时间">
  1228. <!-- 修改 type 属性为 datetime 以支持时分秒选择 -->
  1229. <el-date-picker
  1230. v-model="addRecharge.rechargeTime"
  1231. type="datetime"
  1232. style="width: 300px"
  1233. />
  1234. </el-form-item>
  1235. <el-form-item
  1236. prop="rechargeVoucher"
  1237. label="交款凭证"
  1238. style="margin-bottom: 5px"
  1239. >
  1240. <el-upload
  1241. action="http://39.101.133.168:8828/hljw/api/aws/upload"
  1242. class="avatar-uploader"
  1243. :show-file-list="false"
  1244. :on-success="handleAvatarSuccess"
  1245. :before-upload="beforeAvatarUpload"
  1246. style="width: 100px; height: 115px"
  1247. >
  1248. <img
  1249. v-if="imageUrl"
  1250. :src="imageUrl"
  1251. class="avatar"
  1252. style="width: 100px; height: 115px"
  1253. />
  1254. <el-icon
  1255. v-else
  1256. class="avatar-uploader-icon"
  1257. style="width: 100px; height: 100px"
  1258. >
  1259. <Plus />
  1260. </el-icon>
  1261. </el-upload>
  1262. <p style="margin-left: 10px; color: rgb(177, 176, 176)">
  1263. 仅支持.jpg .png格式文件2MB
  1264. </p>
  1265. </el-form-item>
  1266. <el-form-item prop="remark" label="备注">
  1267. <el-input
  1268. v-model="addRecharge.remark"
  1269. style="width: 300px"
  1270. :rows="2"
  1271. maxlength="100"
  1272. show-word-limit
  1273. type="textarea"
  1274. />
  1275. </el-form-item>
  1276. <el-form-item prop="submitter" label="提交人">
  1277. <el-input
  1278. style="width: 300px"
  1279. :value="adminData.name"
  1280. disabled
  1281. placeholder="提交人姓名"
  1282. />
  1283. </el-form-item>
  1284. <el-button @click="deleteRecharge" style="margin-left: 280px" type="success"
  1285. >重置</el-button
  1286. >
  1287. <el-button type="primary" @click="addBefore"> 提交 </el-button>
  1288. </el-form>
  1289. <!-- 客户信息栏 -->
  1290. <el-card
  1291. style="width: 1200px; float: right;margin-bottom:20px;margin-top: 10px;"
  1292. class="customer-info"
  1293. width="3000px"
  1294. >
  1295. <el-form
  1296. :model="user"
  1297. label-width="auto"
  1298. style="max-width: 1200px"
  1299. label-position="left"
  1300. >
  1301. <el-text size="large" style="margin-left: 20px">客户信息</el-text>
  1302. <el-row style="margin-top: 20px">
  1303. <el-col :span="10">
  1304. <el-form-item label="姓名:">
  1305. <p>{{ user.name }}</p>
  1306. </el-form-item>
  1307. </el-col>
  1308. <el-col :span="14">
  1309. <el-form-item label="历史金币总数">
  1310. <!-- 检查 user.totalRechargeGold 是否为有效的数字 -->
  1311. <p v-if="!isNaN(Number(user.totalRechargeGold))">
  1312. {{ Number(user.totalRechargeGold / 100) }}
  1313. </p>
  1314. <!-- 如果不是有效的数字显示默认值 -->
  1315. <p v-else></p>
  1316. </el-form-item>
  1317. </el-col>
  1318. <el-col :span="10">
  1319. <el-form-item label="精网号">
  1320. <p>{{ user.jwcode }}</p>
  1321. </el-form-item>
  1322. </el-col>
  1323. <el-col :span="14">
  1324. <el-form-item label="当前金币总数" style="width: 500px">
  1325. <span
  1326. style="color: #2fa1ff; margin-right: 5px"
  1327. v-if="user.buyJb !== undefined"
  1328. >{{
  1329. (user.buyJb + user.free6 + user.free12 + user.coreJb) / 100
  1330. }}</span
  1331. >
  1332. <span
  1333. style="display: inline; white-space: nowrap; color: #b1b1b1"
  1334. v-if="user.buyJb !== undefined"
  1335. >(永久金币:{{ user.buyJb / 100 }};免费金币:{{
  1336. (user.free6 + user.free12) / 100
  1337. }};任务金币:{{ user.coreJb / 100 }})</span
  1338. >
  1339. </el-form-item>
  1340. </el-col>
  1341. <el-col :span="10">
  1342. <el-form-item label="首次充值日期">
  1343. <p v-if="user.firstRechargeDate">
  1344. {{ moment(user.firstRechargeDate).format('YYYY-MM-DD HH:mm:ss') }}
  1345. </p>
  1346. </el-form-item>
  1347. </el-col>
  1348. <el-col :span="14">
  1349. <el-form-item label="充值次数">
  1350. <p style="color: #2fa1ff">{{ user.rechargeTimes }}</p>
  1351. </el-form-item>
  1352. </el-col>
  1353. <!-- <el-col :span="10">
  1354. <el-form-item label="负责客服">
  1355. <p>{{ adminData.name }}</p>
  1356. </el-form-item>
  1357. </el-col> -->
  1358. <el-col :span="10">
  1359. <el-form-item label="消费次数">
  1360. <p style="color: #2fa1ff">{{ user.spendTimes }}</p>
  1361. </el-form-item>
  1362. </el-col>
  1363. <el-col :span="10">
  1364. <el-form-item label="所属门店">
  1365. <p>{{ adminData.area }}</p>
  1366. </el-form-item>
  1367. </el-col>
  1368. <el-col :span="14">
  1369. <!-- <el-form-item label="待审核">
  1370. <p style="color: #2fa1ff">
  1371. {{ user.A }}
  1372. </p>
  1373. </el-form-item> -->
  1374. </el-col>
  1375. </el-row>
  1376. </el-form>
  1377. </el-card>
  1378. <el-dialog
  1379. v-model="batchRechargeVisible"
  1380. title="批量充值"
  1381. width="1800px"
  1382. style="height: 700px"
  1383. :close-on-click-modal="false"
  1384. >
  1385. <el-row style="margin-bottom: 10px">
  1386. <!-- <el-button type="primary" @click="addLine()" style="margin-right: 10px">新增一行</el-button> -->
  1387. <div style="font-weight: bold; font-size: 20px">
  1388. <span>添加</span>
  1389. <el-input-number
  1390. min="1"
  1391. style="width: 100px"
  1392. controls-position="right"
  1393. v-model="addLineObj"
  1394. ></el-input-number>
  1395. <span></span>
  1396. <el-button
  1397. type="primary"
  1398. @click="throttledAddLines"
  1399. style="margin-right: 10px"
  1400. >添加</el-button
  1401. >
  1402. </div>
  1403. <el-button
  1404. type="warning"
  1405. @click="batchSettingInit()"
  1406. style="margin-right: 10px"
  1407. >批量设置</el-button
  1408. >
  1409. <!-- <el-upload :ref="(el) => handleSetUploadRefMap(el)" action="" :http-request="httpExcelRequest" :limit="1" :show-file-list="false"
  1410. class="uploadExcelContent" :data={} style="margin-right: auto">
  1411. <el-button type="success" >导入jwcode</el-button>
  1412. </el-upload> -->
  1413. <el-button
  1414. type="danger"
  1415. plain
  1416. @click="batchDel()"
  1417. style="margin-right: 10px; width: 130px"
  1418. >批量删除</el-button
  1419. >
  1420. </el-row>
  1421. <el-row>
  1422. <el-table
  1423. v-loading="loading"
  1424. :data="batchData"
  1425. border
  1426. max-height="540px"
  1427. style="height: 540px"
  1428. @selection-change="handleSelectionChangebatch"
  1429. >
  1430. <el-table-column type="selection" width="50px" />
  1431. <el-table-column property="index" label="序号" width="55px">
  1432. <template #default="scope">
  1433. <span>{{ scope.$index + 1 }}</span>
  1434. </template>
  1435. </el-table-column>
  1436. <el-table-column property="jwcode" label="精网号" width="150px">
  1437. <template #default="scope">
  1438. <el-input
  1439. v-if="scope.row.showInput"
  1440. :class="{ 'is-invalid': scope.row.isInputInvalid }"
  1441. @blur="validateInput(scope.row)"
  1442. v-model="scope.row.jwcode"
  1443. style="width: 110px"
  1444. />
  1445. <p v-if="scope.row.isInputInvalid" class="error-message">
  1446. {{ scope.row.inputErrorMessage }}
  1447. </p>
  1448. </template>
  1449. <!-- <template #default="scope">
  1450. <el-select-v2 v-if="scope.row.showInput" filterable clearable v-model="scope.row.jwcode"
  1451. placeholder="请选择精网号" style="widows: 110px;" :options="jwcodeList">
  1452. <el-select-v2
  1453. v-if="scope.row.showInput"
  1454. filterable
  1455. clearable
  1456. v-model="scope.row.jwcode"
  1457. placeholder="请选择精网号"
  1458. style="widows: 110px"
  1459. :options="jwcodeList"
  1460. >
  1461. </el-select-v2>
  1462. <span v-else>{{ scope.row.jwcode }}</span>
  1463. </template> -->
  1464. </el-table-column>
  1465. <el-table-column property="activityName" label="活动名称" width="150px">
  1466. <template #default="scope">
  1467. <el-select
  1468. v-if="scope.row.showInput"
  1469. filterable
  1470. clearable
  1471. v-model="scope.row.activityId"
  1472. placeholder="请选择活动名称"
  1473. @change="changeActivity(scope.row)"
  1474. >
  1475. <el-option
  1476. v-for="item in activity"
  1477. :key="item.activityId"
  1478. :label="item.activityName"
  1479. :value="item.activityId"
  1480. >
  1481. </el-option>
  1482. </el-select>
  1483. <span v-else>{{ scope.row.activityName }}</span>
  1484. </template>
  1485. </el-table-column>
  1486. <el-table-column property="paidGold" label="永久金币" width="110px">
  1487. <template #default="scope">
  1488. <el-input
  1489. v-if="scope.row.showInput"
  1490. v-model="scope.row.paidGold"
  1491. style="width: 70px"
  1492. @change="changePaidGold(scope.row)"
  1493. />
  1494. <span v-else>{{ scope.row.paidGold }}</span>
  1495. </template>
  1496. </el-table-column>
  1497. <el-table-column property="freeGold" label="免费金币" width="110px">
  1498. <template #default="scope">
  1499. <el-input
  1500. v-if="scope.row.showInput"
  1501. v-model="scope.row.freeGold"
  1502. style="width: 70px"
  1503. />
  1504. <span v-else>{{ scope.row.freeGold }}</span>
  1505. </template>
  1506. </el-table-column>
  1507. <el-table-column property="rate" label="货币名称">
  1508. <template #default="scope">
  1509. <el-select
  1510. v-if="scope.row.showInput"
  1511. filterable
  1512. clearable
  1513. v-model="scope.row.rate"
  1514. placeholder="请选择币种"
  1515. @change="changeRate(scope.row)"
  1516. >
  1517. <el-option
  1518. v-for="item in currency"
  1519. :key="item.exchangeRate"
  1520. :label="item.currency"
  1521. :value="item.exchangeRate"
  1522. >
  1523. </el-option>
  1524. </el-select>
  1525. <span v-else>{{ scope.row.rate }}</span>
  1526. </template>
  1527. </el-table-column>
  1528. <el-table-column label="充值金额" width="110px">
  1529. <template #default="scope">
  1530. <el-input property="rechargeGold" v-model="scope.row.rechargeGold"></el-input>
  1531. </template>
  1532. </el-table-column>
  1533. <el-table-column property="payWay" label="收款方式" width="130px">
  1534. <template #default="scope">
  1535. <el-select
  1536. v-if="scope.row.showInput"
  1537. filterable
  1538. clearable
  1539. v-model="scope.row.payWay"
  1540. placeholder="请选择收款方式"
  1541. >
  1542. <el-option
  1543. v-for="item in options"
  1544. :key="item.value"
  1545. :label="item.label"
  1546. :value="item.value"
  1547. >
  1548. </el-option>
  1549. </el-select>
  1550. <span v-else>{{ scope.row.payWay }}</span>
  1551. </template>
  1552. </el-table-column>
  1553. <el-table-column property="rechargeTime" label="交款时间" width="150px">
  1554. <template #default="scope">
  1555. <el-date-picker
  1556. v-if="scope.row.showInput"
  1557. type="date"
  1558. v-model="scope.row.rechargeTime"
  1559. style="width: 120px"
  1560. placeholder="请选择交款时间"
  1561. >
  1562. </el-date-picker>
  1563. <span v-else>{{
  1564. moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss')
  1565. }}</span>
  1566. </template>
  1567. </el-table-column>
  1568. <el-table-column property="rechargeVoucher" label="充值凭证">
  1569. <template #default="scope">
  1570. <el-upload
  1571. action="http://39.101.133.168:8828/hljw/api/aws/upload"
  1572. class="avatar-uploader"
  1573. :show-file-list="false"
  1574. :on-success="handleBatchAvatarSuccess"
  1575. v-if="scope.row.showInput"
  1576. @change="changeVoucher(scope.row)"
  1577. >
  1578. <img
  1579. v-if="scope.row.imageUrl"
  1580. :src="scope.row.imageUrl"
  1581. class="avatar"
  1582. />
  1583. <el-icon v-else class="avatar-uploader-icon">
  1584. <Plus />
  1585. </el-icon>
  1586. </el-upload>
  1587. <span v-else>{{ scope.row.rechargeVoucher }}</span>
  1588. </template>
  1589. </el-table-column>
  1590. <el-table-column property="remark" label="备注" width="130px">
  1591. <template #default="scope">
  1592. <el-input
  1593. type="textarea"
  1594. v-if="scope.row.showInput"
  1595. v-model="scope.row.remark"
  1596. style="max-width: 90px"
  1597. :rows="1"
  1598. cols="12"
  1599. ></el-input>
  1600. <span v-else>{{ scope.row.remark }}</span>
  1601. </template>
  1602. </el-table-column>
  1603. <el-table-column property="submitter" label="提交人">
  1604. <el-input :value="adminData.name" disabled />
  1605. </el-table-column>
  1606. <el-table-column
  1607. fixed="right"
  1608. prop="operation"
  1609. label="操作"
  1610. width="150px"
  1611. >
  1612. <template #default="scope">
  1613. <div style="display: flex">
  1614. <el-popconfirm
  1615. title="确定将此条信息删除吗?"
  1616. @confirm="delConfirm"
  1617. >
  1618. <template #reference>
  1619. <el-button type="danger" text @click="del(scope.row)">
  1620. 删除
  1621. </el-button>
  1622. </template>
  1623. <template #actions="{ confirm, cancel }">
  1624. <el-button size="small" @click="cancel">取消</el-button>
  1625. <el-button type="primary" size="small" @click="confirm">
  1626. 确定
  1627. </el-button>
  1628. </template>
  1629. </el-popconfirm>
  1630. <el-popconfirm
  1631. title="确定将此条信息重置吗?"
  1632. @confirm="resetConfirm"
  1633. >
  1634. <template #reference>
  1635. <el-button type="success" text @click="reset(scope.row)">
  1636. 重置
  1637. </el-button>
  1638. </template>
  1639. <template #actions="{ confirm, cancel }">
  1640. <el-button size="small" @click="cancel">取消</el-button>
  1641. <el-button type="primary" size="small" @click="confirm">
  1642. 确定
  1643. </el-button>
  1644. </template>
  1645. </el-popconfirm>
  1646. </div>
  1647. </template>
  1648. </el-table-column>
  1649. </el-table>
  1650. </el-row>
  1651. <el-row>
  1652. <div class="batch-btn">
  1653. <el-button @click="cancelBatch()"> 取消 </el-button>
  1654. <el-button type="primary" @click="throttledBatchAdd()">
  1655. 提交
  1656. </el-button>
  1657. </div>
  1658. </el-row>
  1659. </el-dialog>
  1660. <el-dialog
  1661. v-model="batchSettingVisible"
  1662. title="批量设置"
  1663. :close-on-click-modal="false"
  1664. style="width: 550px"
  1665. >
  1666. <el-form label-position="left" label-width="auto">
  1667. <el-form-item label="活动名称">
  1668. <el-select
  1669. v-model="batchSettingObj.activityId"
  1670. placeholder="请选择活动名称"
  1671. clearable
  1672. >
  1673. <el-option
  1674. v-for="item in activity"
  1675. :key="item.activityId"
  1676. :label="item.activityName"
  1677. :value="item.activityId"
  1678. >
  1679. </el-option>
  1680. </el-select>
  1681. </el-form-item>
  1682. <el-form-item label="永久金币">
  1683. <el-input
  1684. v-model="batchSettingObj.paidGold"
  1685. placeholder="请输入永久金币"
  1686. ></el-input>
  1687. </el-form-item>
  1688. <el-form-item label="免费金币">
  1689. <el-input v-model="batchSettingObj.freeGold"></el-input>
  1690. </el-form-item>
  1691. <el-form-item label="充值金额">
  1692. <div style="display: flex">
  1693. <el-select
  1694. v-model="batchSettingObj.rate"
  1695. placeholder="请选择币种"
  1696. style="width: 120px; margin-right: 10px"
  1697. clearable
  1698. >
  1699. <el-option
  1700. v-for="item in currency"
  1701. :key="item.exchangeRate"
  1702. :label="item.currency"
  1703. :value="item.exchangeRate"
  1704. ></el-option>
  1705. </el-select>
  1706. <el-input
  1707. v-model="batchSettingObj.rechargeGold"
  1708. placeholder="请输入充值金额"
  1709. ></el-input>
  1710. </div>
  1711. </el-form-item>
  1712. <el-form-item prop="payWay" label="收款方式">
  1713. <el-select
  1714. v-model="batchSettingObj.payWay"
  1715. placeholder="请选择收款方式"
  1716. clearable
  1717. >
  1718. <el-option
  1719. v-for="item in options"
  1720. :key="item.value"
  1721. :label="item.label"
  1722. :value="item.value"
  1723. ></el-option>
  1724. </el-select>
  1725. </el-form-item>
  1726. <el-form-item prop="rechargeTime" label="交款时间">
  1727. <el-date-picker
  1728. v-model="batchSettingObj.rechargeTime"
  1729. type="date"
  1730. placeholder="请选择交款时间"
  1731. ></el-date-picker>
  1732. </el-form-item>
  1733. <el-form-item prop="rechargeVoucher" label="交款凭证">
  1734. <el-upload
  1735. action="http://39.101.133.168:8828/hljw/api/aws/upload"
  1736. class="avatar-uploader"
  1737. :show-file-list="false"
  1738. :on-success="batchSettingHandleAvatarSuccess"
  1739. :before-upload="beforeAvatarUpload"
  1740. style="width: 100px; height: 115px"
  1741. >
  1742. <img
  1743. v-if="batchSettingObj.imageUrl"
  1744. :src="batchSettingObj.imageUrl"
  1745. class="avatar"
  1746. style="width: 100px; height: 115px"
  1747. />
  1748. <el-icon
  1749. v-else
  1750. class="avatar-uploader-icon"
  1751. style="width: 100px; height: 100px"
  1752. >
  1753. <Plus />
  1754. </el-icon>
  1755. </el-upload>
  1756. </el-form-item>
  1757. <el-form-item prop="remark" label="备注">
  1758. <el-input
  1759. type="textarea"
  1760. v-model="batchSettingObj.remark"
  1761. placeholder="请输入备注"
  1762. />
  1763. </el-form-item>
  1764. </el-form>
  1765. <el-button @click="cancelBatchSetting()" style="margin-left: 370px"
  1766. >取消</el-button
  1767. >
  1768. <el-button type="primary" @click="batchSettingConfirm()"> 确认 </el-button>
  1769. </el-dialog>
  1770. </div>
  1771. <!-- 金币充值明细的布局---------------------------------------------------------- -->
  1772. <div v-else-if="activeTab === 'detail'">
  1773. <el-row>
  1774. <el-col>
  1775. <el-card style="margin-bottom: 20px;margin-top: 10px">
  1776. <el-row style="margin-bottom: 10px">
  1777. <el-col :span="5">
  1778. <div class="head-card-element">
  1779. <el-text class="mx-1" size="large">精网号</el-text>
  1780. <el-input v-model="rechargeVo.jwcode" placeholder="请输入精网号" style="width: 150px" clearable />
  1781. </div>
  1782. </el-col>
  1783. <el-col :span="6">
  1784. <div class="head-card-element">
  1785. <el-text class="mx-1" size="large">活动名称</el-text>
  1786. <el-select v-model="rechargeVo.activityId" placeholder="请选择活动名称" style="width: 180px"
  1787. clearable>
  1788. <el-option v-for="item in activity" :key="item.activityId" :label="item.activityName"
  1789. :value="item.activityId" />
  1790. </el-select>
  1791. </div>
  1792. </el-col>
  1793. <el-col :span="6">
  1794. <div class="head-card-element" v-if="adminData.area == '总部'">
  1795. <el-text class="mx-1" size="large">所属地区</el-text>
  1796. <el-select v-model="rechargeVo.area" placeholder="请选择所属地区" style="width: 180px" clearable>
  1797. <el-option v-for="item in area" :key="item" :label="item" :value="item" />
  1798. </el-select>
  1799. </div>
  1800. </el-col>
  1801. <el-col :span="6">
  1802. <div class="head-card-element">
  1803. <el-text class="mx-1" size="large">充值类型</el-text>
  1804. <el-select v-model="rechargeVo.rechargeWay" placeholder="请选择支付方式" style="width: 180px" clearable>
  1805. <el-option v-for="item in rechargeWay" :key="item.value" :label="item.label" :value="item.value" />
  1806. </el-select>
  1807. </div>
  1808. </el-col>
  1809. </el-row>
  1810. <el-row>
  1811. <el-col :span="21">
  1812. <div class="head-card-element">
  1813. <el-text class="mx-1" size="large">充值时间</el-text>
  1814. <el-date-picker
  1815. v-model="getTime"
  1816. type="datetimerange"
  1817. range-separator="至"
  1818. start-placeholder="起始时间"
  1819. end-placeholder="结束时间"
  1820. />
  1821. <el-button style="margin-left: 10px" @click="getToday()"
  1822. ></el-button
  1823. >
  1824. <el-button @click="getYesterday()"></el-button>
  1825. <el-button @click="get7Days()">近7天</el-button>
  1826. <!-- </div>
  1827. </el-col>
  1828. <el-col :span="3">
  1829. <div class="head-card-btn"> -->
  1830. <el-button type="success" @click="reset()">重置</el-button>
  1831. <el-button type="primary" @click="search()">查询</el-button>
  1832. <el-button type="primary" @click="exportExcel()">导出Excel</el-button>
  1833. </div>
  1834. </el-col>
  1835. </el-row>
  1836. </el-card>
  1837. </el-col>
  1838. </el-row>
  1839. <el-row>
  1840. <el-col>
  1841. <el-card>
  1842. <div>
  1843. 充值金额{{ trueRGold.toFixed(2) }}新币永久金币{{
  1844. trueRGold.toFixed(2)
  1845. }}金币免费金币{{ trueFGold }}金币
  1846. </div>
  1847. <!-- 设置表格容器的高度和滚动样式 -->
  1848. <div style="height: 520px; overflow-y: auto;margin-top: 10px;">
  1849. <el-table
  1850. :data="tableData"
  1851. style="width: 100%"
  1852. height="520px"
  1853. @sort-change="handleSortChange"
  1854. >
  1855. <el-table-column
  1856. type="index"
  1857. label="序号"
  1858. width="80px"
  1859. fixed="left"
  1860. >
  1861. <template #default="scope">
  1862. <span>{{
  1863. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  1864. }}</span>
  1865. </template>
  1866. </el-table-column>
  1867. <el-table-column
  1868. fixed="left"
  1869. prop="username"
  1870. label="姓名"
  1871. width="80px"
  1872. />
  1873. <el-table-column
  1874. fixed="left"
  1875. prop="jwcode"
  1876. label="精网号"
  1877. width="80px"
  1878. />
  1879. <el-table-column prop="area" label="所属地区" width="100px" />
  1880. <el-table-column
  1881. prop="activityName"
  1882. label="活动名称"
  1883. width="100px"
  1884. />
  1885. <el-table-column prop="" label="货币名称" width="110px" />
  1886. <el-table-column
  1887. prop="paidGold"
  1888. sortable="custom"
  1889. label="充值金额"
  1890. width="110px"
  1891. />
  1892. <el-table-column
  1893. prop="paidGold"
  1894. label="永久金币"
  1895. sortable="custom"
  1896. width="110px"
  1897. />
  1898. <el-table-column
  1899. prop="freeGold"
  1900. label="免费金币"
  1901. sortable="custom"
  1902. width="110px"
  1903. />
  1904. <el-table-column
  1905. prop="rechargeWay"
  1906. label="充值方式"
  1907. width="100px"
  1908. />
  1909. <el-table-column prop="payWay" label="支付方式" width="100px" />
  1910. <el-table-column
  1911. prop="remark"
  1912. label="备注"
  1913. width="150px"
  1914. show-overflow-tooltip
  1915. />
  1916. <!-- <el-table-column
  1917. prop="rechargeVoucher"
  1918. label="支付凭证"
  1919. width="150px"
  1920. >
  1921. <template #default="scope">
  1922. <el-image
  1923. :preview-src-list="[scope.row.rechargeVoucher]"
  1924. preview-teleported="true"
  1925. :src="scope.row.rechargeVoucher"
  1926. alt="凭证"
  1927. style="width: 50px; height: 50px"
  1928. />
  1929. </template>
  1930. </el-table-column> -->
  1931. <el-table-column prop="name" label="提交人" width="100px" />
  1932. <!-- <el-table-column prop="status" label="状态" width="100px">
  1933. <template #default="scope">
  1934. <span v-if="scope.row.status === 1">
  1935. <div class="status">
  1936. <span class="green-dot"></span>
  1937. <span>已通过</span>
  1938. </div>
  1939. </span>
  1940. <span v-if="scope.row.status === 0">
  1941. <div class="status">
  1942. <span class="grey-dot"></span>
  1943. <span>待审核</span>
  1944. </div>
  1945. </span>
  1946. <span v-if="scope.row.status === 2">
  1947. <div class="status">
  1948. <span class="red-dot"></span>
  1949. <span>已驳回</span>
  1950. </div>
  1951. </span>
  1952. </template>
  1953. </el-table-column>
  1954. <el-table-column
  1955. prop="reson"
  1956. label="驳回理由"
  1957. width="200px"
  1958. show-overflow-tooltip
  1959. /> -->
  1960. <el-table-column
  1961. prop="rechargeTime"
  1962. sortable
  1963. label="充值时间"
  1964. width="200px"
  1965. >
  1966. <template #default="scope">
  1967. {{
  1968. moment(scope.row.rechargeTime).format('YYYY-MM-DD HH:mm:ss')
  1969. }}
  1970. </template>
  1971. </el-table-column>
  1972. <!-- <el-table-column
  1973. prop="createTime"
  1974. sortable="custom"
  1975. label="提交时间"
  1976. width="200px"
  1977. />
  1978. <el-table-column
  1979. fixed="right"
  1980. prop="operation"
  1981. label="操作"
  1982. width="150px"
  1983. >
  1984. <template #default="scope">
  1985. <el-popconfirm
  1986. title="确定将此条活动删除吗?"
  1987. @confirm="delConfirm"
  1988. >
  1989. <template #reference>
  1990. <el-button type="primary" text @click="del(scope.row)">
  1991. 删除
  1992. </el-button>
  1993. </template>
  1994. <template #actions="{ confirm, cancel }">
  1995. <el-button size="small" @click="cancel">取消</el-button>
  1996. <el-button type="primary" size="small" @click="confirm">
  1997. 确定
  1998. </el-button>
  1999. </template>
  2000. </el-popconfirm>
  2001. </template>
  2002. </el-table-column> -->
  2003. </el-table>
  2004. </div>
  2005. <!-- 分页 -->
  2006. <div class="pagination" style="margin-top: 20px">
  2007. <el-pagination
  2008. background
  2009. :page-size="getObj.pageSize"
  2010. :page-sizes="[5, 10, 20, 50, 100]"
  2011. layout="total, sizes, prev, pager, next, jumper"
  2012. :total="total"
  2013. @size-change="handlePageSizeChange"
  2014. @current-change="handleCurrentChange"
  2015. ></el-pagination>
  2016. </div>
  2017. </el-card>
  2018. </el-col>
  2019. </el-row>
  2020. <!-- 编辑弹窗 -->
  2021. <el-dialog
  2022. v-model="editRechargeVisible"
  2023. title="新增活动"
  2024. width="500"
  2025. :before-close="closeEditRechargeVisible"
  2026. >
  2027. <template #footer>
  2028. <el-form :model="editObj" label-width="auto" style="max-width: 600px">
  2029. <el-form-item label="活动名称:">
  2030. <el-input
  2031. v-model="addObj.activityName"
  2032. placeholder="请输入活动名称"
  2033. style="width: 220px"
  2034. />
  2035. </el-form-item>
  2036. <el-form-item label="免费金币:">
  2037. <el-radio-group v-model="addObj.freeGold">
  2038. <el-radio value="0">无赠送</el-radio>
  2039. <el-radio value="1">有赠送</el-radio>
  2040. </el-radio-group>
  2041. </el-form-item>
  2042. <el-form-item label="免费金币兑换比:">
  2043. <el-input
  2044. v-model="addObj.rechargeRatio"
  2045. placeholder="请输入"
  2046. style="width: 80px"
  2047. />1
  2048. <div style="color: grey">(提示当前规则每10新币可兑换1免费金币)</div>
  2049. </el-form-item>
  2050. <el-form-item label="开始时间:">
  2051. <el-time-picker v-model="addObj.startTime" />
  2052. </el-form-item>
  2053. <el-form-item label="结束时间:">
  2054. <el-time-picker v-model="addObj.endTime" />
  2055. </el-form-item>
  2056. <el-form-item label="添加人:">
  2057. <el-input v-model="addObj.adminName" disabled style="width: 220px" />
  2058. </el-form-item>
  2059. </el-form>
  2060. <div class="dialog-footer">
  2061. <el-button @click="closeAddActivityVisible">取消</el-button>
  2062. <el-button type="primary" @click="closeAddActivityVisible">
  2063. 提交
  2064. </el-button>
  2065. </div>
  2066. </template>
  2067. </el-dialog>
  2068. </div>
  2069. </div>
  2070. </template>
  2071. <style scoped>
  2072. p {
  2073. margin: 0px;
  2074. }
  2075. .batch-btn {
  2076. margin-top: 20px;
  2077. margin-left: auto;
  2078. }
  2079. .el-form-item {
  2080. margin-left: 50px;
  2081. }
  2082. /* 上传图片的格式 */
  2083. .avatar-uploader .avatar {
  2084. width: 50px;
  2085. height: 50px;
  2086. display: block;
  2087. }
  2088. </style>
  2089. <style>
  2090. .error-message {
  2091. color: red;
  2092. font-size: 8px;
  2093. }
  2094. .is-invalid .el-input__inner {
  2095. border-color: red;
  2096. }
  2097. .avatar-uploader .el-upload {
  2098. border: 1px dashed var(--el-border-color);
  2099. border-radius: 6px;
  2100. cursor: pointer;
  2101. position: relative;
  2102. overflow: hidden;
  2103. transition: var(--el-transition-duration-fast);
  2104. }
  2105. .avatar-uploader .el-upload:hover {
  2106. border-color: var(--el-color-primary);
  2107. }
  2108. .el-icon.avatar-uploader-icon {
  2109. font-size: 28px;
  2110. color: #8c939d;
  2111. width: 50px;
  2112. height: 50px;
  2113. text-align: center;
  2114. }
  2115. .add-form {
  2116. margin-top: 50px;
  2117. max-width: 50%;
  2118. float: left;
  2119. }
  2120. .customer-info {
  2121. max-width: 60%;
  2122. }
  2123. </style>