first commit

This commit is contained in:
2025-12-02 18:21:41 +08:00
commit 19c008a401
21 changed files with 4430 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
<template>
<div class="ticket-management">
<!-- 操作栏 -->
<div class="action-bar">
<el-button type="primary" @click="showAddDialog = true" :icon="Plus">
新增工单
</el-button>
<div class="stats">
<el-statistic title="总工单数" :value="totalTickets" />
<el-statistic title="未完成" :value="pendingCount" />
<el-statistic title="正在进行" :value="ongoingCount" />
<el-statistic title="已完成" :value="completedCount" />
<el-statistic title="已完结" :value="iscompleteCount" />
</div>
</div>
<!-- 筛选组件 -->
<TicketFilter :filters="filters" :operators="operators" @filter-change="handleFilterChange"
@reset="handleFilterReset" />
<!-- 工单列表 -->
<TicketList :tickets="tickets" :loading="loading" @edit="handleEdit" @delete="handleDelete" />
<!-- 分页 -->
<div class="pagination">
<el-pagination v-model:current-page="pagination.page" v-model:page-size="pagination.limit"
:total="pagination.total" :page-sizes="[10, 15, 20, 50]"
layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
<!-- 新增/编辑对话框 -->
<TicketForm v-model="showAddDialog" :form-data="currentTicket" :operators="operators" :is-editing="isEditing"
@submit="handleFormSubmit" />
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue' // 引入plus图标
import { ticketApi } from '@/api/ticket'
import TicketFilter from '@/components/TicketFilter.vue'
import TicketList from '@/components/TicketList.vue'
import TicketForm from '@/components/TicketForm.vue'
// 响应式数据
const tickets = ref([])
const operators = ref([])
const loading = ref(false)
const showAddDialog = ref(false)
const isEditing = ref(false)
const currentTicket = ref({})
// 分页和筛选
const pagination = reactive({
page: 1,
limit: 15,
total: 0
})
const filters = reactive({
status: null,
operator_name: null,
principalpeople: null,
search: null,
sort_order: 'desc'
})
// 计算属性
const totalTickets = computed(() => tickets.value.length)
const pendingCount = computed(() => tickets.value.filter(t => t.is_complete==='未分配').length)
const ongoingCount = computed(() => tickets.value.filter(t => t.is_complete==='未分配').length)
const completedCount = computed(() => tickets.value.filter(t => t.is_complete==='已完成').length)
const iscompleteCount = computed(() => tickets.value.filter(t => t.is_complete==='已完结').length)
// 方法
const loadTickets = async () => {
loading.value = true
try {
const params = {
page: pagination.page,
limit: pagination.limit,
...filters
}
const response = await ticketApi.getTickets(params)
const { code, msg, data } = response.data
console.log('对象值:', code)
if (code) {
tickets.value = data.data
console.log(`成功加载 ${tickets.value.length} 条数据`)
pagination.total = data.total
} else {
ElMessage.error(msg || '获取工单列表失败')
}
} catch (error) {
ElMessage.error('网络错误,请稍后重试')
} finally {
loading.value = false
}
}
const loadOperators = async () => {
try {
const response = await ticketApi.getOperators()
if (response.code) {
operators.value = response.data
}
} catch (error) {
console.error('获取运营人员列表失败:', error)
}
}
const handleFilterChange = (newFilters) => {
Object.assign(filters, newFilters)
pagination.page = 1
loadTickets()
}
const handleFilterReset = () => {
Object.assign(filters, {
status: null,
operator_name: null,
principalpeople: null,
search: null,
sort_order: 'desc'
})
pagination.page = 1
loadTickets()
}
const handleEdit = (ticket) => {
currentTicket.value = { ...ticket }
isEditing.value = true
showAddDialog.value = true
}
const handleDelete = async (id) => {
try {
await ElMessageBox.confirm('确定要删除这个工单吗?', '警告', {
type: 'warning'
})
const response = await ticketApi.deleteTicket(id)
if (response.code) {
ElMessage.success('删除成功')
loadTickets()
} else {
ElMessage.error(response.msg || '删除失败')
}
} catch (error) {
// 用户取消删除
}
}
const handleFormSubmit = async (formData) => {
try {
let response
if (isEditing.value) {
response = await ticketApi.updateTicket(currentTicket.value.id, formData)
} else {
response = await ticketApi.addTicket(formData)
}
if (response.code) {
ElMessage.success(isEditing.value ? '更新成功' : '新增成功')
showAddDialog.value = false
resetForm()
loadTickets()
} else {
ElMessage.error(response.msg || '操作失败')
}
} catch (error) {
ElMessage.error('网络错误,请稍后重试')
}
}
const resetForm = () => {
currentTicket.value = {}
isEditing.value = false
}
const handleSizeChange = (newSize) => {
pagination.limit = newSize
pagination.page = 1
loadTickets()
}
const handleCurrentChange = (newPage) => {
pagination.page = newPage
loadTickets()
}
// 生命周期
onMounted(() => {
loadTickets()
loadOperators()
})
</script>
<style scoped>
.ticket-management {
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.action-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #ebeef5;
}
.stats {
display: flex;
gap: 30px;
text-align: center;
}
.pagination {
margin-top: 20px;
display: flex;
justify-content: center;
}
</style>