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.

540 lines
21 KiB

2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
  1. <!-- 客服 -->
  2. <template>
  3. <el-card style="margin-bottom: 0.5vh;">
  4. <div class="condition">
  5. <div class="item1">
  6. <el-text size="large" style="width:4vw;">精网号</el-text>
  7. <el-input v-model="searchForm.jwcode" placeholder="请输入精网号" style="width:9vw;" clearable />
  8. </div>
  9. <div class="item1">
  10. <el-text size="large" style="width:4vw;">客户姓名</el-text>
  11. <el-input v-model="searchForm.name" placeholder="请输入客户姓名" style="width:9vw;" clearable />
  12. </div>
  13. <div class="item1">
  14. <el-text size="large" style="width:4vw;">所属地区</el-text>
  15. <el-input v-model="searchForm.market" placeholder="请输入所属地区" style="width:9vw;" clearable />
  16. </div>
  17. <div class="item1">
  18. <el-text size="large" style="width:4vw;">产品名称</el-text>
  19. <el-input v-model="searchForm.goodsName" placeholder="请输入产品名称" style="width:9vw;" clearable />
  20. </div>
  21. <div class="item1">
  22. <el-text size="large" style="width:4vw;" multiple>订单状态</el-text>
  23. <el-select v-model="searchForm.statuses" style="width:9vw;">
  24. <el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value" />
  25. </el-select>
  26. </div>
  27. </div>
  28. <div class="condition">
  29. <div class="item2">
  30. <el-text size="large" style="width:4vw;">付款币种</el-text>
  31. <el-input v-model="searchForm.paymentCurrency" placeholder="请输入付款币种" style="width:9vw;" clearable />
  32. </div>
  33. <div class="item2">
  34. <el-text size="large" style="width:4vw;">支付方式</el-text>
  35. <el-input v-model="searchForm.payType" placeholder="请输入支付方式" style="width:9vw;" clearable />
  36. </div>
  37. <div class="item2" style="width: 28.5vw;">
  38. <el-text size="large" style="width:4vw;">付款时间</el-text>
  39. <el-date-picker v-model="dateRange" type="datetimerange" range-separator="" start-placeholder="起始时间"
  40. end-placeholder="结束时间" style="width:22vw;" :disabled-date="disabledDate" />
  41. </div>
  42. <div>
  43. <el-button type="primary" @click="getRefund">查询</el-button>
  44. <el-button type="success" @click="reset">重置</el-button>
  45. <el-button type="warning">导出excel</el-button>
  46. <el-button type="primary">查看导出列表</el-button>
  47. </div>
  48. </div>
  49. </el-card>
  50. <div style="display: flex;">
  51. <el-button type="primary" @click="showSteps = true">看看步骤条</el-button>
  52. <el-button type="primary" @click="showError = true">退款金额有误</el-button>
  53. </div>
  54. <el-card style="margin-top: 0.5vh;">
  55. <el-table :data="tableData" style="height:64vh;width:82vw">
  56. <el-table-column type="index" label="序号" width="60" fixed="left" />
  57. <el-table-column prop="jwcode" label="Homily ID" width="120" fixed="left" />
  58. <el-table-column prop="name" label="姓名" width="120" fixed="left" show-overflow-tooltip />
  59. <el-table-column prop="market" label="所属地区" width="120" />
  60. <el-table-column prop="activity" label="活动名称" width="120px" show-overflow-tooltip />
  61. <el-table-column prop="goodsName" label="产品名称" width="120" />
  62. <el-table-column prop="goodNum" label="产品数量" width="120" />
  63. <el-table-column prop="paymentCurrency" label="付款币种" width="120" />
  64. <el-table-column prop="paymentAmount" label="付款金额" width="120" />
  65. <el-table-column prop="payType" label="支付方式" width="120" />
  66. <el-table-column prop="payTime" label="付款时间" width="180" />
  67. <el-table-column prop="voucher" label="转账凭证" width="120" />
  68. <el-table-column prop="remark" label="备注" width="150" show-overflow-tooltip />
  69. <el-table-column prop="status" label="订单状态" width="120" />
  70. <el-table-column prop="operation" label="操作" fixed="right" width="150px">
  71. <template #default="scope">
  72. <div class="operation">
  73. <el-button v-if="scope.row.status === 10" type="primary" text
  74. @click="showBackDialog(scope.row)">
  75. 撤回
  76. </el-button>
  77. <el-button v-if="scope.row.status === 11" type="primary" text
  78. @click="showEditDialog(scope.row)">
  79. 编辑
  80. </el-button>
  81. <el-button v-if="scope.row.status !== 11 && scope.row.status !== 10" type="primary" text @click="">
  82. 查看进度
  83. </el-button>
  84. </div>
  85. </template>
  86. </el-table-column>
  87. </el-table>
  88. <el-pagination v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
  89. layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
  90. @size-change="handlePageSizeChange" @current-change="handleCurrentChange"
  91. style="margin-top: 1vh;"></el-pagination>
  92. </el-card>
  93. <el-dialog v-model="showEdit" title="退款" class="editDialog" overflow draggable style="width: 40vw;">
  94. <div style="display: flex;">
  95. <div class="left">
  96. <div class="add-item">
  97. <el-text style="width:4vw;">精网号</el-text>
  98. <el-input v-model="editRow.jwcode" style="width:10vw;" disabled />
  99. </div>
  100. <div class="add-item">
  101. <el-text style="width:4vw;">客户姓名</el-text>
  102. <el-input v-model="editRow.name" style="width:10vw;" disabled />
  103. </div>
  104. <div class="add-item">
  105. <el-text style="width:4vw;">所属地区</el-text>
  106. <el-input v-model="editRow.markets" style="width:10vw;" disabled />
  107. </div>
  108. <div class="add-item">
  109. <el-text style="width:4vw;">活动名称</el-text>
  110. <el-input v-model="editRow.activity" style="width:10vw;" disabled />
  111. </div>
  112. <div class="add-item">
  113. <el-text style="width:4vw;">产品名称</el-text>
  114. <el-input v-model="editRow.goodsName" style="width:10vw;" disabled />
  115. </div>
  116. <div class="add-item">
  117. <el-text style="width:4vw;">产品数量</el-text>
  118. <el-input v-model="editRow.goodNum" style="width:10vw;" disabled />
  119. &nbsp;
  120. </div>
  121. <div class="add-item">
  122. <el-text style="width:4vw;">付款币种</el-text>
  123. <el-input v-model="editRow.paymentCurrency" style="width:10vw;" disabled />
  124. </div>
  125. <div class="add-item">
  126. <el-text style="width:4vw;">付款金额</el-text>
  127. <el-input v-model="editRow.paymentAmount" style="width:10vw;" disabled />
  128. </div>
  129. <div class="add-item">
  130. <el-text style="width:4vw;">支付方式</el-text>
  131. <el-input v-model="editRow.payType" style="width:10vw;" disabled />
  132. </div>
  133. <div class="add-item">
  134. <el-text style="width:4vw;">付款时间</el-text>
  135. <el-date-picker v-model="editRow.payTime" type="datetime" style="width:10vw;" disabled />
  136. </div>
  137. <div class="add-item">
  138. <el-text style="width:4vw;" size="small">转账凭证</el-text>
  139. <el-form-item :rules="{ required: true, message: '请上传图片', trigger: 'change' }">
  140. <el-upload ref="uploadRef" :auto-upload="false" list-type="picture-card"
  141. :show-file-list="false">
  142. <template #default>
  143. <img v-if="editRow.voucher" :src="editRow.voucher"
  144. style="width: 100%; height: 100%; object-fit: cover;">
  145. <el-icon v-else>
  146. <Plus />
  147. </el-icon>
  148. </template>
  149. </el-upload>
  150. </el-form-item>
  151. </div>
  152. <div class="add-item">
  153. <el-text style="width:4vw;">备注</el-text>
  154. <el-input v-model="editRow.remark" style="width:10vw;" :rows="3" type="textarea" maxLength="100"
  155. disabled show-word-limit />
  156. </div>
  157. </div>
  158. <div class="right">
  159. <div class="add-item">
  160. <el-text style="width:4vw;">退款模式</el-text>
  161. <el-radio-group v-model="editForm.refundModel">
  162. <el-radio value="0">全部退款</el-radio>
  163. <el-radio value="1">部分退款</el-radio>
  164. </el-radio-group>
  165. </div>
  166. <div class="add-item">
  167. <el-text style="width:4vw;">退款理由</el-text>
  168. <el-input v-model="editForm.refundReason" style="width:10vw;" :rows="5" maxlength="150"
  169. show-word-limit type="textarea" />
  170. </div>
  171. <div>ps:请在退款理由表明用户的退款需求</div>
  172. <div style="display:flex;justify-content: center;margin-top: 5vh;">
  173. <el-button type="default" @click="resetEdit">重置</el-button>
  174. <el-button type="primary" @click="submitEdit">提交</el-button>
  175. </div>
  176. </div>
  177. </div>
  178. </el-dialog>
  179. <el-dialog v-model="showSteps" title="唉!!!" overflow draggable width="1206px" :style="{
  180. backgroundImage: 'url(/src/assets/images/背景图.png)',
  181. backgroundSize: 'cover',
  182. backgroundPosition: 'center'
  183. }">
  184. <div class="steps">
  185. <div class="steps-content">
  186. <el-steps style="min-width: 60vw" :active="1" align-center>
  187. <el-step> <template #title>
  188. <div>提交人<br>你是死的</div>
  189. </template>
  190. <template #icon>
  191. <img src="@/assets/images/已审核.png" alt="已审核图标">
  192. </template>
  193. </el-step>
  194. <el-step title="地区财务">
  195. <template #icon>
  196. <img src="@/assets/images/待审核.png" alt="待审核图标">
  197. </template>
  198. </el-step>
  199. <el-step title="地区负责人">
  200. <template #icon>
  201. <img src="@/assets/images/还没传到.png" alt="还没传到图标">
  202. </template>
  203. </el-step>
  204. <el-step title="总部财务">
  205. <template #icon>
  206. <img src="@/assets/images/还没传到.png" alt="还没传到图标">
  207. </template>
  208. </el-step>
  209. <el-step title="指定执行人">
  210. <template #icon>
  211. <img src="@/assets/images/还没传到.png" alt="还没传到图标">
  212. </template>
  213. </el-step>
  214. </el-steps>
  215. </div>
  216. <div class="steps-status">
  217. <el-steps style="min-width: 50vw" :active="1" finish-status="success" simple>
  218. <el-step title="已通过" />
  219. <el-step title="待审核" />
  220. <el-step title="待审核" />
  221. <el-step title="待审核" />
  222. <el-step title="待审核" />
  223. </el-steps>
  224. </div>
  225. <div class="steps-btn">
  226. <el-button type="primary">确定</el-button>
  227. </div>
  228. </div>
  229. </el-dialog>
  230. <el-dialog v-model="showBack" title="撤回退款" overflow draggable class="back-dialog" :style="{
  231. backgroundImage: 'url(/src/assets/images/撤回.png)',
  232. backgroundSize: 'cover',
  233. backgroundPosition: 'center'
  234. }">
  235. <div class="back-text"> </div>
  236. <div class="back-btn">
  237. <el-button type="default" @click="showBack = false">取消</el-button>
  238. <el-button type="primary" @click="recall" style="margin-left: 2vw;">确定</el-button>
  239. </div>
  240. </el-dialog>
  241. <el-dialog v-model="showError" overflow draggable class="back-dialog" :style="{
  242. backgroundImage: 'url(/src/assets/images/撤回.png)',
  243. backgroundSize: 'cover',
  244. backgroundPosition: 'center'
  245. }">
  246. <div class="back-text">退 </div>
  247. <div class="back-btn">
  248. <el-button type="default" @click="showError = false">取消</el-button>
  249. <el-button type="primary" @click="" style="margin-left: 2vw;">确定</el-button>
  250. </div>
  251. </el-dialog>
  252. </template>
  253. <script setup>
  254. import { ref, onMounted } from 'vue'
  255. import { ElMessage } from 'element-plus'
  256. import API from '@/util/http.js'
  257. const uploadUrl = 'https://api.homilychart.com/hljw/api/aws/upload'
  258. import { useAdminStore } from "@/store/index.js"
  259. import { storeToRefs } from "pinia"
  260. import dayjs from 'dayjs'
  261. const adminStore = useAdminStore()
  262. const { adminData, menuTree } = storeToRefs(adminStore)
  263. import { permissionMapping, findMenuById } from "@/utils/menuTreePermission.js"
  264. const dateRange = ref([])
  265. const searchForm = ref({
  266. jwcode: '',
  267. market: [],
  268. statuses: []
  269. })
  270. const backRow = ref({})// 撤回存数据
  271. const editRow = ref({})// 编辑存数据
  272. const editForm = ref({
  273. refundModel: '',
  274. refundReason: ''
  275. })
  276. const auditForm = ref({
  277. refundType: ''
  278. })
  279. const pagination = ref({
  280. pageNum: 1,
  281. pageSize: 50,
  282. total: 0
  283. })
  284. const tableData = ref([])
  285. const showEdit = ref(false)
  286. const showSteps = ref(false)
  287. const uploadRef = ref(null)
  288. const showBack = ref(false)
  289. const showError = ref(false)
  290. const isKF = adminData.value.adminName.includes('客服')
  291. const statusList = ref([
  292. {
  293. value: 'waiting',
  294. label: '待审核',
  295. },
  296. {
  297. value: 'pending',
  298. label: '审核中'
  299. },
  300. {
  301. value: 'completed',
  302. label: '退款完成'
  303. }
  304. ])
  305. // 查全部
  306. const getRefund = async function () {
  307. try {
  308. if(searchForm.value.statuses === 'completed'){
  309. searchForm.value.statuses = [41]
  310. } else if(searchForm.value.statuses === 'pending'){
  311. searchForm.value.statuses = [20, 30, 40]
  312. }else if(searchForm.value.statuses === 'waiting'){
  313. searchForm.value.statuses = [10]
  314. }
  315. const params = {
  316. pageNum: pagination.value.pageNum,
  317. pageSize: pagination.value.pageSize,
  318. cashRecordDone: {
  319. jwcode: searchForm.value.jwcode,//精网号
  320. name: searchForm.value.name,//姓名
  321. markets: searchForm.value.market,//地区
  322. goodsName: searchForm.value.goodsName,//商品名
  323. statuses: searchForm.value.statuses,//10:地区财务待审核;12:地区财务驳回;
  324. // 20:地区负责人待审核;22:地区负责人驳回;
  325. // 30:总部财务待审核;32:总部财务驳回;
  326. // 40:执行人待处理;41:执行人已处理,退款完成;
  327. paymentCurrency: searchForm.value.paymentCurrency,//付款币种
  328. payType: searchForm.value.payType,//支付方式
  329. startTime: dateRange.value && dateRange.value[0] ? moment(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss') : "",
  330. endtime: dateRange.value && dateRange.value[1] ? moment(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss') : "",
  331. submitterId: isKF ? adminData.value.id : null
  332. }
  333. }
  334. const result = await API({
  335. url: '/Money/select',
  336. method: 'POST',
  337. data: params
  338. })
  339. tableData.value = result.data.list || []
  340. } catch (error) {
  341. ElMessage.error(error.message || '查询失败')
  342. }
  343. }
  344. // 撤回
  345. const recall = async function () {
  346. try {
  347. console.log(backRow.value)
  348. const params = {
  349. id: backRow.value.id,
  350. status: backRow.value.status,
  351. orderType: backRow.value.orderType
  352. }
  353. const result = await API({
  354. url: '/Money/update',
  355. data: params
  356. })
  357. if (result.code === 200) {
  358. ElMessage.success(result.msg || '退款成功')
  359. showBack.value = false
  360. getRefund()
  361. } else {
  362. ElMessage.error(result.msg || '退款失败')
  363. }
  364. } catch (error) {
  365. ElMessage.error(error.message || '退款失败')
  366. }
  367. }
  368. // 编辑
  369. const submitEdit = async function () {
  370. try {
  371. console.log(editRow.value)
  372. const params = {
  373. id: editRow.value.id,
  374. status: editRow.value.status,
  375. refundModel: editForm.value.refundModel,
  376. refundReason: editForm.value.refundReason,
  377. jwcode: editRow.value.jwcode,
  378. paymentAmount: editRow.value.paymentAmount,
  379. paymentCurrency: editRow.value.paymentCurrency
  380. }
  381. const result = await API({
  382. url: '/Money/update',
  383. data: params
  384. })
  385. if (result.code === 200) {
  386. ElMessage.success(result.msg || '编辑成功')
  387. showEdit.value = false
  388. getRefund()
  389. } else {
  390. ElMessage.error(result.msg || '编辑失败')
  391. }
  392. } catch (error) {
  393. ElMessage.error(error.message || '编辑失败')
  394. }
  395. }
  396. const reset = function () {
  397. searchForm.value = {
  398. jwcode: ''
  399. }
  400. dateRange.value = []
  401. getRefund()
  402. }
  403. const resetEdit = function () {
  404. editForm.value = {
  405. refundModel: '',
  406. refundReason: ''
  407. }
  408. }
  409. const showBackDialog = function (row) {
  410. backRow.value = row
  411. showBack.value = true
  412. }
  413. const showEditDialog = function (row) {
  414. editRow.value = row
  415. showEdit.value = true
  416. }
  417. const handlePageSizeChange = function (val) {
  418. pagination.value.pageSize = val
  419. getRefund()
  420. }
  421. const handleCurrentChange = function (val) {
  422. pagination.value.pageNum = val
  423. getRefund()
  424. }
  425. const disabledDate = (time) => {
  426. const limitDate = new Date(2025, 0, 1);
  427. return time.getTime() < limitDate.getTime();
  428. }
  429. onMounted(() => {
  430. getRefund()
  431. console.log('???????????????????', adminData.value)
  432. })
  433. </script>
  434. <style scoped lang="scss">
  435. .condition {
  436. width: 82vw;
  437. display: flex;
  438. align-items: center;
  439. height: 4vh;
  440. .item1 {
  441. width: 18%;
  442. display: flex;
  443. align-items: center;
  444. margin-bottom: 1vh;
  445. margin-right: 0.5vw;
  446. }
  447. .item2 {
  448. width: 18%;
  449. display: flex;
  450. align-items: center;
  451. margin-right: 0.5vw;
  452. }
  453. }
  454. .editDialog {
  455. .left {
  456. width: 50%;
  457. height: 70vh;
  458. padding: 0 2vw;
  459. .add-item {
  460. display: flex;
  461. align-items: center;
  462. margin-bottom: 1vh;
  463. }
  464. .image {
  465. width: 4vw !important;
  466. height: 4vw !important;
  467. }
  468. }
  469. .right {
  470. width: 50%;
  471. height: 50vh;
  472. .add-item {
  473. display: flex;
  474. align-items: center;
  475. margin-bottom: 1vh;
  476. }
  477. }
  478. }
  479. .steps {
  480. .steps-content {
  481. width: 45vw;
  482. height: 15vh;
  483. display: flex;
  484. justify-content: center;
  485. padding-top: 15vw;
  486. padding-left: 8vw;
  487. }
  488. .steps-status {
  489. display: flex;
  490. align-items: center;
  491. justify-content: center;
  492. }
  493. .steps-btn {
  494. height: 15vh;
  495. display: flex;
  496. justify-content: center;
  497. align-items: center;
  498. }
  499. }
  500. .back-dialog {
  501. width: 700px;
  502. height: auto;
  503. .back-text {
  504. font-size: 60px;
  505. font-weight: bold;
  506. color: #000000;
  507. text-align: center;
  508. justify-content: center;
  509. margin-top: 22vh;
  510. }
  511. .back-btn {
  512. height: 20vh;
  513. display: flex;
  514. justify-content: center;
  515. align-items: center;
  516. }
  517. }
  518. </style>