<template>
|
<view class="after-sales-registration">
|
<!-- 使用通用页面头部组件 -->
|
<PageHeader title="售后登记" @back="goBack" />
|
|
<!-- 统计卡片区域 -->
|
<view class="stats-container">
|
<view v-for="(item, index) in statsList" :key="index" class="stat-card">
|
<view class="stat-icon" :style="{ backgroundColor: item.bgColor }">
|
<up-icon :name="item.icon" :color="item.color" size="20"></up-icon>
|
</view>
|
<view class="stat-info">
|
<text class="stat-number">{{ item.count }}</text>
|
<text class="stat-label">{{ item.label }}</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 搜索和筛选区域 -->
|
<view class="search-section">
|
<view class="search-bar">
|
<view class="search-input">
|
<up-input class="search-text" placeholder="请输入工单编号搜索" v-model="searchForm.afterSalesServiceNo" @change="handleQuery" clearable />
|
</view>
|
<view class="filter-button" @click="handleQuery">
|
<up-icon name="search" size="24" color="#999"></up-icon>
|
</view>
|
</view>
|
</view>
|
|
<!-- 售后单列表 -->
|
<view class="ledger-list" v-if="tableData.length > 0">
|
<view v-for="(item, index) in tableData" :key="index" class="ledger-item">
|
<view class="item-header">
|
<view class="item-left">
|
<view class="document-icon">
|
<up-icon name="file-text" size="16" color="#ffffff"></up-icon>
|
</view>
|
<text class="item-id">{{ item.afterSalesServiceNo }}</text>
|
</view>
|
<view class="item-tag">
|
<up-tag :text="getStatusLabel(item.status)" :type="getStatusType(item.status)" size="mini"></up-tag>
|
</view>
|
</view>
|
<up-divider></up-divider>
|
<view class="item-details">
|
<view class="detail-row">
|
<text class="detail-label">销售单号</text>
|
<text class="detail-value">{{ item.salesContractNo }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">客户名称</text>
|
<text class="detail-value">{{ item.customerName }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">反馈日期</text>
|
<text class="detail-value">{{ item.feedbackDate }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">售后类型</text>
|
<text class="detail-value">{{ getDictLabel(post_sale_waiting_list, item.serviceType) }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">紧急程度</text>
|
<text class="detail-value">{{ getDictLabel(degree_of_urgency, item.urgency) }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">登记人</text>
|
<text class="detail-value">{{ item.checkNickName }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">问题描述</text>
|
<text class="detail-value">{{ item.disRes }}</text>
|
</view>
|
</view>
|
<up-divider v-if="canEdit(item)"></up-divider>
|
</view>
|
</view>
|
<view v-else class="no-data">
|
<text>暂无售后登记数据</text>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed, onMounted } from 'vue';
|
import { onShow } from '@dcloudio/uni-app';
|
import { afterSalesServiceListPage, afterSalesServiceDelete, getSalesLedgerDetail } from '@/api/customerService/index';
|
import useUserStore from '@/store/modules/user';
|
import PageHeader from '@/components/PageHeader.vue';
|
import { useDict } from '@/utils/dict';
|
|
const userStore = useUserStore();
|
|
// 字典
|
const { post_sale_waiting_list, degree_of_urgency, work_order_status } = useDict(
|
'post_sale_waiting_list',
|
'degree_of_urgency',
|
'work_order_status'
|
);
|
|
const statsList = ref([
|
{
|
icon: 'file-text',
|
count: 0,
|
label: '全部工单',
|
color: '#4080ff',
|
bgColor: '#eaf2ff'
|
},
|
{
|
icon: 'file-text',
|
count: 0,
|
label: '已处理',
|
color: '#ff9a2e',
|
bgColor: '#fff5e6'
|
},
|
{
|
icon: 'account',
|
count: 0,
|
label: '已完成',
|
color: '#00b42a',
|
bgColor: '#e6f7ed'
|
},
|
]);
|
|
const searchForm = reactive({
|
afterSalesServiceNo: '',
|
status: '',
|
urgency: '',
|
serviceType: '',
|
orderNo: '',
|
});
|
|
const tableData = ref([]);
|
const loading = ref(false);
|
const page = reactive({
|
current: 1,
|
size: 20,
|
total: 0,
|
});
|
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
const handleQuery = () => {
|
page.current = 1;
|
getList();
|
};
|
|
const getList = () => {
|
loading.value = true;
|
uni.showLoading({ title: '加载中...' });
|
|
getStats();
|
|
afterSalesServiceListPage({ ...searchForm, ...page })
|
.then((res) => {
|
const records = res?.data?.records ?? res?.records ?? [];
|
const total = res?.data?.total ?? res?.total ?? 0;
|
tableData.value = Array.isArray(records) ? records : [];
|
page.total = Number.isFinite(Number(total)) ? Number(total) : 0;
|
})
|
.finally(() => {
|
loading.value = false;
|
uni.hideLoading();
|
});
|
};
|
|
const getStats = () => {
|
getSalesLedgerDetail({}).then((res) => {
|
if (res.code === 200) {
|
console.log(res.data);
|
const statsData = Array.isArray(res.data) ? res.data : [];
|
statsList.value[0].count = getStatsCountByStatus(statsData, 3) || 0;
|
statsList.value[1].count = getStatsCountByStatus(statsData, 2) || 0;
|
statsList.value[2].count = getStatsCountByStatus(statsData, 1) || 0;
|
}
|
});
|
};
|
|
const getStatsCountByStatus = (list, status) => {
|
if (!Array.isArray(list)) return 0;
|
return list.find((item) => item?.status === status)?.count || 0;
|
};
|
|
const getStatusLabel = (status) => {
|
if (status === 1) return '待处理';
|
if (status === 2) return '已处理';
|
return '未知';
|
};
|
|
const getStatusType = (status) => {
|
if (status === 1) return 'error';
|
if (status === 2) return 'success';
|
return 'info';
|
};
|
|
const getDictLabel = (dict, value) => {
|
if (!dict || !dict.value) return value;
|
const item = dict.value.find(i => i.value == value);
|
return item ? item.label : value;
|
};
|
|
const canEdit = (row) => {
|
if (!row) return false;
|
return row.status === 1 && String(row.checkUserId) === String(userStore.id);
|
}
|
|
const handleRowClick = (row) => {
|
if (canEdit(row)) {
|
openForm('edit', row)
|
return
|
}
|
openForm('view', row)
|
}
|
|
const openForm = (type, row) => {
|
uni.setStorageSync('afterSalesOperationType', type);
|
if (row) {
|
uni.setStorageSync('afterSalesEditData', JSON.stringify(row));
|
} else {
|
uni.removeStorageSync('afterSalesEditData');
|
}
|
uni.navigateTo({
|
url: '/pages/customerService/feedbackRegistration/edit'
|
});
|
};
|
|
const handleDelete = (row) => {
|
if (row.checkUserId !== userStore.id) {
|
uni.showToast({ title: '不可删除他人维护的数据', icon: 'none' });
|
return;
|
}
|
|
uni.showModal({
|
title: '提示',
|
content: '选中的内容将被删除,是否确认删除?',
|
success: (res) => {
|
if (res.confirm) {
|
afterSalesServiceDelete([row.id]).then(() => {
|
uni.showToast({ title: '删除成功', icon: 'success' });
|
getList();
|
});
|
}
|
}
|
});
|
};
|
|
onShow(() => {
|
getList();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/styles/sales-common.scss";
|
|
.after-sales-registration {
|
min-height: 100vh;
|
background: #f8f9fa;
|
}
|
|
.stats-container {
|
display: flex;
|
gap: 10px;
|
padding: 15px 20px;
|
background: #ffffff;
|
}
|
|
.stat-card {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
padding: 12px 10px;
|
background-color: #f8f9fa;
|
border-radius: 8px;
|
}
|
|
.stat-icon {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
width: 36px;
|
height: 36px;
|
border-radius: 6px;
|
}
|
|
.stat-info {
|
display: flex;
|
flex-direction: column;
|
}
|
|
.stat-number {
|
font-size: 16px;
|
font-weight: 600;
|
color: #303133;
|
}
|
|
.stat-label {
|
font-size: 10px;
|
color: #909399;
|
}
|
|
.detail-buttons {
|
display: flex;
|
gap: 10px;
|
justify-content: flex-end;
|
padding: 12px 0;
|
}
|
|
.ledger-item {
|
padding: 0 16px;
|
}
|
</style>
|