提交代码

This commit is contained in:
shaoleiliu-netizen123 2026-07-27 17:53:59 +08:00
parent 77aae7a280
commit a8c1a388f6
13 changed files with 473 additions and 18 deletions

View File

@ -103,11 +103,14 @@ export const deviceApi = {
export(
params?:{
ids?:string[],
deviceCode:any
deviceCode:any,
deviceFlag?:string
}){
const p:Record<string,any> = {}
console.log( params)
if(params?.ids?.length) p.ids = params.ids.join(',')
if(params?.deviceCode != undefined && params?.deviceCode !== null) p.sectionCode = params.deviceCode
if(params?.deviceFlag != undefined && params?.deviceFlag !== null) p.deviceFlag = params.deviceFlag
return request({
url:`/biz/device/report`,
method:"get",
@ -122,5 +125,11 @@ export const deviceApi = {
method:"get",
params
})
},
deviceList() {
return request({
url:"/biz/device/list",
method:"get"
})
}
}

View File

@ -0,0 +1,72 @@
import { request } from '@/utils/request'
// 设备操作日志 类型定义
export interface DeviceOperationLog {
id?: number
assingWorkId?: number
userId?: number
deviceId?: number
source?: number
operationType?: number
createTime?: string
}
// 设备操作日志 API
export const deviceOperationLogApi = {
// 分页查询
page(params: { page: number; pageSize: number; deviceId?: number; operationType?: number;userId?: number }) {
return request({ url: '/terminal/operation/page', method: 'get', params })
},
// 获取详情
detail(id: string) {
return request({ url: `/biz/deviceOperationLog/${id}`, method: 'get' })
},
// 新增
create(data: DeviceOperationLog) {
return request({ url: '/biz/deviceOperationLog', method: 'post', data })
},
// 修改
update(data: DeviceOperationLog) {
return request({ url: '/biz/deviceOperationLog', method: 'put', data })
},
// 删除
delete(ids: string[]) {
return request({ url: `/biz/deviceOperationLog/${ids.join(',')}`, method: 'delete' })
},
// 导出
export(params?: { ids?: string[]; id?: number }) {
const p: Record<string, any> = {}
if (params?.ids?.length) p.ids = params.ids.join(',')
if (params?.id !== undefined && params?.id !== null) p.id = params.id
return request({ url: `/biz/deviceOperationLog/export`, method: 'get', params: p, responseType: 'blob' })
},
// 导入
importData(file: File) {
const formData = new FormData()
formData.append('file', file)
return request<{ success: number; fail: number; errors: string[] }>({
url: `/biz/deviceOperationLog/import`,
method: 'post',
data: formData,
headers: { 'Content-Type': 'multipart/form-data' }
})
},
// 下载导入模板
downloadTemplate() {
return request({ url: `/biz/deviceOperationLog/template`, method: 'get', responseType: 'blob' })
}
}

102
src/api/issuerecord.ts Normal file
View File

@ -0,0 +1,102 @@
import { request } from '@/utils/request'
// 下发记录表 类型定义
export interface IssueRecord {
id?: number
issueCode?: string
issueType?: string
issueTypeName?: string
sourceId?: number
sourceCode?: string
sourceName?: string
deviceId?: number
status?: number
statusName?: string
issueTime?: string
issueBy?: number
completeTime?: string
result?: string
remark?: string
createTime?: string
createBy?: number
assingId?: number
processId?: number
}
// 下发记录表 API
export const issueRecordApi = {
// 分页查询
page(params: { page: number; pageSize: number; id?: number; status?: number }) {
return request({ url: '/biz/issueRecord/page', method: 'get', params })
},
// 获取详情
detail(id: number) {
return request({ url: `/biz/issueRecord/${id}`, method: 'get' })
},
// 新增
create(data: IssueRecord) {
return request({ url: '/biz/issueRecord', method: 'post', data })
},
// 修改
update(data: IssueRecord) {
return request({ url: '/biz/issueRecord', method: 'put', data })
},
// 删除
delete(ids: number[]) {
return request({ url: `/biz/issueRecord/${ids.join(',')}`, method: 'delete' })
},
// 导出
export(params?: { ids?: number[]; id?: number; status?: number }) {
const p: Record<string, any> = {}
if (params?.ids?.length) p.ids = params.ids.join(',')
if (params?.id !== undefined && params?.id !== null) p.id = params.id
if (params?.status !== undefined && params?.status !== null) p.status = params.status
return request({ url: `/biz/issueRecord/export`, method: 'get', params: p, responseType: 'blob' })
},
// 导入
importData(file: File) {
const formData = new FormData()
formData.append('file', file)
return request<{ success: number; fail: number; errors: string[] }>({
url: `/biz/issueRecord/import`,
method: 'post',
data: formData,
headers: { 'Content-Type': 'multipart/form-data' }
})
},
// 下载导入模板
downloadTemplate() {
return request({ url: `/biz/issueRecord/template`, method: 'get', responseType: 'blob' })
},
//设备下发记录
getDeviceDispatchLogList(deviceId: number) {
return request({ url: `/biz/issueRecord/deviceIssueRecords/${deviceId}`, method: 'get' })
}
}

View File

@ -67,6 +67,15 @@ export function issuecopy(data:any) {
})
}
// 导出
export function exportIssue(params?: { ids?: number[]; id?: number; status?: number }) {
const p: Record<string, any> = {}
if (params?.ids?.length) p.ids = params.ids.join(',')
if (params?.id !== undefined && params?.id !== null) p.id = params.id
if (params?.status !== undefined && params?.status !== null) p.status = params.status
return request({ url: `/biz/ncCode/export`, method: 'get', params: p, responseType: 'blob' })
}
//任务树
export function opertree() {
return request({

View File

@ -0,0 +1,9 @@
<template>
</template>
<script>
</script>

View File

@ -47,6 +47,7 @@
:loading="loading"
:row-key="(row) => row.id"
:scroll-x="1200"
v-model:checked-row-keys="selectedIds"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">

View File

@ -0,0 +1,221 @@
<script setup lang="ts">
import {NButton, NIcon, NSpace} from "naive-ui";
import {ArrowDown, ArrowUp, RefreshOutline, SearchOutline} from "@vicons/ionicons5";
import {onMounted, reactive, ref} from "vue";
import { deviceApi, Device} from '@/api/device.ts'
import {dictDataApi} from "@/api/org.ts";
import {userApi,SysUser} from "@/api/system.ts";
import { deviceOperationLogApi,type DeviceOperationLog } from '@/api/deviceOperationLog.ts'
const pagination = reactive({
page: 1,
pageSize: 10,
itemCount: 0,
showSizePicker: true,
pageSizes: [10, 20, 50]
})
const props = defineProps({
deviceId:Number
})
const showSearchInput = ref<Boolean>(false)
const searchForm = ref({
createTime: undefined,
operationType: undefined,
userId: undefined
})
const doShowInner = () => {
if (showSearchInput.value) {
showSearchInput.value = false
}else {
showSearchInput.value = true
}
}
//
const deviceList = ref<Device[]>([])
const getDeviceList = async () => {
try {
const res = await deviceApi.deviceList()
deviceList.value = res.map((n:any)=>{
return {
label:n.deviceName,
value:n.id
}
})
} catch (error) {
//
}
}
//
const optionTypeList = ref([])
const loadDictOptions = async ()=>{
try {
const data = await dictDataApi.listByType("option_type")
optionTypeList.value = data.map(d => ({
label: d.dictLabel,
value: (Number(d.dictValue) || d.dictValue),
class: d.listClass
}))
} catch {
}
}
//
const optionUserList = ref<SysUser[]>([])
const loadUserList = async ()=>{
try {
const data = await userApi.getPathList()
optionUserList.value = data.map(d => ({
label: d.nickname,
value: d.id
}))
} catch {
}
}
//
const data = ref([])
const load = async()=>{
const res = await deviceOperationLogApi.page({
page: pagination.page,
pageSize: pagination.pageSize,
deviceId: props.deviceId,
createTime: searchForm.value.createTime,
operationType: searchForm.value.operationType,
userId: searchForm.value.userId
});
data.value = res.list
pagination.itemCount = res.total
}
//
const columns = [
{
title: '设备名称',
key: 'deviceName'
},
{
title: '操作类型',
key: 'operationType'
},
{
title: '操作人员',
key: 'nickname'
},
{
title: '操作时间',
key: 'createTime'
}
]
onMounted(()=>{
getDeviceList()
loadDictOptions()
loadUserList()
load()
})
</script>
<template>
<div>
<n-button @click="doShowInner" v-if="showSearchInput">
<n-icon size="20" :depth="3">
<ArrowDown/>
</n-icon>
展开
</n-button>
<n-card v-if="!showSearchInput">
<n-form inline :model="searchForm" label-placement="left">
<n-grid :x-gap="8" :cols="4">
<n-gi>
<n-form-item label="日期">
<n-date-picker
v-model:value="searchForm.createTime"
type="date" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="操作类型">
<n-select
v-model:value="searchForm.operationType"
:options="optionTypeList"
placeholder="请选择设备类型"
clearable
style="width: 200px"
/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="操作人员">
<n-select
v-model:value="searchForm.userId"
:options="optionUserList"
placeholder="请选择设备类型"
clearable
style="width: 200px"
/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item>
<n-space>
<n-button type="primary" @click="handleSearch">
<template #icon>
<n-icon>
<SearchOutline/>
</n-icon>
</template>
搜索
</n-button>
<n-button @click="handleReset">
<template #icon>
<n-icon>
<RefreshOutline/>
</n-icon>
</template>
重置
</n-button>
</n-space>
</n-form-item>
</n-gi>
</n-grid>
</n-form>
<n-button @click="doShowInner" v-if="!showSearchInput" style="float: right;margin: 10px">
<n-icon size="20" :depth="3">
<ArrowUp/>
</n-icon>
闭合
</n-button>
</n-card>
<n-card style="margin: 20px 0">
<n-data-table
:columns="columns"
:data="data"
:pagination="pagination"
:bordered="false"
/>
</n-card>
</div>
</template>
<style scoped>
</style>

View File

@ -74,6 +74,7 @@
:loading="loading"
:row-key="(row) => row.id"
:scroll-x="1200"
v-model:checked-row-keys="selectedIds"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
<n-pagination
@ -213,6 +214,21 @@
</template>
</n-drawer-content>
</n-drawer>
<!--操作日志抽屉-->
<n-drawer v-model:show="deviceOperationLogDrawerVisible" width="1800">
<n-drawer-content :title="title">
<DeviceOperationLogPage
:deviceId = deviceId
/>
<template #footer>
<n-button @click="doShowInner">
取消
</n-button>
</template>
</n-drawer-content>
</n-drawer>
</div>
</template>
@ -239,10 +255,15 @@ import {sectionApi} from '@/api/section'
import {SysUser, userApi} from '@/api/system'
import {DeviceAbnormalRecord, deviceAbnormalRecordApi} from "@/api/deviceAbnormalRecord.ts";
import DeviceAbnormalRecordPage from '@/views/biz/device/DeviceAbnomarlRecord.vue'
import DeviceOperationLogPage from "@/views/biz/device/DeviceOperationLog.vue";
import { issueRecordApi } from '@/api/issuerecord'
const message = useMessage()
const dialog = useDialog()
const router = useRouter()
//Id
const deviceId = ref<number>(undefined)
//
const deviceManagerList = ref<{ label: string, value: any }[]>([])
@ -256,8 +277,8 @@ const title = ref('')
//
const deviceIssueRecordList = ref<[]>([])
//
const deviceOperationLogDrawerVisible = ref<Boolean>(false)
//
const searchForm = reactive({
@ -365,12 +386,14 @@ const columns: DataTableColumns<Device> = [
{
label: '设备异常记录',
key: 'deviceErrorLog',
},
{
label: '设备下发记录',
key: 'deviceDispatchLog',
},
{
label: '设备操作日志',
key: 'deviceOperationLog',
}
], onSelect: (key: string) => {
switch (key) {
@ -380,6 +403,9 @@ const columns: DataTableColumns<Device> = [
case "deviceDispatchLog":
handleDeviceDispatchLog(row)
break
case "deviceOperationLog":
deviceOperationLog(row)
break
}
}
}, {
@ -531,6 +557,7 @@ async function handleExport() {
const params: Record<string, any> = {}
if (selectedIds.value.length > 0) params.ids = selectedIds.value
if (searchForm.deviceCode != null) params.deviceCode = searchForm.deviceCode
params.deviceFlag = "mes_equipment"
const blob = await deviceApi.export(params)
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
@ -633,13 +660,22 @@ async function handleDeviceErrorLog(row: Device) {
deviceErrorLogList.value = row.abnormalRecordList
}
async function handleDeviceDispatchLog(row: Device) {
const deviceId = row.id
//deviceIssueRecordList.value = await deviceIssueRecordApi.getDeviceDispatchLogList(deviceId)
deviceIssueRecordList.value = await issueRecordApi.getDeviceDispatchLogList(deviceId)
}
async function deviceOperationLog(row: Device) {
deviceId.value = row.id
deviceOperationLogDrawerVisible.value = true
title.value = row.deviceName + "操作记录";
}
function doShowInner() {
deviceAbnormalRecordDrawerVisible.value = false
deviceOperationLogDrawerVisible.value = false
}
onMounted(() => {

View File

@ -664,8 +664,8 @@ const submitLogModalVisible = ref<Boolean>(false)
//
function openDetailModel(order:ProcessPlanItemVO,procces?:OrderProcessPlanVO) {
submitLogModalVisible.value = true
const processId = procces.planId
// submitLogModalVisible.value = true
// const processId = procces.planId
}

View File

@ -82,15 +82,13 @@
</template>
<script setup lang="ts">
import { ref,reactive, watch } from 'vue'
import { ref,reactive } from 'vue'
import { userApi } from '@/api/system'
import {deviceApi} from '@/api/device'
import {sectionApi, type Section} from '@/api/section'
import {
AddOutline,
TrashOutline,
} from '@vicons/ionicons5'
import { label } from 'three/tsl'
const props = withDefaults(defineProps<{
listname:any

View File

@ -51,6 +51,7 @@
:loading="loading"
:row-key="(row) => row.id"
:scroll-x="1200"
v-model:checked-row-keys="selectedIds"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">

View File

@ -51,6 +51,7 @@
:loading="loading"
:row-key="(row) => row.id"
:scroll-x="1200"
v-model:checked-row-keys="selectedIds"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
<n-pagination
@ -361,6 +362,7 @@ async function handleExport() {
const params: Record<string, any> = {}
if (selectedIds.value.length > 0) params.ids = selectedIds.value
if (searchForm.deviceCode != null) params.deviceCode = searchForm.deviceCode
params.deviceFlag = "mes_station"
const blob = await deviceApi.export(params)
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')

View File

@ -248,7 +248,6 @@ import {
reactive,
h,
onMounted,
watch,
} from 'vue'
@ -258,12 +257,9 @@ import {
NSpace,
NImage,
NPagination,
NGrid,
// NGi,
NTag,
NGrid,
useMessage,
useDialog,
//type FormInst,
} from 'naive-ui'
import {
@ -278,8 +274,7 @@ import { useUserStore } from '@/stores/user'
import {
addDrawing,
editDrawing,
drawinglist,
drawingIssue,
drawinglist,
deleteDrawing
} from '@/api/illustrated'