Browse Source

feat(mes): 新增MES TID EPC日志管理功能

- 创建MES TID EPC日志API接口,包括查询、导入、导出、删除等功能
- 开发TID EPC日志管理页面,实现分页查询和表格展示
- 添加Excel导入功能,支持批量导入TID EPC数据
- 实现数据导出功能,支持按条件导出日志数据
- 集成BU站点选择功能,支持按站点和BU进行数据过滤
- 添加批量删除功能,支持多选删除日志记录
- 实现完整的CRUD操作界面,包含搜索、分页、导入导出等交互功能
master
常熟吴彦祖 4 weeks ago
parent
commit
b5371cf527
  1. 41
      src/api/mes/mesTidEpcLog.js
  2. 497
      src/views/modules/mes/mesTidEpcLog.vue

41
src/api/mes/mesTidEpcLog.js

@ -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)

497
src/views/modules/mes/mesTidEpcLog.vue

@ -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>
Loading…
Cancel
Save