Browse Source
feat(mes): 新增MES TID EPC日志管理功能
feat(mes): 新增MES TID EPC日志管理功能
- 创建MES TID EPC日志API接口,包括查询、导入、导出、删除等功能 - 开发TID EPC日志管理页面,实现分页查询和表格展示 - 添加Excel导入功能,支持批量导入TID EPC数据 - 实现数据导出功能,支持按条件导出日志数据 - 集成BU站点选择功能,支持按站点和BU进行数据过滤 - 添加批量删除功能,支持多选删除日志记录 - 实现完整的CRUD操作界面,包含搜索、分页、导入导出等交互功能master
2 changed files with 538 additions and 0 deletions
@ -0,0 +1,41 @@ |
|||
/** |
|||
* MES TID EPC日志API - rqrq |
|||
* @author rqrq |
|||
* @date 2025/01/30 |
|||
*/ |
|||
import { createAPI } from "@/utils/httpRequest.js"; |
|||
|
|||
// ================= 查询 =================
|
|||
|
|||
/** |
|||
* 分页查询日志列表 - rqrq |
|||
* @param data 查询条件 |
|||
*/ |
|||
export const searchList = data => createAPI(`/pms/mesTidEpcLog/searchList`, 'post', data) |
|||
|
|||
/** |
|||
* 导出数据列表 - rqrq |
|||
* @param data 查询条件 |
|||
*/ |
|||
export const getExportList = data => createAPI(`/pms/mesTidEpcLog/getExportList`, 'post', data) |
|||
|
|||
// ================= 导入 =================
|
|||
|
|||
/** |
|||
* 导入Excel数据 - rqrq |
|||
* @param data FormData对象 |
|||
*/ |
|||
export const importExcel = data => createAPI(`/pms/mesTidEpcLog/importExcel`, 'post', data) |
|||
|
|||
/** |
|||
* 下载导入模板 - rqrq |
|||
*/ |
|||
export const downloadTemplate = () => createAPI(`/pms/mesTidEpcLog/downloadTemplate`, 'get', null, 'download') |
|||
|
|||
// ================= 删除 =================
|
|||
|
|||
/** |
|||
* 删除日志数据 - rqrq |
|||
* @param data ID数组 |
|||
*/ |
|||
export const deleteData = data => createAPI(`/pms/mesTidEpcLog/delete`, 'post', data) |
|||
@ -0,0 +1,497 @@ |
|||
<template> |
|||
<div class="mod-config"> |
|||
<!-- 查询表单 - rqrq --> |
|||
<el-form :inline="true" label-position="top" :model="searchData"> |
|||
<el-form-item :label="'序号'"> |
|||
<el-input v-model="searchData.searchSeqNo" clearable style="width: 120px"></el-input> |
|||
</el-form-item> |
|||
<el-form-item :label="'EPC'"> |
|||
<el-input v-model="searchData.searchEpc" clearable style="width: 200px"></el-input> |
|||
</el-form-item> |
|||
<el-form-item :label="'TID'"> |
|||
<el-input v-model="searchData.searchTid" clearable style="width: 200px"></el-input> |
|||
</el-form-item> |
|||
<el-form-item :label="'用户区'"> |
|||
<el-input v-model="searchData.searchUserArea" clearable style="width: 150px"></el-input> |
|||
</el-form-item> |
|||
<el-form-item :label="'批次号'"> |
|||
<el-input v-model="searchData.searchBatchNo" clearable style="width: 140px"></el-input> |
|||
</el-form-item> |
|||
</el-form> |
|||
<el-form :inline="true" label-position="top" :model="searchData"> |
|||
<el-form-item :label="'扫描时间'"> |
|||
<el-date-picker style="width: 170px" v-model="searchData.scanTimeStart" type="datetime" value-format='yyyy-MM-dd HH:mm:ss' format='yyyy-MM-dd HH:mm:ss' placeholder="开始日期"></el-date-picker> |
|||
- |
|||
<el-date-picker style="width: 170px" v-model="searchData.scanTimeEnd" type="datetime" value-format='yyyy-MM-dd HH:mm:ss' format='yyyy-MM-dd HH:mm:ss' placeholder="结束日期"></el-date-picker> |
|||
</el-form-item> |
|||
<el-form-item :label="' '"> |
|||
<el-button type="primary" @click="getDataList()" :loading="dataListLoading">查询</el-button> |
|||
<el-button type="primary" @click="openImportModal()">导入</el-button> |
|||
<download-excel |
|||
:fields="fields()" |
|||
:data="exportData" |
|||
type="xls" |
|||
:name="exportName" |
|||
:header="exportHeader" |
|||
:footer="exportFooter" |
|||
:fetch="createExportData" |
|||
:before-generate="startDownload" |
|||
:before-finish="finishDownload" |
|||
worksheet="TID_EPC日志" |
|||
class="el-button el-button--primary el-button--medium"> |
|||
{{ "导出" }} |
|||
</download-excel> |
|||
<el-button type="danger" @click="deleteData()" :disabled="selectedList.length === 0">删除</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
|
|||
<!-- 主表格 - rqrq --> |
|||
<el-table |
|||
:data="dataList" |
|||
:height="height" |
|||
border |
|||
highlight-current-row |
|||
v-loading="dataListLoading" |
|||
@selection-change="handleSelectionChange" |
|||
style="width: 100%;"> |
|||
<el-table-column type="selection" width="50" align="center"></el-table-column> |
|||
<el-table-column prop="seqNo" label="序号" width="100" show-overflow-tooltip></el-table-column> |
|||
<el-table-column prop="epc" label="EPC" min-width="200" show-overflow-tooltip></el-table-column> |
|||
<el-table-column prop="tid" label="TID" min-width="200" show-overflow-tooltip></el-table-column> |
|||
<el-table-column prop="userArea" label="用户区" width="150" show-overflow-tooltip></el-table-column> |
|||
<el-table-column prop="lockBits" label="LockiBtis" width="80"></el-table-column> |
|||
<el-table-column prop="secretKey" label="密匙" width="100" show-overflow-tooltip></el-table-column> |
|||
<el-table-column prop="writeSuccess" label="写码成功" width="80" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span :style="{color: scope.row.writeSuccess === 'True' ? '#67C23A' : '#F56C6C'}"> |
|||
{{ scope.row.writeSuccess }} |
|||
</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="readSuccess" label="读码成功" width="80" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span :style="{color: scope.row.readSuccess === 'True' ? '#67C23A' : '#F56C6C'}"> |
|||
{{ scope.row.readSuccess }} |
|||
</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="epcLocked" label="EPC锁定" width="80" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span :style="{color: scope.row.epcLocked === 'True' ? '#67C23A' : '#F56C6C'}"> |
|||
{{ scope.row.epcLocked }} |
|||
</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="signalStrength" label="强度/读距" width="80"></el-table-column> |
|||
<el-table-column prop="scanTime" label="扫描时间" width="160"></el-table-column> |
|||
<el-table-column prop="countInfo" label="计数" min-width="180" show-overflow-tooltip></el-table-column> |
|||
<el-table-column prop="batchNo" label="批次号" width="130"></el-table-column> |
|||
<el-table-column prop="uploadBy" label="上传人" width="100"></el-table-column> |
|||
<el-table-column prop="uploadTime" label="上传时间" width="160"></el-table-column> |
|||
<el-table-column prop="remark" label="备注" min-width="150" show-overflow-tooltip></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="导入TID_EPC日志" :close-on-click-modal="false" v-drag :visible.sync="importModalFlag" width="500px" @close="closeImportModal"> |
|||
<el-form :inline="true" label-position="top" :model="importData" ref="importForm"> |
|||
<el-row> |
|||
<el-col :span="12"> |
|||
<el-form-item label="Site" prop="site" :rules="[{required: true, message: '请选择Site', trigger: 'change'}]"> |
|||
<el-input v-model="importData.site" disabled style="width: 200px"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="12"> |
|||
<el-form-item label="BU" prop="buNo" :rules="[{required: true, message: '请选择BU', trigger: 'change'}]"> |
|||
<el-select v-model="importData.buNo" placeholder="请选择" style="width: 200px"> |
|||
<el-option |
|||
v-for="i in userBuList" |
|||
:key="i.buNo" |
|||
:label="i.sitename" |
|||
:value="i.buNo"> |
|||
<span style="float: left;width: 100px">{{ i.sitename }}</span> |
|||
<span style="float: right; color: #8492a6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; font-size: 11px;width: 60px"> |
|||
{{ i.buDesc }} |
|||
</span> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row> |
|||
<el-col :span="24"> |
|||
<el-form-item label="备注"> |
|||
<el-input v-model="importData.remark" type="textarea" :rows="2" resize="none" placeholder="请输入备注(可选)" style="width: 430px"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row style="margin-top: 10px;"> |
|||
<el-col :span="24"> |
|||
<el-upload |
|||
class="upload-demo" |
|||
drag |
|||
action="javascript:void(0);" |
|||
ref="uploadFile" |
|||
:limit="1" |
|||
accept=".xlsx,.xls" |
|||
:before-upload="beforeUploadHandle" |
|||
:on-change="onFileChange" |
|||
:auto-upload="false" |
|||
style="text-align: left;"> |
|||
<i class="el-icon-upload"></i> |
|||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
|||
<div class="el-upload__tip" slot="tip">只能上传xlsx/xls文件</div> |
|||
</el-upload> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row style="margin-top: 10px;"> |
|||
<el-col :span="24"> |
|||
<el-button type="text" @click="downloadTemplateFile"> |
|||
<i class="el-icon-download"></i> 下载导入模板 |
|||
</el-button> |
|||
</el-col> |
|||
</el-row> |
|||
</el-form> |
|||
<span slot="footer" class="dialog-footer"> |
|||
<el-button type="primary" :loading="importLoading" :disabled="importLoading" @click="submitImport"> |
|||
{{ importLoading ? '导入中...' : '导入' }} |
|||
</el-button> |
|||
<el-button @click="importModalFlag = false" :disabled="importLoading">关闭</el-button> |
|||
</span> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { searchList, getExportList, importExcel, deleteData, downloadTemplate } from "@/api/mes/mesTidEpcLog.js" |
|||
import { getSiteAndBuByUserName } from "@/api/eam/eam.js" |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
// 页面状态 - rqrq |
|||
height: 200, |
|||
dataListLoading: false, |
|||
importModalFlag: false, |
|||
importLoading: false, |
|||
deleteLoading: false, |
|||
|
|||
// 数据列表 - rqrq |
|||
dataList: [], |
|||
selectedList: [], |
|||
|
|||
// 查询条件 - rqrq |
|||
searchData: { |
|||
site: this.$store.state.user.site, |
|||
searchSeqNo: '', |
|||
searchEpc: '', |
|||
searchTid: '', |
|||
searchUserArea: '', |
|||
searchBatchNo: '', |
|||
scanTimeStart: '', |
|||
scanTimeEnd: '', |
|||
page: 1, |
|||
limit: 20 |
|||
}, |
|||
|
|||
// 分页信息 - rqrq |
|||
pageIndex: 1, |
|||
pageSize: 20, |
|||
totalPage: 0, |
|||
|
|||
// 导入数据 - rqrq |
|||
importData: { |
|||
site: this.$store.state.user.site, |
|||
buNo: '', |
|||
remark: '' |
|||
}, |
|||
fileList: [], |
|||
userBuList: [], |
|||
|
|||
// 导出相关 - rqrq |
|||
exportData: [], |
|||
exportName: 'TID_EPC日志导出.xls', |
|||
exportHeader: '', |
|||
exportFooter: '' |
|||
} |
|||
}, |
|||
|
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
// 计算表格高度 - rqrq |
|||
this.height = window.innerHeight - 240 |
|||
// 获取BU列表 - rqrq |
|||
this.getSiteAndBuByUserName() |
|||
} ) |
|||
}, |
|||
|
|||
methods: { |
|||
// 获取用户的BU列表 - rqrq |
|||
getSiteAndBuByUserName() { |
|||
let tempData = { |
|||
username: this.$store.state.user.name |
|||
} |
|||
getSiteAndBuByUserName(tempData).then(({data}) => { |
|||
if (data.code === 0) { |
|||
this.userBuList = data.rows |
|||
// 默认选中第一个BU - rqrq |
|||
if (data.rows && data.rows.length > 0) { |
|||
this.importData.buNo = data.rows[0].buNo |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
// 校验筛选条件是否至少填写一个 - rqrq |
|||
validateSearchCondition() { |
|||
if (this.searchData.searchSeqNo || |
|||
this.searchData.searchEpc || |
|||
this.searchData.searchTid || |
|||
this.searchData.searchUserArea || |
|||
this.searchData.searchBatchNo || |
|||
this.searchData.scanTimeStart || |
|||
this.searchData.scanTimeEnd) { |
|||
return true |
|||
} |
|||
return false |
|||
}, |
|||
|
|||
// 查询数据列表 - rqrq |
|||
getDataList() { |
|||
// 校验筛选条件 - rqrq |
|||
if (!this.validateSearchCondition()) { |
|||
this.$message.warning('请至少填写一个筛选条件') |
|||
return |
|||
} |
|||
|
|||
this.searchData.page = this.pageIndex |
|||
this.searchData.limit = this.pageSize |
|||
this.dataListLoading = true |
|||
|
|||
searchList(this.searchData).then(({data}) => { |
|||
this.dataListLoading = false |
|||
if (data && data.code === 0) { |
|||
this.dataList = data.page.list || [] |
|||
this.totalPage = data.page.totalCount |
|||
} else { |
|||
this.dataList = [] |
|||
this.$message.error(data.msg || '查询失败') |
|||
} |
|||
}).catch(() => { |
|||
this.dataListLoading = false |
|||
this.$message.error('查询失败') |
|||
}) |
|||
}, |
|||
|
|||
// 分页事件 - rqrq |
|||
sizeChangeHandle(val) { |
|||
this.pageSize = val |
|||
this.getDataList() |
|||
}, |
|||
|
|||
currentChangeHandle(val) { |
|||
this.pageIndex = val |
|||
this.getDataList() |
|||
}, |
|||
|
|||
// 表格选择事件 - rqrq |
|||
handleSelectionChange(val) { |
|||
this.selectedList = val |
|||
}, |
|||
|
|||
// 打开导入弹窗 - rqrq |
|||
openImportModal() { |
|||
this.importData.remark = '' |
|||
this.fileList = [] |
|||
this.importModalFlag = true |
|||
}, |
|||
|
|||
// 关闭导入弹窗 - rqrq |
|||
closeImportModal() { |
|||
this.fileList = [] |
|||
if (this.$refs.uploadFile) { |
|||
this.$refs.uploadFile.clearFiles() |
|||
} |
|||
}, |
|||
|
|||
// 上传前验证 - rqrq |
|||
beforeUploadHandle(file) { |
|||
let extName = file.name.substring(file.name.lastIndexOf('.')).toLowerCase() |
|||
if (!(extName === '.xlsx' || extName === '.xls')) { |
|||
this.$message.error('请选择正确的Excel文件(.xlsx或.xls)') |
|||
return false |
|||
} |
|||
return true |
|||
}, |
|||
|
|||
// 文件选择事件 - rqrq |
|||
onFileChange(file) { |
|||
this.fileList = [file] |
|||
}, |
|||
|
|||
// 下载导入模板 - rqrq |
|||
downloadTemplateFile() { |
|||
downloadTemplate().then(({data}) => { |
|||
// 创建Blob对象 - rqrq |
|||
const blob = new Blob([data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}) |
|||
// 下载文件名称 - rqrq |
|||
const fileName = 'TID_EPC日志导入模板.xlsx' |
|||
// a标签下载 - rqrq |
|||
const linkNode = document.createElement('a') |
|||
linkNode.download = fileName |
|||
linkNode.style.display = 'none' |
|||
linkNode.href = URL.createObjectURL(blob) |
|||
document.body.appendChild(linkNode) |
|||
linkNode.click() |
|||
URL.revokeObjectURL(linkNode.href) |
|||
document.body.removeChild(linkNode) |
|||
this.$message.success('模板下载成功') |
|||
}).catch(() => { |
|||
this.$message.error('模板下载失败') |
|||
}) |
|||
}, |
|||
|
|||
// 提交导入 - rqrq |
|||
submitImport() { |
|||
this.$refs.importForm.validate((valid) => { |
|||
if (!valid) { |
|||
return |
|||
} |
|||
|
|||
if (this.fileList.length === 0) { |
|||
this.$message.error('请先选择要上传的文件') |
|||
return |
|||
} |
|||
|
|||
this.importLoading = true |
|||
|
|||
const formData = new FormData() |
|||
formData.append('file', this.fileList[0].raw) |
|||
formData.append('site', this.importData.site) |
|||
formData.append('buNo', this.importData.buNo) |
|||
formData.append('remark', this.importData.remark || '') |
|||
formData.append('username', this.$store.state.user.name) |
|||
|
|||
importExcel(formData).then(({data}) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success(data.msg || '导入成功') |
|||
this.importModalFlag = false |
|||
this.getDataList() |
|||
} else { |
|||
this.$alert(data.msg || '导入失败', '错误', { |
|||
confirmButtonText: '确定' |
|||
}) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('导入失败') |
|||
}).finally(() => { |
|||
this.importLoading = false |
|||
}) |
|||
}) |
|||
}, |
|||
|
|||
// 删除数据 - rqrq |
|||
deleteData() { |
|||
if (this.selectedList.length === 0) { |
|||
this.$message.warning('请选择要删除的数据') |
|||
return |
|||
} |
|||
|
|||
this.$confirm(`确定删除选中的 ${this.selectedList.length} 条数据?`, '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
this.deleteLoading = true |
|||
const ids = this.selectedList.map(item => item.id) |
|||
|
|||
deleteData(ids).then(({data}) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('删除成功') |
|||
this.getDataList() |
|||
} else { |
|||
this.$message.error(data.msg || '删除失败') |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('删除失败') |
|||
}).finally(() => { |
|||
this.deleteLoading = false |
|||
}) |
|||
}).catch(() => {}) |
|||
}, |
|||
|
|||
// 导出相关方法 - rqrq |
|||
fields() { |
|||
return { |
|||
'序号': 'seqNo', |
|||
'EPC': 'epc', |
|||
'TID': 'tid', |
|||
'用户区': 'userArea', |
|||
'LockiBtis': 'lockBits', |
|||
'密匙': 'secretKey', |
|||
'写码成功': 'writeSuccess', |
|||
'读码成功': 'readSuccess', |
|||
'EPC锁定': 'epcLocked', |
|||
'强度/读距': 'signalStrength', |
|||
'扫描时间': 'scanTime', |
|||
'计数': 'countInfo', |
|||
'批次号': 'batchNo', |
|||
'上传人': 'uploadBy', |
|||
'上传时间': 'uploadTime', |
|||
'备注': 'remark' |
|||
} |
|||
}, |
|||
|
|||
startDownload() { |
|||
this.$message.info('正在准备导出数据...') |
|||
}, |
|||
|
|||
finishDownload() { |
|||
this.$message.success('导出完成') |
|||
}, |
|||
|
|||
// 创建导出数据 - rqrq |
|||
async createExportData() { |
|||
// 校验筛选条件 - rqrq |
|||
if (!this.validateSearchCondition()) { |
|||
this.$message.warning('请至少填写一个筛选条件后再导出') |
|||
return [] |
|||
} |
|||
|
|||
const { data } = await getExportList(this.searchData) |
|||
if (data && data.code === 0) { |
|||
return data.rows || [] |
|||
} else { |
|||
this.$message.error('获取导出数据失败') |
|||
return [] |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 自定义样式 - rqrq */ |
|||
.upload-demo { |
|||
width: 100%; |
|||
} |
|||
|
|||
/deep/ .el-upload-dragger { |
|||
width: 430px; |
|||
height: 120px; |
|||
} |
|||
|
|||
/deep/ .el-upload-dragger .el-icon-upload { |
|||
margin-top: 20px; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue