物料需求计划 列表页面数据加载

pull/4/head
siontion 8 months ago
parent 9f8cf8f198
commit 47fe291ed0

@ -44,6 +44,7 @@ public enum CodeEnum {
PROJECT_ORDER("业务订单", 3, "yyyyMM"),
PROJECT_DELIVERY_ORDER("发货单", "HL", 3, "yyyyMM"),
PROJECT_PLAN("生产计划", "PP",3, "yyyyMM"),
MATERIAL_PLAN("物料需求计划", "PR",4, "yyyyMMdd"),
;

@ -7,6 +7,7 @@ import com.chanko.yunxi.mes.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.chanko.yunxi.mes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static com.chanko.yunxi.mes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 物料需求计划分页 Request VO")
@ -21,6 +22,12 @@ public class MaterialPlanPageReqVO extends PageParam {
@Schema(description = "物料计划单号")
private String projectMaterialPlanNo;
@Schema(description = "生产计划单号")
private String planNo;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "订单id")
private Long projectId;
@ -48,7 +55,6 @@ public class MaterialPlanPageReqVO extends PageParam {
private String description;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
private String createTime;
}

@ -23,6 +23,14 @@ public class MaterialPlanRespVO {
@ExcelProperty("物料计划单号")
private String projectMaterialPlanNo;
@Schema(description = "生产计划单号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("生产计划单号")
private String planNo;
@Schema(description = "项目单号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("项目单号")
private String projectName;
@Schema(description = "订单id")
@ExcelProperty("订单id")
private Long projectId;
@ -56,6 +64,10 @@ public class MaterialPlanRespVO {
@ExcelProperty("备注")
private String description;
@Schema(description = "创建人")
@ExcelProperty("创建人")
private Long creator;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;

@ -16,7 +16,6 @@ public class MaterialPlanSaveReqVO {
private Long id;
@Schema(description = "物料计划单号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "物料计划单号不能为空")
private String projectMaterialPlanNo;
@Schema(description = "订单id")

@ -79,6 +79,14 @@ public class PlanController {
return success(BeanUtils.toBean(pageResult, PlanRespVO.class));
}
@GetMapping("/page-by-status")
@Operation(summary = "获得生产计划分页")
@PreAuthorize("@ss.hasPermission('heli:plan:query')")
public CommonResult<PageResult<PlanRespVO>> getPlanPageByStatus(@Valid PlanPageReqVO pageReqVO) {
PageResult<PlanDO> pageResult = planService.getPlanPageByStatus(pageReqVO);
return success(BeanUtils.toBean(pageResult, PlanRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出生产计划 Excel")
@PreAuthorize("@ss.hasPermission('heli:plan:export')")

@ -33,6 +33,7 @@ public class MaterialPlanDO extends BaseDO {
*
*/
private String projectMaterialPlanNo;
/**
* id
*/
@ -68,4 +69,19 @@ public class MaterialPlanDO extends BaseDO {
*/
private String description;
/**
*
*/
private String creator;
/**
*
*/
@TableField(exist = false)
private String planNo;
/**
*
*/
@TableField(exist = false)
private String projectName;
}

@ -53,6 +53,7 @@ public class StorageLogAllDO extends BaseDO {
private String matType;
private String whName;
private Long whId;
private String rgName;

@ -5,9 +5,16 @@ import java.util.*;
import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
import com.chanko.yunxi.mes.module.heli.controller.admin.plan.vo.PlanPageReqVO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.customer.CustomerDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.materialplan.MaterialPlanDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plan.PlanDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.projectorder.ProjectOrderDO;
import com.chanko.yunxi.mes.module.system.dal.dataobject.user.AdminUserDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import com.chanko.yunxi.mes.module.heli.controller.admin.materialplan.vo.*;
import org.springframework.util.StringUtils;
/**
* Mapper
@ -18,19 +25,36 @@ import com.chanko.yunxi.mes.module.heli.controller.admin.materialplan.vo.*;
public interface MaterialPlanMapper extends BaseMapperX<MaterialPlanDO> {
default PageResult<MaterialPlanDO> selectPage(MaterialPlanPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MaterialPlanDO>()
.eqIfPresent(MaterialPlanDO::getId, reqVO.getId())
.likeIfPresent(MaterialPlanDO::getProjectMaterialPlanNo, reqVO.getProjectMaterialPlanNo())
.eqIfPresent(MaterialPlanDO::getProjectId, reqVO.getProjectId())
.eqIfPresent(MaterialPlanDO::getProjectPlanId, reqVO.getProjectPlanId())
.eqIfPresent(MaterialPlanDO::getSubmitUserId, reqVO.getSubmitUserId())
.betweenIfPresent(MaterialPlanDO::getSubmitTime, reqVO.getSubmitTime())
.eqIfPresent(MaterialPlanDO::getAuditor, reqVO.getAuditor())
.betweenIfPresent(MaterialPlanDO::getAuditTime, reqVO.getAuditTime())
.eqIfPresent(MaterialPlanDO::getStatus, reqVO.getStatus())
.eqIfPresent(MaterialPlanDO::getDescription, reqVO.getDescription())
.betweenIfPresent(MaterialPlanDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MaterialPlanDO::getId));
MPJLambdaWrapper<MaterialPlanDO> query = new MPJLambdaWrapper<>();
query.selectAll(MaterialPlanDO.class)
.select("p.project_name as projectName","pl.plan_no as planNo")
.leftJoin(PlanDO.class, "pl", PlanDO::getId, MaterialPlanDO::getProjectPlanId)
.leftJoin(ProjectOrderDO.class, "p", ProjectOrderDO::getId, MaterialPlanDO::getProjectId)
.disableSubLogicDel()
.orderByDesc(MaterialPlanDO::getCreateTime);
query.like(!StringUtils.isEmpty(reqVO.getProjectMaterialPlanNo()), MaterialPlanDO::getProjectMaterialPlanNo, reqVO.getProjectMaterialPlanNo())
.like(!StringUtils.isEmpty(reqVO.getProjectName()), "p.project_name", reqVO.getProjectName())
.like(!StringUtils.isEmpty(reqVO.getPlanNo()), "pl.plan_no", reqVO.getPlanNo())
.apply(reqVO.getCreateTime() != null, "DATE_FORMAT(t.create_time,'%Y-%m-%d') = {0}", reqVO.getCreateTime())
.eq(reqVO.getStatus() != null, MaterialPlanDO::getStatus, reqVO.getStatus());
return selectPage(reqVO, query);
}
// default PageResult<MaterialPlanDO> selectPage(MaterialPlanPageReqVO reqVO) {
// return selectPage(reqVO, new LambdaQueryWrapperX<MaterialPlanDO>()
// .eqIfPresent(MaterialPlanDO::getId, reqVO.getId())
// .likeIfPresent(MaterialPlanDO::getProjectMaterialPlanNo, reqVO.getProjectMaterialPlanNo())
// .eqIfPresent(MaterialPlanDO::getProjectId, reqVO.getProjectId())
// .eqIfPresent(MaterialPlanDO::getProjectPlanId, reqVO.getProjectPlanId())
// .eqIfPresent(MaterialPlanDO::getSubmitUserId, reqVO.getSubmitUserId())
// .betweenIfPresent(MaterialPlanDO::getSubmitTime, reqVO.getSubmitTime())
// .eqIfPresent(MaterialPlanDO::getAuditor, reqVO.getAuditor())
// .betweenIfPresent(MaterialPlanDO::getAuditTime, reqVO.getAuditTime())
// .eqIfPresent(MaterialPlanDO::getStatus, reqVO.getStatus())
// .eqIfPresent(MaterialPlanDO::getDescription, reqVO.getDescription())
// .betweenIfPresent(MaterialPlanDO::getCreateTime, reqVO.getCreateTime())
// .orderByDesc(MaterialPlanDO::getId));
// }
}

@ -8,6 +8,7 @@ import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.customer.CustomerDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plan.PlanDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.projectorder.ProjectOrderDO;
import com.chanko.yunxi.mes.module.heli.enums.ProjectPlanStatusEnum;
import com.chanko.yunxi.mes.module.system.dal.dataobject.dept.DeptDO;
import com.chanko.yunxi.mes.module.system.dal.dataobject.user.AdminUserDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@ -46,6 +47,30 @@ public interface PlanMapper extends BaseMapperX<PlanDO> {
return selectPage(reqVO, query);
}
default PageResult<PlanDO> selectPageByStatus(PlanPageReqVO reqVO) {
MPJLambdaWrapper<PlanDO> query = new MPJLambdaWrapper<>();
query.selectAll(PlanDO.class)
.select("u.nickname as businessManName", "e.name as customerName","p.code as projectCode","p.project_name as projectName","p.project_start_time as projectStartTime","p.project_end_time as projectEndTime","p.business_line as businessLine","p.property","p.is_urgency as isUrgency","p.has_alter as hasAlter")
.leftJoin(ProjectOrderDO.class, "p", ProjectOrderDO::getId, PlanDO::getProjectId)
.leftJoin(AdminUserDO.class, "u", AdminUserDO::getId, ProjectOrderDO::getBusinessMan)
.leftJoin(CustomerDO.class, "e", CustomerDO::getId, ProjectOrderDO::getCustomerId)
.disableSubLogicDel()
.orderByDesc(PlanDO::getPlanNo);
query.like(!StringUtils.isEmpty(reqVO.getPlanNo()), PlanDO::getPlanNo, reqVO.getPlanNo())
.like(!StringUtils.isEmpty(reqVO.getProjectCode()), "p.code", reqVO.getProjectCode())
.like(!StringUtils.isEmpty(reqVO.getCustomerName()), "e.name", reqVO.getCustomerName())
.like(!StringUtils.isEmpty(reqVO.getProjectName()), ProjectOrderDO::getProjectName, reqVO.getProjectName())
.like(!StringUtils.isEmpty(reqVO.getBusinessManName()), "u.nickname", reqVO.getBusinessManName())
.like(!StringUtils.isEmpty(reqVO.getProjectOwner()), PlanDO::getProjectOwner, reqVO.getProjectOwner())
.eq(reqVO.getBusinessLine() != null, ProjectOrderDO::getBusinessLine, reqVO.getBusinessLine())
.eq(reqVO.getProperty() != null, ProjectOrderDO::getProperty, reqVO.getProperty())
.ne(true, PlanDO::getStatus, ProjectPlanStatusEnum.COMPLETE.getCode())
.ne(true,PlanDO::getStatus,ProjectPlanStatusEnum.TERMINATE.getCode());
return selectPage(reqVO, query);
}
// default PageResult<PlanDO> selectPage(PlanPageReqVO reqVO) {
// return selectPage(reqVO, new LambdaQueryWrapperX<PlanDO>()
// .eqIfPresent(PlanDO::getId, reqVO.getId())

@ -30,6 +30,7 @@ public interface StorageLogAllMapper extends BaseMapperX<StorageLogAllDO> {
query.like(!StringUtils.isEmpty(reqVO.getMatType()),StorageLogAllDO::getMatType, reqVO.getMatType())
.eq(reqVO.getStockType()!= null,StorageLogAllDO::getStockType, reqVO.getStockType())
.eq(reqVO.getWhId()!= null,StorageLogAllDO::getWhId, reqVO.getWhId())
.like(!StringUtils.isEmpty(reqVO.getMatName()), StorageLogAllDO::getMatName, reqVO.getMatName())
.like(!StringUtils.isEmpty(reqVO.getMatCode()), StorageLogAllDO::getMatCode, reqVO.getMatCode())
.like(!StringUtils.isEmpty(reqVO.getStockNo()), StorageLogAllDO::getStockNo, reqVO.getStockNo())

@ -1,10 +1,13 @@
package com.chanko.yunxi.mes.module.heli.service.materialplan;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.serialnumber.SerialNumberDO;
import com.chanko.yunxi.mes.module.heli.service.serialnumber.SerialNumberService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.*;
import com.chanko.yunxi.mes.module.heli.controller.admin.materialplan.vo.*;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.materialplan.MaterialPlanDO;
@ -15,6 +18,8 @@ import com.chanko.yunxi.mes.framework.common.util.object.BeanUtils;
import com.chanko.yunxi.mes.module.heli.dal.mysql.materialplan.MaterialPlanMapper;
import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.chanko.yunxi.mes.module.heli.enums.CodeEnum.MATERIAL_PLAN;
import static com.chanko.yunxi.mes.module.heli.enums.CodeEnum.PROJECT_PLAN;
import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.*;
/**
@ -29,11 +34,25 @@ public class MaterialPlanServiceImpl implements MaterialPlanService {
@Resource
private MaterialPlanMapper materialPlanMapper;
@Resource
private SerialNumberService serialNumberService;
@Override
public Long createMaterialPlan(MaterialPlanSaveReqVO createReqVO) {
// 插入
MaterialPlanDO materialPlan = BeanUtils.toBean(createReqVO, MaterialPlanDO.class);
// 月度流水号
SerialNumberDO serialNumberDO = new SerialNumberDO();
serialNumberDO = serialNumberService.getSerialNumber(MATERIAL_PLAN.name(), new SimpleDateFormat("yyyyMMdd").format(new Date()));
serialNumberDO.setSerialNumber(serialNumberDO.getSerialNumber()+1);
materialPlan.setProjectMaterialPlanNo(MATERIAL_PLAN.getCode(serialNumberDO.getSerialNumber().toString()));
materialPlanMapper.insert(materialPlan);
// 回写序列记录
serialNumberService.updateSerialNumber(serialNumberDO);
// 返回
return materialPlan.getId();
}

@ -52,6 +52,8 @@ public interface PlanService {
*/
PageResult<PlanDO> getPlanPage(PlanPageReqVO pageReqVO);
PageResult<PlanDO> getPlanPageByStatus(PlanPageReqVO pageReqVO);
void generatePlanByProjectId(Long projectId);
void updatePlanStatusToTerminateByProjectId(Long projectId);
}

@ -109,6 +109,11 @@ public class PlanServiceImpl implements PlanService {
return planMapper.selectPage(pageReqVO);
}
@Override
public PageResult<PlanDO> getPlanPageByStatus(PlanPageReqVO pageReqVO) {
return planMapper.selectPageByStatus(pageReqVO);
}
@Override
public void generatePlanByProjectId(Long projectId){
// 查询最近归档历史并对比变化字段

@ -20,6 +20,11 @@ export interface PlanVO {
status: number
}
// 查询生产计划分页
export const getPlanPageByStatus = async (params) => {
return await request.get({ url: `/heli/plan/page-by-status`, params })
}
// 查询生产计划分页
export const getPlanPage = async (params) => {
return await request.get({ url: `/heli/plan/page`, params })

@ -242,4 +242,5 @@ export enum DICT_TYPE {
HELI_DELIVER_MATERIAL_TYPE = 'heli_deliver_material_type', // 发货物料类型
HELI_PROJECT_PLAN_STATUS = 'heli_project_plan_status',//生产计划状态
HELI_CRAFT = 'heli_craft',//工艺流程
HELI_PROJECT_MATERIAL_PLAN_STATUS = 'heli_project_material_plan_status',//物料需求计划状态
}

@ -1,148 +0,0 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="物料计划单号" prop="projectMaterialPlanNo">
<el-input v-model="formData.projectMaterialPlanNo" placeholder="请输入物料计划单号" />
</el-form-item>
<el-form-item label="订单id" prop="projectId">
<el-input v-model="formData.projectId" placeholder="请输入订单id" />
</el-form-item>
<el-form-item label="生产计划id" prop="projectPlanId">
<el-input v-model="formData.projectPlanId" placeholder="请输入生产计划id" />
</el-form-item>
<el-form-item label="送审人" prop="submitUserId">
<el-input v-model="formData.submitUserId" placeholder="请输入送审人" />
</el-form-item>
<el-form-item label="送审时间" prop="submitTime">
<el-date-picker
v-model="formData.submitTime"
type="date"
value-format="x"
placeholder="选择送审时间"
/>
</el-form-item>
<el-form-item label="审核人" prop="auditor">
<el-input v-model="formData.auditor" placeholder="请输入审核人" />
</el-form-item>
<el-form-item label="审核时间" prop="auditTime">
<el-date-picker
v-model="formData.auditTime"
type="date"
value-format="x"
placeholder="选择审核时间"
/>
</el-form-item>
<el-form-item label="状态,1已保存2已送审3已审核4已打回 默认是1" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_PROJECT_MATERIAL_PLAN_STATUS)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="description">
<el-input v-model="formData.description" type="textarea" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as MaterialPlanApi from '@/api/heli/materialplan'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
projectMaterialPlanNo: undefined,
projectId: undefined,
projectPlanId: undefined,
submitUserId: undefined,
submitTime: undefined,
auditor: undefined,
auditTime: undefined,
status: undefined,
description: undefined,
})
const formRules = reactive({
projectMaterialPlanNo: [{ required: true, message: '物料计划单号不能为空', trigger: 'blur' }],
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await MaterialPlanApi.getMaterialPlan(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as MaterialPlanApi.MaterialPlanVO
if (formType.value === 'create') {
await MaterialPlanApi.createMaterialPlan(data)
message.success(t('common.createSuccess'))
} else {
await MaterialPlanApi.updateMaterialPlan(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
projectMaterialPlanNo: undefined,
projectId: undefined,
projectPlanId: undefined,
submitUserId: undefined,
submitTime: undefined,
auditor: undefined,
auditTime: undefined,
status: undefined,
description: undefined,
}
formRef.value?.resetFields()
}
</script>

@ -0,0 +1,157 @@
<template>
<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>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">基础信息</span>
</template>
<el-row>
<el-col :span="24">
<el-row>
<el-col :span="6">
<el-row>
<el-col :span="24">
<el-form-item label="物料需求计划编号" prop="materialPlanNo">
<el-input class="!w-265px" placeholder="系统自动生成" v-model="formData.materialPlanNo" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="80">
<el-form-item label="备注" prop="description" >
<el-input class="!w-713px" type="textarea" v-model="formData.description" show-word-limit maxlength="200" />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<el-row>
<el-col :span="24">
<el-form-item label="单据日期" prop="createTime">
<el-date-picker class="!w-265px" v-model="formData.createTime" value-format="x" placeholder="单据日期" disabled/>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<el-row>
<el-col :span="24">
<el-form-item label="生产计划单号" prop="planNo">
<el-input class="!w-265px" placeholder="生产计划单号" v-model="formData.planNo" disabled >
<template #append><el-button @click="openprojectPlanDialog" :icon="Search" /></template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="项目名称" prop="projectName">
<el-input class="!w-265px" placeholder="项目名称" v-model="formData.projectName" disabled />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<el-row>
<el-col :span="24">
<el-form-item label="项目编号" prop="projectCode">
<el-input class="!w-265px" v-model="formData.projectCode" placeholder="项目编号" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="单据状态" prop="status" >
<el-input class="!w-265px" v-model="formData.status" disabled value="已保存" />
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
</el-col>
</el-row>
</el-card>
</el-form>
<div class="text-center hl-footer">
<el-button @click="() => router.back()" size="large"> </el-button>
<el-button @click="submitForm" type="success" size="large"> </el-button>
</div>
</el-card>
<ProjectPlanDialog ref="projectPlanDialog" @success="handleSelectedProjectPlan" />
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as MaterialPlanApi from '@/api/heli/materialplan'
import { Search, Plus } from '@element-plus/icons-vue'
import ProjectPlanDialog from '@/views/heli/materialplan/ProjectPlanDialog.vue'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
projectMaterialPlanNo: undefined,
projectId: undefined,
projectPlanId: undefined,
projectPlanNo: undefined,
projectCode: undefined,
auditor: undefined,
createTime: new Date(),
status: 1,
description: undefined,
})
const formRules = reactive({
projectPlanId: [{ required: true, message: '生产计划单号不能为空', trigger: 'blur' }],
})
const formRef = ref() // Ref
defineExpose({ open }) // open
const projectPlanDialog = ref()
const openprojectPlanDialog = () => {
projectPlanDialog.value?.open()
}
const handleSelectedProjectPlan = (arr) => {
if (arr) {
formData.value.projectPlanId = arr.id
formData.value.projectId = arr.projectId
formData.value.projectCode = arr.projectCode
formData.value.projectName = arr.projectName
formData.value.planNo = arr.planNo
}
}
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as MaterialPlanApi.MaterialPlanVO
await MaterialPlanApi.createMaterialPlan(data)
message.success(t('common.createSuccess'))
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
onMounted(async () => {
})
</script>

@ -1,7 +1,7 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="130px">
<el-form-item label="物料计划单号" prop="projectMaterialPlanNo">
<el-input v-model="queryParams.projectMaterialPlanNo" placeholder="物料计划单号" clearable @keyup.enter="handleQuery"
class="!w-240px" />
@ -15,7 +15,8 @@
class="!w-240px" />
</el-form-item>
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="项目名称" clearable @keyup.enter="handleQuery" class="!w-250px" />
<el-input v-model="queryParams.projectName" placeholder="项目名称" clearable @keyup.enter="handleQuery"
class="!w-250px" />
</el-form-item>
<el-form-item label="单据状态" prop="status">
<el-select v-model="queryParams.status" placeholder="下拉选择" clearable class="!w-240px">
@ -40,25 +41,41 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="物料需求计划单号" align="center" prop="projectMaterialPlanNo" />
<el-table-column label="单据日期" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
<el-table-column label="物料需求计划单号" align="center" prop="projectMaterialPlanNo" width="180" fixed>
<template #default="scope">
<el-button text type="primary" @click="openForm('review', scope.row.id)">
{{ scope.row.projectMaterialPlanNo }}
</el-button>
</template>
</el-table-column>
<el-table-column label="单据日期" align="center" prop="createTime" :formatter="dateFormatter" width="180px" fixed>
<template #default="scope">
{{
formatDate(scope.row.createTime, 'YYYY-MM-DD')
}}
</template>
</el-table-column>
<el-table-column label="生产计划单号" align="center" prop="planNo" />
<el-table-column label="项目名称" align="center" prop="projectName" />
<el-table-column label="备注" align="center" prop="description" />
<el-table-column label="创建人" align="center" prop="creator" />
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
<el-table-column label="创建人" align="center" prop="creator" >
<template #default="scope">
{{ userInit.find((user) => user.id == scope.row.creator)?.nickname }}
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="220" />
<el-table-column label="送审人" align="center" prop="submitUserId" />
<el-table-column label="送审时间" align="center" prop="submitTime" :formatter="dateFormatter" width="180px" />
<el-table-column label="送审时间" align="center" prop="submitTime" :formatter="dateFormatter" width="220" />
<el-table-column label="审核人" align="center" prop="auditor" />
<el-table-column label="审核时间" align="center" prop="auditTime" :formatter="dateFormatter" width="180px" />
<el-table-column label="单据状态" align="center" prop="status">
<el-table-column label="审核时间" align="center" prop="auditTime" :formatter="dateFormatter" width="220" />
<el-table-column label="单据状态" align="center" prop="status" fixed="right">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_PROJECT_MATERIAL_PLAN_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<el-table-column label="操作" align="center" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)">
编辑
@ -80,13 +97,13 @@
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import { dateFormatter, formatDate } from '@/utils/formatTime'
import download from '@/utils/download'
import * as MaterialPlanApi from '@/api/heli/materialplan'
import MaterialPlanForm from './MaterialPlanForm.vue'
import * as UserApi from '@/api/system/user'
defineOptions({ name: 'MaterialPlan' })
const router = useRouter()
const message = useMessage() //
const { t } = useI18n() //
@ -126,6 +143,7 @@ const getList = async () => {
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
queryParams.createTime= formatDate(queryParams.createTime, 'YYYY-MM-DD')
getList()
}
@ -136,9 +154,23 @@ const resetQuery = () => {
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
switch (type) {
case 'create':
router.push({ path: '/purchase/materialplanadd', query: { id: id } })
break;
case 'update':
router.push({ path: '/purchase/materialplanedit', query: { id: id } })
break;
case 'review':
router.push({ path: '/purchase/materialplanreview', query: { id: id } })
break;
default:
break;
}
}
/** 删除按钮操作 */
@ -169,8 +201,11 @@ const handleExport = async () => {
}
}
const userInit = ref()
/** 初始化 **/
onMounted(() => {
onMounted(async () => {
//
userInit.value = await UserApi.getSimpleUserList()
getList()
})
</script>

@ -0,0 +1,210 @@
<template>
<Dialog :title="dialogTitle" width="80%" v-model="dialogVisible" center>
<ContentWrap class="borderxx">
<!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="108px">
<el-form-item label="生产计划单号" prop="planNo">
<el-input v-model="queryParams.planNo" placeholder="请输入生产计划单号" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="queryParams.projectCode" placeholder="请输入项目编号" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item>
<el-button @click="handleQuery" type="primary">
<Icon icon="ep:search" class="mr-5px" /> 搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> 重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<el-card class="hl-card">
<!-- 列表 -->
<ContentWrap>
<el-table ref="multipleTable" v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"
class="hl-table" @selection-change="handleSelectionChange" @row-click="clickRow" selection>
<el-table-column fixed type="selection" width="40"/>
<el-table-column fixed label="计划单号" align="center" prop="planNo" width="150" />
<el-table-column fixed label="项目编号" align="center" prop="projectCode" width="220" />
<el-table-column fixed label="项目变更次数" align="center" prop="changeNum" width="150" />
<el-table-column label="客户名称" align="center" prop="customerName" width="150" />
<el-table-column label="项目名称" align="center" prop="projectName" width="150" />
<el-table-column label="业务员" align="center" prop="businessManName" width="150" />
<el-table-column label="起止时间" align="center" prop="projectStartTime" width="260">
<template #default="scope">
{{
formatDate(scope.row.projectStartTime, 'YYYY-MM-DD') +
'~' +
formatDate(scope.row.projectEndTime, 'YYYY-MM-DD')
}}
</template>
</el-table-column>
<el-table-column label="所属业务线" align="center" prop="businessLine" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_BUSINESS_LINE" :value="scope.row.businessLine" />
</template>
</el-table-column>
<el-table-column label="性质" align="center" prop="property" width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_PROJECT_PROPERTY" :value="scope.row.property" />
</template>
</el-table-column>
<el-table-column label="是否紧急" align="center" prop="isUrgency" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_COMMON_IS_OR_NOT" :value="scope.row.isUrgency" />
</template>
</el-table-column>
<el-table-column label="是否已变更" align="center" prop="hasAlter" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_COMMON_IS_OR_NOT" :value="scope.row.hasAlter" />
</template>
</el-table-column>
<el-table-column label="是否要工艺" align="center" prop="hasCraft" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_COMMON_IS_OR_NOT" :value="scope.row.hasCraft" />
</template>
</el-table-column>
<el-table-column label="工艺起止时间" align="center" prop="craftStartDate" width="260">
<template #default="scope">
{{
formatDate(scope.row.craftStartDate, 'YYYY-MM-DD') +
'~' +
formatDate(scope.row.craftEndDate, 'YYYY-MM-DD')
}}
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="220px" />
<el-table-column label="备注" align="center" prop="description" width="150" />
<el-table-column fixed="right" label="项目负责人" align="center" prop="projectOwner" width="150">
<template #default="scope">
{{ userInit.find((user) => user.id == scope.row.projectOwner)?.nickname }}
</template>
</el-table-column>
<el-table-column fixed="right" label="工艺负责人" align="center" prop="craftOwner" width="150">
<template #default="scope">
{{ userInit.find((user) => user.id == scope.row.craftOwner)?.nickname }}
</template>
</el-table-column>
<el-table-column fixed="right" label="生产状态" align="center" prop="status" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_PROJECT_PLAN_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
</el-card>
<template #footer>
<el-button @click="dialogVisible = false" size="large"> </el-button>
<el-button @click="submitForm" type="success" size="large"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter, dateFormatter2, formatDate } from '@/utils/formatTime'
import * as PlanApi from '@/api/heli/plan'
import * as UserApi from '@/api/system/user'
import { ref } from "vue";
import { ElTable } from 'element-plus'
import { ProjectOrderVO } from "@/api/heli/projectorder";
const message = useMessage() //
const { t } = useI18n() //
const router = useRouter()
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const loading = ref(true) //
const list = ref([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
planNo: undefined,
projectCode: undefined,
projectName: undefined
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await PlanApi.getPlanPageByStatus(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const multipleTable: any = ref<InstanceType<typeof ElTable>>()
const multipleSelection: any = ref([])
const handleSelectionChange = (val: ProjectOrderVO[]) => {
if (val.length > 1) {
multipleTable.value.clearSelection()
multipleTable.value.toggleRowSelection(val.pop())
} else {
multipleSelection.value = val.pop()
}
}
const clickRow = (row: any) => {
if (row) {
multipleTable.value!.toggleRowSelection(row, undefined)
} else {
multipleTable.value!.clearSelection()
}
}
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = () => {
if (!multipleSelection.value || multipleSelection.value.length <= 0) {
message.warning(t('common.selectText'))
return
}
dialogVisible.value = false
//
emit('success', multipleSelection.value)
}
const userInit = ref()
/** 打开弹窗 */
const open = async () => {
dialogVisible.value = true
//
userInit.value = await UserApi.getSimpleUserList()
handleQuery()
}
defineExpose({ open }) // open
</script>

@ -1,545 +0,0 @@
<template>
<Dialog title="打印预览" v-model="dialogVisible" width="1000">
<!-- 打印预览 -->
<div class="print-wrap page" ref="print">
<table border="2" cellspacing="0" id="table">
<tbody>
<tr>
<td colspan="2">
<div style="width: 110px; text-align: center">
<img :src="logoDataUrl" style="width: 100%; padding: 0 5px" alt="" />
</div>
</td>
<td colspan="6">
<span style="font-size: 20px; font-weight: 700">开发项目启动单</span>
</td>
<td colspan="2" style="padding: 5px 0">
<div style="border-bottom: 1px solid #666; padding-bottom: 5px">项目编号</div>
<div style="padding-top: 5px">{{ formData.code}}</div>
</td>
</tr>
</tbody>
<tbody>
<tr>
<td colspan="2"> 客户名称 </td>
<td colspan="5">
<span>{{ formData.customer.name }}</span>
</td>
<td colspan="1">{{ formData.customer.brief }}</td>
<td> 编码 </td>
<td>{{ formData.customer.code }} </td>
</tr>
</tbody>
<tr>
<td colspan="2"> 项目名称 </td>
<td colspan="6">
{{ formData.projectName }}
</td>
<td> 业务员 </td>
<td>{{ formData.businessManName }} </td>
</tr>
<tr>
<td colspan="2"> 项目工期 </td>
<td colspan="1"> </td>
<td colspan="1">
<span>{{ formatDate(new Date(formData.projectStartTime), 'YYYY-MM-DD') }}</span>
</td>
<td colspan="1"></td>
<td colspan="1">{{ formatDate(new Date(formData.projectEndTime), 'YYYY-MM-DD') }}</td>
<td>天数</td>
<td colspan="1">{{ betweenDay(new Date(formData.projectStartTime), new Date(formData.projectEndTime)) }}</td>
<td colspan="1"> 是否紧急 </td>
<td colspan="1">{{ getDictLabel(DICT_TYPE.HELI_COMMON_IS_OR_NOT, formData.isUrgency) }} </td>
</tr>
<tr>
<td colspan="10">
<div style="display: flex; justify-content: space-between">
<div style="width: 42%; font-size: 12px; display: flex; flex-direction: column">
<div style="text-align: left; width: 100%">客户提供资料</div>
<div id="fruitForm" style="display: flex; justify-content: flex-start; align-items: center">
<span class="checkbox" v-if="formData.hasContract == 0"></span>
<span class="checkbox" v-else-if="formData.hasContract == 1"></span>
<label for="checkbox1">开发合同</label>
<span class="checkbox" v-if="formData.hasTechnologyProtocol == 0"></span>
<span class="checkbox" v-else-if="formData.hasTechnologyProtocol == 1"></span>
<label for="checkbox2">技术协议</label>
<span class="checkbox" v-if="formData.hasBlueprint == 0"></span>
<span class="checkbox" v-else-if="formData.hasBlueprint == 1"></span>
<label for="checkbox3">图纸/数模</label>
</div>
</div>
<div style="width: 27%; display: flex; justify-content: center; font-size: 12px">
<span>费用说明</span>
<div style="border: 1px solid #333">
<div style="border-bottom: 1px solid #333">
<span v-if="formData.hasPrice == 1"></span>
<span v-else></span>
</div>
<div style="padding: 0 3px">
<span v-if="formData.hasPrice == 1">{{ formData.price }}()</span>
<span v-else> </span>
</div>
</div>
</div>
<div style="width: 22%; display: flex; justify-content: center; font-size: 12px">
<div>
<div>类别</div>
<div>性质</div>
</div>
<div style="border: 1px solid #333; width: 100px">
<div style="border-bottom: 1px solid #333">{{ getDictLabel(DICT_TYPE.HELI_BUSINESS_LINE, formData.businessLine) }}</div>
<div>{{ getDictLabel(DICT_TYPE.HELI_PROJECT_PROPERTY, formData.property) }}</div>
</div>
</div>
</div>
</td>
</tr>
<tbody>
<tr>
<td colspan="10">
<div style="text-align: left; width: 100%">子项目信息</div>
</td>
</tr>
<tr>
<td class="xh"> 序号 </td>
<td colspan="2"> 名称 </td>
<td> 设备型号 </td>
<td style="width:10%"> 简称 </td>
<td> 数量 </td>
<td> 主要材料 </td>
<td colspan="3"> 子项目编号 </td>
</tr>
<tr v-for="(item,idx) in formData.projectOrderSubs" :key="idx">
<td>{{ idx+1 }}</td>
<td colspan="2">{{item.name}}</td>
<td>{{item.deviceModel}}</td>
<td></td>
<td>{{item.amount}}</td>
<td>{{item.compositionName}}</td>
<td colspan="3"></td>
</tr>
</tbody>
<tbody>
<tr>
<td colspan="10">
<div style="text-align: left; width: 100%">备注</div>
</td>
</tr>
<tr>
<td colspan="10">
<div style="text-align: left; height: 150px; padding: 10px">
<p> {{ formData.remark }}</p>
</div>
</td>
</tr>
</tbody>
<tbody>
<tr>
<td colspan="4" style="width:33%"> 编制/日期 </td>
<td colspan="3" style="width:33%"> 审核/日期 </td>
<td colspan="3" style="width:33%"> 批准/日期 </td>
</tr>
<tr>
<td colspan="4">{{formData.creatorName}}</td>
<td colspan="3">{{formData.auditUserName}}</td>
<td colspan="3">{{formData.approveUserName}}</td>
</tr>
<tr>
<td colspan="4">{{formatDate(new Date(formData.createTime), 'YYYY-MM-DD')}}</td>
<td colspan="3">{{formatDate(new Date(formData.auditTime), 'YYYY-MM-DD')}}</td>
<td colspan="3">{{formatDate(new Date(formData.approveTime), 'YYYY-MM-DD')}}</td>
</tr>
</tbody>
</table>
</div>
<template #footer>
<!-- 打印 -->
<el-button @click="onPrint" type="primary">打印</el-button>
<el-button @click="outopen"></el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
// import { ref, reactive } from 'vue'
import * as PlanApi from '@/api/heli/plan'
import * as PlanSubApi from '@/api/heli/plansub'
import * as ProjectOrderApi from '@/api/heli/projectorder'
import { getIntDictOptions, getStrDictOptions, DICT_TYPE, getDictLabel } from '@/utils/dict'
import { betweenDay, dateFormatter, formatDate } from '@/utils/formatTime'
import { Check } from '@element-plus/icons-vue'
import { getCustomer } from '@/api/heli/customer'
import { getOperateLogPage } from '@/api/system/operatelog'
import urlimg from '@/assets/imgs/exlogo.png'
const logoDataUrl = ref('') // LogoBase64URL
const dialogVisible = ref(false) //
const onPrint = () => {
// dom
const printNode = document.querySelector('.print-wrap')
if (!printNode) return
//
const newIframe: any = document.createElement('iframe')
newIframe.setAttribute(
'style',
'width:0px;height:0px;position:absolute;left:-9999px;top:-9999px;'
)
newIframe.setAttribute('align', 'center')
document.body.appendChild(newIframe)
//
let doc: any = null
doc = newIframe.contentWindow.document
doc.write(`
<style type="text/css">
/* 浏览器打印基本样式 */
.page {
width: 21cm;
min-height: 29.7cm;
padding: 10mm;
margin: 20px auto;
border: 1px #d3d3d3 solid;
border-radius: 5px;
background: white;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
position: relative;
font-size: 14px !important;
}
@page {
size: A4;
margin:1cm;
}
@media print {
.page {
margin: 10mm;
border: initial;
border-radius: initial;
width: initial;
min-height: initial;
box-shadow: initial;
background: initial;
page-break-after: always;
}
}
table {
width: 100%; /* 让表格宽度100%占满其父元素宽度 */
height: auto; /* 高度根据内容自适应 */
font-size: 14px;
text-align: center;
border-collapse: collapse;
margin-top: 5mm; /* 添加顶部外边距,替代原先的页内边距 */
td {
padding: 10px 0;
border: 1px solid #333;
}
}
.xh {
width: 50px !important;
}
.checkbox {
border: 2px solid #999;
width: 10px;
height: 10px;
display: flex;
justify-content: center;
align-items: center;
margin-left:10px ;
}
</style>
<div>
${printNode.innerHTML}
</div>`)
doc.close()
//
setTimeout(() => {
newIframe.contentWindow.focus()
newIframe.contentWindow.print()
document.body.removeChild(newIframe) //
dialogVisible.value = false
}, 100)
}
const outopen = () => {
dialogVisible.value = false
}
const queryParams: any = ref({
code: undefined
})
const isSelected = ref([1, 3])
const formData = ref({
id: undefined,
code: undefined,
orderStatus: 4,
deliveryStatus: 1,
businessDeptId: undefined,
customerId: undefined,
projectName: undefined,
businessLine: undefined,
blueprintNo: undefined,
hasPrice: 1,
price: undefined,
currency: '1',
projectStartTime: undefined,
projectEndTime: undefined,
isUrgency: 0,
property: 1,
referenceTechnology: undefined,
hasAlter: 0,
lastAlterTime: undefined,
qualityRequirement: undefined,
remark: undefined,
hasContract: 0,
hasTechnologyProtocol: 0,
hasBlueprint: 0,
blueprintRemark: undefined,
status: 1,
businessMan: undefined,
createTime: new Date(),
projectOrderSubs: [],
attachments: [],
operateLogs: [],
contractNo: undefined,
active: '',
activeOpinion: '',
isSnapshot: 0,
snapshotId: undefined,
snapshotCode: undefined,
orderTime: new Date(),
snapshotOrderTime: undefined,
alterFieldNames: [],
customer: {},
creatorName: undefined,
auditTime: undefined,
auditUserName: undefined,
approveTime: undefined,
approveUserName: undefined
})
const planData = ref({
id: undefined,
projectId: undefined,
projectOwner: undefined,
hasCraft: undefined,
craftOwner: undefined,
craftStartTime: undefined,
craftEndTime: undefined,
editor: undefined,
editorDate: undefined,
auditor: undefined,
auditDate: undefined,
approver: undefined,
approveDate: undefined,
description: undefined,
status: undefined,
createTime: undefined,
operateLogs: [],
projectOrderSubs: [],
projectPlanSubs: [],
craftInfos: [],
craftContent: undefined
})
/** 打开弹窗 */
const open = async (id: number) => {
//
// LogoBase64URL
const logoImage = new Image()
logoImage.src = urlimg // Logo
logoImage.onload = () => {
const canvas = document.createElement('canvas')
canvas.width = logoImage.width
canvas.height = logoImage.height
const context = canvas.getContext('2d')
context.drawImage(logoImage, 0, 0)
const base64String = canvas.toDataURL('image/png')
logoDataUrl.value = base64String
}
dialogVisible.value = true
resetForm()
//
planData.value = await PlanApi.getPlan(id)
//
await handleInitPlanSub(id)
//
await handleCraftInfo()
formData.value = await ProjectOrderApi.getProjectOrder(planData.value.projectId)
//
formData.value.projectOrderSubs = await ProjectOrderApi.getProjectOrderSubListByProjectOrderId(planData.value.projectId)
formData.value.customer = await getCustomer(formData.value.customerId)
// /
let logParams = {
pageNo: 1,
pageSize: 2,
typeList: [9, 10]
}
const logs = await getOperateLogPage(logParams)
if (logs.list && logs.list.length == 2) {
const approveLog = logs.list[0]
const auditLog = logs.list[1]
formData.value.approveTime = approveLog.startTime
formData.value.approveUserName = approveLog.userNickname
formData.value.auditTime = auditLog.startTime
formData.value.auditUserName = auditLog.userNickname
}
}
defineExpose({ open }) // open
const handleCraftInfo = async () =>{
if (planData.value.craftContent == null) {
planData.value.craftInfos = []
getIntDictOptions(DICT_TYPE.HELI_CRAFT).forEach(dict => {
planData.value.craftInfos.push({ id: dict.value, name: dict.label, startDate: '', endDate: '', owner: '', description: '' })
})
} else {
planData.value.craftInfos = eval(planData.value.craftContent)
}
}
const handleInitPlanSub = async (id) => {
//
const queryParams = reactive({
pageNo: 1,
pageSize: 99,
projectPlanId: id
})
planData.value.projectPlanSubs =
(await PlanSubApi.getPlanSubPage(queryParams)).list
formData.value.projectOrderSubs.forEach(item => {
if (planData.value.projectPlanSubs.filter(sub => sub.projectSubId == item.id).length > 0) {
var subTemp = planData.value.projectPlanSubs.find(sub => sub.projectSubId == item.id)
item.planSubId = subTemp.id
item.projectPlanId = subTemp.projectPlanId
item.projectId = subTemp.projectId
item.projectSubId = subTemp.projectSubId
item.projectSubShortName = subTemp.projectSubShortName
item.projectSubCode = subTemp.projectSubCode
item.mouldId = subTemp.mouldId
item.equipId = subTemp.equipId
item.blankDate = subTemp.blankDate
item.blankOwner = subTemp.blankOwner
item.twoDimDate = subTemp.twoDimDate
item.twoDimOwner = subTemp.twoDimOwner
item.threeDimDate = subTemp.threeDimDate
item.threeDimOwner = subTemp.threeDimOwner
}
})
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
code: undefined,
orderStatus: 4,
deliveryStatus: 1,
businessDeptId: undefined,
customerId: undefined,
projectName: undefined,
businessLine: undefined,
blueprintNo: undefined,
hasPrice: 1,
price: undefined,
currency: '1',
projectStartTime: undefined,
projectEndTime: undefined,
isUrgency: 0,
property: 1,
referenceTechnology: undefined,
hasAlter: 0,
lastAlterTime: undefined,
qualityRequirement: undefined,
remark: undefined,
hasContract: 0,
hasTechnologyProtocol: 0,
hasBlueprint: 0,
blueprintRemark: undefined,
status: 1,
businessMan: undefined,
createTime: new Date(),
projectOrderSubs: [],
attachments: [],
operateLogs: [],
contractNo: undefined,
active: '',
activeOpinion: '',
isSnapshot: 0,
snapshotId: undefined,
snapshotCode: undefined,
orderTime: new Date(),
snapshotOrderTime: undefined,
alterFieldNames: [],
customer: {},
creatorName: undefined,
auditTime: undefined,
auditUserName: undefined,
approveTime: undefined,
approveUserName: undefined
}
}
onMounted(() => {})
</script>
<style scoped lang="scss">
.page {
width: 21cm;
min-height: 29.7cm;
padding: 10mm;
margin: 20px auto;
border: 1px #d3d3d3 solid;
border-radius: 5px;
background: white;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
position: relative;
font-size: 14px !important;
}
@page {
size: A4;
margin: 0;
}
@media print {
.page {
margin: 0;
border: initial;
border-radius: initial;
width: initial;
min-height: initial;
box-shadow: initial;
background: initial;
page-break-after: always;
}
}
table {
width: 100%; /* 让表格宽度100%占满其父元素宽度 */
height: auto; /* 高度根据内容自适应 */
font-size: 14px;
text-align: center;
border-collapse: collapse;
margin-top: 5mm; /* 添加顶部外边距,替代原先的页内边距 */
td {
padding: 10px 0;
border: 1px solid #333;
}
}
.xh {
width: 50px !important;
}
.checkbox {
border: 2px solid #999;
width: 15px;
height: 15px;
display: flex;
justify-content: center;
align-items: center;
margin-left: 10px;
}
/*
A4的大小21cm*29.7cmwidth:794px;
单位换算1 inch = 2.54 cm 1mm = 96 px 1 cm = 37.79528 px*/
</style>

@ -17,6 +17,11 @@
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.HELI_MATERIAL_TYPE)" :key="dict.label" :label="dict.label" :value="dict.label" />
</el-select>
</el-form-item>
<el-form-item label="仓库" prop="whId">
<el-select v-model="queryParams.whId" placeholder="下拉选择" clearable class="!w-240px">
<el-option v-for="dict in whList" :key="dict.id" :label="dict.wh_name" :value="dict.id" />
</el-select>
</el-form-item>
<el-form-item label="批次号" prop="lotNo" v-if="false">
<el-input v-model="queryParams.lotNo" placeholder="批次号" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
@ -87,13 +92,13 @@ import * as StorageLogApi from '@/api/heli/storagelog'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
// import * as WarehouseApi from '@/api/heli/warehouse'
import * as WarehouseApi from '@/api/heli/warehouse'
// import * as RgApi from '@/api/heli/rg'
// import * as PnApi from '@/api/heli/pn'
defineOptions({ name: 'StorageLog' })
// const whList = ref([])
const whList = ref([])
// const rgList = ref([])
// const pnList = ref([])
@ -109,6 +114,7 @@ const queryParams = reactive({
matCode: undefined,
matName: undefined,
matType: undefined,
whId:undefined,
lotNo: undefined,
pnId: undefined,
stockNo: undefined,
@ -140,10 +146,10 @@ const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
// //
// const init_page_wh = (async ()=>{
// whList.value = await WarehouseApi.getSimpList()
// })
//
const init_page_wh = (async ()=>{
whList.value = await WarehouseApi.getSimpList()
})
// //
// const init_page_rg = (async ()=>{
// rgList.value = await RgApi.getSimpList()
@ -155,7 +161,7 @@ const resetQuery = () => {
/** 初始化 **/
onMounted(async () => {
// await init_page_wh()
await init_page_wh()
// await init_page_rg()
// await init_page_pn()
await getList()

@ -167,6 +167,26 @@ CREATE TABLE `project_material_plan_detail` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='物料需求计划物料详情表';
CREATE OR REPLACE VIEW v_storage_material_log AS
select 0 AS `deleted`,`lg`.`id` AS `id`,`lg`.`creator` AS `creator`,`lg`.`create_time` AS `create_time`,`lg`.`updater` AS `updater`,`lg`.`update_time` AS `update_time`,
`lg`.`tenant_id` AS `tenant_id`,`lg`.`status` AS `status`,`mat`.`code` AS `mat_code`,`mat`.`name` AS `mat_name`,
(select `system_dict_data`.`label` from `system_dict_data` where ((`system_dict_data`.`dict_type` = 'heli_material_type') and (`system_dict_data`.`value` = `mat`.`material_type`))) AS `mat_type`,
(case when (isnull(`mat`.`short_name`) = TRUE) then '' else `mat`.`short_name` end) AS `short_name`,
(case when (isnull(`mat`.`spec`) = TRUE) then '' else `mat`.`spec` end) AS `mat_spec`,
(case when (isnull(`mat`.`brand`) = TRUE) then '' else `mat`.`brand` end) AS `mat_brand`,
(select `system_dict_data`.`label` from `system_dict_data` where ((`system_dict_data`.`dict_type` = 'heli_material_unit') and (`system_dict_data`.`value` = `mat`.`unit`))) AS `mat_unit`,
`st`.`stock_no` AS `stock_no`,`st`.`stock_type` AS `stock_type`,
(case when (`st`.`stock_type` = 1) then (select `system_dict_data`.`label` from `system_dict_data` where ((`system_dict_data`.`dict_type` = 'heli_storage_in_type') and (`system_dict_data`.`value` = `st`.`stock_in_type`))) else (select `system_dict_data`.`label` from `system_dict_data` where ((`system_dict_data`.`dict_type` = 'heli_storage_out_type') and (`system_dict_data`.`value` = `st`.`stock_in_type`))) end) AS `stock_type_name`,
(case when (isnull(`st`.`header_no`) = TRUE) then '' else `st`.`header_no` end) AS `header_no`,`wh`.`id` AS `wh_id`,`wh`.`wh_name` AS `wh_name`,`rg`.`rg_name` AS `rg_name`,`pn`.`pn_name` AS `pn_name`,
(case when (isnull(`lg`.`lot_no`) = 1) then '' else `lg`.`lot_no` end) AS `lot_no`,
(case when ((`st`.`stock_type` = 1) and (`lg`.`status` = 2)) then `lg`.`storage_ok_qty` when ((`st`.`stock_type` = 1) and (`lg`.`status` = 3)) then (-(1) * `lg`.`storage_ok_qty`) when ((`st`.`stock_type` = 2) and (`lg`.`status` = 2)) then (-(1) * `lg`.`storage_ok_qty`) when ((`st`.`stock_type` = 2) and (`lg`.`status` = 3)) then `lg`.`storage_ok_qty` else `lg`.`storage_ok_qty` end) AS `storage_ok_qty`
from (((((`wms_storage_log` `lg` left join `wms_storage` `st` on((`lg`.`stock_id` = `st`.`id`)))
left join `base_material` `mat` on((`lg`.`mat_id` = `mat`.`id`)))
left join `wms_wh` `wh` on((`lg`.`wh_id` = `wh`.`id`)))
left join `wms_rg` `rg` on((`lg`.`rg_id` = `rg`.`id`)))
left join `wms_pn` `pn` on((`lg`.`pn_id` = `pn`.`id`)))
where ((`st`.`deleted` = 0) and (`mat`.`deleted` = 0) and (`wh`.`deleted` = 0) and (`rg`.`deleted` = 0) and (`pn`.`deleted` = 0));
DROP TABLE IF EXISTS `base_bom`;
DROP TABLE IF EXISTS `pro_plan`;

Loading…
Cancel
Save