Compare commits

...

2 Commits

Author SHA1 Message Date
shaoleiliu-netizen123
3c02f65a44 Merge branch 'master' of https://git.evo-techina.com/sgc/mes-vue 2026-07-16 11:28:10 +08:00
shaoleiliu-netizen123
b259962512 修改工位 提前明细公共页面 2026-07-16 11:28:08 +08:00
11 changed files with 518 additions and 128 deletions

View File

@ -0,0 +1,84 @@
<template>
<n-form ref="formRef" :model="formDetailData" label-placement="left" label-width="80">
<n-form-item label="批次号/SN码" path="traceCode" label-width="100" v-show="showTraceCode">
<n-input v-model:value="formDetailData.traceCode" disabled />
</n-form-item>
<n-form-item label="判定数量" path="qty" label-width="100" >
<n-input-number v-model:value="formDetailData.qty"
placeholder="请输入判定数量" :min="0"
:disabled="disabled"
/>
</n-form-item>
<n-form-item label="备注" label-width="100">
<n-input
v-model:value="formDetailData.remark"
type="textarea"
placeholder="输入备注原因"
:disabled="disabled"
/>
</n-form-item>
</n-form>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import {qcResultDetailApi,QcResultDetail} from "@/api/qcResultDetail.ts";
const emit = defineEmits(['update:formDetailData'])
const props = defineProps({
id:Number,
formDetailData:Object as () => QcResultDetail,
disabled:Boolean,
showTraceCode:Boolean
})
let formDetailData = ref({...props.formDetailData})
let isInitLoading = true
watch(
()=> props.formDetailData,
(newVal)=>{
formDetailData.value = {...newVal}
},
{ deep: true, immediate: true }
)
watch(
formDetailData,
(newVal)=>{
// if (isInitLoading) {
// isInitLoading = false
// return
// }
emit('update:formDetailData',{...newVal})
},
{ deep: true, flush: 'post' }
)
async function loadData() {
if(!props.id) return
qcResultDetailApi.detail(props.id).then((res:any)=>{
formDetailData.value = { ...formDetailData.value, ...res }
})
}
// watch(() => props.id, (val: Number)=>{
// loadData();
// })
watch(() => props.id, (val: number)=>{
loadData();
})
onMounted(()=>{
loadData()
})
</script>

View File

@ -0,0 +1,138 @@
<template>
<n-tabs type="card" animated>
<n-tab-pane name="合格" tab="合格" v-if="showOkTab">
<SubmitDetailPage
key="ok"
:disabled="false"
:formDetailData="formDetailOKData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailOKData"
/>
</n-tab-pane>
<n-tab-pane name="报废" tab="报废" v-if="showScrapTab">
<SubmitDetailPage
key="scrap"
:disabled="false"
:formDetailData="formDetailScrapData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailScrapData"
/>
</n-tab-pane>
<n-tab-pane name="返工" tab="返工" v-if="showReworkTab">
<SubmitDetailPage
key="rework"
:disabled="false"
:formDetailData="formDetailReworkData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailReworkData"
/>
</n-tab-pane>
<n-tab-pane name="让步接收" tab="让步接收" v-if="showConnessionTab">
<SubmitDetailPage
key="conession"
:disabled="false"
:formDetailData="formDetailConcessionData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailConcessionData"
/>
</n-tab-pane>
</n-tabs>
</template>
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
import {
NButton, NSpace, useMessage
} from 'naive-ui'
import {useRoute} from "vue-router";
import {QcResultDetail} from "@/api/qcResultDetail.ts";
import { qualityTestingApi} from '@/api/qualityTesting'
import router from '@/router';
import SubmitDetailPage from '@/components/SubmitDetailPage.vue';
const props = defineProps({
showOkTab:Boolean,
showScrapTab:Boolean,
showReworkTab:Boolean,
showConnessionTab:Boolean,
showTraceCode:Boolean,
})
const message = useMessage()
const route = useRoute()
const traceCode = ref(String(route.params.traceCode))
const emit = defineEmits(['updateSubmitDetail'])
const submitDetail = reactive<any>({})
const defaultFormDetailData:QcResultDetail = {
qcId: undefined,
resultType: undefined,
qty: 0,
traceCode: undefined,
defectCode: undefined,
handleAction: undefined,
actionStatus: undefined,
remark: '',
title:undefined,
images:[],
attachments:[]
}
const formDetailOKData = reactive<QcResultDetail>({ ...defaultFormDetailData,traceCode:traceCode.value, resultType: 1,handleAction:'下一道工序',actionStatus:1 })
const formDetailScrapData = reactive<QcResultDetail>({ ...defaultFormDetailData,traceCode:traceCode.value,resultType: 2,handleAction:'报废次品',actionStatus:1 })
const formDetailReworkData = reactive<QcResultDetail>({ ...defaultFormDetailData,traceCode:traceCode.value,resultType: 3,handleAction:'返工',actionStatus:1 })
const formDetailConcessionData = reactive<QcResultDetail>({ ...defaultFormDetailData,traceCode:traceCode.value,resultType: 4,handleAction:'让步接收',actionStatus:1 })
function handleFormDetailOKData(formDetailData:QcResultDetail) {
console.log('===OK表单触发更新===', formDetailData)
Object.assign(formDetailOKData, formDetailData)
submitDetail.okData = formDetailOKData
}
function handleFormDetailScrapData(formDetailData:QcResultDetail) {
console.log('===报废表单触发更新===', formDetailData)
Object.assign(formDetailScrapData, formDetailData)
submitDetail.scrapData = formDetailScrapData
}
function handleFormDetailReworkData(formDetailData:QcResultDetail) {
Object.assign(formDetailReworkData, formDetailData)
}
function handleFormDetailConcessionData(formDetailData:QcResultDetail){
Object.assign(formDetailConcessionData, formDetailData)
}
watch(
submitDetail,
(newVal)=>{
console.log(newVal);
emit('updateSubmitDetail',{...newVal})
},{ deep: true }
)
function handleReset() {
Object.assign(formDetailOKData, { ...defaultFormDetailData, resultType: 1, handleAction: '下一道工序', actionStatus: 1 })
Object.assign(formDetailScrapData, { ...defaultFormDetailData, resultType: 2, handleAction: '报废次品', actionStatus: 1 })
Object.assign(formDetailReworkData, { ...defaultFormDetailData, resultType: 3, handleAction: '返工', actionStatus: 1 })
Object.assign(formDetailConcessionData, { ...defaultFormDetailData, resultType: 4, handleAction: '让步接收', actionStatus: 1 })
message.info("表单已重置")
}
</script>

View File

@ -63,15 +63,6 @@
<n-form ref="formRef" :model="formData" :rules="formRules" label-placement="left" label-width="100px">
<n-form-item label="设备名称" path="deviceName">
<n-input v-model:value="formData.deviceName" placeholder="请输入设备名称" />
</n-form-item>
<n-form-item label="设备类型" path="deviceTypeId">
<n-select
v-model:value="formData.deviceTypeId"
:options="deviceTypeList"
placeholder="请选择设备类型"
clearable
style="width: 200px"
/>
</n-form-item>
<n-form-item label="所属工段" path="sectionId">
<n-select
@ -82,8 +73,14 @@
style="width: 200px"
/>
</n-form-item>
<n-form-item label="设备规格型号" path="spec">
<n-input v-model:value="formData.spec" placeholder="请输入设备规格型号" />
<n-form-item label="设备类型" path="deviceTypeId">
<n-select
v-model:value="formData.deviceTypeId"
:options="deviceTypeList"
placeholder="请选择设备类型"
clearable
style="width: 200px"
/>
</n-form-item>
<n-form-item label="生产厂家" path="manufacturer">
<n-input v-model:value="formData.manufacturer" placeholder="请输入生产厂家" />
@ -148,7 +145,6 @@ import { NButton, NSpace,NTag, NIcon, NUpload, useMessage, useDialog, type DataT
import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline } from '@vicons/ionicons5'
import { deviceApi, type Device } from '@/api/device'
import { stationApi, type Station } from '@/api/station'
import { dictDataApi } from '@/api/org'
import {sectionApi, type Section} from '@/api/section'
@ -193,7 +189,8 @@ const defaultFormData: Device = {
manufactureDate: undefined,
workshopId: '',
remark: '',
status:''
status:0,
deviceFlag:'mes_equipment'
}
const formData = reactive<Device>({ ...defaultFormData })
@ -201,6 +198,8 @@ const formData = reactive<Device>({ ...defaultFormData })
const deviceTypeList = ref<{ label: string; value: any ;class:any}[]>([])
const statusList = ref<{ label: string; value: any ;class:any}[]>([])
const deviceFlagList = ref<{ label: string; value: any ;class:any}[]>([])
//
const formRules = {
}
@ -248,7 +247,8 @@ async function loadData() {
const res = await deviceApi.page({
page: pagination.page,
pageSize: pagination.pageSize,
deviceCode:searchForm.deviceCode
deviceCode:searchForm.deviceCode,
deviceFlag:"mes_equipment"
})
tableData.value = res.list
pagination.itemCount = res.total
@ -297,12 +297,7 @@ function handleAdd() {
//
function handleEdit(row: Device) {
modalTitle.value = '编辑设备表'
console.log(row);
Object.assign(formData, row)
if (formData.manufactureDate && typeof formData.manufactureDate === 'string') {
formData.manufactureDate = new Date(formData.manufactureDate.replace(' ', 'T')).getTime()
}
modalVisible.value = true
}
@ -432,6 +427,10 @@ async function loadDictOptions() {
const data = await dictDataApi.listByType("sys_status")
statusList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType("mes_device_flag")
deviceFlagList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
}

View File

@ -7,7 +7,10 @@
<n-input v-model:value="pauseform.processName" disabled />
</n-form-item>
<n-form-item label="报检数量" path="qcNum">
<n-input v-model:value="pauseform.qcNum" disabled />
<n-input v-model:value="pauseform.qcNum"
:disabled = "qcNumDisabled"
@input="handleQcNumChange"
/>
</n-form-item>
</n-form>
</template>
@ -17,12 +20,14 @@
import { ref, reactive, h, defineProps, onMounted, watch} from 'vue';
import { info } from '@/api/production'
const props = defineProps<{
const props = defineProps<{
id: number;
num: number
num: number;
qcNumDisabled:boolean
}>();
const emit = defineEmits(['updateWidth'])
const emit = defineEmits(['updateWidth','updateQcNum'])
let pauseform = reactive<any>({
id:'',
@ -38,6 +43,10 @@ async function loadData(){
}
function handleQcNumChange(){
emit('updateQcNum', pauseform.qcNum)
}
watch(() => props.id, (val: number)=>{
loadData();
})

View File

@ -95,7 +95,16 @@
</n-modal>
<n-modal v-model:show="modalCheckVisible" preset="card" :title="modalCheckTitle" :style="parentWidth" >
<AssingWorkVue v-if="modalCheckData?.businessCode === 'mes_assing_work'" :id="modalCheckData.businessId" :num="modalCheckData.quantity" @updateWidth="handleUpdateWidth"/>
<AssingWorkVue v-if="modalCheckData?.businessCode === 'mes_assing_work'"
:id="modalCheckData.businessId"
:num="modalCheckData.quantity"
:qcNumDisabled ="true"
@updateWidth="handleUpdateWidth"/>
<SubmitDetailPage
v-if="modalCheckData?.businessCode === 'mes_quality_testing'"
:id="modalCheckData.businessId"
:disabled="true"
/>
</n-modal>
<!-- 导入弹窗 -->
@ -109,6 +118,7 @@ import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline,
import { flowingAroundApi, type FlowingAround } from '@/api/flowingAround'
import { dictDataApi } from '@/api/org'
import AssingWorkVue from '@/views/biz/flowingAround/assingWork.vue'
import SubmitDetailPage from '@/components/SubmitDetailPage.vue'
const message = useMessage()
const dialog = useDialog()
@ -226,7 +236,7 @@ async function loadData() {
}
let parentWidth = ref('width: 40%;')
let parentWidth = ref('width: 20%;')
function handleUpdateWidth(width:string){
@ -273,6 +283,8 @@ const modalCheckData = ref<FlowingAround>()
const modalCheckTitle = ref('')
//
function handleView(row: FlowingAround){
console.log(row);
modalCheckTitle.value = '提交详情'
modalCheckData.value = row
modalCheckVisible.value = true

View File

@ -402,7 +402,7 @@ const dispatchLoading = ref(false)
const dispatchformRef = ref()
const dispatchform = reactive<any>({
id: '', name: '', beginTime: '', endTime: '', quantity: '',
list: [{ sectionId:'',deviceId:'',userId: '', quantity: '' }],
list: [{ sectionId:'',deviceList:'',userList: '', quantity: '' }],
})
const dispatchrules = {}
@ -606,11 +606,13 @@ function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
dispatchform.beginTime = entity.beginTime
dispatchform.endTime = entity.endTime
dispatchform.quantity = entity.quantity
dispatchform.list = [{ sectionId:'',deviceId:'',userId: '', quantity: '' }]
dispatchform.orderItemId = entity.orderItemId
dispatchform.sort = entity.sort
dispatchform.list = [{ sectionId:'',deviceList:'',userList: '', quantity: '' }]
}
function addpgnum() {
dispatchform.list.push({ sectionId:'',deviceId:'',userId: '', quantity: '' })
dispatchform.list.push({ sectionId:'',deviceList:'',userList: '', quantity: '' })
}
function deletenum(index: number) {
@ -619,13 +621,17 @@ function deletenum(index: number) {
function dispatchSubmit() {
let total = 0
dispatchform.list.forEach((n: any) => { total += Number(n.quantity) || 0 })
dispatchform.list.forEach((n: any) => {
total += Number(n.quantity) || 0
})
dispatchformRef.value?.validate((v: boolean) => {
if (v) return
if (total !== Number(dispatchform.quantity)) {
message.error('派工总数量需等于生产总数', { duration: 4000 })
return
}
dispatchLoading.value = true
orderProcessPlanApi.assignWork(dispatchform).then(() => {
message.success('派工成功')

View File

@ -27,19 +27,28 @@
<n-gi :span="10">
<n-form-item
label="指派工位"
:path="`${listname}[${index}].deviceId`"
:path="`${listname}[${index}].deviceList`"
:rule="{
required:true,
message:`请选择工位`,
trigger: 'blur'
trigger: 'blur',
validator: (rule, value, callback) => {
// value
if (!Array.isArray(value) || value.length === 0) {
callback(new Error('请选择工位'))
} else {
callback()
}
}
}"
>
<n-select
v-model:value="obj.deviceId"
v-model:value="obj.deviceList"
filterable
placeholder="请选择工位"
:options="deviceList"
:loading="loadingRef"
multiple
clearable
remote
:clear-filter-after-select="false"
@ -53,21 +62,30 @@
<n-gi :span="10">
<n-form-item
label="分配人员"
:path="`${listname}[${index}].userId`"
:path="`${listname}[${index}].userList`"
:rule="{
required: true,
message: '请选择员工',
trigger: 'blur'
trigger: 'blur',
validator: (rule, value, callback) => {
// value
if (!Array.isArray(value) || value.length === 0) {
callback(new Error('请选择员工'))
} else {
callback()
}
}
}"
>
<!--multiple-->
<n-select
v-model:value="obj.userId"
v-model:value="obj.userList"
filterable
placeholder="请输入用户名称搜索"
:options="yglist"
:loading="loadingRef"
clearable
multiple
remote
:clear-filter-after-select="false"
@search="slehand"

View File

@ -466,6 +466,7 @@ const columns: DataTableColumns<QualityTesting> = [
// { title: 'ID', key: 'orderId' },
// { title: 'ID', key: 'processId' },
// { title: 'ID', key: 'itemId' },
{ title: '追溯码', key: 'traceCode',align: 'center' },
{ title: '报检总数', key: 'totalQty',align: 'center' },
{ title: '已检验数量', key: 'inspectQty',align: 'center' },
{ title: '质检状态', key: 'status',align: 'center',
@ -508,12 +509,12 @@ const columns: DataTableColumns<QualityTesting> = [
{ label: '查看详情', key: 'view' },
{ type: 'divider' }, // 线
{ label: '提交判定明细', key: 'submitResultDetail',show:row.status == 1 },
{ type: 'divider',show:row.status == 1 }, // 线
{ label: '提交部分判定明细', key: 'submitBFResultDetail',show:(row.status == 1 || row.status == 2) },
// { type: 'divider',show:row.status == 1 }, // 线
// { label: '', key: 'submitBFResultDetail',show:(row.status == 1 || row.status == 2) },
{ type: 'divider',show:(row.status == 1 || row.status == 2) }, // 线
{ label: '查询判定明细', key: 'queryResultDetail' },
{ type: 'divider' }, // 线
{ label: '质检撤回', key: 'cancelQuality' },
// { type: 'divider' }, // 线
// { label: '', key: 'cancelQuality' },
],
//
onSelect: (key: string) => {
@ -524,15 +525,15 @@ const columns: DataTableColumns<QualityTesting> = [
case 'submitResultDetail':
submitResultDetail(row)
break
case 'submitBFResultDetail':
submitBFResultDetail(row)
break
// case 'submitBFResultDetail':
// submitBFResultDetail(row)
// break
case 'queryResultDetail':
queryResultDetail(row)
break
case 'cancelQuality':
handleCancelQuality(row)
break
// case 'cancelQuality':
// handleCancelQuality(row)
// break
}
}
}, {
@ -844,7 +845,7 @@ function submitResultDetail(row:any) {
submitFlag.value = true
let path = `/qc/submitDetail/${row.qcNo}/${row.id}/${submitFlag.value}/${traceCodeShow.value}`
let path = `/qc/submitDetail/${row.qcNo}/${row.id}/${submitFlag.value}/${row.traceCode}`
router.push(path)
}

View File

@ -4,8 +4,8 @@
<!-- 搜索表单 -->
<div class="search-form">
<n-form inline :model="searchForm" label-placement="left">
<n-form-item label="工位编码">
<n-input v-model:value="searchForm.stationCode" placeholder="请输入工位编码" clearable />
<n-form-item label="主键ID">
<n-input v-model:value="searchForm.deviceCode" placeholder="请输入工位编码" clearable />
</n-form-item>
<n-form-item>
<n-space>
@ -61,10 +61,10 @@
<!-- 新增/编辑弹窗 -->
<n-modal v-model:show="modalVisible" preset="card" :title="modalTitle" style="width: 600px">
<n-form ref="formRef" :model="formData" :rules="formRules" label-placement="left" label-width="100px">
<n-form-item label="工位名称" path="stationName">
<n-input v-model:value="formData.stationName" placeholder="请输入工位名称" />
<n-form-item label="工位名称" path="deviceName">
<n-input v-model:value="formData.deviceName" placeholder="请输入设备名称" />
</n-form-item>
<n-form-item label="所属工段" path="sectionId">
<n-form-item label="所属工段" path="sectionId">
<n-select
v-model:value="formData.sectionId"
:options="sectionList"
@ -92,7 +92,7 @@
</n-modal>
<!-- 导入弹窗 -->
<n-modal v-model:show="importModalVisible" preset="card" title="导入工位表" style="width: 500px">
<n-modal v-model:show="importModalVisible" preset="card" title="导入设备表" style="width: 500px">
<n-space vertical>
<n-alert type="info">
<template #header>导入说明</template>
@ -128,20 +128,24 @@
import { ref, reactive, h, onMounted } from 'vue'
import { NButton, NSpace,NTag, NIcon, NUpload, useMessage, useDialog, type DataTableColumns, type UploadCustomRequestOptions } from 'naive-ui'
import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline } from '@vicons/ionicons5'
import { stationApi, type Station } from '@/api/station'
import { deviceApi, type Device } from '@/api/device'
import { dictDataApi } from '@/api/org'
import {sectionApi, type Section} from '@/api/section'
const message = useMessage()
const dialog = useDialog()
let sectionList = reactive<{label:string,value:any}[]>([])
//
const searchForm = reactive({
stationCode: null as string | null,
deviceCode: null as number | null,
})
//
const tableData = ref<Station[]>([])
const tableData = ref<Device[]>([])
const loading = ref(false)
const selectedIds = ref<number[]>([])
const pagination = reactive({
@ -157,42 +161,48 @@ const modalVisible = ref(false)
const modalTitle = ref('')
const importModalVisible = ref(false)
const formRef = ref()
const defaultFormData: Station = {
id:'',
stationCode: '',
stationName: '',
sectionId: undefined,
status:undefined,
remark:undefined
const defaultFormData: Device = {
id:"",
deviceCode: '',
deviceName: '',
deviceTypeId: undefined,
deviceType:"",
sectionId: "",
sectionName:"",
spec: '',
manufacturer: '',
manufactureDate: undefined,
workshopId: '',
remark: '',
status:0,
deviceFlag:'mes_station'
}
const formData = reactive<Station>({ ...defaultFormData })
let sectionList = reactive<{label:string,value:any}[]>([])
const formData = reactive<Device>({ ...defaultFormData })
// //使
const deviceTypeList = ref<{ label: string; value: any ;class:any}[]>([])
const statusList = ref<{ label: string; value: any ;class:any}[]>([])
const deviceFlagList = ref<{ label: string; value: any ;class:any}[]>([])
//
const formRules = {
}
//
const columns: DataTableColumns<Station> = [
const columns: DataTableColumns<Device> = [
{ type: 'selection' },
{ title: '工位编码', key: 'stationCode' },
{ title: '工位名称', key: 'stationName' },
{ title: '工位编码', key: 'deviceCode' },
{ title: '工位名称', key: 'deviceName' },
{ title: '所属工段', key: 'sectionName' },
{ title: '备注', key: 'remark' },
{ title: '启用状态', key: 'status',
{ title: '状态', key: 'status',
render:(row) =>{
const val = row.status
const opt = statusList.value.find(o => o.value === val || String(o.value) === String(val))
if (!opt) return val ?? '-'
return h(NTag, { type: opt.class, size: 'small' }, { default: () => opt.label })
}
},
{ title: '创建时间', key: 'createTime' },
},
{
title: '操作',
key: 'actions',
@ -215,10 +225,11 @@ const columns: DataTableColumns<Station> = [
async function loadData() {
loading.value = true
try {
const res = await stationApi.page({
const res = await deviceApi.page({
page: pagination.page,
pageSize: pagination.pageSize,
stationCode: searchForm.stationCode || undefined,
deviceCode:searchForm.deviceCode,
deviceFlag:"mes_station"
})
tableData.value = res.list
pagination.itemCount = res.total
@ -235,7 +246,7 @@ function handleSearch() {
//
function handleReset() {
searchForm.stationCode = null
searchForm.deviceCode = null
handleSearch()
}
@ -259,14 +270,16 @@ function handleCheck(keys: Array<string | number>) {
//
function handleAdd() {
modalTitle.value = '新增工位表'
modalTitle.value = '新增设备表'
Object.assign(formData, defaultFormData)
modalVisible.value = true
}
//
function handleEdit(row: Station) {
modalTitle.value = '编辑工位表'
function handleEdit(row: Device) {
modalTitle.value = '编辑设备表'
console.log(row);
Object.assign(formData, row)
modalVisible.value = true
}
@ -275,12 +288,12 @@ function handleEdit(row: Station) {
async function handleSubmit() {
await formRef.value?.validate()
try {
const submitData = { ...formData } as Station
const submitData = { ...formData } as Device
if (submitData.id) {
await stationApi.update(submitData)
await deviceApi.update(submitData)
message.success('修改成功')
} else {
await stationApi.create(submitData)
await deviceApi.create(submitData)
message.success('新增成功')
}
modalVisible.value = false
@ -291,7 +304,7 @@ async function handleSubmit() {
}
//
function handleDelete(row: Station) {
function handleDelete(row: Device) {
dialog.warning({
title: '提示',
content: '确定要删除该记录吗?',
@ -299,7 +312,7 @@ function handleDelete(row: Station) {
negativeText: '取消',
onPositiveClick: async () => {
try {
await stationApi.delete([row.id!])
await deviceApi.delete([row.id!])
message.success('删除成功')
loadData()
} catch (error) {
@ -318,7 +331,7 @@ function handleBatchDelete() {
negativeText: '取消',
onPositiveClick: async () => {
try {
await stationApi.delete(selectedIds.value)
await deviceApi.delete(selectedIds.value)
message.success('删除成功')
selectedIds.value = []
loadData()
@ -334,12 +347,12 @@ async function handleExport() {
try {
const params: Record<string, any> = {}
if (selectedIds.value.length > 0) params.ids = selectedIds.value
if (searchForm.stationCode != null) params.stationCode = searchForm.stationCode
const blob = await stationApi.export(params)
if (searchForm.deviceCode != null) params.deviceCode = searchForm.deviceCode
const blob = await deviceApi.export(params)
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = '工位表数据.xlsx'
link.download = '设备表数据.xlsx'
link.click()
window.URL.revokeObjectURL(url)
} catch (error) {
@ -350,11 +363,11 @@ async function handleExport() {
//
async function handleDownloadTemplate() {
try {
const blob = await stationApi.downloadTemplate()
const blob = await deviceApi.downloadTemplate()
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = '工位表导入模板.xlsx'
link.download = '设备表导入模板.xlsx'
link.click()
window.URL.revokeObjectURL(url)
} catch (error) {
@ -366,7 +379,7 @@ async function handleDownloadTemplate() {
async function handleImportUpload({ file }: UploadCustomRequestOptions) {
if (!file.file) return
try {
const result = await stationApi.importData(file.file)
const result = await deviceApi.importData(file.file)
if (result.fail > 0) {
dialog.warning({
title: '导入结果',
@ -385,10 +398,19 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) {
//
async function loadDictOptions() {
try {
const data = await dictDataApi.listByType("sys_status")
statusList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType("device_type")
deviceTypeList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType("sys_status")
statusList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType("mes_device_flag")
deviceFlagList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
}

View File

@ -496,6 +496,24 @@ const columns = [
key: 'processName',
minWidth: 200
},
{
align:'center',
title:"追溯类型",
key:"traceType",
render(row:any) {
const val = row.traceType
if(val == 1) return '-'
if(val == 2) return '追溯码'
if(val == 3) return '批次码'
},
minWidth:80
},
// {
// align:'center',
// title:"/",
// key:"traceCode",
// minWidth:200
// },
{
align:'center',
title: '派工状态',
@ -557,6 +575,26 @@ const columns = [
key: 'reworkNum',
minWidth: 150
},
{
align:'center',
title:"是否质检",
key:"isQual",
minWidth:100,
render(row:any) {
const qual = row.isQual === 1
return h(NTag, {type: qual ? 'error' : 'success', size: 'small'}, {default: () => (qual ? '是' : '否')})
}
},
{
align:'center',
title:"是否直接入库",
key:"isStorage",
minWidth:120,
render(row:any) {
const storage = row.isQual === 1
return h(NTag, {type: storage ? 'error' : 'success', size: 'small'}, {default: () => (storage ? '是' : '否')})
}
},
{
align:'center',
title: '完成数量',

View File

@ -120,24 +120,20 @@
style="width: 400px"
:mask-closable="false"
>
<AssingWorkVue
:id="gxobg.id"
:qcNumDisabled ="false"
@updateQcNum="handleUpdateQcNum"
/>
<SumbitDetailCard
:showOkTab="true"
:showScrapTab="true"
:showReworkTab = false
:showTraceCode="false"
@updateSubmitDetail="handleSubmitDetail"
/>
<n-form
ref="pauseformRef"
:model="pauseform"
:rules="pauserules"
label-placement="top"
label-width="80"
>
<n-form-item label="工序编号">
<n-input v-model:value="gxobg.id" disabled />
</n-form-item>
<n-form-item label="工序名称">
<n-input v-model:value="gxobg.name" disabled />
</n-form-item>
<n-form-item label="报检数量" path="qcNum">
<n-input v-model:value="pauseform.qcNum" placeholder="请输入报检数量" />
</n-form-item>
</n-form>
<template #footer>
<n-space justify="end">
<n-button @click="pausemodal = false">取消</n-button>
@ -152,6 +148,7 @@
</n-modal>
</div>
</template>
@ -174,7 +171,7 @@ import {
// NGi,
NTag,
useMessage,
//useDialog,
useDialog,
//type FormInst,
} from 'naive-ui'
@ -191,8 +188,11 @@ import {
} from '@/api/production'
import PlmModelDrawer from '@/components/PlmModelDrawer.vue'
import type { PlmModelOpenContext } from '@/api/plmModel'
import AssingWorkVue from '@/views/biz/flowingAround/assingWork.vue'
import { qualityTestingApi, type QualityTesting } from '@/api/qualityTesting'
import SumbitDetailCard from '@/components/SumbitDetailCard.vue'
//const dialog = useDialog()
const dialog = useDialog()
const message = useMessage()
@ -431,7 +431,7 @@ const columns = [
align:'center',
title: '操作',
key: 'actions',
width: 100,
width: 250,
fixed: 'right',
render(row:any) {
const buttons:any = []
@ -442,7 +442,7 @@ const columns = [
type:'primary',
ghost:true,
onClick: () => { handlpause(row) } },
{ default: () => ''}
{ default: () => '完工汇报'}
))
}
buttons.push(h(NButton, {
@ -452,6 +452,13 @@ const columns = [
onClick: () => openPlmModel(row),
}, { default: () => '模型' }))
buttons.push(h(NButton, {
size: 'small',
type: 'info',
ghost: true,
onClick: ()=> cancelQuality(row)
}, { default: () => '质检撤回' }))
return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-'
}
}
@ -506,7 +513,9 @@ let gxobg = reactive<any>({})
let pausemodal = ref(false)
let pauseform = reactive<any>({
id:'',
qcNum:''
qcNum:'',
okData:undefined,
scrapData:undefined
})
const pauseformRef = ref()
@ -542,13 +551,39 @@ function handlpause(n:any) {
pauseformRef.value?.restoreValidation()
pauseform.id = n.id
//pauseform.qcNum = `${n.quantity}`
pauseform.qcNum = n.quantity-(n.completedQuantity ?? 0)
// pauseform.qcNum = n.quantity-(n.completedQuantity ?? 0)
}
function checkPauseSumbit():boolean {
if(pauseform.id == null) {
message.error("参数id为空")
return false
}
if(pauseform.qcNum == null || pauseform.qcNum == '') {
message.error("质检数量不能为空")
return false
}
//
const checkNum = pauseform.okData?.qty + pauseform.scrapData?.qty
if(checkNum != pauseform.qcNum) {
message.error("汇报数量总和不等于提交数量")
return false
}
return true
}
function pauseSubmit() {
pauseformRef.value?.validate((v:any) => {
if(!v){
pauseLoading.value = true
var pass = checkPauseSumbit();
console.log(pass);
if(!pass) return
pauseLoading.value = true
pauseisedbtn.value = true
inspectio(Object.assign({},pauseform,{qcNum:pauseform.qcNum*1})).then(() => {
message.success('操作成功!')
@ -561,11 +596,22 @@ function pauseSubmit() {
}).catch(() => {
pauseLoading.value = false
pauseisedbtn.value = false
})
}
})
}
function handleUpdateQcNum(qcNum:number) {
pauseform.qcNum = qcNum
}
function handleSubmitDetail(submitDetail:any){
pauseform.okData = submitDetail.okData
pauseform.scrapData = submitDetail.scrapData
console.log(pauseform);
}
//
async function loadDictOptions() {
try {
@ -588,10 +634,27 @@ async function loadDictOptions() {
// }
// })
// }
function cancelQuality(row:any) {
dialog.warning({
title: '提示',
content: '确定要撤回质检记录吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: async () => {
try {
await qualityTestingApi.cancel(row.id)
message.success('撤回成功')
getlist()
} catch (error) {
console.log("撤回失败"+error)
}
}
})
}
onMounted(() => {
getlist()
getlist()
loadDictOptions()
})