Merge branch 'vue3'

This commit is contained in:
田香琪
2026-07-09 11:03:16 +08:00
672 changed files with 77633 additions and 60878 deletions

View File

@@ -1,258 +1,212 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
clearable
placeholder="请输入会员名称"
style="width: 240px"
/>
</Form-item>
<Form-item label="订单号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
clearable
placeholder="请输入订单号"
style="width: 240px"
/>
</Form-item>
<Form-item label="状态" prop="status">
<Select v-model="searchForm.status" placeholder="请选择订单状态" clearable style="width: 240px">
<Option value="NEW">新投诉</Option>
<Option value="CANCEL">已撤销</Option>
<Option value="WAIT_APPEAL">待申诉</Option>
<Option value="COMMUNICATION">对话中</Option>
<Option value="WAIT_ARBITRATION">等待仲裁</Option>
<Option value="COMPLETE">已完成</Option>
</Select>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
<Button @click="handleReset" class="search-btn">重置</Button>
</Form>
</Row>
</Card>
<Card>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
class="mt_10"
ref="table"
<el-card>
<el-form
ref="searchForm"
:model="searchForm"
inline
label-width="70px"
class="search-form"
@keyup.enter="handleSearch"
>
<template slot-scope="{row}" slot="goodsName">
<a class="mr_10" @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
</div>
<img src="../../../assets/qrcode.svg" style="vertical-align:bottom;" class="hover-pointer" width="20" height="20" alt="">
</Poptip>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
<el-form-item label="订单编号" prop="orderSn">
<el-input
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="会员名称" prop="memberName">
<el-input
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="searchForm.status" placeholder="请选择" clearable style="width: 240px">
<el-option label="新投诉" value="NEW" />
<el-option label="已撤销" value="CANCEL" />
<el-option label="待申诉" value="WAIT_APPEAL" />
<el-option label="对话中" value="COMMUNICATION" />
<el-option label="等待仲裁" value="WAIT_ARBITRATION" />
<el-option label="已完成" value="COMPLETE" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card>
<el-table v-loading="loading" border :data="data" ref="table" class="mt_10" style="width: 100%">
<el-table-column prop="memberName" label="会员名称" width="200" />
<el-table-column prop="orderSn" label="订单编号" min-width="120" show-overflow-tooltip />
<el-table-column label="商品名称" min-width="180" show-overflow-tooltip>
<template #default="{ row }">
<template v-if="row">
<a class="link-text mr_10" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
<template #reference>
<img
src="../../../assets/qrcode.svg"
class="hover-pointer"
width="20"
height="20"
alt="qrcode"
/>
</template>
<vue-qr
:text="wapLinkTo(row.goodsId, row.skuId)"
:margin="0"
color-dark="#000"
color-light="#fff"
:size="150"
/>
</el-popover>
</template>
</template>
</el-table-column>
<el-table-column prop="complainTopic" label="投诉主题" min-width="160" show-overflow-tooltip />
<el-table-column prop="createTime" label="投诉时间" width="180" />
<el-table-column label="投诉状态" width="110">
<template #default="{ row }">
<el-tag v-if="row" :type="complainStatusTagType(row.complainStatus)">
{{ complainStatusText(row.complainStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template #default="{ row }">
<a v-if="row" class="link-text" @click="detail(row)">
{{ row.complainStatus === "COMPLETE" ? "详情" : "处理" }}
</a>
</template>
</el-table-column>
</el-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<el-pagination
v-model:current-page="searchForm.pageNumber"
v-model:page-size="searchForm.pageSize"
:page-sizes="[20, 50, 100]"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
@current-change="changePage"
@size-change="changePageSize"
/>
</div>
</el-card>
</div>
</template>
<script>
import * as API_Member from "@/api/member";
import * as API_Order from "@/api/order";
import uploadPicThumb from "@/views/my-components/lili/upload-pic-thumb";
import * as API_Order from "@/api/order";
import vueQr from "vue-qr";
export default {
name: "orderComplaint",
components: {
uploadPicThumb
export default {
name: "orderComplaint",
components: { vueQr },
data() {
return {
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
},
data: [],
total: 0,
};
},
watch: {
$route() {
this.getDataList();
},
data() {
return {
loading: true, // 表单加载状态
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
},
columns: [
// 表头
{
title: "会员名称",
key: "memberName",
sortable: false,
},
{
title: "订单编号",
key: "orderSn",
},
{
title: "商品名称",
slot: "goodsName",
},
{
title: "投诉主题",
key: "complainTopic",
},
{
title: "投诉时间",
key: "createTime",
},
{
title: "投诉状态",
key: "complainStatus",
render: (h, params) => {
if (params.row.complainStatus == "NEW") {
return h('div', [h('tag',{props: {color: "purple"}}, '新投诉'),]);
} else if (params.row.complainStatus == "CANCEL") {
return h('div', [h('tag', {props: {color: "cyan"}}, '已撤销'),]);
} else if (params.row.complainStatus == "WAIT_APPEAL") {
return h('div', [h('tag', {props: {color: "volcano"}}, '待申诉'),]);
} else if (params.row.complainStatus == "COMMUNICATION") {
return h('div', [h('tag', {props: {color: "orange"}}, '对话中'),]);
}else if (params.row.complainStatus == "WAIT_ARBITRATION") {
return h('div', [h('tag', {props: {color: "blue"}}, '等待仲裁'),]);
}else if (params.row.complainStatus == "COMPLETE") {
return h('div', [h('tag', {props: {color: "green"}}, '已完成'),]);
}
}
},
{
title: "操作",
key: "action",
align: "center",
fixed: 'right',
width: 200,
render: (h, params) => {
if (params.row.complainStatus === "COMPLETE") {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"详情"
),
]);
} else {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"处理"
),
]);
}
},
},
],
data: [], // 表格数据
total: 0, // 表单数据总数
},
methods: {
complainStatusText(v) {
const map = {
NEW: "新投诉",
CANCEL: "已撤销",
WAIT_APPEAL: "待申诉",
COMMUNICATION: "对话中",
WAIT_ARBITRATION: "等待仲裁",
COMPLETE: "已完成",
};
return map[v] || v || "-";
},
methods: {
// 初始化数据
init() {
this.getDataList();
},
// 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 重置
handleReset() {
this.searchForm = {}
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 获取数据
getDataList() {
this.loading = true;
API_Order.getComplainPage(this.searchForm).then((res) => {
complainStatusTagType(v) {
const map = {
NEW: "primary",
CANCEL: "info",
WAIT_APPEAL: "warning",
COMMUNICATION: "warning",
WAIT_ARBITRATION: "",
COMPLETE: "success",
};
return map[v] || "info";
},
init() {
this.getDataList();
},
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
getDataList() {
this.loading = true;
API_Order.getOrderComplain(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
this.loading = false;
},
//投诉详情
detail(v) {
let id = v.id;
this.$options.filters.customRouterPush({
name: "order-complaint-detail",
query: { id: id },
})
},
.catch(() => {
this.loading = false;
});
},
mounted() {
this.init();
detail(v) {
this.$filters.customRouterPush({
name: "order-complaint-detail",
query: { id: v.id },
});
},
// 页面缓存处理从该页面离开时修改KeepAlive为false保证进入该页面是刷新
beforeRouteLeave(to, from, next) {
from.meta.keepAlive = false
next()
}
};
},
mounted() {
this.init();
},
};
</script>
<style lang="scss">
// 建议引入通用样式 可删除下面样式代码
@import "@/styles/table-common.scss";
<style scoped>
.link-text {
color: #409eff;
cursor: pointer;
text-decoration: none;
}
.mr_10 {
margin-right: 10px;
}
.hover-pointer {
cursor: pointer;
vertical-align: bottom;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="search">
<Card>
<div class="main-content">
<div class="search" v-loading="loading">
<el-card>
<div class="main-content" v-if="complaintInfo.id">
<div class="div-flow-left">
<div class="div-form-default">
<h3>投诉信息</h3>
@@ -9,20 +9,15 @@
<dt>投诉商品</dt>
<dd>
<div>
<img :src="complaintInfo.goodsImage" style="height: 60px">
<img :src="complaintInfo.goodsImage" style="height: 60px" alt="" />
</div>
<a>{{ complaintInfo.goodsName }}</a><br>
<span>{{ complaintInfo.goodsPrice | unitPrice }} * {{ complaintInfo.num }}(数量)</span>
<a class="link-text">{{ complaintInfo.goodsName }}</a><br />
<span>{{ complaintInfo.num }}(数量)</span>
</dd>
</dl>
<dl>
<dt>投诉状态</dt>
<dd v-if="complaintInfo.complainStatus =='NEW'">新投诉</dd>
<dd v-if="complaintInfo.complainStatus =='CANCEL'">已撤销</dd>
<dd v-if="complaintInfo.complainStatus =='WAIT_APPEAL'">待申诉</dd>
<dd v-if="complaintInfo.complainStatus =='COMMUNICATION'">对话中</dd>
<dd v-if="complaintInfo.complainStatus =='WAIT_ARBITRATION'">等待仲裁</dd>
<dd v-if="complaintInfo.complainStatus =='COMPLETE'">已完成</dd>
<dd>{{ complainStatusText(complaintInfo.complainStatus) }}</dd>
</dl>
<dl>
<dt>投诉时间</dt>
@@ -38,17 +33,45 @@
</dl>
<dl>
<dt>投诉凭证</dt>
<dd v-if="images === ''">
暂无投诉凭证
</dd>
<dd v-if="!images.length">暂无投诉凭证</dd>
<dd v-else>
<div class="div-img" v-for="(item, index) in images" :key="index">
<img class="complain-img" :src=item>
<img class="complain-img" :src="item" alt="" />
</div>
</dd>
</dl>
</div>
<div class="div-form-default" v-if="complaintInfo.complainStatus !== 'WAIT_APPEAL'">
<div class="div-form-default" v-if="complaintInfo.complainStatus === 'WAIT_APPEAL'">
<h3>商家申诉</h3>
<dl>
<dt>申诉内容</dt>
<dd>
<el-input
v-model="appeal.appealContent"
type="textarea"
maxlength="200"
:rows="4"
clearable
style="width: 260px"
/>
</dd>
</dl>
<dl>
<dt>申诉凭证</dt>
<dd>
<upload-pic-thumb v-model="appeal.appealImages" :limit="5" />
</dd>
</dl>
<dl>
<dt></dt>
<dd>
<el-button type="primary" :loading="submitLoading" @click="appealSubmit">提交申诉</el-button>
</dd>
</dl>
</div>
<div class="div-form-default" v-else-if="complaintInfo.appealContent">
<h3>商家申诉信息</h3>
<dl>
<dt>申诉时间</dt>
@@ -60,198 +83,136 @@
</dl>
<dl>
<dt>申诉凭证</dt>
<dd v-if="appealImages == ''">
暂无申诉凭证
</dd>
<dd v-if="!appealImages.length">暂无申诉凭证</dd>
<dd v-else>
<div class="div-img" v-for="(item, index) in appealImages" :key="index">
<img class="complain-img" :src=item>
<img class="complain-img" :src="item" alt="" />
</div>
</dd>
</dl>
</div>
<div class="div-form-default" v-if="complaintInfo.complainStatus === 'WAIT_APPEAL'">
<h3>商家申诉</h3>
<dl>
<dt>申诉内容</dt>
<dd>
<Input v-model="appeal.appealContent" type="textarea" maxlength="200" :rows="4" clearable style="width:260px" />
</dd>
</dl>
<dl>
<dt>申诉凭证</dt>
<dd>
<div class="complain-upload-list" :key="index" v-for="(item,index) in appeal.appealImages">
<template v-if="item.status === 'finished'">
<img class="complain-img" :src="item.url">
<div class="complain-upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(item.url)"></Icon>
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
</div>
</template>
<template v-else>
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
</template>
</div>
<Upload ref="upload" :show-upload-list="false" :on-format-error="handleFormatError" :action="uploadFileUrl" :headers="accessToken" :on-success="handleSuccessGoodsPicture"
:format="['jpg','jpeg','png']" :max-size="1024" :on-exceeded-size="handleMaxSize" :before-upload="handleBeforeUpload" multiple type="drag"
style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
</div>
</Upload>
<Modal title="View Image" v-model="visible">
<img :src="imgName" v-if="visible" style="width: 100%">
</Modal>
</dd>
</dl>
<dl>
<dt></dt>
<dd>
<Button type="primary" :loading="submitLoading" @click="appealSubmit()" style="margin-left: 5px">
提交申诉
</Button>
</dd>
</dl>
</div>
<div class="div-form-default">
<h3>对话详情</h3>
<dl>
<dt>对话记录</dt>
<dd>
<div class="div-content">
<p v-for="(item, index) in complaintInfo.orderComplaintCommunications" :key="index">
<span v-if="item.owner === 'STORE'">商家[{{ item.createTime }}]</span>
<span v-if="item.owner === 'BUYER'">买家[{{ item.createTime }}]</span>
<span v-if="item.owner === 'PLATFORM'">平台[{{ item.createTime }}]</span>
<p
v-for="(item, index) in complaintInfo.orderComplaintCommunications || []"
:key="index"
>
<span v-if="item.owner == 'STORE'">商家[{{ item.createTime }}]</span>
<span v-else-if="item.owner == 'BUYER'">买家[{{ item.createTime }}]</span>
<span v-else-if="item.owner == 'PLATFORM'">平台[{{ item.createTime }}]</span>
{{ item.content }}
</p>
</div>
</dd>
</dl>
<dl v-if="complaintInfo.complainStatus!='COMPLETE'">
<dl v-if="complaintInfo.complainStatus != 'COMPLETE'">
<dt>发送对话</dt>
<dd>
<Input v-model="params.content" type="textarea" maxlength="200" :rows="4" clearable style="width:260px" />
<el-input
v-model="params.content"
type="textarea"
maxlength="200"
:rows="4"
clearable
style="width: 260px"
/>
</dd>
</dl>
<dl>
<dl v-if="complaintInfo.complainStatus != 'COMPLETE'">
<dt></dt>
<dd v-if="complaintInfo.complainStatus != 'COMPLETE'">
<div style="text-align: right;width: 45%;margin-top: 10px">
<Button type="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 5px">
<dd>
<div style="text-align: left; margin-top: 10px">
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
回复
</Button>
<Button type="default" :loading="submitLoading" @click="returnDataList" style="margin-left: 5px">
</el-button>
<el-button type="primary" :loading="submitLoading" @click="returnDataList" style="margin-left: 5px">
返回列表
</Button>
</el-button>
</div>
</dd>
</dl>
</div>
<div class="div-form-default" v-if="complaintInfo.complainStatus === 'COMPLETE'">
<div class="div-form-default" v-if="complaintInfo.complainStatus == 'COMPLETE'">
<h3>仲裁结果</h3>
<dl>
<dt>仲裁意见</dt>
<dd>
{{ complaintInfo.arbitrationResult }}
</dd>
<dd>{{ complaintInfo.arbitrationResult }}</dd>
</dl>
</div>
</div>
<div class="div-flow-center">
</div>
<div class="div-flow-center"></div>
<div class="div-flow-right">
<div class="div-form-default">
<h3>订单相关信息</h3>
<dl>
<dt>
订单编号
</dt>
<dd>
{{ complaintInfo.orderSn }}
</dd>
<dt>订单编号</dt>
<dd>{{ complaintInfo.orderSn }}</dd>
</dl>
<dl>
<dt>
下单时间
</dt>
<dd>
{{ complaintInfo.orderTime }}
</dd>
<dt>下单时间</dt>
<dd>{{ complaintInfo.orderTime || complaintInfo.createTime }}</dd>
</dl>
<dl>
<dt>
订单金额
</dt>
<dt>订单金额</dt>
<dd>
<priceColorScheme :value="complaintInfo.orderPrice" :color="$mainColor"></priceColorScheme>
<span class="price-text">{{ $filters.unitPrice(complaintInfo.orderPrice, "¥") }}</span>
</dd>
</dl>
</div>
<div class="div-form-default">
<h3>收件人信息</h3>
<dl>
<dt>
收货人
</dt>
<dd>
{{ complaintInfo.consigneeName }}
</dd>
<dt>收货人</dt>
<dd>{{ complaintInfo.consigneeName }}</dd>
</dl>
<dl>
<dt>
收货地址
</dt>
<dd>
{{ complaintInfo.consigneeAddressPath }}
</dd>
<dt>收货地址</dt>
<dd>{{ complaintInfo.consigneeAddressPath }}</dd>
</dl>
<dl>
<dt>
收货人手机
</dt>
<dd>
{{ complaintInfo.consigneeMobile }}
</dd>
<dt>收货人手机</dt>
<dd>{{ complaintInfo.consigneeMobile }}</dd>
</dl>
</div>
</div>
</div>
</Card>
</el-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import { uploadFile } from "@/libs/axios";
import uploadPicThumb from "@/views/my-components/lili/upload-pic-thumb";
const emptyComplaint = () => ({
id: "",
orderComplaintCommunications: [],
});
export default {
name: "orderComplaint",
name: "orderComplaintDetail",
components: {
uploadPicThumb,
},
data() {
return {
//展示图片层
visible: false,
//上传图片路径
uploadFileUrl: uploadFile,
accessToken: "", // 验证token
id: 0, // 投诉单id
complaintInfo: "", // 投诉信息
images: [], //会员申诉图片
appealImages: [], //商家申诉的图片
applyAppealImages: [], //商家申诉表单填写的图片
submitLoading: false, // 添加或编辑提交状态
//商家回复内容
loading: false,
id: "",
complaintInfo: emptyComplaint(),
images: [],
appealImages: [],
submitLoading: false,
params: {
content: "",
complainId: "",
},
//投诉
appeal: {
orderComplaintId: "",
appealContent: "",
@@ -259,169 +220,105 @@ export default {
},
};
},
watch: {
$route() {
this.getDetail();
},
},
methods: {
// 预览图片
handleView(name) {
this.imgName = name;
this.visible = true;
complainStatusText(v) {
const map = {
NEW: "新投诉",
CANCEL: "已撤销",
WAIT_APPEAL: "待申诉",
COMMUNICATION: "对话中",
WAIT_ARBITRATION: "等待仲裁",
COMPLETE: "已完成",
};
return map[v] || v || "-";
},
// 移除回复图片
handleRemove(file) {
this.appeal.appealImages = this.appeal.appealImages.filter(
(i) => i.url !== file.url
);
},
// 上传成功回调
handleSuccessGoodsPicture(res, file) {
if (file.response) {
file.url = file.response.result;
this.appeal.appealImages.push(file);
}
},
// 上传之前钩子
handleBeforeUpload() {
const check =
this.images.images !== undefined && this.images.images.length > 5;
if (check) {
this.$Notice.warning({
title: "Up to five pictures can be uploaded.",
});
}
return !check;
},
// 上传格式错误
handleFormatError(file) {
this.$Notice.warning({
title: "图片格式不正确",
desc:
"File format of " +
file.name +
" is incorrect, please select jpg or png.",
});
},
// 上传大小限制
handleMaxSize(file) {
this.$Notice.warning({
title: "超过文件大小限制",
desc: "图片不能超过1mb",
});
},
// 获取详情
getDetail() {
if (!this.id) return;
this.loading = true;
API_Order.getComplainDetail(this.id).then((res) => {
this.loading = false;
if (res.success) {
this.complaintInfo = res.result;
this.images = (res.result.images || "").split(",");
this.appealImages = (res.result.appealImages || "").split(",");
}
});
API_Order.getOrderComplainDetail(this.id)
.then((res) => {
this.loading = false;
if (res.success) {
this.complaintInfo = res.result || emptyComplaint();
this.images = (res.result.images || "")
.split(",")
.map((s) => s.trim())
.filter(Boolean);
this.appealImages = (res.result.appealImages || "")
.split(",")
.map((s) => s.trim())
.filter(Boolean);
}
})
.catch(() => {
this.loading = false;
});
},
//返回列表
returnDataList() {
this.$router.push({
name: "orderComplaint",
});
this.$router.push({ name: "orderComplaint" });
},
appealSubmit() {
if (!this.appeal.appealContent) {
this.$Message.error("请填写申诉内容");
return;
}
this.submitLoading = true;
const appealImages = Array.isArray(this.appeal.appealImages)
? this.appeal.appealImages
: [];
API_Order.appeal({
orderComplaintId: this.id,
appealContent: this.appeal.appealContent,
appealImages,
})
.then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("申诉成功");
this.appeal.appealContent = "";
this.appeal.appealImages = [];
this.getDetail();
}
})
.catch(() => {
this.submitLoading = false;
});
},
//回复
handleSubmit() {
if (this.params.content === "") {
if (!this.params.content) {
this.$Message.error("请填写对话内容");
return;
}
this.submitLoading = true;
this.params.complainId = this.id;
API_Order.addOrderComplaint(this.params).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("对话成功");
this.params.content = "";
this.getDetail();
}
});
},
//申诉
appealSubmit() {
if (this.appeal.appealContent === "") {
this.$Message.error("请填写内容");
return;
}
this.appeal.appealImages = this.appeal.appealImages.map(item=> item.url)
this.appeal.orderComplaintId = this.id;
API_Order.appeal(this.appeal).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("申诉成功");
this.getDetail();
}
});
API_Order.addOrderCommunication(this.params)
.then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("对话成功");
this.params.content = "";
this.getDetail();
}
})
.catch(() => {
this.submitLoading = false;
});
},
},
mounted () {
mounted() {
this.id = this.$route.query.id;
this.getDetail();
this.accessToken = {
accessToken: this.getStore("accessToken"),
};
},
// 如果是从详情页返回列表页修改列表页keepAlive为true确保不刷新页面
beforeRouteLeave(to, from, next){
if(to.name === 'orderComplaint') {
to.meta.keepAlive = true
}
next()
}
watch: {
"$route.query.id"(val) {
this.id = val;
this.getDetail();
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .ivu-col {
width: 100% !important;
}
.complain-upload-list {
display: inline-block;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
margin-right: 4px;
}
.complain-upload-list img {
width: 100%;
height: 100%;
}
.complain-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
.complain-upload-list:hover .complain-upload-list-cover {
display: block;
}
.complain-upload-list-cover i {
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
.main-content {
min-height: 600px;
padding: 10px;
@@ -545,5 +442,31 @@ export default {
overflow-y: auto;
overflow-x: auto;
height: 150px;
scrollbar-width: auto;
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgba(50, 50, 50, 0.45);
}
&::-webkit-scrollbar-track {
border-radius: 4px;
background-color: rgba(50, 50, 50, 0.12);
}
}
.link-text {
color: #409eff;
cursor: pointer;
}
.price-text {
color: #ff5c58;
font-weight: 600;
}
</style>

View File

@@ -1,369 +1,345 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="商品" prop="goodsName">
<Input
type="text"
v-model="searchForm.goodsName"
clearable
placeholder="请输入商品名称"
style="width: 240px"
/>
</Form-item>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
clearable
placeholder="请输入会员名称"
style="width: 240px"
/>
</Form-item>
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
clearable
placeholder="请输入订单编号"
style="width: 240px"
/>
</Form-item>
<Form-item label="申请时间">
<DatePicker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 240px"
></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
<Button @click="handleReset" class="search-btn">重置</Button>
</Form>
</Row>
</Card>
<Card>
<div class="order-tab">
<Tabs v-model="currentStatus" @on-click="serviceStatusClick">
<TabPane v-for="item in serviceStatusWithCount" :key="item.value" :label="item.title" :name="item.value"/>
</Tabs>
</div>
<Table
:loading="loading"
class="mt_10"
:columns="columns"
:data="data"
ref="table"
<el-card>
<el-form
ref="searchForm"
:model="searchForm"
inline
label-width="70px"
class="search-form"
@keyup.enter="handleSearch"
>
<el-form-item label="关键字" prop="keywords">
<el-input
v-model="searchForm.keywords"
placeholder="请输入商品名称、订单编号搜索"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="订单编号" prop="orderSn">
<el-input
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="售后单号" prop="sn">
<el-input
v-model="searchForm.sn"
placeholder="请输入售后单号"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="申请时间">
<el-date-picker
v-model="selectDate"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
clearable
start-placeholder="开始时间"
end-placeholder="结束时间"
style="width: 360px"
@change="selectDateRange"
/>
</el-form-item>
<el-form-item label="商家名称" prop="storeName">
<el-input
v-model="searchForm.storeName"
placeholder="请输入商家名称"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="会员名称" prop="memberName">
<el-input
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 商品栏目格式化 -->
<template slot="goodsSlot" slot-scope="{row}">
<div style="margin-top: 5px;height: 60px; display: flex;">
<div style="">
<img :src="row.goodsImage" style="height: 50px;margin-top: 3px">
</div>
<el-card>
<div class="order-tab">
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
<el-tab-pane
v-for="item in serviceStatusWithCount"
:key="item.value"
:label="item.title"
:name="item.value"
/>
</el-tabs>
</div>
<div style="margin-left: 13px;">
<div class="div-zoom">
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<el-table
ref="table"
v-loading="loading"
:data="data"
class="mt_10"
style="width: 100%"
>
<el-table-column prop="sn" label="售后服务单号" min-width="140" show-overflow-tooltip />
<el-table-column prop="orderSn" label="订单编号" min-width="120" show-overflow-tooltip />
<el-table-column label="商品" min-width="300">
<template #default="{ row }">
<div v-if="row" style="margin-top: 5px; height: 80px; display: flex">
<div>
<img
:src="row.goodsImage"
style="width: 60px; height: 60px; margin-top: 3px; object-fit: cover; border-radius: 4px"
alt=""
/>
</div>
<div style="margin-left: 13px">
<div class="div-zoom">
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
</div>
<div style="color: #999; font-size: 12px; margin-top: 5px">
商品ID: {{ row.goodsId }}
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="memberId" label="会员ID" min-width="120" show-overflow-tooltip />
<el-table-column prop="memberName" label="会员名称" width="140" />
<el-table-column prop="storeName" label="店铺名称" width="100" show-overflow-tooltip />
<el-table-column label="售后金额" width="110">
<template #default="{ row }">
<span v-if="row" :style="{ color: $mainColor }">
{{ $filters.unitPrice(row.applyRefundPrice, "") }}</span>
</template>
</el-table-column>
<el-table-column label="售后状态" width="180">
<template #default="{ row }">
<el-tag
v-if="row"
:type="serviceStatusTagType(row.serviceStatus)"
effect="plain"
>
{{ serviceStatusText(row.serviceStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="申请时间" width="180" />
<el-table-column label="操作" fixed="right" align="center" width="100">
<template #default="{ row }">
<a v-if="row" class="link-text" @click="detail(row)">查看</a>
</template>
</el-table-column>
</el-table>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
<div class="mt_10" style="display: flex; justify-content: flex-end">
<el-pagination
v-model:current-page="searchForm.pageNumber"
v-model:page-size="searchForm.pageSize"
:page-sizes="[20, 50, 100]"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
@current-change="changePage"
@size-change="changePageSize"
/>
</div>
</el-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import * as API_Order from "@/api/order";
export default {
name: "returnGoodsOrder",
components: {},
data() {
return {
loading: true, // 表单加载状态
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
// serviceType:"RETURN_GOODS",
orderSn:"",
memberName:"",
goodsName:""
export default {
name: "after-sale-order",
data() {
return {
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
serviceType: "RETURN_GOODS",
orderSn: "",
memberName: "",
serviceStatus: "",
storeName: "",
sn: "",
keywords: "",
},
selectDate: null,
data: [],
total: 0,
currentStatus: "",
afterSaleNumData: {},
};
},
computed: {
serviceStatusWithCount() {
return [
{ title: "全部", value: "" },
{
title: `申请售后${this.afterSaleNumData.applyNum ? "(" + this.afterSaleNumData.applyNum + ")" : ""}`,
value: "APPLY",
},
selectDate: null,
columns: [
{
title: "售后单号",
key: "sn",
minWidth: 150,
},
{
title: "订单号",
key: "orderSn",
minWidth: 150,
},
{
title: "商品",
key: "sn",
minWidth: 200,
slot: "goodsSlot",
},
{
title: "申请退款金额",
key: "applyRefundPrice",
width: 130,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
},
},
{
title: "会员名称",
key: "memberName",
minWidth: 120,
},
{
title: "会员ID",
key: "memberId",
minWidth: 120,
},
{
title: "状态",
align: "center",
key: "serviceStatus",
width: 200,
render: (h, params) => {
if (params.row.serviceStatus == "APPLY") {
return h('div', [h('tag', {props: {color: "blue"}}, '申请中'),]);
} else if (params.row.serviceStatus == "PASS") {
return h('div', [h('tag', {props: {color: "cyan"}}, '通过售后'),]);
} else if (params.row.serviceStatus == "REFUSE") {
return h('div', [h('tag', {props: {color: "volcano"}}, '拒绝售后'),]);
} else if (params.row.serviceStatus == "BUYER_RETURN") {
return h('div', [h('tag', {props: {color: "orange"}}, '买家退货,待卖家收货'),]);
} else if (params.row.serviceStatus == "SELLER_CONFIRM") {
return h('div', [h('tag', {props: {color: "gold"}}, '卖家确认收货'),]);
} else if (params.row.serviceStatus == "SELLER_TERMINATION") {
return h('div', [h('tag', {props: {color: "lime"}}, '卖家终止售后'),]);
} else if (params.row.serviceStatus == "BUYER_CANCEL") {
return h('div', [h('tag', {props: {color: "purple"}}, '买家取消售后'),]);
} else if (params.row.serviceStatus == "COMPLETE") {
return h('div', [h('tag', {props: {color: "green"}}, '完成售后'),]);
}else if (params.row.serviceStatus == "WAIT_REFUND") {
return h('div', [h('tag', {props: {color: "geekblue"}}, '待平台退款'),]);
}
}
},
{
title: "申请时间",
key: "createTime",
width: 170
},
{
title: "操作",
key: "action",
align: "center",
fixed: 'right',
width: 200,
render: (h, params) => {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]);
},
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
serviceStatus: [
{title: '全部', value: ''},
{title: '申请售后', value: 'APPLY'},
{title: '通过售后', value: 'PASS'},
{title: '拒绝售后', value: 'REFUSE'},
{title: '待收货', value: 'BUYER_RETURN'},
{title: '确认收货', value: 'SELLER_CONFIRM'},
{title: '完成售后', value: 'COMPLETE'},
{title: '卖家终止售后', value: 'SELLER_TERMINATION'},
{title: '买家取消售后', value: 'BUYER_CANCEL'},
{title: '等待平台退款', value: 'WAIT_REFUND'}
],
currentStatus: '',
afterSaleNumData: {} // 售后数量统计数据
{
title: `通过售后${this.afterSaleNumData.passNum ? "(" + this.afterSaleNumData.passNum + ")" : ""}`,
value: "PASS",
},
{
title: `拒绝售后${this.afterSaleNumData.refuseNum ? "(" + this.afterSaleNumData.refuseNum + ")" : ""}`,
value: "REFUSE",
},
{
title: `待收货${this.afterSaleNumData.buyerReturnNum ? "(" + this.afterSaleNumData.buyerReturnNum + ")" : ""}`,
value: "BUYER_RETURN",
},
{
title: `确认收货${this.afterSaleNumData.sellerConfirmNum ? "(" + this.afterSaleNumData.sellerConfirmNum + ")" : ""}`,
value: "SELLER_CONFIRM",
},
{
title: `完成售后${this.afterSaleNumData.completeNum ? "(" + this.afterSaleNumData.completeNum + ")" : ""}`,
value: "COMPLETE",
},
{
title: `卖家终止售后${this.afterSaleNumData.sellerTerminationNum ? "(" + this.afterSaleNumData.sellerTerminationNum + ")" : ""}`,
value: "SELLER_TERMINATION",
},
{
title: `买家取消售后${this.afterSaleNumData.buyerCancelNum ? "(" + this.afterSaleNumData.buyerCancelNum + ")" : ""}`,
value: "BUYER_CANCEL",
},
{
title: `等待平台退款${this.afterSaleNumData.waitRefundNum ? "(" + this.afterSaleNumData.waitRefundNum + ")" : ""}`,
value: "WAIT_REFUND",
},
];
},
},
methods: {
serviceStatusText(status) {
const map = {
APPLY: "申请中",
PASS: "通过售后",
REFUSE: "拒绝售后",
BUYER_RETURN: "买家退货,待卖家收货",
SELLER_CONFIRM: "卖家确认收货",
SELLER_TERMINATION: "卖家终止售后",
BUYER_CANCEL: "买家取消售后",
COMPLETE: "完成售后",
WAIT_REFUND: "待平台退款",
};
return map[status] || status || "-";
},
methods: {
// 初始化数据
init() {
this.getDataList();
this.getAfterSaleNumData();
},
// 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
this.getAfterSaleNumData();
},
// 重置
handleReset() {
const defaultForm = {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
// serviceType:"RETURN_GOODS",
orderSn:"",
memberName:"",
goodsName:""
}
this.searchForm = defaultForm;
this.selectDate = ''
this.getDataList();
this.getAfterSaleNumData();
},
// 范围时间选择格式化
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
}
},
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.afterSaleOrderPage(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
this.loading = false;
},
// 获取售后数量统计
getAfterSaleNumData() {
const { serviceStatus, ...searchParams } = this.searchForm;
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
if (res.success) {
this.afterSaleNumData = res.result;
}
});
},
// 退货订单详情
detail(v) {
let sn = v.sn;
this.$options.filters.customRouterPush({
name: "return-goods-order-detail",
query: { sn: sn },
})
},
// 售后筛选
serviceStatusClick(item) {
this.currentStatus = item;
// 如果是全部空字符串则删除serviceStatus字段
if (item === 0) {
delete this.searchForm.serviceStatus;
} else {
this.searchForm.serviceStatus = item;
}
this.getDataList();
this.getAfterSaleNumData();
},
serviceStatusTagType(status) {
const map = {
APPLY: "primary",
PASS: "info",
REFUSE: "warning",
BUYER_RETURN: "warning",
SELLER_CONFIRM: "",
SELLER_TERMINATION: "success",
BUYER_CANCEL: "danger",
COMPLETE: "success",
WAIT_REFUND: "primary",
};
return map[status] || "info";
},
mounted () {
this.init();
init() {
this.getDataList();
this.getAfterSaleNumData();
},
computed: {
// 带数量的售后状态
serviceStatusWithCount() {
return [
{title: '全部', value: ''},
{title: `申请售后${this.afterSaleNumData.applyNum ? '(' + this.afterSaleNumData.applyNum + ')' : ''}`, value: 'APPLY'},
{title: `通过售后${this.afterSaleNumData.passNum ? '(' + this.afterSaleNumData.passNum + ')' : ''}`, value: 'PASS'},
{title: `拒绝售后${this.afterSaleNumData.refuseNum ? '(' + this.afterSaleNumData.refuseNum + ')' : ''}`, value: 'REFUSE'},
{title: `待收货${this.afterSaleNumData.buyerReturnNum ? '(' + this.afterSaleNumData.buyerReturnNum + ')' : ''}`, value: 'BUYER_RETURN'},
{title: `确认收货${this.afterSaleNumData.sellerConfirmNum ? '(' + this.afterSaleNumData.sellerConfirmNum + ')' : ''}`, value: 'SELLER_CONFIRM'},
{title: `完成售后${this.afterSaleNumData.completeNum ? '(' + this.afterSaleNumData.completeNum + ')' : ''}`, value: 'COMPLETE'},
{title: `卖家终止售后${this.afterSaleNumData.sellerTerminationNum ? '(' + this.afterSaleNumData.sellerTerminationNum + ')' : ''}`, value: 'SELLER_TERMINATION'},
{title: `买家取消售后${this.afterSaleNumData.buyerCancelNum ? '(' + this.afterSaleNumData.buyerCancelNum + ')' : ''}`, value: 'BUYER_CANCEL'},
{title: `等待平台退款${this.afterSaleNumData.waitRefundNum ? '(' + this.afterSaleNumData.waitRefundNum + ')' : ''}`, value: 'WAIT_REFUND'}
];
changePage() {
this.getDataList();
},
changePageSize() {
this.searchForm.pageNumber = 1;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
this.getAfterSaleNumData();
},
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
} else {
this.searchForm.startDate = "";
this.searchForm.endDate = "";
}
},
// 页面缓存处理从该页面离开时修改KeepAlive为false保证进入该页面是刷新
beforeRouteLeave(to, from, next) {
from.meta.keepAlive = false
next()
}
};
getDataList() {
this.loading = true;
API_Order.getAfterSaleOrderPage(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
},
getAfterSaleNumData() {
const { serviceStatus, ...searchParams } = this.searchForm;
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
if (res.success) {
this.afterSaleNumData = res.result;
}
});
},
detail(v) {
const sn = v.sn;
this.$filters.customRouterPush({
name: "return-goods-order-detail",
query: { sn: sn },
});
},
onStatusTabClick(tab) {
this.serviceStatusClick(tab.paneName);
},
serviceStatusClick(item) {
this.currentStatus = item;
if (item === "" || item === undefined) {
delete this.searchForm.serviceStatus;
} else {
this.searchForm.serviceStatus = item;
}
this.getDataList();
this.getAfterSaleNumData();
},
},
mounted() {
this.init();
},
};
</script>
<style lang="scss">
// 建议引入通用样式 可删除下面样式代码
@import "@/styles/table-common.scss";
// Tab组件样式
.order-tab {
::v-deep .ivu-tabs-tab {
font-size: 14px;
}
<style lang="scss" scoped>
.order-tab {
:deep(.el-tabs__item) {
font-size: 14px;
}
}
.link-text {
color: #409eff;
cursor: pointer;
text-decoration: none;
}
.mt_10 {
margin-top: 10px;
}
</style>

View File

@@ -1,298 +1,339 @@
<template>
<div class="search">
<Card>
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="商品" prop="goodsName">
<Input
type="text"
v-model="searchForm.goodsName"
<el-card>
<el-form
ref="searchForm"
:model="searchForm"
inline
label-width="70px"
class="search-form"
@keyup.enter="handleSearch"
>
<el-form-item label="关键字" prop="keywords">
<el-input
v-model="searchForm.keywords"
placeholder="请输入商品名称、订单编号搜索"
clearable
placeholder="请输入商品名称"
style="width: 240px"
/>
</Form-item>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
clearable
placeholder="请输入会员名称"
style="width: 240px"
/>
</Form-item>
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
</el-form-item>
<el-form-item label="订单编号" prop="orderSn">
<el-input
v-model="searchForm.orderSn"
clearable
placeholder="请输入订单编号"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="申请时间">
<DatePicker
</el-form-item>
<el-form-item label="售后单号" prop="sn">
<el-input
v-model="searchForm.sn"
placeholder="请输入售后单号"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="会员名称" prop="memberName">
<el-input
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="申请时间">
<el-date-picker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 240px"
></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
<Button @click="handleReset" class="search-btn">重置</Button>
</Form>
</Card>
<Card>
<Table
:loading="loading"
border
class="mt_10"
:columns="columns"
:data="data"
start-placeholder="开始时间"
end-placeholder="结束时间"
style="width: 360px"
@change="selectDateRange"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
<el-button class="search-btn" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card>
<div class="order-tab">
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
<el-tab-pane
v-for="item in serviceStatusWithCount"
:key="item.value"
:label="item.title"
:name="item.value"
/>
</el-tabs>
</div>
<el-table
ref="table"
v-loading="loading"
:data="data"
class="mt_10"
style="width: 100%"
>
<!-- 商品栏目格式化 -->
<template slot="goodsSlot" slot-scope="{row}">
<div style="margin-top: 5px;height: 90px; display: flex;">
<div style="">
<img :src="row.goodsImage" style="height: 80px;margin-top: 3px">
</div>
<div style="margin-left: 13px;">
<div class="div-zoom">
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<el-table-column prop="sn" label="售后服务单号" min-width="140" show-overflow-tooltip />
<el-table-column prop="orderSn" label="订单编号" min-width="120" show-overflow-tooltip />
<el-table-column label="商品" min-width="300">
<template #default="{ row }">
<div v-if="row" style="margin-top: 5px; height: 80px; display: flex">
<div>
<img
:src="row.goodsImage"
style="width: 60px; height: 60px; margin-top: 3px; object-fit: cover; border-radius: 4px"
alt=""
/>
</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
<div style="margin-left: 13px">
<div class="div-zoom">
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
</div>
<img src="../../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
</Poptip>
<div style="color: #999; font-size: 12px; margin-top: 5px">
商品ID: {{ row.goodsId }}
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="memberId" label="会员ID" min-width="120" show-overflow-tooltip />
<el-table-column prop="memberName" label="会员名称" width="140" />
<el-table-column label="售后金额" width="110">
<template #default="{ row }">
<span v-if="row" :style="{ color: $mainColor }">
{{ $filters.unitPrice(row.applyRefundPrice, "") }}</span>
</template>
</el-table-column>
<el-table-column label="售后状态" width="180">
<template #default="{ row }">
<el-tag
v-if="row"
:type="serviceStatusTagType(row.serviceStatus)"
effect="plain"
>
{{ serviceStatusText(row.serviceStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="申请时间" width="180" />
<el-table-column label="操作" fixed="right" align="center" width="100">
<template #default="{ row }">
<a v-if="row" class="link-text" @click="detail(row)">查看</a>
</template>
</el-table-column>
</el-table>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
<div class="mt_10" style="display: flex; justify-content: flex-end">
<el-pagination
v-model:current-page="searchForm.pageNumber"
v-model:page-size="searchForm.pageSize"
:page-sizes="[20, 50, 100]"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
@current-change="changePage"
@size-change="changePageSize"
/>
</div>
</el-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import * as API_Order from "@/api/order";
export default {
name: "returnMoneyOrder",
data() {
return {
loading: true, // 表单加载状态
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
serviceType:"RETURN_MONEY",
orderSn:"",
memberName:"",
goodsName:""
const createDefaultSearchForm = () => ({
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
serviceType: "RETURN_MONEY",
orderSn: "",
memberName: "",
serviceStatus: "",
sn: "",
keywords: "",
});
export default {
name: "returnMoneyOrder",
data() {
return {
loading: true,
searchForm: createDefaultSearchForm(),
selectDate: null,
data: [],
total: 0,
currentStatus: "",
afterSaleNumData: {},
};
},
computed: {
serviceStatusWithCount() {
return [
{ title: "全部", value: "" },
{
title: `申请售后${this.afterSaleNumData.applyNum ? "(" + this.afterSaleNumData.applyNum + ")" : ""}`,
value: "APPLY",
},
selectDate: null,
submitLoading: false, // 添加或编辑提交状态
columns: [
// 表头
{
title: "退款编号",
key: "sn",
minWidth: 150,
},
{
title: "订单号",
key: "orderSn",
minWidth: 150,
},
{
title: "商品",
key: "sn",
minWidth: 250,
sortable: false,
slot: "goodsSlot",
},
{
title: "申请退款金额",
key: "applyRefundPrice",
width: 130,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
},
},
{
title: "会员",
key: "memberName",
minWidth: 130,
tooltip: true
},
{
title: "申请时间",
key: "createTime",
width: 170
},
{
title: "售后状态",
key: "serviceStatus",
minWidth: 120,
render: (h, params) => {
if (params.row.serviceStatus == "APPLY") {
return h('div', [h('tag', {props: {color: "blue"}}, '申请中'),]);
} else if (params.row.serviceStatus == "PASS") {
return h('div', [h('tag', {props: {color: "cyan"}}, '通过售后'),]);
} else if (params.row.serviceStatus == "REFUSE") {
return h('div', [h('tag', {props: {color: "volcano"}}, '拒绝售后'),]);
} else if (params.row.serviceStatus == "BUYER_CANCEL") {
return h('div', [h('tag', {props: {color: "purple"}}, '买家取消售后'),]);
} else if (params.row.serviceStatus == "COMPLETE") {
return h('div', [h('tag', {props: {color: "green"}}, '完成售后'),]);
}else if (params.row.serviceStatus == "WAIT_REFUND") {
return h('div', [h('tag', {props: {color: "geekblue"}}, '待平台退款'),]);
}
}
},
{
title: "操作",
key: "action",
align: "center",
fixed: 'right',
width: 200,
render: (h, params) => {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]);
},
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
};
{
title: `通过售后${this.afterSaleNumData.passNum ? "(" + this.afterSaleNumData.passNum + ")" : ""}`,
value: "PASS",
},
{
title: `拒绝售后${this.afterSaleNumData.refuseNum ? "(" + this.afterSaleNumData.refuseNum + ")" : ""}`,
value: "REFUSE",
},
{
title: `完成售后${this.afterSaleNumData.completeNum ? "(" + this.afterSaleNumData.completeNum + ")" : ""}`,
value: "COMPLETE",
},
{
title: `卖家终止售后${this.afterSaleNumData.sellerTerminationNum ? "(" + this.afterSaleNumData.sellerTerminationNum + ")" : ""}`,
value: "SELLER_TERMINATION",
},
{
title: `买家取消售后${this.afterSaleNumData.buyerCancelNum ? "(" + this.afterSaleNumData.buyerCancelNum + ")" : ""}`,
value: "BUYER_CANCEL",
},
{
title: `等待平台退款${this.afterSaleNumData.waitRefundNum ? "(" + this.afterSaleNumData.waitRefundNum + ")" : ""}`,
value: "WAIT_REFUND",
},
];
},
methods: {
// 初始化数据
init() {
this.getDataList();
},
// 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 重置
handleReset() {
this.searchForm = {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
serviceType:"RETURN_MONEY",
orderSn:"",
memberName:"",
goodsName:""
}
this.selectDate = ''
this.getDataList();
},
// 范围时间重新赋值
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
}
},
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.afterSaleOrderPage(this.searchForm).then((res) => {
this.loading = false;
},
methods: {
serviceStatusText(status) {
const map = {
APPLY: "申请中",
PASS: "通过售后",
REFUSE: "拒绝售后",
BUYER_RETURN: "买家退货,待卖家收货",
SELLER_CONFIRM: "卖家确认收货",
SELLER_TERMINATION: "卖家终止售后",
BUYER_CANCEL: "买家取消售后",
COMPLETE: "完成售后",
WAIT_REFUND: "待平台退款",
};
return map[status] || status || "-";
},
serviceStatusTagType(status) {
const map = {
APPLY: "primary",
PASS: "info",
REFUSE: "warning",
BUYER_RETURN: "warning",
SELLER_CONFIRM: "",
SELLER_TERMINATION: "success",
BUYER_CANCEL: "danger",
COMPLETE: "success",
WAIT_REFUND: "primary",
};
return map[status] || "info";
},
init() {
this.getDataList();
this.getAfterSaleNumData();
},
changePage() {
this.getDataList();
},
changePageSize() {
this.searchForm.pageNumber = 1;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
this.getAfterSaleNumData();
},
handleReset() {
this.searchForm = createDefaultSearchForm();
this.selectDate = null;
this.currentStatus = "";
this.getDataList();
this.getAfterSaleNumData();
},
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
} else {
this.searchForm.startDate = "";
this.searchForm.endDate = "";
}
},
getDataList() {
this.loading = true;
API_Order.getAfterSaleOrderPage(this.searchForm)
.then((res) => {
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
this.loading = false;
},
// 退款订单详情
detail(v) {
let sn = v.sn;
this.$options.filters.customRouterPush({
name: "return-goods-order-detail",
query: { sn: sn },
})
},
.finally(() => {
this.loading = false;
});
},
mounted() {
this.init();
getAfterSaleNumData() {
const { serviceStatus, ...searchParams } = this.searchForm;
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
if (res.success) {
this.afterSaleNumData = res.result;
}
});
},
// 页面缓存处理从该页面离开时修改KeepAlive为false保证进入该页面是刷新
beforeRouteLeave(to, from, next) {
from.meta.keepAlive = false
next()
}
};
detail(v) {
this.$filters.customRouterPush({
name: "return-goods-order-detail",
query: { sn: v.sn },
});
},
onStatusTabClick(tab) {
this.serviceStatusClick(tab.paneName);
},
serviceStatusClick(item) {
this.currentStatus = item;
if (item === "" || item === undefined) {
delete this.searchForm.serviceStatus;
} else {
this.searchForm.serviceStatus = item;
}
this.getDataList();
this.getAfterSaleNumData();
},
},
mounted() {
this.init();
},
};
</script>
<style lang="scss">
// 建议引入通用样式 可删除下面样式代码
@import "@/styles/table-common.scss";
<style lang="scss" scoped>
.order-tab {
:deep(.el-tabs__item) {
font-size: 14px;
}
}
.link-text {
color: #409eff;
cursor: pointer;
text-decoration: none;
}
.mt_10 {
margin-top: 10px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,73 +1,78 @@
<template>
<Card>
<el-card>
<div class="step-list">
<div class="step-item" @click="handleCheckStep(item)" :class="{'active':item.checked}" v-for="(item,index) in stepList" :key="index">
<img class="img" :src="item.img" alt="">
<div
v-for="(item, index) in stepList"
:key="index"
class="step-item"
:class="{ active: item.checked }"
@click="handleCheckStep(item)"
>
<img class="img" :src="item.img" alt="" />
<div>
<h2>{{item.title}}</h2>
<h2>{{ item.title }}</h2>
</div>
</div>
</div>
<div v-for="(item,index) in stepList" :key="index">
<!-- 下载 -->
<div v-if="item.checked && index ==0" class="tpl">
<Button @click="downLoad">下载导入模板</Button>
<div v-for="(item, index) in stepList" :key="'step-' + index">
<div v-if="item.checked && index === 0" class="tpl">
<el-button @click="downLoad">下载导入模板</el-button>
</div>
<!-- 上传 -->
<div v-if="item.checked && index ==1" class="tpl">
<Upload :before-upload="handleUpload" name="files" style="width:50%; height:400px;" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
multiple type="drag" :action="action" :headers="accessToken">
<div style="padding: 50px 0">
<Icon type="ios-cloud-upload" size="102" style="color: #3399ff"></Icon>
<h2>选择或拖拽文件上传</h2>
</div>
</Upload>
<div v-if="item.checked && index === 1" class="tpl">
<el-upload
drag
name="files"
style="width: 50%; height: 400px"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
:action="action"
:headers="accessToken"
:before-upload="handleUpload"
:show-file-list="false"
>
<el-icon :size="102" style="color: #3399ff"><UploadFilled /></el-icon>
<h2>选择或拖拽文件上传</h2>
</el-upload>
</div>
<!-- 上传 -->
<div v-if="item.checked && index ==2" class="tpl success">
<div v-if="item.checked && index === 2" class="tpl success">
<h1>发货完成</h1>
<div>
<Button class="btn" @click="close">关闭页面</Button>
<Button class="btn" type="primary" @click="navigationToGoodsOrder">商品订单</Button>
<el-button class="btn" @click="close">关闭页面</el-button>
<el-button class="btn" type="primary" @click="navigationToGoodsOrder">商品订单</el-button>
</div>
</div>
</div>
</Card>
</el-card>
</template>
<script>
import JsonExcel from "vue-json-excel";
import { UploadFilled } from "@element-plus/icons-vue";
import { downLoadDeliverExcel, uploadDeliverExcel } from "@/api/order.js";
import { baseUrl } from "@/libs/axios.js";
import downloadImg from "@/assets/download.png";
import uploadImg from "@/assets/upload.png";
import successImg from "@/assets/success.png";
export default {
components: {
"download-excel": JsonExcel,
},
components: { UploadFilled },
data() {
return {
file: "",
action: baseUrl + "/order/order/batchDeliver", // 上传接口
accessToken: {}, // 验证token
// 步骤集合
action: baseUrl + "/order/order/batchDeliver",
accessToken: {},
stepList: [
{
img: require("@/assets/download.png"),
img: downloadImg,
title: "1.下载批量发货导入模板",
checked: true,
},
{
img: require("@/assets/upload.png"),
img: uploadImg,
title: "2.上传数据",
checked: false,
},
{
img: require("@/assets/success.png"),
img: successImg,
title: "3.完成",
checked: false,
},
@@ -78,75 +83,55 @@ export default {
this.accessToken.accessToken = this.getStore("accessToken");
},
methods: {
// 点击选择步骤
handleCheckStep(val) {
if (val.title.search("3") == -1) {
this.stepList.map((item) => {
if (val.title.search("3") === -1) {
this.stepList.forEach((item) => {
item.checked = false;
});
val.checked = true;
}
},
// 上传数据
handleUpload(file) {
this.file = file;
this.upload();
return false;
},
// 跳转订单列表
navigationToGoodsOrder() {
this.$router.push({
path: "/order/orderList",
});
this.$router.push({ path: "/order/orderList" });
},
// 关闭页面
close() {
this.$store.commit("removeTag", "export-order-deliver");
localStorage.storeOpenedList = JSON.stringify(
this.$store.state.app.storeOpenedList
);
localStorage.storeOpenedList = JSON.stringify(this.$store.state.app.storeOpenedList);
this.$router.go(-1);
},
/**
* 上传文件
*/
async upload() {
let fd = new FormData();
const fd = new FormData();
fd.append("files", this.file);
let res = await uploadDeliverExcel(fd);
const res = await uploadDeliverExcel(fd);
if (res.success) {
this.stepList.map((item) => {
this.stepList.forEach((item) => {
item.checked = false;
});
this.stepList[2].checked = true;
}
},
/**
* 下载excel
*/
downLoad() {
downLoadDeliverExcel()
.then((res) => {
const blob = new Blob([res], {
type: "application/vnd.ms-excel;charset=utf-8",
});
//对于<a>标签,只有 Firefox 和 Chrome内核 支持 download 属性
//IE10以上支持blob但是依然不支持download
if ("download" in document.createElement("a")) {
//支持a标签download的浏览器
const link = document.createElement("a"); //创建a标签
link.download = "批量发货导入模板.xls"; //a标签添加属性
const link = document.createElement("a");
link.download = "批量发货导入模板.xls";
link.style.display = "none";
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click(); //执行下载
URL.revokeObjectURL(link.href); //释放url
document.body.removeChild(link); //释放标签
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
} else {
navigator.msSaveBlob(blob, fileName);
navigator.msSaveBlob(blob, "批量发货导入模板.xls");
}
})
.catch((err) => {
@@ -201,7 +186,7 @@ img {
font-size: 28px;
margin: 10px;
}
::v-deep .btn {
:deep(.btn) {
margin: 10px;
}
}

View File

@@ -1,543 +1,415 @@
<template>
<div class="search">
<Card>
<Form
<el-card>
<el-form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
label-width="70px"
class="search-form"
@keyup.enter="handleSearch"
>
<Form-item label="关键字" prop="keywords" style="display: block; width: 100%;">
<Input
type="text"
<el-form-item label="关键字" prop="keywords" style="display: block; width: 100%">
<el-input
v-model="searchForm.keywords"
placeholder="请输入商品名称/收货人/收货人手机号/店铺名称"
clearable
style="width: 500px"
/>
</Form-item>
<Form-item label="订单号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
clearable
placeholder="请输入订单编号"
style="width: 240px"
/>
</Form-item>
<Form-item label="会员名称" prop="buyerName">
<Input
type="text"
v-model="searchForm.buyerName"
clearable
placeholder="请输入会员名称"
style="width: 240px"
/>
</Form-item>
<Form-item label="收货人" prop="shipName">
<Input
type="text"
v-model="searchForm.shipName"
placeholder="请输入收货人姓名"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="订单类型" prop="orderType">
<Select
v-model="searchForm.orderPromotionType"
placeholder="请选择"
clearable
style="width: 240px"
>
<Option value="NORMAL">普通订单</Option>
<Option value="PINTUAN">拼团订单</Option>
<Option value="GIFT">赠品订单</Option>
<Option value="POINTS">积分订单</Option>
<Option value="KANJIA">砍价订单</Option>
</Select>
</Form-item>
<Form-item label="下单时间">
<DatePicker
</el-form-item>
<el-form-item label="订单号" prop="orderSn">
<el-input v-model="searchForm.orderSn" placeholder="请输入订单号" clearable style="width: 240px" />
</el-form-item>
<el-form-item label="会员名称" prop="buyerName">
<el-input v-model="searchForm.buyerName" placeholder="请输入会员名称" clearable style="width: 240px" />
</el-form-item>
<el-form-item label="商品名称" prop="goodsName">
<el-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
</el-form-item>
<el-form-item label="收货人" prop="shipName">
<el-input v-model="searchForm.shipName" placeholder="请输入收货人姓名" clearable style="width: 240px" />
</el-form-item>
<el-form-item label="订单类型" prop="orderType">
<el-select v-model="searchForm.orderPromotionType" placeholder="请选择" clearable style="width: 240px">
<el-option label="普通订单" value="NORMAL" />
<el-option label="拼团订单" value="PINTUAN" />
<el-option label="赠品订单" value="GIFT" />
<el-option label="积分订单" value="POINTS" />
<el-option label="砍价订单" value="KANJIA" />
</el-select>
</el-form-item>
<el-form-item label="支付方式" prop="paymentMethod">
<el-select v-model="searchForm.paymentMethod" placeholder="请选择支付方式" clearable style="width: 240px">
<el-option label="微信支付" value="WECHAT" />
<el-option label="支付宝" value="ALIPAY" />
<el-option label="余额支付" value="WALLET" />
<el-option label="线下转账" value="BANK_TRANSFER" />
</el-select>
</el-form-item>
<el-form-item label="下单时间">
<el-date-picker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd"
value-format="YYYY-MM-DD HH:mm:ss"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 240px"
></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn"
>搜索</Button
>
<Button @click="handleReset" class="search-btn">重置</Button>
</Form>
</Card>
<Card>
start-placeholder="开始时间"
end-placeholder="结束时间"
style="width: 360px"
@change="selectDateRange"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card>
<div class="order-tab">
<Tabs v-model="currentStatus" @on-click="orderStatusClick">
<TabPane v-for="(item,index) in orderStatusWithCount" :key="index" :label="item.title" :name="item.value">
</TabPane>
</Tabs>
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
<el-tab-pane
v-for="(item, index) in orderStatusWithCount"
:key="index"
:label="item.title"
:name="item.value"
/>
</el-tabs>
</div>
<div class="export">
<Button type="primary" class="mr_10" @click="expressOrderDeliver">批量发货</Button>
<Button @click="exportOrder" type="info" class="export">导出订单</Button>
<Poptip @keydown.enter.native="orderVerification" placement="bottom-start" width="400">
<Button class="export">
核验订单
</Button>
<div class="api" slot="content">
<h2>核验码</h2>
<div style="margin:10px 0;">
<Input v-model="orderCode" style="width:300px; margin-right:10px;" />
<Button style="primary" @click="orderVerification">核验</Button>
</div>
</div>
</Poptip>
<div>
<el-button type="info" class="export" @click="exportOrder">导出订单</el-button>
</div>
<Table
:loading="loading"
:columns="columns"
:data="data"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
<el-table v-loading="loading" :data="data" ref="table" class="mt_10" style="width: 100%">
<el-table-column prop="sn" label="订单号" min-width="240" show-overflow-tooltip />
<el-table-column label="订单来源" width="120">
<template #default="{ row }">{{ clientTypeText(row.clientType) }}</template>
</el-table-column>
<el-table-column label="订单类型" width="120">
<template #default="{ row }">
<el-tag :type="orderPromotionTagType(row.orderPromotionType)">
{{ orderPromotionText(row.orderPromotionType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="memberName" label="买家名称" min-width="130" show-overflow-tooltip />
<el-table-column prop="memberId" label="会员ID" min-width="120" show-overflow-tooltip />
<el-table-column prop="storeName" label="店铺名称" min-width="150" show-overflow-tooltip />
<el-table-column label="订单金额" min-width="100">
<template #default="{ row }">
<span :style="{ color: $mainColor }">{{ $filters.unitPrice(row.flowPrice, '¥') }}</span>
</template>
</el-table-column>
<el-table-column label="支付方式" width="120">
<template #default="{ row }">{{ paymentMethodText(row.paymentMethod) }}</template>
</el-table-column>
<el-table-column label="订单状态" min-width="100">
<template #default="{ row }">
<el-tag :type="orderStatusTagType(row.orderStatus)">{{ orderStatusText(row.orderStatus) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="下单时间" width="170" />
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="{ row }">
<a class="link-text" @click="detail(row)">查看</a>
</template>
</el-table-column>
</el-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<el-pagination
v-model:current-page="searchForm.pageNumber"
v-model:page-size="searchForm.pageSize"
:page-sizes="[20, 50, 100]"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
@current-change="changePage"
@size-change="changePageSize"
/>
</div>
</el-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import JsonExcel from "vue-json-excel";
import Cookies from "js-cookie";
import {verificationCode} from "@/api/order";
export default {
name: "orderList",
components: {
"download-excel": JsonExcel,
},
data() {
return {
loading: true, // 表单加载状态
fields: {
订单编号: "sn",
下单时间: "createTime",
客户名称: "memberName",
支付方式: {
field: "clientType",
callback: (value) => {
if (value == "H5") return "移动端";
if (value == "PC") return "PC端";
if (value == "WECHAT_MP") return "小程序端";
if (value == "APP") return "移动应用端";
return value;
},
},
商品数量: "groupNum",
付款状态: {
field: "payStatus",
callback: (value) =>
value == "UNPAID" ? "未付款" : value == "PAID" ? "已付款" : "",
},
店铺: "storeName",
},
loading: true,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "", // 默认排序字段
order: "", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderType: "",
orderSn: "",
keywords: "",
buyerName: "",
goodsName: "",
shipName: "",
orderStatus: "",
orderType: "NORMAL",
paymentMethod: "",
orderPromotionType: "",
},
selectDate: null,
columns: [
{
title: "订单号",
key: "sn",
minWidth: 200,
tooltip: true,
render: (h, params) => {
if (params.row.sellerRemark) {
return h("div", {}, params.row.sellerRemark + " ("+params.row.sn+")");
} else {
return h("div", {}, params.row.sn);
}
},
},
{
title: "订单来源",
key: "clientType",
width: 120,
render: (h, params) => {
if (params.row.clientType == "H5") {
return h("div", {}, "移动端");
} else if (params.row.clientType == "PC") {
return h("div", {}, "PC端");
} else if (params.row.clientType == "WECHAT_MP") {
return h("div", {}, "小程序端");
} else if (params.row.clientType == "APP") {
return h("div", {}, "APP端");
} else {
return h("div", {}, params.row.clientType);
}
},
},
{
title: "订单类型",
key: "orderPromotionType",
width: 120,
render: (h, params) => {
if (params.row.orderPromotionType == "NORMAL") {
return h("div", [
h("tag", { props: { color: "blue" } }, "普通订单"),
]);
} else if (params.row.orderPromotionType == "PINTUAN") {
return h("div", [
h("tag", { props: { color: "volcano" } }, "拼团订单"),
]);
} else if (params.row.orderPromotionType == "GIFT") {
return h("div", [
h("tag", { props: { color: "green" } }, "赠品订单"),
]);
} else if (params.row.orderPromotionType == "POINTS") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "积分订单"),
]);
} else if (params.row.orderPromotionType == "KANJIA") {
return h("div", [
h("tag", { props: { color: "pink" } }, "砍价订单"),
]);
}
},
},
{
title: "买家名称",
key: "memberName",
minWidth: 130,
tooltip: true,
},
{
title: "会员ID",
key: "memberId",
minWidth: 120,
tooltip: true,
},
{
title: "订单金额",
key: "flowPrice",
minWidth: 100,
tooltip: true,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
},
},
{
title: "订单状态",
key: "orderStatus",
minWidth: 100,
render: (h, params) => {
if (params.row.orderStatus == "UNPAID") {
return h("div", [
h("tag", { props: { color: "magenta" } }, "未付款"),
]);
} else if (params.row.orderStatus == "PAID") {
return h("div", [
h("tag", { props: { color: "blue" } }, "已付款"),
]);
} else if (params.row.orderStatus == "UNDELIVERED") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "待发货"),
]);
} else if (params.row.orderStatus == "STAY_PICKED_UP") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "待自提"),
]);
} else if (params.row.orderStatus == "PARTS_DELIVERED") {
return h("div", [
h("tag", { props: { color: "cyan" } }, "部分发货"),
]);
} else if (params.row.orderStatus == "DELIVERED") {
return h("div", [
h("tag", { props: { color: "cyan" } }, "已发货"),
]);
} else if (params.row.orderStatus == "COMPLETED") {
return h("div", [
h("tag", { props: { color: "green" } }, "已完成"),
]);
} else if (params.row.orderStatus == "TAKE") {
return h("div", [
h("tag", { props: { color: "volcano" } }, "待核验"),
]);
} else if (params.row.orderStatus == "CANCELLED") {
return h("div", [
h("tag", { props: { color: "red" } }, "已取消"),
]);
}
},
},
{
title: "支付方式",
key: "paymentMethod",
width: 120,
render: (h, params) => {
if (params.row.paymentMethod == "NOT_ACTUALLY_PAID") {
return h("div", {}, "-");
} else if (params.row.paymentMethod == "WECHAT") {
return h("div", {}, "微信支付");
} else if (params.row.paymentMethod == "ALIPAY") {
return h("div", {}, "支付宝");
} else if (params.row.paymentMethod == "WALLET") {
return h("div", {}, "余额支付");
} else if (params.row.paymentMethod == "BANK_TRANSFER") {
return h("div", {}, "线下转账");
} else {
return h("div", {}, params.row.paymentMethod || "-");
}
},
},
{
title: "下单时间",
key: "createTime",
width: 170,
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 200,
render: (h, params) => {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]);
},
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
orderNumData: {}, // 新增:订单数量统计数据
excelColumns: {
// 导出excel的参数
编号: "index",
订单号: "sn",
收货人: "consigneeName",
收货人联系电话: "consigneeMobile",
收货地址: "consigneeAddress",
商品名称: "goodsName",
商品价格: "goodsPrice",
订单金额: "flowPrice",
商品数量: "num",
店铺名称: "storeName",
创建时间: "createTime",
},
orderStatus: [
{title: '全部', value: ''},
{title: '未付款', value: 'UNPAID'},
{title: '已付款', value: 'PAID'},
{title: '待发货', value: 'UNDELIVERED'},
{title: '部分发货', value: 'PARTS_DELIVERED'},
{title: '已发货', value: 'DELIVERED'},
{title: '待核验', value: 'TAKE'},
{title: '待自提', value: 'STAY_PICKED_UP'},
{title: '已完成', value: 'COMPLETED'},
{title: '已关闭', value: 'CANCELLED'},
],
currentStatus: ''
data: [],
total: 0,
orderNumData: {},
currentStatus: "ALL",
};
},
computed: {
// 新增:带数量的订单状态选项
orderStatusWithCount() {
return [
{title: '全部', value: ''},
{title: `未付款${this.orderNumData.waitPayNum ? '(' + this.orderNumData.waitPayNum + ')' : ''}`, value: 'UNPAID'},
{title: `付款${this.orderNumData.waitDeliveryNum ? '(' + this.orderNumData.waitDeliveryNum + ')' : ''}`, value: 'PAID'},
{title: `待发货${this.orderNumData.waitShipNum ? '(' + this.orderNumData.waitShipNum + ')' : ''}`, value: 'UNDELIVERED'},
{title: `部分发货${this.orderNumData.partsDeliveredNumNum ? '(' + this.orderNumData.partsDeliveredNumNum + ')' : ''}`, value: 'PARTS_DELIVERED'},
{title: `已发货${this.orderNumData.deliveredNum ? '(' + this.orderNumData.deliveredNum + ')' : ''}`, value: 'DELIVERED'},
{title: `待核验${this.orderNumData.waitCheckNum ? '(' + this.orderNumData.waitCheckNum + ')' : ''}`, value: 'TAKE'},
{title: `待自提${this.orderNumData.waitSelfPickNum ? '(' + this.orderNumData.waitSelfPickNum + ')' : ''}`, value: 'STAY_PICKED_UP'},
{title: `已完成${this.orderNumData.finishNum ? '(' + this.orderNumData.finishNum + ')' : ''}`, value: 'COMPLETED'},
{title: `已关闭${this.orderNumData.closeNum ? '(' + this.orderNumData.closeNum + ')' : ''}`, value: 'CANCELLED'},
{ title: "全部", value: "ALL" },
{
title: `付款${this.orderNumData.waitPayNum ? "(" + this.orderNumData.waitPayNum + ")" : ""}`,
value: "UNPAID",
},
{
title: `已付款${this.orderNumData.waitDeliveryNum ? "(" + this.orderNumData.waitDeliveryNum + ")" : ""}`,
value: "PAID",
},
{
title: `待发货${this.orderNumData.waitShipNum ? "(" + this.orderNumData.waitShipNum + ")" : ""}`,
value: "UNDELIVERED",
},
{
title: `部分发货${this.orderNumData.partsDeliveredNumNum ? "(" + this.orderNumData.partsDeliveredNumNum + ")" : ""}`,
value: "PARTS_DELIVERED",
},
{
title: `待收货${this.orderNumData.deliveredNum ? "(" + this.orderNumData.deliveredNum + ")" : ""}`,
value: "DELIVERED",
},
{
title: `待核验${this.orderNumData.waitCheckNum ? "(" + this.orderNumData.waitCheckNum + ")" : ""}`,
value: "TAKE",
},
{
title: `待自提${this.orderNumData.waitSelfPickNum ? "(" + this.orderNumData.waitSelfPickNum + ")" : ""}`,
value: "STAY_PICKED_UP",
},
{
title: `已完成${this.orderNumData.finishNum ? "(" + this.orderNumData.finishNum + ")" : ""}`,
value: "COMPLETED",
},
{
title: `已关闭${this.orderNumData.closeNum ? "(" + this.orderNumData.closeNum + ")" : ""}`,
value: "CANCELLED",
},
];
}
},
},
methods: {
/**
* 核验订单
*/
async orderVerification() {
let result = await verificationCode(this.orderCode);
if (result.success) {
this.$router.push({
name: "order-detail",
query: { sn: result.result.sn || this.orderCode },
});
}
onStatusTabClick(tab) {
this.orderStatusClick(tab.paneName);
},
/**
* 批量发货
*/
expressOrderDeliver() {
this.$router.push({
path: "/export-order-deliver",
});
clientTypeText(v) {
const map = { H5: "移动端", PC: "PC端", WECHAT_MP: "小程序端", APP: "移动应用端" };
return map[v] || v || "-";
},
orderPromotionText(v) {
const map = {
NORMAL: "普通订单",
PINTUAN: "拼团订单",
GIFT: "赠品订单",
POINTS: "积分订单",
KANJIA: "砍价订单",
};
return map[v] || v || "-";
},
orderPromotionTagType(v) {
const map = {
NORMAL: "primary",
PINTUAN: "danger",
GIFT: "success",
POINTS: "info",
KANJIA: "warning",
};
return map[v] || "info";
},
paymentMethodText(v) {
const map = {
NOT_ACTUALLY_PAID: "-",
WECHAT: "微信支付",
ALIPAY: "支付宝",
WALLET: "余额支付",
BANK_TRANSFER: "线下转账",
};
return map[v] || v || "-";
},
orderStatusText(v) {
const map = {
UNPAID: "未付款",
PAID: "已付款",
UNDELIVERED: "待发货",
STAY_PICKED_UP: "待自提",
PARTS_DELIVERED: "部分发货",
DELIVERED: "已发货",
COMPLETED: "已完成",
TAKE: "待核验",
CANCELLED: "已关闭",
};
return map[v] || v || "-";
},
orderStatusTagType(v) {
const map = {
UNPAID: "danger",
PAID: "primary",
UNDELIVERED: "info",
STAY_PICKED_UP: "info",
PARTS_DELIVERED: "warning",
DELIVERED: "warning",
COMPLETED: "success",
TAKE: "warning",
CANCELLED: "danger",
};
return map[v] || "info";
},
// 初始化数据
init() {
this.getDataList();
this.getOrderNumData(); // 新增:获取订单数量统计
this.getOrderNumData();
},
// 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索订单
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
this.getOrderNumData(); // 新增:搜索时也更新数量统计
this.getOrderNumData();
},
// 重置
handleReset() {
this.searchForm = {};
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.selectDate = null;
this.searchForm.startDate = "";
this.searchForm.endDate = "";
this.searchForm.orderType = "NORMAL",
// 重新加载数据
this.getDataList();
},
// 起始时间处理
selectDateRange(v) {
if (v) {
if (v && v.length === 2) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
} else {
this.searchForm.startDate = "";
this.searchForm.endDate = "";
}
},
// 获取表格数据
getDataList() {
this.loading = true;
API_Order.getOrderList(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
API_Order.getOrderList(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.catch(() => {
this.loading = false;
});
},
detail(v) {
this.$filters.customRouterPush({
name: "order-detail",
query: { sn: v.sn },
});
},
// 导出订单
async exportOrder() {
if(this.searchForm.startDate==""||this.searchForm.endDate==""){
if (!this.searchForm.startDate || !this.searchForm.endDate) {
this.$Message.error("必须选择时间范围,搜索后进行导出!");
}else{
API_Order.exportOrder(this.searchForm)
.then((res) => {
const blob = new Blob([res], {
type: "application/vnd.ms-excel;charset=utf-8",
});
//对于<a>标签,只有 Firefox 和 Chrome内核 支持 download 属性
//IE10以上支持blob但是依然不支持download
if ("download" in document.createElement("a")) {
//支持a标签download的浏览器
const link = document.createElement("a"); //创建a标签
link.download = "订单列表.xlsx"; //a标签添加属性
link.style.display = "none";
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click(); //执行下载
URL.revokeObjectURL(link.href); //释放url
document.body.removeChild(link); //释放标签
} else {
navigator.msSaveBlob(blob, fileName);
}
})
.catch((err) => {
console.log(err);
return;
}
API_Order.exportOrder(this.searchForm)
.then((res) => {
const blob = new Blob([res], {
type: "application/vnd.ms-excel;charset=utf-8",
});
}
if ("download" in document.createElement("a")) {
const link = document.createElement("a");
link.download = "订单列表.xlsx";
link.style.display = "none";
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
} else {
navigator.msSaveBlob(blob, "订单列表.xlsx");
}
})
.catch((err) => {
console.log(err);
});
},
// 查看订单详情
detail(v) {
let sn = v.sn;
this.$options.filters.customRouterPush({
name: "order-detail",
query: { sn: sn },
})
},
// 订单筛选
orderStatusClick(name) {
if (name === 0) {
// 点击"全部"时设置为空字符串在getDataList中会被过滤掉
this.searchForm.orderStatus = '';
if (name === "ALL" || name === "" || name === undefined) {
this.searchForm.orderStatus = "";
this.currentStatus = "ALL";
} else {
// 其他状态正常赋值
this.searchForm.orderStatus = name;
this.currentStatus = name;
}
this.currentStatus = name;
this.getDataList();
},
getOrderNumData() {
// 创建一个不包含orderStatus字段的搜索参数
const { orderStatus, ...searchParams } = this.searchForm;
API_Order.getOrderNum(searchParams).then((res) => {
if (res.success) {
this.orderNumData = res.result;
}
}).catch((err) => {
console.error('获取订单数量统计失败:', err);
});
// orderNum 接口仅查 li_order不含 order_item 关联keywords/goodsName 会引用 oi 字段导致 SQL 报错
const { orderStatus, keywords, goodsName, ...searchParams } = this.searchForm;
API_Order.getOrderNum(searchParams)
.then((res) => {
if (res.success) {
this.orderNumData = res.result;
}
})
.catch((err) => {
console.error("获取订单数量统计失败:", err);
});
},
},
mounted() {
this.init();
},
// 页面缓存处理从该页面离开时修改KeepAlive为false保证进入该页面是刷新
beforeRouteLeave(to, from, next) {
from.meta.keepAlive = false;
next();
},
};
</script>
<style lang="scss">
// 建议引入通用样式 可删除下面样式代码
@import "@/styles/table-common.scss";
<style lang="scss" scoped>
.export {
margin: 10px 20px 10px 0;
}
// Tab组件样式
.order-tab {
::v-deep .ivu-tabs-tab {
:deep(.el-tabs__item) {
font-size: 14px;
}
}
.link-text {
color: #409eff;
cursor: pointer;
text-decoration: none;
}
</style>

View File

@@ -1,245 +1,191 @@
<template>
<div class="search">
<Card>
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="订单编号" prop="orderSn">
<Input type="text" v-model="searchForm.orderSn" clearable placeholder="请输入订单编号" style="width: 240px" />
</Form-item>
<Form-item label="会员名称" prop="buyerName">
<Input type="text" v-model="searchForm.buyerName" clearable placeholder="请输入会员名称" style="width: 240px" />
</Form-item>
<Form-item label="订单状态" prop="orderStatus">
<Select v-model="searchForm.orderStatus" placeholder="请选择" clearable style="width: 240px">
<Option value="UNPAID">未付款</Option>
<Option value="PAID">已付款</Option>
<Option value="COMPLETED">已完成</Option>
<Option value="TAKE">待核验</Option>
<Option value="CANCELLED">已取消</Option>
</Select>
</Form-item>
<Form-item label="下单时间">
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
<Button @click="handleReset" class="search-btn">重置</Button>
</Form>
</Card>
<Card>
<div>
<Poptip @keydown.enter.native="orderVerification" placement="bottom-start" width="400">
<Button class="export">
核验订单
</Button>
<div class="api" slot="content">
<h2>核验码</h2>
<div style="margin:10px 0;">
<Input v-model="orderCode" style="width:300px; margin-right:10px;" />
<Button style="primary" @click="orderVerification">核验</Button>
</div>
</div>
</Poptip>
<el-card>
<el-form
ref="searchForm"
:model="searchForm"
inline
label-width="70px"
class="search-form"
@keyup.enter="handleSearch"
>
<el-form-item label="订单号" prop="orderSn">
<el-input
v-model="searchForm.orderSn"
placeholder="请输入订单号"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="会员名称" prop="buyerName">
<el-input
v-model="searchForm.buyerName"
placeholder="请输入会员名称"
clearable
style="width: 240px"
/>
</el-form-item>
<el-form-item label="下单时间">
<el-date-picker
v-model="selectDate"
type="datetimerange"
value-format="YYYY-MM-DD"
clearable
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择起始时间"
style="width: 240px"
@change="selectDateRange"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card>
<div class="order-tab">
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
<el-tab-pane
v-for="(item, index) in orderStatus"
:key="index"
:label="item.title"
:name="item.value"
/>
</el-tabs>
</div>
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom" @on-sort-change="changeSort"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small"
show-total show-elevator show-sizer></Page>
</Row>
</Card>
<el-table
ref="table"
v-loading="loading"
border
:data="data"
class="mt_10"
style="width: 100%"
@sort-change="changeSort"
>
<el-table-column prop="sn" label="订单号" min-width="230" show-overflow-tooltip />
<el-table-column prop="createTime" label="下单时间" width="200" />
<el-table-column label="订单来源" width="95">
<template #default="{ row }">
<span v-if="row">
<span v-if="row.clientType == 'H5'">移动端</span>
<span v-else-if="row.clientType == 'PC'">PC端</span>
<span v-else-if="row.clientType == 'WECHAT_MP'">小程序端</span>
<span v-else-if="row.clientType == 'APP'">移动应用端</span>
<span v-else>{{ row.clientType }}</span>
</span>
</template>
</el-table-column>
<el-table-column prop="memberName" label="会员名称" width="130" />
<el-table-column label="订单金额" prop="flowPrice" min-width="120" sortable="custom">
<template #default="{ row }">
<priceColorScheme v-if="row" :value="row.flowPrice" :color="$mainColor" />
</template>
</el-table-column>
<el-table-column label="订单状态" width="95">
<template #default="{ row }">
<template v-if="row">
<el-tag v-if="row.orderStatus == 'UNPAID'" type="danger">未付款</el-tag>
<el-tag v-else-if="row.orderStatus == 'PAID'" type="primary">已付款</el-tag>
<el-tag v-else-if="row.orderStatus == 'COMPLETED'" type="success">已完成</el-tag>
<el-tag v-else-if="row.orderStatus == 'TAKE'" type="warning">待核验</el-tag>
<el-tag v-else-if="row.orderStatus == 'CANCELLED'" type="info">已关闭</el-tag>
</template>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template #default="{ row }">
<template v-if="row">
<a
class="link-text"
:class="{ disabled: row.orderStatus != 'UNPAID' }"
@click="row.orderStatus == 'UNPAID' && confirmPrice(row)"
>收款</a>
<span class="op-split">|</span>
<a class="link-text" @click="detail(row)">查看</a>
</template>
</template>
</el-table-column>
</el-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<el-pagination
v-model:current-page="searchForm.pageNumber"
v-model:page-size="searchForm.pageSize"
:page-sizes="[20, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
size="small"
@current-change="changePage"
@size-change="changePageSize"
/>
</div>
</el-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import { verificationCode } from "@/api/order";
export default {
name: "virtualOrderList",
name: "fictitiousOrderList",
data() {
return {
orderCode: "", // 核验码
loading: true, // 表单加载状态
loading: true,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
pageNumber: 1,
pageSize: 20,
sort: "",
order: "",
startDate: "",
endDate: "",
orderType: "VIRTUAL",
orderSn: "",
buyerName: "",
orderStatus: "",
orderType: "VIRTUAL",
},
selectDate: null,
columns: [
{
title: "订单号",
key: "sn",
minWidth: 240,
tooltip: true,
},
{
title: "订单来源",
key: "clientType",
width: 120,
render: (h, params) => {
if (params.row.clientType == "H5") {
return h("div", {}, "移动端");
} else if (params.row.clientType == "PC") {
return h("div", {}, "PC端");
} else if (params.row.clientType == "WECHAT_MP") {
return h("div", {}, "小程序端");
} else if (params.row.clientType == "APP") {
return h("div", {}, "移动应用端");
} else {
return h("div", {}, params.row.clientType);
}
},
},
{
title: "买家名称",
key: "memberName",
minWidth: 130,
tooltip: true,
},
{
title: "订单金额",
key: "flowPrice",
minWidth: 100,
tooltip: true,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
},
},
{
title: "订单状态",
key: "orderStatus",
minWidth: 100,
render: (h, params) => {
if (params.row.orderStatus == "UNPAID") {
return h("div", [h("tag", {props: {color: "magenta"}}, "未付款")]);
} else if (params.row.orderStatus == "PAID") {
return h("div", [h("tag", {props: {color: "blue"}}, "已付款")]);
} else if (params.row.orderStatus == "UNDELIVERED") {
return h("div", [h("tag", {props: {color: "geekblue"}}, "待发货")]);
} else if (params.row.orderStatus == "DELIVERED") {
return h("div", [h("tag", {props: {color: "cyan"}}, "已发货")]);
} else if (params.row.orderStatus == "COMPLETED") {
return h("div", [h("tag", {props: {color: "green"}}, "已完成")]);
} else if (params.row.orderStatus == "TAKE") {
return h("div", [h("tag", {props: {color: "volcano"}}, "待核验")]);
} else if (params.row.orderStatus == "CANCELLED") {
return h("div", [h("tag", {props: {color: "red"}}, "已取消")]);
}
},
},
{
title: "下单时间",
key: "createTime",
width: 170,
sortable: true,
sortType: "desc",
},
{
title: "操作",
key: "action",
align: "center",
width: 100,
render: (h, params) => {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]);
},
},
data: [],
total: 0,
orderStatus: [
{ title: "全部", value: "" },
{ title: "未付款", value: "UNPAID" },
{ title: "已付款", value: "PAID" },
{ title: "待核验", value: "TAKE" },
{ title: "已完成", value: "COMPLETED" },
{ title: "已关闭", value: "CANCELLED" },
],
data: [], // 表单数据
total: 0, // 表单数据总数
currentStatus: "",
};
},
methods: {
/**
* 核验订单
*/
async orderVerification() {
let result = await verificationCode(this.orderCode);
if (result.success) {
this.$router.push({
name: "order-detail",
query: { sn: result.result.sn || this.orderCode },
});
}
},
// 初始化数据
init() {
this.getDataList();
},
// 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
changePage() {
this.getDataList();
},
// 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
changePageSize() {
this.searchForm.pageNumber = 1;
this.getDataList();
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 重置
handleReset() {
this.searchForm = {};
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.orderType = "VIRTUAL";
this.selectDate = null;
this.searchForm.startDate = "";
this.searchForm.endDate = "";
// 重新加载数据
this.getDataList();
},
// 表格排序
changeSort(e) {
this.searchForm.sort = e.key;
this.searchForm.order = e.order;
if (e.order === "normal") {
this.searchForm.order = "";
}
this.searchForm.sort = e.prop;
this.searchForm.order = e.order === "ascending" ? "asc" : e.order === "descending" ? "desc" : "";
this.getDataList();
},
// 时间段重新赋值
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
}
},
// 获取商品列表
getDataList() {
this.loading = true;
API_Order.getOrderList(this.searchForm).then((res) => {
@@ -250,29 +196,44 @@ export default {
}
});
},
// 跳转详情
confirmPrice(v) {
this.$Modal.confirm({
title: "确认收款",
content: "您确定要收款吗?",
loading: true,
onOk: () => {
API_Order.orderPay(v.sn).then((res) => {
if (res.success) {
this.$Message.success("收款成功");
this.getDataList();
}
this.$Modal.remove();
});
},
});
},
detail(v) {
let sn = v.sn;
this.$options.filters.customRouterPush({
this.$filters.customRouterPush({
name: "order-detail",
query: { sn: sn },
})
query: { sn: sn, orderType: v.orderType },
});
},
onStatusTabClick(tab) {
const item = tab.paneName;
this.currentStatus = item;
this.searchForm.orderStatus = item;
this.getDataList();
},
},
mounted() {
this.init();
},
// 页面缓存处理从该页面离开时修改KeepAlive为false保证进入该页面是刷新
beforeRouteLeave(to, from, next) {
from.meta.keepAlive = false
next()
}
};
</script>
<style lang="scss">
// 建议引入通用样式 可删除下面样式代码
@import "@/styles/table-common.scss";
.export {
margin: 10px 20px 10px 0;
<style lang="scss" scoped>
.order-tab {
margin-top: 20px;
}
</style>

View File

@@ -1,52 +1,95 @@
<template>
<div class="search">
<Card>
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="订单编号" prop="orderSn">
<Input type="text" v-model="searchForm.orderSn" clearable placeholder="请输入订单编号" style="width: 240px" />
</Form-item>
<Form-item label="会员名称" prop="memberName">
<Input type="text" v-model="searchForm.memberName" clearable placeholder="请输入会员名称" style="width: 240px" />
</Form-item>
<Form-item label="发票抬头" prop="receiptTitle">
<Input type="text" v-model="searchForm.receiptTitle" clearable placeholder="请输入发票抬头" style="width: 240px" />
</Form-item>
<Form-item label="状态" prop="receiptStatus">
<Select v-model="searchForm.receiptStatus" placeholder="请选择" clearable style="width: 240px">
<Option :value="0">未开票</Option>
<Option :value="1">已开票</Option>
</Select>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
<Button @click="handleReset" class="search-btn">重置</Button>
</Form>
</Card>
<el-card>
<el-form ref="searchForm" :model="searchForm" inline label-width="70px" class="search-form">
<el-form-item label="订单编号" prop="orderSn">
<el-input v-model="searchForm.orderSn" clearable placeholder="请输入订单编号" style="width: 240px" />
</el-form-item>
<el-form-item label="会员名称" prop="memberName">
<el-input v-model="searchForm.memberName" clearable placeholder="请输入会员名称" style="width: 240px" />
</el-form-item>
<el-form-item label="发票抬头" prop="receiptTitle">
<el-input v-model="searchForm.receiptTitle" clearable placeholder="请输入发票抬头" style="width: 240px" />
</el-form-item>
<el-form-item label="状态" prop="receiptStatus">
<el-select v-model="searchForm.receiptStatus" placeholder="请选择" clearable style="width: 240px">
<el-option label="未开票" :value="0" />
<el-option label="已开票" :value="1" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
<el-button class="search-btn" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<Card>
<div class="receipt-tip">
订单状态为已发货/已完成可开票
<el-card>
<div class="receipt-tip">订单状态为已发货/已完成可开票</div>
<el-table ref="table" v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
<el-table-column label="订单号" min-width="120">
<template #default="{ row }">
<a class="link-text" @click="$router.push({ name: 'order-detail', query: { sn: row.orderSn } })">
{{ row.orderSn }}
</a>
</template>
</el-table-column>
<el-table-column prop="memberName" label="会员名称" min-width="90" show-overflow-tooltip />
<el-table-column label="发票抬头" min-width="90" show-overflow-tooltip>
<template #default="{ row }">{{ row.receiptTitle || "暂未填写" }}</template>
</el-table-column>
<el-table-column label="纳税人识别号" min-width="100" show-overflow-tooltip>
<template #default="{ row }">{{ row.taxpayerId || "暂未填写" }}</template>
</el-table-column>
<el-table-column label="发票内容" min-width="90" show-overflow-tooltip>
<template #default="{ row }">{{ row.receiptContent || "暂未填写" }}</template>
</el-table-column>
<el-table-column label="发票金额" width="150">
<template #default="{ row }">
<priceColorScheme :value="row.receiptPrice" :color="$mainColor" />
</template>
</el-table-column>
<el-table-column label="发票状态" width="100">
<template #default="{ row }">
<el-tag :type="Number(row.receiptStatus) === 0 ? 'warning' : 'success'">
{{ Number(row.receiptStatus) === 0 ? "未开票" : "已开票" }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="订单状态" width="100">
<template #default="{ row }">
<el-tag :type="orderStatusTagType(row.orderStatus)">{{ orderStatusText(row.orderStatus) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="{ row }">
<a class="link-text" style="margin-right: 12px" @click="openReceiptModal(row, 'detail')">详情</a>
<a
class="link-text"
:class="{ disabled: !canInvoicing(row) }"
@click="canInvoicing(row) && openReceiptModal(row, 'invoicing')"
>
开票
</a>
</template>
</el-table-column>
</el-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<el-pagination
v-model:current-page="searchForm.pageNumber"
v-model:page-size="searchForm.pageSize"
:page-sizes="[10, 20, 50]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
size="small"
@current-change="changePage"
@size-change="changePageSize"
/>
</div>
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table">
<!-- 订单详情格式化 -->
<template slot="orderSlot" slot-scope="scope">
<a @click="$router.push({name: 'order-detail',query: {sn: scope.row.orderSn}})">{{scope.row.orderSn}}</a>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small"
show-total show-elevator show-sizer></Page>
</Row>
</Card>
<Modal
v-model="receiptModalVisible"
title="发票信息"
:mask-closable="false"
width="680"
>
<div v-if="receiptDetailLoading" class="receipt-modal-loading">
<Spin size="large" />
</div>
<div v-else class="receipt-modal-content">
</el-card>
<el-dialog v-model="receiptModalVisible" title="发票信息" :close-on-click-modal="false" width="680px">
<div v-loading="receiptDetailLoading" class="receipt-modal-content">
<div v-if="hasValue(currentReceipt.orderSn)" class="receipt-item">
<span class="receipt-label">订单号</span>
<span class="receipt-value">{{ currentReceipt.orderSn }}</span>
@@ -110,39 +153,31 @@
<div v-if="hasValue(getInvoiceAddress(currentReceipt))" class="receipt-item">
<span class="receipt-label">发票附件</span>
<span class="receipt-value">
<a @click="viewInvoiceFile(getInvoiceAddress(currentReceipt))">查看附件</a>
<a class="link-text" @click="viewInvoiceFile(getInvoiceAddress(currentReceipt))">查看附件</a>
</span>
</div>
</div>
<div slot="footer">
<template #footer>
<template v-if="receiptModalMode === 'invoicing'">
<Upload
<el-upload
:action="uploadFileUrl"
:data="receiptUploadData"
:headers="{ ...accessToken }"
:format="['jpg', 'jpeg', 'png', 'pdf']"
:max-size="10240"
:accept="'.jpg,.jpeg,.png,.pdf'"
:show-file-list="false"
:on-success="handleInvoiceUploadSuccess"
:on-error="handleInvoiceUploadError"
:on-format-error="handleInvoiceFormatError"
:on-exceeded-size="handleInvoiceMaxSize"
:show-upload-list="false"
:before-upload="beforeInvoiceUpload"
style="display: inline-block; margin-right: 8px"
>
<Button :disabled="receiptDetailLoading">上传发票</Button>
</Upload>
<Button @click="receiptModalVisible = false">取消</Button>
<Button
type="primary"
:loading="invoiceSubmitting"
@click="submitInvoicing"
>
确认开票
</Button>
<el-button :disabled="receiptDetailLoading">上传发票</el-button>
</el-upload>
<el-button @click="receiptModalVisible = false">取消</el-button>
<el-button type="primary" :loading="invoiceSubmitting" @click="submitInvoicing">确认开票</el-button>
</template>
<Button v-else @click="receiptModalVisible = false">关闭</Button>
</div>
</Modal>
<el-button v-else @click="receiptModalVisible = false">关闭</el-button>
</template>
</el-dialog>
</div>
</template>
@@ -154,178 +189,61 @@ export default {
name: "receipt",
data() {
return {
loading: true, // 表单加载状态
loading: true,
receiptModalVisible: false,
receiptDetailLoading: false,
invoiceSubmitting: false,
receiptModalMode: "detail",
uploadFileUrl: uploadFile,
accessToken: {},
receiptUploadData: {
directoryPath: "receipt"
},
receiptUploadData: { directoryPath: "receipt" },
currentReceipt: {},
selectedReceiptRow: null,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
receiptStatus: "", // 发票状态
pageNumber: 1,
pageSize: 10,
sort: "createTime",
order: "desc",
receiptStatus: "",
},
columns: [
{
title: "订单号",
key: "orderSn",
minWidth: 120,
slot: "orderSlot",
},
{
title: "会员名称",
key: "memberName",
minWidth: 90,
tooltip: true,
},
{
title: "发票抬头",
key: "receiptTitle",
minWidth: 90,
tooltip: true,
render: (h, params) => {
return h("div", params.row.receiptTitle || "暂未填写");
},
},
{
title: "纳税人识别号",
key: "taxpayerId",
minWidth: 100,
tooltip: true,
render: (h, params) => {
return h("div", params.row.taxpayerId || "暂未填写");
},
},
{
title: "发票内容",
key: "receiptContent",
minWidth: 90,
tooltip: true,
render: (h, params) => {
return h("div", params.row.receiptContent || "暂未填写");
},
},
{
title: "发票金额",
key: "billPrice",
width: 150,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.receiptPrice,color:this.$mainColor}} );
},
},
{
title: "发票状态",
key: "receiptStatus",
width: 100,
tooltip: true,
render: (h, params) => {
if (Number(params.row.receiptStatus) === 0) {
return h("div", [
h("tag", { props: { color: "volcano" } }, "未开票"),
]);
} else {
return h("div", [
h("tag", { props: { color: "green" } }, "已开票"),
]);
}
},
},
{
title: "订单状态",
key: "orderStatus",
width: 100,
render: (h, params) => {
if (params.row.orderStatus == "UNPAID") {
return h("div", [
h("tag", { props: { color: "magenta" } }, "未付款"),
]);
} else if (params.row.orderStatus == "PAID") {
return h("div", [
h("tag", { props: { color: "blue" } }, "已付款"),
]);
} else if (params.row.orderStatus == "UNDELIVERED") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "待发货"),
]);
} else if (params.row.orderStatus == "DELIVERED") {
return h("div", [
h("tag", { props: { color: "cyan" } }, "已发货"),
]);
} else if (params.row.orderStatus == "COMPLETED") {
return h("div", [
h("tag", { props: { color: "green" } }, "已完成"),
]);
} else if (params.row.orderStatus == "TAKE") {
return h("div", [
h("tag", { props: { color: "volcano" } }, "待核验"),
]);
} else if (params.row.orderStatus == "CANCELLED") {
return h("div", [
h("tag", { props: { color: "red" } }, "已取消"),
]);
}
},
},
{
title: "操作",
key: "action",
align: "center",
fixed: 'right',
width: 200,
render: (h, params) => {
const disabled = !this.canInvoicing(params.row);
const detailStyle = { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "12px" };
const style = disabled
? { color: "#c5c8ce", cursor: "not-allowed", textDecoration: "none" }
: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" };
const on = disabled ? {} : { click: () => { this.openReceiptModal(params.row, "invoicing"); } };
return h("div", [
h(
"a",
{
style: detailStyle,
on: { click: () => { this.openReceiptModal(params.row, "detail"); } },
},
"详情"
),
h(
"a",
{
style,
on,
},
"开票"
),
]);
},
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
data: [],
total: 0,
};
},
methods: {
orderStatusText(status) {
const map = {
UNPAID: "未付款",
PAID: "已付款",
UNDELIVERED: "待发货",
DELIVERED: "已发货",
COMPLETED: "已完成",
TAKE: "待核验",
CANCELLED: "已取消",
};
return map[status] || status;
},
orderStatusTagType(status) {
const map = {
UNPAID: "danger",
PAID: "primary",
UNDELIVERED: "",
DELIVERED: "info",
COMPLETED: "success",
TAKE: "warning",
CANCELLED: "danger",
};
return map[status] || "";
},
canInvoicing(row) {
if (!row) return false;
const orderStatus = row.orderStatus;
const receiptStatus = Number(row.receiptStatus);
return (orderStatus === "COMPLETED" || orderStatus === "DELIVERED") && receiptStatus === 0;
return (
(row.orderStatus === "COMPLETED" || row.orderStatus === "DELIVERED") &&
Number(row.receiptStatus) === 0
);
},
initUploadAccessToken() {
this.accessToken = {
accessToken: this.getStore("accessToken")
};
this.accessToken = { accessToken: this.getStore("accessToken") };
},
hasValue(value) {
if (value === null || value === undefined) return false;
@@ -334,11 +252,6 @@ export default {
hasPrice(value) {
return value !== null && value !== undefined && value !== "";
},
formatValue(value) {
if (value === null || value === undefined) return "暂无";
const text = String(value).trim();
return text ? text : "暂无";
},
formatPrice(value) {
if (value === null || value === undefined || value === "") return "暂无";
return `${value}`;
@@ -354,26 +267,6 @@ export default {
if (receiptType === "电子普通发票" || receiptType === "增值税专用发票") return receiptType;
return this.isVatSpecialReceipt(receipt) ? "增值税专用发票" : "电子普通发票";
},
formatReceiptHeaderType(receipt) {
if (!receipt) return "暂无";
if (this.isVatSpecialReceipt(receipt)) return "单位";
if (receipt.companyName) return "单位";
if (receipt.personalName) return "个人";
const receiptTitle = receipt.receiptTitle != null ? String(receipt.receiptTitle).trim() : "";
if (receiptTitle === "单位" || receiptTitle === "个人") return receiptTitle;
return receipt.taxpayerId ? "单位" : "个人";
},
getReceiptTitleLabel(receipt) {
return this.formatReceiptHeaderType(receipt) === "单位" ? "单位名称" : "个人名称";
},
getReceiptTitleName(receipt) {
if (!receipt) return "";
if (receipt.companyName) return receipt.companyName;
if (receipt.personalName) return receipt.personalName;
const receiptTitle = receipt.receiptTitle != null ? String(receipt.receiptTitle).trim() : "";
if (receiptTitle === "单位" || receiptTitle === "个人") return "";
return receiptTitle;
},
getInvoiceAddress(receipt) {
if (!receipt) return "";
return receipt.invoiceAddress || receipt.invoiceFileUrl || "";
@@ -382,11 +275,24 @@ export default {
const invoiceAddress = this.getInvoiceAddress(this.currentReceipt);
return invoiceAddress ? { invoiceAddress } : {};
},
beforeInvoiceUpload(file) {
const allowed = ["image/jpeg", "image/jpg", "image/png", "application/pdf"];
const okType = allowed.includes(file.type) || /\.(jpg|jpeg|png|pdf)$/i.test(file.name);
if (!okType) {
this.$Message.warning("请上传 jpg、jpeg、png 或 pdf 格式文件");
return false;
}
if (file.size / 1024 / 1024 > 10) {
this.$Message.warning("发票附件不能超过 10MB");
return false;
}
return true;
},
handleInvoiceUploadSuccess(res) {
if (res && res.success && res.result) {
this.$set(this.currentReceipt, "invoiceAddress", res.result);
this.currentReceipt.invoiceAddress = res.result;
if (this.selectedReceiptRow) {
this.$set(this.selectedReceiptRow, "invoiceAddress", res.result);
this.selectedReceiptRow.invoiceAddress = res.result;
}
this.$Message.success("发票上传成功");
} else {
@@ -396,57 +302,35 @@ export default {
handleInvoiceUploadError() {
this.$Message.error("发票上传失败");
},
handleInvoiceFormatError() {
this.$Notice.warning({
title: "文件格式不正确",
desc: "请上传 jpg、jpeg、png 或 pdf 格式文件"
});
},
handleInvoiceMaxSize() {
this.$Notice.warning({
title: "超过文件大小限制",
desc: "发票附件不能超过 10MB"
});
},
viewInvoiceFile(url) {
if (!url) return;
window.open(url, "_blank");
},
// 初始化数据
init() {
this.getData();
},
// 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getData();
},
// 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getData();
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.getData();
},
// 重置搜索条件
handleReset() {
this.searchForm = {};
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm = {
pageNumber: 1,
pageSize: 10,
sort: "createTime",
order: "desc",
receiptStatus: "",
};
this.getData();
},
// 时间段从新赋值
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
}
},
// 获取数据
getData() {
this.loading = true;
API_Order.getReceiptPage(this.searchForm).then((res) => {
@@ -456,8 +340,6 @@ export default {
this.total = res.result.total;
}
});
this.total = this.data.length;
this.loading = false;
},
async openReceiptModal(row, mode = "detail") {
if (!row) return;
@@ -512,16 +394,8 @@ export default {
};
</script>
<style lang="scss">
// 建议引入通用样式 可删除下面样式代码
@import "@/styles/table-common.scss";
.receipt-modal-loading {
display: flex;
align-items: center;
justify-content: center;
min-height: 240px;
}
.receipt-modal-content {
max-height: 460px;
overflow-y: auto;
@@ -554,4 +428,14 @@ export default {
color: #17233d;
word-break: break-all;
}
.link-text {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.link-text.disabled {
color: #c5c8ce;
cursor: not-allowed;
}
</style>