功能优化:任务单人员配置,供应商选择后,如果复选框没有选择,自动选择

This commit is contained in:
zxy 2026-01-13 16:31:41 +08:00
parent 1acef9b999
commit 73e6245496
15 changed files with 548 additions and 302 deletions

View File

@ -128,6 +128,7 @@ public interface ErrorCodeConstants {
ErrorCode TASK_DISPATCH_TASK_IS_OVER = new ErrorCode(1_009_007, "报工数量已完成"); ErrorCode TASK_DISPATCH_TASK_IS_OVER = new ErrorCode(1_009_007, "报工数量已完成");
ErrorCode TASK_DISPATCH_TASK_REPORT_AMOUNT_EXCESS = new ErrorCode(1_009_006, "无法超额报工"); ErrorCode TASK_DISPATCH_TASK_REPORT_AMOUNT_EXCESS = new ErrorCode(1_009_006, "无法超额报工");
ErrorCode TASK_REPORT_OTHER_PERSON_NO_SUBMIT = new ErrorCode(1_009_020, "其他人员尚未报工,无法结束生产"); ErrorCode TASK_REPORT_OTHER_PERSON_NO_SUBMIT = new ErrorCode(1_009_020, "其他人员尚未报工,无法结束生产");
ErrorCode THE_REPORT_APPLICATION_NOT_ENDED = new ErrorCode(1_009_021, "该报工没有结束,请刷新界面");
//1_009_021已被使用 //1_009_021已被使用
/*************质量管理***********/ /*************质量管理***********/
ErrorCode UNQUALIFIED_NOTIFICATION_NOT_EXISTS = new ErrorCode(1_010_001, "品质异常通知单审核不存在"); ErrorCode UNQUALIFIED_NOTIFICATION_NOT_EXISTS = new ErrorCode(1_010_001, "品质异常通知单审核不存在");

View File

@ -6,6 +6,7 @@ import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
import com.chanko.yunxi.mes.framework.common.util.object.BeanUtils; import com.chanko.yunxi.mes.framework.common.util.object.BeanUtils;
import com.chanko.yunxi.mes.framework.excel.core.util.ExcelUtils; import com.chanko.yunxi.mes.framework.excel.core.util.ExcelUtils;
import com.chanko.yunxi.mes.framework.operatelog.core.annotations.OperateLog; import com.chanko.yunxi.mes.framework.operatelog.core.annotations.OperateLog;
import com.chanko.yunxi.mes.module.heli.controller.admin.taskinreport.vo.TaskReworkReqVO;
import com.chanko.yunxi.mes.module.heli.controller.admin.taskreport.vo.TaskReportPageReqVO; import com.chanko.yunxi.mes.module.heli.controller.admin.taskreport.vo.TaskReportPageReqVO;
import com.chanko.yunxi.mes.module.heli.controller.admin.taskreport.vo.TaskReportRespVO; import com.chanko.yunxi.mes.module.heli.controller.admin.taskreport.vo.TaskReportRespVO;
import com.chanko.yunxi.mes.module.heli.controller.admin.taskreport.vo.TaskReportSaveReqVO; import com.chanko.yunxi.mes.module.heli.controller.admin.taskreport.vo.TaskReportSaveReqVO;
@ -52,6 +53,15 @@ public class TaskReportController {
return taskReportService.updateTaskReport(updateReqVO); return taskReportService.updateTaskReport(updateReqVO);
} }
@PostMapping("/rework")
@Operation(summary = "返工")
@PreAuthorize("@ss.hasPermission('heli:task-in-report:update')")
public CommonResult<Boolean> rework(@Valid @RequestBody TaskReworkReqVO reworkReqVO) {
taskReportService.rework(reworkReqVO.getId(), reworkReqVO.getRemark());
return success(true);
}
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除任务报工") @Operation(summary = "删除任务报工")
@Parameter(name = "id", description = "编号", required = true) @Parameter(name = "id", description = "编号", required = true)

View File

@ -106,4 +106,8 @@ public class TaskReportRespVO {
@Schema(description = "单位") @Schema(description = "单位")
private String unit; private String unit;
@Schema(description = "报工状态")
private String reportProcess;
} }

View File

@ -103,4 +103,7 @@ public class TaskReportDO extends BaseDO {
@TableField(exist = false) @TableField(exist = false)
private String unit; private String unit;
@TableField(exist = false)
private String reportProcess;
} }

View File

@ -241,7 +241,8 @@ public interface StorageInventoryMapper extends BaseMapperX<StorageInventoryDO>
query.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatSpec()),MaterialDO::getSpec, pageReqVO.getMatSpec()) query.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatSpec()),MaterialDO::getSpec, pageReqVO.getMatSpec())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatName()), MaterialDO::getName, pageReqVO.getMatName()) .like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatName()), MaterialDO::getName, pageReqVO.getMatName())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatCode()), MaterialDO::getCode, pageReqVO.getMatCode()) .like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatCode()), MaterialDO::getCode, pageReqVO.getMatCode())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getShortName()), MaterialDO::getShortName, pageReqVO.getShortName()) .like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getShortName()), StorageInventoryDO::getShortName, pageReqVO.getShortName())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getBoomSpec()), StorageInventoryDO::getBoomSpec, pageReqVO.getBoomSpec())
.eq(ObjectUtil.isNotEmpty(pageReqVO.getMatType()),MaterialDO::getMaterialType, pageReqVO.getMatType()) .eq(ObjectUtil.isNotEmpty(pageReqVO.getMatType()),MaterialDO::getMaterialType, pageReqVO.getMatType())
.eq(ObjectUtil.isNotEmpty(pageReqVO.getLotNo()),StorageInventoryDO::getLotNo, pageReqVO.getLotNo()) .eq(ObjectUtil.isNotEmpty(pageReqVO.getLotNo()),StorageInventoryDO::getLotNo, pageReqVO.getLotNo())
.eq(true,MaterialDO::getVirtualPart, YesOrNoEnum.N.name()) .eq(true,MaterialDO::getVirtualPart, YesOrNoEnum.N.name())

View File

@ -38,6 +38,7 @@ public interface TaskReportMapper extends BaseMapperX<TaskReportDO> {
query.selectAll(TaskReportDO.class) query.selectAll(TaskReportDO.class)
.select("d.code as projectCode", "d.project_name as projectName", "c.name as projectSubName") .select("d.code as projectCode", "d.project_name as projectName", "c.name as projectSubName")
.select("z.code as dispatchCode") .select("z.code as dispatchCode")
.select("x.report_process as reportProcess")
.select("f.material_name as materialName", "f.spec", "f.unit") .select("f.material_name as materialName", "f.spec", "f.unit")
.select("y.name as procedureName") .select("y.name as procedureName")
.select("u1.nickname as ownerName", "u2.nickname as updaterName") .select("u1.nickname as ownerName", "u2.nickname as updaterName")

View File

@ -54,4 +54,10 @@ public interface TaskReportService {
*/ */
PageResult<TaskReportDO> getTaskReportPage(TaskReportPageReqVO pageReqVO); PageResult<TaskReportDO> getTaskReportPage(TaskReportPageReqVO pageReqVO);
/**
* 返工
* @param id
* @param remark
*/
void rework(Long id, String remark);
} }

View File

@ -15,6 +15,8 @@ import com.chanko.yunxi.mes.framework.common.util.object.BeanUtils;
import com.chanko.yunxi.mes.module.heli.dal.mysql.taskreport.TaskReportMapper; import com.chanko.yunxi.mes.module.heli.dal.mysql.taskreport.TaskReportMapper;
import java.util.List;
import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.*; import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.*;
@ -86,6 +88,21 @@ public class TaskReportServiceImpl implements TaskReportService {
return taskReportMapper.selectPage(pageReqVO); return taskReportMapper.selectPage(pageReqVO);
} }
@Override
public void rework(Long id, String remark) {
TaskReportDO taskReportDO = taskReportMapper.selectById(id);
if (taskReportDO == null) {
throw exception(TASK_REPORT_NOT_EXISTS);
}
TaskDispatchDetailDO taskDispatchDetailDO = taskDispatchDetailMapper.selectById(taskReportDO.getDispatchDetailId());
if (taskDispatchDetailDO != null) {
if (taskDispatchDetailDO.getReportProcess() != 2) {
throw exception(THE_REPORT_APPLICATION_NOT_ENDED);
} else {
taskDispatchDetailDO.setReportProcess(1);
taskDispatchDetailDO.setReturnRemark(remark);
taskDispatchDetailMapper.updateById(taskDispatchDetailDO);
}
}
}
} }

View File

@ -33,6 +33,11 @@ export const updateTaskReport = async (data: TaskReportVO) => {
return await request.put({ url: `/heli/task-report/update`, data }) return await request.put({ url: `/heli/task-report/update`, data })
} }
// 返工
export const rework = async (data: TaskReportVO) => {
return await request.post({url: `/heli/task-report/rework`, data})
}
// 删除任务报工 // 删除任务报工
export const deleteTaskReport = async (id: number) => { export const deleteTaskReport = async (id: number) => {
return await request.delete({ url: `/heli/task-report/delete?id=` + id }) return await request.delete({ url: `/heli/task-report/delete?id=` + id })

View File

@ -1,118 +1,139 @@
<template> <template>
<!-- <Dialog :title="dialogTitle" v-model="dialogVisible">--> <!-- <Dialog :title="dialogTitle" v-model="dialogVisible">-->
<el-card class="hl-card" style="position: relative"> <el-card class="hl-card" style="position: relative">
<template #header>
<span>编辑页</span>
</template>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="160px" v-loading="formLoading">
<!-- 基础信息 -->
<el-card class="hl-card-info">
<template #header> <template #header>
<span>编辑页</span> <div class="hl-card-info-icona"></div><span class="hl-card-info-text">任务单类型</span>
</template> </template>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="160px" v-loading="formLoading"> </el-card>
<!-- 基础信息 --> <el-row>
<el-card class="hl-card-info"> <el-col :span="24">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">任务单类型</span>
</template>
</el-card>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="8">
<el-row> <el-row>
<el-col :span="8"> <el-col :span="24">
<el-row> <el-form-item label="业务类型" prop="type">
<el-col :span="24"> <el-select v-model="formData.type" placeholder="请选择业务类型" :disabled="true">
<el-form-item label="业务类型" prop="type"> <el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id" />
<el-select v-model="formData.type" placeholder="请选择业务类型" :disabled="true"> </el-select>
<el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id" /> </el-form-item>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="8">
<el-row>
<el-col :span="24">
<el-form-item label="岗位" prop="postId">
<el-select v-model="formData.postId" placeholder="请选择岗位">
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.HELI_POST)" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="8">
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-col> </el-col>
</el-row> </el-row>
</el-col> </el-col>
<el-card class="hl-card-info"> <el-col :span="8">
<template #header> <el-row>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">人员信息</span> <el-col :span="24">
</template> <el-form-item label="岗位" prop="postId">
<el-row> <el-select v-model="formData.postId" placeholder="请选择岗位">
<el-col> <el-option v-for="dict in getStrDictOptions(DICT_TYPE.HELI_POST)" :key="dict.value" :label="dict.label" :value="dict.value" />
<el-card class="hl-incard"> </el-select>
<el-col> </el-form-item>
<el-button type="primary" size="large" @click="userAddItem">新增</el-button> </el-col>
</el-col>
<el-form ref="subFormRef" :model="formData.userList" label-width="0">
<el-table :data="formData.userList" class="hl-table">
<el-table-column type="index" label="序号" align="center" min-width="60" fixed />
<el-table-column prop="description" min-width="200" label="业务人员" align="center">
<template #default="scope">
<el-select v-model="scope.row.busyId" filterable element-loading-background="rgb(255, 255, 255)" placeholder="请选择" >
<el-option v-for="item in userSelectList" :key="item.id" :label="item.username + ' ' + item.nickname" :value="item.id" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="postId" min-width="120" label="岗位" align="center">
<template #default="scope">
<el-select v-model="scope.row.postId" element-loading-background="rgb(255, 255, 255)" placeholder="请选择" >
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.HELI_POST)" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="procedureId" min-width="600" label="工序" align="center" >
<template #default="scope">
<el-select v-model="scope.row.procCd" multiple clearable element-loading-background="rgb(255, 255, 255)" filterable placeholder="请选择" style="width: 100%;">
<el-option
v-for="dict in procedureList" :key="dict.id"
:label="dict.name" :value="dict.id" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="description" min-width="200" label="是否是负责人" align="center">
<template #default="scope">
<el-select v-model="scope.row.isRes" element-loading-background="rgb(255, 255, 255)" placeholder="请选择" >
<el-option v-for="item in isResList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="120" fixed="right">
<template #default="scope">
<el-button link type="danger" size="small" @click.prevent="handleDeleteUser(scope.$index)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
</el-card>
</el-col>
</el-row>
</el-card>
</el-row> </el-row>
<div class="hl-footer text-center"> </el-col>
<el-button @click="submitForm" type="primary" size="large"> <el-col :span="8">
</el-button> <el-row>
<el-button @click="closeForm" size="large"> </el-button> <el-col :span="24">
</div> <el-form-item label="备注" prop="remark">
</el-form> <el-input v-model="formData.remark" placeholder="请输入备注" />
</el-card> </el-form-item>
<!-- </Dialog>--> </el-col>
</el-row>
</el-col>
</el-row>
</el-col>
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">人员信息</span>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-col>
<el-button type="primary" size="large" @click="userAddItem">新增</el-button>
</el-col>
<el-form ref="subFormRef" :model="formData.userList" label-width="0">
<el-table :data="formData.userList" class="hl-table">
<el-table-column type="index" label="序号" align="center" min-width="60" fixed />
<el-table-column prop="description" min-width="200" label="业务人员" align="center">
<template #default="scope">
<el-select
v-model="scope.row.busyId"
filterable
element-loading-background="rgb(255, 255, 255)"
placeholder="请选择"
@change="(val) => handleUserSelection(val, scope.row, scope.$index)">
<el-option
v-for="item in userSelectList"
:key="item.id"
:label="item.username + ' ' + item.nickname"
:value="item.id"
:disabled="isUserSelected(item.id)"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="postId" min-width="120" label="岗位" align="center">
<template #default="scope">
<el-select
v-model="scope.row.postId"
element-loading-background="rgb(255, 255, 255)"
placeholder="请选择"
@change="(val) => handlePostSelection(val, scope.row, scope.$index)">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.HELI_POST)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="procedureId" min-width="600" label="工序" align="center" >
<template #default="scope">
<el-select v-model="scope.row.procCd" multiple clearable element-loading-background="rgb(255, 255, 255)" filterable placeholder="请选择" style="width: 100%;">
<el-option
v-for="dict in procedureList" :key="dict.id"
:label="dict.name" :value="dict.id" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="description" min-width="200" label="是否是负责人" align="center">
<template #default="scope">
<el-select v-model="scope.row.isRes" element-loading-background="rgb(255, 255, 255)" placeholder="请选择" >
<el-option v-for="item in isResList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="120" fixed="right">
<template #default="scope">
<el-button link type="danger" size="small" @click.prevent="handleDeleteUser(scope.$index)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
</el-card>
</el-col>
</el-row>
</el-card>
</el-row>
<div class="hl-footer text-center">
<el-button @click="submitForm" type="primary" size="large">
</el-button>
<el-button @click="closeForm" size="large"> </el-button>
</div>
</el-form>
</el-card>
<!-- </Dialog>-->
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import * as FpUserDetailApi from '@/api/heli/fpuserdetail' import * as FpUserDetailApi from '@/api/heli/fpuserdetail'
@ -143,8 +164,6 @@ const formData = ref({
remark: undefined, remark: undefined,
userList: [], userList: [],
}) })
const formRules = reactive({
})
const queryParams = { const queryParams = {
pageNo: 1, pageNo: 1,
pageSize: 99, pageSize: 99,
@ -210,6 +229,59 @@ const closeForm = async () => {
router.push({ path: '/base/fpuserdetail' }) router.push({ path: '/base/fpuserdetail' })
tagsViewStore.delVisitedView(router.currentRoute.value) tagsViewStore.delVisitedView(router.currentRoute.value)
} }
//
const handleUserSelection = (userId: number, currentRow: any, currentIndex: number) => {
if (!userId) return //
//
const duplicateIndex = formData.value.userList.findIndex(
(user, index) =>
user.busyId === userId &&
user.postId === currentRow.postId &&
index !== currentIndex
)
if (duplicateIndex !== -1) {
message.error("该用户已在相同岗位被选择,请选择其他用户或岗位")
currentRow.busyId = '' //
return
}
}
//
const handlePostSelection = (postId: number, currentRow: any, currentIndex: number) => {
if (!postId || !currentRow.busyId) return //
//
const duplicateIndex = formData.value.userList.findIndex(
(user, index) =>
user.busyId === currentRow.busyId &&
user.postId === postId &&
index !== currentIndex
)
if (duplicateIndex !== -1) {
message.error("该用户已在相同岗位被选择,请选择其他岗位或用户")
currentRow.postId = '' //
return
}
}
//
//
const isUserSelected = (userId: number, currentPostId: number | null = null) => {
//
return formData.value.userList.some(
user => user.busyId === userId && user.postId === currentPostId
)
}
/** 提交表单 */ /** 提交表单 */
const emit = defineEmits(['success']) // success const emit = defineEmits(['success']) // success
const submitForm = async () => { const submitForm = async () => {
@ -229,8 +301,8 @@ const submitForm = async () => {
try { try {
// const data = FpUserDetailApi.createFpUserDetail(formData.value) // const data = FpUserDetailApi.createFpUserDetail(formData.value)
// if (formType.value === 'create') { // if (formType.value === 'create') {
await FpUserDetailApi.createFpUserDetail(formData.value) await FpUserDetailApi.createFpUserDetail(formData.value)
message.success(t('common.createSuccess')) message.success(t('common.createSuccess'))
// } else { // } else {
// await FpUserDetailApi.updateFpUserDetail(data) // await FpUserDetailApi.updateFpUserDetail(data)
// message.success(t('common.updateSuccess')) // message.success(t('common.updateSuccess'))

View File

@ -281,7 +281,7 @@ const handleDelete = async (id: number) => {
} catch {} } catch {}
} }
const getSummaries = (param: SummaryMethodProps) => { const getSummaries = (param: SummaryMethodProps) => {
const summaryField = ["cgYishou","remainingYishou","amount","remainingAmount"]; const summaryField = ["cgYs","cgYishou","remainingYishou","amount","remainingAmount"];
const { columns, data } = param; const { columns, data } = param;
const sums = []; const sums = [];
columns.forEach((column, index) => { columns.forEach((column, index) => {

View File

@ -82,168 +82,168 @@
<el-row> <el-row>
<el-col> <el-col>
<el-card class="hl-incard"> <el-card class="hl-incard">
<el-form ref="multipleTable" :model="list" v-loading="formLoading" label-width="0" > <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true"
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" class="hl-table" @selection-change="handleSelectionChange" show-summary :summary-method="getSummaries" :row-class-name="tableRowClassName"> ref="multipleTable" class="hl-table" @selection-change="handleSelectionChange"
<el-table-column type="selection" width="70" /> show-summary :summary-method="getSummaries" :row-class-name="tableRowClassName">
<el-table-column fixed label="序号" align="center" type="index" width="60" /> <el-table-column type="selection" width="70" />
<el-table-column fixed label="序号" align="center" type="index" width="60" />
<!-- <el-table-column label="客户简称" align="center" prop="brief" min-width="180" fixed />--> <!-- <el-table-column label="客户简称" align="center" prop="brief" min-width="180" fixed />-->
<el-table-column label="项目名称" align="center" prop="projectName" min-width="180" fixed /> <el-table-column label="项目名称" align="center" prop="projectName" min-width="180" fixed />
<el-table-column label="子项目名称" align="center" prop="projectSubName" min-width="180" /> <el-table-column label="子项目名称" align="center" prop="projectSubName" min-width="180" />
<el-table-column label="图号" align="center" prop="blueprintNo" min-width="120" /> <el-table-column label="图号" align="center" prop="blueprintNo" min-width="120" />
<!-- <el-table-column label="泡沫" align="center" prop="isFoams">--> <!-- <el-table-column label="泡沫" align="center" prop="isFoams">-->
<!-- <template #default="{ row }">--> <!-- <template #default="{ row }">-->
<!-- <el-checkbox v-model="row.isFoams" @change="handleOutsourcingChange(row)" disabled/>--> <!-- <el-checkbox v-model="row.isFoams" @change="handleOutsourcingChange(row)" disabled/>-->
<!-- </template>--> <!-- </template>-->
<!-- </el-table-column>--> <!-- </el-table-column>-->
<!-- <el-table-column min-width="200px" align="center" >--> <!-- <el-table-column min-width="200px" align="center" >-->
<!-- <template #header><span class="hl-table_header">*</span>泡沫费用</template>--> <!-- <template #header><span class="hl-table_header">*</span>泡沫费用</template>-->
<!-- <template #default="{ row, $index }">--> <!-- <template #default="{ row, $index }">-->
<!-- <el-form-item :prop="`${$index}.foamPrice`" class="mb-0px!" v-if="row.isFoams == 'Y'||row.isFoams==true">--> <!-- <el-form-item :prop="`${$index}.foamPrice`" class="mb-0px!" v-if="row.isFoams == 'Y'||row.isFoams==true">-->
<!-- <el-input-number v-model="row.foamPrice" type="number" :precision="0" />--> <!-- <el-input-number v-model="row.foamPrice" type="number" :precision="0" />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<!-- </template>--> <!-- </template>-->
<!-- </el-table-column>--> <!-- </el-table-column>-->
<el-table-column label="零件名称" align="center" prop="matName" min-width="180" /> <el-table-column label="零件名称" align="center" prop="matName" min-width="180" />
<el-table-column label="工序" align="center" prop="procedureName" min-width="100" > <el-table-column label="工序" align="center" prop="procedureName" min-width="100" >
<template #default="scope"> <template #default="scope">
<el-button text type="primary"> <el-button text type="primary">
{{ scope.row.procedureName }} {{ scope.row.procedureName }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="材质" align="center" prop="compositionName" min-width="120" /> <el-table-column label="材质" align="center" prop="compositionName" min-width="120" />
<el-table-column min-width="200px" align="center" > <el-table-column min-width="200px" align="center" >
<template #header>规格</template> <template #header>规格</template>
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.boomSpec`" class="mb-0px!" > <el-form-item :prop="`${$index}.boomSpec`" class="mb-0px!" >
<el-input class="!w-265px" v-model="row.boomSpec" placeholder="规格" /> <el-input class="!w-265px" v-model="row.boomSpec" placeholder="规格" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="需求数量" align="center" prop="boomAmount" min-width="120" /> <el-table-column label="需求数量" align="center" prop="boomAmount" min-width="120" />
<el-table-column label="单位" align="center" prop="unit" min-width="120"> <el-table-column label="单位" align="center" prop="unit" min-width="120">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_MATERIAL_UNIT" :value="scope.row.unit" /> <dict-tag :type="DICT_TYPE.HELI_MATERIAL_UNIT" :value="scope.row.unit" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column min-width="200px" align="center" prop="purchaseAmounts"> <el-table-column min-width="200px" align="center" prop="purchaseAmounts">
<template #header><span class="hl-table_header">*</span>采购数量</template> <template #header><span class="hl-table_header">*</span>采购数量</template>
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.purchaseAmounts`" class="mb-0px!" > <el-form-item :prop="`${$index}.purchaseAmounts`" class="mb-0px!" >
<el-input-number v-model="row.purchaseAmounts" type="number" :precision="0" /> <el-input-number v-model="row.purchaseAmounts" type="number" :precision="0" />
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="supplierIds" min-width="180" > <el-table-column align="center" prop="supplierIds" min-width="180" >
<template #header><span class="hl-table_header">*</span>供应商</template> <template #header><span class="hl-table_header">*</span>供应商</template>
<template #default="scope"> <template #default="scope">
<el-select <el-select
v-model="scope.row.supplierIds" v-model="scope.row.supplierIds"
size="large" size="large"
clearable clearable
filterable filterable
@change="change(scope.row)" @change="onSupplierChange(scope.row)"
style="width: 165px" style="width: 165px"
> >
<el-option
v-for="item in supplierList"
:key="item.id"
:label="item.brief"
:value="item.id"
/>
</el-select>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" prop="unitPrice">
<template #header><span class="hl-table_header">*</span>预估单价</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.unitPrice`" class="mb-0px!" >
<el-input
v-model="row.unitPrice"
type="number"
placeholder="两位小数"
@change="changeUnitPrice(row)"
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" prop="estimatedPrices">
<template #header><span class="hl-table_header">*</span>预估总价</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.estimatedPrices`" class="mb-0px!" >
<el-input
v-model="row.estimatedPrices"
type="number"
@change="changeEstimatedPrices(row)"
placeholder="两位小数"
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>预计到货日期</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.arriveTimes`" class="mb-0px!" >
<el-date-picker class="!w-265px" v-model="row.arriveTimes" type="date" value-format="x" placeholder="预计到货日期" @change="change1(row)"/>
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header>技术要求</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.descriptions`" class="mb-0px!" >
<el-input class="!w-265px" v-model="row.descriptions" placeholder="技术要求" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center">
<template #header>理论重量()</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.theWeight`" class="mb-0px!" >
<el-input-number v-model="row.theWeight" type="number" :precision="3" />
</el-form-item>
</template>
</el-table-column>
<!-- <el-table-column label="责任人" align="center" prop="duEmpName" min-width="120" />-->
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>责任人</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.duEmpId`" class="mb-0px!" >
<!-- <UserSelect v-model="row.duEmpId" class="!w-265px" clearable @update:newValue="handleSelectedUser($index, $event)"/>-->
<el-select class="!w-265px" v-model="row.duEmpId" clearable @update:new-value="handleSelectedUsers($index,$event)" @change="change2(row)" filterable>
<el-option <el-option
v-for="item in supplierList" v-for="dict in userInit" :key="dict.id"
:key="item.id" :label="dict.username+' '+dict.nickname" :value="dict.id" />
:label="item.brief"
:value="item.id"
/>
</el-select> </el-select>
</template> </el-form-item>
</el-table-column> </template>
<el-table-column min-width="200px" align="center" prop="unitPrice"> </el-table-column>
<template #header><span class="hl-table_header">*</span>预估单价</template> <el-table-column label="状态" align="center" prop="mplanStatus" min-width="120" >
<template #default="{ row, $index }"> <template #default="scope">
<el-form-item :prop="`${$index}.unitPrice`" class="mb-0px!" > {{
<el-input getIntDictOptions(DICT_TYPE.MATERIAL_PLAN_BOOM_MPLAN_STATUS).find(
v-model="row.unitPrice" (dict) => dict.value === scope.row.mplanStatus
type="number" )?.label || '未知状态'
placeholder="两位小数" }}
@change="changeUnitPrice(row)" </template>
</el-table-column>
/> <el-table-column label="打回原因" align="center" prop="rejRemark" min-width="120" />
</el-form-item> <el-table-column label="采购单号" align="center" prop="purchaseNo" min-width="180" />
</template> <el-table-column fixed="right" label="操作" align="center" min-width="100" >
</el-table-column> <template #default="scope">
<el-table-column min-width="200px" align="center" prop="estimatedPrices"> <el-button
<template #header><span class="hl-table_header">*</span>预估总价</template> v-if="scope.row.mplanStatus==1" link type="danger"
<template #default="{ row, $index }"> size="small" @click="handleDelete(scope.row.projectPurchaseOrderMakeDetailId)">
<el-form-item :prop="`${$index}.estimatedPrices`" class="mb-0px!" > 删除
<el-input </el-button>
v-model="row.estimatedPrices" </template>
type="number" </el-table-column>
@change="changeEstimatedPrices(row)" </el-table>
placeholder="两位小数" <!-- 分页 -->
/> <Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>预计到货日期</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.arriveTimes`" class="mb-0px!" >
<el-date-picker class="!w-265px" v-model="row.arriveTimes" type="date" value-format="x" placeholder="预计到货日期" @change="change1(row)"/>
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center" >
<template #header>技术要求</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.descriptions`" class="mb-0px!" >
<el-input class="!w-265px" v-model="row.descriptions" placeholder="技术要求" />
</el-form-item>
</template>
</el-table-column>
<el-table-column min-width="200px" align="center">
<template #header>理论重量()</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.theWeight`" class="mb-0px!" >
<el-input-number v-model="row.theWeight" type="number" :precision="3" />
</el-form-item>
</template>
</el-table-column>
<!-- <el-table-column label="责任人" align="center" prop="duEmpName" min-width="120" />-->
<el-table-column min-width="200px" align="center" >
<template #header><span class="hl-table_header">*</span>责任人</template>
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.duEmpId`" class="mb-0px!" >
<!-- <UserSelect v-model="row.duEmpId" class="!w-265px" clearable @update:newValue="handleSelectedUser($index, $event)"/>-->
<el-select class="!w-265px" v-model="row.duEmpId" clearable @update:new-value="handleSelectedUsers($index,$event)" @change="change2(row)" filterable>
<el-option
v-for="dict in userInit" :key="dict.id"
:label="dict.username+' '+dict.nickname" :value="dict.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="mplanStatus" min-width="120" >
<template #default="scope">
{{
getIntDictOptions(DICT_TYPE.MATERIAL_PLAN_BOOM_MPLAN_STATUS).find(
(dict) => dict.value === scope.row.mplanStatus
)?.label || '未知状态'
}}
</template>
</el-table-column>
<el-table-column label="打回原因" align="center" prop="rejRemark" min-width="120" />
<el-table-column label="采购单号" align="center" prop="purchaseNo" min-width="180" />
<el-table-column fixed="right" label="操作" align="center" min-width="100" >
<template #default="scope">
<el-button
v-if="scope.row.mplanStatus==1" link type="danger"
size="small" @click="handleDelete(scope.row.projectPurchaseOrderMakeDetailId)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-form>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
@ -535,7 +535,7 @@ const floatMul = (a, b) => {
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c); return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
} }
const changeUnitPrice =(row:any)=>{ const changeUnitPrice =(row:any)=>{
row.estimatedPrices=parseFloat((row.unitPrice* row.purchaseAmounts).toFixed(1)) row.estimatedPrices=parseFloat((row.unitPrice* row.purchaseAmounts).toFixed(1))
} }
const changeEstimatedPrices =(row:any)=>{ const changeEstimatedPrices =(row:any)=>{
@ -555,48 +555,55 @@ const change1 =(row:any)=>{
} }
} }
} }
const tableRowClassName = ({ row }) => { const tableRowClassName = ({ row }) => {
return row.isSelected ? 'selected-row' : ''; return row.isSelected ? 'selected-row' : '';
} }
const handleSelectionChange = (val) => { const handleSelectionChange = (val) => {
// multipleTable.value.clearSelection() // isSelected chkboxEnable
// isSelected false
list.value.forEach(row => { list.value.forEach(row => {
row.isSelected = false; row.isSelected = false;
row.chkboxEnable = false;
}); });
// isSelected true //
val.forEach(selectedRow => { val.forEach(selectedRow => {
//
const targetRow = list.value.find(row => row.id === selectedRow.id); const targetRow = list.value.find(row => row.id === selectedRow.id);
if (targetRow) { if (targetRow) {
targetRow.isSelected = true; targetRow.isSelected = true;
targetRow.chkboxEnable = true;
} }
}); });
multipleTable.value=val
multipleTable.value=val // selection-change
var bomDetails = list.value; updateCheckboxEnableState(val);
if (val.length==0) { };
for (let i = 0; i < bomDetails.length; i++) { //
bomDetails[i].chkboxEnable=false const updateCheckboxEnableState = (selectedRows) => {
} const allSelected = selectedRows.length === list.value.length;
}else if (val.length== bomDetails.length) { const noneSelected = selectedRows.length === 0;
for (let i = 0; i < bomDetails.length; i++) {
bomDetails[i].chkboxEnable=true list.value.forEach(row => {
} row.chkboxEnable = noneSelected ? false :
}else { allSelected ? true :
for (let i = 0; i < bomDetails.length; i++) { selectedRows.some(selected => selected.id === row.id);
for (let j = 0; j < val.length; j++) { });
if (val[j].id==bomDetails[i].id){ };
bomDetails[i].chkboxEnable=true
break //
}else { //
bomDetails[i].chkboxEnable=false const onSupplierChange = (row) => {
} //
} if (!row.chkboxEnable) {
//
if (multipleTable.value) {
multipleTable.value.toggleRowSelection(row, true);
} }
} }
} // change
change(row);
};
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
queryParams.pageNo = 1 queryParams.pageNo = 1

View File

@ -16,6 +16,16 @@ v-model="queryParams.matCode" placeholder="物料编码" clearable @keyup.enter=
v-model="queryParams.matName" placeholder="物料名称" clearable @keyup.enter="handleQuery" v-model="queryParams.matName" placeholder="物料名称" clearable @keyup.enter="handleQuery"
class="!w-240px" /> class="!w-240px" />
</el-form-item> </el-form-item>
<el-form-item label="物料简称" prop="shortName">
<el-input
v-model="queryParams.shortName" placeholder="物料简称" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="规格型号" prop="boomSpec">
<el-input
v-model="queryParams.boomSpec" placeholder="规格型号" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="物料类型" prop="matType"> <el-form-item label="物料类型" prop="matType">
<el-select v-model="queryParams.matType" placeholder="下拉选择" clearable class="!w-240px"> <el-select v-model="queryParams.matType" placeholder="下拉选择" clearable class="!w-240px">
<el-option <el-option
@ -80,7 +90,7 @@ v-for="dict in pnCurrentList" :key="dict.id" :label="dict.pn_name"
<el-table-column label="物料名称" align="center" prop="matName" fixed min-width="120"/> <el-table-column label="物料名称" align="center" prop="matName" fixed min-width="120"/>
<el-table-column label="物料类型" align="center" prop="matType" min-width="120"/> <el-table-column label="物料类型" align="center" prop="matType" min-width="120"/>
<el-table-column label="物料简称" align="center" prop="shortName" min-width="120"/> <el-table-column label="物料简称" align="center" prop="shortName" min-width="120"/>
<el-table-column label="规格/型号" align="center" prop="matSpec" min-width="120"/> <el-table-column label="规格/型号" align="center" prop="boomSpec" min-width="120"/>
<el-table-column label="品牌" align="center" prop="matBrand" min-width="120"/> <el-table-column label="品牌" align="center" prop="matBrand" min-width="120"/>
<el-table-column label="仓库" align="center" prop="whName" min-width="120"/> <el-table-column label="仓库" align="center" prop="whName" min-width="120"/>
<el-table-column label="库区" align="center" prop="rgName" min-width="120"/> <el-table-column label="库区" align="center" prop="rgName" min-width="120"/>
@ -151,6 +161,8 @@ const queryParams = reactive({
rgId:undefined, rgId:undefined,
pnId: undefined, pnId: undefined,
headerNo: undefined, headerNo: undefined,
shortName: undefined,
boomSpec: undefined,
}) })
const queryFormRef = ref() // const queryFormRef = ref() //
/** 添加/修改操作 */ /** 添加/修改操作 */

View File

@ -108,7 +108,15 @@
<el-table-column label="报工工序" align="center" prop="procedureName" width="160" /> <el-table-column label="报工工序" align="center" prop="procedureName" width="160" />
<el-table-column label="报工工时" align="center" prop="workTime" width="160" /> <el-table-column label="报工工时" align="center" prop="workTime" width="160" />
<el-table-column label="报工数量" align="center" prop="amount" width="120" /> <el-table-column label="报工数量" align="center" prop="amount" width="120" />
<!-- <el-table-column-->
<el-table-column label="报工进度" align="center" prop="reportProcess" width="160">
<template #default="scope">
<el-tag v-if="scope.row.reportProcess === '1'" type="warning">已报工</el-tag>
<el-tag v-else-if="scope.row.reportProcess === '2'" type="success">报工完成</el-tag>
<el-tag v-else>{{ scope.row.reportProcess }}</el-tag>
</template>
</el-table-column>
<!-- <el-table-column-->
<!-- label="生产起止时间"--> <!-- label="生产起止时间"-->
<!-- align="center"--> <!-- align="center"-->
<!-- prop="startTime"--> <!-- prop="startTime"-->
@ -142,7 +150,7 @@
<!-- </el-tooltip>--> <!-- </el-tooltip>-->
<!-- </template>--> <!-- </template>-->
<!-- </el-table-column>--> <!-- </el-table-column>-->
<el-table-column fixed="right" label="操作" align="center" width="140"> <el-table-column fixed="right" label="操作" align="center" width="180">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -152,6 +160,14 @@
> >
编辑 编辑
</el-button> </el-button>
<el-button
v-if="scope.row.reportProcess == 2"
link
type="primary"
@click="rework('update', scope.row.id)"
>
返工
</el-button>
<el-button <el-button
link link
type="danger" type="danger"
@ -159,6 +175,7 @@
> >
删除 删除
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -174,6 +191,8 @@
</el-card> </el-card>
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
<TaskReportForm ref="formRef" @success="getList" /> <TaskReportForm ref="formRef" @success="getList" />
<reworkForm ref="reworkRef" @success="getList"/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -182,6 +201,8 @@ import {dateFormatter, formatDate} from '@/utils/formatTime'
import download from '@/utils/download' import download from '@/utils/download'
import * as TaskReportApi from '@/api/heli/taskreport' import * as TaskReportApi from '@/api/heli/taskreport'
import TaskReportForm from './TaskReportForm.vue' import TaskReportForm from './TaskReportForm.vue'
import reworkForm from './reworkForm.vue'
import dayjs from "dayjs"; import dayjs from "dayjs";
import {Setting} from "@element-plus/icons-vue"; import {Setting} from "@element-plus/icons-vue";
import ElTooltip from "element-plus/es/components/tooltip"; import ElTooltip from "element-plus/es/components/tooltip";
@ -288,6 +309,12 @@ onMounted(() => {
setDefaultDate() setDefaultDate()
getList() getList()
}) })
const reworkRef = ref()
const rework = (type: string, id?: number) => {
reworkRef.value.open(type, id)
}
</script> </script>
<style scoped> <style scoped>
/* 固定搜索栏样式 */ /* 固定搜索栏样式 */

View File

@ -0,0 +1,80 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="600px" @close="emits">
<el-form
ref="reworkRef"
:model="formData"
label-width="100px"
v-loading="formLoading"
>
<el-row>
<el-col :span="24">
<el-form-item label="返工原因" prop="remark">
<el-input type="textarea" :rows="3" placeholder="请输入返工原因"
v-model="formData.remark"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="emits"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as TaskReportApi from '@/api/heli/taskreport'
const {t} = useI18n() //
const message = useMessage() //
import {formatAmount} from '@/utils/formatter'
import {ifError} from "assert";
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
remark: undefined,
})
const emits = async () => {
dialogVisible.value = false
emit('success')
}
const emit = defineEmits(['success']) // success
const reworkRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
//
if (id) {
formData.value.id= id
}
}
defineExpose({open}) // open
const submitForm = async () => {
try {
//
const data = formData.value as unknown as TaskReportApi.TaskReportVO
//
await TaskReportApi.rework(data);
message.success(t('common.updateSuccess'))
dialogVisible.value = false
//
emit('success')
} catch (error) {
dialogVisible.value = false
}
};
</script>