减少冗余代码

This commit is contained in:
2026-05-14 15:41:00 +08:00
parent ae4cf4540b
commit fa0c718c8b
15 changed files with 802 additions and 439 deletions

View File

@@ -53,11 +53,18 @@
<div class="left">
<el-button type="primary" @click="handleAdd" :icon="Plus">新增任务</el-button>
</div>
<TicketFilter :operators="operatorsForFilter" :staffs="staffList" :filters="filters"
<TicketFilter :operators="operatorsForFilter" :staffs="userStaffList" :filters="filters"
@filter-change="handleFilterChange" @reset="handleFilterReset" />
</div>
<TicketList :tickets="tickets" :loading="loading" @edit="handleEdit" @delete="handleDelete" />
<div class="batch-bar" v-if="selectedTickets.length">
<span class="batch-info">已选 <strong>{{ selectedTickets.length }}</strong> 个工单</span>
<el-button type="warning" @click="handleBatchFinish">一键已完结</el-button>
<el-button link type="info" @click="ticketListRef.clearSelection()">取消选择</el-button>
</div>
<TicketList ref="ticketListRef" :tickets="tickets" :loading="loading" @edit="handleEdit" @delete="handleDelete"
@selection-change="val => selectedTickets = val" />
<div class="pagination-container">
<el-pagination v-model:current-page="pagination.page" v-model:page-size="pagination.limit"
@@ -66,14 +73,13 @@
</div>
</div>
<TicketForm v-model="showAddDialog" :form-data="currentTicket" :customers="customerList"
:customer-employees="allCustomerEmployees" :staffs="staffList" :is-editing="isEditing"
@submit="handleFormSubmit" />
<TicketForm v-model="showAddDialog" :form-data="currentTicket" :companiesWithOperators="companywithoperatorsList"
:user-staffs="userStaffList" :is-editing="isEditing" @submit="handleFormSubmit" />
</div>
</template>
<script setup>
import { ref, reactive, onMounted, computed } from "vue";
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
Plus,
@@ -85,7 +91,7 @@ import {
} from "@element-plus/icons-vue";
// API 引入
import { ticketApi, customerApi } from "@/api/ticket";
import { ticketApi } from "@/api/ticket";
// 组件引入
import TicketFilter from "@/components/ticket/TicketFilter.vue";
@@ -94,14 +100,16 @@ import TicketForm from "@/components/ticket/TicketForm.vue";
// --- 响应式状态 ---
const tickets = ref([]);
const operators = ref([]);
const staffList = ref([]);
const customerList = ref([]);
const allCustomerEmployees = ref([]);
const userStaffList = ref([]);
const companywithoperatorsList = ref([]);
const loading = ref(false);
const showAddDialog = ref(false);
const isEditing = ref(false);
const currentTicket = ref({});
const selectedTickets = ref([]);
const ticketListRef = ref(null);
const operatorsForFilter = ref([]);
const allStats = reactive({
total: 0,
@@ -119,54 +127,56 @@ const pagination = reactive({
const filters = reactive({
status: null,
operator_name: null,
staff_id: null,
operator_id: null,
user_id: null,
search: null,
sort_order: "desc",
});
// --- 核心数据加载方法 ---
/* 获取运营人员数据的方法*/
// 在 TicketManagement.vue 中利用 computed 提取
const operatorsForFilter = computed(() => {
// 返回包含 ID、姓名和公司名的对象数组
return allCustomerEmployees.value.map((emp) => {
// 在 allCustomers 中找到该员工所属的公司名
const company = customerList.value.find((c) => c.customer_id === emp.customer_id);
return {
id: emp.employee_id,
name: emp.employee_name,
company: company ? company.company_name : "未知单位",
};
});
});
/**
* 加载客户单位及对应员工数据
* 根据你提供的接口返回结构进行了适配
*/
const loadCustomerData = async () => {
const fetchOperatorsForFilter = async () => {
try {
const res = await customerApi.getCustomers();
// 适配点:根据返回的 code: 200 逻辑进行判断
if (res.code === 200) {
// 适配点:直接从 res 中获取 customers 和 employees 数组
customerList.value = res.customers || [];
allCustomerEmployees.value = res.employees || [];
const response = await ticketApi.getOperatorsNew();
if (response.code === 200) {
// 将新的嵌套数据结构转换为原来的扁平格式
operatorsForFilter.value = response.data.flatMap(company =>
company.companyoperators.map(op => ({
id: op.id,
operator_name: op.operator_name,
company_name: company.company_name
}))
);
}
} catch (error) {
console.error("获取客户数据失败:", error);
console.error("获取运营人员数据失败:", error);
}
};
/**
* 加载客户单位and运营人员
*/
const loadCompanyWithOperatorsData = async () => {
try {
const res = await ticketApi.getOperatorsNew();
if (res.code === 200) {
companywithoperatorsList.value = res.data || [];
}
} catch (error) {
console.error("获取客户及其运营人员数据失败:", error);
}
};
/**
* 加载我方员工列表
*/
const loadStaffData = async () => {
const loadUserStaffData = async () => {
try {
const res = await ticketApi.getStaffs();
if (res.code) {
staffList.value = res.data;
const res = await ticketApi.getUserStaffs();
if (res.code === 200) {
userStaffList.value = res.data;
}
} catch (error) {
console.error("获取我方员工列表失败:", error);
@@ -178,13 +188,26 @@ const loadStaffData = async () => {
*/
const initGlobalStats = async () => {
try {
const response = await ticketApi.getticketsstatuscount();
if (response.code) {
allStats.total = response.data["total"];
allStats.pending = response.data["pending"];
allStats.ongoing = response.data["ongoing"];
allStats.completed = response.data["completed"];
allStats.is_completed = response.data["is_completed"];
const response = await ticketApi.getticketdashboardstats();
if (response.code === 200) {
allStats.total = response.data.total;
const statusCounts = response.data.status_counts || [];
statusCounts.forEach((item) => {
switch (item.status) {
case 0:
allStats.pending = item.count;
break;
case 1:
allStats.ongoing = item.count;
break;
case 2:
allStats.completed = item.count;
break;
case 3:
allStats.is_completed = item.count;
break;
}
});
}
} catch (error) {
console.error("统计全局数据失败:", error);
@@ -224,18 +247,20 @@ const refreshAll = () => {
const handleFilterChange = (newFilters) => {
Object.assign(filters, newFilters);
pagination.page = 1;
selectedTickets.value = [];
loadTickets();
};
const handleFilterReset = () => {
Object.assign(filters, {
status: null,
operator_name: null,
staff_id: null,
operator_id: null,
user_id: null,
search: null,
sort_order: "desc",
});
pagination.page = 1;
selectedTickets.value = [];
loadTickets();
};
@@ -289,7 +314,6 @@ const handleDelete = async (id) => {
cancelButtonText: "取消",
});
const res = await ticketApi.deleteTicket(id);
// console.log('删除',res)
if (res.code) {
ElMessage.success("删除成功");
refreshAll();
@@ -299,15 +323,28 @@ const handleDelete = async (id) => {
}
};
// 加载所有运营人员
const loadOperators = async () => {
const handleBatchFinish = async () => {
const ids = selectedTickets.value.map((t) => t.id);
try {
const response = await ticketApi.getOperators();
if (response.code) {
operators.value = response.data;
await ElMessageBox.confirm(
`确认将选中的 ${ids.length} 个工单一键已完结?`,
"批量操作",
{ type: "warning", confirmButtonText: "确认已完结" }
);
const res = await ticketApi.batchUpdateTicket({
ids,
status: "已完结",
remark: "批量结单",
});
if (res.code === 200) {
ElMessage.success(res.data?.msg || `成功完结 ${ids.length} 个工单`);
ticketListRef.value.clearSelection();
refreshAll();
} else {
ElMessage.error(res.msg || "批量操作失败");
}
} catch (error) {
console.error("获取运营人员筛选列表失败:", error);
if (error !== "cancel") ElMessage.error("批量操作失败");
}
};
@@ -315,17 +352,18 @@ const handleSizeChange = (val) => {
pagination.limit = val;
loadTickets();
};
const handleCurrentChange = (val) => {
pagination.page = val;
loadTickets();
};
onMounted(() => {
fetchOperatorsForFilter();
loadTickets();
initGlobalStats();
loadOperators();
loadStaffData();
loadCustomerData(); // 级联数据加载
loadUserStaffData();
loadCompanyWithOperatorsData();
});
</script>
@@ -445,6 +483,22 @@ onMounted(() => {
margin-bottom: 20px;
}
.batch-bar {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 16px;
margin-bottom: 12px;
background: #fdf6ec;
border: 1px solid #faecd8;
border-radius: 8px;
}
.batch-info {
font-size: 13px;
color: #606266;
}
.pagination-container {
margin-top: 20px;
display: flex;