mes-vue/src/views/lllustrated/index.vue
shaoleiliu-netizen123 eec8421b61 提交代码
2026-09-10 11:04:27 +08:00

981 lines
24 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="图文编号">
<n-input v-model:value="searchForm.drawingCode" placeholder="请输入图文编号"/>
</n-form-item>
<n-form-item label="图文名称">
<n-input v-model:value="searchForm.drawingName" placeholder="请输入图文名称"/>
</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:drawingFile:add')" type="primary" @click="addhand(1)" size="small">
<template #icon>
<n-icon>
<AddOutline/>
</n-icon>
</template>
新增
</n-button>
<n-button type="success" v-if="hasPermission('biz:drawingFile:export')" @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 v-if="pagination.itemCount > pagination.pageSize" 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="isstype.value == 1?'新增':'修改'"
preset="card"
style="width: 500px"
:mask-closable="false"
>
<n-form
ref="addformRef"
:model="formData"
:rules="addrules"
label-placement="left"
label-width="80"
>
<n-grid :cols="1" :x-gap="24">
<n-gi>
<n-form-item path="drawingCode" label="图文编号">
<n-input v-model:value="formData.drawingCode" disabled placeholder="自动生成"/>
</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>
<n-form-item path="drawingName" label="图文名称">
<n-input v-model:value="formData.drawingName" placeholder="请输入图文名称"/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="类型">
<n-radio-group v-model:value="formData.drawingType" :default-value="1" name="radiogroup">
<n-space>
<n-radio :value="0">
图纸
</n-radio>
<n-radio :value="1">
文件
</n-radio>
</n-space>
</n-radio-group>
</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"-->
<n-upload
directory-dnd
auto-upload="false"
:action="URL"
:headers="{
Authorization:TOKEN
}"
:max="20"
v-model:file-list="flist"
@finish="flchang"
accept=".pdf,.png,.jpg"
@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 path="gxname" label="备注">
<n-input type="textarea" v-model:value="formData.remark" placeholder="请输入备注" />
</n-form-item>
</n-gi> -->
</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;">图文编号</div>
<div style="padding: 2px 5px;border: 1px solid #50a5b7;border-radius: 0 6px 6px 0;">{{ imgCode }}</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 {
NButton,
NIcon,
NSpace,
NPagination,
NGrid,
NTree,
NTag,
useMessage,
useDialog, type DataTableColumns,
} from 'naive-ui'
import {
SearchOutline,
RefreshOutline,
AddOutline,
ArrowDownCircleOutline,
CloudUploadOutline
} from '@vicons/ionicons5'
import {useUserStore} from '@/stores/user'
import {
addDrawing,
editDrawing,
drawinglist,
drawingIssue,
deleteDrawing,
generateDFCode,
exportdraFile,
opertree,
multifilelist,
getDeviceByDrawingId
} from '@/api/illustrated'
import {
basicProcessPlanApi
} from '@/api/basicProcessPlan'
import {DeviceDocumentConnection, deviceDocumentConnectionApi} from "@/api/deviceDocumentConnection.ts";
import {Device} from "@/api/device.ts";
const URL = `${import.meta.env.VITE_APP_BASE_API}/sys/file/upload`
const dialog = useDialog()
const message = useMessage()
const userStore = useUserStore()
const TOKEN = userStore.token
// 权限检查
const hasPermission = (permission: string) => userStore.hasPermission(permission)
// ==================== 搜索表单 ====================
const searchForm = reactive({
page: 1,
pageSize: 20,
drawingCode: '',
drawingName: '',
drawingVersion: ''
})
// ==================== 表格 ====================
const datalist = ref<any>([])
const loading = ref(false)
//分页
const pagination = reactive({
page: 1,
pageSize: 20,
itemCount: 0
})
const columns = [
{
align: "center",
title: "图文编号",
key: "drawingCode",
minWidth: 150
},
{
align: "center",
title: "图文名称",
key: "drawingName",
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.isIssued == 1) {
return '已下发'
}
return '未下发'
}
},
{
align: "center",
title: "下发时间",
key: "issueTime",
minWidth: 150
},
{
align: "center",
title: "下发人",
key: "issueBy",
minWidth: 150
},
{
align: "center",
title: "备注",
key: "remark",
minWidth: 150
},
{
align: 'center',
title: '操作',
key: 'actions',
width: 320,
fixed: 'right',
render(row: any) {
const buttons: any = []
if (hasPermission('biz:drawingFile:issue')) {
buttons.push(h(NButton, {
size: 'small',
type: 'info',
ghost: true,
onClick: () => {
issuehand(row)
}
},
{default: () => '下发'}
))
}
if (hasPermission('biz:drawingFile:edit')) {
buttons.push(h(NButton, {
size: 'small',
type: 'primary',
ghost: true,
onClick: () => {
addhand(2, row)
}
},
{default: () => '编辑'}
))
}
if (hasPermission('biz:drawingFile:remove')) {
buttons.push(h(NButton, {
size: 'small',
type: 'error',
ghost: true,
onClick: () => {
dialog.warning({
title: '警告',
content: `你确定删除图文编号为:${row.drawingCode}的数据`,
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
deleteDrawing(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.drawingCode = ''
searchForm.drawingName = ''
searchForm.drawingVersion = ''
}
//获取列表数据
function getlist() {
drawinglist(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()
}
let loadingRef = ref(false)
let yglist = ref<any>([])
function slehand(v?: any) {
loadingRef.value = true
basicProcessPlanApi.page({
page: 1,
pageSize: 200,
name: v,
}).then((rps: any) => {
if (rps.list && rps.list.length > 0) {
yglist.value = rps.list.map((n: any) => {
return {
label: n.name,
value: n.id //`${n.id}-${n.code}-${n.name}`
}
})
}
loadingRef.value = false
}).catch(() => {
loadingRef.value = false
})
}
//新增
let addModel = ref(false)
const addformRef = ref()
let formData = reactive<any>({
id: '',
drawingCode: '', //图文编号
processId: '', //关联工序ID
drawingType: 0, //0 图纸 1 文件
fileId: '', //文件id
status: 1, //状态:1-启用 0-禁用
})
const addrules = {
drawingCode: [
{required: true, message: '请输入图文编号', trigger: 'blur'},
],
processId: [
{required: true, message: '请选择工序', trigger: 'blur'}
],
fileId: [
{required: true, message: '请上传文件', trigger: 'blur'}
]
}
//文件上传回调
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 + ','
}
console.log(formData.fileId)
}
let isstype = ref<any>(1)
let selval = ref<any>('')
function addhand(type: any, row?: any) {
addModel.value = true
formData.value?.restoreValidation()
isstype.value = type
if (row) {
formData.id = row.id
formData.drawingCode = row.drawingCode
formData.drawingName = row.drawingName
formData.processId = row.processId
formData.drawingType = row.drawingType
formData.fileId = row.fileId + ','
selval.value = row.processId
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,
}
})
}
})
// formData.drawingName = row.drawingName
// formData.drawingVersion = row.drawingVersion
// formData.processRouteStepId = row.processRouteStepId
// formData.processCode = row.processCode
// formData.processName = row.processName
// formData.filePath = row.filePath
// formData.fileName = row.fileName
// formData.fileSize = row.fileSize
// formData.fileType = row.fileType
// formData.plmDocId = row.plmDocId
// formData.plmVersion = row.plmVersion
// formData.plmStatus = row.plmStatus
// formData.status = row.status
// formData.remark = row.remark
} else {
formData.id = ''
formData.drawingCode = ''
formData.drawingName = ''
formData.processId = ''
formData.drawingType = 0
formData.status = 1
formData.fileId = ''
flist.value.splice(0)
// formData.drawingCode = ''
// formData.drawingName = ''
// formData.drawingVersion = ''
// formData.processRouteStepId = ''
// formData.processCode = ''
// formData.processName = ''
// formData.filePath = ''
// formData.fileName = ''
// formData.fileSize = ''
// formData.fileType = ''
// formData.plmDocId = ''
// formData.plmVersion = ''
// formData.plmStatus = ''
// formData.status = 1
// formData.remark = ''
generateDFCode().then(rps => {
formData.drawingCode = rps
})
}
}
function addEdi() {
if (isstype.value == 1) {
return addDrawing(formData)
}
return editDrawing(formData)
}
function savehand() {
addformRef.value?.validate((e: any) => {
if (!e) {
formData.fileId = formData.fileId.replace(/,+$/, '')
addEdi().then(() => {
message.success(isstype.value == 1 ? '新增成功' : '修改成功')
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)
}
//下发
let issueModel = ref(false)
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) => {
if (item.childList) {
flatten(item.childList)
} else {
result.push(item)
}
})
}
flatten(list)
return result
}
let issarr: any[] = []
let imgCode = ref<any>('')
function tranupdate(v: any) {
issarr = []
if (v.length > 0) {
v.forEach((n: any) => {
if (n.split('-').length == 3) {
issarr.push(n)
}
})
}
}
let imgid = ''
function issuehand(row: any) {
issueModel.value = true
issarr = []
imgid = row.id
imgCode.value = row.drawingCode
}
function flremove(n:any) {
let reg = new RegExp(`${n.file.id},?`)
formData.fileId = formData.fileId.replace(reg,'')
}
function isssavehand() {
if (issarr.length > 0) {
drawingIssue({
id: imgid,
twCode: issarr
}).then(() => {
message.success('操作成功')
setTimeout(() => {
getlist()
issueModel.value = false
}, 1500)
})
} else {
message.warning('请选择设备')
}
}
function handleExport() {
exportdraFile({}).then(rps => {
const url = window.URL.createObjectURL(rps)
const link = document.createElement('a')
link.href = url
link.download = '图文数据.xlsx'
link.click()
window.URL.revokeObjectURL(url)
})
}
const deviceDocumentConnectionVisible = ref<Boolean>(false)
const title = ref<String>("")
const deviceDocumentConnection = ref<DeviceDocumentConnection>({})
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<Device[]>([])
function handlerConnectionDevice(row:any) {
deviceDocumentConnectionVisible.value = true
title.value = row.drawingName + "关联设备"
deviceDocumentConnection.sourceId = row.drawingCode
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
}
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.createDeviceDraw(deviceDocumentConnection)
message.success("关联成功")
getDeviceList(deviceDocumentConnection.sourceId)
}catch (error) {
message.error("关联失败")
}
}
async function getDeviceList(id:number) {
try {
const res = await getDeviceByDrawingId({
drawId:id,
page:connectionPagination.page,
pageSize:connectionPagination.pageSize
})
deviceList.value = res.list
connectionPagination.itemCount = res.total
//回显
selectedDeviceIds.value = deviceList.value.filter(item=>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) {
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>