Browse Source
feat(sop): 新增SOP管理系统功能
feat(sop): 新增SOP管理系统功能
- 创建了sop.js API文件,提供URL配置和错误详情相关的接口方法 - 实现了URL配置管理功能,包括查询、保存、删除等操作 - 开发了错误详情管理功能,支持错误信息的查看和处理方式编辑 - 构建了自动化仓库SOP管理界面,包含三级级联选择功能 - 添加了平台、模块、功能页面的选择过滤功能 - 实现了错误详情的数据表格展示和分页功能 - 集成了错误类型的分类显示和搜索功能 - 创建了处理方式编辑弹窗,支持默认和用户补充处理方式的修改master
2 changed files with 494 additions and 0 deletions
@ -0,0 +1,47 @@ |
|||||
|
import { createAPI } from "@/utils/httpRequest.js"; |
||||
|
|
||||
|
// ========== URL配置相关 ========== - rqrq
|
||||
|
|
||||
|
// 查询URL配置列表 - rqrq
|
||||
|
export const getUrlConfigList = data => createAPI('/sys/sop/urlConfig/list', 'post', data) |
||||
|
|
||||
|
// 查询所有启用的URL配置(下拉选择)- rqrq
|
||||
|
export const getActiveUrlList = data => createAPI('/sys/sop/urlConfig/activeList', 'post', data) |
||||
|
|
||||
|
// 获取平台列表(PC/PDA)- rqrq
|
||||
|
export const getPlatformList = data => createAPI('/sys/sop/urlConfig/platformList', 'post', data) |
||||
|
|
||||
|
// 根据平台获取模块列表 - rqrq
|
||||
|
export const getModuleListByPlatform = data => createAPI('/sys/sop/urlConfig/moduleList', 'post', data) |
||||
|
|
||||
|
// 根据平台和模块获取功能页面列表 - rqrq
|
||||
|
export const getPageListByPlatformAndModule = data => createAPI('/sys/sop/urlConfig/pageList', 'post', data) |
||||
|
|
||||
|
// 根据URL查询配置 - rqrq
|
||||
|
export const getUrlConfigByUrl = data => createAPI('/sys/sop/urlConfig/getByUrl', 'post', data) |
||||
|
|
||||
|
// 保存URL配置 - rqrq
|
||||
|
export const saveUrlConfig = data => createAPI('/sys/sop/urlConfig/save', 'post', data) |
||||
|
|
||||
|
// 删除URL配置 - rqrq
|
||||
|
export const deleteUrlConfig = data => createAPI('/sys/sop/urlConfig/delete', 'post', data) |
||||
|
|
||||
|
// ========== 错误详情相关 ========== - rqrq
|
||||
|
|
||||
|
// 查询错误详情列表 - rqrq
|
||||
|
export const getErrorDetailList = data => createAPI('/sys/sop/errorDetail/list', 'post', data) |
||||
|
|
||||
|
// 根据URL查询错误详情 - rqrq
|
||||
|
export const getErrorDetailByUrl = data => createAPI('/sys/sop/errorDetail/getByUrl', 'post', data) |
||||
|
|
||||
|
// 根据URL获取按钮列表 - rqrq
|
||||
|
export const getFunctionButtonsByUrl = data => createAPI('/sys/sop/errorDetail/getFunctionButtons', 'post', data) |
||||
|
|
||||
|
// 保存错误详情 - rqrq
|
||||
|
export const saveErrorDetail = data => createAPI('/sys/sop/errorDetail/save', 'post', data) |
||||
|
|
||||
|
// 更新错误详情 - rqrq
|
||||
|
export const updateErrorDetail = data => createAPI('/sys/sop/errorDetail/update', 'post', data) |
||||
|
|
||||
|
// 删除错误详情 - rqrq
|
||||
|
export const deleteErrorDetail = data => createAPI('/sys/sop/errorDetail/delete', 'post', data) |
||||
@ -0,0 +1,447 @@ |
|||||
|
<template> |
||||
|
<div class="mod-config yzz"> |
||||
|
<!-- 查询表单 - rqrq --> |
||||
|
<el-form :inline="true" label-position="top" style="margin-top: 1px; margin-left: 0px;"> |
||||
|
<!-- 三级级联选择:平台 -> 模块 -> 功能页面 - rqrq --> |
||||
|
<el-form-item label="平台"> |
||||
|
<el-select |
||||
|
v-model="queryData.platform" |
||||
|
placeholder="请选择平台" |
||||
|
style="width: 100px" |
||||
|
@change="handlePlatformChange"> |
||||
|
<el-option |
||||
|
v-for="item in platformOptions" |
||||
|
:key="item" |
||||
|
:label="item" |
||||
|
:value="item"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="模块"> |
||||
|
<el-select |
||||
|
v-model="queryData.moduleName" |
||||
|
placeholder="请选择模块" |
||||
|
style="width: 150px" |
||||
|
:disabled="!queryData.platform" |
||||
|
@change="handleModuleChange"> |
||||
|
<el-option |
||||
|
v-for="item in moduleOptions" |
||||
|
:key="item" |
||||
|
:label="item" |
||||
|
:value="item"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="功能页面"> |
||||
|
<el-select |
||||
|
v-model="queryData.url" |
||||
|
placeholder="请选择功能页面" |
||||
|
style="width: 180px" |
||||
|
:disabled="!queryData.moduleName" |
||||
|
@change="handlePageChange"> |
||||
|
<el-option |
||||
|
v-for="item in pageOptions" |
||||
|
:key="item.url" |
||||
|
:label="item.pageName" |
||||
|
:value="item.url"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="按钮/功能"> |
||||
|
<el-select |
||||
|
v-model="queryData.functionButton" |
||||
|
placeholder="全部按钮" |
||||
|
style="width: 150px" |
||||
|
filterable |
||||
|
clearable> |
||||
|
<el-option label="全部按钮" value=""></el-option> |
||||
|
<el-option |
||||
|
v-for="item in buttonOptions" |
||||
|
:key="item" |
||||
|
:label="item" |
||||
|
:value="item"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="错误类型"> |
||||
|
<el-select v-model="queryData.searchErrorType" placeholder="请选择" style="width: 100px" clearable> |
||||
|
<el-option label="全部" value=""></el-option> |
||||
|
<el-option label="后端" value="BACKEND"></el-option> |
||||
|
<el-option label="前端" value="FRONTEND"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label="错误信息"> |
||||
|
<el-input v-model="queryData.searchErrorMessage" style="width: 180px" placeholder="错误信息关键字" clearable></el-input> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<el-form-item label=" "> |
||||
|
<el-button type="primary" @click="getDataList()">查询</el-button> |
||||
|
<el-button @click="resetQuery()">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
|
||||
|
<!-- 当前选中页面信息 - rqrq --> |
||||
|
<div v-if="currentUrlConfig" class="url-info-card"> |
||||
|
<el-card shadow="never"> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span> |
||||
|
<el-tag :type="currentUrlConfig.platform === 'PC' ? 'primary' : 'success'" size="small" style="margin-right: 10px"> |
||||
|
{{ currentUrlConfig.platform }} |
||||
|
</el-tag> |
||||
|
<i class="el-icon-document"></i> |
||||
|
{{ currentUrlConfig.moduleName }} - {{ currentUrlConfig.pageName }} |
||||
|
</span> |
||||
|
</div> |
||||
|
</el-card> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 数据表格 - rqrq --> |
||||
|
<el-table |
||||
|
:data="dataList" |
||||
|
:height="height" |
||||
|
border |
||||
|
highlight-current-row |
||||
|
v-loading="dataListLoading" |
||||
|
style="width: 100%;"> |
||||
|
|
||||
|
<el-table-column prop="functionButton" label="功能/按钮" width="150" header-align="center" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-tag type="primary" size="small">{{ scope.row.functionButton }}</el-tag> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
|
||||
|
<el-table-column prop="seqNo" label="序号" width="60" header-align="center" align="center"></el-table-column> |
||||
|
|
||||
|
<el-table-column prop="errorMessage" label="错误信息" min-width="280" header-align="center" show-overflow-tooltip> |
||||
|
<template slot-scope="scope"> |
||||
|
<span style="color: #F56C6C">{{ scope.row.errorMessage }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
|
||||
|
<el-table-column prop="errorType" label="类型" width="80" header-align="center" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-tag :type="scope.row.errorType === 'BACKEND' ? 'warning' : 'info'" size="mini"> |
||||
|
{{ scope.row.errorType === 'BACKEND' ? '后端' : '前端' }} |
||||
|
</el-tag> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
|
||||
|
<el-table-column prop="errorSource" label="错误来源" width="180" header-align="center" show-overflow-tooltip> |
||||
|
<template slot-scope="scope"> |
||||
|
<span style="color: #909399; font-size: 12px">{{ scope.row.errorSource }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
|
||||
|
<el-table-column prop="defaultSolution" label="默认处理方式" min-width="220" header-align="center" show-overflow-tooltip> |
||||
|
<template slot-scope="scope"> |
||||
|
<span style="color: #67C23A">{{ scope.row.defaultSolution || '-' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
|
||||
|
<el-table-column prop="userSolution" label="用户补充处理方式" min-width="220" header-align="center" show-overflow-tooltip> |
||||
|
<template slot-scope="scope"> |
||||
|
<span style="color: #409EFF">{{ scope.row.userSolution || '-' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
|
||||
|
<!-- 操作列 - rqrq --> |
||||
|
<el-table-column header-align="center" align="center" fixed="right" width="100" label="操作"> |
||||
|
<template slot-scope="scope"> |
||||
|
<a type="text" @click="editSolution(scope.row)">编辑</a> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<!-- 分页 - rqrq --> |
||||
|
<el-pagination |
||||
|
@size-change="sizeChangeHandle" |
||||
|
@current-change="currentChangeHandle" |
||||
|
:current-page="pageIndex" |
||||
|
:page-sizes="[20, 50, 100, 1000]" |
||||
|
:page-size="pageSize" |
||||
|
:total="totalPage" |
||||
|
layout="total, sizes, prev, pager, next, jumper"> |
||||
|
</el-pagination> |
||||
|
|
||||
|
<!-- 编辑处理方式弹窗 - rqrq --> |
||||
|
<el-dialog |
||||
|
title="编辑处理方式" |
||||
|
:visible.sync="editDialogVisible" |
||||
|
:close-on-click-modal="false" |
||||
|
v-drag |
||||
|
width="800px"> |
||||
|
|
||||
|
<el-form :model="editForm" label-position="top" style="margin-top: 1px; margin-left: 0px;"> |
||||
|
<el-row :gutter="20"> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="功能/按钮"> |
||||
|
<el-input v-model="editForm.functionButton" readonly></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="错误类型"> |
||||
|
<el-input v-model="editForm.errorTypeText" readonly></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-row> |
||||
|
<el-col :span="24"> |
||||
|
<el-form-item label="错误信息"> |
||||
|
<el-input type="textarea" :rows="3" resize="none" v-model="editForm.errorMessage" readonly></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-row style="margin-top: 52px"> |
||||
|
<el-col :span="24"> |
||||
|
<el-form-item label="默认处理方式"> |
||||
|
<el-input type="textarea" :rows="4" resize="none" v-model="editForm.defaultSolution" placeholder="请输入默认处理方式"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-row style="margin-top: 70px"> |
||||
|
<el-col :span="24"> |
||||
|
<el-form-item label="用户补充处理方式"> |
||||
|
<el-input type="textarea" :rows="4" resize="none" v-model="editForm.userSolution" placeholder="请输入用户补充处理方式"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
|
||||
|
<div slot="footer" class="dialog-footer" style="margin-top: 70px"> |
||||
|
<el-button type="primary" @click="saveSolution" :disabled="saveLoading"> |
||||
|
{{ saveLoading ? '保存中...' : '保存' }} |
||||
|
</el-button> |
||||
|
<el-button @click="editDialogVisible = false" :disabled="saveLoading">取消</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { |
||||
|
getPlatformList, |
||||
|
getModuleListByPlatform, |
||||
|
getPageListByPlatformAndModule, |
||||
|
getErrorDetailList, |
||||
|
getFunctionButtonsByUrl, |
||||
|
updateErrorDetail |
||||
|
} from "@/api/sys/sop.js" |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
height: 200, |
||||
|
dataListLoading: false, |
||||
|
saveLoading: false, |
||||
|
editDialogVisible: false, |
||||
|
platformOptions: [], |
||||
|
moduleOptions: [], |
||||
|
pageOptions: [], |
||||
|
buttonOptions: [], |
||||
|
currentUrlConfig: null, |
||||
|
queryData: { |
||||
|
platform: '', |
||||
|
moduleName: '', |
||||
|
url: '', |
||||
|
functionButton: '', |
||||
|
searchErrorType: '', |
||||
|
searchErrorMessage: '', |
||||
|
page: 1, |
||||
|
limit: 20 |
||||
|
}, |
||||
|
editForm: { |
||||
|
url: '', |
||||
|
functionButton: '', |
||||
|
seqNo: null, |
||||
|
errorMessage: '', |
||||
|
errorType: '', |
||||
|
errorTypeText: '', |
||||
|
defaultSolution: '', |
||||
|
userSolution: '' |
||||
|
}, |
||||
|
dataList: [], |
||||
|
pageIndex: 1, |
||||
|
pageSize: 20, |
||||
|
totalPage: 0 |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.height = window.innerHeight - 320 |
||||
|
this.loadPlatformOptions() |
||||
|
}, |
||||
|
methods: { |
||||
|
loadPlatformOptions() { |
||||
|
getPlatformList({}).then(({ data }) => { |
||||
|
if (data && data.code == 0) { |
||||
|
this.platformOptions = data.rows || [] |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
handlePlatformChange(platform) { |
||||
|
this.queryData.moduleName = '' |
||||
|
this.queryData.url = '' |
||||
|
this.moduleOptions = [] |
||||
|
this.pageOptions = [] |
||||
|
this.buttonOptions = [] |
||||
|
this.currentUrlConfig = null |
||||
|
this.dataList = [] |
||||
|
this.totalPage = 0 |
||||
|
if (platform) { |
||||
|
getModuleListByPlatform({ platform: platform }).then(({ data }) => { |
||||
|
if (data && data.code == 0) { |
||||
|
this.moduleOptions = data.rows || [] |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
handleModuleChange(moduleName) { |
||||
|
this.queryData.url = '' |
||||
|
this.pageOptions = [] |
||||
|
this.buttonOptions = [] |
||||
|
this.currentUrlConfig = null |
||||
|
this.dataList = [] |
||||
|
this.totalPage = 0 |
||||
|
if (moduleName) { |
||||
|
getPageListByPlatformAndModule({ |
||||
|
platform: this.queryData.platform, |
||||
|
moduleName: moduleName |
||||
|
}).then(({ data }) => { |
||||
|
if (data && data.code == 0) { |
||||
|
this.pageOptions = data.rows || [] |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
handlePageChange(url) { |
||||
|
this.buttonOptions = [] |
||||
|
if (url) { |
||||
|
this.currentUrlConfig = this.pageOptions.find(item => item.url === url) |
||||
|
this.loadButtonOptions(url) |
||||
|
this.getDataList() |
||||
|
} else { |
||||
|
this.currentUrlConfig = null |
||||
|
this.dataList = [] |
||||
|
this.totalPage = 0 |
||||
|
} |
||||
|
}, |
||||
|
loadButtonOptions(url) { |
||||
|
getFunctionButtonsByUrl({ url: url }).then(({ data }) => { |
||||
|
if (data && data.code == 0) { |
||||
|
this.buttonOptions = data.rows || [] |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
getDataList() { |
||||
|
if (!this.queryData.url) { |
||||
|
this.$message.warning('请先选择功能页面') |
||||
|
return |
||||
|
} |
||||
|
this.dataListLoading = true |
||||
|
this.queryData.page = this.pageIndex |
||||
|
this.queryData.limit = this.pageSize |
||||
|
getErrorDetailList(this.queryData).then(({ data }) => { |
||||
|
this.dataListLoading = false |
||||
|
if (data && data.code == 0) { |
||||
|
this.dataList = data.rows || [] |
||||
|
this.totalPage = data.total || 0 |
||||
|
} else { |
||||
|
this.dataList = [] |
||||
|
this.totalPage = 0 |
||||
|
this.$alert(data.msg || '查询失败', '错误', { confirmButtonText: '确定' }) |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.dataListLoading = false |
||||
|
this.$alert('查询失败', '错误', { confirmButtonText: '确定' }) |
||||
|
}) |
||||
|
}, |
||||
|
resetQuery() { |
||||
|
this.queryData = { |
||||
|
platform: '', |
||||
|
moduleName: '', |
||||
|
url: '', |
||||
|
functionButton: '', |
||||
|
searchErrorType: '', |
||||
|
searchErrorMessage: '', |
||||
|
page: 1, |
||||
|
limit: 20 |
||||
|
} |
||||
|
this.moduleOptions = [] |
||||
|
this.pageOptions = [] |
||||
|
this.buttonOptions = [] |
||||
|
this.currentUrlConfig = null |
||||
|
this.dataList = [] |
||||
|
this.totalPage = 0 |
||||
|
this.pageIndex = 1 |
||||
|
}, |
||||
|
editSolution(row) { |
||||
|
this.editForm = { |
||||
|
url: row.url, |
||||
|
functionButton: row.functionButton, |
||||
|
seqNo: row.seqNo, |
||||
|
errorMessage: row.errorMessage, |
||||
|
errorType: row.errorType, |
||||
|
errorTypeText: row.errorType === 'BACKEND' ? '后端' : '前端', |
||||
|
defaultSolution: row.defaultSolution || '', |
||||
|
userSolution: row.userSolution || '' |
||||
|
} |
||||
|
this.editDialogVisible = true |
||||
|
}, |
||||
|
saveSolution() { |
||||
|
this.saveLoading = true |
||||
|
const updateData = { |
||||
|
url: this.editForm.url, |
||||
|
functionButton: this.editForm.functionButton, |
||||
|
seqNo: this.editForm.seqNo, |
||||
|
defaultSolution: this.editForm.defaultSolution, |
||||
|
userSolution: this.editForm.userSolution, |
||||
|
errorMessage: this.editForm.errorMessage, |
||||
|
errorType: this.editForm.errorType, |
||||
|
isActive: 'Y' |
||||
|
} |
||||
|
updateErrorDetail(updateData).then(({ data }) => { |
||||
|
if (data && data.code == 0) { |
||||
|
this.$message.success('保存成功') |
||||
|
this.editDialogVisible = false |
||||
|
this.getDataList() |
||||
|
} else { |
||||
|
this.$alert(data.msg || '保存失败', '错误', { confirmButtonText: '确定' }) |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.$alert('保存失败', '错误', { confirmButtonText: '确定' }) |
||||
|
}).finally(() => { |
||||
|
this.saveLoading = false |
||||
|
}) |
||||
|
}, |
||||
|
sizeChangeHandle(val) { |
||||
|
this.pageSize = val |
||||
|
this.pageIndex = 1 |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
currentChangeHandle(val) { |
||||
|
this.pageIndex = val |
||||
|
this.getDataList() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.url-info-card { |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
.url-info-card /deep/ .el-card__header { |
||||
|
padding: 10px 15px; |
||||
|
background-color: #f5f7fa; |
||||
|
} |
||||
|
.url-info-card /deep/ .el-card__body { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue