feat[litemall-admin, litemall-admin-api]: 支持售后管理页面
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package org.linlinjava.litemall.admin.web;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc;
|
||||
import org.linlinjava.litemall.core.util.JacksonUtil;
|
||||
import org.linlinjava.litemall.core.util.ResponseUtil;
|
||||
import org.linlinjava.litemall.core.validator.Order;
|
||||
import org.linlinjava.litemall.core.validator.Sort;
|
||||
import org.linlinjava.litemall.db.domain.LitemallAftersale;
|
||||
import org.linlinjava.litemall.db.service.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/aftersale")
|
||||
@Validated
|
||||
public class AdminAftersaleController {
|
||||
private final Log logger = LogFactory.getLog(AdminAftersaleController.class);
|
||||
|
||||
@Autowired
|
||||
private LitemallAftersaleService aftersaleService;
|
||||
@Autowired
|
||||
private LitemallOrderService orderService;
|
||||
@Autowired
|
||||
private LitemallOrderGoodsService orderGoodsService;
|
||||
|
||||
@RequiresPermissions("admin:aftersale:list")
|
||||
@RequiresPermissionsDesc(menu = {"商城管理", "售后管理"}, button = "查询")
|
||||
@GetMapping("/list")
|
||||
public Object list(Integer orderId, String aftersaleSn,
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer limit,
|
||||
@Sort @RequestParam(defaultValue = "add_time") String sort,
|
||||
@Order @RequestParam(defaultValue = "desc") String order) {
|
||||
List<LitemallAftersale> aftersaleList = aftersaleService.querySelective(orderId, aftersaleSn, page, limit, sort, order);
|
||||
return ResponseUtil.okList(aftersaleList);
|
||||
}
|
||||
|
||||
|
||||
@RequiresPermissions("admin:aftersale:delete")
|
||||
@RequiresPermissionsDesc(menu = {"商城管理", "售后管理"}, button = "删除")
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@RequestBody LitemallAftersale aftersale) {
|
||||
aftersaleService.deleteById(aftersale.getId());
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
|
||||
@RequiresPermissions("admin:aftersale:batch-delete")
|
||||
@RequiresPermissionsDesc(menu = {"商城管理", "售后管理"}, button = "批量删除")
|
||||
@PostMapping("/batch-delete")
|
||||
public Object batchDelete(@RequestBody String body) {
|
||||
List<Integer> ids = JacksonUtil.parseIntegerList(body, "ids");
|
||||
aftersaleService.deleteByIds(ids);
|
||||
return ResponseUtil.ok();
|
||||
}
|
||||
}
|
||||
25
litemall-admin/src/api/aftersale.js
Normal file
25
litemall-admin/src/api/aftersale.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listAftersale(query) {
|
||||
return request({
|
||||
url: '/aftersale/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteAftersale(data) {
|
||||
return request({
|
||||
url: '/aftersale/delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function batchDeleteAftersale(data) {
|
||||
return request({
|
||||
url: '/aftersale/batch-delete',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
@@ -202,6 +202,16 @@ export const asyncRouterMap = [
|
||||
noCache: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'aftersale',
|
||||
component: () => import('@/views/mall/aftersale'),
|
||||
name: 'aftersale',
|
||||
meta: {
|
||||
perms: ['GET /admin/aftersale/list', 'GET /admin/aftersale/detail', 'POST /admin/order/receive', 'POST /admin/aftersale/complete', 'POST /admin/aftersale/reject'],
|
||||
title: '售后管理',
|
||||
noCache: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'issue',
|
||||
component: () => import('@/views/mall/issue'),
|
||||
|
||||
184
litemall-admin/src/views/mall/aftersale.vue
Normal file
184
litemall-admin/src/views/mall/aftersale.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<!-- 查询和其他操作 -->
|
||||
<div class="filter-container">
|
||||
<el-input v-model="listQuery.aftersaleSn" clearable class="filter-item" style="width: 200px;" placeholder="请输入服务编号" />
|
||||
<el-input v-model="listQuery.orderId" clearable class="filter-item" style="width: 200px;" placeholder="请输入订单ID" />
|
||||
<el-button v-permission="['GET /admin/aftersale/list']" class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
|
||||
<el-button :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">导出</el-button>
|
||||
</div>
|
||||
|
||||
<div class="operator-container">
|
||||
<el-button v-permission="['GET /admin/aftersale/batch-delete']" class="filter-item" type="danger" icon="el-icon-delete" @click="handleBatchDelete">批量删除</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 查询结果 -->
|
||||
<el-table v-loading="listLoading" :data="list" element-loading-text="正在查询中。。。" border fit highlight-current-row @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
|
||||
<el-table-column align="center" label="服务编号" prop="aftersaleSn" />
|
||||
<el-table-column align="center" label="订单ID" prop="orderId" />
|
||||
<el-table-column align="center" label="用户ID" prop="userId" />
|
||||
<el-table-column align="center" label="售后类型" prop="type">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="typeTag[scope.row.type]">{{ typeDesc[scope.row.type] }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="退款原因" prop="reason" />
|
||||
<el-table-column align="center" label="退款价格" prop="amount" />
|
||||
<el-table-column align="center" label="申请时间" prop="addTime" />
|
||||
|
||||
<el-table-column align="center" label="操作" min-width="100" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini" @click="handleRead(scope.row)">详情</el-button>
|
||||
<el-button v-permission="['POST /admin/aftersale/delete']" type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
||||
|
||||
<el-tooltip placement="top" content="返回顶部">
|
||||
<back-to-top :visibility-height="100" />
|
||||
</el-tooltip>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listAftersale, deleteAftersale, batchDeleteAftersale } from '@/api/aftersale'
|
||||
import BackToTop from '@/components/BackToTop'
|
||||
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Topic',
|
||||
components: { BackToTop, Pagination },
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
total: 0,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
aftersaleSn: undefined,
|
||||
orderId: undefined,
|
||||
sort: 'add_time',
|
||||
order: 'desc'
|
||||
},
|
||||
typeTag: [
|
||||
'',
|
||||
'success',
|
||||
'warning'
|
||||
],
|
||||
typeDesc: [
|
||||
'未收货退款',
|
||||
'不退货退款',
|
||||
'退货退款'
|
||||
],
|
||||
multipleSelection: [],
|
||||
contentDetail: '',
|
||||
contentDialogVisible: false,
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
listAftersale(this.listQuery)
|
||||
.then(response => {
|
||||
this.list = response.data.data.list
|
||||
this.total = response.data.data.total
|
||||
this.listLoading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.list = []
|
||||
this.total = 0
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleDelete(row) {
|
||||
deleteAftersale(row)
|
||||
.then(response => {
|
||||
this.$notify.success({
|
||||
title: '成功',
|
||||
message: '删除专题成功'
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
})
|
||||
.catch(response => {
|
||||
this.$notify.error({
|
||||
title: '失败',
|
||||
message: response.data.errmsg
|
||||
})
|
||||
})
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
},
|
||||
showContent(content) {
|
||||
this.contentDetail = content
|
||||
this.contentDialogVisible = true
|
||||
},
|
||||
handleBatchDelete() {
|
||||
if (this.multipleSelection.length === 0) {
|
||||
this.$message.error('请选择至少一条记录')
|
||||
return
|
||||
}
|
||||
const ids = []
|
||||
_.forEach(this.multipleSelection, function(item) {
|
||||
ids.push(item.id)
|
||||
})
|
||||
batchDeleteAftersale({ ids: ids })
|
||||
.then(response => {
|
||||
this.$notify.success({
|
||||
title: '成功',
|
||||
message: '批量删除售后成功'
|
||||
})
|
||||
this.getList()
|
||||
})
|
||||
.catch(response => {
|
||||
this.$notify.error({
|
||||
title: '失败',
|
||||
message: response.data.errmsg
|
||||
})
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = [
|
||||
'服务编号',
|
||||
'订单ID',
|
||||
'用户ID',
|
||||
'售后类型',
|
||||
'退款原因',
|
||||
'退款价格',
|
||||
'申请时间'
|
||||
]
|
||||
const filterVal = [
|
||||
'aftersaleSn',
|
||||
'orderId',
|
||||
'userId',
|
||||
'type',
|
||||
'reason',
|
||||
'amount',
|
||||
'addTime'
|
||||
]
|
||||
excel.export_json_to_excel2(tHeader, this.list, filterVal, '售后信息')
|
||||
this.downloadLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user