feat: 取消订单

feature/task1.0.0__0514__ch
向文可 3 years ago
parent 5067f42478
commit 734afe1ed9

@ -13,9 +13,14 @@
};
},
},
info: {
type: Array,
default: () => [],
},
});
const attrs = useAttrs();
const slots = useSlots();
const emits = defineEmits(['update:info']);
const convert = (obj) =>
obj
? Object.entries(obj).map((entry) => {
@ -23,6 +28,20 @@
})
: [];
const options = convert(data[86]);
const handleInfo = (code) => {
let province = data[86],
city = data[code[0]],
area = data[code[1]];
let res = [province?.[code[0]], city?.[code[1]], area?.[code[2]]];
return res;
};
watch(
() => attrs.modelValue,
(value) => {
emits('update:info', handleInfo(value));
},
{ immediate: true, deep: true }
);
const render = () => <ElCascader {...{ ...props, options }} {...attrs} v-slots={slots} />;
</script>
<style lang="less" scoped></style>

@ -8,8 +8,20 @@ const state = () => ({
summary: [],
opts: {
init: false,
source: [],
status: [],
source: [
{ label: '未知来源', value: 1 },
{ label: '安卓端APP', value: 2 },
{ label: 'IOS端APP', value: 3 },
],
status: [
{ label: '全部', value: 0, count: 0 },
{ label: '待支付', value: 1, count: 0 },
{ label: '已关闭', value: 2, count: 0 },
{ label: '已支付', value: 3, count: 0 },
{ label: '已发货', value: 4, count: 0 },
{ label: '已收货', value: 5, count: 0 },
{ label: '已完成', value: 6, count: 0 },
],
},
});
const getters = {};
@ -53,23 +65,10 @@ const actions = {
}
return res;
},
load: async ({ commit }) => {
load: async ({ commit, state }) => {
commit('setOpts', {
...state.opts,
init: true,
source: [
{ label: '未知来源', value: 1 },
{ label: '安卓端APP', value: 2 },
{ label: 'IOS端APP', value: 3 },
],
status: [
{ label: '全部', value: 0, count: 0 },
{ label: '待支付', value: 1, count: 0 },
{ label: '已关闭', value: 2, count: 0 },
{ label: '待发货', value: 3, count: 0 },
{ label: '已发货', value: 4, count: 0 },
{ label: '已收货', value: 5, count: 0 },
{ label: '已完成', value: 6, count: 0 },
],
});
},
detail: async (context, id) => {
@ -96,6 +95,16 @@ const actions = {
}
return res;
},
cancel: async ({ dispatch }, data) => {
let res = await api.cancel(data);
if (res) {
ElMessage.success('取消订单成功');
dispatch('search');
} else {
ElMessage.error('取消订单失败');
}
return res;
},
address: async (context, data) => {
let res = await api.updateAddress(data);
if (res) {

@ -7,11 +7,11 @@
<el-form-item label="手机号码" prop="recipientPhone">
<el-input v-model="state.form.recipientPhone" />
</el-form-item>
<el-form-item label="所在区域" prop="area">
<el-area v-model="state.form.area" />
<el-form-item label="所在区域" prop="address">
<el-area v-model="state.form.address" v-model:info="state.form.addressInfo" />
</el-form-item>
<el-form-item label="详细地址" prop="recipientAddress">
<el-input v-model="state.form.recipientAddress" type="textarea" />
<el-form-item label="详细地址" prop="detailAddress">
<el-input v-model="state.form.detailAddress" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
@ -31,27 +31,29 @@
order: null,
form: {
orderId: null,
area: [],
address: [],
addressInfo: [],
recipientName: null,
recipientPhone: null,
recipientAddress: null,
detailAddress: null,
},
rules: {
orderId: [{ required: true, message: '订单ID不能为空' }],
area: [{ required: true, message: '省市区不能为空' }],
address: [{ required: true, message: '省市区不能为空' }],
recipientName: [{ required: true, message: '收货人姓名不能为空' }],
recipientPhone: [{ required: true, message: '收货人手机不能为空' }],
recipientAddress: [{ required: true, message: '详细地址不能为空' }],
detailAddress: [{ required: true, message: '详细地址不能为空' }],
},
});
const show = (order) => {
state.order = order;
state.form = {
orderId: order.orderId,
area: [],
address: [order.logistics?.provinceCode, order.logistics?.cityCode, order.logistics?.areaCode],
addressInfo: [order.logistics?.province, order.logistics?.city, order.logistics?.area],
recipientName: order.logistics?.recipientName,
recipientPhone: order.logistics?.recipientPhone,
recipientAddress: order.logistics?.recipientAddress,
detailAddress: order.logistics?.detailAddress,
};
state.visible = true;
};
@ -66,7 +68,16 @@
state.submitting = true;
try {
await unref(refsForm).validate();
let res = await store.dispatch('order/address', state.form);
let data = _.cloneDeep(state.form);
data.province = data.addressInfo[0];
data.city = data.addressInfo[1];
data.area = data.addressInfo[2];
delete data.addressInfo;
data.provinceCode = data.address[0];
data.cityCode = data.address[1];
data.areaCode = data.address[2];
delete data.address;
let res = await store.dispatch('order/address', data);
if (res) {
Object.assign(state.order, state.form);
state.visible = false;

@ -0,0 +1,90 @@
<template>
<el-dialog v-model="state.visible" title="取消订单">
<el-form
ref="refsForm"
v-loading="state.submitting"
label-width="100px"
:model="state.form"
:rules="state.rules"
>
<el-form-item label="订单金额">
{{ state.form.totalAmount }}
</el-form-item>
<el-form-item label="运费">
{{ state.form.shippingAmount }}
</el-form-item>
<el-form-item label="退款金额">
{{ state.form.payAmount }}
</el-form-item>
<el-form-item label="取消原因" prop="cancelReason">
<el-input v-model="state.form.cancelReason" type="textarea" />
<p class="tips">会显示在客户的订单中</p>
</el-form-item>
<el-form-item label="操作备注" prop="remark">
<el-input v-model="state.form.remark" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="close"></el-button>
<el-button :loading="state.submitting" type="primary" @click="handleSave"></el-button>
</template>
</el-dialog>
</template>
<script setup lang="jsx">
const store = useStore();
const refsForm = ref(null);
const state = reactive({
submitting: false,
visible: false,
form: {
orderId: null,
totalAmount: 0,
shippingAmount: 0,
payAmount: 0,
cancelReason: null,
remark: null,
},
rules: {
orderId: [{ required: true, message: '订单ID不能为空' }],
cancelReason: [{ required: true, message: '取消原因不能为空' }],
remark: [{ required: true, message: '操作备注不能为空' }],
},
});
const show = (form) => {
state.form.orderId = form.orderId;
state.form.totalAmount = form.totalAmount;
state.form.shippingAmount = form.shippingAmount;
state.form.payAmount = form.payAmount;
state.form.cancelReason = null;
state.form.remark = null;
state.visible = true;
};
const close = () => {
state.visible = false;
};
defineExpose({
show,
close,
});
const handleSave = async () => {
state.submitting = true;
try {
await unref(refsForm).validate();
let res = await store.dispatch('order/cancel', state.form);
if (res) {
state.visible = false;
}
} catch (e) {
console.info('取消关闭', e);
}
state.submitting = false;
};
</script>
<style lang="less" scoped>
.tips {
color: @color-white2;
}
</style>

@ -1,15 +1,27 @@
<template>
<div v-loading="state.loading" class="detail-container">
<el-steps :active="1" align-center>
<el-steps :active="state.currentStep" align-center>
<el-step v-for="(item, index) in state.steps" :key="index" :description="item.desc" :title="item.title" />
</el-steps>
<div class="card">
<div class="header">
<h3 class="left red">当前订单状态{{ state.form.payTypeDesc }}</h3>
<h3 class="left red">当前订单状态{{ state.form.orderStatusDesc }}</h3>
<div class="right">
<template v-if="state.form.orderStatus !== 2">
<template v-if="[1, 3].includes(state.form.orderStatus)">
<el-button type="primary" @click="handleAddress"></el-button>
<template v-if="state.form.orderStatus === 3">
<el-button type="danger" @click="handleCancel"></el-button>
</template>
<template v-if="state.form.orderStatus === 1">
<el-button type="primary" @click="handleFees"></el-button>
<el-button type="danger" @click="handleClose"></el-button>
</template>
</template>
<template v-if="[4, 5, 6].includes(state.form.orderStatus)">
<el-button type="primary" @click="handleTrack"></el-button>
</template>
</template>
</div>
</div>
<el-scrollbar class="body">
@ -112,16 +124,20 @@
</el-table>
</el-scrollbar>
</div>
<CloseOrder ref="refsCloseOrder" />
<UpdateAddress ref="refsUpdateAddress" />
<UpdateFees ref="refsUpdateFees" />
<CloseOrder ref="refsCloseOrder" @close="handleLoad" />
<CancelOrder ref="refsCancelOrder" @close="handleLoad" />
<UpdateAddress ref="refsUpdateAddress" @close="handleLoad" />
<UpdateFees ref="refsUpdateFees" @close="handleLoad" />
<OrderTrack ref="refsOrderTrack" />
</div>
</template>
<script setup lang="jsx">
import UpdateAddress from './address.vue';
import CancelOrder from './cancel.vue';
import CloseOrder from './close.vue';
import UpdateFees from './fees.vue';
import OrderTrack from './track.vue';
const store = useStore();
const route = useRoute();
const opts = computed(() => store.state.order.opts);
@ -136,21 +152,22 @@
},
{
title: '支付订单',
desc: '',
desc: '未支付',
},
{
title: '平台发货',
desc: '',
desc: '未发货',
},
{
title: '确认收货',
desc: '',
desc: '未收货',
},
{
title: '完成评价',
desc: '',
desc: '未评价',
},
],
currentStep: 1,
loading: false,
form: {
products: [],
@ -166,6 +183,13 @@
products: [],
}
);
state.steps.forEach((step, index) => {
let date = res.orderLogs.find((item) => item.operationTypeDesc === step.title);
step.desc = date?.createTime || step.desc;
if (date) {
state.currentStep = index + 1;
}
});
state.loading = false;
};
onActivated(handleLoad);
@ -173,6 +197,10 @@
const handleClose = () => {
unref(refsCloseOrder).show(state.form.orderId);
};
const refsCancelOrder = ref(null);
const handleCancel = () => {
unref(refsCancelOrder).show(state.form);
};
const refsUpdateAddress = ref(null);
const handleAddress = () => {
unref(refsUpdateAddress).show(state.form);
@ -181,6 +209,10 @@
const handleFees = () => {
unref(refsUpdateFees).show(state.form);
};
const refsOrderTrack = ref(null);
const handleTrack = () => {
unref(refsOrderTrack).show(state.form.orderId);
};
</script>
<style lang="less" scoped>

@ -136,6 +136,7 @@
await store.dispatch('order/search');
loading.value = false;
};
onActivated(handleSearch);
/* 导出订单 */
const handleExport = async () => {

@ -20,9 +20,9 @@ export default (configEnv) => {
open: false,
proxy: {
'/api': {
// target: 'http://192.168.10.52:8090/', // 显雨
target: 'http://192.168.10.251:8090', // 高玉
// target: 'http://k8s-horse-gateway.mashibing.cn/', // 测试地址
// target: 'http://192.168.10.109:8090/', // 显雨
// target: 'http://192.168.10.251:8090', // 高玉
target: 'http://k8s-horse-gateway.mashibing.cn/', // 测试地址
// target: 'https://gateway.mashibing.cn', // 预发地址
// target: 'https://gateway.mashibing.com', // 生产环境
changeOrigin: true,

Loading…
Cancel
Save