提交代码

This commit is contained in:
shaoleiliu-netizen123 2026-08-14 16:38:45 +08:00
parent d12738722c
commit 26bfafc358
8 changed files with 229 additions and 9 deletions

View File

@ -185,5 +185,12 @@ export const deviceApi = {
method:"get",
params
})
},
getById(deviceId:number) {
return request({
url:`/biz/device/getByid/${deviceId}`,
method:"get"
})
}
}

View File

@ -103,9 +103,9 @@ export function exportNccode(params:any) {
}
//加载全部NC代码
export function loadAllNcCode() {
export function loadAllNcCode(id:number) {
return request({
url: `biz/ncCode/loadAllNcCode`,
url: `biz/ncCode/loadAllNcCode/${id}`,
method: 'get'
})
}

View File

@ -42,6 +42,8 @@ export interface OrderProcessPlan {
workshopId?: number | null
leftoverMaterials?:number | null
}
@ -189,6 +191,8 @@ export interface OrderProcessPlanVO {
currentOperNumber?: number
leftoverMaterials?:number
processList?: ProcessPlanItemVO[]
}

76
src/api/refillRecord.ts Normal file
View File

@ -0,0 +1,76 @@
import { request } from '@/utils/request'
// 补料记录 类型定义
export interface RefillRecord {
id?: number
processId?: number
num?: number
createTime?: string
createBy?: number
}
// 补料记录 API
export const refillRecordApi = {
// 分页查询
page(params: { page: number; pageSize: number; id?: number }) {
return request({ url: '/biz/refillRecord/page', method: 'get', params })
},
// 获取详情
detail(id: number) {
return request({ url: `/biz/refillRecord/${id}`, method: 'get' })
},
// 新增
create(data: RefillRecord) {
return request({ url: '/biz/refillRecord', method: 'post', data })
},
// 修改
update(data: RefillRecord) {
return request({ url: '/biz/refillRecord', method: 'put', data })
},
// 删除
delete(ids: number[]) {
return request({ url: `/biz/refillRecord/${ids.join(',')}`, method: 'delete' })
},
// 导出
export(params?: { ids?: number[]; 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/refillRecord/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/refillRecord/import`,
method: 'post',
data: formData,
headers: { 'Content-Type': 'multipart/form-data' }
})
},
// 下载导入模板
downloadTemplate() {
return request({ url: `/biz/refillRecord/template`, method: 'get', responseType: 'blob' })
},
//查询该工序补料数量
getRefillNumByProcessId(processId:number){
return request({
url:`/biz/refillRecord/getRefillNumByProcessId/${processId}`,
method:"get"
})
}
}

View File

@ -390,6 +390,7 @@ import { noticeApi, chatApi, type SysNotice, type ChatMessage } from '@/api/mess
import { iconMap as externalIconMap } from '@/utils/icons'
import ErrorReportModal from "@/components/ErrorReportModal.vue";
import {errorNotificationApi} from "@/api/errorNotification.ts";
import {deviceApi} from "@/api/device.ts";
const route = useRoute()
const router = useRouter()
@ -612,6 +613,8 @@ function stripHtml(html: string | undefined): string {
const notice = ref<SysNotice>( {})
async function handleNoticeClick(item: SysNotice) {
notice.value = item
const res = await deviceApi.getById(Number(notice.value.deviceId))
notice.value.deviceName = res
//
showErrorReportModal.value = true
//

View File

@ -157,6 +157,7 @@
@outsource="(p) => openOutsource(order, p)"
@view-model="(p) => openPlmModel(order, p)"
@submit-detail = "(p) => openDetailModel(order,p)"
@handleLeftoverMaterial = "(p) => openLeftoverMaterialModel(order,p)"
/>
</div>
</div>
@ -608,11 +609,69 @@
</n-space>
</template>
</n-modal>
<!--补料弹窗-->
<n-modal v-model:show="leftMaterialVisible" preset="card" title="工序补料" style="width: 800px">
<n-card>
<n-grid :cols="2">
<n-gi>
<span class="pgClass">物料编码</span>
<span>{{leftMaterialOrder.materialCode}}</span>
</n-gi>
<n-gi>
<span class="pgClass">物料名称</span>
<span>{{leftMaterialOrder.materialName}}</span>
</n-gi>
</n-grid>
<n-grid :cols="2">
<n-gi>
<span class="pgClass">工序编号</span>
<span>{{leftMaterialPlan.processCode}}</span>
</n-gi>
<n-gi>
<span class="pgClass">工序名称</span>
<span>{{leftMaterialPlan.processName}}</span>
</n-gi>
</n-grid>
<n-grid :cols="2">
<n-gi>
<span class="pgClass">可补料数</span>
<span style="color: #2080f0; font-weight: 600">{{leftMaterialPlan.enablefill}}</span>
</n-gi>
</n-grid>
</n-card>
<n-form ref="dispatchformRef" :model="planForm"
label-placement="left"
:rules="dispatchrules"
style="margin-top: 10px;"
label-width="80">
<n-grid :cols="2">
<n-gi :span="24">
<n-form-item label="补料数量" path="leftoverMaterials">
<n-input-number
v-model:value="planForm.leftoverMaterials"
:min="0"
:max="leftMaterialPlan.enablefill"
placeholder="输入补料数量"
/>
</n-form-item>
</n-gi>
</n-grid>
</n-form>
<template #footer>
<n-space justify="end">
<n-button size="small" @click="leftMaterialVisible = false">取消</n-button>
<n-button size="small" type="primary" @click="submitLeftoverMaterial">确定</n-button>
</n-space>
</template>
</n-modal>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, h, computed, type Component } from 'vue'
import {ref, reactive, onMounted, h, computed, type Component, toRaw} from 'vue'
import {
NButton, NSpace, NIcon, NTag, NSpin, NModal, NForm, NFormItem, NGrid, NGi,
NInput, NInputNumber, NDatePicker, NCheckbox, NEmpty, NPagination, NDropdown, NDescriptions,
@ -635,7 +694,7 @@ import {
type OrderProcessPlanVO,
type ProcessPlanItemVO,
type OutsourcingOptions,
type OutsourcingProcessOption,
type OutsourcingProcessOption, OrderProcessPlan,
} from '@/api/orderProcessPlan'
import { useUserStore } from '@/stores/user'
import ProcessFlowStepper from './components/ProcessFlowStepper.vue'
@ -646,6 +705,7 @@ import type { PlmModelOpenContext } from '@/api/plmModel'
import Pgitem from './pgitem.vue'
import ReportDetailPage from "@/views/biz/orderProcessPlan/components/ReportDetail.vue";
import OrderReportDetailPage from "@/views/biz/orderProcessPlan/components/OrderReportDetail.vue";
import {refillRecordApi} from "@/api/refillRecord.ts";
const message = useMessage()
@ -754,11 +814,48 @@ const processId = ref<number | null>(null)
function openDetailModel(order:ProcessPlanItemVO,process?:OrderProcessPlanVO) {
submitLogModalVisible.value = true
console.log(process.planId)
processId.value = process.planId
}
const leftMaterialVisible = ref<Boolean>(false)
const leftMaterialOrder = ref<ProcessPlanItemVO>({})
const leftMaterialPlan = ref<OrderProcessPlanVO>({})
const planForm = ref<OrderProcessPlanVO>({})
//
async function openLeftoverMaterialModel(order:ProcessPlanItemVO,process?:OrderProcessPlanVO) {
//
const res = await refillRecordApi.getRefillNumByProcessId(process.planId);
leftMaterialVisible.value = true
leftMaterialOrder.value = order
leftMaterialPlan.value = process
planForm.value.leftoverMaterials = 0;
leftMaterialPlan.value.enablefill = Number(leftMaterialPlan.value.scrapQty) - Number(res);
}
//
async function submitLeftoverMaterial(){
const rawPlan = toRaw(leftMaterialPlan.value)
let orderProcessPlan = {...rawPlan}
try {
//
await refillRecordApi.create({processId:orderProcessPlan.planId,num:planForm.value.leftoverMaterials})
message.success("补料成功")
loadData()
}catch (e) {
console.log("补料异常:"+e)
message.error("补料失败")
}finally {
leftMaterialVisible.value = false
}
}
const batchOptions = [
{ label: '全部展开', key: 'expandAll' },
{ label: '全部收起', key: 'collapseAll' },

View File

@ -51,7 +51,7 @@
</div>
<div class="flow-item">
<span>剩余物料</span>
<strong>{{ remainQty }}</strong>
<strong>{{ leftoverMaterials }}</strong>
</div>
<div class="flow-item">
@ -106,6 +106,13 @@
ghost
@click="emit('submitDetail', process)"
>汇报</n-button>
<n-button
:disabled="refillDisAbled"
size="tiny"
type="info"
ghost
@click="emit('handleLeftoverMaterial', process)"
>补料</n-button>
<n-button
size="tiny"
:type="process.processStatus === 4 ? 'success' : 'default'"
@ -121,10 +128,12 @@
</template>
<script setup lang="ts">
import { computed } from 'vue'
import {computed, onMounted, ref} from 'vue'
import { NButton, NIcon, NProgress, NTag } from 'naive-ui'
import { ChevronForwardOutline } from '@vicons/ionicons5'
import { PROCESS_STATUS_MAP, type ProcessPlanItemVO } from '@/api/orderProcessPlan'
import { refillRecordApi } from '@/api/refillRecord.ts'
const props = defineProps<{
process: ProcessPlanItemVO
@ -153,6 +162,7 @@ const emit = defineEmits<{
viewModel: [process: ProcessPlanItemVO]
outsource: [process: ProcessPlanItemVO]
submitDetail: [process: ProcessPlanItemVO]
handleLeftoverMaterial: [process: ProcessPlanItemVO]
}>()
const reportedQuantity = computed(() => props.process.reportedQuantity ?? 0)
@ -160,6 +170,8 @@ const totalQty = computed(() => props.process.quantity ?? 0)
const completedQty = computed(() => props.process.completedQty ?? 0)
const scrapQty = computed(() => props.process.scrapQty ?? 0)
const qualifiedQty = computed(() => Math.max(0, completedQty.value - scrapQty.value))
const leftoverMaterials = computed(() => props.process.leftoverMaterials ?? 0) //
const progressPct = computed(() => {
if (!totalQty.value) return 0
@ -171,7 +183,7 @@ const passRate = computed(() => {
return Math.round((qualifiedQty.value / completedQty.value) * 100)
})
const remainQty = computed(() => Math.max(0, totalQty.value - completedQty.value))
// const remainQty = computed(() => Math.max(0, totalQty.value - completedQty.value))
const statusTag = computed(() => {
const s = props.process.processStatus
@ -237,6 +249,22 @@ const planTimeText = computed(() => {
}
return start || end || '-'
})
const refillDisAbled = ref<Boolean>(false);
async function geRefillRecord() {
//
const res = await refillRecordApi.getRefillNumByProcessId(props.process.planId);
if (res >= props.process.scrapQty){
refillDisAbled.value = true
}
refillDisAbled.value = false
}
onMounted(()=>{
geRefillRecord()
})
</script>
<style scoped>

View File

@ -422,7 +422,12 @@ const columns: DataTableColumns<OrderProject> = [
const buttons = []
if (hasPermission('biz:orderProject:getKingdeeOrder')) {
buttons.push(
h(NButton, { size: 'small', quaternary: true, type: 'info', onClick: () => handleKingdeeQuery(row, false) }, {
h(NButton, {
size: 'small',
quaternary: true,
type: 'info',
disabled: row.status != 1,
onClick: () => handleKingdeeQuery(row, false) }, {
default: () => [h(NIcon, null, { default: () => h(EyeOutline) }), ' 预生产查询']
})
)