小程序工单设备代码传入
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
// 全局EL分页组件样式
|
||||
|
||||
// ==================== 品牌色变量 ====================
|
||||
$brand-color: #0055AA;
|
||||
$brand-color-light: #EBF5FF;
|
||||
$brand-color-hover: #004488;
|
||||
|
||||
.content-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -190,11 +195,32 @@
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
// 分页样式
|
||||
.table-pagination {
|
||||
margin-top: 12px;
|
||||
padding: 16px 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
// 全局分页样式(不需要 :deep,因为这是全局样式)
|
||||
.el-pagination {
|
||||
.el-pager {
|
||||
li {
|
||||
border-radius: 6px;
|
||||
|
||||
&.is-active {
|
||||
background: $brand-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-prev,
|
||||
.btn-next {
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.file-name-cell {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AdminLayout title="工单日志" info="查看工单操作记录">
|
||||
<AdminLayout title="工单日志" info="查看工单流程处理记录">
|
||||
<template #action>
|
||||
<el-button type="primary" @click="exportLogs">
|
||||
<el-icon><Download /></el-icon>
|
||||
@@ -11,46 +11,48 @@
|
||||
<!-- 筛选区域 -->
|
||||
<el-card class="filter-card">
|
||||
<div class="ticket-filters">
|
||||
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" style="width: 280px;" />
|
||||
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" style="width: 280px;" @change="handleSearch" />
|
||||
|
||||
<div class="filter-right">
|
||||
<el-select v-model="operationFilter" placeholder="操作类型" clearable style="width: 140px;">
|
||||
<el-option label="创建" value="create" />
|
||||
<el-option label="更新" value="update" />
|
||||
<el-option label="指派" value="assign" />
|
||||
<el-option label="完成" value="complete" />
|
||||
<el-option label="关闭" value="close" />
|
||||
<el-select v-model="filter.action" placeholder="操作类型" clearable style="width: 140px;" @change="handleSearch">
|
||||
<el-option v-for="item in actionOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<el-select v-model="operatorFilter" placeholder="操作人" clearable style="width: 120px;">
|
||||
<el-option label="王五" value="wangwu" />
|
||||
<el-option label="赵六" value="zhaoliu" />
|
||||
<el-option label="孙七" value="sunqi" />
|
||||
</el-select>
|
||||
<el-input v-model="searchKeyword" placeholder="搜索工单号/内容" style="width: 200px;" :prefix-icon="Search" clearable />
|
||||
<el-input v-model="filter.workcaseId" placeholder="搜索工单ID" style="width: 200px;" :prefix-icon="Search" clearable @keyup.enter="handleSearch" @clear="handleSearch" />
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 日志列表 -->
|
||||
<el-card>
|
||||
<el-table :data="filteredLogs" style="width: 100%">
|
||||
<el-table-column prop="logId" label="日志ID" width="120">
|
||||
<el-table :data="processLogs" style="width: 100%" v-loading="loading">
|
||||
<el-table-column prop="processId" label="流程ID" width="180">
|
||||
<template #default="{ row }">
|
||||
<span style="color: #409eff; font-weight: 500;">{{ row.logId }}</span>
|
||||
<span style="color: #409eff; font-weight: 500;">{{ row.processId }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ticketNo" label="工单号" width="120" />
|
||||
<el-table-column prop="operation" label="操作类型" width="100">
|
||||
<el-table-column prop="workcaseId" label="工单ID" width="180" />
|
||||
<el-table-column prop="action" label="操作类型" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getOperationType(row.operation)" size="small">
|
||||
{{ row.operationName }}
|
||||
<el-tag :type="getActionTagType(row.action)" size="small">
|
||||
{{ getActionLabel(row.action) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operator" label="操作人" width="100" />
|
||||
<el-table-column prop="content" label="操作内容" min-width="200" />
|
||||
<el-table-column prop="operationTime" label="操作时间" width="160" />
|
||||
<el-table-column prop="ipAddress" label="IP地址" width="130" />
|
||||
<el-table-column prop="message" label="操作内容" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="processor" label="处理人" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.processor || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="files" label="附件" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.files?.length" size="small" type="info">{{ row.files.length }}个</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="creator" label="操作人" width="120" />
|
||||
<el-table-column prop="createTime" label="操作时间" width="170" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="viewDetail(row)">详情</el-button>
|
||||
@@ -59,99 +61,154 @@
|
||||
</el-table>
|
||||
|
||||
<div class="table-pagination">
|
||||
<el-pagination v-model:current-page="currentPage" :page-size="10" :total="logs.length" layout="total, prev, pager, next" />
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.current"
|
||||
v-model:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
@size-change="handleSearch"
|
||||
@current-change="handleSearch"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 日志详情弹窗 -->
|
||||
<el-dialog v-model="showDetailDialog" title="日志详情" width="600px">
|
||||
<el-form v-if="selectedLog" label-width="100px">
|
||||
<el-form-item label="日志ID">
|
||||
<span>{{ selectedLog.logId }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="工单号">
|
||||
<span>{{ selectedLog.ticketNo }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型">
|
||||
<el-tag :type="getOperationType(selectedLog.operation)">{{ selectedLog.operationName }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作人">
|
||||
<span>{{ selectedLog.operator }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作内容">
|
||||
<span>{{ selectedLog.content }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作时间">
|
||||
<span>{{ selectedLog.operationTime }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="IP地址">
|
||||
<span>{{ selectedLog.ipAddress }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog v-model="showDetailDialog" title="流程详情" width="600px">
|
||||
<el-descriptions v-if="selectedLog" :column="1" border>
|
||||
<el-descriptions-item label="流程ID">{{ selectedLog.processId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="工单ID">{{ selectedLog.workcaseId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="操作类型">
|
||||
<el-tag :type="getActionTagType(selectedLog.action)">{{ getActionLabel(selectedLog.action) }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="操作内容">{{ selectedLog.message || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="处理人">{{ selectedLog.processor || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="操作人">{{ selectedLog.creator }}</el-descriptions-item>
|
||||
<el-descriptions-item label="操作时间">{{ selectedLog.createTime }}</el-descriptions-item>
|
||||
<el-descriptions-item v-if="selectedLog.files?.length" label="附件">
|
||||
<div class="file-list">
|
||||
<el-tag v-for="(file, index) in selectedLog.files" :key="index" size="small" style="margin-right: 8px; margin-bottom: 4px;">
|
||||
{{ file }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
</AdminLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import AdminLayout from '@/views/admin/AdminLayout.vue'
|
||||
import { Download, Search } from 'lucide-vue-next'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { workcaseAPI } from '@/api/workcase'
|
||||
import type { TbWorkcaseProcessDTO } from '@/types/workcase'
|
||||
import type { PageRequest, PageParam } from 'shared/types'
|
||||
|
||||
const dateRange = ref<[Date, Date] | null>(null)
|
||||
const operationFilter = ref('')
|
||||
const operatorFilter = ref('')
|
||||
const searchKeyword = ref('')
|
||||
const currentPage = ref(1)
|
||||
// 操作类型选项
|
||||
const actionOptions = [
|
||||
{ value: 'info', label: '记录' },
|
||||
{ value: 'assign', label: '指派' },
|
||||
{ value: 'redeploy', label: '转派' },
|
||||
{ value: 'repeal', label: '撤销' },
|
||||
{ value: 'finish', label: '完成' }
|
||||
]
|
||||
|
||||
// 状态
|
||||
const loading = ref(false)
|
||||
const dateRange = ref<[string, string] | null>(null)
|
||||
const showDetailDialog = ref(false)
|
||||
const selectedLog = ref<any>(null)
|
||||
const selectedLog = ref<TbWorkcaseProcessDTO | null>(null)
|
||||
const processLogs = ref<TbWorkcaseProcessDTO[]>([])
|
||||
|
||||
const logs = ref([
|
||||
{ logId: 'LOG001', ticketNo: 'TK001', operation: 'create', operationName: '创建', operator: '王五', content: '创建工单,客户反映设备显示屏不亮', operationTime: '2024-12-13 10:30', ipAddress: '192.168.1.100' },
|
||||
{ logId: 'LOG002', ticketNo: 'TK001', operation: 'assign', operationName: '指派', operator: '赵六', content: '将工单指派给技术人员处理', operationTime: '2024-12-13 10:35', ipAddress: '192.168.1.101' },
|
||||
{ logId: 'LOG003', ticketNo: 'TK002', operation: 'create', operationName: '创建', operator: '孙七', content: '创建工单,客户反映机械故障', operationTime: '2024-12-13 09:15', ipAddress: '192.168.1.102' },
|
||||
{ logId: 'LOG004', ticketNo: 'TK002', operation: 'update', operationName: '更新', operator: '王五', content: '更新工单状态为处理中', operationTime: '2024-12-13 09:45', ipAddress: '192.168.1.100' },
|
||||
{ logId: 'LOG005', ticketNo: 'TK003', operation: 'complete', operationName: '完成', operator: '赵六', content: '工单处理完成,客户已确认', operationTime: '2024-12-12 14:20', ipAddress: '192.168.1.101' }
|
||||
])
|
||||
|
||||
const filteredLogs = computed(() => {
|
||||
let result = logs.value
|
||||
if (operationFilter.value) {
|
||||
result = result.filter(l => l.operation === operationFilter.value)
|
||||
}
|
||||
if (operatorFilter.value) {
|
||||
result = result.filter(l => l.operator === operatorFilter.value)
|
||||
}
|
||||
if (searchKeyword.value) {
|
||||
const keyword = searchKeyword.value.toLowerCase()
|
||||
result = result.filter(l =>
|
||||
l.ticketNo.toLowerCase().includes(keyword) ||
|
||||
l.content.toLowerCase().includes(keyword)
|
||||
)
|
||||
}
|
||||
return result.slice((currentPage.value - 1) * 10, currentPage.value * 10)
|
||||
// 筛选条件
|
||||
const filter = reactive<TbWorkcaseProcessDTO>({
|
||||
workcaseId: '',
|
||||
action: undefined
|
||||
})
|
||||
|
||||
const getOperationType = (operation: string) => {
|
||||
// 分页
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 获取操作类型标签
|
||||
const getActionLabel = (action?: string) => {
|
||||
const map: Record<string, string> = {
|
||||
create: 'success',
|
||||
update: 'info',
|
||||
assign: 'warning',
|
||||
complete: 'success',
|
||||
close: 'danger'
|
||||
info: '记录',
|
||||
assign: '指派',
|
||||
redeploy: '转派',
|
||||
repeal: '撤销',
|
||||
finish: '完成'
|
||||
}
|
||||
return map[operation] || 'info'
|
||||
return map[action || ''] || action || '-'
|
||||
}
|
||||
|
||||
const viewDetail = (row: any) => {
|
||||
// 获取操作类型标签样式
|
||||
const getActionTagType = (action?: string) => {
|
||||
const map: Record<string, string> = {
|
||||
info: 'info',
|
||||
assign: 'warning',
|
||||
redeploy: '',
|
||||
repeal: 'danger',
|
||||
finish: 'success'
|
||||
}
|
||||
return map[action || ''] || 'info'
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
const handleSearch = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const filterData: TbWorkcaseProcessDTO = { ...filter }
|
||||
|
||||
// 日期范围
|
||||
if (dateRange.value) {
|
||||
filterData.startTime = dateRange.value[0]
|
||||
filterData.endTime = dateRange.value[1]
|
||||
}
|
||||
|
||||
const pageParam: PageParam = {
|
||||
pageNumber: pagination.current,
|
||||
pageSize: pagination.size
|
||||
}
|
||||
|
||||
const pageRequest: PageRequest<TbWorkcaseProcessDTO> = {
|
||||
filter: filterData,
|
||||
pageParam
|
||||
}
|
||||
|
||||
const res = await workcaseAPI.getWorkcaseProcessPage(pageRequest)
|
||||
if (res.success) {
|
||||
processLogs.value = res.dataList || res.pageDomain?.dataList || []
|
||||
pagination.total = res.pageDomain?.pageParam?.totalElements || 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询工单流程失败:', error)
|
||||
ElMessage.error('查询失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const viewDetail = (row: TbWorkcaseProcessDTO) => {
|
||||
selectedLog.value = row
|
||||
showDetailDialog.value = true
|
||||
}
|
||||
|
||||
// 导出日志
|
||||
const exportLogs = () => {
|
||||
ElMessage.success('日志导出成功')
|
||||
ElMessage.success('日志导出功能开发中')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleSearch()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -162,4 +219,9 @@ const exportLogs = () => {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
.file-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -247,32 +247,6 @@ $brand-color-hover: #004488;
|
||||
}
|
||||
}
|
||||
|
||||
// 分页样式
|
||||
.table-pagination {
|
||||
padding: 16px 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-pagination) {
|
||||
.el-pager {
|
||||
li {
|
||||
border-radius: 6px;
|
||||
|
||||
&.is-active {
|
||||
background: $brand-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-prev,
|
||||
.btn-next {
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
// 弹窗样式
|
||||
:deep(.el-dialog) {
|
||||
|
||||
Reference in New Issue
Block a user