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 attrs = useAttrs();
const slots = useSlots(); const slots = useSlots();
const emits = defineEmits(['update:info']);
const convert = (obj) => const convert = (obj) =>
obj obj
? Object.entries(obj).map((entry) => { ? Object.entries(obj).map((entry) => {
@ -23,6 +28,20 @@
}) })
: []; : [];
const options = convert(data[86]); 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} />; const render = () => <ElCascader {...{ ...props, options }} {...attrs} v-slots={slots} />;
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped></style>

@ -8,8 +8,20 @@ const state = () => ({
summary: [], summary: [],
opts: { opts: {
init: false, init: false,
source: [], source: [
status: [], { 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 = {}; const getters = {};
@ -53,23 +65,10 @@ const actions = {
} }
return res; return res;
}, },
load: async ({ commit }) => { load: async ({ commit, state }) => {
commit('setOpts', { commit('setOpts', {
...state.opts,
init: true, 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) => { detail: async (context, id) => {
@ -96,6 +95,16 @@ const actions = {
} }
return res; 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) => { address: async (context, data) => {
let res = await api.updateAddress(data); let res = await api.updateAddress(data);
if (res) { if (res) {

@ -7,11 +7,11 @@
<el-form-item label="手机号码" prop="recipientPhone"> <el-form-item label="手机号码" prop="recipientPhone">
<el-input v-model="state.form.recipientPhone" /> <el-input v-model="state.form.recipientPhone" />
</el-form-item> </el-form-item>
<el-form-item label="所在区域" prop="area"> <el-form-item label="所在区域" prop="address">
<el-area v-model="state.form.area" /> <el-area v-model="state.form.address" v-model:info="state.form.addressInfo" />
</el-form-item> </el-form-item>
<el-form-item label="详细地址" prop="recipientAddress"> <el-form-item label="详细地址" prop="detailAddress">
<el-input v-model="state.form.recipientAddress" type="textarea" /> <el-input v-model="state.form.detailAddress" type="textarea" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -31,27 +31,29 @@
order: null, order: null,
form: { form: {
orderId: null, orderId: null,
area: [], address: [],
addressInfo: [],
recipientName: null, recipientName: null,
recipientPhone: null, recipientPhone: null,
recipientAddress: null, detailAddress: null,
}, },
rules: { rules: {
orderId: [{ required: true, message: '订单ID不能为空' }], orderId: [{ required: true, message: '订单ID不能为空' }],
area: [{ required: true, message: '省市区不能为空' }], address: [{ required: true, message: '省市区不能为空' }],
recipientName: [{ required: true, message: '收货人姓名不能为空' }], recipientName: [{ required: true, message: '收货人姓名不能为空' }],
recipientPhone: [{ required: true, message: '收货人手机不能为空' }], recipientPhone: [{ required: true, message: '收货人手机不能为空' }],
recipientAddress: [{ required: true, message: '详细地址不能为空' }], detailAddress: [{ required: true, message: '详细地址不能为空' }],
}, },
}); });
const show = (order) => { const show = (order) => {
state.order = order; state.order = order;
state.form = { state.form = {
orderId: order.orderId, 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, recipientName: order.logistics?.recipientName,
recipientPhone: order.logistics?.recipientPhone, recipientPhone: order.logistics?.recipientPhone,
recipientAddress: order.logistics?.recipientAddress, detailAddress: order.logistics?.detailAddress,
}; };
state.visible = true; state.visible = true;
}; };
@ -66,7 +68,16 @@
state.submitting = true; state.submitting = true;
try { try {
await unref(refsForm).validate(); 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) { if (res) {
Object.assign(state.order, state.form); Object.assign(state.order, state.form);
state.visible = false; 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> <template>
<div v-loading="state.loading" class="detail-container"> <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-step v-for="(item, index) in state.steps" :key="index" :description="item.desc" :title="item.title" />
</el-steps> </el-steps>
<div class="card"> <div class="card">
<div class="header"> <div class="header">
<h3 class="left red">当前订单状态{{ state.form.payTypeDesc }}</h3> <h3 class="left red">当前订单状态{{ state.form.orderStatusDesc }}</h3>
<div class="right"> <div class="right">
<el-button type="primary" @click="handleAddress"></el-button> <template v-if="state.form.orderStatus !== 2">
<el-button type="primary" @click="handleFees"></el-button> <template v-if="[1, 3].includes(state.form.orderStatus)">
<el-button type="danger" @click="handleClose"></el-button> <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>
</div> </div>
<el-scrollbar class="body"> <el-scrollbar class="body">
@ -112,16 +124,20 @@
</el-table> </el-table>
</el-scrollbar> </el-scrollbar>
</div> </div>
<CloseOrder ref="refsCloseOrder" /> <CloseOrder ref="refsCloseOrder" @close="handleLoad" />
<UpdateAddress ref="refsUpdateAddress" /> <CancelOrder ref="refsCancelOrder" @close="handleLoad" />
<UpdateFees ref="refsUpdateFees" /> <UpdateAddress ref="refsUpdateAddress" @close="handleLoad" />
<UpdateFees ref="refsUpdateFees" @close="handleLoad" />
<OrderTrack ref="refsOrderTrack" />
</div> </div>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import UpdateAddress from './address.vue'; import UpdateAddress from './address.vue';
import CancelOrder from './cancel.vue';
import CloseOrder from './close.vue'; import CloseOrder from './close.vue';
import UpdateFees from './fees.vue'; import UpdateFees from './fees.vue';
import OrderTrack from './track.vue';
const store = useStore(); const store = useStore();
const route = useRoute(); const route = useRoute();
const opts = computed(() => store.state.order.opts); const opts = computed(() => store.state.order.opts);
@ -136,21 +152,22 @@
}, },
{ {
title: '支付订单', title: '支付订单',
desc: '', desc: '未支付',
}, },
{ {
title: '平台发货', title: '平台发货',
desc: '', desc: '未发货',
}, },
{ {
title: '确认收货', title: '确认收货',
desc: '', desc: '未收货',
}, },
{ {
title: '完成评价', title: '完成评价',
desc: '', desc: '未评价',
}, },
], ],
currentStep: 1,
loading: false, loading: false,
form: { form: {
products: [], products: [],
@ -166,6 +183,13 @@
products: [], 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; state.loading = false;
}; };
onActivated(handleLoad); onActivated(handleLoad);
@ -173,6 +197,10 @@
const handleClose = () => { const handleClose = () => {
unref(refsCloseOrder).show(state.form.orderId); unref(refsCloseOrder).show(state.form.orderId);
}; };
const refsCancelOrder = ref(null);
const handleCancel = () => {
unref(refsCancelOrder).show(state.form);
};
const refsUpdateAddress = ref(null); const refsUpdateAddress = ref(null);
const handleAddress = () => { const handleAddress = () => {
unref(refsUpdateAddress).show(state.form); unref(refsUpdateAddress).show(state.form);
@ -181,6 +209,10 @@
const handleFees = () => { const handleFees = () => {
unref(refsUpdateFees).show(state.form); unref(refsUpdateFees).show(state.form);
}; };
const refsOrderTrack = ref(null);
const handleTrack = () => {
unref(refsOrderTrack).show(state.form.orderId);
};
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

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

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

Loading…
Cancel
Save