mes-vue/src/views/NCcode/index.vue
shaoleiliu-netizen123 c257821ca8 提交代码
2026-08-27 13:29:39 +08:00

1114 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="page-container">
<!-- 用户列表 -->
<n-card class="user-list-card" size="small">
<!-- 搜索表单 -->
<div class="search-form">
<n-form
inline
:model="searchForm"
label-placement="left"
>
<n-form-item label="NC代码编号">
<n-input v-model:value="searchForm.ncCode" placeholder="请输入NC代码编号" />
</n-form-item>
<n-form-item label="NC代码名称">
<n-input v-model:value="searchForm.ncName" placeholder="请输入NC代码名称" />
</n-form-item>
<n-space>
<n-button type="primary" @click="search">
<template #icon><n-icon><SearchOutline /></n-icon></template>
搜索
</n-button>
<n-button @click="reset">
<template #icon><n-icon><RefreshOutline /></n-icon></template>
重置
</n-button>
</n-space>
</n-form>
</div>
<n-space style="margin-bottom: 15px;">
<n-button v-if="hasPermission('biz:ncCode:add')" type="primary" @click="addhand(1)" size="small">
<template #icon>
<n-icon>
<AddOutline />
</n-icon>
</template>
新增
</n-button>
<!-- <n-button type="error" @click="delhand" size="small">
<template #icon>
<n-icon>
<ArrowDownCircleOutline />
</n-icon>
</template>
删除
</n-button> -->
<n-button v-if="hasPermission('biz:ncCode:export')" type="success" @click="handleExport" size="small">
<template #icon>
<n-icon>
<ArrowDownCircleOutline />
</n-icon>
</template>
导出
</n-button>
</n-space>
<!-- 表格 -->
<n-data-table
:columns="columns"
size="small"
striped
:data="datalist"
:bordere="false"
:single-line="false"
:loading="loading"
remote
:row-key="rowKey"
@update:checked-row-keys="handleCheck"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
<n-pagination
v-model:page="pagination.page"
v-model:page-size="pagination.pageSize"
:item-count="pagination.itemCount"
:page-sizes="[10, 20, 50, 100]"
show-size-picker
show-quick-jumper
@update:page="handlePageChange"
@update:page-size="handlePageSizeChange"
>
<template #prefix>
共 {{ pagination.itemCount }} 条
</template>
</n-pagination>
</div>
</n-card>
<n-modal
v-model:show="addModel"
:title="cztype[isstype]"
preset="card"
style="width: 600px"
:mask-closable="false"
>
<n-form
ref="addformRef"
:model="formData"
:rules="addrules"
label-placement="left"
label-width="100"
>
<n-grid :cols="1" :x-gap="24">
<n-gi>
<n-form-item path="ncCode" label="NC代码编号">
<n-input v-model:value="formData.ncCode" placeholder="自动生成" disabled />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item path="ncName" label="NC代码名称">
<n-input v-model:value="formData.ncName" placeholder="请输入NC代码名称" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="状态">
<n-radio-group v-model:value="formData.status" :default-value="1" name="radiogroup">
<n-space>
<n-radio :value="1">
启用
</n-radio>
<n-radio :value="0">
禁用
</n-radio>
</n-space>
</n-radio-group>
</n-form-item>
</n-gi>
<n-gi>
<!--type="textarea"-->
<n-form-item path="ncContent" label="NC代码内容">
<n-input type="textarea" v-model:value="formData.ncContent" placeholder="请输入NC代码内容" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item path="fileId" label="上传文件">
<!--:default-file-list="fileList"-->
<!-- <n-upload
:action="URL"
:headers="{
Authorization:TOKEN
}"
list-type="image-card"
>
点击上传
</n-upload> -->
<!-- @before-upload ="flchang"
@change="flchang"
@remove="flchang"
.doc,.docx,
-->
<n-upload
directory-dnd
auto-upload="false"
:action="URL"
:headers="{
Authorization:TOKEN
}"
:max="20"
accept=".pdf,.png,.jpg"
v-model:file-list="flist"
@finish="flchang"
@remove="flremove"
>
<n-upload-dragger>
<div>
<n-icon size="40" :depth="3">
<CloudUploadOutline />
</n-icon>
</div>
<n-text style="font-size: 14px">
点击或者拖动文件到该区域来上传
</n-text>
</n-upload-dragger>
</n-upload>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="备注">
<n-input type="textarea" v-model:value="formData.remark" placeholder="请输入备注" />
</n-form-item>
</n-gi>
<!-- <n-gi>
<n-form-item label="工作中心">
<n-input v-model:value="formData.workCenter" placeholder="请输入工作中心" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="设备ID">
<n-input v-model:value="formData.deviceId" placeholder="请输入设备ID" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="设备名称">
<n-input v-model:value="formData.deviceName" placeholder="请输入设备名称" />
</n-form-item>
</n-gi> -->
<!-- <n-gi>
<n-form-item label="下发状态">
<n-radio-group v-model:value="formData.isIssued" name="radiogroup">
<n-space>
<n-radio :value="1">
已下发
</n-radio>
<n-radio :value="0">
未下发
</n-radio>
</n-space>
</n-radio-group>
</n-form-item>
</n-gi> -->
<!-- <template v-if="formData.isIssued == 1">
<n-gi>
<n-form-item label="下发时间">
<n-date-picker
v-model:formatted-value="formData.issueTime"
type="datetime"
style="width: 100%;"
clearable
value-format="yyyy-MM-dd HH:mm:ss"
/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="下发人">
<n-input v-model:value="formData.issueBy" placeholder="请选择下发人" />
</n-form-item>
</n-gi>
</template> -->
</n-grid>
</n-form>
<template #footer>
<n-space justify="end">
<n-button @click="addModel = false">取消</n-button>
<n-button
type="primary"
@click="savehand"
>确认</n-button>
</n-space>
</template>
</n-modal>
<!--下发-->
<n-modal
v-model:show="issueModel"
title="下发"
preset="card"
style="width: 600px"
:mask-closable="false"
>
<div style="display: flex;padding-bottom: 15px;font-size: 16px;">
<div style="padding: 2px 5px;background: #50a5b7;color: #fff;border-radius: 6px 0 0 6px;">NC代码编号</div>
<div style="padding: 2px 5px;border: 1px solid #50a5b7;border-radius: 0 6px 6px 0;">{{ ncCode }}</div>
</div>
<n-transfer
v-model:value="xfsbvalue"
style="height:500px;"
:options="options"
:render-source-list="renderSourceList"
source-filterable
@update:value="tranupdate"
/>
<template #footer>
<n-space justify="end">
<n-button @click="issueModel = false">取消</n-button>
<n-button
type="primary"
@click="isssavehand"
>确认</n-button>
</n-space>
</template>
</n-modal>
<!--工艺文档抽屉-->
<n-drawer v-model:show="deviceDocumentConnectionVisible" width="1000">
<n-drawer-content :title="title">
<n-space justify="space-between" class="mb-3">
<n-checkbox v-model:checked="isAllCheck" @update:checked="handleAllCheck">
全选当前筛选文档
</n-checkbox>
<n-tag type="info">已勾选 {{ selectedDeviceIds.length }} 道文档</n-tag>
</n-space>
<!-- 工序表格带复选框 -->
<n-data-table
:columns="deviceColumns"
:data="deviceList"
max-height="700"
v-model:checked-row-keys="selectedDeviceIds"
:row-key="rowKey"
:scroll-x="1200"
:loading="connectionLoading"
@update:checked-row-keys="handleUpateCheck"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
<n-pagination
v-model:page="connectionPagination.page"
v-model:page-size="connectionPagination.pageSize"
:item-count="connectionPagination.itemCount"
:page-sizes="[10, 20, 50, 100]"
show-size-picker
show-quick-jumper
@update:page="handleRelatePageChange"
@update:page-size="handleRelatePageSizeChange"
>
<template #prefix>
{{ connectionPagination.itemCount }}
</template>
</n-pagination>
</div>
<template #footer>
<n-button @click="deviceDocumentConnectionVisible = false">
取消
</n-button>
</template>
</n-drawer-content>
</n-drawer>
</div>
</template>
<script setup lang="ts">
import {
ref,
reactive,
h,
onMounted, computed,
} from 'vue'
import {
NTree,
NButton,
NIcon,
NSpace,
NPagination,
NGrid,
useMessage,
useDialog,
NDropdown, NTag, type DataTableColumns,
} from 'naive-ui'
import {
SearchOutline,
RefreshOutline,
AddOutline,
ArrowDownCircleOutline,
EllipsisHorizontalOutline,
CloudUploadOutline
} from '@vicons/ionicons5'
import { useUserStore } from '@/stores/user'
import {
addnccode,
nccodelist,
batchIssue,
editccode,
issuecopy,
generateNccode,
opertree,
exportNccode,
deleteIssue
} from '@/api/nccode'
import
{
multifilelist
} from '@/api/illustrated'
import {DeviceDocumentConnection, deviceDocumentConnectionApi} from "@/api/deviceDocumentConnection.ts";
import {Device, deviceApi} from "@/api/device.ts";
import {RowData} from "naive-ui/es/data-table/src/interface";
const dialog = useDialog()
const message = useMessage()
const userStore = useUserStore()
const URL = `${import.meta.env.VITE_APP_BASE_API}/sys/file/upload`
const TOKEN = userStore.token
// 权限检查
const hasPermission = (permission: string) => userStore.hasPermission(permission)
//const ncDispatchRecords = ref<ncCode[]>([])
//派工状态字典
//const qcAssingStatusOptions = ref<{ label: string; value: any;class:any }[]>([])
// ==================== 搜索表单 ====================
const searchForm = reactive({
page: 1,
pageSize: 20,
ncCode:'',
ncName:''
//status:1
})
// ==================== 表格 ====================
const datalist = ref<any>([])
const loading = ref(false)
//分页
const pagination = reactive({
page: 1,
pageSize: 20,
itemCount: 0
})
const columns = [
// {
// type: 'selection',
// minWidth:60
// },
{
align:"center",
title:"NC代码编号",
key:"ncCode",
minWidth:150
},
{
align:"center",
title:"NC代码名称",
key:"ncName",
minWidth:150
},
{
align:"center",
title:"NC代码内容",
key:"ncContent",
minWidth:150
},
// {
// align:"center",
// title:"工作中心",
// key:"workCenter",
// minWidth:150
// },
// {
// align:"center",
// title:"设备ID",
// key:"deviceId",
// minWidth:150
// },
// {
// align:"center",
// title:"设备名称",
// key:"deviceName",
// minWidth:150
// },
{
align:"center",
title:"状态",
key:"status",
minWidth:150,
render(row:any) {
if(row.status == 1){
return '启用'
}
return '禁用'
}
},
{
align:"center",
title:"是否下发",
key:"isIssued",
minWidth:150,
render(row:any) {
if(row.isSued== 1){
return '已下发'
}
return '未下发'
}
},
{
align:"center",
title:"下发时间",
key:"issueTime",
minWidth:150
},
{
align:"center",
title:"下发人",
key:"issueName",
minWidth:150
},
{
align:"center",
title:"备注",
key:"remark",
minWidth:150
},
{
align:'center',
title: '操作',
key: 'actions',
width: 360,
fixed: 'right',
render(row:any) {
const buttons:any = []
if(hasPermission('biz:ncCode:issue')){
buttons.push(h(NButton, {
size: 'small',
type:'info',
ghost:true,
onClick: () => {
issuehand(row)
} },
{ default: () => '下发'}
))
}
if(hasPermission('biz:nccode:add')){
buttons.push(h(NButton, {
size: 'small',
type:'warning',
ghost:true,
onClick: () => {
addhand(3,row)
}},
{ default: () => '复制'}
))
}
if(hasPermission('biz:ncCode:edit')){
buttons.push(h(NButton, {
size: 'small',
type:'primary',
ghost:true,
onClick: () => {
addhand(2,row)
} },
{ default: () => '编辑'}
))
}
if(hasPermission('biz:ncCode:remove')){
buttons.push(h(NButton, {
size: 'small',
type:'error',
ghost:true,
onClick: () => {
dialog.warning({
title: '警告',
content: `你确定删除NC代码编号为:${row.ncCode}的数据`,
positiveText: '确定',
negativeText: '取消',
//draggable: true,
onPositiveClick: () => {
deleteIssue(row.id).then(() => {
message.success('操作成功')
setTimeout(() => {
search()
},1000)
})
},
onNegativeClick: () => {
}
})
} },
{ default: () => '删除'}
))
}
buttons.push(h(NButton, {
size: 'small',
type:'primary',
ghost:true,
onClick: () => {
handlerConnectionDevice(row)
} },
{ default: () => '关联设备'}
))
return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-'
}
}
]
//搜索数据
function search() {
pagination.page = 1
searchForm.page = 1
searchForm.pageSize = 20
getlist()
}
//重置
function reset() {
searchForm.ncCode = ''
searchForm.ncName = ''
}
//获取列表数据
function getlist() {
nccodelist(searchForm).then((rps:any) => {
datalist.value = rps.list
pagination.itemCount = rps.total
})
}
function handlePageChange(page: number) {
pagination.page = page
searchForm.page = page
getlist()
}
function handlePageSizeChange(pageSize: number) {
pagination.pageSize = pageSize
pagination.page = 1
searchForm.page = 1
searchForm.pageSize = pageSize
getlist()
}
// // 加载字典选项
// async function loadDictOptions() {
// //qcCancelLoading = true
// try {
// const data = await dictDataApi.listByType('assing_status')
// qcAssingStatusOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
// }catch {}
// }
//新增
let addModel = ref(false)
const addformRef = ref()
let formData = reactive<any>({
id:'',
ncCode:'', //NC代码编号
ncName:'', //NC代码名称
ncContent:'', //NC代码内容
workCenter:'', //工作中心
deviceId:'', //设备ID
deviceName:'', //设备名称
fileId:'',
status:1, //状态1-启用 0-禁用
// isIssued:1, //是否已下发1-已下发 0-未下发
// issueTime:null, //下发时间
// issueBy:'', //下发人
remark:'' //备注
})
const addrules = {
ncCode: [
{ required: true, message: '请输入NC代码编号', trigger: 'blur' },
// {
// validator(rule:any,value: any) {
// if(value > pauseform.qcNum){
// return new Error(`报检数量最大为${pauseform.qcNum}`)
// }
// return true
// },
// trigger: ['blur']
// }
],
ncName:[
{ required: true, message: '请输入NC代码名称', trigger: 'blur' }
],
ncContent:[
{ required: true, message: '请输入NC代码内容', trigger: 'blur' }
]
}
let isstype = ref<any>(1)
const cztype = reactive<any>({
1:'新增',
2:'编辑',
3:'复制'
})
//文件上传回调
let flist = ref<any>([])
function flchang(n:any) {
let v = JSON.parse(n.event.target.responseText)
if(v.data && v.data.id){
formData.fileId = formData.fileId + v.data.id+','
}
}
function flremove(n:any) {
let reg = new RegExp(`${n.file.id},?`)
formData.fileId = formData.fileId.replace(reg,'')
console.log(n,'flremove')
console.log(flist.value,'flist-r')
console.log(formData.fileId)
}
function addhand(type:any,row?:any) {
addModel.value = true
formData.value?.restoreValidation()
isstype.value = type
if(row){
formData.id = row.id
formData.ncName = row.ncName
formData.ncContent = row.ncContent
formData.workCenter = row.workCenter
formData.deviceId = row.deviceId
formData.deviceName = row.deviceName
formData.status = row.status
formData.fileId = row.fileId+','
// formData.isIssued = row.isIssued
// formData.issueTime = row.issueTime
// formData.issueBy = row.issueBy
formData.remark = row.remark
if(type == 2){
formData.ncCode = row.ncCode
}else{
formData.ncCode = ''
}
flist.value.splice(0)
multifilelist(row.fileId).then(rps => {
if(rps && rps.length > 0){
// flist.value.push({
// id: rps.id,
// name: rps.originalName,
// status: 'finished', // 关键:状态设为 'finished' 表示上传完成
// url: rps.url, // 用于预览
// })
flist.value = rps.map((n:any) => {
return {
id: n.id,
name: n.originalName,
status: 'finished', // 关键:状态设为 'finished' 表示上传完成
url: n.url,
}
})
}
})
}else{
formData.id = ''
formData.ncCode = ''
formData.ncName = ''
formData.ncContent = ''
formData.workCenter = ''
formData.deviceId = ''
formData.deviceName = ''
formData.status = 1
// formData.isIssued = ''
// formData.issueTime = ''
// formData.issueBy = ''
formData.remark = ''
formData.fileId = ''
flist.value.splice(0)
}
if(type == 1 || type == 3){
generateNccode().then(rps => {
formData.ncCode = rps
})
}
}
function addEdi(){
formData.fileId = formData.fileId.replace(/,+$/,'')
if(isstype.value == 1){
return addnccode(formData)
}
if(isstype.value == 2){
return editccode(formData)
}
formData.id = ''
return issuecopy(formData)
}
function savehand() {
addformRef.value?.validate((e:any) => {
if (!e) {
addEdi().then(() => {
message.success(`${cztype[isstype.value]}成功`)
setTimeout(() => {
getlist()
addModel.value = false
},1500)
})
}
})
}
//表格选中
function rowKey(row:any) {
return row.id
}
let chearr = ref<any>([])
function handleCheck(v:any) {
chearr.value = v
console.log(v)
}
//删除
function delhand() {
if(chearr.value.length > 0){
batchIssue(chearr.value).then(() => {
message.success('操作成功')
})
}else{
message.error('请勾选设备')
}
}
//下发任务列表
//let isstasklist = ref<any>([])
//下发设备列表
//let issequiplist = ref<any>([])
let treeData:any = []
let xfsbvalue = ref<Array<string | number>>([])
let renderSourceList:any = ''
let options = ref<any>([]) //flattenTree(createData())
function flattenTree(list: undefined | any[]) {
const result: any[] = []
function flatten(_list: any[] = []) {
_list.forEach((item) => {
//result.push(item)
if(item.childList){
flatten(item.childList)
}else{
result.push(item)
}
})
}
flatten(list)
return result
}
//下发
let issueModel = ref(false)
// let issformData = reactive<any>({
// taskid:'',
// equis:''
// })
// const issaddrules = {
// taskid:[
// { required: true, message: '请选择下发任务', trigger: 'blur' }
// ],
// equis:[
// { required: true, message: '请选择下发设备', trigger: 'blur' }
// ]
// }
let issarr:any[] = []
let ncCode = ref<any>('')
function tranupdate(v:any) {
issarr = []
if(v.length > 0){
v.forEach((n:any) => {
if(n.split('-').length == 3){
issarr.push(n)
}
})
}
}
let ncid = ''
function issuehand(row:any) {
issueModel.value = true
issarr = []
ncid = row.id
ncCode.value = row.ncCode
}
function isssavehand() {
if(issarr.length > 0){
batchIssue({
//ncCode:ncid,
id:ncid,
ncCodeList:issarr
}).then(() => {
message.success('操作成功')
setTimeout(() => {
getlist()
issueModel.value = false
},1500)
})
}else{
message.warning('请选择设备')
}
}
//导出
//let selectedIds = ref<any>([])
function handleExport() {
exportNccode({}).then(rps => {
const url = window.URL.createObjectURL(rps)
const link = document.createElement('a')
link.href = url
link.download = 'NC代码数据.xlsx'
link.click()
window.URL.revokeObjectURL(url)
})
}
const deviceDocumentConnectionVisible = ref<Boolean>(false)
const title = ref<String>("")
const deviceDocumentConnection = reactive<any>({})
const connectionLoading = ref<boolean>(false)
const connectionPagination = reactive({
page: 1,
pageSize: 10,
itemCount: 0,
showSizePicker: true,
pageSizes: [10, 20, 50]
})
const deviceList = ref<Device[]>([])
const selectedDeviceIds = ref<any>([])
function handlerConnectionDevice(row:any) {
deviceDocumentConnectionVisible.value = true
title.value = row.ncName + "关联设备"
deviceDocumentConnection.sourceId = row.id
getDeviceList(deviceDocumentConnection.sourceId)
}
//取消|全选
const isAllCheck = computed({
get() {
return deviceList.value.length > 0 && selectedDeviceIds.value.length === deviceList.value.length
},
set(val) {
if (val) {
selectedDeviceIds.value = deviceList.value.map(item => item.id)
}else {
selectedDeviceIds.value = []
}
loadCreateApi()
}
})
const handleAllCheck = (val:boolean) => {
isAllCheck.value = val
}
// function rowKey(row:RowData){
// return row.id
// }
const handleUpateCheck = async (keys:Array<string | number>,)=>{
selectedDeviceIds.value = keys
loadCreateApi()
}
const loadCreateApi = async ()=>{
deviceDocumentConnection.deviceIds = selectedDeviceIds.value
deviceDocumentConnection.page = connectionPagination.page
deviceDocumentConnection.pageSize = connectionPagination.pageSize
try {
await deviceDocumentConnectionApi.createDevice(deviceDocumentConnection)
message.success("关联成功")
getDeviceList(deviceDocumentConnection.sourceId)
}catch (error) {
message.error("关联失败")
}
}
async function getDeviceList(id:any) {
try {
const res = await deviceApi.getDeviceByNcId({
ncId:id,
page:connectionPagination.page,
pageSize:connectionPagination.pageSize
})
deviceList.value = res.list
connectionPagination.itemCount = res.total
//回显
selectedDeviceIds.value = deviceList.value.filter((item:any) =>item.isBind).map(item=>item.id)
connectionLoading.value = false
}catch (error) {
message.error("获取关联异常")
connectionLoading.value = false
}
}
// 分页
function handleRelatePageChange(page: number) {
connectionPagination.page = page
getDeviceList(deviceDocumentConnection.sourceId)
}
function handleRelatePageSizeChange(pageSize: number) {
connectionPagination.pageSize = pageSize
connectionPagination.page = 1
getDeviceList(deviceDocumentConnection.sourceId)
}
const deviceColumns:DataTableColumns<Device> = [
{ type: 'selection' },
{title: '设备名称', key: 'deviceName',width:80},
{ title: "关联状态",key:"isBind",width:80,
render(row:any) {
const val = row.isBind;
if (val) {
return h(NTag, { type: "success" }, { default: () => "已关联" });
} else {
return h(NTag, { type: "default" }, { default: () => "未关联" });
}
}
}
]
getlist()
onMounted(() => {
//加载任务树
opertree().then(rps => {
treeData = rps
options.value = flattenTree(treeData)
renderSourceList = function (obj:any) {
return h(NTree, {
style: 'margin: 0 4px;',
keyField: 'value',
checkable: true,
selectable: false,
blockLine: true,
checkOnClick: true,
childrenField:'childList',
data: treeData,
cascade:true,
defaultExpandAll:true,
pattern:obj.pattern,
checkedKeys: xfsbvalue.value,
onUpdateCheckedKeys: (checkedKeys:any) => {
obj.onCheck(checkedKeys)
}
})
}
})
})
</script>
<style scoped>
</style>