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.

680 lines
28 KiB

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