mitao
昨天 cff854df2740e862a9255df58c7629e5c559d973
广告物料单价接口
16个文件已修改
6个文件已添加
732 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdMakeController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdMaterialPriceController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/listener/AssetAdValidatorListener.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AdHandleCompleteDTO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AdUpdateMaterialDTO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AssetAdMaterialPriceDTO.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/AssetAdMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/AssetAdMaterialPriceMapper.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetAd.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetAdMaterialPrice.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/AssetAdMaterialPriceQuery.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/AssetAdQuery.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/AssetAdMaterialPriceService.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/OaApprovalApplicationAdService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetAdMaterialPriceServiceImpl.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetAdServiceImpl.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationAdServiceImpl.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/AssetAdMaterialPriceVO.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/AssetAdMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/AssetAdMaterialPriceMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdController.java
@@ -14,6 +14,7 @@
import com.ruoyi.system.service.AssetAdService;
import com.ruoyi.system.vo.asset.AssetAdDetailVO;
import com.ruoyi.system.vo.asset.AssetAdVO;
import com.ruoyi.web.controller.listener.AssetAdValidatorListener;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@@ -111,7 +112,7 @@
            return R.fail("请选择一个文件上传!");
        }
        try {
            List<AssetAdDTO> list = FastExcel.read(file.getInputStream()).head(AssetAdDTO.class)
            List<AssetAdDTO> list = FastExcel.read(file.getInputStream(), AssetAdDTO.class, new AssetAdValidatorListener())
                    .sheet()
                    .doReadSync();
            assetAdService.importAssetAd(list);
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdMakeController.java
@@ -5,6 +5,8 @@
import com.ruoyi.system.query.ApprovalApplicationAdQuery;
import com.ruoyi.system.service.OaApprovalApplicationAdService;
import com.ruoyi.system.vo.ApprovalApplicationAdVO;
import com.ruoyi.system.dto.asset.AdHandleCompleteDTO;
import com.ruoyi.system.dto.asset.AdUpdateMaterialDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
@@ -35,4 +37,26 @@
        return R.ok(oaApprovalApplicationAdService.getPageList(query));
    }
    @PostMapping("/handle-complete")
    @ApiOperation("处理完成 - 更新接单人员、广告图、处理状态")
    public R<Boolean> handleComplete(@RequestBody @Validated AdHandleCompleteDTO dto) {
        boolean success = oaApprovalApplicationAdService.handleComplete(dto);
        if (success) {
            return R.ok(true, "处理完成操作成功");
        } else {
            return R.fail("处理完成操作失败,请检查记录是否存在或权限不足");
        }
    }
    @PostMapping("/update-material")
    @ApiOperation("修改完成资料 - 更新广告图")
    public R<Boolean> updateMaterial(@RequestBody @Validated AdUpdateMaterialDTO dto) {
        boolean success = oaApprovalApplicationAdService.updateMaterial(dto);
        if (success) {
            return R.ok(true, "修改完成资料操作成功");
        } else {
            return R.fail("修改完成资料操作失败,请检查记录是否存在或权限不足");
        }
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdMaterialPriceController.java
@@ -1,8 +1,38 @@
package com.ruoyi.web.controller.api;
import cn.idev.excel.FastExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.dto.asset.AssetAdMaterialPriceDTO;
import com.ruoyi.system.query.AssetAdMaterialPriceQuery;
import com.ruoyi.system.service.AssetAdMaterialPriceService;
import com.ruoyi.system.vo.asset.AssetAdMaterialPriceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
/**
 * <p>
@@ -12,9 +42,87 @@
 * @author WuGuanFengYue
 * @since 2025-09-15
 */
@Api(tags = {"广告物料单价相关接口"})
@Slf4j
@Validated
@RestController
@RequestMapping("/asset-ad-material-price")
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class AssetAdMaterialPriceController {
    private final AssetAdMaterialPriceService assetAdMaterialPriceService;
    @ApiOperation(value = "新增广告物料单价")
    @Log(title = "新增广告物料单价", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public R<?> addAssetAdMaterialPrice(@Valid @RequestBody AssetAdMaterialPriceDTO dto) {
        assetAdMaterialPriceService.addAssetAdMaterialPrice(dto);
        return R.ok();
    }
    @ApiOperation(value = "编辑广告物料单价")
    @Log(title = "编辑广告物料单价", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public R<?> editAssetAdMaterialPrice(@Valid @RequestBody AssetAdMaterialPriceDTO dto) {
        assetAdMaterialPriceService.editAssetAdMaterialPrice(dto);
        return R.ok();
    }
    @ApiOperation("获取分页列表")
    @PostMapping("/page")
    public R<IPage<AssetAdMaterialPriceVO>> getPageList(@RequestBody AssetAdMaterialPriceQuery query) {
        return R.ok(assetAdMaterialPriceService.getPageList(query));
    }
    @ApiOperation("详情")
    @GetMapping("/detail/{id}")
    public R<AssetAdMaterialPriceVO> getDetail(@ApiParam(name = "id", value = "广告物料单价ID") @PathVariable Integer id) {
        return R.ok(assetAdMaterialPriceService.getDetail(id));
    }
    @ApiOperation("删除")
    @Transactional(rollbackFor = Exception.class)
    @DeleteMapping("/{id}")
    public R<?> delete(@ApiParam(name = "id", value = "广告物料单价ID") @PathVariable Integer id) {
        assetAdMaterialPriceService.removeById(id);
        return R.ok();
    }
    @ApiOperation("下载导入模板")
    @GetMapping("/template")
    public void getTemplate(HttpServletResponse response){
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = null;
        try {
            fileName = URLEncoder.encode("广告物料单价导入模板", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            FastExcel.write(response.getOutputStream(), AssetAdMaterialPriceDTO.class)
                    .sheet("广告物料单价")
                    .doWrite(Collections.emptyList());
        } catch (IOException e) {
            log.error("下载导入模板异常", e);
        }
    }
    @ApiOperation("导入")
    @Log(title = "导入广告物料单价", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    public R<?> importAssetAdMaterialPrice(@RequestPart("file") MultipartFile file){
        if (file.isEmpty()) {
            return R.fail("请选择一个文件上传!");
        }
        try {
            List<AssetAdMaterialPriceDTO> list = FastExcel.read(file.getInputStream())
                    .head(AssetAdMaterialPriceDTO.class)
                    .sheet()
                    .doReadSync();
            assetAdMaterialPriceService.importAssetAdMaterialPrice(list);
            return R.ok();
        } catch (IOException e) {
            log.error("文件处理失败", e);
            return R.fail("文件处理失败!");
        }
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/listener/AssetAdValidatorListener.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.web.controller.listener;
import cn.hutool.core.collection.CollUtil;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.event.AnalysisEventListener;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.dto.asset.AssetAdDTO;
import java.util.ArrayList;
import java.util.List;
/**
 * @author mitao
 * @date 2025/10/21
 */
public class AssetAdValidatorListener extends AnalysisEventListener<AssetAdDTO> {
    private List<String> errList = new ArrayList<>();
    @Override
    public void invoke(AssetAdDTO assetAdDTO, AnalysisContext analysisContext) {
        Integer rowIndex = analysisContext.readRowHolder().getRowIndex();
        rowIndex += 1;
        if (StringUtils.isBlank(assetAdDTO.getAssetName())) {
            errList.add(String.format("第%d行", rowIndex));
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (CollUtil.isNotEmpty(errList)) {
            throw new ServiceException(String.format("%s,资产名称不能为空",String.join(",", errList)));
        }
    }
}
ruoyi-system/pom.xml
@@ -65,7 +65,7 @@
        <dependency>
            <groupId>cn.idev.excel</groupId>
            <artifactId>fastexcel</artifactId>
            <version>1.3.0</version>
            <version>1.2.0</version>
        </dependency>
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AdHandleCompleteDTO.java
New file
@@ -0,0 +1,36 @@
package com.ruoyi.system.dto.asset;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * 广告制作申请处理完成请求参数
 *
 * @author mitao
 * @date 2025/10/21
 */
@Data
@ApiModel("广告制作申请处理完成请求参数")
public class AdHandleCompleteDTO {
    @ApiModelProperty(value = "广告制作申请ID", required = true)
    @NotNull(message = "广告制作申请ID不能为空")
    private Integer id;
    @ApiModelProperty(value = "接单人员", required = true)
    @NotBlank(message = "接单人员不能为空")
    private String orderTaker;
    @ApiModelProperty(value = "广告图(多个使用英文逗号拼接)", required = true)
    @NotBlank(message = "广告图不能为空")
    private String fileUrl;
    @ApiModelProperty(value = "处理状态 0-待处理,1-已处理", required = true)
    @NotNull(message = "处理状态不能为空")
    private Integer status;
}
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AdUpdateMaterialDTO.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.system.dto.asset;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * 广告制作申请修改完成资料请求参数
 *
 * @author mitao
 * @date 2025/10/21
 */
@Data
@ApiModel("广告制作申请修改完成资料请求参数")
public class AdUpdateMaterialDTO {
    @ApiModelProperty(value = "广告制作申请ID", required = true)
    @NotNull(message = "广告制作申请ID不能为空")
    private Integer id;
    @ApiModelProperty(value = "广告图(多个使用英文逗号拼接)", required = true)
    @NotBlank(message = "广告图不能为空")
    private String fileUrl;
}
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AssetAdMaterialPriceDTO.java
New file
@@ -0,0 +1,53 @@
package com.ruoyi.system.dto.asset;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
 * 广告物料单价数据传输对象
 *
 * @author WuGuanFengYue
 * @since 2025-09-15
 */
@ExcelIgnoreUnannotated
@Data
@ApiModel("广告物料单价数据传输对象")
public class AssetAdMaterialPriceDTO {
    @ApiModelProperty(value = "主键")
    private Integer id;
    @ApiModelProperty(value = "物料名称")
    @ExcelProperty("物料名称")
    @ColumnWidth(15)
    @NotBlank(message = "物料名称不能为空")
    private String materialName;
    @ApiModelProperty(value = "单价")
    @ExcelProperty("单价")
    @ColumnWidth(10)
    @NotNull(message = "单价不能为空")
    @DecimalMin(value = "0.01", message = "单价必须大于0")
    private BigDecimal unitPrice;
    @ApiModelProperty(value = "单位(元、平方米等)")
    @ExcelProperty("单位")
    @ColumnWidth(8)
    @NotBlank(message = "单位不能为空")
    private String priceUnit;
    @ApiModelProperty(value = "备注")
    @ExcelProperty("备注")
    @ColumnWidth(20)
    private String remarks;
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/AssetAdMapper.java
@@ -1,7 +1,11 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.system.model.AssetAd;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.system.query.AssetAdQuery;
import com.ruoyi.system.vo.asset.AssetAdVO;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
@@ -13,4 +17,5 @@
 */
public interface AssetAdMapper extends BaseMapper<AssetAd> {
    Page<AssetAdVO> getPageList(Page<AssetAdVO> page, @Param("query") AssetAdQuery query);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/AssetAdMaterialPriceMapper.java
@@ -1,7 +1,12 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.system.model.AssetAdMaterialPrice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.system.query.AssetAdMaterialPriceQuery;
import com.ruoyi.system.vo.asset.AssetAdMaterialPriceVO;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
@@ -13,4 +18,12 @@
 */
public interface AssetAdMaterialPriceMapper extends BaseMapper<AssetAdMaterialPrice> {
    /**
     * 分页查询
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<AssetAdMaterialPriceVO> getPageList(Page<AssetAdMaterialPriceVO> page, @Param("query") AssetAdMaterialPriceQuery query);
}
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetAd.java
@@ -45,6 +45,10 @@
    @TableField("asset_type_id")
    private Integer assetTypeId;
    @ApiModelProperty(value = "所属部门")
    @TableField("dept_id")
    private Integer deptId;
    @ApiModelProperty(value = "位置")
    @TableField("location")
    private String location;
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetAdMaterialPrice.java
@@ -34,6 +34,10 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty(value = "部门id")
    @TableField("dept_id")
    private Integer deptId;
    @ApiModelProperty(value = "物料名称")
    @TableField("material_name")
    private String materialName;
ruoyi-system/src/main/java/com/ruoyi/system/query/AssetAdMaterialPriceQuery.java
New file
@@ -0,0 +1,26 @@
package com.ruoyi.system.query;
import com.ruoyi.common.core.domain.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * 广告物料单价查询条件对象
 *
 * @author WuGuanFengYue
 * @since 2025-09-15
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("广告物料单价查询条件对象")
public class AssetAdMaterialPriceQuery extends BasePage {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("物料名称(模糊搜索)")
    private String materialName;
    @ApiModelProperty("部门ID(非管理员时作为数据权限过滤),前端不传")
    private Integer deptId;
}
ruoyi-system/src/main/java/com/ruoyi/system/query/AssetAdQuery.java
@@ -18,4 +18,7 @@
    @ApiModelProperty("关键字 资产名称/资产编号")
    private String keyword;
    @ApiModelProperty("部门ID(非管理员时作为数据权限过滤),前端不传")
    private Integer deptId;
}
ruoyi-system/src/main/java/com/ruoyi/system/service/AssetAdMaterialPriceService.java
@@ -1,7 +1,13 @@
package com.ruoyi.system.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.system.dto.asset.AssetAdMaterialPriceDTO;
import com.ruoyi.system.model.AssetAdMaterialPrice;
import com.ruoyi.system.query.AssetAdMaterialPriceQuery;
import com.ruoyi.system.vo.asset.AssetAdMaterialPriceVO;
import java.util.List;
/**
 * <p>
@@ -13,4 +19,36 @@
 */
public interface AssetAdMaterialPriceService extends IService<AssetAdMaterialPrice> {
    /**
     * 添加广告物料单价
     * @param dto
     */
    void addAssetAdMaterialPrice(AssetAdMaterialPriceDTO dto);
    /**
     * 编辑广告物料单价
     * @param dto
     */
    void editAssetAdMaterialPrice(AssetAdMaterialPriceDTO dto);
    /**
     * 广告物料单价分页列表
     * @param query
     * @return
     */
    IPage<AssetAdMaterialPriceVO> getPageList(AssetAdMaterialPriceQuery query);
    /**
     * 获取详情
     *
     * @param id
     * @return
     */
    AssetAdMaterialPriceVO getDetail(Integer id);
    /**
     * 导入广告物料单价
     * @param list
     */
    void importAssetAdMaterialPrice(List<AssetAdMaterialPriceDTO> list);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/OaApprovalApplicationAdService.java
@@ -5,6 +5,8 @@
import com.ruoyi.system.model.OaApprovalApplicationAd;
import com.ruoyi.system.query.ApprovalApplicationAdQuery;
import com.ruoyi.system.vo.ApprovalApplicationAdVO;
import com.ruoyi.system.dto.asset.AdHandleCompleteDTO;
import com.ruoyi.system.dto.asset.AdUpdateMaterialDTO;
/**
 * <p>
@@ -17,4 +19,20 @@
public interface OaApprovalApplicationAdService extends IService<OaApprovalApplicationAd> {
    IPage<ApprovalApplicationAdVO> getPageList(ApprovalApplicationAdQuery query);
    /**
     * 处理完成 - 更新接单人员、广告图、处理状态
     *
     * @param dto 处理完成请求参数
     * @return 是否成功
     */
    boolean handleComplete(AdHandleCompleteDTO dto);
    /**
     * 修改完成资料 - 更新广告图
     *
     * @param dto 修改完成资料请求参数
     * @return 是否成功
     */
    boolean updateMaterial(AdUpdateMaterialDTO dto);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetAdMaterialPriceServiceImpl.java
@@ -1,10 +1,26 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.constants.AssetDeptConstant;
import com.ruoyi.system.dto.asset.AssetAdMaterialPriceDTO;
import com.ruoyi.system.mapper.AssetAdMaterialPriceMapper;
import com.ruoyi.system.model.AssetAdMaterialPrice;
import com.ruoyi.system.query.AssetAdMaterialPriceQuery;
import com.ruoyi.system.service.AssetAdMaterialPriceService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.vo.asset.AssetAdMaterialPriceVO;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -15,6 +31,78 @@
 * @since 2025-09-15
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class AssetAdMaterialPriceServiceImpl extends ServiceImpl<AssetAdMaterialPriceMapper, AssetAdMaterialPrice> implements AssetAdMaterialPriceService {
    private final ISysUserService sysUserService;
    @Override
    public void addAssetAdMaterialPrice(AssetAdMaterialPriceDTO dto) {
        AssetAdMaterialPrice entity = BeanUtil.copyProperties(dto, AssetAdMaterialPrice.class);
        entity.setDeptId(Integer.parseInt(SecurityUtils.getLoginUser().getUser().getDeptId()));
        entity.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        entity.setCreateTime(LocalDateTime.now());
        save(entity);
    }
    @Override
    public void editAssetAdMaterialPrice(AssetAdMaterialPriceDTO dto) {
        AssetAdMaterialPrice entity = BeanUtil.copyProperties(dto, AssetAdMaterialPrice.class);
        entity.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        entity.setUpdateTime(LocalDateTime.now());
        updateById(entity);
    }
    @Override
    public IPage<AssetAdMaterialPriceVO> getPageList(AssetAdMaterialPriceQuery query) {
        // 数据权限:超级管理员/资产管理部查看所有数据,其他部门查看当前及下级部门的数据
        Long userId = SecurityUtils.getUserId();
        boolean isAdmin = SecurityUtils.isAdmin(userId);
        if (!isAdmin) {
            try {
                // 获取当前用户的部门名称
                String deptName = sysUserService.selectUserById(userId).getDeptName();
                // 非超级管理员且非资产管理部,设置部门权限
                if (!AssetDeptConstant.ASSET_INVENTORY_DEPT_NAMES.contains(deptName)) {
                    query.setDeptId(Integer.valueOf(SecurityUtils.getLoginUser().getDeptId()));
                }
            } catch (Exception e) {
                // 如果获取部门信息失败,默认设置部门权限
                try {
                    query.setDeptId(Integer.valueOf(SecurityUtils.getLoginUser().getDeptId()));
                } catch (Exception ex) {
                    // ignore parse, leave null if cannot parse
                }
            }
        }
        // 直接使用Mapper的分页查询方法
        Page<AssetAdMaterialPriceVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        return baseMapper.getPageList(page, query);
    }
    @Override
    public AssetAdMaterialPriceVO getDetail(Integer id) {
        AssetAdMaterialPrice entity = getById(id);
        if (entity == null) {
            return null;
        }
        return BeanUtil.copyProperties(entity, AssetAdMaterialPriceVO.class);
    }
    @Override
    public void importAssetAdMaterialPrice(List<AssetAdMaterialPriceDTO> list) {
        if (CollUtil.isNotEmpty(list)) {
            String currentUser = SecurityUtils.getLoginUser().getUser().getNickName();
            LocalDateTime now = LocalDateTime.now();
            List<AssetAdMaterialPrice> entities = list.stream().map(dto -> {
                AssetAdMaterialPrice entity = BeanUtil.copyProperties(dto, AssetAdMaterialPrice.class);
                entity.setCreateBy(currentUser);
                entity.setCreateTime(now);
                return entity;
            }).collect(Collectors.toList());
            saveBatch(entities);
        }
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetAdServiceImpl.java
@@ -1,11 +1,13 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.constants.AssetDeptConstant;
import com.ruoyi.system.dto.asset.AssetAdDTO;
import com.ruoyi.system.mapper.AssetAdMapper;
import com.ruoyi.system.mapper.AssetAdRentalRecordMapper;
@@ -14,18 +16,17 @@
import com.ruoyi.system.query.AssetAdQuery;
import com.ruoyi.system.service.AssetAdService;
import com.ruoyi.system.service.AssetTypeService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.vo.asset.AssetAdDetailVO;
import com.ruoyi.system.vo.asset.AssetAdRentalRecordVO;
import com.ruoyi.system.vo.asset.AssetAdVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -44,6 +45,7 @@
public class AssetAdServiceImpl extends ServiceImpl<AssetAdMapper, AssetAd> implements AssetAdService {
    private final AssetTypeService assetTypeService;
    private final AssetAdRentalRecordMapper rentalRecordMapper;
    private final ISysUserService sysUserService;
    @Override
    public void addAssetAd(AssetAdDTO dto) {
@@ -51,6 +53,7 @@
        assetAd.setAssetTypeId(2);
        assetAd.setAssetCode(generateCode());
        assetAd.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        assetAd.setDeptId(Integer.parseInt(SecurityUtils.getLoginUser().getUser().getDeptId()));
        save(assetAd);
    }
@@ -83,15 +86,30 @@
    @Override
    public IPage<AssetAdVO> getPageList(AssetAdQuery query) {
        // 1. 分页查询 AssetAd
        Page<AssetAd> page = new Page<>(query.getPageNum(), query.getPageSize());
        LambdaQueryWrapper<AssetAd> queryWrapper = new LambdaQueryWrapper<AssetAd>()
            .like(StringUtils.isNotBlank(query.getKeyword()), AssetAd::getAssetName, query.getKeyword())
            .or()
            .like(StringUtils.isNotBlank(query.getKeyword()), AssetAd::getAssetCode, query.getKeyword())
            .orderByDesc(AssetAd::getCreateTime);
        // 数据权限:超级管理员/资产管理部查看所有数据,其他部门查看当前及下级部门的数据
        Long userId = SecurityUtils.getUserId();
        boolean isAdmin = SecurityUtils.isAdmin(userId);
        Page<AssetAd> assetPage = this.page(page, queryWrapper);
        if (!isAdmin) {
            try {
                // 获取当前用户的部门名称
                String deptName = sysUserService.selectUserById(userId).getDeptName();
                // 非超级管理员且非资产管理部,设置部门权限
                if (!AssetDeptConstant.ASSET_INVENTORY_DEPT_NAMES.contains(deptName)) {
                    query.setDeptId(Integer.valueOf(SecurityUtils.getLoginUser().getDeptId()));
                }
            } catch (Exception e) {
                // 如果获取部门信息失败,默认设置部门权限
                try {
                    query.setDeptId(Integer.valueOf(SecurityUtils.getLoginUser().getDeptId()));
                } catch (Exception ex) {
                    // ignore parse, leave null if cannot parse
                }
            }
        }
        // 1. 分页查询 AssetAd
        Page<AssetAdVO> assetPage = this.baseMapper.getPageList(new Page<>(query.getPageNum(), query.getPageSize()), query);
        // 2. 如果没有数据,返回空分页
        if (assetPage.getRecords().isEmpty()) {
@@ -100,7 +118,7 @@
        // 3. 获取所有资产ID
        List<Integer> assetAdIds = assetPage.getRecords().stream()
            .map(AssetAd::getId)
            .map(AssetAdVO::getId)
            .collect(Collectors.toList());
        // 4. 查询相关租赁记录
@@ -118,30 +136,18 @@
                .collect(Collectors.toMap(AssetAdRentalRecord::getAssetAdId, Function.identity()));
        // 6. 组装VO数据
        List<AssetAdVO> voList = new ArrayList<>();
        for (AssetAd asset : assetPage.getRecords()) {
            AssetAdVO vo = BeanUtil.copyProperties(asset, AssetAdVO.class);
        for (AssetAdVO vo : assetPage.getRecords()) {
            // 设置租赁相关信息
            AssetAdRentalRecord currentRental = currentRentalMap.get(asset.getId());
            AssetAdRentalRecord currentRental = currentRentalMap.get(vo.getId());
            if (currentRental != null) {
                vo.setCurrentUseBy(currentRental.getUseBy());
                vo.setRentalPrice(currentRental.getRentalPrice());
                vo.setUseDuration(calculateUseDuration(currentRental.getStartDate(), currentRental.getEndDate()));
            }
            voList.add(vo);
        }
        // 7. 返回分页结果
        Page<AssetAdVO> resultPage = new Page<>(query.getPageNum(), query.getPageSize());
        resultPage.setRecords(voList);
        resultPage.setTotal(assetPage.getTotal());
        resultPage.setSize(assetPage.getSize());
        resultPage.setCurrent(assetPage.getCurrent());
        resultPage.setPages(assetPage.getPages());
        return resultPage;
        return assetPage;
    }
    /**
@@ -184,13 +190,15 @@
    @Override
    public void importAssetAd(List<AssetAdDTO> list) {
        List<AssetAd> collect = list.stream().map(item -> {
            AssetAd assetAd = BeanUtil.copyProperties(item, AssetAd.class);
            assetAd.setAssetTypeId(2);
            assetAd.setAssetCode(generateCode());
            assetAd.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
            return assetAd;
        }).collect(Collectors.toList());
        saveBatch(collect);
        if (CollUtil.isNotEmpty(list)) {
            List<AssetAd> collect = list.stream().map(item -> {
                AssetAd assetAd = BeanUtil.copyProperties(item, AssetAd.class);
                assetAd.setAssetTypeId(2);
                assetAd.setAssetCode(generateCode());
                assetAd.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
                return assetAd;
            }).collect(Collectors.toList());
            saveBatch(collect);
        }
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationAdServiceImpl.java
@@ -5,6 +5,8 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.constants.AssetDeptConstant;
import com.ruoyi.system.dto.asset.AdHandleCompleteDTO;
import com.ruoyi.system.dto.asset.AdUpdateMaterialDTO;
import com.ruoyi.system.mapper.OaApprovalApplicationAdMapper;
import com.ruoyi.system.model.OaApprovalApplicationAd;
import com.ruoyi.system.query.ApprovalApplicationAdQuery;
@@ -14,6 +16,8 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
/**
 * <p>
@@ -53,4 +57,65 @@
        }
        return baseMapper.getPageList(new Page<>(query.getPageNum(), query.getPageSize()), query);
    }
    @Override
    public boolean handleComplete(AdHandleCompleteDTO dto) {
        // 查询记录是否存在
        OaApprovalApplicationAd entity = getById(dto.getId());
        if (entity == null) {
            return false;
        }
        // 更新字段
        entity.setOrderTaker(dto.getOrderTaker());
        entity.setFileUrl(dto.getFileUrl());
        entity.setStatus(dto.getStatus());
        entity.setHandleTime(LocalDateTime.now());
        return updateById(entity);
    }
    @Override
    public boolean updateMaterial(AdUpdateMaterialDTO dto) {
        // 查询记录是否存在
        OaApprovalApplicationAd entity = getById(dto.getId());
        if (entity == null) {
            return false;
        }
        // 只更新广告图
        entity.setFileUrl(dto.getFileUrl());
        return updateById(entity);
    }
    /**
     * 检查用户是否有数据权限处理该记录
     *
     * @param entity 实体对象
     * @return 是否有权限
     */
    private boolean hasDataPermission(OaApprovalApplicationAd entity) {
        Long userId = SecurityUtils.getUserId();
        boolean isAdmin = SecurityUtils.isAdmin(userId);
        // 超级管理员有所有权限
        if (isAdmin) {
            return true;
        }
        try {
            // 获取当前用户的部门名称
            String deptName = sysUserService.selectUserById(userId).getDeptName();
            // 资产管理部有所有权限
            if (AssetDeptConstant.ASSET_DEPARTMENT_NAME.equals(deptName)) {
                return true;
            }
        } catch (Exception e) {
            // 如果获取部门信息失败,默认无权限
            return false;
        }
        return false;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/AssetAdMaterialPriceVO.java
New file
@@ -0,0 +1,50 @@
package com.ruoyi.system.vo.asset;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * 广告物料单价视图对象
 *
 * @author WuGuanFengYue
 * @since 2025-09-15
 */
@Data
@ApiModel("广告物料单价视图对象")
public class AssetAdMaterialPriceVO {
    @ApiModelProperty(value = "主键")
    private Integer id;
    @ApiModelProperty(value = "物料名称")
    private String materialName;
    @ApiModelProperty(value = "单价")
    private BigDecimal unitPrice;
    @ApiModelProperty(value = "单位(元、平方米等)")
    private String priceUnit;
    @ApiModelProperty(value = "备注")
    private String remarks;
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建人")
    private String createBy;
    @ApiModelProperty(value = "更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "更新人")
    private String updateBy;
}
ruoyi-system/src/main/resources/mapper/system/AssetAdMapper.xml
@@ -24,5 +24,31 @@
    <sql id="Base_Column_List">
        id, asset_name, asset_code, asset_type_id, location, rental_type, asset_status, remarks, attachment_urls, create_time, create_by, update_time, update_by, disabled
    </sql>
    <select id="getPageList" resultType="com.ruoyi.system.vo.asset.AssetAdVO">
        SELECT aa.id,
        asset_name,
        asset_code,
        dept_id,
        asset_type_id,
        location,
        rental_type,
        asset_status,
        remarks,
        attachment_urls,
        create_time,
        create_by
        FROM asset_ad aa LEFT JOIN t_dept td ON aa.dept_id = td.id
        <where>
            aa.disabled = 0
            <if test="query.keyword != null and query.keyword != ''">
                AND (aa.asset_name LIKE CONCAT('%', #{query.keyword}, '%')
                OR aa.asset_code LIKE CONCAT('%', #{query.keyword}, '%'))
            </if>
            <if test="query.deptId != null">
                AND (td.id = #{query.deptId} OR FIND_IN_SET(#{query.deptId}, od.parent_id))
            </if>
        </where>
        ORDER BY aa.create_time DESC
    </select>
</mapper>
ruoyi-system/src/main/resources/mapper/system/AssetAdMaterialPriceMapper.xml
@@ -21,4 +21,30 @@
        id, material_name, unit_price, price_unit, remarks, create_time, create_by, update_time, update_by, disabled
    </sql>
    <!-- 分页查询 -->
    <select id="getPageList" resultType="com.ruoyi.system.vo.asset.AssetAdMaterialPriceVO">
        SELECT
            id,
            material_name,
            dept_id,
            unit_price,
            price_unit,
            remarks,
            create_time,
            create_by,
            update_time,
            update_by
        FROM asset_ad_material_price aamp LEFT JOIN t_dept td ON aamp.dept_id = td.id
        <where>
            disabled = 0
            <if test="query.materialName != null and query.materialName != ''">
                AND material_name LIKE CONCAT('%', #{query.materialName}, '%')
            </if>
            <if test="query.deptId != null">
                AND (td.id = #{query.deptId} OR FIND_IN_SET(#{query.deptId}, od.parent_id))
            </if>
        </where>
        ORDER BY create_time DESC
    </select>
</mapper>