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.

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