refactor: 四端完成 Options API → script setup + vuex → pinia 迁移

- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup>
- 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录)
- util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入
- 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md)
- 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API
- 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
lifenlong
2026-10-13 07:06:59 +08:00
parent 870bacdd8c
commit 88fc1b0b2a
674 changed files with 71220 additions and 69943 deletions

View File

@@ -55,7 +55,7 @@
</el-card>
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px" :close-on-click-modal="false">
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
<el-form ref="formRef" :model="form" label-width="100px" :rules="formValidate">
<el-form-item label="售后原因" prop="reason">
<el-input v-model="form.reason" maxlength="20" clearable style="width: 100%" />
</el-form-item>
@@ -67,116 +67,113 @@
</el-dialog>
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref } from "vue";
import * as API_Order from "@/api/order";
import { ElMessage, ElMessageBox } from "element-plus";
export default {
data() {
return {
activeTab: "RETURN_MONEY",
modalVisible: false,
modalTitle: "",
loading: true,
submitLoading: false,
form: { reason: "" },
formValidate: {
reason: [{ required: true, message: "请输入售后原因", trigger: "blur" }],
},
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
serviceType: "RETURN_MONEY",
},
data: [],
total: 0,
};
},
methods: {
onTabClick(tab) {
this.handleClickType(tab.paneName);
},
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
handleClickType(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.serviceType = v;
this.getDataList();
},
getDataList() {
this.loading = true;
API_Order.getAfterSaleReasonPage(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
},
add() {
this.form.reason = "";
this.modalVisible = true;
this.modalTitle = "添加售后原因";
},
edit(v) {
this.form.reason = v.reason;
this.form.id = v.id;
this.modalVisible = true;
this.modalTitle = "修改售后原因";
},
handleSubmit() {
this.form.serviceType = this.searchForm.serviceType;
this.$refs.form.validate((valid) => {
if (valid) {
this.submitLoading = true;
if (this.modalTitle == "添加售后原因") {
delete this.form.id;
API_Order.addAfterSaleReason(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
ElMessage.success("添加成功");
this.getDataList();
this.modalVisible = false;
}
});
} else {
API_Order.editAfterSaleReason(this.form.id, this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
ElMessage.success("修改成功");
this.getDataList();
this.modalVisible = false;
}
});
}
}
});
},
remove(v) {
ElMessageBox.confirm("确认要删除此售后原因?", "确认删除", { type: "warning" }).then(() => {
API_Order.delAfterSaleReason(v.id).then((res) => {
const activeTab = ref("RETURN_MONEY");
const modalVisible = ref(false);
const modalTitle = ref("");
const loading = ref(true);
const submitLoading = ref(false);
const form = reactive({ reason: "" });
const formValidate = reactive({
reason: [{ required: true, message: "请输入售后原因", trigger: "blur" }],
});
const searchForm = reactive({
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
serviceType: "RETURN_MONEY",
});
const data = ref([]);
const total = ref(0);
const formRef = ref(null);
function onTabClick(tab) {
handleClickType(tab.paneName);
}
function changePage(v) {
searchForm.pageNumber = v;
getDataList();
}
function changePageSize(v) {
searchForm.pageNumber = 1;
searchForm.pageSize = v;
getDataList();
}
function handleClickType(v) {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
searchForm.serviceType = v;
getDataList();
}
function getDataList() {
loading.value = true;
API_Order.getAfterSaleReasonPage(searchForm).then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
});
}
function add() {
form.reason = "";
modalVisible.value = true;
modalTitle.value = "添加售后原因";
}
function edit(v) {
form.reason = v.reason;
form.id = v.id;
modalVisible.value = true;
modalTitle.value = "修改售后原因";
}
function handleSubmit() {
form.serviceType = searchForm.serviceType;
formRef.value.validate((valid) => {
if (valid) {
submitLoading.value = true;
if (modalTitle.value == "添加售后原因") {
delete form.id;
API_Order.addAfterSaleReason(form).then((res) => {
submitLoading.value = false;
if (res.success) {
ElMessage.success("售后原因已删除");
this.getDataList();
ElMessage.success("添加成功");
getDataList();
modalVisible.value = false;
}
});
}).catch(() => {});
},
},
mounted() {
this.getDataList();
},
};
} else {
API_Order.editAfterSaleReason(form.id, form).then((res) => {
submitLoading.value = false;
if (res.success) {
ElMessage.success("修改成功");
getDataList();
modalVisible.value = false;
}
});
}
}
});
}
function remove(v) {
ElMessageBox.confirm("确认要删除此售后原因?", "确认删除", { type: "warning" }).then(() => {
API_Order.delAfterSaleReason(v.id).then((res) => {
if (res.success) {
ElMessage.success("售后原因已删除");
getDataList();
}
});
}).catch(() => {});
}
onMounted(() => {
getDataList();
});
</script>
<style scoped>
.link-text {

View File

@@ -2,7 +2,7 @@
<div class="search">
<el-card>
<el-form
ref="searchForm"
ref="searchFormRef"
:model="searchForm"
inline
label-width="70px"
@@ -167,194 +167,193 @@
</div>
</template>
<script>
<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import * as API_Order from "@/api/order";
import { unitPrice, customRouterPush } from "@/utils/filters";
export default {
name: "after-sale-order",
data() {
return {
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
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",
},
{
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",
},
];
defineOptions({ name: "after-sale-order" });
// 模板 ref(模板 ref="searchForm" 与 data 同名,改名 searchFormRef 避免互相覆盖)
const searchFormRef = ref(null);
// 模板 ref="table"
const table = ref(null);
const loading = ref(true);
const searchForm = reactive({
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderSn: "",
memberName: "",
serviceStatus: "",
storeName: "",
sn: "",
keywords: "",
});
const selectDate = ref(null);
const data = ref([]);
const total = ref(0);
const currentStatus = ref("");
const afterSaleNumData = ref({});
const serviceStatusWithCount = computed(() => {
return [
{ title: "全部", value: "" },
{
title: `申请售后${afterSaleNumData.value.applyNum ? "(" + afterSaleNumData.value.applyNum + ")" : ""}`,
value: "APPLY",
},
},
methods: {
unitPrice,
serviceTypeText(type) {
const map = {
RETURN_MONEY: "退款",
RETURN_GOODS: "退货",
EXCHANGE_GOODS: "换货",
};
return map[type] || type || "-";
{
title: `通过售后${afterSaleNumData.value.passNum ? "(" + afterSaleNumData.value.passNum + ")" : ""}`,
value: "PASS",
},
serviceTypeTagType(type) {
const map = {
RETURN_MONEY: "primary",
RETURN_GOODS: "warning",
EXCHANGE_GOODS: "success",
};
return map[type] || "info";
{
title: `拒绝售后${afterSaleNumData.value.refuseNum ? "(" + afterSaleNumData.value.refuseNum + ")" : ""}`,
value: "REFUSE",
},
serviceStatusText(status) {
const map = {
APPLY: "申请中",
PASS: "通过售后",
REFUSE: "拒绝售后",
BUYER_RETURN: "买家退货,待卖家收货",
SELLER_CONFIRM: "卖家确认收货",
SELLER_TERMINATION: "卖家终止售后",
BUYER_CANCEL: "买家取消售后",
COMPLETE: "完成售后",
WAIT_REFUND: "待平台退款",
};
return map[status] || status || "-";
{
title: `待收货${afterSaleNumData.value.buyerReturnNum ? "(" + afterSaleNumData.value.buyerReturnNum + ")" : ""}`,
value: "BUYER_RETURN",
},
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";
{
title: `确认收货${afterSaleNumData.value.sellerConfirmNum ? "(" + afterSaleNumData.value.sellerConfirmNum + ")" : ""}`,
value: "SELLER_CONFIRM",
},
init() {
this.getDataList();
this.getAfterSaleNumData();
{
title: `完成售后${afterSaleNumData.value.completeNum ? "(" + afterSaleNumData.value.completeNum + ")" : ""}`,
value: "COMPLETE",
},
changePage() {
this.getDataList();
{
title: `卖家终止售后${afterSaleNumData.value.sellerTerminationNum ? "(" + afterSaleNumData.value.sellerTerminationNum + ")" : ""}`,
value: "SELLER_TERMINATION",
},
changePageSize() {
this.searchForm.pageNumber = 1;
this.getDataList();
{
title: `买家取消售后${afterSaleNumData.value.buyerCancelNum ? "(" + afterSaleNumData.value.buyerCancelNum + ")" : ""}`,
value: "BUYER_CANCEL",
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
this.getAfterSaleNumData();
{
title: `等待平台退款${afterSaleNumData.value.waitRefundNum ? "(" + afterSaleNumData.value.waitRefundNum + ")" : ""}`,
value: "WAIT_REFUND",
},
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) => {
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;
customRouterPush({
name: "after-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();
},
};
];
});
function serviceTypeText(type) {
const map = {
RETURN_MONEY: "退款",
RETURN_GOODS: "退货",
EXCHANGE_GOODS: "换货",
};
return map[type] || type || "-";
}
function serviceTypeTagType(type) {
const map = {
RETURN_MONEY: "primary",
RETURN_GOODS: "warning",
EXCHANGE_GOODS: "success",
};
return map[type] || "info";
}
function serviceStatusText(status) {
const map = {
APPLY: "申请中",
PASS: "通过售后",
REFUSE: "拒绝售后",
BUYER_RETURN: "买家退货,待卖家收货",
SELLER_CONFIRM: "卖家确认收货",
SELLER_TERMINATION: "卖家终止售后",
BUYER_CANCEL: "买家取消售后",
COMPLETE: "完成售后",
WAIT_REFUND: "待平台退款",
};
return map[status] || status || "-";
}
function 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";
}
function init() {
getDataList();
getAfterSaleNumData();
}
function changePage() {
getDataList();
}
function changePageSize() {
searchForm.pageNumber = 1;
getDataList();
}
function handleSearch() {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
getDataList();
getAfterSaleNumData();
}
function selectDateRange(v) {
if (v) {
searchForm.startDate = v[0];
searchForm.endDate = v[1];
} else {
searchForm.startDate = "";
searchForm.endDate = "";
}
}
function getDataList() {
loading.value = true;
API_Order.getAfterSaleOrderPage(searchForm).then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
});
}
function getAfterSaleNumData() {
const { serviceStatus, ...searchParams } = searchForm;
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
if (res.success) {
afterSaleNumData.value = res.result;
}
});
}
function detail(v) {
const sn = v.sn;
customRouterPush({
name: "after-order-detail",
query: { sn: sn },
});
}
function onStatusTabClick(tab) {
serviceStatusClick(tab.paneName);
}
function serviceStatusClick(item) {
currentStatus.value = item;
if (item === "" || item === undefined) {
delete searchForm.serviceStatus;
} else {
searchForm.serviceStatus = item;
}
getDataList();
getAfterSaleNumData();
}
onMounted(() => {
init();
});
</script>
<style lang="scss" scoped>

View File

@@ -332,185 +332,184 @@
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref } from "vue";
import { useRoute } from "vue-router";
import * as API_Order from "@/api/order";
import vueQr from "vue-qr";
import { ElMessage, ElMessageBox } from "element-plus";
export default {
components: {
"vue-qr": vueQr,
},
name: "orderDetail",
data() {
return {
sn: "", // 订单号
logisticsModal: false, //查询物流模态框
logisticsInfo: {}, //物流信息
afterSaleInfo: {}, // 售后信息
afterSaleImage: [], //会员申诉图片
submitLoading: false, // 添加或编辑提交状态
storeMsg: {}, // 商家地址信息
//商家处理意见
params: {
serviceStatus: "PASS",
remark: "",
},
//平台退款
refundPriceForm: {
remark: "",
},
afterSaleStatusList: [
// 售后状态列表
{
name: "申请中",
status: "APPLY",
},
{
name: "通过售后",
status: "PASS",
},
{
name: "拒绝售后",
status: "REFUSE",
},
{
name: "买家退货,待卖家收货",
status: "BUYER_RETURN",
},
{
name: "卖家确认收货",
status: "SELLER_CONFIRM",
},
{
name: "卖家终止售后",
status: "SELLER_TERMINATION",
},
{
name: "买家取消售后",
status: "BUYER_CANCEL",
},
{
name: "完成售后",
status: "COMPLETE",
},
{
name: "待平台退款",
status: "WAIT_REFUND",
},
],
};
defineOptions({ name: "orderDetail" });
const route = useRoute();
const sn = ref(""); // 订单号
const logisticsModal = ref(false); //查询物流模态框
const logisticsInfo = ref({}); //物流信息
const afterSaleInfo = ref({}); // 售后信息
const afterSaleImage = ref([]); //会员申诉图片
const submitLoading = ref(false); // 添加或编辑提交状态
const storeMsg = ref({}); // 商家地址信息
// 原代码未在 data 声明、直接挂 this 上的字段,补声明避免 ReferenceError
let loading = false;
//商家处理意见
const params = reactive({
serviceStatus: "PASS",
remark: "",
});
//平台退款
const refundPriceForm = reactive({
remark: "",
});
const afterSaleStatusList = ref([
// 售后状态列表
{
name: "申请中",
status: "APPLY",
},
methods: {
// 获取售后详情
getDetail() {
this.loading = true;
API_Order.getAfterSaleOrderDetail(this.sn).then((res) => {
this.loading = false;
if (res.success) {
this.afterSaleInfo = res.result;
this.afterSaleInfo.showDelivery = this.showDelivery(
this.afterSaleInfo.serviceStatus
);
this.afterSaleInfo.serviceName = this.filterOrderStatus(
this.afterSaleInfo.serviceStatus
);
this.afterSaleImage = (res.result.afterSaleImage || "").split(",");
//退货地址去掉逗号
if (this.afterSaleInfo.mconsigneeAddressPath)
this.afterSaleInfo.mconsigneeAddressPath = this.afterSaleInfo.mconsigneeAddressPath.replaceAll(
{
name: "通过售后",
status: "PASS",
},
{
name: "拒绝售后",
status: "REFUSE",
},
{
name: "买家退货,待卖家收货",
status: "BUYER_RETURN",
},
{
name: "卖家确认收货",
status: "SELLER_CONFIRM",
},
{
name: "卖家终止售后",
status: "SELLER_TERMINATION",
},
{
name: "买家取消售后",
status: "BUYER_CANCEL",
},
{
name: "完成售后",
status: "COMPLETE",
},
{
name: "待平台退款",
status: "WAIT_REFUND",
},
]);
// 获取售后详情
function getDetail() {
loading = true;
API_Order.getAfterSaleOrderDetail(sn.value).then((res) => {
loading = false;
if (res.success) {
afterSaleInfo.value = res.result;
afterSaleInfo.value.showDelivery = showDelivery(
afterSaleInfo.value.serviceStatus
);
afterSaleInfo.value.serviceName = filterOrderStatus(
afterSaleInfo.value.serviceStatus
);
afterSaleImage.value = (res.result.afterSaleImage || "").split(",");
//退货地址去掉逗号
if (afterSaleInfo.value.mconsigneeAddressPath)
afterSaleInfo.value.mconsigneeAddressPath = afterSaleInfo.value.mconsigneeAddressPath.replaceAll(
",",
" "
);
params.actualRefundPrice = afterSaleInfo.value.applyRefundPrice;
// 如果显示物流信息,展示商家地址
if (afterSaleInfo.value.showDelivery) {
API_Order.storeAddress(sn.value).then((resu) => {
if (resu.success) {
const obj = resu.result;
obj.salesConsigneeAddressPath = obj.salesConsigneeAddressPath.replaceAll(
",",
" "
""
);
this.params.actualRefundPrice = this.afterSaleInfo.applyRefundPrice;
// 如果显示物流信息,展示商家地址
if (this.afterSaleInfo.showDelivery) {
API_Order.storeAddress(this.sn).then((resu) => {
if (resu.success) {
const obj = resu.result;
obj.salesConsigneeAddressPath = obj.salesConsigneeAddressPath.replaceAll(
",",
""
);
this.storeMsg = obj;
}
});
}
}
});
},
//平台退款
refundPriceSubmit() {
if (this.refundPriceForm.remark == "") {
ElMessage.error("请输入退款备注");
return;
}
ElMessageBox.confirm("请确认退款?", "确认退款", { type: "warning" }).then(() => {
API_Order.refundPrice(this.sn, this.refundPriceForm).then((res) => {
if (res.success) {
ElMessage.success("收款成功");
this.getDetail();
storeMsg.value = obj;
}
});
}).catch(() => {});
},
//查询物流
logisticsSeller() {
this.logisticsModal = true;
API_Order.getAfterSaleTraces(this.sn).then((res) => {
if (res.success && res.result != null) {
this.logisticsInfo = res.result;
}
});
},
//关闭物流弹出框
logisticsClose() {
this.logisticsModal = false;
},
//回复
handleSubmit() {
if (this.params.remark == "") {
ElMessage.error("请输入备注信息");
return;
}
if (this.params.actualRefundPrice == "") {
ElMessage.error("请输入退款金额");
return;
}
});
}
//平台退款
function refundPriceSubmit() {
if (refundPriceForm.remark == "") {
ElMessage.error("请输入退款备注");
return;
}
ElMessageBox.confirm("请确认退款?", "确认退款", { type: "warning" }).then(() => {
API_Order.refundPrice(sn.value, refundPriceForm).then((res) => {
if (res.success) {
ElMessage.success("收款成功");
getDetail();
}
API_Order.afterSaleSellerReview(this.sn, this.params).then((res) => {
this.submitLoading = false;
if (res.success) {
ElMessage.success("审核成功");
this.params.remark = "";
this.getDetail();
}
});
},
filterOrderStatus(status) {
// 获取订单状态中文
const ob = this.afterSaleStatusList.filter((e) => {
return e.status === status;
});
return ob.length > 0 ? ob[0].name : status;
},
// 根据订单状态判断是否显示物流信息
showDelivery(status) {
let flag = false;
this.afterSaleStatusList.forEach((e, index) => {
// 订单为买家退货,待卖家收货之后的状态,并且不是买家取消售后,展示物流信息
if (e.status === status && index >= 3 && index !== 6) {
flag = true;
}
});
return flag;
},
},
mounted() {
this.sn = this.$route.query.sn;
this.getDetail();
},
};
});
}).catch(() => {});
}
//查询物流
function logisticsSeller() {
logisticsModal.value = true;
API_Order.getAfterSaleTraces(sn.value).then((res) => {
if (res.success && res.result != null) {
logisticsInfo.value = res.result;
}
});
}
//关闭物流弹出框
function logisticsClose() {
logisticsModal.value = false;
}
//回复
function handleSubmit() {
if (params.remark == "") {
ElMessage.error("请输入备注信息");
return;
}
if (params.actualRefundPrice == "") {
ElMessage.error("请输入退款金额");
return;
}
API_Order.afterSaleSellerReview(sn.value, params).then((res) => {
submitLoading.value = false;
if (res.success) {
ElMessage.success("审核成功");
params.remark = "";
getDetail();
}
});
}
function filterOrderStatus(status) {
// 获取订单状态中文
const ob = afterSaleStatusList.value.filter((e) => {
return e.status === status;
});
return ob.length > 0 ? ob[0].name : status;
}
// 根据订单状态判断是否显示物流信息
function showDelivery(status) {
let flag = false;
afterSaleStatusList.value.forEach((e, index) => {
// 订单为买家退货,待卖家收货之后的状态,并且不是买家取消售后,展示物流信息
if (e.status === status && index >= 3 && index !== 6) {
flag = true;
}
});
return flag;
}
onMounted(() => {
sn.value = route.query.sn;
getDetail();
});
</script>
<style lang="scss">
.main-content {

View File

@@ -2,7 +2,7 @@
<div class="search">
<el-card>
<el-form
ref="searchForm"
ref="searchFormRef"
:model="searchForm"
inline
label-width="70px"
@@ -104,97 +104,100 @@
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref, watch } from "vue";
import { useRoute } from "vue-router";
import * as API_Order from "@/api/order";
import vueQr from "vue-qr";
import { customRouterPush } from "@/utils/filters";
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();
},
},
methods: {
complainStatusText(v) {
const map = {
NEW: "新投诉",
CANCEL: "已撤销",
WAIT_APPEAL: "待申诉",
COMMUNICATION: "对话中",
WAIT_ARBITRATION: "等待仲裁",
COMPLETE: "已完成",
};
return map[v] || v || "-";
},
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;
}
})
.catch(() => {
this.loading = false;
});
},
detail(v) {
customRouterPush({
name: "order-complaint-detail",
query: { id: v.id },
});
},
},
mounted() {
this.init();
},
};
defineOptions({ name: "orderComplaint" });
const route = useRoute();
const searchFormRef = ref(null);
const table = ref(null);
const loading = ref(true);
const searchForm = reactive({
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
});
const data = ref([]);
const total = ref(0);
watch(
() => route.query,
() => {
getDataList();
}
);
function complainStatusText(v) {
const map = {
NEW: "新投诉",
CANCEL: "已撤销",
WAIT_APPEAL: "待申诉",
COMMUNICATION: "对话中",
WAIT_ARBITRATION: "等待仲裁",
COMPLETE: "已完成",
};
return map[v] || v || "-";
}
function complainStatusTagType(v) {
const map = {
NEW: "primary",
CANCEL: "info",
WAIT_APPEAL: "warning",
COMMUNICATION: "warning",
WAIT_ARBITRATION: "",
COMPLETE: "success",
};
return map[v] || "info";
}
function init() {
getDataList();
}
function changePage(v) {
searchForm.pageNumber = v;
getDataList();
}
function changePageSize(v) {
searchForm.pageNumber = 1;
searchForm.pageSize = v;
getDataList();
}
function handleSearch() {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
getDataList();
}
function getDataList() {
loading.value = true;
API_Order.getOrderComplain(searchForm)
.then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
})
.catch(() => {
loading.value = false;
});
}
function detail(v) {
customRouterPush({
name: "order-complaint-detail",
query: { id: v.id },
});
}
onMounted(() => {
init();
});
</script>
<style scoped>

View File

@@ -203,140 +203,141 @@
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import * as API_Order from "@/api/order";
import { ElMessage } from "element-plus";
import { unitPrice } from "@/utils/filters";
defineOptions({ name: "orderComplaintDetail" });
const route = useRoute();
const router = useRouter();
const emptyComplaint = () => ({
id: "",
orderComplaintCommunications: [],
});
export default {
name: "orderComplaintDetail",
data() {
return {
loading: false,
id: "",
complaintInfo: emptyComplaint(),
images: [],
appealImages: [],
submitLoading: false,
params: {
content: "",
complainId: "",
},
arbitrationParams: {
arbitrationResult: "",
},
arbitrationResultShow: false,
};
},
methods: {
unitPrice,
complainStatusText(v) {
const map = {
NEW: "新投诉",
CANCEL: "已撤销",
WAIT_APPEAL: "待申诉",
COMMUNICATION: "对话中",
WAIT_ARBITRATION: "等待仲裁",
COMPLETE: "已完成",
};
return map[v] || v || "-";
},
handleStoreComplaint() {
API_Order.storeComplain({
complainStatus: "WAIT_APPEAL",
complainId: this.complaintInfo.id,
}).then((res) => {
if (res.success) {
ElMessage.success("操作成功");
this.getDetail();
}
});
},
getDetail() {
if (!this.id) return;
this.loading = true;
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" });
},
arbitrationHandle() {
this.arbitrationResultShow = true;
},
arbitrationHandleSubmit() {
if (!this.arbitrationParams.arbitrationResult) {
ElMessage.error("请填写仲裁内容");
return;
const loading = ref(false);
const id = ref("");
const complaintInfo = ref(emptyComplaint());
const images = ref([]);
const appealImages = ref([]);
const submitLoading = ref(false);
const params = reactive({
content: "",
complainId: "",
});
const arbitrationParams = reactive({
arbitrationResult: "",
});
const arbitrationResultShow = ref(false);
function complainStatusText(v) {
const map = {
NEW: "新投诉",
CANCEL: "已撤销",
WAIT_APPEAL: "待申诉",
COMMUNICATION: "对话中",
WAIT_ARBITRATION: "等待仲裁",
COMPLETE: "已完成",
};
return map[v] || v || "-";
}
function handleStoreComplaint() {
API_Order.storeComplain({
complainStatus: "WAIT_APPEAL",
complainId: complaintInfo.value.id,
}).then((res) => {
if (res.success) {
ElMessage.success("操作成功");
getDetail();
}
});
}
function getDetail() {
if (!id.value) return;
loading.value = true;
API_Order.getOrderComplainDetail(id.value)
.then((res) => {
loading.value = false;
if (res.success) {
complaintInfo.value = res.result || emptyComplaint();
images.value = (res.result.images || "")
.split(",")
.map((s) => s.trim())
.filter(Boolean);
appealImages.value = (res.result.appealImages || "")
.split(",")
.map((s) => s.trim())
.filter(Boolean);
}
this.submitLoading = true;
API_Order.orderComplete(this.id, this.arbitrationParams)
.then((res) => {
this.submitLoading = false;
if (res.success) {
ElMessage.success("仲裁成功");
this.arbitrationParams.arbitrationResult = "";
this.arbitrationResultShow = false;
this.getDetail();
}
})
.catch(() => {
this.submitLoading = false;
});
},
handleSubmit() {
if (!this.params.content) {
ElMessage.error("请填写对话内容");
return;
})
.catch(() => {
loading.value = false;
});
}
function returnDataList() {
router.push({ name: "orderComplaint" });
}
function arbitrationHandle() {
arbitrationResultShow.value = true;
}
function arbitrationHandleSubmit() {
if (!arbitrationParams.arbitrationResult) {
ElMessage.error("请填写仲裁内容");
return;
}
submitLoading.value = true;
API_Order.orderComplete(id.value, arbitrationParams)
.then((res) => {
submitLoading.value = false;
if (res.success) {
ElMessage.success("仲裁成功");
arbitrationParams.arbitrationResult = "";
arbitrationResultShow.value = false;
getDetail();
}
this.submitLoading = true;
this.params.complainId = this.id;
API_Order.addOrderCommunication(this.params)
.then((res) => {
this.submitLoading = false;
if (res.success) {
ElMessage.success("对话成功");
this.params.content = "";
this.getDetail();
}
})
.catch(() => {
this.submitLoading = false;
});
},
},
mounted() {
this.id = this.$route.query.id;
this.getDetail();
},
watch: {
"$route.query.id"(val) {
this.id = val;
this.getDetail();
},
},
};
})
.catch(() => {
submitLoading.value = false;
});
}
function handleSubmit() {
if (!params.content) {
ElMessage.error("请填写对话内容");
return;
}
submitLoading.value = true;
params.complainId = id.value;
API_Order.addOrderCommunication(params)
.then((res) => {
submitLoading.value = false;
if (res.success) {
ElMessage.success("对话成功");
params.content = "";
getDetail();
}
})
.catch(() => {
submitLoading.value = false;
});
}
onMounted(() => {
id.value = route.query.id;
getDetail();
});
watch(
() => route.query.id,
(val) => {
id.value = val;
getDetail();
}
);
</script>
<style lang="scss" scoped>

View File

@@ -2,7 +2,7 @@
<div class="search">
<el-card>
<el-form
ref="searchForm"
ref="searchFormRef"
:model="searchForm"
inline
label-width="70px"
@@ -111,62 +111,60 @@
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref } from "vue";
import * as API_Order from "@/api/order";
export default {
name: "paymentLog",
data() {
return {
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
sn: "",
payStatus: "",
startDate: "",
endDate: "",
},
times: [],
data: [],
total: 0,
};
},
methods: {
init() {
this.getDataList();
},
changePage() {
this.getDataList();
},
changePageSize() {
this.searchForm.pageNumber = 1;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
changeDate(val) {
this.searchForm.startDate = val[0];
this.searchForm.endDate = val[1];
},
getDataList() {
this.loading = true;
API_Order.paymentLog(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
},
},
mounted() {
this.init();
},
};
defineOptions({ name: "paymentLog" });
const searchFormRef = ref(null);
const loading = ref(true);
const searchForm = reactive({
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
sn: "",
payStatus: "",
startDate: "",
endDate: "",
});
const times = ref([]);
const data = ref([]);
const total = ref(0);
function init() {
getDataList();
}
function changePage() {
getDataList();
}
function changePageSize() {
searchForm.pageNumber = 1;
getDataList();
}
function handleSearch() {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
getDataList();
}
function changeDate(val) {
searchForm.startDate = val[0];
searchForm.endDate = val[1];
}
function getDataList() {
loading.value = true;
API_Order.paymentLog(searchForm).then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
});
}
onMounted(() => {
init();
});
</script>

View File

@@ -2,7 +2,7 @@
<div class="search">
<el-card>
<el-form
ref="searchForm"
ref="searchFormRef"
:model="searchForm"
inline
label-width="70px"
@@ -108,71 +108,68 @@
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref } from "vue";
import * as API_Order from "@/api/order";
import { unitPrice } from "@/utils/filters";
export default {
name: "refundLog",
data() {
return {
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderSn: "",
isRefund: "",
},
selectDate: null,
data: [],
total: 0,
};
},
methods: {
unitPrice,
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();
},
selectDateRange(v) {
if (v && v[0] && v[1]) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
} else {
this.searchForm.startDate = "";
this.searchForm.endDate = "";
}
},
getDataList() {
this.loading = true;
API_Order.refundLog(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
},
},
mounted() {
this.init();
},
};
defineOptions({ name: "refundLog" });
const searchFormRef = ref(null);
const loading = ref(true);
const searchForm = reactive({
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderSn: "",
isRefund: "",
});
const selectDate = ref(null);
const data = ref([]);
const total = ref(0);
function init() {
getDataList();
}
function changePage(v) {
searchForm.pageNumber = v;
getDataList();
}
function changePageSize(v) {
searchForm.pageNumber = 1;
searchForm.pageSize = v;
getDataList();
}
function handleSearch() {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
getDataList();
}
function selectDateRange(v) {
if (v && v[0] && v[1]) {
searchForm.startDate = v[0];
searchForm.endDate = v[1];
} else {
searchForm.startDate = "";
searchForm.endDate = "";
}
}
function getDataList() {
loading.value = true;
API_Order.refundLog(searchForm).then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
});
}
onMounted(() => {
init();
});
</script>

View File

@@ -2,7 +2,7 @@
<div class="search">
<el-card>
<el-form
ref="searchForm"
ref="searchFormRef"
:model="searchForm"
inline
label-width="70px"
@@ -57,7 +57,7 @@
</div>
<el-table
ref="table"
ref="tableRef"
v-loading="loading"
border
:data="data"
@@ -126,107 +126,106 @@
</div>
</template>
<script>
<script setup>
import { onMounted, reactive, ref } from "vue";
import * as API_Order from "@/api/order";
import { ElMessage, ElMessageBox } from "element-plus";
import { customRouterPush } from "@/utils/filters";
export default {
name: "fictitiousOrderList",
data() {
return {
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 20,
sort: "",
order: "",
startDate: "",
endDate: "",
orderType: "VIRTUAL",
orderSn: "",
buyerName: "",
orderStatus: "",
},
selectDate: null,
data: [],
total: 0,
orderStatus: [
{ title: "全部", value: "" },
{ title: "未付款", value: "UNPAID" },
{ title: "已付款", value: "PAID" },
{ title: "待核验", value: "TAKE" },
{ title: "已完成", value: "COMPLETED" },
{ title: "已关闭", value: "CANCELLED" },
],
currentStatus: "",
};
},
methods: {
init() {
this.getDataList();
},
changePage() {
this.getDataList();
},
changePageSize() {
this.searchForm.pageNumber = 1;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
changeSort(e) {
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];
defineOptions({ name: "fictitiousOrderList" });
const searchFormRef = ref(null);
const tableRef = ref(null);
const loading = ref(true);
const searchForm = reactive({
pageNumber: 1,
pageSize: 20,
sort: "",
order: "",
startDate: "",
endDate: "",
orderType: "VIRTUAL",
orderSn: "",
buyerName: "",
orderStatus: "",
});
const selectDate = ref(null);
const data = ref([]);
const total = ref(0);
const orderStatus = ref([
{ title: "全部", value: "" },
{ title: "未付款", value: "UNPAID" },
{ title: "已付款", value: "PAID" },
{ title: "待核验", value: "TAKE" },
{ title: "已完成", value: "COMPLETED" },
{ title: "已关闭", value: "CANCELLED" },
]);
const currentStatus = ref("");
onMounted(() => {
init();
});
function init() {
getDataList();
}
function changePage() {
getDataList();
}
function changePageSize() {
searchForm.pageNumber = 1;
getDataList();
}
function handleSearch() {
searchForm.pageNumber = 1;
searchForm.pageSize = 20;
getDataList();
}
function changeSort(e) {
searchForm.sort = e.prop;
searchForm.order = e.order === "ascending" ? "asc" : e.order === "descending" ? "desc" : "";
getDataList();
}
function selectDateRange(v) {
if (v) {
searchForm.startDate = v[0];
searchForm.endDate = v[1];
}
}
function getDataList() {
loading.value = true;
API_Order.getOrderList(searchForm).then((res) => {
loading.value = false;
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
});
}
function confirmPrice(v) {
ElMessageBox.confirm("您确定要收款吗?", "确认收款", { type: "warning" }).then(() => {
API_Order.orderPay(v.sn).then((res) => {
if (res.success) {
ElMessage.success("收款成功");
getDataList();
}
},
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;
}
});
},
confirmPrice(v) {
ElMessageBox.confirm("您确定要收款吗?", "确认收款", { type: "warning" }).then(() => {
API_Order.orderPay(v.sn).then((res) => {
if (res.success) {
ElMessage.success("收款成功");
this.getDataList();
}
});
}).catch(() => {});
},
detail(v) {
let sn = v.sn;
customRouterPush({
name: "order-detail",
query: { sn: sn, orderType: v.orderType },
});
},
onStatusTabClick(tab) {
const item = tab.paneName;
this.currentStatus = item;
this.searchForm.orderStatus = item;
this.getDataList();
},
},
mounted() {
this.init();
},
};
});
}).catch(() => {});
}
function detail(v) {
let sn = v.sn;
customRouterPush({
name: "order-detail",
query: { sn: sn, orderType: v.orderType },
});
}
function onStatusTabClick(tab) {
const item = tab.paneName;
currentStatus.value = item;
searchForm.orderStatus = item;
getDataList();
}
</script>
<style lang="scss" scoped>

View File

@@ -357,7 +357,7 @@
</div>
<el-dialog v-model="modal" title="修改金额" width="530px">
<el-form ref="modifyPriceForm" :model="modifyPriceForm" label-width="70px" :rules="modifyPriceValidate" @submit.prevent>
<el-form ref="modifyPriceFormRef" :model="modifyPriceForm" label-width="70px" :rules="modifyPriceValidate" @submit.prevent>
<el-form-item label="订单金额" prop="price">
<el-input-number v-model="modifyPriceForm.price" :min="0" :max="999999" style="width: 120px" />
<span class="ml_10">元</span>
@@ -370,7 +370,7 @@
</el-dialog>
<el-dialog v-model="orderCancelModal" title="订单取消" width="530px">
<el-form ref="orderCancelForm" :model="orderCancelForm" label-width="100px" :rules="orderCancelValidate">
<el-form ref="orderCancelFormRef" :model="orderCancelForm" label-width="100px" :rules="orderCancelValidate">
<el-form-item label="取消原因" prop="reason">
<el-input v-model="orderCancelForm.reason" type="textarea" :rows="3" placeholder="请输入取消原因" />
</el-form-item>
@@ -382,7 +382,7 @@
</el-dialog>
<el-dialog v-model="addressModal" title="修改收件信息" width="530px">
<el-form ref="addressForm" :model="addressForm" label-width="100px" :rules="addressRule">
<el-form ref="addressFormRef" :model="addressForm" label-width="100px" :rules="addressRule">
<el-form-item label="收件人" prop="consigneeName">
<el-input v-model="addressForm.consigneeName" maxlength="20" />
</el-form-item>
@@ -518,7 +518,9 @@
</div>
</template>
<script>
<script setup>
import { computed, onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import * as API_Order from "@/api/order";
import { platformRefund, noShowRefund, getAppointmentOrderDetail } from "@/api/appointment";
import * as RegExp from "@/libs/RegExp.js";
@@ -529,457 +531,456 @@ import { printElement } from "@/utils/print";
import { ElMessage, ElMessageBox } from "element-plus";
import { unitPrice, clientTypeWay } from "@/utils/filters";
import { formatCardKeyStatus } from "@/constants/cardKey";
export default {
name: "orderList",
components: {
multipleMap,
"vue-qr": vueQr,
defineOptions({ name: "orderList" });
const route = useRoute();
const router = useRouter();
// 模板 ref(与表单 data 同名的改为 xxxRef,避免互相覆盖)
const modifyPriceFormRef = ref(null);
const orderCancelFormRef = ref(null);
const addressFormRef = ref(null);
const map = ref(null);
const typeList = ref([]);
const showPrices = ref(false);
const printHiddenFlag = ref(false);//隐藏信息
const loading = ref(false); //加载表格
const addr = ref(""); //地区
let regionId = ""; // 原代码未在 data 声明直接挂 this 的历史遗留字段
const orderLogInfo = ref([]); //订单日志数据
const orderLogModal = ref(false); //弹出调整价格框
const checkedLogistics = ref([]); //选中的物流公司集合
const allowOperation = ref({}); //订单可才做选项
const sn = ref(""); //订单编号
const orderInfo = ref({
order: {
priceDetailDTO: {},
},
computed: {
/** 电子卡券订单:无物流区,卡密来自 orderItems[].cardKeys */
isECouponOrder() {
const t = this.orderInfo?.order?.orderType;
return t === "E_COUPON" || this.$route.query.orderType === "E_COUPON";
});
const appointmentExt = ref({});
const modal = ref(false); //弹出调整价格框
const searchForm = reactive({
pageNumber: 1, // 当前页数
pageSize: 100, // 页面大小
orderSn: "", //订单sn
});
//调整价格表单
const modifyPriceForm = reactive({
price: 0,
});
//订单取消表单
const orderCancelForm = reactive({
reason: "",
});
//弹出订单取消框
const orderCancelModal = ref(false);
//订单发货
const orderDeliveryForm = reactive({
logisticsNo: "", //发货单号
logisticsId: "", //物流公司
});
//验证要调整的订单金额
const modifyPriceValidate = {
reason: [
{ required: true, message: "请输入大于0小于99999的合法金额" },
{
pattern: /^[1-9]\d{0,3}(\.\d{1,2})?$/,
message: "请输入大于0小于9999的合法金额",
trigger: "change",
},
isVirtualOrder() {
const t = this.orderInfo?.order?.orderType;
return t === "VIRTUAL" || this.$route.query.orderType === "VIRTUAL";
},
isNonPhysicalOrder() {
return this.isVirtualOrder || this.isECouponOrder || this.isAppointmentOrder;
},
isAppointmentOrder() {
const t = this.orderInfo?.order?.orderType;
return t === "APPOINTMENT" || this.$route.query.orderType === "APPOINTMENT";
},
appointmentSlotText() {
const v = this.appointmentExt || {};
if (!v.slotDate) return "";
const date = String(v.slotDate).slice(0, 10);
const slot = v.slotStartTime && v.slotEndTime ? `${v.slotStartTime}-${v.slotEndTime}` : "";
return [date, slot].filter(Boolean).join(" ");
},
appointmentFormGroups() {
return this.parseFormAnswerGroups(this.appointmentExt?.formAnswerJson);
},
canPlatformRefund() {
const order = this.orderInfo?.order;
return order && order.payStatus === "PAID" && order.orderStatus !== "CANCELLED";
},
canNoShowRefund() {
return this.canPlatformRefund;
},
ecouponCardKeyDelivered() {
return (this.data || []).some((item) => item.cardKeyDelivered);
},
ecouponCardKeyRows() {
const rows = [];
(this.data || []).forEach((item) => {
(item.cardKeys || []).forEach((ck) => {
rows.push({ ...ck });
});
});
return rows;
},
},
data () {
return {
typeList: [],
showPrices: false,
printHiddenFlag: false,//隐藏信息
loading: false, //加载表格
addr: "", //地区
orderLogInfo: [], //订单日志数据
orderLogModal: false, //弹出调整价格框
checkedLogistics: [], //选中的物流公司集合
allowOperation: {}, //订单可才做选项
sn: "", //订单编号
orderInfo: {
order: {
priceDetailDTO: {},
},
},
appointmentExt: {},
modal: false, //弹出调整价格框
searchForm: {
pageNumber: 1, // 当前页数
pageSize: 100, // 页面大小
orderSn: "", //订单sn
},
//调整价格表单
modifyPriceForm: {
price: 0,
},
//订单取消表单
orderCancelForm: {
reason: "",
},
//弹出订单取消框
orderCancelModal: false,
//订单发货
orderDeliveryForm: {
logisticsNo: "", //发货单号
logisticsId: "", //物流公司
},
//验证要调整的订单金额
modifyPriceValidate: {
reason: [
{ required: true, message: "请输入大于0小于99999的合法金额" },
{
pattern: /^[1-9]\d{0,3}(\.\d{1,2})?$/,
message: "请输入大于0小于9999的合法金额",
trigger: "change",
},
],
},
//验证取消订单原因
orderCancelValidate: {
reason: [{ required: true, message: "取消原因不能为空", trigger: "blur" }],
},
addressModal: false, //弹出修改收件信息框
printModal: false,
platformRefundModal: false,
noShowRefundModal: false,
refundLoading: false,
platformRefundForm: {
refundType: "UNSERVED",
refundAmount: 0,
reason: "",
},
noShowRefundForm: {
refundAmount: 0,
reason: "",
},
//收件地址表单
addressForm: {
consigneeName: "",
consigneeMobile: "",
consigneeDetail: "",
consigneeAddressPath: "",
consigneeAddressIdPath: "",
},
orderDeliverFormValidate: {
logisticsNo: [{ required: true, message: "发货单号不能为空", trigger: "change" }],
logisticsId: [{ required: true, message: "请选择物流公司", trigger: "blur" }],
},
addressRule: {
consigneeName: [
{ required: true, message: "收货人姓名不能为空", trigger: "blur" },
],
consigneeMobile: [
{ required: true, message: "联系方式不能为空", trigger: "blur" },
{
pattern: RegExp.mobile,
trigger: "blur",
message: "请输入正确的手机号",
},
],
consigneeDetail: [
{ required: true, message: "详细地址不能为空", trigger: "blur" },
],
},
data: [], // 表单数据
};
},
watch: {
$route (to, from) {
this.$router.go(0);
},
},
methods: {
unitPrice,
clientTypeWay,
formatCardKeyStatus,
copyCardKey(row) {
const text = `卡号:${row.cardNo || ""}\n卡密:${row.cardSecret || ""}`;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(() => {
ElMessage.success("已复制到剪贴板");
});
} else {
const ta = document.createElement("textarea");
ta.value = text;
document.body.appendChild(ta);
ta.select();
document.execCommand("copy");
document.body.removeChild(ta);
ElMessage.success("已复制到剪贴板");
}
},
getPromotionText(row) {
let resultText = "";
if (row && row.promotionType) {
const type = row.promotionType.split(",");
if (type.indexOf("PINTUAN") != -1) resultText += "拼团 ";
if (type.indexOf("SECKILL") != -1) resultText += "秒杀 ";
if (type.indexOf("COUPON") != -1) resultText += "优惠券 ";
if (type.indexOf("FULL_DISCOUNT") != -1) resultText += "满减 ";
if (type.indexOf("POINTS_GOODS") != -1) resultText += "积分商品 ";
}
return resultText === "" ? "未参与" : resultText;
},
gotoHomes () {
return false
},
//确认收款
confirmPrice () {
ElMessageBox.confirm(
"您确定要收款吗?线下收款涉及库存变更,需异步进行,等待约一分钟刷新列表查看",
"提示",
{ type: "warning" }
).then(() => {
API_Order.orderPay(this.sn).then((res) => {
if (res.success) {
ElMessage.success("收款成功");
this.getDataList();
}
});
}).catch(() => {});
},
getOrderPrice () {
if (this.showPrices) {
this.showPrices = false
} else if (!this.showPrices) {
this.showPrices = true
}
},
getContentPrice () {
for (let i = 0; i < this.typeList.length; i++) {
for (let j = i + 1; j < this.typeList.length; j++) {
if (this.typeList[i].promotionId === this.typeList[j].promotionId) {
this.typeList[i].discountPrice = this.typeList[i].discountPrice + this.typeList[j].discountPrice
this.typeList.splice(j, 1)
}
}
}
if (this.typeList.length >= 3) {
this.getContentPrice()
}
},
// 获取订单详情
getDataList () {
this.loading = true;
API_Order.orderDetail(this.sn).then((res) => {
this.loading = false;
if (res.success) {
this.orderInfo = res.result;
this.allowOperation = res.result.allowOperationVO;
this.data = res.result.orderItems;
this.typeList = JSON.parse(JSON.stringify(res.result.order.priceDetailDTO.discountPriceDetail));
this.getContentPrice()
this.getOrderPrice()
if (this.isAppointmentOrder) {
this.loadAppointmentExt();
}
}
});
},
loadAppointmentExt() {
getAppointmentOrderDetail(this.sn)
.then((res) => {
if (res.success) {
this.appointmentExt = res.result || {};
}
})
.catch(() => {
this.appointmentExt = {};
});
},
parseFormAnswerGroups(formAnswerJson) {
if (!formAnswerJson) return [];
let data = formAnswerJson;
if (typeof data === "string") {
try {
data = JSON.parse(data);
} catch (e) {
return [];
}
}
const fields = Array.isArray(data?.fields) ? data.fields : [];
const answers = Array.isArray(data?.answers) ? data.answers : [];
return answers
.map((group) => {
const map = group && typeof group === "object" && !Array.isArray(group) ? group : {};
const source = fields.length
? fields
: Object.keys(map).map((key) => ({ fieldKey: key, fieldLabel: key }));
return source
.map((field) => ({
fieldKey: field.fieldKey,
fieldLabel: field.fieldLabel || field.fieldKey,
value: map[field.fieldKey] ?? "",
}))
.filter((row) => row.value !== "" && row.value != null);
})
.filter((rows) => rows.length);
},
modifyPrice () {
//默认要修改的金额为订单总金额
this.modifyPriceForm.price = this.orderInfo.order.flowPrice;
this.modal = true;
},
//修改订单金额提交
modifyPriceSubmit () {
this.$refs.modifyPriceForm.validate((valid) => {
if (valid) {
API_Order.updateOrderPrice(this.sn, this.modifyPriceForm).then((res) => {
if (res.success) {
ElMessage.success("修改订单金额成功");
this.modal = false;
this.getDataList();
}
});
}
});
},
// 选中的地址
selectedRegion (val) {
if(val.type === 'select'){
const paths = val.data.map(item => item.name).join(',')
const ids = val.data.map(item => item.id).join(',')
this.addr = paths;
this.regionId = ids;
}
else{
this.addr = val.data.addr;
this.regionId = val.data.addrId;
}
},
//订单取消
orderCancel () {
this.orderCancelModal = true;
},
//订单取消提交
orderCancelSubmit () {
this.$refs.orderCancelForm.validate((valid) => {
if (valid) {
API_Order.orderCancel(this.sn, this.orderCancelForm).then((res) => {
if (res.success) {
ElMessage.success("取消成功");
this.getDataList();
}
this.orderCancelModal = false;
});
}
});
},
openPlatformRefund() {
this.platformRefundForm = {
refundType: "UNSERVED",
refundAmount: this.orderInfo?.order?.flowPrice || 0,
reason: "",
};
this.platformRefundModal = true;
},
submitPlatformRefund() {
if (!this.platformRefundForm.reason) {
ElMessage.warning("请填写退款原因");
return;
}
this.refundLoading = true;
platformRefund(this.sn, this.platformRefundForm)
.then((res) => {
if (res.success) {
ElMessage.success("退款成功");
this.platformRefundModal = false;
this.getDataList();
}
})
.finally(() => {
this.refundLoading = false;
});
},
openNoShowRefund() {
this.noShowRefundForm = {
refundAmount: this.orderInfo?.order?.flowPrice || 0,
reason: "",
};
this.noShowRefundModal = true;
},
submitNoShowRefund() {
if (!this.noShowRefundForm.reason) {
ElMessage.warning("请填写退款原因");
return;
}
this.refundLoading = true;
noShowRefund(this.sn, this.noShowRefundForm)
.then((res) => {
if (res.success) {
ElMessage.success("退款成功");
this.noShowRefundModal = false;
this.getDataList();
}
})
.finally(() => {
this.refundLoading = false;
});
},
//订单日志
orderLog () {
this.orderLogModal = true;
},
//订单日志取消
handelCancel () {
this.orderLogModal = false;
},
//打印发货单
printOrder () {
this.printModal = true;
},
printHiddenInfo () {
this.printHiddenFlag = !this.printHiddenFlag;
},
printCancel () {
// this.printHiddenFlag = false;
},
handlePrintInvoice () {
printElement("printInfo", "发货单");
},
//弹出修改收货地址框
editAddress () {
this.addressModal = true;
this.addr = this.orderInfo.order.consigneeAddressPath;
this.regionId = this.orderInfo.order.consigneeAddressIdPath;
this.addressForm.consigneeName = this.orderInfo.order.consigneeName;
this.addressForm.consigneeMobile = this.orderInfo.order.consigneeMobile;
this.addressForm.consigneeDetail = this.orderInfo.order.consigneeDetail;
this.addressForm.consigneeAddressPath = this.orderInfo.order.consigneeAddressPath;
this.addressForm.consigneeAddressIdPath = this.orderInfo.order.consigneeAddressIdPath;
},
//修改收货地址
editAddressSubmit () {
if (this.regionId == "") {
ElMessage.error("请选择地址");
return;
}
this.addressForm.consigneeAddressPath = this.addr;
this.addressForm.consigneeAddressIdPath = this.regionId;
this.$refs.addressForm.validate((valid) => {
if (valid) {
API_Order.editOrderConsignee(this.sn, this.addressForm).then((res) => {
if (res.success) {
ElMessage.success("收货地址修改成功");
this.addressModal = false;
this.getDataList();
}
});
}
});
},
},
mounted () {
this.sn = this.$route.query.sn;
this.getDataList();
},
],
};
//验证取消订单原因
const orderCancelValidate = {
reason: [{ required: true, message: "取消原因不能为空", trigger: "blur" }],
};
const addressModal = ref(false); //弹出修改收件信息框
const printModal = ref(false);
const platformRefundModal = ref(false);
const noShowRefundModal = ref(false);
const refundLoading = ref(false);
const platformRefundForm = ref({
refundType: "UNSERVED",
refundAmount: 0,
reason: "",
});
const noShowRefundForm = ref({
refundAmount: 0,
reason: "",
});
//收件地址表单
const addressForm = reactive({
consigneeName: "",
consigneeMobile: "",
consigneeDetail: "",
consigneeAddressPath: "",
consigneeAddressIdPath: "",
});
const orderDeliverFormValidate = {
logisticsNo: [{ required: true, message: "发货单号不能为空", trigger: "change" }],
logisticsId: [{ required: true, message: "请选择物流公司", trigger: "blur" }],
};
const addressRule = {
consigneeName: [
{ required: true, message: "收货人姓名不能为空", trigger: "blur" },
],
consigneeMobile: [
{ required: true, message: "联系方式不能为空", trigger: "blur" },
{
pattern: RegExp.mobile,
trigger: "blur",
message: "请输入正确的手机号",
},
],
consigneeDetail: [
{ required: true, message: "详细地址不能为空", trigger: "blur" },
],
};
const data = ref([]); // 表单数据
/** 电子卡券订单:无物流区,卡密来自 orderItems[].cardKeys */
const isECouponOrder = computed(() => {
const t = orderInfo.value?.order?.orderType;
return t === "E_COUPON" || route.query.orderType === "E_COUPON";
});
const isVirtualOrder = computed(() => {
const t = orderInfo.value?.order?.orderType;
return t === "VIRTUAL" || route.query.orderType === "VIRTUAL";
});
const isNonPhysicalOrder = computed(() => {
return isVirtualOrder.value || isECouponOrder.value || isAppointmentOrder.value;
});
const isAppointmentOrder = computed(() => {
const t = orderInfo.value?.order?.orderType;
return t === "APPOINTMENT" || route.query.orderType === "APPOINTMENT";
});
const appointmentSlotText = computed(() => {
const v = appointmentExt.value || {};
if (!v.slotDate) return "";
const date = String(v.slotDate).slice(0, 10);
const slot = v.slotStartTime && v.slotEndTime ? `${v.slotStartTime}-${v.slotEndTime}` : "";
return [date, slot].filter(Boolean).join(" ");
});
const appointmentFormGroups = computed(() => {
return parseFormAnswerGroups(appointmentExt.value?.formAnswerJson);
});
const canPlatformRefund = computed(() => {
const order = orderInfo.value?.order;
return order && order.payStatus === "PAID" && order.orderStatus !== "CANCELLED";
});
const canNoShowRefund = computed(() => {
return canPlatformRefund.value;
});
const ecouponCardKeyDelivered = computed(() => {
return (data.value || []).some((item) => item.cardKeyDelivered);
});
const ecouponCardKeyRows = computed(() => {
const rows = [];
(data.value || []).forEach((item) => {
(item.cardKeys || []).forEach((ck) => {
rows.push({ ...ck });
});
});
return rows;
});
watch(
() => route.query,
(to, from) => {
router.go(0);
}
);
onMounted(() => {
sn.value = route.query.sn;
getDataList();
});
function copyCardKey(row) {
const text = `卡号:${row.cardNo || ""}\n卡密:${row.cardSecret || ""}`;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(() => {
ElMessage.success("已复制到剪贴板");
});
} else {
const ta = document.createElement("textarea");
ta.value = text;
document.body.appendChild(ta);
ta.select();
document.execCommand("copy");
document.body.removeChild(ta);
ElMessage.success("已复制到剪贴板");
}
}
function getPromotionText(row) {
let resultText = "";
if (row && row.promotionType) {
const type = row.promotionType.split(",");
if (type.indexOf("PINTUAN") != -1) resultText += "拼团 ";
if (type.indexOf("SECKILL") != -1) resultText += "秒杀 ";
if (type.indexOf("COUPON") != -1) resultText += "优惠券 ";
if (type.indexOf("FULL_DISCOUNT") != -1) resultText += "满减 ";
if (type.indexOf("POINTS_GOODS") != -1) resultText += "积分商品 ";
}
return resultText === "" ? "未参与" : resultText;
}
function gotoHomes () {
return false
}
//确认收款
function confirmPrice () {
ElMessageBox.confirm(
"您确定要收款吗?线下收款涉及库存变更,需异步进行,等待约一分钟刷新列表查看",
"提示",
{ type: "warning" }
).then(() => {
API_Order.orderPay(sn.value).then((res) => {
if (res.success) {
ElMessage.success("收款成功");
getDataList();
}
});
}).catch(() => {});
}
function getOrderPrice () {
if (showPrices.value) {
showPrices.value = false
} else if (!showPrices.value) {
showPrices.value = true
}
}
function getContentPrice () {
for (let i = 0; i < typeList.value.length; i++) {
for (let j = i + 1; j < typeList.value.length; j++) {
if (typeList.value[i].promotionId === typeList.value[j].promotionId) {
typeList.value[i].discountPrice = typeList.value[i].discountPrice + typeList.value[j].discountPrice
typeList.value.splice(j, 1)
}
}
}
if (typeList.value.length >= 3) {
getContentPrice()
}
}
// 获取订单详情
function getDataList () {
loading.value = true;
API_Order.orderDetail(sn.value).then((res) => {
loading.value = false;
if (res.success) {
orderInfo.value = res.result;
allowOperation.value = res.result.allowOperationVO;
data.value = res.result.orderItems;
typeList.value = JSON.parse(JSON.stringify(res.result.order.priceDetailDTO.discountPriceDetail));
getContentPrice()
getOrderPrice()
if (isAppointmentOrder.value) {
loadAppointmentExt();
}
}
});
}
function loadAppointmentExt() {
getAppointmentOrderDetail(sn.value)
.then((res) => {
if (res.success) {
appointmentExt.value = res.result || {};
}
})
.catch(() => {
appointmentExt.value = {};
});
}
function parseFormAnswerGroups(formAnswerJson) {
if (!formAnswerJson) return [];
let data = formAnswerJson;
if (typeof data === "string") {
try {
data = JSON.parse(data);
} catch (e) {
return [];
}
}
const fields = Array.isArray(data?.fields) ? data.fields : [];
const answers = Array.isArray(data?.answers) ? data.answers : [];
return answers
.map((group) => {
const map = group && typeof group === "object" && !Array.isArray(group) ? group : {};
const source = fields.length
? fields
: Object.keys(map).map((key) => ({ fieldKey: key, fieldLabel: key }));
return source
.map((field) => ({
fieldKey: field.fieldKey,
fieldLabel: field.fieldLabel || field.fieldKey,
value: map[field.fieldKey] ?? "",
}))
.filter((row) => row.value !== "" && row.value != null);
})
.filter((rows) => rows.length);
}
function modifyPrice () {
//默认要修改的金额为订单总金额
modifyPriceForm.price = orderInfo.value.order.flowPrice;
modal.value = true;
}
//修改订单金额提交
function modifyPriceSubmit () {
modifyPriceFormRef.value.validate((valid) => {
if (valid) {
API_Order.updateOrderPrice(sn.value, modifyPriceForm).then((res) => {
if (res.success) {
ElMessage.success("修改订单金额成功");
modal.value = false;
getDataList();
}
});
}
});
}
// 选中的地址
function selectedRegion (val) {
if(val.type === 'select'){
const paths = val.data.map(item => item.name).join(',')
const ids = val.data.map(item => item.id).join(',')
addr.value = paths;
regionId = ids;
}
else{
addr.value = val.data.addr;
regionId = val.data.addrId;
}
}
//订单取消
function orderCancel () {
orderCancelModal.value = true;
}
//订单取消提交
function orderCancelSubmit () {
orderCancelFormRef.value.validate((valid) => {
if (valid) {
API_Order.orderCancel(sn.value, orderCancelForm).then((res) => {
if (res.success) {
ElMessage.success("取消成功");
getDataList();
}
orderCancelModal.value = false;
});
}
});
}
function openPlatformRefund() {
platformRefundForm.value = {
refundType: "UNSERVED",
refundAmount: orderInfo.value?.order?.flowPrice || 0,
reason: "",
};
platformRefundModal.value = true;
}
function submitPlatformRefund() {
if (!platformRefundForm.value.reason) {
ElMessage.warning("请填写退款原因");
return;
}
refundLoading.value = true;
platformRefund(sn.value, platformRefundForm.value)
.then((res) => {
if (res.success) {
ElMessage.success("退款成功");
platformRefundModal.value = false;
getDataList();
}
})
.finally(() => {
refundLoading.value = false;
});
}
function openNoShowRefund() {
noShowRefundForm.value = {
refundAmount: orderInfo.value?.order?.flowPrice || 0,
reason: "",
};
noShowRefundModal.value = true;
}
function submitNoShowRefund() {
if (!noShowRefundForm.value.reason) {
ElMessage.warning("请填写退款原因");
return;
}
refundLoading.value = true;
noShowRefund(sn.value, noShowRefundForm.value)
.then((res) => {
if (res.success) {
ElMessage.success("退款成功");
noShowRefundModal.value = false;
getDataList();
}
})
.finally(() => {
refundLoading.value = false;
});
}
//订单日志
function orderLog () {
orderLogModal.value = true;
}
//订单日志取消
function handelCancel () {
orderLogModal.value = false;
}
//打印发货单
function printOrder () {
printModal.value = true;
}
function printHiddenInfo () {
printHiddenFlag.value = !printHiddenFlag.value;
}
function printCancel () {
// printHiddenFlag.value = false;
}
function handlePrintInvoice () {
printElement("printInfo", "发货单");
}
//弹出修改收货地址框
function editAddress () {
addressModal.value = true;
addr.value = orderInfo.value.order.consigneeAddressPath;
regionId = orderInfo.value.order.consigneeAddressIdPath;
addressForm.consigneeName = orderInfo.value.order.consigneeName;
addressForm.consigneeMobile = orderInfo.value.order.consigneeMobile;
addressForm.consigneeDetail = orderInfo.value.order.consigneeDetail;
addressForm.consigneeAddressPath = orderInfo.value.order.consigneeAddressPath;
addressForm.consigneeAddressIdPath = orderInfo.value.order.consigneeAddressIdPath;
}
//修改收货地址
function editAddressSubmit () {
if (regionId == "") {
ElMessage.error("请选择地址");
return;
}
addressForm.consigneeAddressPath = addr.value;
addressForm.consigneeAddressIdPath = regionId;
addressFormRef.value.validate((valid) => {
if (valid) {
API_Order.editOrderConsignee(sn.value, addressForm).then((res) => {
if (res.success) {
ElMessage.success("收货地址修改成功");
addressModal.value = false;
getDataList();
}
});
}
});
}
</script>
<style lang="scss">
.lineH30 {

View File

@@ -2,7 +2,7 @@
<div class="search">
<el-card>
<el-form
ref="searchForm"
ref="searchFormRef"
:model="searchForm"
label-width="70px"
class="search-form order-search-form"
@@ -74,7 +74,7 @@
<el-button type="warning" class="export" :loading="exporting" @click="exportOrder">导出订单</el-button>
</div>
<el-table v-loading="loading" :data="data" ref="table" class="mt_10" style="width: 100%">
<el-table v-loading="loading" :data="data" ref="tableRef" class="mt_10" style="width: 100%">
<el-table-column prop="sn" label="订单号" min-width="200" show-overflow-tooltip />
<el-table-column label="商品" min-width="280">
<template #default="{ row }">
@@ -149,7 +149,8 @@
</div>
</template>
<script>
<script setup>
import { computed, onMounted, ref } from "vue";
import * as API_Order from "@/api/order";
import { ElMessage, ElMessageBox } from "element-plus";
import { unitPrice, customRouterPush } from "@/utils/filters";
@@ -229,264 +230,260 @@ function readSavedQuery() {
}
}
export default {
name: "orderList",
data() {
return {
loading: true,
exporting: false,
pageSizes: PAGE_SIZES,
promotionOptions: PROMOTION_OPTIONS,
orderTypeOptions: ORDER_TYPE_OPTIONS,
paymentOptions: PAYMENT_OPTIONS,
searchForm: emptySearchForm(),
selectDate: null,
data: [],
total: 0,
orderNumData: {},
currentStatus: "ALL",
};
},
computed: {
orderStatusWithCount() {
const count = (value) => (value ? `(${value})` : "");
return [
{ title: "全部", value: "ALL" },
{ title: `未付款${count(this.orderNumData.waitPayNum)}`, value: "UNPAID" },
{ title: `已付款${count(this.orderNumData.waitDeliveryNum)}`, value: "PAID" },
{ title: `待发货${count(this.orderNumData.waitShipNum)}`, value: "UNDELIVERED" },
{ title: `部分发货${count(this.orderNumData.partsDeliveredNumNum)}`, value: "PARTS_DELIVERED" },
{ title: `待收货${count(this.orderNumData.deliveredNum)}`, value: "DELIVERED" },
{ title: `待核验${count(this.orderNumData.waitCheckNum)}`, value: "TAKE" },
{ title: `待自提${count(this.orderNumData.waitSelfPickNum)}`, value: "STAY_PICKED_UP" },
{ title: `已完成${count(this.orderNumData.finishNum)}`, value: "COMPLETED" },
{ title: `已关闭${count(this.orderNumData.closeNum)}`, value: "CANCELLED" },
];
},
},
methods: {
unitPrice,
onStatusTabClick(tab) {
this.orderStatusClick(tab.paneName);
},
orderGoods(row) {
const items = row && row.orderItems;
return items && items.length ? items : [];
},
clientTypeText(v) {
const map = { H5: "移动端", PC: "PC端", WECHAT_MP: "小程序端", APP: "移动应用端" };
return map[v] || v || "—";
},
orderTypeText(v) {
const found = ORDER_TYPE_OPTIONS.find((item) => item.value === v);
return found ? found.label : v || "—";
},
orderPromotionText(v) {
const found = PROMOTION_OPTIONS.find((item) => item.value === v);
return found ? found.label : v || "—";
},
orderPromotionTagType(v) {
const map = {
NORMAL: "primary",
PINTUAN: "danger",
GIFT: "success",
POINTS: "info",
KANJIA: "warning",
};
return map[v] || "info";
},
deliveryMethodText(v) {
const map = {
SELF_PICK_UP: "自提",
LOCAL_TOWN_DELIVERY: "同城配送",
LOGISTICS: "物流",
VIRTUAL: "虚拟发货",
};
return map[v] || v || "—";
},
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";
},
rememberQuery() {
sessionStorage.setItem(
QUERY_KEY,
JSON.stringify({
searchForm: this.searchForm,
selectDate: this.selectDate,
currentStatus: this.currentStatus,
})
defineOptions({ name: "orderList" });
const searchFormRef = ref(null);
const tableRef = ref(null);
const loading = ref(true);
const exporting = ref(false);
const pageSizes = ref(PAGE_SIZES);
const promotionOptions = ref(PROMOTION_OPTIONS);
const orderTypeOptions = ref(ORDER_TYPE_OPTIONS);
const paymentOptions = ref(PAYMENT_OPTIONS);
const searchForm = ref(emptySearchForm());
const selectDate = ref(null);
const data = ref([]);
const total = ref(0);
const orderNumData = ref({});
const currentStatus = ref("ALL");
const orderStatusWithCount = computed(() => {
const count = (value) => (value ? `(${value})` : "");
return [
{ title: "全部", value: "ALL" },
{ title: `未付款${count(orderNumData.value.waitPayNum)}`, value: "UNPAID" },
{ title: `已付款${count(orderNumData.value.waitDeliveryNum)}`, value: "PAID" },
{ title: `待发货${count(orderNumData.value.waitShipNum)}`, value: "UNDELIVERED" },
{ title: `部分发货${count(orderNumData.value.partsDeliveredNumNum)}`, value: "PARTS_DELIVERED" },
{ title: `待收货${count(orderNumData.value.deliveredNum)}`, value: "DELIVERED" },
{ title: `待核验${count(orderNumData.value.waitCheckNum)}`, value: "TAKE" },
{ title: `待自提${count(orderNumData.value.waitSelfPickNum)}`, value: "STAY_PICKED_UP" },
{ title: `已完成${count(orderNumData.value.finishNum)}`, value: "COMPLETED" },
{ title: `已关闭${count(orderNumData.value.closeNum)}`, value: "CANCELLED" },
];
});
function onStatusTabClick(tab) {
orderStatusClick(tab.paneName);
}
function orderGoods(row) {
const items = row && row.orderItems;
return items && items.length ? items : [];
}
function clientTypeText(v) {
const map = { H5: "移动端", PC: "PC端", WECHAT_MP: "小程序端", APP: "移动应用端" };
return map[v] || v || "—";
}
function orderTypeText(v) {
const found = ORDER_TYPE_OPTIONS.find((item) => item.value === v);
return found ? found.label : v || "—";
}
function orderPromotionText(v) {
const found = PROMOTION_OPTIONS.find((item) => item.value === v);
return found ? found.label : v || "—";
}
function orderPromotionTagType(v) {
const map = {
NORMAL: "primary",
PINTUAN: "danger",
GIFT: "success",
POINTS: "info",
KANJIA: "warning",
};
return map[v] || "info";
}
function deliveryMethodText(v) {
const map = {
SELF_PICK_UP: "自提",
LOCAL_TOWN_DELIVERY: "同城配送",
LOGISTICS: "物流",
VIRTUAL: "虚拟发货",
};
return map[v] || v || "—";
}
function paymentMethodText(v) {
const map = {
NOT_ACTUALLY_PAID: "—",
WECHAT: "微信支付",
ALIPAY: "支付宝",
WALLET: "余额支付",
BANK_TRANSFER: "线下转账",
};
return map[v] || v || "—";
}
function orderStatusText(v) {
const map = {
UNPAID: "未付款",
PAID: "已付款",
UNDELIVERED: "待发货",
STAY_PICKED_UP: "待自提",
PARTS_DELIVERED: "部分发货",
DELIVERED: "已发货",
COMPLETED: "已完成",
TAKE: "待核验",
CANCELLED: "已关闭",
};
return map[v] || v || "—";
}
function 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";
}
function rememberQuery() {
sessionStorage.setItem(
QUERY_KEY,
JSON.stringify({
searchForm: searchForm.value,
selectDate: selectDate.value,
currentStatus: currentStatus.value,
})
);
}
function restoreQuery() {
const saved = readSavedQuery();
if (!saved) return;
searchForm.value = saved.searchForm;
selectDate.value = saved.selectDate;
currentStatus.value = saved.currentStatus;
}
function init() {
getDataList();
getOrderNumData();
}
function changePage(v) {
searchForm.value.pageNumber = v;
getDataList();
}
function changePageSize(v) {
searchForm.value.pageNumber = 1;
searchForm.value.pageSize = v;
getDataList();
}
function handleSearch() {
searchForm.value.pageNumber = 1;
getDataList();
getOrderNumData();
}
function handleReset() {
const pageSize = searchForm.value.pageSize;
searchForm.value = emptySearchForm(pageSize);
selectDate.value = null;
currentStatus.value = "ALL";
sessionStorage.removeItem(QUERY_KEY);
init();
}
function selectDateRange(v) {
if (v && v.length === 2) {
searchForm.value.startDate = v[0];
searchForm.value.endDate = v[1];
} else {
searchForm.value.startDate = "";
searchForm.value.endDate = "";
}
}
function countParams() {
const params = { ...searchForm.value };
delete params.orderStatus;
delete params.pageNumber;
delete params.pageSize;
delete params.sort;
delete params.order;
return params;
}
function getDataList() {
loading.value = true;
rememberQuery();
API_Order.getOrderList(searchForm.value)
.then((res) => {
if (res.success) {
data.value = res.result.records;
total.value = res.result.total;
}
})
.finally(() => {
loading.value = false;
});
}
function detail(v) {
customRouterPush({
name: "order-detail",
query: { sn: v.sn },
});
}
async function exportOrder() {
if (!searchForm.value.startDate || !searchForm.value.endDate) {
try {
await ElMessageBox.confirm(
"未选择下单时间,将按当前筛选条件导出全部匹配订单。",
"导出订单",
{ type: "warning", confirmButtonText: "继续导出", cancelButtonText: "取消" }
);
},
restoreQuery() {
const saved = readSavedQuery();
if (!saved) return;
this.searchForm = saved.searchForm;
this.selectDate = saved.selectDate;
this.currentStatus = saved.currentStatus;
},
init() {
this.getDataList();
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.getDataList();
this.getOrderNumData();
},
handleReset() {
const pageSize = this.searchForm.pageSize;
this.searchForm = emptySearchForm(pageSize);
this.selectDate = null;
this.currentStatus = "ALL";
sessionStorage.removeItem(QUERY_KEY);
this.init();
},
selectDateRange(v) {
if (v && v.length === 2) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
} else {
this.searchForm.startDate = "";
this.searchForm.endDate = "";
}
},
countParams() {
const params = { ...this.searchForm };
delete params.orderStatus;
delete params.pageNumber;
delete params.pageSize;
delete params.sort;
delete params.order;
return params;
},
getDataList() {
this.loading = true;
this.rememberQuery();
API_Order.getOrderList(this.searchForm)
.then((res) => {
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.finally(() => {
this.loading = false;
});
},
detail(v) {
customRouterPush({
name: "order-detail",
query: { sn: v.sn },
} catch (e) {
return;
}
}
exporting.value = true;
API_Order.exportOrder(searchForm.value)
.then((res) => {
const blob = new Blob([res], {
type: "application/vnd.ms-excel;charset=utf-8",
});
},
async exportOrder() {
if (!this.searchForm.startDate || !this.searchForm.endDate) {
try {
await ElMessageBox.confirm(
"未选择下单时间,将按当前筛选条件导出全部匹配订单。",
"导出订单",
{ type: "warning", confirmButtonText: "继续导出", cancelButtonText: "取消" }
);
} catch (e) {
return;
}
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);
})
.catch(() => {
ElMessage.error("导出失败");
})
.finally(() => {
exporting.value = false;
});
}
function orderStatusClick(name) {
if (name === "ALL" || name === "" || name === undefined) {
searchForm.value.orderStatus = "";
currentStatus.value = "ALL";
} else {
searchForm.value.orderStatus = name;
currentStatus.value = name;
}
searchForm.value.pageNumber = 1;
getDataList();
}
function getOrderNumData() {
API_Order.getOrderNum(countParams())
.then((res) => {
if (res.success) {
orderNumData.value = res.result;
}
this.exporting = true;
API_Order.exportOrder(this.searchForm)
.then((res) => {
const blob = new Blob([res], {
type: "application/vnd.ms-excel;charset=utf-8",
});
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);
})
.catch(() => {
ElMessage.error("导出失败");
})
.finally(() => {
this.exporting = false;
});
},
orderStatusClick(name) {
if (name === "ALL" || name === "" || name === undefined) {
this.searchForm.orderStatus = "";
this.currentStatus = "ALL";
} else {
this.searchForm.orderStatus = name;
this.currentStatus = name;
}
this.searchForm.pageNumber = 1;
this.getDataList();
},
getOrderNumData() {
API_Order.getOrderNum(this.countParams())
.then((res) => {
if (res.success) {
this.orderNumData = res.result;
}
})
.catch(() => {
this.orderNumData = {};
});
},
},
created() {
this.restoreQuery();
},
mounted() {
this.init();
},
};
})
.catch(() => {
orderNumData.value = {};
});
}
// created
restoreQuery();
onMounted(() => {
init();
});
</script>
<style lang="scss" scoped>