refactor: 重构多个组件以支持 Vue 3 语法和功能

- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能
- 优化状态管理和事件处理逻辑,简化代码结构
- 更新样式和布局以适应新组件结构
- 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
Yer11214
2026-07-08 18:37:11 +08:00
parent 4d0b0fb5e4
commit 349ffa4f34
189 changed files with 18278 additions and 20758 deletions

View File

@@ -6,8 +6,8 @@
:scrollable="false"
v-model:current="current"
@change="change"
:lineColor="$lightColor"
:activeStyle="{ color: $lightColor }"
:lineColor="lightColor"
:activeStyle="{ color: lightColor }"
></u-tabs>
</view>
<div class="u-tabs-search">
@@ -194,279 +194,199 @@
</view>
</template>
<script>
import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue";
import { getAfterSaleList, cancelAfterSale } from "@/api/after-sale.js";
import { getOrderList } from "@/api/order.js";
import storage from "@/utils/storage";
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { unitPrice, serviceStatusList, parseGoodsImageUrl } from '@/utils/filters.js'
import { getAfterSaleList, cancelAfterSale } from '@/api/after-sale.js'
import { getOrderList } from '@/api/order.js'
import storage from '@/utils/storage'
export default {
components: {
uniLoadMore,
},
data() {
return {
list: [
//tab表头
const store = useStore()
const lightColor = computed(() => store.getters.lightColor)
const list = [
{ name: '售后申请' },
{ name: '申请中' },
{ name: '申请记录' },
]
const current = ref(0)
const tipsShow = ref(false)
const cancelShow = ref(false)
const selectedOrder = ref<any>(null)
const orderList = ref<any[]>([])
const params = reactive<Record<string, any>>({
pageNumber: 1,
pageSize: 10,
sort: 'createTime',
flowPrice: 0,
order: 'desc',
})
const logParams = reactive<Record<string, any>>({
pageNumber: 1,
pageSize: 10,
})
const status = ref('loadmore')
const keywords = ref('')
onLoad((options) => {
orderList.value = []
params.pageNumber = 1
if (options?.orderSn) params.keywords = options.orderSn
searchOrderList(current.value)
})
onPullDownRefresh(() => {
change(current.value)
})
function hideLoadingIfNeeded() {
if (store.state.isShowToast) uni.hideLoading()
}
function getGoodsName(sku: any) {
return sku.goodsName || sku.name || ''
}
function getGoodsImage(goods: any, order: any, index: number) {
let image = goods.image || goods.goodsImage || goods.thumbnail
if (!image && order.groupImages) {
const images = String(order.groupImages).split(',')
image = images[index] || images[0]
}
return parseGoodsImageUrl(image)
}
function submitSearchOrderList(tabIndex: number) {
params.pageNumber = 1
logParams.pageNumber = 1
orderList.value = []
searchOrderList(tabIndex)
}
function clear(tabIndex: number) {
params.pageNumber = 1
logParams.pageNumber = 1
params.keywords = ''
orderList.value = []
searchOrderList(tabIndex)
}
function change(e: number | { index: number }) {
const index = typeof e === 'object' && e != null ? e.index : e
current.value = index
Object.assign(params, { pageNumber: 1, pageSize: 10 })
orderList.value = []
searchOrderList(index)
uni.stopPullDownRefresh()
}
function searchOrderList(index: number) {
if (index == 0) {
if (keywords.value) params.keywords = keywords.value
fetchOrderList()
} else {
Object.assign(logParams, {
pageNumber: 1,
pageSize: 10,
sort: 'createTime',
order: 'desc',
})
if (index === 1) {
logParams.serviceStatus = 'APPLY'
}
if (keywords.value) logParams.keywords = keywords.value
orderList.value = []
fetchAfterSaleLogList()
}
}
function fetchOrderList() {
uni.showLoading({ title: '加载中', mask: true })
getOrderList(params).then((res) => {
hideLoadingIfNeeded()
const records = res.data.result.records
if (records.length > 0) {
orderList.value = orderList.value.concat(records)
params.pageNumber += 1
}
status.value = records.length < 10 ? 'nomore' : 'loading'
})
}
function close(order: any, _sku: any) {
selectedOrder.value = order
cancelShow.value = true
}
async function closeService() {
uni.showLoading({ title: '加载中' })
const res = await cancelAfterSale(selectedOrder.value.sn)
if (res.data.success) {
uni.showToast({ title: '取消成功!', duration: 2000, icon: 'none' })
}
orderList.value = []
searchOrderList(current.value)
hideLoadingIfNeeded()
}
function afterDetails(order: any, _sku?: any) {
uni.navigateTo({ url: './applyDetail?sn=' + order.sn })
}
function fetchAfterSaleLogList() {
getAfterSaleList(logParams).then((res) => {
const afterSaleLogList = res.data.result.records
afterSaleLogList.forEach((item: any) => {
item.orderItems = [
{
name: "售后申请",
image: item.goodsImage,
skuId: item.skuId,
name: item.goodsName,
num: item.num,
price: item.flowPrice,
},
{
name: "申请中",
},
{
name: "申请记录",
},
],
current: 0, //当前表头索引
tipsShow: false, //提示开关
cancelShow: false, //取消显示开关
selectedOrder: "", //选中的order
orderList: [], //订单集合
params: {
pageNumber: 1,
pageSize: 10,
sort: "createTime",
flowPrice: 0,
order: "desc",
},
]
})
orderList.value = orderList.value.concat(afterSaleLogList)
status.value = afterSaleLogList.length < 10 ? 'nomore' : 'loading'
})
}
logParams: {
pageNumber: 1,
pageSize: 10,
},
status: "loadmore",
keywords: "", // 搜索订单sn
};
},
onLoad(options) {
this.orderList = [];
this.params.pageNumber = 1;
if (options.orderSn) this.params.keywords = options.orderSn;
this.searchOrderList(this.current);
},
onPullDownRefresh() {
this.change(this.current);
},
methods: {
getGoodsName(sku) {
return sku.goodsName || sku.name || "";
},
getGoodsImage(goods, order, index) {
let image = goods.image || goods.goodsImage || goods.thumbnail;
if (!image && order.groupImages) {
const images = String(order.groupImages).split(",");
image = images[index] || images[0];
}
return this.parseGoodsImageUrl(image);
},
/**
* 点击搜索执行搜索
*/
submitSearchOrderList(current) {
this.params.pageNumber = 1;
this.logParams.pageNumber = 1;
this.orderList = [];
this.searchOrderList(current);
},
// 清空
clear(current){
this.params.pageNumber = 1;
this.logParams.pageNumber = 1;
this.params.keywords = ''
this.orderList = [];
this.searchOrderList(current);
},
/**
* 切换tab页时初始化数据
*/
change(e) {
const index = typeof e === 'object' && e != null ? e.index : e;
this.current = index;
this.params = {
pageNumber: 1,
pageSize: 10,
};
this.orderList = [];
//如果是2 则读取售后申请记录列表
this.searchOrderList(index);
uni.stopPullDownRefresh();
},
function applyService(sn: string, order: any, sku: any) {
storage.setAfterSaleData({ ...order, ...sku })
uni.navigateTo({ url: `/pages/order/afterSales/afterSalesSelect?sn=${sn}` })
}
/**
* 搜索初始化
* 根据当前tab传值的索引进行更改
*/
searchOrderList(index) {
if (index == 0) {
this.keywords ? (this.params.keywords = this.keywords) : "";
this.getOrderList();
} else {
this.logParams = {
pageNumber: 1,
pageSize: 10,
sort: "createTime",
order: "desc",
};
if (index === 1) {
this.logParams.serviceStatus = "APPLY";
}
this.keywords ? (this.logParams.keywords = this.keywords) : "";
this.orderList = [];
this.getAfterSaleLogList();
}
},
function onExpress(order: any, sku: any) {
sku.storeName = order.storeName
storage.setAfterSaleData({ ...order, ...sku })
uni.navigateTo({ url: `./afterSalesDetailExpress?serviceSn=${order.sn}` })
}
/**
* 获取订单列表
*/
getOrderList() {
uni.showLoading({
title: "加载中",
mask: true,
});
getOrderList(this.params).then((res) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
const orderList = res.data.result.records;
if (orderList.length > 0) {
this.orderList = this.orderList.concat(orderList);
this.params.pageNumber += 1;
}
if (orderList.length < 10) {
this.status = "nomore";
} else {
this.status = "loading";
}
});
},
function onDetail(goods: any, sku: any) {
if (current.value == 0) {
uni.navigateTo({
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId || sku.goodsId}`,
})
} else {
uni.navigateTo({
url: `/pages/product/goods?id=${goods.skuId}&goodsId=${goods.goodsId || goods.goodsId}`,
})
}
}
close(order, sku) {
console.log(order, sku);
this.selectedOrder = order;
this.cancelShow = true;
},
async closeService() {
uni.showLoading({
title: "加载中",
});
console.log(this.selectedOrder);
let res = await cancelAfterSale(this.selectedOrder.sn);
if (res.data.success) {
uni.showToast({
title: "取消成功!",
duration: 2000,
icon: "none",
});
}
this.orderList = [];
this.searchOrderList(this.current);
if (this.$store.state.isShowToast){ uni.hideLoading() };
},
/**
* 售后详情
*/
afterDetails(order) {
uni.navigateTo({
url: "./applyDetail?sn=" + order.sn,
});
},
/**
* 申请记录列表
*/
getAfterSaleLogList() {
getAfterSaleList(this.logParams).then((res) => {
let afterSaleLogList = res.data.result.records;
afterSaleLogList.forEach((item) => {
item.orderItems = [
{
image: item.goodsImage,
skuId: item.skuId,
name: item.goodsName,
num: item.num,
price: item.flowPrice,
},
];
});
this.orderList = this.orderList.concat(afterSaleLogList);
if (afterSaleLogList.length < 10) {
this.status = "nomore";
} else {
this.status = "loading";
}
});
},
/**
* 申请售后
*/
applyService(sn, order, sku) {
let data = {
...order,
...sku,
};
storage.setAfterSaleData(data);
uni.navigateTo({
url: `/pages/order/afterSales/afterSalesSelect?sn=${sn}`,
});
},
/**
* 提交物流信息
*/
onExpress(order, sku) {
sku.storeName = order.storeName;
let data = {
...order,
...sku,
};
storage.setAfterSaleData(data);
uni.navigateTo({
url: `./afterSalesDetailExpress?serviceSn=${order.sn}`,
});
},
/**
* 查看详情
*/
onDetail(goods, sku) {
// 售后申请
if (this.current == 0) {
uni.navigateTo({
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${
sku.goodsId || sku.goodsId
}`,
});
} else {
uni.navigateTo({
url: `/pages/product/goods?id=${goods.skuId}&goodsId=${
goods.goodsId || goods.goodsId
}`,
});
}
},
/**
* 底部加载数据
*/
renderDate() {
if (this.current === 0) {
this.params.pageNumber += 1;
this.getOrderList();
} else {
this.logParams.pageNumber += 1;
this.getAfterSaleLogList();
}
},
},
};
function renderDate() {
if (current.value === 0) {
params.pageNumber += 1
fetchOrderList()
} else {
logParams.pageNumber += 1
fetchAfterSaleLogList()
}
}
</script>
<style lang="scss">

View File

@@ -1,7 +1,12 @@
<template>
<view class="page-wrap">
<scroll-view scroll-y class="page-scroll">
<u-form :model="form" ref="uForm">
<up-form
:model="form"
ref="uForm"
label-position="left"
label-width="180rpx"
>
<view class="after-sales-goods-detail-view">
<view class="header">
<view>
@@ -58,7 +63,7 @@
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
</view>
</view>
<u-form-item label="申请说明" label-width="150" :border-bottom="false" class="desc-item">
<up-form-item label="申请说明" label-width="180rpx" :border-bottom="false" class="desc-item">
<u-input
v-model="form.problemDesc"
type="textarea"
@@ -67,54 +72,54 @@
height="120"
placeholder="请描述申请售后的说明"
/>
</u-form-item>
</up-form-item>
</view>
<!-- 退款方式 / 银行信息 -->
<view class="opt-view form-block">
<u-form-item label="退款方式" label-width="150" :border-bottom="true">
<up-form-item label="退款方式" label-width="180rpx" :border-bottom="true">
<view class="form-value">{{
applyInfo.refundWay == 'ORIGINAL' ? '原路退回' : '账号退款'
}}</view>
</u-form-item>
</up-form-item>
<template v-if="
applyInfo.accountType === 'BANK_TRANSFER' &&
applyInfo.applyRefundPrice != 0
">
<u-form-item label="银行开户行" label-width="150" :border-bottom="true">
<up-form-item label="银行开户行" label-width="180rpx" :border-bottom="true">
<u-input
v-model="form.bankDepositName"
border="none"
input-align="right"
placeholder="请输入银行开户行"
/>
</u-form-item>
<u-form-item label="银行开户名" label-width="150" :border-bottom="true">
</up-form-item>
<up-form-item label="银行开户名" label-width="180rpx" :border-bottom="true">
<u-input
v-model="form.bankAccountName"
border="none"
input-align="right"
placeholder="请输入银行开户名"
/>
</u-form-item>
<u-form-item label="银行账号" label-width="150" :border-bottom="true" class="bank-account-item">
</up-form-item>
<up-form-item label="银行账号" label-width="180rpx" :border-bottom="true" class="bank-account-item">
<u-input
v-model="form.bankAccountNumber"
border="none"
input-align="right"
placeholder="请输入银行账号"
/>
</u-form-item>
</up-form-item>
</template>
<u-form-item
<up-form-item
v-if="form.serviceType !== 'RETURN_MONEY'"
label="返回方式"
label-width="150"
label-width="180rpx"
:border-bottom="false"
>
<view class="form-value">快递至第三方卖家</view>
</u-form-item>
</up-form-item>
</view>
<!-- 上传凭证 -->
@@ -133,7 +138,7 @@
<view class="opt-tip">提交服务单后,售后专员可能与您电话沟通,请保持手机畅通</view>
</view>
</u-form>
</up-form>
</scroll-view>
<view class="submit-view">
@@ -142,7 +147,7 @@
ripple
shape="circle"
v-if="applyInfo.refundWay"
:custom-style="{ backgroundColor: $lightColor, width: '100%' }"
:custom-style="{ backgroundColor: lightColor, width: '100%' }"
@click="onSubmit"
>提交申请</u-button>
</view>
@@ -158,246 +163,214 @@
</view>
</template>
<script>
import {
getAfterSaleReason,
applyReturn,
getAfterSaleInfo,
} from "@/api/after-sale";
<script setup lang="ts">
import { ref, reactive, computed, getCurrentInstance } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { unitPrice, parseGoodsImageUrl } from '@/utils/filters.js'
import { getAfterSaleReason, applyReturn, getAfterSaleInfo } from '@/api/after-sale'
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
import storage from '@/utils/storage.js'
import city from "@/components/m-city/m-city";
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
import storage from "@/utils/storage.js";
export default {
component: {
city,
},
data() {
return {
storage,
list: [{ id: "", localName: "请选择", children: [] }],
fileList: [],
sn: "",
sku: {},
typeValue: 0,
value: "",
type: "textarea",
border: true,
//退款原因 弹出框
reasonSelectShow: false,
reasonList: [],
applyInfo: {},
form: {
orderItemSn: "", // 订单sn
skuId: "",
reason: "", //退款原因
problemDesc: "", //退款说明
images: [], //图片凭证
num: 1, //退货数量
goodsId: "", //商品id
accountType: "",
applyRefundPrice: "",
refundWay: "",
serviceType: "", //申请类型
},
};
},
const store = useStore()
const { proxy } = getCurrentInstance()!
const $u = proxy!.$u
/**
* 判断当前内容并生成数据
*/
onLoad(options) {
let navTitle = "申请售后";
this.form.serviceType = "RETURN_GOODS";
if (options.value == 1) {
navTitle = "申请退货";
this.form.serviceType = "RETURN_GOODS";
const lightColor = computed(() => store.getters.lightColor)
const fileList = ref<any[]>([])
const sn = ref('')
const sku = ref<any>({})
const reasonSelectShow = ref(false)
const reasonList = ref<any[]>([])
const applyInfo = ref<any>({})
const uToast = ref<any>(null)
const form = reactive({
orderItemSn: '',
skuId: '',
reason: '',
problemDesc: '',
images: [] as string[],
num: 1,
goodsId: '',
accountType: '',
applyRefundPrice: '',
refundWay: '',
serviceType: 'RETURN_GOODS',
bankDepositName: '',
bankAccountName: '',
bankAccountNumber: '',
})
onLoad((options) => {
let navTitle = '申请售后'
form.serviceType = 'RETURN_GOODS'
if (options?.value == '1') {
navTitle = '申请退货'
form.serviceType = 'RETURN_GOODS'
}
if (options?.value == '2') {
navTitle = '申请换货'
form.serviceType = 'EXCHANGE_GOODS'
}
if (options?.value == '3') {
navTitle = '申请退款'
form.serviceType = 'RETURN_MONEY'
}
uni.setNavigationBarTitle({ title: navTitle })
sn.value = options?.sn || ''
sku.value = storage.getAfterSaleData()
form.orderItemSn = options?.sn || ''
form.skuId = sku.value.skuId
form.num = sku.value.num
form.goodsId = sku.value.goodsId
fetchReasonActions(form.serviceType)
init(options?.sn || '')
})
function hideLoadingIfNeeded() {
if (store.state.isShowToast) uni.hideLoading()
}
function getGoodsName(item: any) {
return item.goodsName || item.name || ''
}
function getGoodsImage(item: any) {
const image = item.image || item.goodsImage || item.thumbnail
return parseGoodsImageUrl(image)
}
function gotoGoodsDetail(goodsId: string) {
if (!goodsId) return
uni.navigateTo({
url: `/pages/product/goods?id=${form.skuId}&goodsId=${goodsId}`,
})
}
async function fetchReasonActions(serviceType: string) {
uni.showLoading({ title: '加载中' })
await getAfterSaleReason(serviceType).then((res) => {
if (res.data.success) {
reasonList.value = res.data.result.map((item: any) => ({
value: item.id,
label: item.reason,
}))
}
if (options.value == 2) {
navTitle = "申请换货";
this.form.serviceType = "EXCHANGE_GOODS";
}
if (options.value == 3) {
navTitle = "申请退款";
this.form.serviceType = "RETURN_MONEY";
}
this.typeValue = options.value;
uni.setNavigationBarTitle({
title: navTitle, //此处写页面的title
});
this.sn = options.sn;
this.sku = storage.getAfterSaleData();;
})
hideLoadingIfNeeded()
}
this.form.orderItemSn = options.sn;
this.form.skuId = this.sku.skuId;
this.form.num = this.sku.num;
this.form.goodsId = this.sku.goodsId;
this.getReasonActions(this.form.serviceType);
this.init(options.sn);
},
methods: {
getGoodsName(item) {
return item.goodsName || item.name || "";
},
getGoodsImage(item) {
const image = item.image || item.goodsImage || item.thumbnail;
return this.parseGoodsImageUrl(image);
},
gotoGoodsDetail(goodsId) {
if (!goodsId) return;
uni.navigateTo({
url: `/pages/product/goods?id=${this.form.skuId}&goodsId=${goodsId}`,
});
},
/** 获取申请原因下拉框数据 */
async getReasonActions(serviceType) {
uni.showLoading({
title: "加载中",
});
await getAfterSaleReason(serviceType).then((res) => {
if (res.data.success) {
let action = [];
res.data.result.forEach((item) => {
action.push({
value: item.id,
label: item.reason,
});
});
this.reasonList = action;
}
});
if (this.$store.state.isShowToast){ uni.hideLoading() };
},
//打开地区选择器
showCitySelect() {
this.$refs.cityPicker.show();
},
// 初始化数据
init(sn) {
getAfterSaleInfo(sn).then((response) => {
if (response.data.code == 400) {
uni.showToast({
title: response.data.message,
duration: 2000,
icon: "none",
});
} else {
this.applyInfo = response.data.result;
this.form.accountType = response.data.result.accountType;
}
});
},
openReasonPicker() {
if (!this.reasonList.length) {
uni.showToast({
title: "暂无可选原因",
icon: "none",
});
return;
}
this.reasonSelectShow = true;
},
//退款原因
reasonSelectConfirm(val) {
const selected = val?.value?.[0] || val?.[0];
if (selected) {
this.form.reason = selected.label || selected.text || "";
}
},
//修改申请数量
valChange(e) {
this.form.num = e.value;
},
onUploadAfterRead(event) {
handleUploadAfterRead(event, this.fileList, (urls) => {
this.form.images = urls;
});
},
showToast(message, type = "error") {
const text = message || (type === "success" ? "操作成功" : "操作失败");
if (this.$refs.uToast) {
this.$refs.uToast.show({ message: text, type });
return;
}
function init(orderItemSn: string) {
getAfterSaleInfo(orderItemSn).then((response) => {
if (response.data.code == 400) {
uni.showToast({
title: text,
icon: type === "success" ? "success" : "none",
});
},
//提交申请
onSubmit() {
//提交申请前检测参数
if (!this.handleCheckParams()) {
return;
}
title: response.data.message,
duration: 2000,
icon: 'none',
})
} else {
applyInfo.value = response.data.result
form.accountType = response.data.result.accountType
}
})
}
uni.showLoading({
title: "加载中",
});
this.form.accountType = this.applyInfo.accountType;
this.form.refundWay = this.applyInfo.refundWay;
this.form.applyRefundPrice = this.applyInfo.applyRefundPrice;
function openReasonPicker() {
if (!reasonList.value.length) {
uni.showToast({ title: '暂无可选原因', icon: 'none' })
return
}
reasonSelectShow.value = true
}
applyReturn(this.sn, this.form).then((resp) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
if (resp.data.success) {
this.showToast("提交成功", "success");
uni.redirectTo({
url: "/pages/order/afterSales/applySuccess",
});
} else {
this.showToast(resp.data.message || "提交失败", "error");
}
});
},
//检测提交参数
handleCheckParams() {
if (this.$u.test.isEmpty(this.form.reason)) {
this.showToast("请选择退款原因");
return false;
}
if (this.$u.test.isEmpty(this.form.problemDesc)) {
this.showToast("请输入退款说明");
return false;
}
function reasonSelectConfirm(val: any) {
const selected = val?.value?.[0] || val?.[0]
if (selected) {
form.reason = selected.label || selected.text || ''
}
}
if (
this.applyInfo.accountType === "BANK_TRANSFER" &&
this.applyInfo.applyRefundPrice != 0
) {
if (this.$u.test.isEmpty(this.form.bankDepositName)) {
this.showToast("请输入银行开户行");
return false;
}
if (this.$u.test.isEmpty(this.form.bankAccountName)) {
this.showToast("请输入银行开户名");
return false;
}
if (this.$u.test.isEmpty(this.form.bankAccountNumber)) {
this.showToast("请输入银行账号");
return false;
}
if (this.$u.test.chinese(this.form.bankAccountName) === false) {
this.showToast("银行开户名需为中文");
return false;
}
if (this.$u.test.chinese(this.form.bankDepositName) === false) {
this.showToast("银行开户行需为中文");
return false;
}
}
function valChange(e: { value: number }) {
form.num = e.value
}
return true;
},
},
};
function onUploadAfterRead(event: any) {
handleUploadAfterRead(event, fileList.value, (urls) => {
form.images = urls
})
}
function showToast(message: string, type = 'error') {
const text = message || (type === 'success' ? '操作成功' : '操作失败')
if (uToast.value) {
uToast.value.show({ message: text, type })
return
}
uni.showToast({
title: text,
icon: type === 'success' ? 'success' : 'none',
})
}
function onSubmit() {
if (!validateFormParams()) return
uni.showLoading({ title: '加载中' })
form.accountType = applyInfo.value.accountType
form.refundWay = applyInfo.value.refundWay
form.applyRefundPrice = applyInfo.value.applyRefundPrice
applyReturn(sn.value, form).then((resp) => {
hideLoadingIfNeeded()
if (resp.data.success) {
showToast('提交成功', 'success')
uni.redirectTo({ url: '/pages/order/afterSales/applySuccess' })
} else {
showToast(resp.data.message || '提交失败', 'error')
}
})
}
function validateFormParams() {
if ($u.test.isEmpty(form.reason)) {
showToast('请选择退款原因')
return false
}
if ($u.test.isEmpty(form.problemDesc)) {
showToast('请输入退款说明')
return false
}
if (
applyInfo.value.accountType === 'BANK_TRANSFER' &&
applyInfo.value.applyRefundPrice != 0
) {
if ($u.test.isEmpty(form.bankDepositName)) {
showToast('请输入银行开户行')
return false
}
if ($u.test.isEmpty(form.bankAccountName)) {
showToast('请输入银行开户名')
return false
}
if ($u.test.isEmpty(form.bankAccountNumber)) {
showToast('请输入银行账号')
return false
}
if ($u.test.chinese(form.bankAccountName) === false) {
showToast('银行开户名需为中文')
return false
}
if ($u.test.chinese(form.bankDepositName) === false) {
showToast('银行开户行需为中文')
return false
}
}
return true
}
</script>
<style lang="scss" scoped>

View File

@@ -1,6 +1,11 @@
<template>
<view class="mp-iphonex-bottom content">
<u-form :model="form" ref="uForm">
<up-form
:model="form"
ref="uForm"
label-position="left"
label-width="180rpx"
>
<view class="after-sales-goods-detail-view">
<view class="header">
<view>
@@ -29,32 +34,32 @@
<!-- 上传凭证 -->
<view class="opt-view">
<view class="img-title" style="font-size: 30rpx">填写物流信息</view>
<u-form-item label="返回方式" :label-width="150">
<up-form-item label="返回方式" label-width="180rpx">
<div style="width: 100%; text-align: right;">快递至第三方卖家</div>
</u-form-item>
<u-form-item label="快递公司" :label-width="150">
</up-form-item>
<up-form-item label="快递公司" label-width="180rpx">
<div style="width: 100%; text-align: right;" @click="companySelectShow = true">
{{ form.courierCompany || '请选择快递公司' }}
</div>
</u-form-item>
<u-form-item label="快递单号" :label-width="150">
</up-form-item>
<up-form-item label="快递单号" label-width="180rpx">
<u-input input-align="right" v-model="form.logisticsNo" placeholder="请输入快递单号"/>
</u-form-item>
<u-form-item label="发货时间" :label-width="150">
</up-form-item>
<up-form-item label="发货时间" label-width="180rpx">
<div style="width: 100%; text-align: right;" @click="timeshow = true">{{
form.mDeliverTime || '请选择发货时间'
}}
</div>
</u-form-item>
</up-form-item>
</view>
</scroll-view>
<view class="submit-view">
<u-button ripple :customStyle="{'background':$lightColor,'color':'#fff' }" shape="circle" @click="onSubmit">
<u-button ripple :customStyle="{ background: lightColor, color: '#fff' }" shape="circle" @click="onSubmit">
提交申请
</u-button>
</view>
</u-form>
</up-form>
<u-select mode="single-column" :list="companyList" v-model:show="companySelectShow"
@confirm="companySelectConfirm"></u-select>
<u-calendar v-model:show="timeshow" :mode="'date'" @change="onTimeChange"></u-calendar>
@@ -62,124 +67,98 @@
</view>
</template>
<script>
import {getLogistics} from "@/api/address.js";
import {fillShipInfo} from "@/api/after-sale.js";
import storage from "@/utils/storage";
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { unitPrice } from '@/utils/filters.js'
import { getLogistics } from '@/api/address.js'
import { fillShipInfo } from '@/api/after-sale.js'
import storage from '@/utils/storage'
export default {
data() {
return {
//快递公司 弹出框
companySelectShow: false,
companyList: [], //快递公司集合
timeshow: false, //发货时间
form: {
courierCompany: "", //快递公司
logisticsId: "", //快递公司ID
logisticsNo: "", //快递单号
mDeliverTime: "", //发货时间
},
serviceDetail: {}, //服务详情
sku: {}, //sku信息
};
},
onLoad(options) {
const store = useStore()
const lightColor = computed(() => store.getters.lightColor)
this.sku = storage.getAfterSaleData();
let navTitle = "服务单详情";
uni.setNavigationBarTitle({
title: navTitle, //此处写页面的title
});
this.serviceDetail.sn = options.serviceSn;
this.Logistics();
},
methods: {
/**
* 确认快递公司
*/
companySelectConfirm(e) {
this.form.logisticsId = e[0].value;
this.form.courierCompany = e[0].label;
},
const companySelectShow = ref(false)
const companyList = ref<any[]>([])
const timeshow = ref(false)
const form = reactive({
courierCompany: '',
logisticsId: '',
logisticsNo: '',
mDeliverTime: '',
})
const serviceDetail = reactive<{ sn: string }>({ sn: '' })
const sku = ref<any>({})
const uToast = ref<any>(null)
/**
* 获取快递公司
*/
Logistics() {
getLogistics().then((res) => {
if (res.data.success) {
res.data.result.forEach((item, index) => {
this.companyList[index] = {
value: item.id,
label: item.name,
};
});
}
});
},
onLoad((options) => {
sku.value = storage.getAfterSaleData()
uni.setNavigationBarTitle({ title: '服务单详情' })
serviceDetail.sn = options?.serviceSn || ''
fetchLogisticsList()
})
/**
* 更改时间
*/
onTimeChange(e) {
this.form.mDeliverTime = e.result;
},
function hideLoadingIfNeeded() {
if (store.state.isShowToast) uni.hideLoading()
}
/**
* 点击提交
*/
onSubmit() {
delete this.form.courierCompany;
function companySelectConfirm(e: any[]) {
form.logisticsId = e[0].value
form.courierCompany = e[0].label
}
if (this.form.logisticsId == "") {
this.$refs.uToast.show({
title: "请选择快递公司",
type: "error",
});
return;
}
if (this.form.logisticsNo == "") {
this.$refs.uToast.show({
title: "请填写快递单号",
type: "error",
});
return;
}
if (this.form.mDeliverTime == "") {
this.$refs.uToast.show({
title: "请选择发货时间",
type: "error",
});
return;
}
function fetchLogisticsList() {
getLogistics().then((res) => {
if (res.data.success) {
companyList.value = res.data.result.map((item: any) => ({
value: item.id,
label: item.name,
}))
}
})
}
uni.showLoading({
title: "加载中",
mask: true,
});
fillShipInfo(this.serviceDetail.sn, this.form).then((res) => {
if (this.$store.state.isShowToast) {
uni.hideLoading()
}
;
if (res.statusCode === 200) {
this.$refs.uToast.show({
title: "提交成功",
type: "success",
back: true,
url: "/pages/order/afterSales/afterSales",
});
}
});
},
gotoGoodsDetail(sku) {
uni.navigateTo({
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`,
});
},
},
};
function onTimeChange(e: { result: string }) {
form.mDeliverTime = e.result
}
function onSubmit() {
const submitForm = { ...form }
delete submitForm.courierCompany
if (form.logisticsId == '') {
uToast.value?.show({ title: '请选择快递公司', type: 'error' })
return
}
if (form.logisticsNo == '') {
uToast.value?.show({ title: '请填写快递单号', type: 'error' })
return
}
if (form.mDeliverTime == '') {
uToast.value?.show({ title: '请选择发货时间', type: 'error' })
return
}
uni.showLoading({ title: '加载中', mask: true })
fillShipInfo(serviceDetail.sn, submitForm).then((res) => {
hideLoadingIfNeeded()
if (res.statusCode === 200) {
uToast.value?.show({
title: '提交成功',
type: 'success',
back: true,
url: '/pages/order/afterSales/afterSales',
})
}
})
}
function gotoGoodsDetail(item: any) {
uni.navigateTo({
url: `/pages/product/goods?id=${item.skuId}&goodsId=${item.goodsId}`,
})
}
</script>
<style lang="scss" scoped>

View File

@@ -57,59 +57,51 @@
</view>
</template>
<script>
import { getAfterSaleInfo } from "@/api/after-sale";
import storage from "@/utils/storage";
export default {
data() {
return {
sn: "",
sku: {}, //sku
applyInfo:""
};
},
onLoad(options) {
this.sn = options.sn;
this.sku = storage.getAfterSaleData();
// 查看当前商品是否支持退款退货
this.init()
},
methods: {
getGoodsName(item) {
return item.goodsName || item.name || "";
},
getGoodsImage(item) {
const image = item.image || item.goodsImage || item.thumbnail;
return this.parseGoodsImageUrl(image);
},
// 初始化数据
init() {
getAfterSaleInfo(this.sn).then((response) => {
if (response.data.success) {
this.applyInfo = response.data.result;
}
});
},
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { unitPrice, parseGoodsImageUrl } from '@/utils/filters.js'
import { getAfterSaleInfo } from '@/api/after-sale'
import storage from '@/utils/storage'
/**
* 选择退货流程
*/
onSelect(value) {
uni.redirectTo({
url: `./afterSalesDetail?sn=${this.sn}&value=${value}`,
});
},
const sn = ref('')
const sku = ref<any>({})
const applyInfo = ref<any>({})
/**
* 跳转到商品信息
*/
navigateToGoodsDetail(id) {
uni.navigateTo({
url: `/pages/product/goods?id=${id}&goodsId=${goodsId}`,
});
},
},
};
onLoad((options) => {
sn.value = options?.sn || ''
sku.value = storage.getAfterSaleData()
init()
})
function getGoodsName(item: any) {
return item.goodsName || item.name || ''
}
function getGoodsImage(item: any) {
const image = item.image || item.goodsImage || item.thumbnail
return parseGoodsImageUrl(image)
}
function init() {
getAfterSaleInfo(sn.value).then((response) => {
if (response.data.success) {
applyInfo.value = response.data.result
}
})
}
function onSelect(value: number) {
uni.redirectTo({
url: `./afterSalesDetail?sn=${sn.value}&value=${value}`,
})
}
function navigateToGoodsDetail(skuId: string) {
uni.navigateTo({
url: `/pages/product/goods?id=${skuId}&goodsId=${sku.value.goodsId}`,
})
}
</script>
<style lang="scss">

View File

@@ -25,7 +25,7 @@
</view>
<view class="goods-info">
<view class="info-box">
<view class="goods-item-view" @click="navgiateToGoodsDetail(serviceDetail)">
<view class="goods-item-view" @click="navigateToGoodsDetail(serviceDetail)">
<view class="goods-img">
<u-image
border-radius="6"
@@ -184,198 +184,184 @@
</view>
</template>
<script>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import {
unitPrice,
parseGoodsImageUrl,
serviceStatusList,
secrecyMobile,
unixToDate,
} from '@/utils/filters.js'
import {
getServiceDetail,
getStoreAfterSaleAddress,
getAfterSaleLog,
getAfterSaleReason,
} from "@/api/after-sale.js";
export default {
data() {
return {
reason: "", //申请原因
serviceTypeList: {
// 售后类型
CANCEL: "取消",
RETURN_GOODS: "退货",
EXCHANGE_GOODS: "换货",
RETURN_MONEY: "退款",
},
serviceDetail: {}, // 售后详情
logs: [], //日志
goodsList: [], //商品列表
storeAfterSaleAddress: {}, //售后地址
refundShow: false, //退款开关
accountShow: false, //账户显示
bankShow: false, //银行显示
sn: "", //订单sn
};
},
onLoad(options) {
uni.setNavigationBarTitle({
title: "服务单详情",
});
this.sn = options.sn;
this.loadDetail();
this.getAddress();
this.getLog(options.sn);
},
methods: {
statusFilter(val) {
switch (val) {
case "APPLY":
return "售后服务申请成功,等待商家审核";
case "PASS":
return "售后服务申请审核通过";
case "REFUSE":
return "售后服务申请已被商家拒绝,如有疑问请及时联系商家";
case "FULL_COURIER":
return "申请售后的商品已经寄出,等待商家收货";
case "STOCK_IN":
return "商家已将售后商品入库";
case "WAIT_FOR_MANUAL":
return "等待平台进行人工退款";
case "REFUNDING":
return "商家退款中,请您耐心等待";
case "COMPLETED":
return "售后服务已完成,感谢您的支持";
case "ERROR_EXCEPTION":
return "系统生成新订单异常,等待商家手动创建新订单";
case "CLOSED":
return "售后服务已关闭";
case "WAIT_REFUND":
return "等待平台进行退款";
default:
return "";
}
},
refundWayFilter(val) {
switch (val) {
case "OFFLINE":
return "账户退款";
case "ORIGINAL":
return "原路退回";
default:
return "";
}
},
accountTypeFilter(val) {
switch (val) {
case "WEIXINPAY":
return "微信";
case "ALIPAY":
return "支付宝";
case "BANK_TRANSFER":
return "银行卡";
default:
return "";
}
},
/**
* 点击图片放大或保存
*/
preview(urls, index) {
uni.previewImage({
current: index,
urls: urls,
longPressActions: {
itemList: ["保存图片"],
success: function (data) {},
fail: function (err) {},
},
});
},
} from '@/api/after-sale.js'
/**
* 获取地址信息
*/
getAddress() {
getStoreAfterSaleAddress(this.sn).then((res) => {
if (res.data.success) {
this.storeAfterSaleAddress = res.data.result;
}
});
const store = useStore()
const reason = ref('')
const serviceTypeList: Record<string, string> = {
CANCEL: '取消',
RETURN_GOODS: '退货',
EXCHANGE_GOODS: '换货',
RETURN_MONEY: '退款',
}
const serviceDetail = ref<any>(null)
const logs = ref<any[]>([])
const storeAfterSaleAddress = ref<any>({})
const refundShow = ref(false)
const accountShow = ref(false)
const bankShow = ref(false)
const sn = ref('')
onLoad((options) => {
uni.setNavigationBarTitle({ title: '服务单详情' })
sn.value = options?.sn || ''
loadDetail()
fetchAddress()
fetchLog(sn.value)
})
function hideLoadingIfNeeded() {
if (store.state.isShowToast) uni.hideLoading()
}
function statusFilter(val: string) {
switch (val) {
case 'APPLY':
return '售后服务申请成功,等待商家审核'
case 'PASS':
return '售后服务申请审核通过'
case 'REFUSE':
return '售后服务申请已被商家拒绝,如有疑问请及时联系商家'
case 'FULL_COURIER':
return '申请售后的商品已经寄出,等待商家收货'
case 'STOCK_IN':
return '商家已将售后商品入库'
case 'WAIT_FOR_MANUAL':
return '等待平台进行人工退款'
case 'REFUNDING':
return '商家退款中,请您耐心等待'
case 'COMPLETED':
return '售后服务已完成,感谢您的支持'
case 'ERROR_EXCEPTION':
return '系统生成新订单异常,等待商家手动创建新订单'
case 'CLOSED':
return '售后服务已关闭'
case 'WAIT_REFUND':
return '等待平台进行退款'
default:
return ''
}
}
function refundWayFilter(val: string) {
switch (val) {
case 'OFFLINE':
return '账户退款'
case 'ORIGINAL':
return '原路退回'
default:
return ''
}
}
function accountTypeFilter(val: string) {
switch (val) {
case 'WEIXINPAY':
return '微信'
case 'ALIPAY':
return '支付宝'
case 'BANK_TRANSFER':
return '银行卡'
default:
return ''
}
}
function preview(urls: string[], index: number) {
uni.previewImage({
current: index,
urls,
longPressActions: {
itemList: ['保存图片'],
success: () => {},
fail: () => {},
},
})
}
/**
* 获取日志
*/
getLog(sn) {
getAfterSaleLog(sn).then((res) => {
this.logs = res.data.result;
});
},
function fetchAddress() {
getStoreAfterSaleAddress(sn.value).then((res) => {
if (res.data.success) {
storeAfterSaleAddress.value = res.data.result
}
})
}
/**
* 获取申请原因
*/
getReasonList(serviceType) {
getAfterSaleReason(serviceType).then((res) => {
if (res.data.success) {
// 1357583466371219456
this.reason = this.serviceDetail.reason;
}
});
},
function fetchLog(serviceSn: string) {
getAfterSaleLog(serviceSn).then((res) => {
logs.value = res.data.result
})
}
/**
* 初始化详情
*/
loadDetail() {
uni.showLoading({
title: "加载中",
});
getServiceDetail(this.sn).then((res) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
this.serviceDetail = res.data.result;
if (
this.serviceDetail.serviceType == "RETURN_GOODS" ||
this.serviceDetail.serviceType === "RETURN_MONEY"
) {
this.refundShow = true;
}
function fetchReasonList(serviceType: string) {
getAfterSaleReason(serviceType).then((res) => {
if (res.data.success) {
reason.value = serviceDetail.value.reason
}
})
}
this.accountShow =
(this.serviceDetail.serviceType === "RETURN_GOODS" ||
this.serviceDetail.serviceType === "ORDER_CANCEL") &&
this.serviceDetail.refundWay === "OFFLINE";
function loadDetail() {
uni.showLoading({ title: '加载中' })
getServiceDetail(sn.value).then((res) => {
hideLoadingIfNeeded()
serviceDetail.value = res.data.result
if (
serviceDetail.value.serviceType == 'RETURN_GOODS' ||
serviceDetail.value.serviceType === 'RETURN_MONEY'
) {
refundShow.value = true
}
this.bankShow =
this.serviceDetail.accountType === "BANK_TRANSFER" &&
this.serviceDetail.refundWay === "OFFLINE" &&
((this.serviceDetail.serviceType === "RETURN_GOODS") |
(this.serviceDetail.serviceType === "ORDER_CANCEL") ||
this.serviceDetail.serviceType === "RETURN_MONEY");
accountShow.value =
(serviceDetail.value.serviceType === 'RETURN_GOODS' ||
serviceDetail.value.serviceType === 'ORDER_CANCEL') &&
serviceDetail.value.refundWay === 'OFFLINE'
this.getReasonList(this.serviceDetail.serviceType);
});
},
bankShow.value =
serviceDetail.value.accountType === 'BANK_TRANSFER' &&
serviceDetail.value.refundWay === 'OFFLINE' &&
((serviceDetail.value.serviceType === 'RETURN_GOODS') |
(serviceDetail.value.serviceType === 'ORDER_CANCEL') ||
serviceDetail.value.serviceType === 'RETURN_MONEY')
/**
* 访问商品详情
*/
navgiateToGoodsDetail(item) {
uni.navigateTo({
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
});
},
fetchReasonList(serviceDetail.value.serviceType)
})
}
/**
* 进度
*/
onProgress() {
uni.navigateTo({
url: `./applyProgress?sn=${
this.serviceDetail.sn
}&createTime=${encodeURIComponent(this.serviceDetail.createTime)}
&logs=${encodeURIComponent(JSON.stringify(this.logs))}&serviceStatus=${
this.serviceDetail.serviceStatus
}`,
});
},
},
};
function navigateToGoodsDetail(item: any) {
uni.navigateTo({
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
})
}
function onProgress() {
uni.navigateTo({
url: `./applyProgress?sn=${
serviceDetail.value.sn
}&createTime=${encodeURIComponent(serviceDetail.value.createTime)}
&logs=${encodeURIComponent(JSON.stringify(logs.value))}&serviceStatus=${
serviceDetail.value.serviceStatus
}`,
})
}
</script>
<style lang="scss" scoped>

View File

@@ -35,54 +35,50 @@
</view>
</template>
<script>
export default {
data() {
return {
sn: "", //sn
createTime: "", //创建时间
logList: [], //日志集合
serviceStatus: "", //订单状态
};
},
onLoad(options) {
this.sn = options.sn;
this.createTime = decodeURIComponent(options.createTime);
this.serviceStatus = this.statusFilter(options.serviceStatus);
this.logList = JSON.parse(decodeURIComponent(options.logs));
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
},
methods: {
statusFilter(val) {
switch (val) {
case "APPLY":
return "售后服务申请成功,等待商家审核";
case "PASS":
return "售后服务申请审核通过";
case "REFUSE":
return "售后服务申请已被商家拒绝,如有疑问请及时联系商家";
case "FULL_COURIER":
return "申请售后的商品已经寄出,等待商家收货";
case "STOCK_IN":
return "商家已将售后商品入库";
case "WAIT_FOR_MANUAL":
return "等待平台进行人工退款";
case "REFUNDING":
return "商家退款中,请您耐心等待";
case "COMPLETED":
return "售后服务已完成,感谢您的支持";
case "ERROR_EXCEPTION":
return "系统生成新订单异常,等待商家手动创建新订单";
case "CLOSED":
return "售后服务已关闭";
case "WAIT_REFUND":
return "等待平台进行退款";
default:
return "";
}
},
},
};
const sn = ref('')
const createTime = ref('')
const logList = ref<any[]>([])
const serviceStatus = ref('')
function statusFilter(val: string) {
switch (val) {
case 'APPLY':
return '售后服务申请成功,等待商家审核'
case 'PASS':
return '售后服务申请审核通过'
case 'REFUSE':
return '售后服务申请已被商家拒绝,如有疑问请及时联系商家'
case 'FULL_COURIER':
return '申请售后的商品已经寄出,等待商家收货'
case 'STOCK_IN':
return '商家已将售后商品入库'
case 'WAIT_FOR_MANUAL':
return '等待平台进行人工退款'
case 'REFUNDING':
return '商家退款中,请您耐心等待'
case 'COMPLETED':
return '售后服务已完成,感谢您的支持'
case 'ERROR_EXCEPTION':
return '系统生成新订单异常,等待商家手动创建新订单'
case 'CLOSED':
return '售后服务已关闭'
case 'WAIT_REFUND':
return '等待平台进行退款'
default:
return ''
}
}
onLoad((options) => {
sn.value = options.sn || ''
createTime.value = decodeURIComponent(options.createTime || '')
serviceStatus.value = statusFilter(options.serviceStatus || '')
logList.value = JSON.parse(decodeURIComponent(options.logs || '[]'))
})
</script>
<style lang="scss" scoped>

View File

@@ -21,31 +21,18 @@
</view>
</template>
<script>
export default {
data() {
return {};
},
methods: {
/**
* 跳转到售后服务
*/
navigateToAfterSales() {
uni.redirectTo({
url: "/pages/order/afterSales/afterSales",
});
},
<script setup lang="ts">
function navigateToAfterSales() {
uni.redirectTo({
url: '/pages/order/afterSales/afterSales',
})
}
/**
* 跳转到首页
*/
navigateToHome() {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
},
},
};
function navigateToHome() {
uni.switchTab({
url: '/pages/tabbar/home/index',
})
}
</script>
<style lang="scss" scoped>