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.

698 lines
29 KiB

5 months ago
4 months ago
5 months ago
1 month ago
5 months ago
1 month ago
5 months ago
3 months ago
1 month ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
3 months ago
5 months ago
4 months ago
3 months ago
5 months ago
1 month ago
5 months ago
5 months ago
4 months ago
3 months ago
5 months ago
1 month ago
3 months ago
3 months ago
1 month ago
3 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
1 month 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
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
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
3 months ago
3 months ago
3 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
1 month ago
5 months ago
5 months ago
5 months ago
5 months ago
1 month ago
5 months ago
5 months ago
4 months ago
4 months ago
4 months ago
3 months ago
3 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
1 month ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
3 months ago
4 months ago
3 months ago
5 months ago
3 months ago
3 months ago
3 months ago
1 month ago
3 months ago
5 months ago
5 months ago
4 months ago
5 months ago
3 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
5 months ago
1 month ago
3 months ago
1 month ago
3 months ago
3 months ago
3 months ago
3 months ago
5 months ago
3 months ago
3 months ago
3 months ago
3 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
5 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
4 months ago
3 months ago
1 month ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
4 months ago
5 months ago
  1. <!-- 客服 -->
  2. <template>
  3. <el-card style="margin-bottom: 0.5vh;background-color: rgb(243,250,254);">
  4. <div class="condition">
  5. <div class="item1">
  6. <el-text size="large" style="width:4vw;">{{ t('common.jwcode') }}</el-text>
  7. <el-input v-model="searchForm.jwcode" :placeholder="t('common.jwcodePlaceholder')" style="width:9vw;"
  8. clearable />
  9. </div>
  10. <div class="item1">
  11. <el-text size="large" style="width:4vw;">{{ t('common.customerName') }}</el-text>
  12. <el-input v-model="searchForm.name" :placeholder="t('common.customerNamePlaceholder')"
  13. style="width:9vw;" clearable />
  14. </div>
  15. <div class="item1">
  16. <el-text size="large" style="width:4vw;">{{ t('common.productName') }}</el-text>
  17. <el-cascader v-model="searchForm.goodsName" :props="{ multiple: true, emitPath: false }" :show-all-levels="false" collapse-tags collapse-tags-tooltip :options="productList" style="width: 10vw;" :placeholder="t('common.productNamePlaceholder')" clearable />
  18. </div>
  19. <div class="item1" v-if="isHeadquarters">
  20. <el-text size="large" style="width:4vw;">{{ t('common.market') }}</el-text>
  21. <el-cascader style="width: 9vw;" v-model="searchForm.market" :options="market"
  22. :placeholder="t('common.marketPlaceholder')" clearable @change="handleMarketChange" />
  23. </div>
  24. <div class="item1">
  25. <el-text size="large" style="width:4vw;" multiple>{{ t('common.orderStatus') }}</el-text>
  26. <el-select v-model="searchForm.statuses" style="width:9vw;" clearable>
  27. <el-option v-for="item in statusList" :key="item" :label="item" :value="item" />
  28. </el-select>
  29. </div>
  30. </div>
  31. <div class="condition">
  32. <div class="item2">
  33. <el-text size="large" style="width:4vw;">{{ t('common.payCurrency') }}</el-text>
  34. <el-select v-model="searchForm.paymentCurrency" style="width:9vw;" clearable>
  35. <el-option v-for="item in currencies" :key="item" :label="item" :value="item" />
  36. </el-select>
  37. </div>
  38. <div class="item2">
  39. <el-text size="large" style="width:4vw;">{{ t('common.payModel') }}</el-text>
  40. <el-select v-model="searchForm.payType" style="width:9vw;" clearable>
  41. <el-option v-for="item in channelOptions" :key="item" :label="item" :value="item" />
  42. </el-select>
  43. </div>
  44. <div class="item2" style="width: 28.5vw;">
  45. <el-text size="large" style="width:4vw;">{{ t('common.payTime') }}</el-text>
  46. <el-date-picker v-model="dateRange" type="datetimerange" :range-separator="t('common.to')"
  47. :start-placeholder="t('common.startTime')" :end-placeholder="t('common.endTime')"
  48. style="width:22vw;" :disabled-date="disabledDate" :default-time="defaultTime" clearable />
  49. </div>
  50. <div>
  51. <el-button type="primary" @click="getRefund">{{ t('common.search') }}</el-button>
  52. <!-- <el-button type="warning">导出excel</el-button>
  53. <el-button type="primary">查看导出列表</el-button> -->
  54. <el-button type="success" @click="reset">{{ t('common.reset') }}</el-button>
  55. </div>
  56. </div>
  57. </el-card>
  58. <el-card style="margin-top: 0.5vh;background-color: rgb(231,244,253);">
  59. <el-table :data="tableData" style="height:73vh;width:82vw;background-color: rgb(243,250,254);">
  60. <el-table-column type="index" :label="t('common_list.id')" width="60" fixed="left">
  61. <template #default="scope">
  62. {{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}
  63. </template>
  64. </el-table-column>
  65. <el-table-column prop="jwcode" label="Homily ID" width="120" fixed="left" />
  66. <el-table-column prop="name" :label="t('common_list.name')" width="120" fixed="left"
  67. show-overflow-tooltip />
  68. <el-table-column prop="marketName" :label="t('common_list.market')" width="120" />
  69. <el-table-column prop="activity" :label="t('common_list.activity')" width="120px" show-overflow-tooltip />
  70. <el-table-column prop="goodsName" :label="t('common_list.productName')" width="130" show-overflow-tooltip />
  71. <el-table-column prop="goodsNum" :label="t('common_list.productNum')" width="120" />
  72. <el-table-column prop="paymentCurrency" :label="t('common_add.payCurrency')" width="120" />
  73. <el-table-column prop="paymentAmount" :label="t('common_add.payAmount')" width="120" />
  74. <el-table-column prop="payType" :label="t('common_add.payMethod')" width="140" />
  75. <el-table-column prop="payTime" :label="t('common_add.payTime')" width="180" />
  76. <el-table-column prop="voucher" :label="t('common_add.transferVoucher')" width="110px">
  77. <template #default="scope">
  78. <div v-if="scope.row.voucher"
  79. style="display: flex; justify-content: center; align-items: center; cursor: pointer;"
  80. @click="previewImage(scope.row.voucher)">
  81. <img :src="scope.row.voucher" alt="转账凭证" style="width: auto; height: 40px;">
  82. </div>
  83. <div v-else style="display: flex; justify-content: center; align-items: center; height: 40px;">{{
  84. t('common_add.noTransferVoucher') }}
  85. </div>
  86. </template>
  87. </el-table-column>
  88. <el-table-column prop="remark" :label="t('common_list.remark')" width="150" show-overflow-tooltip />
  89. <el-table-column prop="status" :label="t('common_list.orderStatus')" width="120">
  90. <template #default="scope">
  91. {{
  92. [10].includes(scope.row.status) ? t('cash.statusList.submitted') :
  93. [20, 30, 40].includes(scope.row.status) ? t('cash.statusList.inProgress') :
  94. [12, 22, 32].includes(scope.row.status) ? t('cash.statusList.rejected') :
  95. [11].includes(scope.row.status) ? t('cash.statusList.recalled') :
  96. scope.row.status === 41 ? t('cash.statusList.refunded') : scope.row.status
  97. }}
  98. </template>
  99. </el-table-column>
  100. <el-table-column prop="operation" :label="t('common_list.operation')" fixed="right" width="140px">
  101. <template #default="scope">
  102. <div class="operation">
  103. <el-button v-if="scope.row.status === 10" type="primary" text
  104. @click="showBackDialog(scope.row)">
  105. {{ t('common.withdraw') }}
  106. </el-button>
  107. <el-button v-if="scope.row.status === 11" type="primary" text
  108. @click="showEditDialog(scope.row)">
  109. {{ t('common.edit') }}
  110. </el-button>
  111. <el-button v-if="[12, 22, 32].includes(scope.row.status)" type="primary" text
  112. @click="showRejectReasonDialog(scope.row)">
  113. 查看驳回理由
  114. </el-button>
  115. </div>
  116. </template>
  117. </el-table-column>
  118. </el-table>
  119. <el-pagination v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
  120. layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
  121. @size-change="handlePageSizeChange" @current-change="handleCurrentChange"
  122. style="margin-top: 1vh;"></el-pagination>
  123. </el-card>
  124. <el-dialog v-model="showEdit" :title="t('common_add.refund')" class="editDialog" overflow draggable
  125. style="width: 40vw; background-color: #F3FAFE !important;">
  126. <div style="display: flex;">
  127. <div class="left">
  128. <div class="add-item">
  129. <el-text style="width:4vw;">{{ t('common_add.jwcode') }}</el-text>
  130. <el-input v-model="editRow.jwcode" style="width:10vw;" disabled />
  131. </div>
  132. <div class="add-item">
  133. <el-text style="width:4vw;">{{ t('common_add.customerName') }}</el-text>
  134. <el-input v-model="editRow.name" style="width:10vw;" disabled />
  135. </div>
  136. <div class="add-item">
  137. <el-text style="width:4vw;">{{ t('common_add.market') }}</el-text>
  138. <el-input v-model="editRow.marketName" style="width:10vw;" disabled />
  139. </div>
  140. <div class="add-item">
  141. <el-text style="width:4vw;">{{ t('common_add.activity') }}</el-text>
  142. <el-input v-model="editRow.activity" style="width:10vw;" disabled />
  143. </div>
  144. <div class="add-item">
  145. <el-text style="width:4vw;">{{ t('common_add.productName') }}</el-text>
  146. <el-input v-model="editRow.goodsName" style="width:10vw;" disabled />
  147. </div>
  148. <div class="add-item" v-if="editRow.goodsName !== t('cash.coinRecharge')">
  149. <el-text style="width:4vw;">{{ t('common_add.productNum') }}</el-text>
  150. <el-input v-model="editRow.goodsNum" style="width:10vw;" disabled />
  151. &nbsp;{{ t('cash.unit') }}
  152. </div>
  153. <div class="add-item" v-if="editRow.goodsName == t('cash.coinRecharge')">
  154. <el-text style="width:4vw;">{{ t('refund.permanentGold') }}</el-text>
  155. <el-input v-model="editRow.gold" style="width:10vw;" disabled />
  156. &nbsp;{{ t('cash.unit') }}
  157. </div>
  158. <div class="add-item" v-if="editRow.goodsName == t('cash.coinRecharge')">
  159. <el-text style="width:4vw;">{{ t('refund.freeGold') }}</el-text>
  160. <el-input v-model="editRow.free" style="width:10vw;" disabled />
  161. &nbsp;{{ t('cash.unit') }}
  162. </div>
  163. <div class="add-item">
  164. <el-text style="width:4vw;">{{ t('common_add.payCurrency') }}</el-text>
  165. <el-input v-model="editRow.paymentCurrency" style="width:10vw;" disabled />
  166. </div>
  167. <div class="add-item">
  168. <el-text style="width:4vw;">{{ t('common_add.payAmount') }}</el-text>
  169. <el-input v-model="editRow.paymentAmount" style="width:10vw;" disabled />
  170. </div>
  171. <div class="add-item">
  172. <el-text style="width:4vw;">{{ t('common_add.payMethod') }}</el-text>
  173. <el-input v-model="editRow.payType" style="width:10vw;" disabled />
  174. </div>
  175. <div class="add-item">
  176. <el-text style="width:4vw;">{{ t('common_add.payTime') }}</el-text>
  177. <el-date-picker v-model="editRow.payTime" type="datetime" style="width:10vw;" disabled />
  178. </div>
  179. <div class="add-item">
  180. <el-text style="width:4vw;">{{ t('common_add.transferVoucher') }}</el-text>
  181. <img v-if="editRow.voucher" :src="editRow.voucher"
  182. style="width: 80px; height: 80px; object-fit: cover;">
  183. <div v-else>
  184. {{ t('common_add.noTransferVoucher') }}
  185. </div>
  186. </div>
  187. <div class="add-item">
  188. <el-text style="width:4vw;">{{ t('common_add.remark') }}</el-text>
  189. <el-input v-model="editRow.remark" style="width:10vw;" :rows="3" type="textarea" maxLength="100"
  190. disabled show-word-limit />
  191. </div>
  192. </div>
  193. <div class="right">
  194. <div class="add-item">
  195. <el-text style="width:4vw;">{{ t('common_add.refundType') }}</el-text>
  196. <el-radio-group v-model="editForm.refundModel">
  197. <el-radio value="0">{{ t('common_add.refundModelAll') }}</el-radio>
  198. <el-radio value="1">{{ t('common_add.refundModelPart') }}</el-radio>
  199. </el-radio-group>
  200. </div>
  201. <div class="add-item" v-show="editRow.goodsName === '金币充值' && editForm.refundModel === '1'">
  202. <el-text style="width:4vw;">{{ t('common_add.permanentGold') }}</el-text>
  203. <el-input v-model="editForm.partRefundGold" style="width:5vw;" />&nbsp;&nbsp;{{ t('cash.unit') }}
  204. </div>
  205. <div class="add-item" v-show="editRow.goodsName === '金币充值' && editForm.refundModel === '1'">
  206. <el-text style="width:4vw;">{{ t('common_add.freeGold') }}</el-text>
  207. <el-input v-model="editForm.partRefundFree" style="width:5vw;" />&nbsp;&nbsp;{{ t('cash.unit') }}
  208. </div>
  209. <div class="add-item">
  210. <el-text style="width:4vw;">{{ t('common_add.refundReason') }}</el-text>
  211. <el-input v-model="editForm.refundReason" style="width:10vw;" :rows="5" maxlength="150"
  212. show-word-limit type="textarea" />
  213. </div>
  214. <div>{{ t('common_add.tip') }}</div>
  215. <div style="display:flex;justify-content: center;margin-top: 5vh;">
  216. <el-button type="default" @click="cancelEdit">{{ t('common.cancel') }}</el-button>
  217. <el-button type="primary" @click="submitEdit">{{ t('common.submit') }}</el-button>
  218. </div>
  219. </div>
  220. </div>
  221. </el-dialog>
  222. <ConfirmDialog v-model="showBack" :message="t('common.willRecallOrder')" @confirm="recall"
  223. @cancel="showBack = false" @close="showBack = false" />
  224. <el-dialog v-model="showError" overflow draggable class="back-dialog" :style="{
  225. backgroundImage: `url(${RefundRecallBackground})`,
  226. backgroundSize: 'cover',
  227. backgroundPosition: 'center'
  228. }">
  229. <div class="back-text">{{ t('elmessage.refundAmountError') }}</div>
  230. <div class="back-btn">
  231. <el-button type="default" @click="showError = false">{{ t('common.cancel') }}</el-button>
  232. <el-button type="primary" @click="" style="margin-left: 2vw;">{{ t('common.confirm') }}</el-button>
  233. </div>
  234. </el-dialog>
  235. <el-dialog v-model="showRejectReason" title="驳回理由" width="40%" style="background-color: rgb(243,250,254);">
  236. <div>{{ rejectReason }}</div>
  237. </el-dialog>
  238. </template>
  239. <script setup>
  240. import { ref, onMounted, computed } from 'vue'
  241. import { ElMessage } from 'element-plus'
  242. import API from '@/util/http.js'
  243. const uploadUrl = 'https://api.homilychart.com/hljw/api/aws/upload'
  244. import { useAdminStore } from "@/store/index.js"
  245. import { storeToRefs } from "pinia"
  246. import dayjs from 'dayjs'
  247. const adminStore = useAdminStore()
  248. const { adminData, menuTree } = storeToRefs(adminStore)
  249. import { permissionMapping, findMenuById, hasMenuPermission } from "@/utils/menuTreePermission.js"
  250. import ConfirmDialog from '@/components/dialogs/ConfirmDialog.vue'
  251. import { pa } from 'element-plus/es/locales.mjs'
  252. import { productList, CurrencyForId } from '@/views/moneyManage/receiveDetail/utils/staticData.js'
  253. import RefundRecallBackground from '@/assets/images/refund-recall.png'
  254. import { isNumber } from 'lodash'
  255. import { re } from 'mathjs'
  256. import { useI18n } from 'vue-i18n'
  257. const { t } = useI18n()
  258. const isHeadquarters = computed(() => {
  259. const m = adminData.value.markets
  260. return m === t('common.markets.headquarters') || m === '总部' || m === 'Headquarters'
  261. })
  262. const dateRange = ref([])
  263. const searchForm = ref({
  264. jwcode: '',
  265. market: [],
  266. statuses: [],
  267. goodsName: []
  268. })
  269. const market = ref([])
  270. const backRow = ref({})// 撤回存数据
  271. const editRow = ref({})// 编辑存数据
  272. const rejectReason = ref('')// 驳回理由
  273. const showRejectReason = ref(false)
  274. const editForm = ref({
  275. refundModel: '',
  276. refundReason: ''
  277. })
  278. const auditForm = ref({
  279. refundType: ''
  280. })
  281. const pagination = ref({
  282. pageNum: 1,
  283. pageSize: 50,
  284. total: 0
  285. })
  286. const tableData = ref([])
  287. const showEdit = ref(false)
  288. const uploadRef = ref(null)
  289. const showBack = ref(false)
  290. const showError = ref(false)
  291. const isKF = adminData.value.adminName.includes('客服')
  292. const statusList = computed(() => [
  293. t('cash.statusList.submitted'),
  294. t('cash.statusList.recalled'),
  295. t('cash.statusList.inProgress'),
  296. t('cash.statusList.refunded'),
  297. t('cash.statusList.rejected')
  298. ])
  299. // 查全部
  300. const getRefund = async function () {
  301. if (!hasMenuPermission(menuTree.value, permissionMapping.view_customer_service_refund_pending)) {
  302. ElMessage.error(t('elmessage.noPermission'))
  303. return
  304. }
  305. try {
  306. const statusParam = ref([])
  307. if (searchForm.value.statuses === t('cash.statusList.submitted')) {
  308. statusParam.value = [10]
  309. } else if (searchForm.value.statuses === t('cash.statusList.recalled')) {
  310. statusParam.value = [11]
  311. } else if (searchForm.value.statuses === t('cash.statusList.inProgress')) {
  312. statusParam.value = [20, 30, 40]
  313. } else if (searchForm.value.statuses === t('cash.statusList.refunded')) {
  314. statusParam.value = [41]
  315. } else if (searchForm.value.statuses === t('cash.statusList.rejected')) {
  316. statusParam.value = [12, 22, 32]
  317. }
  318. const goodsName = searchForm.value.goodsName && searchForm.value.goodsName.length > 0
  319. ? searchForm.value.goodsName : []
  320. if (searchForm.value.jwcode) {
  321. const isPositiveInteger = /^[1-9]\d*$/.test(searchForm.value.jwcode);
  322. if (!isPositiveInteger) {
  323. ElMessage.error(t('elmessage.checkJwcodeFormat'))
  324. return;
  325. }
  326. }
  327. // 增加精网号长度限制,防止后端400错误
  328. if (searchForm.value.jwcode.length > 8) {
  329. ElMessage.error(t('elmessage.limitJwcodeLength'))
  330. return;
  331. }
  332. const params = {
  333. pageNum: pagination.value.pageNum,
  334. pageSize: pagination.value.pageSize,
  335. cashRecordDTO: {
  336. jwcode: searchForm.value.jwcode,//精网号
  337. name: searchForm.value.name,//姓名
  338. markets: searchForm.value.market && searchForm.value.market.length > 0 ? [searchForm.value.market[searchForm.value.market.length - 1]] : [],
  339. goodsNames: goodsName,//商品名
  340. statuses: statusParam.value,//10:地区财务待审核;12:地区财务驳回;
  341. // 20:地区负责人待审核;22:地区负责人驳回;
  342. // 30:总部财务待审核;32:总部财务驳回;
  343. // 40:执行人待处理;41:执行人已处理,退款完成;
  344. paymentCurrency: CurrencyForId(searchForm.value.paymentCurrency),//付款币种
  345. payType: searchForm.value.payType,//支付方式
  346. startTime: dateRange.value && dateRange.value[0] ? dayjs(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss') : "",
  347. endTime: dateRange.value && dateRange.value[1] ? dayjs(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss') : "",
  348. submitterId: adminData.value.id
  349. }
  350. }
  351. const result = await API({
  352. url: '/Money/selecta',
  353. method: 'POST',
  354. data: params
  355. })
  356. tableData.value = result.data.list || []
  357. pagination.value.total = result.data.total || 0
  358. } catch (error) {
  359. ElMessage.error(error.message || t('elmessage.searchFailed'))
  360. }
  361. }
  362. // 撤回
  363. const recall = async function () {
  364. if (!hasMenuPermission(menuTree.value, permissionMapping.withdraw_customer_service_refund)) {
  365. ElMessage.error(t('elmessage.noPermission'))
  366. return
  367. }
  368. try {
  369. console.log(backRow.value)
  370. const params = {
  371. id: backRow.value.id,
  372. status: backRow.value.status,
  373. orderType: backRow.value.orderType
  374. }
  375. const result = await API({
  376. url: '/Money/update',
  377. data: params
  378. })
  379. if (result.code === 200) {
  380. ElMessage.success(result.msg || t('elmessage.withdrawSuccess'))
  381. showBack.value = false
  382. getRefund()
  383. } else {
  384. ElMessage.error(result.msg || t('elmessage.operationFailed'))
  385. }
  386. } catch (error) {
  387. ElMessage.error(error.message || t('elmessage.operationFailed'))
  388. }
  389. }
  390. // 编辑
  391. const submitEdit = async function () {
  392. if (!hasMenuPermission(menuTree.value, permissionMapping.edit_customer_service_refund)) {
  393. ElMessage.error(t('elmessage.noPermission'))
  394. return
  395. }
  396. try {
  397. console.log(editRow.value)
  398. if (!editForm.value.refundModel) {
  399. ElMessage.error(t('elmessage.selectRefundModel'))
  400. return
  401. } else if (!editForm.value.refundReason) {
  402. ElMessage.error(t('elmessage.refundReasonPlaceholder'))
  403. return
  404. } else if (editRow.value.goodsName === '金币充值' && editForm.value.refundModel == 1) {
  405. if (!editForm.value.partRefundGold || !editForm.value.partRefundFree) {
  406. ElMessage.error(t('elmessage.inputRefundBeansBoth'))
  407. return
  408. }
  409. const isPositiveInteger = /^[1-9]\d*$/.test(editForm.value.partRefundGold)
  410. if (!isPositiveInteger) {
  411. ElMessage.error(t('elmessage.checkPermanentFormat'))
  412. return
  413. }
  414. const isPositiveInteger1 = /^[1-9]\d*$/.test(editForm.value.partRefundFree)
  415. if (!isPositiveInteger1) {
  416. ElMessage.error(t('elmessage.checkFreeFormat'))
  417. return
  418. }
  419. }
  420. let params = {
  421. id: editRow.value.id,
  422. status: editRow.value.status,
  423. refundModel: editForm.value.refundModel,
  424. refundReason: editForm.value.refundReason,
  425. jwcode: editRow.value.jwcode,
  426. paymentAmount: editRow.value.paymentAmount,
  427. paymentCurrency: editRow.value.paymentCurrency,
  428. newRefundGold: (editForm.value.partRefundGold * 100),
  429. newRefundFree: (editForm.value.partRefundFree) * 100
  430. }
  431. console.log(editRow.value.goodsName);
  432. if (editRow.value.goodsName != '金币充值') {
  433. params.newRefundGold = ''
  434. params.newRefundFree = ''
  435. }
  436. if (editRow.value.goodsName == '金币充值') {
  437. if (editForm.value.partRefundGold > editRow.value.gold) {
  438. ElMessage.error(t('elmessage.limitRefundGoldNotExceedOriginal'))
  439. return
  440. }
  441. if (editForm.value.partRefundFree > editRow.value.free) {
  442. ElMessage.error(t('elmessage.limitRefundFreeNotExceedOriginal'))
  443. return
  444. }
  445. }
  446. const result = await API({
  447. url: '/Money/update',
  448. data: params
  449. })
  450. if (result.code === 200) {
  451. ElMessage.success(result.msg || t('elmessage.editSuccess'))
  452. showEdit.value = false
  453. getRefund()
  454. } else {
  455. ElMessage.error(result.msg || t('elmessage.editFailed'))
  456. }
  457. } catch (error) {
  458. ElMessage.error(error.message || t('elmessage.editFailed'))
  459. }
  460. }
  461. const getMarket = async function () {
  462. try {
  463. const result = await API({
  464. url: '/market/selectMarket',
  465. })
  466. console.log('看看地区树', result)
  467. const transformTree = (nodes) => {
  468. const allChildren = nodes.flatMap(node => node.children || []);
  469. return allChildren.map(child => {
  470. const grandchildren = child.children && child.children.length
  471. ? transformTree([child])
  472. : null;
  473. return {
  474. value: child.id,
  475. label: child.name,
  476. children: grandchildren
  477. };
  478. });
  479. };
  480. market.value = transformTree(result.data)
  481. console.log('转换后的地区树==============', market.value)
  482. } catch (error) {
  483. console.log('请求失败', error)
  484. }
  485. }
  486. // 预览图片函数
  487. const previewImage = (imageUrl) => {
  488. // 使用 element-plus 的 el-image 组件实现图片预览功能
  489. const imageElement = document.createElement('img');
  490. imageElement.src = imageUrl;
  491. imageElement.style.maxWidth = '80vw';
  492. imageElement.style.maxHeight = '80vh';
  493. const viewer = document.createElement('div');
  494. viewer.style.position = 'fixed';
  495. viewer.style.top = '0';
  496. viewer.style.left = '0';
  497. viewer.style.width = '100vw';
  498. viewer.style.height = '100vh';
  499. viewer.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  500. viewer.style.display = 'flex';
  501. viewer.style.justifyContent = 'center';
  502. viewer.style.alignItems = 'center';
  503. viewer.style.zIndex = '9999';
  504. viewer.style.overflow = 'auto';
  505. viewer.appendChild(imageElement);
  506. document.body.appendChild(viewer);
  507. viewer.addEventListener('click', () => {
  508. document.body.removeChild(viewer);
  509. });
  510. };
  511. const cancelEdit = function () {
  512. editForm.value = {
  513. refundModel: '',
  514. refundReason: '',
  515. partRefundGold: '',
  516. partRefundFree: ''
  517. }
  518. showEdit.value = false
  519. }
  520. const currencies = computed(() => [
  521. t('cash.currency.usd'),
  522. t('cash.currency.hkd'),
  523. t('cash.currency.sgd'),
  524. t('cash.currency.myr'),
  525. t('cash.currency.thb'),
  526. t('cash.currency.cad'),
  527. t('cash.currency.vnd'),
  528. t('cash.currency.krw')
  529. ])
  530. const channelOptions = computed(() => [
  531. t('cash.payMethods.stripe'),
  532. t('cash.payMethods.paymentAsia'),
  533. t('cash.payMethods.ipay88'),
  534. t('cash.payMethods.bankTransfer'),
  535. t('cash.payMethods.card'),
  536. t('cash.payMethods.cash'),
  537. t('cash.payMethods.check'),
  538. t('cash.payMethods.grabpay'),
  539. t('cash.payMethods.nets'),
  540. t('cash.payMethods.transfer'),
  541. t('cash.payMethods.paypal')
  542. ])
  543. const reset = function () {
  544. searchForm.value = {
  545. jwcode: '',
  546. market: [],
  547. statuses: [],
  548. goodsName: []
  549. }
  550. // 重置页码
  551. pagination.value.pageNum = 1
  552. dateRange.value = []
  553. getRefund()
  554. }
  555. const showBackDialog = function (row) {
  556. backRow.value = row
  557. showBack.value = true
  558. }
  559. const showEditDialog = function (row) {
  560. editRow.value = row
  561. showEdit.value = true
  562. }
  563. const handlePageSizeChange = function (val) {
  564. pagination.value.pageSize = val
  565. getRefund()
  566. }
  567. const handleCurrentChange = function (val) {
  568. pagination.value.pageNum = val
  569. getRefund()
  570. }
  571. const disabledDate = (time) => {
  572. const limitDate = new Date(2025, 0, 1);
  573. return time.getTime() < limitDate.getTime();
  574. }
  575. const handleMarketChange = (value) => {
  576. searchForm.value.market = value || []
  577. }
  578. const defaultTime = [
  579. new Date(2000, 1, 1, 0, 0, 0),
  580. new Date(2000, 2, 1, 23, 59, 59),
  581. ]
  582. const showRejectReasonDialog = function (row) {
  583. rejectReason.value = row.rejectReason
  584. showRejectReason.value = true
  585. }
  586. onMounted(() => {
  587. getRefund()
  588. getMarket()
  589. console.log('???????????????????', adminData.value)
  590. })
  591. </script>
  592. <style scoped lang="scss">
  593. :deep(.el-table__header-wrapper),
  594. :deep(.el-table__body-wrapper),
  595. :deep(.el-table__cell),
  596. :deep(.el-table__body td) {
  597. background-color: #F3FAFE !important;
  598. }
  599. :deep(.el-table__header th) {
  600. background-color: #F3FAFE !important;
  601. }
  602. .condition {
  603. width: 82vw;
  604. display: flex;
  605. align-items: center;
  606. height: 4vh;
  607. .item1 {
  608. width: 18%;
  609. display: flex;
  610. align-items: center;
  611. margin-bottom: 1vh;
  612. margin-right: 0.5vw;
  613. }
  614. .item2 {
  615. width: 18%;
  616. display: flex;
  617. align-items: center;
  618. margin-right: 0.5vw;
  619. }
  620. }
  621. .editDialog {
  622. .left {
  623. width: 50%;
  624. height: 70vh;
  625. padding: 0 2vw;
  626. .add-item {
  627. display: flex;
  628. align-items: center;
  629. margin-bottom: 1vh;
  630. }
  631. .image {
  632. width: 4vw !important;
  633. height: 4vw !important;
  634. }
  635. }
  636. .right {
  637. width: 50%;
  638. height: 50vh;
  639. .add-item {
  640. display: flex;
  641. align-items: center;
  642. margin-bottom: 1vh;
  643. }
  644. }
  645. }
  646. .back-dialog {
  647. width: 700px;
  648. height: auto;
  649. .back-text {
  650. font-size: 60px;
  651. font-weight: bold;
  652. color: #000000;
  653. text-align: center;
  654. justify-content: center;
  655. margin-top: 22vh;
  656. }
  657. .back-btn {
  658. height: 20vh;
  659. display: flex;
  660. justify-content: center;
  661. align-items: center;
  662. }
  663. }
  664. </style>