skyouc
7 天以前 4b4ee0952cf886a5a2baf160a7aea88201979aed
PO单导入功能
1个文件已添加
12个文件已修改
353 ■■■■ 已修改文件
rsf-admin/src/i18n/en.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/purchase/PurchaseCreate.jsx 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/purchase/PurchaseEdit.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/purchase/PurchaseList.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/waitPakin/WaitPakinList.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/PurchaseItemController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/PurchaseTemplate.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/PurchaseItemService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/PurchaseItemServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/DictData.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -599,7 +599,6 @@
                barcode: "barcode",
                packName: "packName",
                ntyStatus: "ntyStatus",
                platItemId: 'platItemId'
            },
            asnOrderLog: {
                code: "code",
rsf-admin/src/i18n/zh.js
@@ -539,7 +539,7 @@
                code: "ASN单号",
                poCode: "PO编码",
                poId: "PO标识",
                type: "类型",
                type: "单据类型",
                wkType: "业务类型",
                anfme: "计划数量",
                qty: "完成数量",
@@ -587,11 +587,10 @@
                splrCode: "供应商编码",
                splrName: "供应商",
                qrcode: "二维码",
                barcode: "条形码",
                barcode: "序列码",
                packName: "包装",
                ntyStatus: "报检状态",
                prodTime: "生产日期",
                platItemId: '行号'
            },
            outStockItem: {
                asnId: "主单标识",
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx
@@ -183,7 +183,7 @@
            <MyButton setCreateDialog={setCreateDialog} setmodalType={setmodalType} />
            <InspectionButton />
            <CompleteButton />
            <DeleteButton mutationMode="pessimistic" />
            <ODeleteButton  />
            {/* <CloseButton /> */}
          </WrapperField>
        </StyledDatagrid>
@@ -207,9 +207,8 @@
const ODeleteButton = () => {
  const record = useRecordContext();
  return (
    record.exceStatus === 0 ? <DeleteButton /> : <></>
    record.exceStatus === 0 ? <DeleteButton  mutationMode="pessimistic"/> : <></>
  )
}
@@ -224,6 +223,7 @@
  };
  return (
    record.exceStatus === 1 || record.exceStatus === 0 ?
    <Button
      color="primary"
      startIcon={<EditIcon />}
@@ -232,6 +232,7 @@
      label={'ra.action.edit'}
    >
    </Button>
    : <></>
  )
}
rsf-admin/src/page/orders/purchase/PurchaseCreate.jsx
@@ -33,6 +33,9 @@
const PurchaseCreate = (props) => {
    const { open, setOpen } = props;
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_in_stock_type')) || [];
    const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type'))?.filter(data => (data.group == '1')) || [];
    console.log(business);
    const translate = useTranslate();
    const notify = useNotify();
@@ -93,11 +96,23 @@
                                    />
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.purchase.type"
                                    <AutocompleteInput
                                        choices={dicts}
                                        optionText="label"
                                        label="table.field.asnOrder.type"
                                        source="type"
                                        optionValue="value"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <AutocompleteInput
                                        choices={business}
                                        optionText="label"
                                        label="table.field.asnOrder.wkType"
                                        source="wkType"
                                        optionValue="value"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
@@ -108,12 +123,12 @@
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.purchase.preArr"
                                        source="preArr"
                                    />
                                </Grid>
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.purchase.anfme"
@@ -121,7 +136,7 @@
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.purchase.qty"
                                        source="qty"
@@ -134,7 +149,7 @@
                                        source="workQty"
                                        validate={required()}
                                    />
                                </Grid>
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.purchase.channel"
@@ -142,13 +157,13 @@
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                {/* <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.purchase.platCode"
                                        source="platCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                </Grid> */}
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.purchase.startTime"
rsf-admin/src/page/orders/purchase/PurchaseEdit.jsx
@@ -42,7 +42,8 @@
const PurchaseEdit = () => {
    const translate = useTranslate();
    const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_in_stock_type')) || [];
    const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type'))?.filter(data => (data.group == '1')) || [];
    return (
        <>
            <Edit
@@ -59,7 +60,7 @@
                    defaultValues={{}}
                // validate={(values) => { }}
                >
                    <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3}>
                        <Grid item xs={18} md={10}>
                            <Typography variant="h6" gutterBottom>
                                {translate('common.edit.title.main')}
@@ -73,21 +74,27 @@
                            />
                        </Stack> */}
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.purchase.type"
                                    source="type$"
                                <AutocompleteInput
                                    choices={dicts}
                                    optionText="label"
                                    label="table.field.asnOrder.type"
                                    source="type"
                                    optionValue="value"
                                    parse={v => v}
                                    validate={required()}
                                />
                                <AutocompleteInput
                                    choices={business}
                                    optionText="label"
                                    label="table.field.asnOrder.wkType"
                                    source="wkType"
                                    optionValue="value"
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.purchase.source"
                                    source="source"
                                    parse={v => v}
                                    validate={required()}
                                />
                                <DateInput
                                    label="table.field.purchase.preArr"
                                    source="preArr"
                                />
                                <NumberInput
                                    label="table.field.purchase.anfme"
@@ -96,15 +103,10 @@
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <NumberInput
                                    label="table.field.purchase.qty"
                                    source="qty"
                                    validate={required()}
                                />
                                <NumberInput
                                    label="table.field.purchase.workQty"
                                    source="workQty"
                                    validate={required()}
                                <TextInput
                                    label="table.field.purchase.project"
                                    source="project"
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.purchase.channel"
@@ -116,8 +118,6 @@
                                    source="platCode"
                                    parse={v => v}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                            <DateInput
                                    label="table.field.purchase.startTime"
                                    source="startTime"
@@ -125,11 +125,6 @@
                                <DateInput
                                    label="table.field.purchase.endTime"
                                    source="endTime"
                                />
                                <TextInput
                                    label="table.field.purchase.project"
                                    source="project"
                                    parse={v => v}
                                />
                            </Stack>
                        </Grid>
rsf-admin/src/page/orders/purchase/PurchaseList.jsx
@@ -43,6 +43,7 @@
import MyField from "../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
import ImportButton from "../../components/ImportButton";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
@@ -86,10 +87,8 @@
const PurchaseList = () => {
  const translate = useTranslate();
  const [createDialog, setCreateDialog] = useState(false);
  const [drawerVal, setDrawerVal] = useState(false);
  const navigate = useNavigate();
  const assign = (record) => {
    navigate(`/purchaseItem?poId=${record.id}`);
@@ -115,6 +114,7 @@
            <FilterButton />
            <MyCreateButton onClick={() => { setCreateDialog(true) }} />
            <SelectColumnsButton preferenceKey='purchase' />
            <ImportButton value={'purchaseItem'} />
            <MyExportButton />
          </TopToolbar>
        )}
@@ -131,6 +131,7 @@
          <NumberField source="id" />
          <TextField source="code" label="table.field.purchase.code" />
          <TextField source="type$" label="table.field.purchase.type" />
          <TextField source="wkType$" label="table.field.purchase.wkType" />
          <TextField source="source" label="table.field.purchase.source" />
          <DateField source="preArr" label="table.field.purchase.preArr" showTime />
          <NumberField source="anfme" label="table.field.purchase.anfme" />
rsf-admin/src/page/waitPakin/WaitPakinList.jsx
@@ -58,7 +58,7 @@
        width: 90
    },
    '& .opt': {
        width: 180
        width: 210
    },
}));
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/PurchaseItemController.java
@@ -10,11 +10,15 @@
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.manager.entity.PurchaseItem;
import com.vincent.rsf.server.manager.entity.excel.AsnOrderTemplate;
import com.vincent.rsf.server.manager.entity.excel.PurchaseTemplate;
import com.vincent.rsf.server.manager.service.PurchaseItemService;
import com.vincent.rsf.server.system.controller.BaseController;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@@ -107,4 +111,37 @@
        ExcelUtil.build(ExcelUtil.create(purchaseItemService.list(), PurchaseItem.class), response);
    }
    /**
     * ASN单据明细导入
     * @param file
     * @return
     */
    @PostMapping("/purchaseItem/import")
    @ApiOperation("PO单导入接口")
    @PreAuthorize("hasAuthority('manager:purchaseItem:update')")
    public R importExcel(@RequestParam(value = "file") MultipartFile file) throws Exception {
        if (Objects.isNull(file)) {
            return R.error("文件不能为空!!");
        }
        return purchaseItemService.excelImport(file, getLoginUserId());
    }
    /**
     * @author Ryan
     * @description 下载模板
     * @param
     * @return
     * @time 2025/4/18 08:17
     */
    @PostMapping("/purchaseItem/template/download")
    @ApiOperation("下载收货单模板")
    @PreAuthorize("hasAuthority('manager:purchaseItem:update')")
    public void downloadTemplate(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        PurchaseTemplate template = ExcelUtil.mockData(PurchaseTemplate.class);
        List<PurchaseTemplate> list = Arrays.asList(template);
        ExcelUtil.build(ExcelUtil.create(list, PurchaseTemplate.class, true), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java
@@ -10,11 +10,14 @@
import com.vincent.rsf.server.system.service.DictDataService;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
@@ -31,6 +34,7 @@
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@@ -59,6 +63,9 @@
     */
    @ApiModelProperty(value= "单据类型")
    private String type;
    @ApiModelProperty("业务类型")
    private String wkType;
    @ApiModelProperty(value = "erp主单标识")
@@ -179,7 +186,8 @@
    @ApiModelProperty(value= "备注")
    private String memo;
    public Purchase() {}
    public Purchase() {
    }
    public Purchase(String code,String type,String source,String platId ,Date preArr,Double anfme,Double qty,Double workQty,String channel,String platCode,Date startTime,Date endTime,String project,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.code = code;
@@ -242,6 +250,20 @@
        return dictDatas.getLabel();
    }
    public String getWkType$() {
        if (Cools.isEmpty(this.wkType)) {
            return "";
        }
        DictDataService dictDataService = SpringUtils.getBean(DictDataService.class);
        DictData dictData = dictDataService.getOne(new LambdaQueryWrapper<DictData>()
                .eq(DictData::getDictTypeCode, DictTypeCode.DICT_SYS_BUSINESS_TYPE)
                .eq(DictData::getValue, this.wkType));
        if (Objects.isNull(dictData)) {
            return null;
        }
        return dictData.getLabel();
    }
    public String getPreArr$(){
        if (Cools.isEmpty(this.preArr)){
            return "";
@@ -264,7 +286,9 @@
    }
    public String getStatus$(){
        if (null == this.status){ return null; }
        if (null == this.status) {
            return null;
        }
        switch (this.status){
            case 1:
                return "正常";
@@ -308,9 +332,10 @@
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        if (null == this.status) {
            return null;
        }
        switch (this.status){
            case 1:
                return true;
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/PurchaseTemplate.java
New file
@@ -0,0 +1,135 @@
package com.vincent.rsf.server.manager.entity.excel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelAutoColumnSize;
import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelComment;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@ExcelAutoColumnSize
@Accessors(chain = true)
public class PurchaseTemplate implements Serializable {
    private static final long serialVersionUID = 1L;
    @Excel(name = "PO单号")
    @ApiModelProperty(value= "PO单号")
    @ExcelComment(value = "poCode", example = "PO25413975")
    private String poCode;
    @Excel(name = "单据类型")
    @ApiModelProperty(value= "单据类型")
    @ExcelComment(value = "type", example = "采购入库单")
    private String type;
    @Excel(name = "来源平台")
    @ApiModelProperty(value= "来源平台")
    @ExcelComment(value = "source", example = "ERP")
    private String source;
    @Excel(name = "业务类型")
    @ApiModelProperty(value= "业务类型")
    @ExcelComment(value = "wkType", example = "ERP")
    private String wkType;
    @Excel(name = "项目名称")
    @ApiModelProperty(value= "项目名称")
    @ExcelComment(value = "project", example = "京东电商立库")
    private String project;
    @Excel(name = "行号")
    @ApiModelProperty(value= "行号")
    @ExcelComment(value = "platItemId", example = "100068541001")
    private String platItemId;
    /**
     * 物料编码
     */
    @Excel(name = "物料编码")
    @ApiModelProperty(value= "物料编码")
    @ExcelComment(value = "matnrCode", example = "101000000002")
    private String matnrCode;
    /**
     *
     */
    @Excel(name = "物料名称")
    @ApiModelProperty(value= "物料名称")
    @ExcelComment(value = "matnrName", example = "TC-03128寸连体内上托")
    private String matnrName;
    /**
     * 单位
     */
    @Excel(name = "单位")
    @ApiModelProperty(value= "单位")
    @ExcelComment(value = "unit", example = "个")
    private String unit;
    /**
     * 数量
     */
    @Excel(name = "数量")
    @ApiModelProperty(value= "数量")
    @ExcelComment(value = "anfme", example = "75")
    private Double anfme;
    /**
     * 已收数量
     */
    @Excel(name = "已收数量")
    @ApiModelProperty(value= "已收数量")
    @ExcelComment(value = "qty", example = "0")
    private Double qty;
    /**
     * 标准包装
     */
    @Excel(name = "标准包装")
    @ApiModelProperty(value= "标准包装")
    @ExcelComment(value = "nromQty", example = "1")
    private Double nromQty;
    /**
     * 条码打印数量
     */
    @Excel(name = "条码打印数量")
    @ApiModelProperty(value= "条码打印数量")
    @ExcelComment(value = "printQty", example = "0")
    private Double printQty;
    /**
     * 供应商名称
     */
    @Excel(name = "供应商名称")
    @ApiModelProperty(value= "供应商名称")
    @ExcelComment(value = "splrName", example = "浙江中扬立库技术有限公司")
    private String splrName;
    /**
     * 供应商编码
     */
    @Excel(name = "供应商编码")
    @ApiModelProperty(value= "供应商编码")
    @ExcelComment(value = "splrCode", example = "685947")
    private String splrCode;
    /**
     * 供应商批次
     */
    @Excel(name = "供应商批次")
    @ApiModelProperty(value= "供应商批次")
    @ExcelComment(value = "splrBatch", example = "20250401")
    private String splrBatch;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/PurchaseItemService.java
@@ -1,8 +1,14 @@
package com.vincent.rsf.server.manager.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.manager.entity.PurchaseItem;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.HashMap;
public interface PurchaseItemService extends IService<PurchaseItem> {
    R excelImport(MultipartFile file, Long loginUserId) throws Exception;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/PurchaseItemServiceImpl.java
@@ -1,12 +1,43 @@
package com.vincent.rsf.server.manager.service.impl;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.manager.entity.excel.AsnOrderTemplate;
import com.vincent.rsf.server.manager.entity.excel.PurchaseTemplate;
import com.vincent.rsf.server.manager.mapper.PurchaseItemMapper;
import com.vincent.rsf.server.manager.entity.PurchaseItem;
import com.vincent.rsf.server.manager.service.PurchaseItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.HashMap;
@Service("purchaseItemService")
public class PurchaseItemServiceImpl extends ServiceImpl<PurchaseItemMapper, PurchaseItem> implements PurchaseItemService {
    /**
     * @author Ryan
     * @date 2025/5/6
     * @description: PO单导入功能
     * @version 1.0
     */
    @Override
    public R excelImport(MultipartFile file, Long loginUserId) throws Exception {
        ExcelImportResult result = ExcelImportUtil.importExcelMore(file.getInputStream(), PurchaseTemplate.class, ExcelUtil.getDefaultImportParams());
        if (result.getList().isEmpty()) {
            throw new CoolException("物料导入失败!!");
        }
        if (result.getList().isEmpty()) {
            throw new CoolException("表格内容不能为空!!");
        }
        return null;
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/DictData.java
@@ -1,6 +1,7 @@
package com.vincent.rsf.server.system.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -10,10 +11,7 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -73,6 +71,11 @@
    @ApiModelProperty(value= "颜色。例如:#FFFFFF、blue、rgba(0,0,0,0.5)")
    private String color;
    @ApiModelProperty("分组标识")
    @TableField("`group`")
    private String group;
    /**
     * 状态 1: 正常  0: 冻结  
     */