Compare commits

..

4 Commits

Author SHA1 Message Date
andy
d12738722c 修改 2026-08-14 14:22:26 +08:00
andy
e56f0900c6 Merge branch 'master' of https://git.evo-techina.com/sgc/mes-vue 2026-08-14 14:21:32 +08:00
andy
ef2463ec68 修改 2026-08-14 14:21:14 +08:00
andy
b5e07e6e64 修改 2026-08-10 15:59:53 +08:00
10 changed files with 356 additions and 36 deletions

View File

@ -0,0 +1,86 @@
<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="70" >
<n-input-number
style="width: 100%;"
v-model:value="formDetailData.qty"
placeholder="请输入判定数量" :min="0"
:disabled="disabled"
/>
</n-form-item>
<n-form-item label="备注" label-width="70">
<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,222 @@
<template>
<div style="margin: 20px;padding: 20px;border: 4px double #ccc;border-radius: 10px;">
<div style="margin-bottom: 20px;padding-bottom: 10px;font-size: 18px;color: #145165;border-bottom:1px solid #ccc;"><span style="padding-right: 20px;color: #5c6163;">批次号/SN码</span>{{ formDetailOKData.traceCode }}</div>
<div style="display: flex;justify-content: space-between;flex-wrap: wrap;">
<div style="width: 48%;margin-bottom: 20px;padding:15px 15px 0;border: 2px dashed #ccc;border-radius: 8px;">
<div style="margin-bottom: 20px;padding-bottom: 10px;font-size: 16px;color: #838282;border-bottom:1px solid #ccc;">合格</div>
<SubmitDetailPage1
key="ok"
:disabled="false"
:formDetailData="formDetailOKData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailOKData"
/>
</div>
<div style="width: 48%;margin-bottom: 20px;padding:15px 15px 0;border: 2px dashed #ccc;border-radius: 8px;">
<div style="margin-bottom: 20px;padding-bottom: 10px;font-size: 16px;color: #838282;border-bottom:1px solid #ccc;">报废</div>
<SubmitDetailPage1
key="scrap"
:disabled="false"
:formDetailData="formDetailScrapData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailScrapData"
/>
</div>
<div style="width: 48%;padding: 15px 15px 0;border: 2px dashed #ccc;border-radius: 8px;">
<div style="margin-bottom: 20px;padding-bottom: 10px;font-size: 16px;color: #838282;border-bottom:1px solid #ccc;">返工</div>
<SubmitDetailPage1
key="rework"
:disabled="false"
:formDetailData="formDetailReworkData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailReworkData"
/>
</div>
<div style="width: 48%;padding: 15px 15px 0;border: 2px dashed #ccc;border-radius: 8px;">
<div style="margin-bottom: 20px;padding-bottom: 10px;font-size: 16px;color: #838282;border-bottom:1px solid #ccc;">让步接收</div>
<SubmitDetailPage1
key="conession"
:disabled="false"
:formDetailData="formDetailConcessionData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailConcessionData"
/>
</div>
</div>
</div>
<!-- <n-tabs type="card" animated>
<n-tab-pane name="合格" tab="合格" v-if="showOkTab">
<SubmitDetailPage1
key="ok"
:disabled="false"
:formDetailData="formDetailOKData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailOKData"
/>
</n-tab-pane>
<n-tab-pane name="报废" tab="报废" v-if="showScrapTab">
<SubmitDetailPage1
key="scrap"
:disabled="false"
:formDetailData="formDetailScrapData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailScrapData"
/>
</n-tab-pane>
<n-tab-pane name="返工" tab="返工" v-if="showReworkTab">
<SubmitDetailPage1
key="rework"
:disabled="false"
:formDetailData="formDetailReworkData"
:showTraceCode="showTraceCode"
@update:formDetailData= "handleFormDetailReworkData"
/>
</n-tab-pane>
<n-tab-pane name="让步接收" tab="让步接收" v-if="showConnessionTab">
<SubmitDetailPage1
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, onMounted } from 'vue'
import {
NButton, NSpace, useMessage
} from 'naive-ui'
import {useRoute} from "vue-router";
import {qcResultDetailApi, type QcResultDetail} from "@/api/qcResultDetail.ts";
import { qualityTestingApi} from '@/api/qualityTesting'
import router from '@/router';
import SubmitDetailPage1 from '@/components/SubmitDetailPage1.vue';
const props = defineProps({
showOkTab:Boolean,
showScrapTab:Boolean,
showReworkTab:Boolean,
showConnessionTab:Boolean,
showTraceCode:Boolean,
qcId:Number
})
const message = useMessage()
const route = useRoute()
const traceCode = ref(String(route.params.traceCode))
const emit = defineEmits(['updateSubmitDetail','qcSumitDetail'])
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)
submitDetail.reworkData = formDetailReworkData
}
function handleFormDetailConcessionData(formDetailData:QcResultDetail){
Object.assign(formDetailConcessionData, formDetailData)
submitDetail.concessionData = formDetailConcessionData
}
watch(
submitDetail,
(newVal)=>{
emit('updateSubmitDetail',{...newVal})
},{ deep: true }
)
watch(
submitDetail,
(newVal)=>{
emit('qcSumitDetail',{...newVal})
}
)
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("表单已重置")
}
async function loadData() {
if(props.qcId == -1) return
const resultList = await qcResultDetailApi.selectlistByqcId(props.qcId);
Object.assign(formDetailOKData,{...resultList.formDetailOKData})
Object.assign(formDetailScrapData,{...resultList.formDetailScrapData})
Object.assign(formDetailReworkData, { ...resultList.formDetailReworkData})
Object.assign(formDetailConcessionData, { ...resultList.formDetailConsecctionData })
submitDetail.okData = resultList.formDetailOKData ?? { ...defaultFormDetailData, resultType: 1, handleAction: '下一道工序', actionStatus: 1 }
submitDetail.scrapData = resultList.formDetailScrapData ?? { ...defaultFormDetailData, resultType: 2, handleAction: '报废次品', actionStatus: 1 }
submitDetail.reworkData = resultList.formDetailReworkData ?? { ...defaultFormDetailData, resultType: 3, handleAction: '返工', actionStatus: 1 }
submitDetail.concessionData = resultList.formDetailConsecctionData ?? { ...defaultFormDetailData, resultType: 4, handleAction: '让步接收', actionStatus: 1 }
}
onMounted(()=>{
loadData()
})
</script>

View File

@ -215,13 +215,13 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/views/biz/device/board.vue'),
meta: { title: '设备状态监控', icon: 'PulseOutline' }
},
// 入库 管理
{
path: 'biz/stockIn',
name: 'BizStockIn',
component: () => import('@/views/biz/stockIn/index.vue'),
meta: { title: '入库管理', icon: 'ArchiveOutline' }
},
// 入库管理
// {
// path: 'biz/stockIn',
// name: 'BizStockIn',
// component: () => import('@/views/biz/stockIn/index.vue'),
// meta: { title: '入库管理', icon: 'ArchiveOutline' }
// },
// 甘特图排产
{
path: 'biz/orderProject/gantt',

View File

@ -563,7 +563,7 @@ body.dark-theme {
// 页面容器
.page-container {
padding: 20px;
min-height: calc(100vh - 60px);
//min-height: calc(100vh - 60px);
}
// 搜索表单

View File

@ -957,7 +957,7 @@ function handleExport() {
const deviceDocumentConnectionVisible = ref<Boolean>(false)
const title = ref<String>("")
const deviceDocumentConnection = ref<DeviceDocumentConnection>({})
const deviceDocumentConnection = reactive<any>({})
const connectionLoading = ref<boolean>(false)
const connectionPagination = reactive({
page: 1,
@ -968,7 +968,7 @@ const connectionPagination = reactive({
})
const deviceList = ref<Device[]>([])
const selectedDeviceIds = ref<Device[]>([])
const selectedDeviceIds = ref<any>([])
function handlerConnectionDevice(row:any) {
deviceDocumentConnectionVisible.value = true
@ -1022,7 +1022,7 @@ const loadCreateApi = async ()=>{
}
async function getDeviceList(id) {
async function getDeviceList(id:any) {
try {
const res = await deviceApi.getDeviceByNcId({
ncId:id,
@ -1033,7 +1033,7 @@ async function getDeviceList(id) {
connectionPagination.itemCount = res.total
//
selectedDeviceIds.value = deviceList.value.filter(item=>item.isBind).map(item=>item.id)
selectedDeviceIds.value = deviceList.value.filter((item:any) =>item.isBind).map(item=>item.id)
connectionLoading.value = false
}catch (error) {
message.error("获取关联异常")
@ -1059,7 +1059,7 @@ const deviceColumns:DataTableColumns<Device> = [
{ type: 'selection' },
{title: '设备名称', key: 'deviceName',width:80},
{ title: "关联状态",key:"isBind",width:80,
render(row) {
render(row:any) {
const val = row.isBind;
if (val) {
return h(NTag, { type: "success" }, { default: () => "已关联" });

View File

@ -113,9 +113,10 @@
</n-form-item>
<n-form-item label="所属工段" path="sectionId">
<n-tree-select
v-model:value="formData.sectionId"
v-model:value="formData.sectionId"
cascade
checkable
default-expand-all
:options="sectionList"
/>
</n-form-item>

View File

@ -240,14 +240,14 @@ const modalTitle = ref('')
const importModalVisible = ref(false)
const formRef = ref()
const defaultFormData = {
subscriptionKey: '',
subscriptionKey: undefined,
title: '',
subscriptionDeviceIds: '',
subscriptionDiscoverField: '',
subscriptionDiscoverField: undefined,
notifierMethod:1,
sendingMethod: [],
discoverValue: '',
detectionMethod: '',
detectionMethod: undefined,
notifier: '',
notifierContent: '',
abnormalReporting: undefined,
@ -306,10 +306,18 @@ userApi.getPathList().then(rps => {
})
// const itemOptions = computed(() => {
// if (!selectedCategory.value) {
// return [] //
// }
// return allItems[selectedCategory.value] || []
// })
function keyupdate(v:any,n:any) {
formData.subscriptionDiscoverField = ''
formData.subscriptionDiscoverField = null
yiczdopt.value = n.childList
console.log(v)
console.log(n)
}
@ -348,7 +356,7 @@ const columns: DataTableColumns<ErrorNotification> = [
minWidth:150,
render(row) {
const vals = Array.isArray(row.subscriptionDeviceIds) ? row.subscriptionDeviceIds : (row.subscriptionDeviceIds ? String(row.subscriptionDeviceIds).split(',') : [])
return vals.map(v => deviclist.value.find(o => String(o.value) === String(v))?.label ?? v).filter(Boolean).join(', ') || '-'
return vals.map(v => deviclist.value.find((o:any) => String(o.value) === String(v))?.label ?? v).filter(Boolean).join(', ') || '-'
},
},
@ -386,7 +394,7 @@ const columns: DataTableColumns<ErrorNotification> = [
minWidth:150,
render(row) {
const vals = Array.isArray(row.notifier) ? row.notifier : (row.notifier ? String(row.notifier).split(',') : [])
return vals.map(v => userlist.value.find(o => String(o.value) === String(v))?.label ?? v).filter(Boolean).join(', ') || '-'
return vals.map(v => userlist.value.find((o:any) => String(o.value) === String(v))?.label ?? v).filter(Boolean).join(', ') || '-'
},
},
{

View File

@ -393,9 +393,10 @@
</n-gi>
</n-grid>
</n-card>
<!--:rules="dispatchrules"-->
<n-form ref="dispatchformRef" :model="dispatchform"
label-placement="left"
:rules="dispatchrules"
style="margin-top: 10px;"
label-width="80">
<n-grid :cols="2">
@ -1244,7 +1245,7 @@ function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
dispatchform.sort = entity.sort
dispatchform.sectionId = entity.sectionId ?? process.sectionId ?? null
dispatchform.workshopId = entity.workshopId ?? process.workshopId ?? order?.workshopId ?? null
dispatchform.list = [{ sectionId: '', deviceId: '', quantity: remainQty || '',ncId:'' }]
dispatchform.list = [{ sectionId: '', deviceId: '', quantity: remainQty+'' || '',ncId:'' }]
}
function addpgnum() {

View File

@ -32,7 +32,7 @@
</div>
<!-- 工具栏 -->
<div class="table-toolbar">
<!-- <div class="table-toolbar">
<n-space>
<n-button type="primary" @click="handleAdd">
<template #icon><n-icon><AddOutline /></n-icon></template>
@ -51,7 +51,7 @@
删除
</n-button>
</n-space>
</div>
</div> -->
<!-- 表格 -->
<n-data-table
@ -225,8 +225,9 @@
</n-modal>
<!-- 提交判定明细抽屉 -->
<n-drawer v-model:show="showSubmitOuter" :width="800">
<SumbitDetailCard
<n-drawer v-model:show="showSubmitOuter" :width="900">
<SumbitDetailCard1
:mask-closable="false"
:showOkTab="true"
:showScrapTab="true"
:showReworkTab = true
@ -237,7 +238,8 @@
/>
<n-space justify="center" style="width: 100%; margin-top: 16px;">
<n-button size="small" @click="handleReset">重置</n-button>
<!-- <n-button size="small" @click="handleReset">重置</n-button> -->
<n-button size="small" @click="showSubmitOuter = false">取消</n-button>
<n-button type="primary" size="small" @click="handleSubmitResultDetail">提交</n-button>
</n-space>
</n-drawer>
@ -262,7 +264,7 @@ import {assingReworkApi} from '@/api/assingRework'
import { dictDataApi } from '@/api/org'
import {qcResultDetailApi, type QcResultDetail} from "@/api/qcResultDetail.ts";
import SumbitDetailCard from '@/components/SumbitDetailCard.vue'
import SumbitDetailCard1 from '@/components/SumbitDetailCard1.vue'
import router from "@/router";
@ -476,7 +478,7 @@ const formRules = {
//
const columns: DataTableColumns<QualityTesting> = [
{ type: 'selection' },
// { type: 'selection' },
{ title: '质检编号', key: 'qcNo',align: 'center' },
{
title: '物料名称',
@ -538,9 +540,9 @@ const columns: DataTableColumns<QualityTesting> = [
h(NButton, { size: 'small', quaternary: true, onClick: () => handleEdit(row) }, {
default: () => [h(NIcon, null, { default: () => h(CreateOutline) }), ' 编辑']
}),
h(NButton, { size: 'small', quaternary: true, type: 'error', onClick: () => handleDelete(row) }, {
default: () => [h(NIcon, null, { default: () => h(TrashOutline) }), ' 删除']
}),
// h(NButton, { size: 'small', quaternary: true, type: 'error', onClick: () => handleDelete(row) }, {
// default: () => [h(NIcon, null, { default: () => h(TrashOutline) }), ' ']
// }),
h(NDropdown, {
trigger: 'click', //
options: [
@ -930,7 +932,7 @@ function queryResultDetail(row:any) {
onMounted(() => {
loadData()
loadDictOptions()
loadAssignWorkOrder()
//loadAssignWorkOrder()
})
</script>

View File

@ -16,7 +16,7 @@ export default defineConfig({
emptyOutDir: true
},
server: {
host:'192.168.12.4', //true,
//host:'192.168.12.4', //true,
port: 3000,
proxy: {
'/api': {
@ -24,8 +24,8 @@ export default defineConfig({
// target:'http://192.168.12.4:8888/',
//target:'http://192.168.12.230:8888',
//target:'http://192.168.5.230:8888',
//target:'http://192.168.5.232:8888/',
target:'http://localhost:8888',
target:'http://192.168.5.232:8888/',
//target:'http://localhost:8888',
changeOrigin: true
},
'/druid': {