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.

816 lines
25 KiB

2 months ago
2 months ago
2 months ago
5 months ago
6 months ago
6 months ago
5 months ago
6 months ago
5 months ago
2 months ago
2 months ago
2 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
6 months ago
2 months ago
5 months ago
5 months ago
6 months ago
5 months ago
5 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
5 months ago
2 months ago
6 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
2 months ago
6 months ago
2 months ago
6 months ago
6 months ago
  1. <template>
  2. <el-card class="card1" style="margin-bottom: 0.5vh;">
  3. <el-col style="margin-bottom: 1vh">
  4. <div class="select">
  5. <div class="selectRow">
  6. <el-text class="text" size="large">精网号</el-text>
  7. <el-input class="selectContent" v-model="searchForm.jwcode" placeholder="请输入精网号" clearable />
  8. </div>
  9. <div class="selectRow">
  10. <el-text class="text" size="large">商品名称</el-text>
  11. <el-select class="selectContent" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable>
  12. <el-option v-for="item in refundGoodsOptions" :key="item" :label="item" :value="item"></el-option>
  13. </el-select>
  14. </div>
  15. <div class="selectRow">
  16. <el-text class="text" size="large">退款类型</el-text>
  17. <el-select class="selectContent" v-model="searchForm.refundType" placeholder="请选择退款类型" clearable>
  18. <el-option label="商品退款" value="商品退款" />
  19. <el-option label="金币退款" value="金币退款" />
  20. </el-select>
  21. </div>
  22. <div class="selectRow">
  23. <el-text class="text" size="large">所属地区</el-text>
  24. <el-cascader class="selectContent" style="width: 12vw;" v-model="selectedMarketPath" :options="market"
  25. placeholder="请选择所属地区" clearable @change="handleMarketChange" />
  26. </div>
  27. </div>
  28. </el-col>
  29. <el-col>
  30. <div class="select">
  31. <div class="selectRow" style="width: 36vw;">
  32. <el-text class="text" size="large">
  33. {{ activeName === 'wait' ? '提交时间:' : '审核时间:' }}
  34. </el-text>
  35. <el-date-picker class="selectContent" v-model="dateRange" type="datetimerange" range-separator=""
  36. start-placeholder="起始时间" end-placeholder="结束时间" style="margin-right:1vw;width:25vw"
  37. @change="handleDatePickerChange" :default-time="defaultTime" :disabled-date="disabledDate" />
  38. <div v-if="false">
  39. <el-button @click="getToday()" :type="activeTimeRange === 'today' ? 'primary' : ''"></el-button>
  40. <el-button @click="getYesterday()" :type="activeTimeRange === 'yesterday' ? 'primary' : ''"></el-button>
  41. <el-button @click="get7Days()" :type="activeTimeRange === '7days' ? 'primary' : ''">近7天</el-button>
  42. </div>
  43. </div>
  44. <div class="selectRow" style="justify-content: flex-start;">
  45. <el-button @click="handleSearch" type="primary">查询</el-button>
  46. <el-button @click="resetSearch" type="success">重置</el-button>
  47. </div>
  48. </div>
  49. </el-col>
  50. </el-card>
  51. <el-card class="card2">
  52. <div class="custom-button-group">
  53. <el-button v-if="hasrefundWait && hasrefundWaitShow" :type="activeName === 'wait' ? 'primary' : 'default'"
  54. @click="handleButtonClick('wait')" class="custom-tab-button">
  55. 待审核
  56. </el-button>
  57. <el-button v-if="hasrefundThrough" :type="activeName === 'pass' ? 'primary' : 'default'"
  58. @click="handleButtonClick('pass')" class="custom-tab-button">
  59. 已通过
  60. </el-button>
  61. <el-button v-if="hasrefundReject" :type="activeName === 'reject' ? 'primary' : 'default'"
  62. @click="handleButtonClick('reject')" class="custom-tab-button">
  63. 已驳回
  64. </el-button>
  65. </div>
  66. <div class="goldStatistics">
  67. 退款总金币数{{
  68. format3((stats.permanentGolds + stats.freeGolds + stats.taskGolds).toFixed(2))
  69. }}金币&nbsp;&nbsp;&nbsp;&nbsp;
  70. 永久金币{{ format3(stats.permanentGolds.toFixed(2)) }}金币&nbsp;&nbsp;&nbsp;&nbsp;
  71. 免费金币{{ format3(stats.freeGolds.toFixed(2)) }}金币&nbsp;&nbsp;&nbsp;&nbsp;
  72. 任务金币{{ format3(stats.taskGolds.toFixed(2)) }}金币
  73. </div>
  74. <el-table :data="tableData" style="height:61vh;width:82vw" @sort-change="handleSortChange"
  75. :row-style="{ height: '50px' }">
  76. <el-table-column fixed="left" type="index" label="序号" width="60" />
  77. <el-table-column fixed="left" prop="name" label="姓名" width="120" show-overflow-tooltip />
  78. <el-table-column fixed="left" prop="jwcode" label="精网号" width="120" />
  79. <el-table-column prop="market" label="所属地区" width="120" />
  80. <el-table-column prop="orderCode" label="订单号" width="260px" show-overflow-tooltip />
  81. <el-table-column prop="refundType" label="退款类型" width="120" />
  82. <el-table-column prop="refundModel" label="退款方式" width="120">
  83. <template #default="{ row }">
  84. {{ row.refundModel === 0 ? '全部退款' : '部分退款' }}
  85. </template>
  86. </el-table-column>
  87. <el-table-column prop="goodsName" label="退款商品" width="120" show-overflow-tooltip />
  88. <el-table-column prop="sumGold" label="退款金币总数" width="160" sortable="custom">
  89. <template #default="{ row }">
  90. {{ row.sumGold / 100 }}
  91. </template>
  92. </el-table-column>
  93. <el-table-column prop="permanentGold" label="永久金币" width="120" sortable="custom">
  94. <template #default="{ row }">
  95. {{ row.permanentGold / 100 }}
  96. </template>
  97. </el-table-column>
  98. <el-table-column prop="freeGold" label="免费金币" width="120" sortable="custom">
  99. <template #default="{ row }">
  100. {{ (row.freeJune + row.freeDecember) / 100 }}
  101. </template>
  102. </el-table-column>
  103. <el-table-column prop="taskGold" label="任务金币" width="120" sortable="custom">
  104. <template #default="{ row }">
  105. {{ row.taskGold / 100 }}
  106. </template>
  107. </el-table-column>
  108. <el-table-column prop="remark" label="备注" width="150" show-overflow-tooltip />
  109. <el-table-column prop="adminName" label="提交人" width="120" />
  110. <el-table-column v-if="checkTab === 'reject'" prop="rejectReason" label="驳回理由" width="150"
  111. show-overflow-tooltip />
  112. <el-table-column v-if="checkTab !== 'pending'" prop="auditName" label="审核人" width="120" />
  113. <el-table-column prop="createTime" label="提交时间" width="180" sortable="custom">
  114. <template #default="{ row }">
  115. {{
  116. checkTab === 'pending'
  117. ? moment(row.auditTime).format('YYYY-MM-DD HH:mm:ss')
  118. : moment(row.createTime).format('YYYY-MM-DD HH:mm:ss')
  119. }}
  120. </template>
  121. </el-table-column>
  122. <el-table-column v-if="checkTab !== 'pending'" prop="auditTime" label="审核时间" width="180">
  123. <template #default="{ row }">
  124. {{ row.auditTime ? moment(row.auditTime).format('YYYY-MM-DD HH:mm:ss') : '--' }}
  125. </template>
  126. </el-table-column>
  127. <el-table-column
  128. v-if="checkTab === 'pending' && (hasrefundWaitThough || hasrefundWaitReject) && hasrefundWaitShow" fixed="right"
  129. prop="operation" label="操作" width="150px">
  130. <template #default="scope">
  131. <div class="operation">
  132. <el-link :underline="false" class="pass-btn" v-if="hasrefundWaitThough"
  133. :disabled="clicked || cancelClicked"type="primary"
  134. @click="showApproveDialog(scope.row)">
  135. 通过
  136. </el-link>
  137. <el-link :underline="false" class="reject-btn" v-if="hasrefundWaitReject"
  138. :disabled="clicked || cancelClicked" type="primary"
  139. @click="showRejectDialog(scope.row)">
  140. 驳回
  141. </el-link>
  142. </div>
  143. </template>
  144. </el-table-column>
  145. </el-table>
  146. <el-pagination class="pagination" background :current-page="pagination.pageNum" :page-size="pagination.pageSize"
  147. layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" @size-change="handlePageSizeChange"
  148. @current-change="handleCurrentChange"></el-pagination>
  149. </el-card>
  150. <!-- 退款驳回理由输入框 -->
  151. <el-dialog v-model="rejectReasonDialogVisible" title="驳回理由" width="500px">
  152. <el-form>
  153. <el-form-item label="驳回理由" required>
  154. <el-input v-model="rejectReason" type="textarea" :rows="4" placeholder="请输入驳回理由" maxlength="200"
  155. show-word-limit />
  156. </el-form-item>
  157. </el-form>
  158. <template #footer>
  159. <span class="dialog-footer">
  160. <el-button @click="rejectReasonDialogVisible = false">取消</el-button>
  161. <el-button type="primary" @click="handleReject">确定</el-button>
  162. </span>
  163. </template>
  164. </el-dialog>
  165. <ConfirmDialog
  166. v-model="rejectDialogVisible"
  167. message="驳回该记录!"
  168. @confirm="showRejectReasonInput"
  169. @cancel="handleRejectCancel"
  170. @close="handleRejectClose"
  171. />
  172. <!-- 新增使用ConfirmDialog组件 -->
  173. <ConfirmDialog
  174. v-model="approveDialogVisible"
  175. message="通过该记录!"
  176. @confirm="handleApproveConfirm"
  177. @cancel="handleApproveCancel"
  178. @close="handleApproveClose"
  179. />
  180. </template>
  181. <script setup>
  182. import { onMounted, reactive, ref, watch } from 'vue'
  183. import { ElMessage } from 'element-plus'
  184. import API from '@/util/http.js'
  185. import moment from 'moment'
  186. import { useAdminStore } from "@/store/index.js";
  187. import { storeToRefs } from "pinia";
  188. import dayjs from "dayjs";
  189. import { permissionMapping, hasMenuPermission } from "@/utils/menuTreePermission.js"
  190. import ConfirmDialog from '@/components/dialogs/ConfirmDialog.vue';
  191. const adminStore = useAdminStore();
  192. const { adminData, menuTree, flag } = storeToRefs(adminStore);
  193. // 监听全局flag状态变化
  194. watch(flag, (newFlag, oldFlag) => {
  195. // 当flag状态改变时,重新发送请求
  196. if (newFlag !== oldFlag) {
  197. get()
  198. getStats()
  199. }
  200. })
  201. const defaultTime = [
  202. new Date(2000, 1, 1, 0, 0, 0),
  203. new Date(2000, 2, 1, 23, 59, 59),
  204. ]
  205. // 当前激活的时间按钮
  206. const activeTimeRange = ref('')
  207. const currentRecord = ref(null) // 当前行信息
  208. const rejectDialogVisible = ref(false)
  209. const rejectReasonDialogVisible = ref(false)
  210. const rejectReason = ref('')
  211. const approveDialogVisible = ref(false)
  212. // 状态常量
  213. const STATUS = {
  214. PENDING: 0, // 待审核
  215. APPROVED: 1, // 通过
  216. REJECTED: 2 // 驳回
  217. }
  218. //无法选择的时间
  219. const disabledDate = (time) => {
  220. const limitDate = new Date(2025, 0, 1);
  221. return time.getTime() < limitDate.getTime();
  222. }
  223. // 搜索表单数据
  224. const searchForm = ref({
  225. jwcode: '',
  226. refundModel: '',
  227. goodsName: '',
  228. market: "",
  229. startTime: '',
  230. endTime: '',
  231. auditStatus: '0'
  232. })
  233. const checkTab = ref('pending') // 能否不用STATUS常量,0是待审批,1是已通过,2是驳回,参数status需要Integer
  234. const dateRange = ref([])
  235. const pagination = ref({
  236. pageNum: 1,
  237. pageSize: 50,
  238. total: 0
  239. })
  240. const tableData = ref([])
  241. const marketOptions = ref([])
  242. const refundGoodsOptions = ref([])
  243. const adminInfo = ref({})
  244. // 统计合计数
  245. const stats = ref({
  246. totalNum: 0,
  247. totalCoins: 0,
  248. permanentGolds: 0,
  249. freeGolds: 0,
  250. taskGolds: 0
  251. })
  252. const rejectVisible = ref(false)
  253. const rejectObj = ref({})
  254. const passObj = ref({})
  255. // 标签页默认是待审批
  256. const activeName = ref('wait')
  257. const sortField = ref('')
  258. const sortOrder = ref('')
  259. const market = ref("")
  260. //退款操作权限
  261. const hasrefundThrough = ref(false) // 退款审核已通过
  262. const hasrefundReject = ref(false) // 退款审核已驳回
  263. const hasrefundWait = ref(false) // 退款审核待审核
  264. const hasrefundWaitShow = ref(false) // 退款审核待审核查看
  265. const hasrefundWaitThough = ref(false) // 退款审核通过
  266. const hasrefundWaitReject = ref(false) // 退款审核驳回
  267. // 初始化权限状态
  268. const initPermissions = async () => {
  269. if (!menuTree.value || !menuTree.value.length) return;
  270. // 退款相关权限
  271. hasrefundThrough.value = hasMenuPermission(menuTree.value, permissionMapping.gold_coin_refund_approved);
  272. hasrefundReject.value = hasMenuPermission(menuTree.value, permissionMapping.gold_coin_refund_rejected);
  273. hasrefundWait.value = hasMenuPermission(menuTree.value, permissionMapping.gold_coin_refund_pending);
  274. hasrefundWaitShow.value = hasMenuPermission(menuTree.value, permissionMapping.view_gold_refund_pending);
  275. hasrefundWaitThough.value = hasMenuPermission(menuTree.value, permissionMapping.pass_gold_refund_audit);
  276. hasrefundWaitReject.value = hasMenuPermission(menuTree.value, permissionMapping.reject_gold_refund_audit);
  277. console.log('退款权限赋值完成');
  278. };
  279. // 处理排序事件
  280. const handleSortChange = (column) => {
  281. if (column.prop === 'sumGold') {
  282. sortField.value = 'sum_gold'
  283. } else if (column.prop === 'permanentGold') {
  284. sortField.value = 'permanent_gold'
  285. } else if (column.prop === 'freeGold') {
  286. sortField.value = 'freeGold'
  287. } else if (column.prop === 'taskGold') {
  288. sortField.value = 'task_gold'
  289. } else if (column.prop === 'createTime') {
  290. sortField.value = 'create_time'
  291. } else if (column.prop === 'auditTime') {
  292. sortField.value = 'audit_time'
  293. } else {
  294. sortField.value = ''
  295. }
  296. sortOrder.value = column.order === 'ascending' ? 'asc' : 'desc'
  297. console.log('排序字段:', sortField.value)
  298. console.log('排序方式:', sortOrder.value)
  299. get()
  300. }
  301. // 查商品名
  302. const getRefundGoods = async () => {
  303. try {
  304. const res = await API({ url: '/general/goods' })
  305. refundGoodsOptions.value = res.data || []
  306. } catch (error) {
  307. console.error('获取商品列表失败', error)
  308. }
  309. }
  310. // 搜索方法
  311. const get = async function (val) {
  312. if (!hasrefundWaitShow) {
  313. ElMessage.error('暂无权限')
  314. return
  315. }
  316. try {
  317. if (typeof val === 'number') {
  318. pagination.value.pageNum = val
  319. }
  320. if (dateRange.value && dateRange.value.length === 2) {
  321. searchForm.value.startTime = moment(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss')
  322. searchForm.value.endTime = moment(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss')
  323. } else {
  324. searchForm.value.startTime = ''
  325. searchForm.value.endTime = ''
  326. }
  327. // if (searchForm.value.market === '总部' || searchForm.value.market === '研发部') {
  328. // searchForm.value.market = '';
  329. // }
  330. const params = {
  331. pageNum: pagination.value.pageNum,
  332. pageSize: pagination.value.pageSize,
  333. refundAudit: {
  334. ...searchForm.value,
  335. sortField: sortField.value,
  336. sortOrder: sortOrder.value,
  337. flag: flag.value
  338. }
  339. }
  340. console.log('看看传给后端的参数:', params)
  341. // 校验精网号(数字格式)
  342. if (searchForm.value.jwcode) {
  343. // 纯数字
  344. const numberRegex = /^\d{1,9}$/;
  345. // 检查是否不是数字
  346. if (!numberRegex.test(searchForm.value.jwcode)) {
  347. ElMessage.error('请检查精网号格式')
  348. // 上面提示过了
  349. return
  350. }
  351. }
  352. const res = await API({ url: '/audit/selectRefund', data: params })
  353. tableData.value = res.list || []
  354. pagination.value.total = res.total || 0
  355. console.log('查全部的total', pagination.value.total, res.total)
  356. } catch (error) {
  357. console.error('获取数据失败', error)
  358. }
  359. }
  360. const clicked = ref(false);
  361. // 显示通过确认对话框
  362. const showApproveDialog = (row) => {
  363. if(!hasrefundWaitThough){
  364. ElMessage.error('暂无权限')
  365. return
  366. }
  367. currentRecord.value = row
  368. approveDialogVisible.value = true
  369. }
  370. // 使用handleApproveConfirm函数代替handleApprove
  371. const handleApproveConfirm = async () => {
  372. clicked.value = true
  373. try {
  374. const params = {
  375. orderCode: currentRecord.value.orderCode,
  376. auditId: adminData.value.id,
  377. action: 1,// action的1是通过,2是驳回
  378. rejectReason: ''
  379. }
  380. await API({ url: '/audit/audit', data: params })
  381. ElMessage.success('审核通过成功')
  382. approveDialogVisible.value = false
  383. await get()
  384. clicked.value = false
  385. await getStats()
  386. } catch (error) {
  387. console.error('审核通过失败', error)
  388. ElMessage.error('操作失败')
  389. }
  390. }
  391. // 处理通过取消操作
  392. const handleApproveCancel = () => {
  393. approveDialogVisible.value = false
  394. }
  395. // 处理通过关闭操作
  396. const handleApproveClose = () => {
  397. approveDialogVisible.value = false
  398. }
  399. // 显示驳回对话框
  400. const showRejectDialog = (row) => {
  401. if (!hasrefundWaitReject) {
  402. ElMessage.error('暂无权限')
  403. return
  404. }
  405. currentRecord.value = row
  406. rejectReason.value = ''
  407. rejectDialogVisible.value = true
  408. }
  409. //控制驳回确认按钮禁用状态
  410. const cancelClicked = ref(false)
  411. // 处理驳回操作
  412. const handleReject = async () => {
  413. if (!hasrefundWaitReject) {
  414. ElMessage.error('暂无权限')
  415. return
  416. }
  417. cancelClicked.value = true
  418. if (!rejectReason.value.trim()) {
  419. ElMessage.warning('请输入驳回理由')
  420. return
  421. }
  422. try {
  423. const params = {
  424. orderCode: currentRecord.value.orderCode,
  425. auditId: adminData.value.id,
  426. action: 2,
  427. rejectReason: rejectReason.value
  428. }
  429. await API({ url: '/audit/audit', data: params })
  430. ElMessage.success('驳回成功')
  431. rejectReasonDialogVisible.value = false
  432. await get()
  433. cancelClicked.value = false
  434. await getStats()
  435. console.log('看看驳回参数', params)
  436. } catch (error) {
  437. console.error('驳回失败', error)
  438. ElMessage.error('操作失败')
  439. }
  440. }
  441. // 确认驳回后显示理由输入框
  442. const showRejectReasonInput = () => {
  443. rejectDialogVisible.value = false // 关闭确认对话框
  444. rejectReasonDialogVisible.value = true // 打开驳回理由输入框
  445. }
  446. // 处理驳回取消操作
  447. const handleRejectCancel = () => {
  448. rejectDialogVisible.value = false
  449. }
  450. // 处理驳回关闭操作
  451. const handleRejectClose = () => {
  452. rejectDialogVisible.value = false
  453. }
  454. const getStats = async () => {
  455. if (!hasrefundWaitShow) {
  456. return
  457. }
  458. try {
  459. const params = {
  460. pageNum: pagination.value.pageNum,
  461. pageSize: pagination.value.pageSize,
  462. refundAudit: {
  463. ...searchForm.value,
  464. flag: flag.value
  465. }
  466. }
  467. if (searchForm.value.jwcode) {
  468. // 纯数字
  469. const numberRegex = /^\d{1,9}$/;
  470. // 检查是否不是数字
  471. if (!numberRegex.test(searchForm.value.jwcode)) {
  472. // ElMessage.error('精网号必须为数字格式')
  473. // 上面提示过了
  474. return
  475. }
  476. }
  477. const res = await API({
  478. url: '/audit/sumRefundGold',
  479. data: params
  480. })
  481. stats.value.totalNum = res.totalNum
  482. stats.value.permanentGolds = res.permanentGolds / 100
  483. stats.value.freeGolds = res.freeGolds / 100
  484. stats.value.taskGolds = res.taskGolds / 100
  485. console.log('see see stats和搜索对象', stats.value, params)
  486. } catch (error) {
  487. console.log('请求失败', error)
  488. }
  489. }
  490. // 搜索
  491. const handleSearch = function () {
  492. trimJwCode()
  493. get()
  494. getStats()
  495. }
  496. // 重置
  497. const resetSearch = function () {
  498. const auditStatus = searchForm.value.auditStatus;
  499. searchForm.value = {
  500. jwcode: '',
  501. refundType: '',
  502. goodsName: '',
  503. market: "",
  504. startTime: '',
  505. endTime: '',
  506. sortField: '',
  507. sortOrder: '',
  508. auditStatus: auditStatus
  509. }
  510. // 重置页码
  511. pagination.value.pageNum = 1
  512. dateRange.value = []
  513. activeTimeRange.value = '' // 清除激活状态
  514. selectedMarketPath.value = []
  515. get()
  516. getStats()
  517. }
  518. // 今天
  519. const getToday = function () {
  520. const today = dayjs()
  521. const startTime = today.startOf('day').format('YYYY-MM-DD HH:mm:ss')
  522. const endTime = today.endOf('day').format('YYYY-MM-DD HH:mm:ss')
  523. dateRange.value = [startTime, endTime]
  524. console.log('dateRange', dateRange.value)
  525. activeTimeRange.value = 'today'
  526. get()
  527. getStats()
  528. }
  529. // 昨天
  530. const getYesterday = function () {
  531. const today = dayjs()
  532. const startTime = today.subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
  533. const endTime = today.subtract(1, 'day').endOf('day').format('YYYY-MM-DD HH:mm:ss')
  534. dateRange.value = [startTime, endTime]
  535. console.log('dateRange', dateRange.value)
  536. activeTimeRange.value = 'yesterday'
  537. get()
  538. getStats()
  539. }
  540. // 近7天
  541. const get7Days = function () {
  542. const today = dayjs()
  543. const startTime = today.subtract(6, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
  544. const endTime = today.endOf('day').format('YYYY-MM-DD HH:mm:ss')
  545. dateRange.value = [startTime, endTime]
  546. console.log('dateRange', dateRange.value)
  547. activeTimeRange.value = '7days'
  548. get()
  549. getStats()
  550. }
  551. const handleButtonClick = function (name) {
  552. activeName.value = name
  553. if (name === 'wait') {
  554. if (!hasrefundWait) {
  555. ElMessage.error('暂无权限')
  556. return
  557. }
  558. if (hasrefundWaitShow) {
  559. adminWait()
  560. }
  561. } else if (name === 'pass') {
  562. if (!hasrefundThrough) {
  563. ElMessage.error('暂无权限')
  564. return
  565. }
  566. adminPass()
  567. } else if (name === 'reject') {
  568. if (!hasrefundReject) {
  569. ElMessage.error('暂无权限')
  570. return
  571. }
  572. adminReject()
  573. }
  574. }
  575. // const handleClick = function (tab, event) {
  576. // activeName.value = tab.props.name
  577. // if (tab.props.name === 'wait') {
  578. // console.log(hasrefundWait.value);
  579. // if (!hasrefundWait) {
  580. // ElMessage.error('暂无权限')
  581. // return
  582. // }
  583. // adminWait()
  584. // } else if (tab.props.name === 'pass') {
  585. // if (!hasrefundThrough.value) {
  586. // ElMessage.error('暂无权限')
  587. // return
  588. // }
  589. // adminPass()
  590. // } else if (tab.props.name === 'reject') {
  591. // if (!hasrefundReject) {
  592. // ElMessage.error('暂无权限')
  593. // return
  594. // }
  595. // adminReject()
  596. // }
  597. // }
  598. // 待审核
  599. const adminWait = async function () {
  600. checkTab.value = 'pending'
  601. searchForm.value.auditStatus = STATUS.PENDING
  602. await get()
  603. await getStats()
  604. }
  605. // 已通过
  606. const adminPass = async function () {
  607. checkTab.value = 'pass'
  608. searchForm.value.auditStatus = STATUS.APPROVED
  609. await get()
  610. await getStats()
  611. }
  612. // 已驳回
  613. const adminReject = async function () {
  614. checkTab.value = 'reject'
  615. searchForm.value.auditStatus = STATUS.REJECTED
  616. await get()
  617. await getStats()
  618. }
  619. const selectedMarketPath = ref("")
  620. const handleMarketChange = (value) => {
  621. if (value && value.length > 0) {
  622. searchForm.value.market = value[value.length - 1]
  623. } else {
  624. searchForm.value.market = ''
  625. }
  626. }
  627. // 获取地区,修改为级联下拉框
  628. const getMarket = async function () {
  629. try {
  630. const result = await API({
  631. url: '/market/selectMarket',
  632. })
  633. console.log('请求成功', result)
  634. // 递归转换树形结构为级联选择器需要的格式(跳过第一级节点)
  635. const transformTree = (nodes) => {
  636. // 直接处理第一级节点的子节点
  637. const allChildren = nodes.flatMap(node => node.children || []);
  638. return allChildren.map(child => {
  639. const grandchildren = child.children && child.children.length
  640. ? transformTree([child]) // 递归处理子节点
  641. : null;
  642. return {
  643. value: child.name,
  644. label: child.name,
  645. children: grandchildren
  646. };
  647. });
  648. };
  649. market.value = transformTree(result.data)
  650. console.log('转换后的地区树==============', market.value)
  651. } catch (error) {
  652. console.log('请求失败', error)
  653. }
  654. }
  655. const trimJwCode = () => {
  656. if (searchForm.value.jwcode) {
  657. searchForm.value.jwcode = searchForm.value.jwcode.replace(/\s/g, '');
  658. }
  659. }
  660. // 日期选择器变化时清除按钮激活状态
  661. const handleDatePickerChange = () => {
  662. activeTimeRange.value = ''
  663. }
  664. const format3 = (num) => {
  665. // 每三位添加逗号
  666. return num.toLocaleString('en-US')
  667. }
  668. // 表单验证
  669. const rules = reactive({
  670. reason: [{ required: true, message: '请输入驳回理由', trigger: 'blur' }]
  671. })
  672. const handlePageSizeChange = function (val) {
  673. pagination.value.pageSize = val
  674. get()
  675. }
  676. const handleCurrentChange = function (val) {
  677. pagination.value.pageNum = val
  678. get()
  679. }
  680. onMounted(async () => {
  681. await initPermissions()
  682. if (hasrefundWaitShow.value) {
  683. searchForm.value.auditStatus = '0'
  684. } else if (hasrefundThrough.value) {
  685. searchForm.value.auditStatus = '1'
  686. } else if (hasrefundReject) {
  687. searchForm.value.auditStatus = '2'
  688. }
  689. getRefundGoods()
  690. await getMarket()
  691. await get()
  692. await getStats()
  693. })
  694. </script>
  695. <style scoped lang="scss">
  696. .pagination {
  697. display: flex;
  698. margin-top: 1vh;
  699. }
  700. .operation {
  701. display: flex;
  702. }
  703. // 搜索的卡片样式
  704. .card1 {
  705. background: #F3FAFE;
  706. }
  707. // 表单的卡片样式
  708. .card2 {
  709. background: #E7F4FD;
  710. }
  711. // 新币总数等等
  712. .goldStatistics {
  713. margin-left: 1vw;
  714. margin-bottom: 1vh;
  715. color: #000000;
  716. font-family: "PingFang SC";
  717. font-size: 16px;
  718. font-style: normal;
  719. font-weight: 700;
  720. line-height: 20px;
  721. }
  722. // 表头背景等
  723. :deep(.el-table__header-wrapper),
  724. :deep(.el-table__body-wrapper),
  725. :deep(.el-table__cell),
  726. /* 表格 */
  727. :deep(.el-table__body td) {
  728. background-color: #F3FAFE !important;
  729. }
  730. /* 表头 */
  731. :deep(.el-table__header th) {
  732. background-color: #F3FAFE !important;
  733. }
  734. /* 鼠标悬停 */
  735. :deep(.el-table__row:hover > .el-table__cell) {
  736. background-color: #E5EBFE !important;
  737. }
  738. /* 自定义按钮组布局 */
  739. .custom-button-group {
  740. display: flex;
  741. margin-bottom: 16px;
  742. }
  743. /* 自定义激活状态样式 - 使用正确的Element Plus类选择器 */
  744. :deep(.el-button.custom-tab-button.el-button--primary) {
  745. background-color: #2741DE !important;
  746. border-color: #2741DE !important;
  747. color: #F3FAFE !important;
  748. }
  749. /* 鼠标悬停效果 */
  750. :deep(.el-button.custom-tab-button:hover:not(.is-disabled)) {
  751. opacity: 0.8;
  752. }
  753. .select {
  754. display: flex;
  755. .selectRow {
  756. width: 17vw;
  757. display: flex;
  758. align-items: center;
  759. justify-content: center;
  760. padding: 0 0.5vw;
  761. .text {
  762. width: 5vw;
  763. font-size: 15px;
  764. }
  765. .selectContent {
  766. flex: 1;
  767. }
  768. }
  769. }
  770. </style>