Merge remote-tracking branch 'origin/main'

pull/1/head
liutao 4 weeks ago
commit 2400608c78

@ -9,13 +9,14 @@ const props = defineProps({
modelValue: propTypes.bool.def(false),
title: propTypes.string.def('Dialog'),
fullscreen: propTypes.bool.def(true),
initialFullscreen: propTypes.bool.def(false),
width: propTypes.oneOfType([String, Number]).def('40%'),
scroll: propTypes.bool.def(false), // maxHeight
scroll: propTypes.bool.def(false),
maxHeight: propTypes.oneOfType([String, Number]).def('400px')
})
const getBindValue = computed(() => {
const delArr: string[] = ['fullscreen', 'title', 'maxHeight', 'appendToBody']
const delArr: string[] = ['fullscreen', 'initialFullscreen', 'title', 'maxHeight', 'appendToBody']
const attrs = useAttrs()
const obj = { ...attrs, ...props }
for (const key in obj) {
@ -26,7 +27,7 @@ const getBindValue = computed(() => {
return obj
})
const isFullscreen = ref(false)
const isFullscreen = ref(props.initialFullscreen)
const toggleFull = () => {
isFullscreen.value = !unref(isFullscreen)

@ -2737,6 +2737,7 @@ export default {
sampleMethod: 'Sampling Method',
val: 'Value',
item: 'Related Items',
product: 'Related Products',
remark: 'Remark',
createTime: 'Create Time',
operate: 'Operate',
@ -2750,6 +2751,8 @@ export default {
placeholderSampleMethod: 'Please select sampling method',
placeholderVal: 'Please input value',
placeholderItem: 'Please select inspection items',
placeholderProduct: 'Please select related products',
selectProductDialogTitle: 'Select Related Products',
placeholderRemark: 'Please input remark',
placeholderCreateTimeStart: 'Start Date',
placeholderCreateTimeEnd: 'End Date',
@ -3313,7 +3316,8 @@ export default {
detailDialogBoxingDatePlaceholder: 'Select boxing date',
detailDialogArriveDateLabel: 'Arrival Date',
detailDialogArriveDatePlaceholder: 'Select arrival date',
detailDialogRemarkLabel: 'Remark:',
detailDialogRemarkLabel: 'Remark',
detailDialogRemarkPlaceholder: 'Please enter remark',
detailDialogSubmitButtonText: 'Confirm',
detailDialogCancelButtonText: 'Cancel',
@ -3470,7 +3474,55 @@ export default {
validatorPlanFormTaskIdRequired: 'Task order can not be empty',
validatorPlanFormPlanNumberRequired: 'Quantity can not be empty',
validatorPlanFormPlanStartTimeRequired: 'Plan start time can not be empty',
validatorPlanFormPlanEndTimeRequired: 'Plan end time can not be empty'
validatorPlanFormPlanEndTimeRequired: 'Plan end time can not be empty',
scheduleDialogTitle: 'Schedule',
scheduleRuleLabel: 'Schedule Rule',
capacitySourceLabel: 'Capacity Source',
workTimeLabel: 'Work Time',
skipHolidayLabel: 'Skip Holidays',
confirmScheduleButton: 'Confirm Schedule',
scheduleFormCodeLabel: 'Task Order Code',
scheduleFormCodePlaceholder: 'Please input',
scheduleFormOrderDateLabel: 'Order Date',
scheduleFormDeliveryDateLabel: 'Delivery Date',
scheduleFormRemarkLabel: 'Remark',
scheduleFormRemarkPlaceholder: 'Please input',
scheduleFormInventoryTaskLabel: 'Inventory Task',
scheduleFormSearchButton: 'Search',
scheduleFormResetButton: 'Reset',
scheduleYesLabel: 'Yes',
scheduleNoLabel: 'No',
relateDeviceButton: 'Relate Device',
deviceRelationDialogTitle: 'Relate Device',
deviceRelationLabel: 'Related Device',
deviceRelationPlaceholder: 'Click to select device',
deviceRelationSaveButton: 'Save',
deviceRelationCancelButton: 'Cancel',
selectDeviceDialogTitle: 'Select Device',
deviceColumnCode: 'Device Code',
deviceColumnName: 'Device Name',
deviceColumnModel: 'Device Model',
deviceColumnWorkshop: 'Workshop',
scheduleRulePriority: 'Order Priority',
scheduleRuleCategory: 'Product Category Order',
scheduleRuleDelivery: 'Delivery Date Priority',
capacityTypeRated: 'Rated Capacity',
capacityTypeDailyAvg: 'Daily Report Average',
capacityTypeDataCollection: 'Data Collection Capacity',
inventoryTaskType: 'Inventory Task',
taskNoDetailWarning: 'Task order {code} has no detail data, cannot be selected',
partialTaskNoDetailWarning: 'Some task orders have no detail data, selection has been automatically cancelled',
taskItemNeedPrefix: 'Task Order-',
detailNoProductWarning: 'Current detail has no related product, cannot set device',
deviceRelationSaved: 'Device relation saved',
selectScheduleRuleWarning: 'Please select a schedule rule',
selectCapacitySourceWarning: 'Please select a capacity source',
selectWorkTimeWarning: 'Please select work time',
selectDetailWarning: 'Please select at least one task summary detail',
scheduleSubmitted: 'Schedule submitted',
startDatePlaceholder: 'Start Date',
endDatePlaceholder: 'End Date'
},
Plan: {

@ -2245,6 +2245,7 @@ export default {
sampleMethod: '抽检方式',
val: '值',
item: '关联项目',
product: '关联产品',
remark: '备注',
createTime: '创建时间',
operate: '操作',
@ -2258,6 +2259,8 @@ export default {
placeholderSampleMethod: '请选择抽检方式',
placeholderVal: '请输入值',
placeholderItem: '请选择检验项目',
placeholderProduct: '请选择关联产品',
selectProductDialogTitle: '选择关联产品',
placeholderRemark: '请输入备注',
placeholderCreateTimeStart: '开始日期',
placeholderCreateTimeEnd: '结束日期',
@ -3159,7 +3162,8 @@ export default {
detailDialogBoxingDatePlaceholder: '选择装柜日期',
detailDialogArriveDateLabel: '到达日期',
detailDialogArriveDatePlaceholder: '选择到达日期',
detailDialogRemarkLabel: '备注:',
detailDialogRemarkLabel: '备注',
detailDialogRemarkPlaceholder: '请输入备注',
detailDialogSubmitButtonText: '确 定',
detailDialogCancelButtonText: '取 消',
@ -3314,7 +3318,55 @@ export default {
validatorPlanFormTaskIdRequired: '任务单不能为空',
validatorPlanFormPlanNumberRequired: '数量不能为空',
validatorPlanFormPlanStartTimeRequired: '计划开始时间不能为空',
validatorPlanFormPlanEndTimeRequired: '计划结束时间不能为空'
validatorPlanFormPlanEndTimeRequired: '计划结束时间不能为空',
scheduleDialogTitle: '排产',
scheduleRuleLabel: '排产规则',
capacitySourceLabel: '产能来源',
workTimeLabel: '生产时间安排',
skipHolidayLabel: '是否跳过节假日',
confirmScheduleButton: '确认排产',
scheduleFormCodeLabel: '任务单编码',
scheduleFormCodePlaceholder: '请输入',
scheduleFormOrderDateLabel: '下达日期',
scheduleFormDeliveryDateLabel: '交货日期',
scheduleFormRemarkLabel: '备注',
scheduleFormRemarkPlaceholder: '请输入',
scheduleFormInventoryTaskLabel: '库存任务',
scheduleFormSearchButton: '查询',
scheduleFormResetButton: '重置',
scheduleYesLabel: '是',
scheduleNoLabel: '否',
relateDeviceButton: '关联设备',
deviceRelationDialogTitle: '关联设备',
deviceRelationLabel: '关联设备',
deviceRelationPlaceholder: '点击选择设备',
deviceRelationSaveButton: '保存',
deviceRelationCancelButton: '取消',
selectDeviceDialogTitle: '选择设备',
deviceColumnCode: '设备编号',
deviceColumnName: '设备名称',
deviceColumnModel: '设备型号',
deviceColumnWorkshop: '所属车间',
scheduleRulePriority: '订单优先级',
scheduleRuleCategory: '产品类别顺序',
scheduleRuleDelivery: '订单交期优先',
capacityTypeRated: '额定产能',
capacityTypeDailyAvg: '每日报工平均值',
capacityTypeDataCollection: '数据采集产能',
inventoryTaskType: '库存任务',
taskNoDetailWarning: '任务单 {code} 无任务明细数据,无法勾选',
partialTaskNoDetailWarning: '部分任务单无明细数据,已自动取消勾选',
taskItemNeedPrefix: '任务单-',
detailNoProductWarning: '当前明细没有关联产品,无法设置设备',
deviceRelationSaved: '关联设备已保存',
selectScheduleRuleWarning: '请选择排产规则',
selectCapacitySourceWarning: '请选择产能来源',
selectWorkTimeWarning: '请选择生产时间安排',
selectDetailWarning: '至少选一个任务单汇总明细的数据',
scheduleSubmitted: '排产已提交',
startDatePlaceholder: '开始日期',
endDatePlaceholder: '结束日期'
},
Plan: {
moduleName: '生产计划',

@ -87,7 +87,7 @@
/>
</el-form-item>
</el-col> -->
<el-col :span="12">
<!-- <el-col :span="12">
<el-form-item :label="t('FactoryModeling.ProductInformation.dialogPurchasePriceLabel')" prop="purchasePrice">
<el-input-number
v-model="formData.purchasePrice"
@ -119,20 +119,7 @@
class="!w-1/1"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('FactoryModeling.ProductInformation.dialogStatusLabel')" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-col> -->
<el-col v-if="isProductCategory" :span="12">
<el-form-item label="关联设备" prop="devices">
<el-input
@ -152,6 +139,19 @@
@click="openMoldSelectDialog"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('FactoryModeling.ProductInformation.dialogStatusLabel')" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col v-if="formType === 'update'" :span="24">
<el-form-item :label="t('FactoryModeling.ProductInformation.qrcode')" prop="qrcodeUrl">
@ -340,7 +340,7 @@ const deviceColumns = [
{ label: '设备编号', prop: 'deviceCode', minWidth: 140 },
{ label: '设备名称', prop: 'deviceName', minWidth: 160 },
{ label: '设备型号', prop: 'deviceModel', minWidth: 140 },
{ label: '所属车间', prop: 'workshop', minWidth: 140 }
{ label: '所属车间', prop: 'workshopName', minWidth: 140 }
]
const moldColumns = [
{ label: '模具编码', prop: 'code', minWidth: 140 },
@ -351,7 +351,8 @@ const moldColumns = [
const fetchDeviceLedgerPage = (params: Record<string, any>) => {
return DeviceLedgerApi.getDeviceLedgerPage({
...params,
isScheduled: 1
isScheduled: 1,
deviceStatus: 0
})
}
const openDeviceSelectDialog = () => {

@ -17,6 +17,7 @@
clearable
filterable
:placeholder="t('FactoryModeling.ProductBOM.detailMaterialPlaceholder')"
@change="(val) => handleProductChange(val, row)"
>
<el-option
v-for="item in productList"
@ -138,6 +139,16 @@ watch(
)
/** 原料选择变更时,自动带入单位 */
const handleProductChange = (productId: number | undefined, row: any) => {
if (productId) {
const product = productList.value.find((item) => item.id === productId)
row.unitId = product?.unitId ?? undefined
} else {
row.unitId = undefined
}
}
/** 新增按钮操作 */
const handleAdd = () => {
const row = {

@ -241,6 +241,6 @@ const handleExport = async () => {
onMounted(async () => {
await getList()
//
productList.value = await ProductApi.getProductSimpleList()
productList.value = await ProductApi.getMesProductSimpleList()
})
</script>

@ -323,7 +323,7 @@ const handleQuery = async(planId : number) => {
data.value = await PlanApi.getPlan(planId)
//console.log(data.value)
list.value = await ItemRequisitionApi.getItemRequisitionDetailListByItemRequisitionId(data.value.requisitionId)
recordData.value = list.value
recordData.value = list.value.map((item) => ({ ...item, weight: item.weight ?? 0 }))
to.value = list.total
}
</script>

@ -12,6 +12,11 @@
class="!w-360px"
/>
</el-form-item>
<el-form-item label="设备" prop="deviceIds">
<el-select v-model="queryParams.deviceIds" placeholder="请选择设备" clearable multiple collapse-tags class="!w-240px">
<el-option v-for="item in deviceOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" />查询</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
@ -21,7 +26,7 @@
<ContentWrap>
<div v-loading="loading">
<ScheduleGanttPanel :schedule-list="scheduleList" :editable="false" height="calc(100vh - 320px)" />
<ScheduleGanttPanel :schedule-list="filteredList" :editable="false" height="calc(100vh - 320px)" />
</div>
</ContentWrap>
</template>
@ -68,7 +73,20 @@ const buildDefaultRange = () => {
const queryRange = ref<string[]>(buildDefaultRange())
const queryParams = reactive({
startTime: queryRange.value[0],
endTime: queryRange.value[1]
endTime: queryRange.value[1],
deviceIds: [] as (string | number)[]
})
const deviceOptions = computed(() =>
scheduleList.value.map((device) => ({
label: device.deviceName,
value: device.deviceId
}))
)
const filteredList = computed(() => {
if (!queryParams.deviceIds.length) return scheduleList.value
return scheduleList.value.filter((device) => queryParams.deviceIds.includes(device.deviceId))
})
const getList = async () => {

@ -59,7 +59,7 @@
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<!-- <el-tab-pane label="所有" name="" /> -->
<el-tab-pane label="所有" name="" />
<!-- <el-tab-pane label="派工" name="0" /> -->
<el-tab-pane :label="t('ProductionPlan.Plan.tabPlannedLabel')" name="1" />
<el-tab-pane :label="t('ProductionPlan.Plan.tabStartLabel')" name="8" />
@ -282,7 +282,7 @@ const productList = ref<ProductVO[]>([]) // 产品列表
const taskList = ref<TaskVO[]>([]) //
/** 生产计划 列表 */
defineOptions({ name: 'Plan' })
const activeName = ref('1') // tab
const activeName = ref('') // tab
const message = useMessage() //
const { t } = useI18n() //

@ -64,24 +64,13 @@
<el-input-number
v-model="formData.packageNumber"
:min="0"
disabled
class="!w-1/1"
:placeholder="t('ProductionPlan.Task.detailDialogPackageNumberPlaceholder')"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<!-- <el-col :span="8">
<el-form-item label="条码" prop="barCode">
<el-input v-model="formData.barCode" placeholder="请输入条码" />
</el-form-item>
</el-col> -->
<el-col :span="8">
<el-form-item :label="t('ProductionPlan.Task.detailDialogTechRequirementsLabel')" prop="techRequirements">
<el-input v-model="formData.techRequirements" :placeholder="t('ProductionPlan.Task.detailDialogTechRequirementsPlaceholder')" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item :label="t('ProductionPlan.Task.detailFormDeliveryDateLabel')" prop="finishDate">
@ -94,7 +83,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<!-- <el-col :span="8">
<el-form-item :label="t('ProductionPlan.Task.detailDialogBoxingDateLabel')" prop="boxingDate">
<el-date-picker
v-model="formData.boxingDate"
@ -113,12 +102,20 @@
:placeholder="t('ProductionPlan.Task.detailDialogArriveDatePlaceholder')"
/>
</el-form-item>
</el-col>
</el-col> -->
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('ProductionPlan.Task.detailDialogTechRequirementsLabel')" prop="techRequirements">
<el-input v-model="formData.techRequirements" type="textarea" :rows="4" :placeholder="t('ProductionPlan.Task.detailDialogTechRequirementsPlaceholder')" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('ProductionPlan.Task.detailDialogRemarkLabel')" prop="remark">
<Editor disabled="disabled" v-model="formData.remark" height="500px" />
<el-input v-model="formData.remark" type="textarea" :rows="4" :placeholder="t('ProductionPlan.Task.detailDialogRemarkPlaceholder')" />
</el-form-item>
</el-col>
</el-row>
</el-form>
@ -180,7 +177,7 @@ const formRules = reactive({
unitId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailUnitIdRequired'), trigger: 'blur' }],
taskId: [{ required: true, message: t('ProductionPlan.Task.validatorDetailTaskIdRequired'), trigger: 'blur' }],
number: [{ required: true, message: t('ProductionPlan.Task.validatorDetailNumberRequired'), trigger: 'blur' }],
packageSize: [{ required: true, message: t('ProductionPlan.Task.validatorDetailPackageSizeRequired'), trigger: 'blur' }],
packageSize: [],
finishDate: [{ validator: validateFinishDate, trigger: ['change', 'blur'] }]
})
const formRef = ref() // Ref
@ -241,6 +238,22 @@ const submitForm = async () => {
}
}
/** 监听数量和每包数量变化,自动计算打包数量 */
watch(
() => [formData.value.number, formData.value.packageSize],
([number, packageSize]) => {
if (!number && number !== 0) {
formData.value.packageNumber = undefined
return
}
if (!packageSize || packageSize === 0) {
formData.value.packageNumber = number
} else {
formData.value.packageNumber = Math.ceil(number / packageSize)
}
}
)
/** 处理产品变更 */
const onChangeProduct = (productId) => {
const product = productList.value.find((item) => item.id === productId)

@ -54,6 +54,7 @@
排产
</el-button> -->
<el-button
v-if="![2,7,8,9,10].includes(props.taskStatus)"
link
type="primary"
@click="openForm('update', scope.row.id)"
@ -62,6 +63,7 @@
{{ t('ProductionPlan.Task.detailListEditActionText') }}
</el-button>
<el-button
v-if="![2,7,8,9,10].includes(props.taskStatus)"
link
type="danger"
@click="handleDelete(scope.row.id)"

@ -1,23 +1,23 @@
<template>
<Dialog v-model="dialogVisible" title="排产" width="80%" destroy-on-close align-center>
<Dialog v-model="dialogVisible" :title="t('ProductionPlan.TaskSummary.scheduleDialogTitle')" :initialFullscreen="true" destroy-on-close>
<div class="flex items-center gap-20px mb-16px">
<div class="flex items-center gap-8px">
<span class="text-red-500">*</span>
<span>排产规则</span>
<span>{{ t('ProductionPlan.TaskSummary.scheduleRuleLabel') }}</span>
<el-select v-model="searchForm.sortRule" class="!w-220px" clearable>
<el-option v-for="item in scheduleRuleOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="flex items-center gap-8px">
<span class="text-red-500">*</span>
<span>产能来源</span>
<span>{{ t('ProductionPlan.TaskSummary.capacitySourceLabel') }}</span>
<el-select v-model="searchForm.capacityType" class="!w-220px">
<el-option v-for="item in capacityTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="flex items-center gap-8px">
<span class="text-red-500">*</span>
<span>生产时间安排</span>
<span>{{ t('ProductionPlan.TaskSummary.workTimeLabel') }}</span>
<el-time-picker
v-model="searchForm.workTimeRange"
is-range
@ -30,52 +30,53 @@
/>
</div>
<div class="flex items-center gap-8px">
<span>是否跳过节假日</span>
<span>{{ t('ProductionPlan.TaskSummary.skipHolidayLabel') }}</span>
<el-switch v-model="searchForm.skipHoliday" />
</div>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit" class="ml-auto">{{ t('ProductionPlan.TaskSummary.confirmScheduleButton') }}</el-button>
</div>
<div class="border border-solid border-gray-200 rounded p-16px mt-16px">
<el-form :inline="true" :model="searchForm" label-width="90px" class="-mb-8px">
<el-form-item label="任务单编码">
<el-input v-model="searchForm.code" placeholder="请输入" clearable class="!w-200px" />
<el-form-item :label="t('ProductionPlan.TaskSummary.scheduleFormCodeLabel')">
<el-input v-model="searchForm.code" :placeholder="t('ProductionPlan.TaskSummary.scheduleFormCodePlaceholder')" clearable class="!w-200px" />
</el-form-item>
<el-form-item label="下达日期">
<el-form-item :label="t('ProductionPlan.TaskSummary.scheduleFormOrderDateLabel')">
<el-date-picker
v-model="searchForm.orderDate"
type="daterange"
value-format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
:start-placeholder="t('ProductionPlan.TaskSummary.startDatePlaceholder')"
:end-placeholder="t('ProductionPlan.TaskSummary.endDatePlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-260px"
/>
</el-form-item>
<el-form-item label="交货日期">
<el-form-item :label="t('ProductionPlan.TaskSummary.scheduleFormDeliveryDateLabel')">
<el-date-picker
v-model="searchForm.deliveryDate"
type="daterange"
value-format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
:start-placeholder="t('ProductionPlan.TaskSummary.startDatePlaceholder')"
:end-placeholder="t('ProductionPlan.TaskSummary.endDatePlaceholder')"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-260px"
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="searchForm.remark" placeholder="请输入" clearable class="!w-220px" />
<el-form-item :label="t('ProductionPlan.TaskSummary.scheduleFormRemarkLabel')">
<el-input v-model="searchForm.remark" :placeholder="t('ProductionPlan.TaskSummary.scheduleFormRemarkPlaceholder')" clearable class="!w-220px" />
</el-form-item>
<el-form-item label="库存任务">
<el-form-item :label="t('ProductionPlan.TaskSummary.scheduleFormInventoryTaskLabel')">
<div class="flex items-center gap-8px">
<el-switch v-model="searchForm.inventoryTaskSchedule" />
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">
<Icon icon="ep:search" class="mr-5px" /> 查询
<Icon icon="ep:search" class="mr-5px" /> {{ t('ProductionPlan.TaskSummary.scheduleFormSearchButton') }}
</el-button>
<el-button @click="handleReset">
<Icon icon="ep:refresh" class="mr-5px" /> 重置
<Icon icon="ep:refresh" class="mr-5px" /> {{ t('ProductionPlan.TaskSummary.scheduleFormResetButton') }}
</el-button>
</el-form-item>
</el-form>
@ -110,7 +111,7 @@
</el-table-column>
<el-table-column :label="t('ProductionPlan.TaskSummary.tableScheduleCompletedColumn')" align="center">
<template #default="scope">
<el-tag :type="scope.row.isScheduled ? 'success' : 'info'">{{ scope.row.isScheduled ? '是' : '否' }}</el-tag>
<el-tag :type="scope.row.isScheduled ? 'success' : 'info'">{{ scope.row.isScheduled ? t('ProductionPlan.TaskSummary.scheduleYesLabel') : t('ProductionPlan.TaskSummary.scheduleNoLabel') }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="t('ProductionPlan.Task.tableIsUrgentColumn')" align="center" prop="isUrgent" sortable>
@ -150,7 +151,7 @@
@select="handleDetailSelect"
@select-all="handleDetailSelectAll"
>
<el-table-column type="selection" width="55" :reserve-selection="true" align="center" />
<el-table-column type="selection" width="55" :reserve-selection="true" align="center" :selectable="isDetailRowSelectable" />
<el-table-column :label="t('ProductionPlan.TaskSummary.detailTableTaskCodeColumn')" align="center" prop="taskCode" sortable width="200px"/>
<el-table-column :label="t('ProductionPlan.TaskSummary.detailTableProductCodeColumn')" align="center" prop="barCode" sortable />
<el-table-column :label="t('ProductionPlan.TaskSummary.detailTableProductNameColumn')" align="center" prop="productName" sortable />
@ -170,17 +171,13 @@
{{ t('ProductionPlan.TaskSummary.detailActionMaterialLabel') }}
</el-button>
<el-button link type="primary" @click="openDeviceRelationDialog(scope.row)">
关联设备
{{ t('ProductionPlan.TaskSummary.relateDeviceButton') }}
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<template #footer>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit"></el-button>
<el-button @click="dialogVisible = false">取消</el-button>
</template>
</Dialog>
<TaskSchedulePreviewDialog
@ -189,26 +186,26 @@
@saved="handlePreviewSaved"
/>
<Dialog v-model="deviceRelationDialogVisible" title="关联设备" width="520px">
<Dialog v-model="deviceRelationDialogVisible" :title="t('ProductionPlan.TaskSummary.deviceRelationDialogTitle')" width="520px">
<el-form :model="deviceRelationForm" label-width="90px" v-loading="deviceRelationLoading">
<el-form-item label="关联设备">
<el-form-item :label="t('ProductionPlan.TaskSummary.deviceRelationLabel')">
<el-input
:model-value="deviceRelationDisplayText"
placeholder="点击选择设备"
:placeholder="t('ProductionPlan.TaskSummary.deviceRelationPlaceholder')"
readonly
@click="openDeviceSelectDialog"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" :loading="deviceRelationSaving" @click="submitDeviceRelation"></el-button>
<el-button @click="deviceRelationDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="deviceRelationSaving" @click="submitDeviceRelation">{{ t('ProductionPlan.TaskSummary.deviceRelationSaveButton') }}</el-button>
<el-button @click="deviceRelationDialogVisible = false">{{ t('ProductionPlan.TaskSummary.deviceRelationCancelButton') }}</el-button>
</template>
</Dialog>
<TableSelectDialog
ref="deviceSelectDialogRef"
title="选择设备"
:title="t('ProductionPlan.TaskSummary.selectDeviceDialogTitle')"
:columns="deviceColumns"
:fetch-api="fetchDeviceLedgerPage"
row-key="id"
@ -256,28 +253,28 @@ const deviceRelationForm = reactive({
devices: [] as { id: number; name: string }[]
})
const deviceColumns = [
{ label: '设备编号', prop: 'deviceCode', minWidth: 140 },
{ label: '设备名称', prop: 'deviceName', minWidth: 160 },
{ label: '设备型号', prop: 'deviceModel', minWidth: 140 },
{ label: '所属车间', prop: 'workshop', minWidth: 140 }
]
const deviceColumns = computed(() => [
{ label: t('ProductionPlan.TaskSummary.deviceColumnCode'), prop: 'deviceCode', minWidth: 140 },
{ label: t('ProductionPlan.TaskSummary.deviceColumnName'), prop: 'deviceName', minWidth: 160 },
{ label: t('ProductionPlan.TaskSummary.deviceColumnModel'), prop: 'deviceModel', minWidth: 140 },
{ label: t('ProductionPlan.TaskSummary.deviceColumnWorkshop'), prop: 'workshop', minWidth: 140 }
])
const deviceRelationDisplayText = computed(() => {
if (!deviceRelationForm.devices.length) return ''
if (!selectedDeviceRows.value.length) return deviceRelationForm.devices.map((item) => item.name).join('、')
return selectedDeviceRows.value.map((item) => item.deviceName || item.name || item.code || `ID:${item.id}`).join('、')
})
const scheduleRuleOptions = [
{ label: '订单优先级', value: 2 },
{ label: '产品类别顺序', value: 3 },
{ label: '订单交期优先', value: 4 }
]
const capacityTypeOptions = [
{ label: '额定产能', value: 1 },
{ label: '每日报工平均值', value: 2 },
{ label: '数据采集产能', value: 3 }
]
const scheduleRuleOptions = computed(() => [
{ label: t('ProductionPlan.TaskSummary.scheduleRulePriority'), value: 2 },
{ label: t('ProductionPlan.TaskSummary.scheduleRuleCategory'), value: 3 },
{ label: t('ProductionPlan.TaskSummary.scheduleRuleDelivery'), value: 4 }
])
const capacityTypeOptions = computed(() => [
{ label: t('ProductionPlan.TaskSummary.capacityTypeRated'), value: 1 },
{ label: t('ProductionPlan.TaskSummary.capacityTypeDailyAvg'), value: 2 },
{ label: t('ProductionPlan.TaskSummary.capacityTypeDataCollection'), value: 3 }
])
const searchForm = reactive({
inventoryTaskSchedule: false,
@ -387,7 +384,7 @@ const loadTaskList = async () => {
orderDate: searchForm.orderDate,
deliveryDate: searchForm.deliveryDate,
remark: searchForm.remark || undefined,
taskType: searchForm.inventoryTaskSchedule ? '库存任务' : undefined
taskType: searchForm.inventoryTaskSchedule ? t('ProductionPlan.TaskSummary.inventoryTaskType') : undefined
}
const data = await TaskApi.getPlanTaskPage(params)
taskList.value = data?.list ?? []
@ -452,7 +449,10 @@ const handleCurrentTaskChange = async (row: any) => {
const parentIsSelected = taskTableRef.value?.getSelectionRows()?.some((t: any) => t.id === row.id)
if (parentIsSelected) {
detailList.value.forEach(child => {
const unplanNumber = child.number - child.planNumber
if (unplanNumber > 0) {
detailTableRef.value?.toggleRowSelection(child, true)
}
})
}
})
@ -472,12 +472,15 @@ const handleTaskSelect = async (selection: any[], row: any) => {
await handleCurrentTaskChange(row)
const childList = allDetailsMap.value[row.id] || []
if (childList.length === 0) {
message.warning(`任务单 ${row.code} 无任务明细数据,无法勾选`)
message.warning(t('ProductionPlan.TaskSummary.taskNoDetailWarning', { code: row.code }))
taskTableRef.value?.toggleRowSelection(row, false)
return
}
detailList.value.forEach((child) => {
const unplanNumber = child.number - child.planNumber
if (unplanNumber > 0) {
detailTableRef.value?.toggleRowSelection(child, true)
}
})
return
}
@ -510,15 +513,18 @@ const handleTaskSelectAll = async (selection: any[]) => {
taskTableRef.value?.toggleRowSelection(row, false)
} else {
childList.forEach((child) => {
const unplanNumber = child.number - child.planNumber
if (unplanNumber > 0) {
const rowInView = detailList.value.find(d => d.id === child.id)
if (rowInView) {
detailTableRef.value?.toggleRowSelection(rowInView, true)
}
}
})
}
}
if (hasEmptyChild) {
message.warning('部分任务单无明细数据,已自动取消勾选')
message.warning(t('ProductionPlan.TaskSummary.partialTaskNoDetailWarning'))
}
} else {
detailTableRef.value?.clearSelection()
@ -531,10 +537,13 @@ const handleTaskSelectAll = async (selection: any[]) => {
const handleDetailSelect = (selection: any[], row: any) => {
const taskId = row.taskId
const childList = allDetailsMap.value[taskId] || []
const selectableChildren = childList.filter(child => {
const unplanNumber = child.number - child.planNumber
return unplanNumber > 0
})
// check if all children for this task are selected
const allChildrenSelected = childList.every(child => selection.some(sel => sel.id === child.id))
const noChildrenSelected = childList.every(child => !selection.some(sel => sel.id === child.id))
const allChildrenSelected = selectableChildren.length > 0 && selectableChildren.every(child => selection.some(sel => sel.id === child.id))
const noChildrenSelected = selectableChildren.every(child => !selection.some(sel => sel.id === child.id))
const parentTask = taskList.value.find(task => task.id === taskId)
if (parentTask) {
@ -551,14 +560,16 @@ const handleDetailSelectAll = (selection: any[]) => {
const taskId = currentTask.value.id
const childList = allDetailsMap.value[taskId] || []
const selectableChildren = childList.filter(child => {
const unplanNumber = child.number - child.planNumber
return unplanNumber > 0
})
const parentTask = taskList.value.find(task => task.id === taskId)
if (parentTask) {
// if any child in current view is selected, consider it an intent to select parent (if not all were selected)
// selection will contain all selected items across pages, so we need to filter for current view's task
const currentViewSelection = selection.filter(sel => sel.taskId === taskId)
if (currentViewSelection.length === childList.length && childList.length > 0) {
if (selectableChildren.length > 0 && currentViewSelection.length === selectableChildren.length) {
taskTableRef.value?.toggleRowSelection(parentTask, true)
} else if (currentViewSelection.length === 0) {
taskTableRef.value?.toggleRowSelection(parentTask, false)
@ -568,6 +579,11 @@ const handleDetailSelectAll = (selection: any[]) => {
const isTaskRowSelectable = () => !taskTableBusy.value && !detailLoading.value
const isDetailRowSelectable = (row: any) => {
const unplanNumber = row.number - row.planNumber
return unplanNumber > 0
}
const handleSearch = async () => {
queryParams.pageNo = 1
await loadTaskList()
@ -589,7 +605,7 @@ const handleReset = async () => {
const openTaskItemNeed = (row: any) => {
if (!row?.id) return
itemNeedRef.value.open('task', '任务单-' + (row?.code ?? ''), row.id)
itemNeedRef.value.open('task', t('ProductionPlan.TaskSummary.taskItemNeedPrefix') + (row?.code ?? ''), row.id)
}
const openProductItemNeed = (row: any) => {
@ -599,7 +615,7 @@ const openProductItemNeed = (row: any) => {
}
const openDeviceRelationDialog = async (row: any) => {
if (!row?.productId) {
message.warning('当前明细没有关联产品,无法设置设备')
message.warning(t('ProductionPlan.TaskSummary.detailNoProductWarning'))
return
}
currentDeviceRelationRow.value = row
@ -613,7 +629,7 @@ const openDeviceRelationDialog = async (row: any) => {
(productData as any).devices ?? (productData as any).deviceIds,
(productData as any).deviceList,
['name', 'deviceName', 'code'],
'设备'
t('ProductionPlan.TaskSummary.deviceColumnName')
)
deviceRelationForm.productId = Number(row.productId)
deviceRelationForm.devices = devices
@ -635,7 +651,7 @@ const handleDeviceSelectConfirm = (payload: { ids: (number | string)[]; rows: an
if (!Number.isFinite(id)) return undefined
return {
id,
name: item.deviceName || item.name || item.code || `设备ID:${id}`
name: item.deviceName || item.name || item.code || `${t('ProductionPlan.TaskSummary.deviceColumnName')}ID:${id}`
}
})
.filter((item): item is { id: number; name: string } => Boolean(item))
@ -658,7 +674,7 @@ const submitDeviceRelation = async () => {
currentData.molds ?? currentData.moldIds,
currentData.moldList,
['name', 'code'],
'模具'
t('ProductionPlan.TaskSummary.deviceColumnName')
)
const payload: any = {
...currentData,
@ -669,7 +685,7 @@ const submitDeviceRelation = async () => {
delete payload.molds
await ProductApi.updateProduct(payload)
await refreshDetailListAfterDeviceSaved()
message.success('关联设备已保存')
message.success(t('ProductionPlan.TaskSummary.deviceRelationSaved'))
deviceRelationDialogVisible.value = false
} finally {
deviceRelationSaving.value = false
@ -686,28 +702,32 @@ const hasValue = (value: unknown) => value !== null && value !== undefined && va
const handleSubmit = async () => {
if (searchForm.sortRule === undefined) {
message.warning('请选择排产规则')
message.warning(t('ProductionPlan.TaskSummary.selectScheduleRuleWarning'))
return
}
if (searchForm.capacityType === undefined) {
message.warning('请选择产能来源')
message.warning(t('ProductionPlan.TaskSummary.selectCapacitySourceWarning'))
return
}
const [workStartTime, workEndTime] = Array.isArray(searchForm.workTimeRange) ? searchForm.workTimeRange : []
if (!workStartTime || !workEndTime) {
message.warning('请选择生产时间安排')
message.warning(t('ProductionPlan.TaskSummary.selectWorkTimeWarning'))
return
}
const selectedRows = detailTableRef.value?.getSelectionRows() || []
if (selectedRows.length === 0) {
message.warning('至少选一个任务单汇总明细的数据')
const filteredRows = selectedRows.filter((row: any) => {
const unplanNumber = row.number - row.planNumber
return unplanNumber > 0
})
if (filteredRows.length === 0) {
message.warning(t('ProductionPlan.TaskSummary.selectDetailWarning'))
return
}
submitLoading.value = true
try {
console.log(selectedRows)
const createReqVO = selectedRows.map((row: any) => {
console.log(filteredRows)
const createReqVO = filteredRows.map((row: any) => {
const planNumber = row.number - row.planNumber > 0 ? row.number - row.planNumber : 0
return {
// PlanForm fields
@ -745,7 +765,7 @@ const handleSubmit = async () => {
? (scheduleResult as any).data
: []
previewScheduleList.value = scheduleData
message.success('排产已提交')
message.success(t('ProductionPlan.TaskSummary.scheduleSubmitted'))
previewVisible.value = true
emit('success')
} finally {

@ -1,6 +1,6 @@
<template>
<Dialog v-model="previewVisible" title="排产甘特图预览" width="100%" align-center>
<ScheduleGanttPanel :schedule-list="previewScheduleList" :editable="true" height="800px" />
<ScheduleGanttPanelEditable :schedule-list="previewScheduleList" height="800px" />
<template #footer>
<el-button type="primary" :loading="previewSaveLoading" @click="handlePreviewSave"></el-button>
<el-button @click="previewVisible = false">关闭</el-button>
@ -10,7 +10,7 @@
<script setup lang="ts">
import { PlanApi } from '@/api/mes/plan'
import ScheduleGanttPanel from '@/views/mes/components/ScheduleGanttPanel.vue'
import ScheduleGanttPanelEditable from './ScheduleGanttPanelEditable.vue'
import dayjs from 'dayjs'
defineOptions({ name: 'TaskSchedulePreviewDialog' })

@ -2,7 +2,14 @@
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px" v-loading="formLoading">
<el-form-item :label="t('QualityManagement.ZjTask.formCode')" prop="code">
<el-input v-model="formData.code" :placeholder="t('QualityManagement.ZjTask.placeholderFormCode')" />
<el-row :gutter="8" class="w-full">
<el-col :span="20">
<el-input v-model="formData.code" :placeholder="t('QualityManagement.ZjTask.placeholderFormCode')" :disabled="Boolean(formData.isCode) || formType === 'update'" />
</el-col>
<el-col :span="4">
<el-switch v-model="formData.isCode" :disabled="formType === 'update'" @change="handleCodeAutoChange" />
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="t('QualityManagement.ZjTask.formType')" prop="type">
<el-select v-model="formData.type" clearable filterable
@ -120,6 +127,7 @@ const planList = ref<PlanVO[]>([])
const formData = ref<{ [key: string]: any }>({
id: undefined,
code: undefined,
isCode: true,
name: undefined,
type: undefined,
schemaId: undefined,
@ -133,7 +141,17 @@ const formData = ref<{ [key: string]: any }>({
})
const formRules = reactive({
code: [{ required: true, message: t('QualityManagement.ZjTask.validatorCodeRequired'), trigger: 'blur' }],
code: [{ required: true, validator: (_rule, value, callback) => {
if (Boolean(formData.value.isCode)) {
callback()
return
}
if (value === undefined || value === null || String(value).trim() === '') {
callback(new Error(t('QualityManagement.ZjTask.validatorCodeRequired')))
return
}
callback()
}, trigger: 'blur' }],
type: [{ required: true, message: t('QualityManagement.ZjTask.validatorTypeRequired'), trigger: 'change' }],
schemaId: [{ required: true, message: t('QualityManagement.ZjTask.validatorSchemaRequired'), trigger: 'change' }],
ticket: [{ required: true, message: t('QualityManagement.ZjTask.validatorTicketRequired'), trigger: 'blur' }],
@ -150,6 +168,13 @@ const selectedSchemaId = ref<number | undefined>(undefined)
const orgTypeOptions = getStrDictOptions(DICT_TYPE.MES_ORG_TYPE)
const userList = ref<UserApi.UserVO[]>([])
const handleCodeAutoChange = (value: boolean) => {
if (value) {
formData.value.code = undefined
}
formRef.value?.clearValidate('code')
}
const formatSchemaVal = (val: string | number | null | undefined) => {
if (val === null || val === undefined || val === '') return ''
const text = String(val).trim()
@ -205,6 +230,7 @@ const resetForm = () => {
formData.value = {
id: undefined,
code: undefined,
isCode: true,
name: undefined,
type: undefined,
schemaId: undefined,

@ -49,20 +49,11 @@
<el-input :model-value="displayItemNames" readonly clearable class="device-ledger-selection-input"
:placeholder="t('QualityManagement.ZjSchema.placeholderItem')"
@click="openCriticalComponentDialog" @clear="clearBeijian" />
<!-- <el-row :gutter="8" class="w-full">
<el-col :span="22">
<el-input
:model-value="displayItemNames"
:placeholder="t('QualityManagement.ZjSchema.placeholderItem')"
readonly
/>
</el-col>
<el-col :span="2" class="text-right">
<el-button type="primary" @click="openItemDialog">
{{ t('action.select') }}
</el-button>
</el-col>
</el-row>-->
</el-form-item>
<el-form-item :label="t('QualityManagement.ZjSchema.product')" prop="product">
<el-input :model-value="displayProductNames" readonly clearable class="device-ledger-selection-input"
:placeholder="t('QualityManagement.ZjSchema.placeholderProduct')"
@click="openProductDialog" @clear="clearProduct" />
</el-form-item>
<el-form-item :label="t('QualityManagement.ZjSchema.remark')" prop="remark">
<el-input
@ -230,11 +221,69 @@
</el-button>
</template>
</el-dialog>
<el-dialog
v-model="productDialogVisible"
:title="t('QualityManagement.ZjSchema.selectProductDialogTitle')"
width="1300px"
draggable
>
<el-form class="-mb-15px" :model="productQueryParams" ref="productQueryFormRef" :inline="true" min-label-width="68px"
style="margin-bottom: 10px">
<el-form-item :label="t('FactoryModeling.ProductInformation.searchNameLabel')" prop="name">
<el-input
v-model="productQueryParams.name"
:placeholder="t('FactoryModeling.ProductInformation.searchNamePlaceholder')"
clearable
@keyup.enter="handleProductQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleProductQuery">
<Icon icon="ep:search" class="mr-5px" />
{{ t('common.query') }}
</el-button>
<el-button @click="resetProductQuery">
<Icon icon="ep:refresh" class="mr-5px" />
{{ t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
<ContentWrap>
<el-table ref="productTableRef" v-loading="productLoading" :data="productList" :stripe="true"
@selection-change="handleProductSelectionChange" @select="handleProductSelect" @select-all="handleProductSelectAll"
:show-overflow-tooltip="true" row-key="id">
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableBarCodeColumn')" align="center" prop="barCode" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableNameColumn')" align="left" prop="name" width="220px" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableStandardColumn')" align="center" prop="standard" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableCategoryColumn')" align="center" prop="subCategoryName" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableUnitColumn')" align="center" prop="unitName" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableStatusColumn')" align="center" prop="status" sortable>
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
</el-table>
<Pagination :total="productTotal" v-model:page="productQueryParams.pageNo" v-model:limit="productQueryParams.pageSize"
@pagination="getProductList" />
</ContentWrap>
<template #footer>
<el-button @click="productDialogVisible = false">
{{ t('common.cancel') }}
</el-button>
<el-button type="primary" @click="confirmSelectProducts">
{{ t('common.ok') }}
</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { getDictOptions } from '@/utils/dict'
import { DICT_TYPE } from '@/utils/dict'
import { ZjSchemaApi, ZjSchemaVO } from '@/api/mes/zjschema'
import { ZjItemApi, ZjItemVO } from '@/api/mes/zjitem'
import { ProductApi } from '@/api/erp/product/product'
import {ref} from "vue";
import {ElTable} from "element-plus";
import {ZjTypeApi, ZjTypeVO} from "@/api/mes/zjtype";
@ -266,6 +315,7 @@ const formData = ref({
sampleMethod: undefined as string | undefined,
val: undefined as string | undefined,
item: undefined as string | undefined,
product: undefined as string | undefined,
})
const rateVal = ref<number | undefined>(undefined)
const gapInterval = ref<number | undefined>(undefined)
@ -534,6 +584,7 @@ const resetForm = () => {
sampleMethod: undefined,
val: undefined,
item: undefined,
product: undefined,
}
rateVal.value = undefined
gapInterval.value = undefined
@ -543,6 +594,8 @@ const resetForm = () => {
targetKeyword.value = ''
sourceCheckedKeys.value = []
targetCheckedKeys.value = []
productIds.value = []
productSelectedRows.value = []
formRef.value?.resetFields()
}
@ -584,6 +637,118 @@ const initSelectedItems = async () => {
const ids = ref([])
const productDialogVisible = ref(false)
const productLoading = ref(false)
const productList = ref<any[]>([])
const productTotal = ref(0)
const productQueryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined as string | undefined,
categoryId: 2
})
const productQueryFormRef = ref()
const productTableRef = ref<InstanceType<typeof ElTable>>()
const productIds = ref<number[]>([])
const productSelectedRows = ref<any[]>([])
const displayProductNames = computed(() => {
if (!productIds.value.length) return ''
if (!productSelectedRows.value.length) {
return formData.value.product ? String(formData.value.product) : ''
}
const map = new Map(productSelectedRows.value.map((item) => [item.id, item.name]))
return productIds.value.map((id) => map.get(id)).filter(Boolean).join(',')
})
const openProductDialog = async () => {
productDialogVisible.value = true
const initIds = formData.value.product != undefined ? formData.value.product.toString().split(',') : []
productIds.value = initIds.map((id: string) => Number(id))
await getProductList()
nextTick(() => {
setProductDefaultSelections()
})
}
const getProductList = async () => {
productLoading.value = true
try {
const data = await ProductApi.getProductPage(productQueryParams)
productList.value = data.list
productTotal.value = data.total
nextTick(() => {
setProductDefaultSelections()
})
} finally {
productLoading.value = false
}
}
const setProductDefaultSelections = () => {
nextTick(() => {
if (!productTableRef.value) return
productTableRef.value.clearSelection()
productList.value.forEach((row) => {
if (productIds.value.includes(row.id)) {
productTableRef.value!.toggleRowSelection(row, true)
}
})
})
}
const handleProductSelectionChange = (rows: any[]) => {
const currentPageIds = rows.map((item) => item.id)
productSelectedRows.value = productSelectedRows.value.filter(
(item) => !currentPageIds.includes(item.id)
)
productSelectedRows.value.push(...rows)
}
const handleProductSelect = (selection: any[], row: any) => {
const isSelected = selection.includes(row)
if (isSelected) {
productIds.value.push(row.id)
} else {
productIds.value = productIds.value.filter((id) => id !== row.id)
}
}
const handleProductSelectAll = (selection: any[]) => {
const currentPageIds = productList.value.map((row) => row.id)
if (selection.length > 0) {
selection.forEach((row) => {
if (!productIds.value.includes(row.id)) {
productIds.value.push(row.id)
}
})
} else {
productIds.value = productIds.value.filter((id) => !currentPageIds.includes(id))
}
}
const confirmSelectProducts = () => {
formData.value.product = productIds.value.join(',')
productDialogVisible.value = false
}
const clearProduct = () => {
formData.value.product = ''
productIds.value = []
productSelectedRows.value = []
}
const handleProductQuery = () => {
productQueryParams.pageNo = 1
getProductList()
}
const resetProductQuery = () => {
productQueryFormRef.value.resetFields()
handleProductQuery()
}
const handleSelectionChange = (rows: ZjItemVO[]) => {
selectedIds.value = rows.map((r) => r.id).filter((id): id is number => typeof id === 'number')
// id

Loading…
Cancel
Save