zhoulisky 10 months ago
parent
commit
910bcfc92e
18 changed files with 1116 additions and 19 deletions
  1. 49 0
      kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/entity/Subject.java
  2. 5 1
      kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/entity/XmAssetEntity.java
  3. 43 0
      kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/vo/SubjectVO.java
  4. 46 1
      kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/AssetController.java
  5. 40 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/SubjectController.java
  6. 73 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/excel/XmFixedAssetExcel.java
  7. 1 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AssetMapper.java
  8. 11 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AssetMapper.xml
  9. 160 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/SubjectMapper.java
  10. 455 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/SubjectMapper.xml
  11. 1 1
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmAssetHoursMapper.xml
  12. 2 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmAssetMapper.java
  13. 12 4
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmAssetMapper.xml
  14. 1 1
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/YsZjfyycqdtfyMapper.xml
  15. 16 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/ISubjectService.java
  16. 15 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IXmAssetService.java
  17. 67 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/SubjectServiceImpl.java
  18. 119 11
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/XmAssetServiceImpl.java

+ 49 - 0
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/entity/Subject.java

@@ -0,0 +1,49 @@
+ package org.sky.scientific.pojo.entity;
+
+ import com.baomidou.mybatisplus.annotation.IdType;
+ import com.baomidou.mybatisplus.annotation.TableId;
+ import com.baomidou.mybatisplus.annotation.TableName;
+ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+ import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+ import io.swagger.v3.oas.annotations.media.Schema;
+ import lombok.Data;
+
+ import java.io.Serial;
+ import java.io.Serializable;
+
+ /**
+  * 实体类
+  *
+   */
+ @Data
+ @TableName("kd_subject")
+ @Schema(description = "Subject对象")
+ public class Subject implements Serializable {
+
+     @Serial
+     private static final long serialVersionUID = 1L;
+
+     @JsonSerialize(using = ToStringSerializer.class)
+     @Schema(description = "主键")
+     @TableId(value = "id", type = IdType.ASSIGN_ID)
+     private Long id;
+
+     @JsonSerialize(using = ToStringSerializer.class)
+     @Schema(description = "父级科目")
+     private Long parentId;
+
+     @Schema(description = "科目代码")
+     private String code;
+
+     @Schema(description = "科目名称")
+     private String name;
+
+     @Schema(description = "会计科目")
+     private String accSubject;
+
+	 @Schema(description = "高新研发费用科目")
+	 private String rdSubject;
+
+	 @Schema(description = "加计扣除研发费用科目")
+	 private String adSubject;
+ }

+ 5 - 1
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/entity/XmAssetEntity.java

@@ -20,7 +20,7 @@ import java.io.Serial;
  * @since 2025-06-29
  */
 @Data
-@TableName("kd_xm_asset")
+@TableName("kd_xm_fixed_asset")
 @EqualsAndHashCode(callSuper = true)
 @Schema
 public class XmAssetEntity extends TenantEntity {
@@ -49,6 +49,10 @@ public class XmAssetEntity extends TenantEntity {
 	@Schema(description = "资产ID")
 	private Long assetId;
 
+	@Schema(description = "资产编码")
+	@NotNull(message = "资产编码")
+	private String zcbm;
+
 	@TableField(exist = false)
 	@Schema(description = "资产信息",hidden = true)
 	private AssetEntity asset;

+ 43 - 0
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/vo/SubjectVO.java

@@ -0,0 +1,43 @@
+ package org.sky.scientific.pojo.vo;
+
+ import com.fasterxml.jackson.annotation.JsonInclude;
+ import io.swagger.v3.oas.annotations.media.Schema;
+ import lombok.Data;
+ import lombok.EqualsAndHashCode;
+ import org.sky.core.tool.node.INode;
+ import org.sky.scientific.pojo.entity.Subject;
+
+ import java.io.Serial;
+ import java.util.ArrayList;
+ import java.util.List;
+
+ /**
+  * 视图实体类
+  *
+   */
+ @Data
+ @EqualsAndHashCode(callSuper = true)
+ @Schema(description = "Subject对象")
+ public class SubjectVO extends Subject implements INode<SubjectVO> {
+     @Serial
+     private static final long serialVersionUID = 1L;
+
+	 @JsonInclude(JsonInclude.Include.NON_EMPTY)
+	 private Boolean hasChildren;
+
+     @JsonInclude(JsonInclude.Include.NON_EMPTY)
+     private List<SubjectVO> children;
+
+     @Override
+     public List<SubjectVO> getChildren() {
+         if (this.children == null) {
+             this.children = new ArrayList<>();
+         }
+         return this.children;
+     }
+//
+//     private String parentName;
+
+	 @Schema(description = "上级科目列表")
+	 private List<SubjectVO> parentSubjects = new ArrayList<>();
+ }

+ 46 - 1
kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/AssetController.java

@@ -130,13 +130,35 @@ public class AssetController extends KdController {
 		return R.data(pages);
 	}
 
-	@GetMapping("/xm/fetchData")
+	@PostMapping("/keyanyiqishebeimingxibiao/save")
 	@ApiOperationSupport(order = 21)
+	@Operation(summary = "科研仪器设备明细表-新增")
+	public R saveKeyanyiqishebeimingxibiao(@Valid @RequestBody XmAssetEntity xmAsset) {
+		return R.status(xmAssetService.saveXmFixedAsset(xmAsset, "仪器设备"));
+	}
+
+	@PostMapping("/keyanyiqishebeimingxibiao/import")
+	@ApiOperationSupport(order = 21)
+	@Operation(summary = "科研仪器设备明细表-导入")
+	public R importKeyanyiqishebeimingxibiao(MultipartFile file,String yearAndMonth) {
+		xmAssetService.xmFixAssetImport(file, yearAndMonth, "仪器设备");
+		return R.success("操作成功");
+	}
+
+	@GetMapping("/keyanyiqishebeimingxibiao/fetchData")
+	@ApiOperationSupport(order = 22)
 	@Operation(summary = "科研仪器设备明细表-直接引用")
 	public R<Boolean> fetchYiqishebeiData(String yearAndMonth) {
 		return R.status(xmAssetService.xmFixAsset_zhijieyinyong(yearAndMonth, "仪器设备"));
 	}
 
+	@PostMapping("/keyanyiqishebeimingxibiao/remove")
+	@ApiOperationSupport(order = 24)
+	@Operation(summary = "科研仪器设备明细表-删除", description  = "传入ids")
+	public R removeKeyanyiqishebeimingxibiao(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(xmAssetService.physicalDeleteByIds(Func.toLongList(ids)));
+	}
+
 	@PostMapping("/hours/import")
 	@ApiOperationSupport(order = 30)
 	@Operation(summary = "科研仪器设备工时登记表-导入", description = "传入excel")
@@ -179,4 +201,27 @@ public class AssetController extends KdController {
 	public R<Boolean> fetchFangwujianzhuwuData(String yearAndMonth) {
 		return R.status(xmAssetService.xmFixAsset_zhijieyinyong(yearAndMonth, "房屋建筑物"));
 	}
+
+	@PostMapping("/fangwujianzhuwu/save")
+	@ApiOperationSupport(order = 42)
+	@Operation(summary = "科研房屋建筑物明细表-新增")
+	public R saveFangwujianzhuwu(@Valid @RequestBody XmAssetEntity xmAsset) {
+		return R.status(xmAssetService.saveXmFixedAsset(xmAsset, "房屋建筑物"));
+	}
+
+	@PostMapping("/fangwujianzhuwu/import")
+	@ApiOperationSupport(order = 43)
+	@Operation(summary = "科研房屋建筑物明细表-导入")
+	public R importFangwujianzhuwu(MultipartFile file,String yearAndMonth) {
+		xmAssetService.xmFixAssetImport(file, yearAndMonth, "房屋建筑物");
+		return R.success("操作成功");
+	}
+
+	@PostMapping("/fangwujianzhuwu/remove")
+	@ApiOperationSupport(order = 44)
+	@Operation(summary = "科研房屋建筑物明细表-删除", description  = "传入ids")
+	public R removeFangwujianzhuwu(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(xmAssetService.physicalDeleteByIds(Func.toLongList(ids)));
+	}
+
 }

+ 40 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/SubjectController.java

@@ -0,0 +1,40 @@
+package org.sky.scientific.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.sky.core.boot.ctrl.KdController;
+import org.sky.core.tenant.annotation.NonDS;
+import org.sky.core.tool.api.R;
+import org.sky.scientific.pojo.entity.Subject;
+import org.sky.scientific.pojo.vo.SubjectVO;
+import org.sky.scientific.service.ISubjectService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * 控制器
+ *
+ */
+@NonDS
+@RestController
+@AllArgsConstructor
+@RequestMapping("/subject")
+@Tag(name = "研发费用会计科目设置")
+public class SubjectController extends KdController {
+
+	private final ISubjectService service;
+
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 1)
+	@Operation(summary = "列表")
+	public R<List<SubjectVO>> list(Subject subject) {
+		List<SubjectVO> list = service.allSubject(subject);
+		return R.data(list);
+	}
+}

+ 73 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/excel/XmFixedAssetExcel.java

@@ -0,0 +1,73 @@
+
+package org.sky.scientific.excel;
+
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.sky.core.tool.utils.DateUtil;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+ * 项目固定资产表 Excel实体类
+ *
+ * @author Kd
+ * @since 2025-06-29
+ */
+@Data
+public class XmFixedAssetExcel implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	@ExcelProperty("序号")
+	private Integer xh;
+
+	@ExcelProperty("研发项目名称")
+	private String xmmc;
+
+	@ExcelProperty("研发项目编号")
+	private String xmbh;
+
+ 	@ExcelProperty("资产编码")
+	private String zcbm;
+
+ 	@ExcelProperty("资产名称")
+	private String zcmc;
+
+ 	@ExcelProperty("功率")
+	private String gl;
+
+ 	@ExcelProperty("资产类别")
+	private String zclb;
+
+ 	@ExcelProperty("用途")
+	private String yt;
+
+ 	@ExcelProperty("折旧开始日期")
+	@DateTimeFormat(pattern = DateUtil.PATTERN_DATE)
+	@JsonFormat(pattern = DateUtil.PATTERN_DATE)
+	private Date kssj;
+
+ 	@ExcelProperty("使用寿命")
+	private Integer sysm;
+
+ 	@ExcelProperty("已使用月数")
+	private Integer ysysm;
+
+ 	@ExcelProperty("资产原值")
+	private Integer zcyz;
+
+ 	@ExcelProperty("净残值")
+	private Double jcz;
+
+ 	@ExcelProperty("月折旧额(每台/套)")
+	private BigDecimal yzje;
+
+}

+ 1 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AssetMapper.java

@@ -41,6 +41,7 @@ public interface AssetMapper extends BaseMapper<AssetEntity> {
 
 	List<AssetEntity> selectAssetList();
 
+	AssetEntity selectByYearAndMonthAndBmOrMc(@Param("yearAndMonth") String yearAndMonth, @Param("zcbm") String zcbm, @Param("zcmc") String zcmc);
 	/**
 	 * 批量删除
 	 * @param ids

+ 11 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AssetMapper.xml

@@ -75,4 +75,15 @@
         SELECT * FROM kd_asset ${ew.customSqlSegment}
     </select>
 
+    <select id="selectByYearAndMonthAndBmOrMc" resultMap="ResultMap">
+        SELECT * FROM kd_asset
+        WHERE year_and_month = #{yearAndMonth}
+        <if test="zcbm != null and zcbm != ''">
+            and ZCBM = #{zcbm}
+        </if>
+        <if test="zcmc != null and zcmc != ''">
+            and ZCMC = #{zcmc}
+        </if>
+    </select>
+
 </mapper>

+ 160 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/SubjectMapper.java

@@ -0,0 +1,160 @@
+package org.sky.scientific.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.sky.scientific.pojo.entity.Subject;
+
+
+/**
+ * SubjectMapper 接口
+ *
+ */
+public interface SubjectMapper extends BaseMapper<Subject> {
+
+//	/**
+//	 * 懒加载列表
+//	 *
+//	 * @param parentId
+//	 * @param param
+//	 * @return
+//	 */
+//	List<SubjectVO> lazyList(Long parentId, Map<String, Object> param);
+//
+//	/**
+//	 * 懒加载菜单列表
+//	 *
+//	 * @param parentId
+//	 * @param param
+//	 * @return
+//	 */
+//	List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param);
+//
+//	/**
+//	 * 树形结构
+//	 *
+//	 * @return
+//	 */
+//	List<TreeNode> tree();
+//
+//	/**
+//	 * 授权树形结构
+//	 *
+//	 * @return
+//	 */
+//	List<TreeNode> grantTree();
+//
+//	/**
+//	 * 授权树形结构
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<TreeNode> grantTreeByRole(List<Long> roleId);
+//
+//	/**
+//	 * 顶部菜单树形结构
+//	 *
+//	 * @return
+//	 */
+//	List<TreeNode> grantTopTree();
+//
+//	/**
+//	 * 顶部菜单树形结构
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<TreeNode> grantTopTreeByRole(List<Long> roleId);
+//
+//	/**
+//	 * 数据权限授权树形结构
+//	 *
+//	 * @return
+//	 */
+//	List<TreeNode> grantDataScopeTree();
+//
+//	/**
+//	 * 接口权限授权树形结构
+//	 *
+//	 * @return
+//	 */
+//	List<TreeNode> grantApiScopeTree();
+//
+//	/**
+//	 * 数据权限授权树形结构
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<TreeNode> grantDataScopeTreeByRole(List<Long> roleId);
+//
+//	/**
+//	 * 接口权限授权树形结构
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<TreeNode> grantApiScopeTreeByRole(List<Long> roleId);
+//
+//	/**
+//	 * 所有菜单
+//	 *
+//	 * @return
+//	 */
+//	List<Menu> allMenu();
+//
+//	/**
+//	 * 权限配置菜单
+//	 *
+//	 * @param roleId
+//	 * @param topMenuId
+//	 * @return
+//	 */
+//	List<Menu> roleMenu(List<Long> roleId, Long topMenuId);
+//
+//	/**
+//	 * 权限配置菜单
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<Menu> roleMenuByRoleId(List<Long> roleId);
+//
+//	/**
+//	 * 权限配置菜单
+//	 *
+//	 * @param topMenuId
+//	 * @return
+//	 */
+//	List<Menu> roleMenuByTopMenuId(Long topMenuId);
+//
+//	/**
+//	 * 菜单树形结构
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<Menu> routes(List<Long> roleId);
+//
+//	/**
+//	 * 按钮树形结构
+//	 *
+//	 * @return
+//	 */
+//	List<Menu> allButtons();
+//
+//	/**
+//	 * 按钮树形结构
+//	 *
+//	 * @param roleId
+//	 * @return
+//	 */
+//	List<Menu> buttons(List<Long> roleId);
+//
+//	/**
+//	 * 获取配置的角色权限
+//	 *
+//	 * @param roleIds
+//	 * @return
+//	 */
+//	List<MenuDTO> authRoutes(List<Long> roleIds);
+}

+ 455 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/SubjectMapper.xml

@@ -0,0 +1,455 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.sky.scientific.mapper.SubjectMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="ResultMap" type="org.sky.scientific.pojo.entity.Subject">
+        <id column="id" property="id"/>
+        <result column="parent_id" property="parentId"/>
+        <result column="code" property="code"/>
+        <result column="name" property="name"/>
+        <result column="accSubject" property="accSubject"/>
+        <result column="rdSubject" property="rdSubject"/>
+        <result column="adSubject" property="adSubject"/>
+    </resultMap>
+
+    <resultMap id="treeNodeResultMap" type="org.sky.core.tool.node.TreeNode">
+        <id column="id" property="id"/>
+        <result column="parent_id" property="parentId"/>
+        <result column="title" property="title"/>
+        <result column="value" property="value"/>
+        <result column="key" property="key"/>
+    </resultMap>
+
+<!--    <select id="lazyList"  resultMap="menuVOResultMap">-->
+<!--        SELECT-->
+<!--            menu.*,-->
+<!--            (-->
+<!--                SELECT-->
+<!--                    CASE WHEN count( 1 ) > 0 THEN 1 ELSE 0 END-->
+<!--            FROM-->
+<!--                kd_menu-->
+<!--            WHERE-->
+<!--                parent_id = menu.id AND is_deleted = 0-->
+<!--        ) AS "has_children"-->
+<!--        FROM-->
+<!--            kd_menu menu-->
+<!--        WHERE menu.is_deleted = 0-->
+<!--        <if test="param1!=null">-->
+<!--            and menu.parent_id = #{param1}-->
+<!--        </if>-->
+<!--        <if test="param2.name!=null and param2.name!=''">-->
+<!--            and menu.name like concat(concat('%', #{param2.name}),'%')-->
+<!--        </if>-->
+<!--        <if test="param2.code!=null and param2.code!=''">-->
+<!--            and menu.code like concat(concat('%', #{param2.code}),'%')-->
+<!--        </if>-->
+<!--        <if test="param2.alias!=null and param2.alias!=''">-->
+<!--            and menu.alias like concat(concat('%', #{param2.alias}),'%')-->
+<!--        </if>-->
+<!--        ORDER BY menu.sort-->
+<!--    </select>-->
+
+<!--    <select id="lazyMenuList" resultMap="menuVOResultMap">-->
+<!--        SELECT-->
+<!--            menu.*,-->
+<!--            (-->
+<!--                SELECT-->
+<!--                    CASE WHEN count( 1 ) > 0 THEN 1 ELSE 0 END-->
+<!--        FROM-->
+<!--                kd_menu-->
+<!--        WHERE-->
+<!--        parent_id = menu.id AND is_deleted = 0  AND category = 1-->
+<!--        ) AS "has_children"-->
+<!--        FROM-->
+<!--            kd_menu menu-->
+<!--        WHERE menu.is_deleted = 0 AND menu.category = 1-->
+<!--        <if test="param1!=null">-->
+<!--            and menu.parent_id = #{param1}-->
+<!--        </if>-->
+<!--        <if test="param2.name!=null and param2.name!=''">-->
+<!--            and menu.name like concat(concat('%', #{param2.name}),'%')-->
+<!--        </if>-->
+<!--        <if test="param2.code!=null and param2.code!=''">-->
+<!--            and menu.code like concat(concat('%', #{param2.code}),'%')-->
+<!--        </if>-->
+<!--        <if test="param2.alias!=null and param2.alias!=''">-->
+<!--            and menu.alias like concat(concat('%', #{param2.alias}),'%')-->
+<!--        </if>-->
+<!--        ORDER BY menu.sort-->
+<!--    </select>-->
+
+<!--    <select id="tree" resultMap="treeNodeResultMap">-->
+<!--        select id, parent_id, name as title, id as "value", id as "key" from kd_menu where is_deleted = 0 and category = 1-->
+<!--    </select>-->
+
+<!--    <select id="allMenu" resultMap="menuResultMap">-->
+<!--        select * from kd_menu where is_deleted = 0 and category = 1-->
+<!--    </select>-->
+
+<!--    <select id="roleMenu" resultMap="menuResultMap">-->
+<!--        select * from kd_menu where is_deleted = 0 and id IN-->
+<!--        ( SELECT menu_id FROM kd_role_menu WHERE role_id IN-->
+<!--        <foreach collection="param1" index="index" item="item" open="(" separator="," close=")">-->
+<!--            #{item}-->
+<!--        </foreach>-->
+<!--        )-->
+<!--        <if test="param2!=null and param2>0">-->
+<!--            AND id IN-->
+<!--            (-->
+<!--            SELECT menu_id FROM kd_top_menu_setting WHERE top_menu_id = #{param2}-->
+<!--            )-->
+<!--        </if>-->
+<!--    </select>-->
+
+<!--    <select id="roleMenuByRoleId" resultMap="menuResultMap">-->
+<!--        select * from kd_menu where is_deleted = 0 and id IN-->
+<!--            ( SELECT menu_id FROM kd_role_menu WHERE role_id IN-->
+<!--                <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                    #{item}-->
+<!--                </foreach>-->
+<!--            )-->
+<!--    </select>-->
+
+<!--    <select id="roleMenuByTopMenuId" resultMap="menuResultMap">-->
+<!--        select * from kd_menu where is_deleted = 0 and id IN-->
+<!--              (-->
+<!--                  SELECT menu_id FROM kd_top_menu_setting WHERE top_menu_id = #{param1}-->
+<!--              )-->
+<!--    </select>-->
+
+<!--    <select id="routes" resultMap="menuResultMap">-->
+<!--        SELECT-->
+<!--            *-->
+<!--        FROM-->
+<!--            kd_menu-->
+<!--        WHERE-->
+<!--            is_deleted = 0 and category = 1-->
+<!--            and id IN ( SELECT menu_id FROM kd_role_menu WHERE role_id IN-->
+<!--                        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                            #{item}-->
+<!--                        </foreach> )-->
+<!--    </select>-->
+
+<!--    <select id="allButtons" resultMap="menuResultMap">-->
+<!--        SELECT-->
+<!--            id,-->
+<!--            parent_id,-->
+<!--            CODE,-->
+<!--            NAME,-->
+<!--            alias,-->
+<!--            path,-->
+<!--            source,-->
+<!--            action,-->
+<!--            sort-->
+<!--        FROM-->
+<!--            kd_menu-->
+<!--        WHERE-->
+<!--            (-->
+<!--                category = 2 OR id IN ( SELECT parent_id FROM kd_menu WHERE is_deleted = 0 AND category = 2 )-->
+<!--            )-->
+<!--          AND is_deleted = 0-->
+<!--        ORDER BY sort-->
+<!--    </select>-->
+
+<!--    <select id="buttons" resultMap="menuResultMap">-->
+<!--        SELECT * FROM (-->
+<!--            SELECT-->
+<!--                id,-->
+<!--                parent_id,-->
+<!--                code,-->
+<!--                name,-->
+<!--                alias,-->
+<!--                path,-->
+<!--                source,-->
+<!--                action,-->
+<!--                sort-->
+<!--            FROM-->
+<!--                kd_menu-->
+<!--            WHERE-->
+<!--                is_deleted = 0 and id IN (-->
+<!--                  SELECT parent_id FROM kd_menu-->
+<!--                  WHERE ( category = 2 AND id IN ( SELECT menu_id FROM kd_role_menu WHERE role_id IN-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach>-->
+<!--                  ) ) )-->
+
+<!--            UNION ALL-->
+
+<!--            SELECT-->
+<!--                id,-->
+<!--                parent_id,-->
+<!--                code,-->
+<!--                name,-->
+<!--                alias,-->
+<!--                path,-->
+<!--                source,-->
+<!--                action,-->
+<!--                sort-->
+<!--            FROM-->
+<!--                kd_menu-->
+<!--            WHERE-->
+<!--                is_deleted = 0 and  category = 2 AND id IN ( SELECT menu_id FROM kd_role_menu WHERE role_id IN-->
+<!--                <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                    #{item}-->
+<!--                </foreach>)-->
+<!--        ) menu ORDER BY sort-->
+<!--    </select>-->
+
+<!--    <select id="grantTree" resultMap="treeNodeResultMap">-->
+<!--        select id, parent_id, name as title, id as "value", id as "key" from kd_menu where is_deleted = 0 order by sort-->
+<!--    </select>-->
+
+<!--    <select id="grantTreeByRole" resultMap="treeNodeResultMap">-->
+<!--        select id, parent_id, name as title, id as "value", id as "key" from kd_menu where is_deleted = 0-->
+<!--        and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--            #{item}-->
+<!--        </foreach> )-->
+<!--        or id in (-->
+<!--            select parent_id from kd_menu where is_deleted = 0-->
+<!--            and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                #{item}-->
+<!--            </foreach> )-->
+<!--          )-->
+<!--        order by sort-->
+<!--    </select>-->
+
+<!--    <select id="grantTopTree" resultMap="treeNodeResultMap">-->
+<!--        select id, parent_id, name as title, id as "value", id as "key" from kd_menu where category = 1 and is_deleted = 0 order by sort-->
+<!--    </select>-->
+
+<!--    <select id="grantTopTreeByRole" resultMap="treeNodeResultMap">-->
+<!--        select id, parent_id, name as title, id as "value", id as "key" from kd_menu where category = 1 and is_deleted = 0-->
+<!--        and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--            #{item}-->
+<!--        </foreach> )-->
+<!--        or id in (-->
+<!--        select parent_id from kd_menu where is_deleted = 0-->
+<!--        and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--            #{item}-->
+<!--        </foreach> )-->
+<!--        )-->
+<!--        order by sort-->
+<!--    </select>-->
+
+<!--    <select id="grantDataScopeTree" resultMap="treeNodeResultMap">-->
+<!--        SELECT-->
+<!--            *-->
+<!--        FROM-->
+<!--            (-->
+<!--                SELECT-->
+<!--                    id,-->
+<!--                    parent_id,-->
+<!--                    NAME AS title,-->
+<!--                    id AS "value",-->
+<!--                    id AS "key"-->
+<!--                FROM-->
+<!--                    kd_menu-->
+<!--                WHERE-->
+<!--                    category = 1-->
+<!--                  AND is_deleted = 0-->
+<!--                  AND id IN ( SELECT menu_id FROM kd_scope_data WHERE is_deleted = 0 AND menu_id IS NOT NULL )-->
+<!--            ) menu-->
+
+<!--        UNION ALL-->
+
+<!--        SELECT-->
+<!--            id,-->
+<!--            menu_id AS parent_id,-->
+<!--            scope_name AS title,-->
+<!--            id AS "value",-->
+<!--            id AS "key"-->
+<!--        FROM-->
+<!--            kd_scope_data-->
+<!--        WHERE-->
+<!--            is_deleted = 0-->
+<!--          AND menu_id IS NOT NULL-->
+<!--    </select>-->
+
+<!--    <select id="grantApiScopeTree" resultMap="treeNodeResultMap">-->
+<!--        SELECT-->
+<!--            *-->
+<!--        FROM-->
+<!--            (-->
+<!--                SELECT-->
+<!--                    id,-->
+<!--                    parent_id,-->
+<!--                    NAME AS title,-->
+<!--                    id AS "value",-->
+<!--                    id AS "key"-->
+<!--                FROM-->
+<!--                    kd_menu-->
+<!--                WHERE-->
+<!--                    category = 1-->
+<!--                  AND is_deleted = 0-->
+<!--                  AND id IN ( SELECT menu_id FROM kd_scope_api WHERE is_deleted = 0 AND menu_id IS NOT NULL )-->
+<!--            ) menu-->
+
+<!--        UNION ALL-->
+
+<!--        SELECT-->
+<!--            id,-->
+<!--            menu_id AS parent_id,-->
+<!--            scope_name AS title,-->
+<!--            id AS "value",-->
+<!--            id AS "key"-->
+<!--        FROM-->
+<!--            kd_scope_api-->
+<!--        WHERE-->
+<!--            is_deleted = 0-->
+<!--          AND menu_id IS NOT NULL-->
+<!--    </select>-->
+
+<!--    <select id="grantDataScopeTreeByRole" resultMap="treeNodeResultMap">-->
+<!--        SELECT-->
+<!--        *-->
+<!--        FROM-->
+<!--        (-->
+<!--            SELECT-->
+<!--                id,-->
+<!--                parent_id,-->
+<!--                NAME AS title,-->
+<!--                id AS "value",-->
+<!--                id AS "key"-->
+<!--            FROM-->
+<!--                kd_menu-->
+<!--            WHERE-->
+<!--                category = 1-->
+<!--            AND is_deleted = 0-->
+<!--            AND id IN ( SELECT menu_id FROM kd_scope_data WHERE is_deleted = 0 AND menu_id IS NOT NULL )-->
+<!--            AND (-->
+<!--                id IN (-->
+<!--                    select menu_id from kd_role_menu where role_id in-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach>-->
+<!--                )-->
+<!--                OR id IN (-->
+<!--                    select parent_id from kd_menu where is_deleted = 0-->
+<!--                    and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach> )-->
+<!--                )-->
+<!--            )-->
+<!--        ) menu-->
+
+<!--        UNION ALL-->
+
+<!--        SELECT-->
+<!--            id,-->
+<!--            menu_id AS parent_id,-->
+<!--            scope_name AS title,-->
+<!--            id AS "value",-->
+<!--            id AS "key"-->
+<!--        FROM-->
+<!--            kd_scope_data-->
+<!--        WHERE-->
+<!--            is_deleted = 0-->
+<!--        AND (-->
+<!--            menu_id IN (-->
+<!--                select menu_id from kd_role_menu where role_id in-->
+<!--                <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                    #{item}-->
+<!--                </foreach>-->
+<!--            )-->
+<!--            OR menu_id IN (-->
+<!--                select parent_id from kd_menu where is_deleted = 0-->
+<!--                and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--                <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                    #{item}-->
+<!--                </foreach> )-->
+<!--            )-->
+<!--        )-->
+<!--        AND menu_id IS NOT NULL-->
+<!--    </select>-->
+
+<!--    <select id="grantApiScopeTreeByRole" resultMap="treeNodeResultMap">-->
+<!--        SELECT-->
+<!--        *-->
+<!--        FROM-->
+<!--        (-->
+<!--            SELECT-->
+<!--                id,-->
+<!--                parent_id,-->
+<!--                NAME AS title,-->
+<!--                id AS "value",-->
+<!--                id AS "key"-->
+<!--            FROM-->
+<!--                kd_menu-->
+<!--            WHERE-->
+<!--                category = 1-->
+<!--            AND is_deleted = 0-->
+<!--            AND id IN ( SELECT menu_id FROM kd_scope_api WHERE is_deleted = 0 AND menu_id IS NOT NULL )-->
+<!--            AND (-->
+<!--                id IN (-->
+<!--                    select menu_id from kd_role_menu where role_id in-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach>-->
+<!--                )-->
+<!--                OR id IN (-->
+<!--                    select parent_id from kd_menu where is_deleted = 0-->
+<!--                    and id in (-->
+<!--                        select menu_id from kd_role_menu where role_id in-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach> )-->
+<!--                )-->
+<!--            )-->
+<!--        ) menu-->
+
+<!--        UNION ALL-->
+
+<!--        SELECT-->
+<!--            id,-->
+<!--            menu_id AS parent_id,-->
+<!--            scope_name AS title,-->
+<!--            id AS "value",-->
+<!--            id AS "key"-->
+<!--        FROM-->
+<!--            kd_scope_api-->
+<!--        WHERE-->
+<!--            is_deleted = 0-->
+<!--        AND-->
+<!--            (-->
+<!--                menu_id IN (-->
+<!--                    select menu_id from kd_role_menu where role_id in-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach>-->
+<!--                )-->
+<!--            OR menu_id IN (-->
+<!--                    select parent_id from kd_menu where is_deleted = 0-->
+<!--                    and id in ( select menu_id from kd_role_menu where role_id in-->
+<!--                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                        #{item}-->
+<!--                    </foreach> )-->
+<!--                )-->
+<!--        )-->
+<!--        AND menu_id IS NOT NULL-->
+<!--    </select>-->
+
+<!--    <select id="authRoutes" resultType="org.sky.system.pojo.dto.MenuDTO">-->
+<!--        SELECT-->
+<!--            GROUP_CONCAT(r.role_alias) as alias,-->
+<!--            m.path-->
+<!--        FROM-->
+<!--            kd_role_menu rm-->
+<!--            LEFT JOIN kd_menu m ON rm.menu_id = m.id-->
+<!--            LEFT JOIN kd_role r ON rm.role_id = r.id-->
+<!--        WHERE-->
+<!--            rm.role_id IN-->
+<!--            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">-->
+<!--                #{item}-->
+<!--            </foreach>-->
+<!--            AND m.path IS NOT NULL and m.is_deleted = 0-->
+<!--        GROUP BY m.path-->
+<!--    </select>-->
+
+</mapper>

+ 1 - 1
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmAssetHoursMapper.xml

@@ -37,7 +37,7 @@
     <select id="selectXmAssetHoursPage" resultMap="ResultVoMap">
         SELECT xa.xm_id,xm.xmbh,xm.xmmc,xa.asset_id,asset.zcbm,asset.zcmc,asset.zclb,asset.yt,
                (select sum(work_hours) from kd_xm_asset_hours h where h.xm_id = xa.xm_id and h.asset_id = xa.asset_id) as monthly_hours
-        FROM kd_xm_asset xa
+        FROM kd_xm_fixed_asset xa
         LEFT JOIN kd_asset asset ON xa.asset_id = asset.id
         LEFT JOIN
         (

+ 2 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmAssetMapper.java

@@ -27,4 +27,6 @@ public interface XmAssetMapper extends BaseMapper<XmAssetEntity> {
 	List<XmAssetEntity> selectXmFixedAssetPageByYearAndMonth(IPage<XmAssetEntity> page, @Param("ew") XmAssetQueryParam xmAsset, @Param("zclb") String zclb);
 
 	List<XmAssetEntity> selectXmFixedAssetPageByYear(IPage<XmAssetEntity> page, @Param("ew")XmAssetQueryParam xmAsset, @Param("zclb") String zclb);
+
+	boolean physicalDeleteByIds(List<Long> ids);
 }

+ 12 - 4
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmAssetMapper.xml

@@ -8,6 +8,7 @@
         <result column="year_and_month" property="yearAndMonth"/>
         <result column="xm_id" property="xmId"/>
         <result column="asset_id" property="assetId"/>
+        <result column="zcbm" property="zcbm"/>
         <result column="create_user" property="createUser"/>
         <result column="create_dept" property="createDept"/>
         <result column="create_time" property="createTime"/>
@@ -19,8 +20,8 @@
 
     <select id="selectXmFixedAssetByYearAndMonth"
             resultMap="ResultMap">
-        SELECT xa.*
-        FROM kd_xm_asset xa
+        SELECT xa.*,asset.zcbm
+        FROM kd_xm_fixed_asset xa
         inner JOIN kd_asset asset ON xa.asset_id = asset.id
         LEFT JOIN
         (
@@ -38,7 +39,7 @@
     <select id="selectXmFixedAssetPageByYearAndMonth" resultMap="ResultMap">
         SELECT xa.*,xm.xmmc, xm.xmbh,
         <include refid="org.sky.scientific.mapper.AssetMapper.basicColumns"/>
-        FROM kd_xm_asset xa
+        FROM kd_xm_fixed_asset xa
         LEFT JOIN kd_asset asset ON xa.asset_id = asset.id
         LEFT JOIN
         (
@@ -66,7 +67,7 @@
 
     <select id="selectXmFixedAssetPageByYear" resultMap="ResultMap">
         SELECT xa.xm_id, xa.asset_id, <include refid="org.sky.scientific.mapper.AssetMapper.basicColumns"/>
-        FROM kd_xm_asset xa
+        FROM kd_xm_fixed_asset xa
         LEFT JOIN kd_asset asset ON xa.asset_id = asset.id
         LEFT JOIN
         (
@@ -81,4 +82,11 @@
         GROUP BY asset.ZCBM
     </select>
 
+    <delete id="physicalDeleteByIds">
+        DELETE FROM kd_xm_fixed_asset
+        WHERE id IN
+        <foreach item="item" index="index" collection="list" separator="," open="(" close=")">
+            #{item}
+        </foreach>
+    </delete>
 </mapper>

+ 1 - 1
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/YsZjfyycqdtfyMapper.xml

@@ -50,7 +50,7 @@
     </select>
 
     <select id="selectByYearAndMonth" resultMap="ResultMap">
-        SELECT xa.*, s.YZJE
+        SELECT xa.*, s.YZJE,s.zcbm
         FROM kd_ys_zjfyycqdtfy xa
         inner join kd_asset s on s.id = xa.asset_id
         INNER JOIN

+ 16 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/ISubjectService.java

@@ -0,0 +1,16 @@
+ package org.sky.scientific.service;
+
+ import com.baomidou.mybatisplus.extension.service.IService;
+ import org.sky.scientific.pojo.entity.Subject;
+ import org.sky.scientific.pojo.vo.SubjectVO;
+
+ import java.util.List;
+
+ /**
+  * 服务类
+  *
+  */
+ public interface ISubjectService extends IService<Subject> {
+
+	 List<SubjectVO> allSubject(Subject subject);
+ }

+ 15 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IXmAssetService.java

@@ -5,6 +5,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.sky.core.mp.base.BaseService;
 import org.sky.scientific.pojo.dto.XmAssetQueryParam;
 import org.sky.scientific.pojo.entity.XmAssetEntity;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
 
 /**
  * 研发项目固定资产表 服务类
@@ -28,4 +31,16 @@ public interface IXmAssetService extends BaseService<XmAssetEntity> {
 	 * @return
 	 */
 	boolean xmFixAsset_zhijieyinyong(String yearAndMonth, String zclb);
+
+	/**
+	 * 科研仪器设备明细表-导入
+	 * @param file
+	 * @param yearAndMonth
+	 * @param zclb
+	 */
+	void xmFixAssetImport(MultipartFile file, String yearAndMonth, String zclb);
+
+	boolean physicalDeleteByIds(List<Long> ids);
+
+	boolean saveXmFixedAsset(XmAssetEntity xmAsset, String zclb);
 }

+ 67 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/SubjectServiceImpl.java

@@ -0,0 +1,67 @@
+package org.sky.scientific.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.AllArgsConstructor;
+import org.sky.core.tool.utils.BeanUtil;
+import org.sky.scientific.mapper.SubjectMapper;
+import org.sky.scientific.pojo.entity.Subject;
+import org.sky.scientific.pojo.vo.SubjectVO;
+import org.sky.scientific.service.ISubjectService;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 服务实现类
+ */
+@Service
+@AllArgsConstructor
+public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements ISubjectService {
+
+	private final static String PARENT_ID = "parentId";
+
+	@Override
+	public List<SubjectVO> allSubject(Subject subject) {
+		List<Subject> allSubject = baseMapper.selectList(Wrappers.emptyWrapper());
+		List<SubjectVO> list = allSubject.stream().map(menu -> BeanUtil.copyProperties(menu, SubjectVO.class)).toList();
+
+		Map<Long, SubjectVO> subjectMap = new HashMap<>();
+
+		// First pass: create a map for quick lookup
+		for (SubjectVO sub : list) {
+			subjectMap.put(sub.getId(), sub);
+		}
+
+		// Second pass: build parent subjects list for each subject
+		for (SubjectVO sub : list) {
+			buildParentSubjects(sub, subjectMap);
+		}
+
+ 		return list;
+	}
+
+	private void buildParentSubjects(SubjectVO subject, Map<Long, SubjectVO> subjectMap) {
+		List<SubjectVO> parentSubjects = new ArrayList<>();
+		Long currentParentId = subject.getParentId();
+
+		while (currentParentId != null && currentParentId != 0) {
+			Subject parent = subjectMap.get(currentParentId);
+			if (parent == null) break;
+
+			// Create a simplified parent object with only id, code, and name
+			SubjectVO parentCopy = new SubjectVO();
+			parentCopy.setId(parent.getId());
+			parentCopy.setCode(parent.getCode());
+			parentCopy.setName(parent.getName());
+
+			parentSubjects.add(0, parentCopy); // Add to beginning to maintain order
+			currentParentId = parent.getParentId();
+		}
+
+		subject.setParentSubjects(parentSubjects);
+	}
+}

+ 119 - 11
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/XmAssetServiceImpl.java

@@ -4,22 +4,26 @@ package org.sky.scientific.service.impl;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.sky.core.excel.util.ExcelUtil;
 import org.sky.core.log.exception.ServiceException;
 import org.sky.core.mp.base.BaseServiceImpl;
 import org.sky.core.tool.utils.CollectionUtil;
 import org.sky.core.tool.utils.DateUtil;
 import org.sky.core.tool.utils.StringUtil;
+import org.sky.scientific.excel.XmFixedAssetExcel;
+import org.sky.scientific.mapper.AssetMapper;
 import org.sky.scientific.mapper.XmAssetMapper;
+import org.sky.scientific.mapper.XmMapper;
 import org.sky.scientific.mapper.YsZjfyycqdtfyMapper;
 import org.sky.scientific.pojo.dto.XmAssetQueryParam;
+import org.sky.scientific.pojo.entity.AssetEntity;
 import org.sky.scientific.pojo.entity.XmAssetEntity;
 import org.sky.scientific.pojo.entity.YsZjfyycqdtfyEntity;
 import org.sky.scientific.service.IXmAssetService;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 /**
  * 研发项目固定资产表 服务实现类
@@ -33,6 +37,10 @@ public class XmAssetServiceImpl extends BaseServiceImpl<XmAssetMapper, XmAssetEn
 
 	@Resource
 	private YsZjfyycqdtfyMapper ysZjfyycqdtfyMapper;
+	@Resource
+	private XmMapper xmMapper;
+	@Resource
+	private AssetMapper assetMapper;
 
 	@Override
 	public IPage<XmAssetEntity> selectXmFixAssetPage(IPage<XmAssetEntity> page, XmAssetQueryParam param, String zclb) {
@@ -59,32 +67,132 @@ public class XmAssetServiceImpl extends BaseServiceImpl<XmAssetMapper, XmAssetEn
 		Date lastDate = DateUtil.minusMonths(DateUtil.parse(yearAndMonth, DateUtil.PATTERN_YYYYMM), 1);
 		//获取上个月数据
 		List<XmAssetEntity> lastMonthList = baseMapper.selectXmFixedAssetByYearAndMonth(DateUtil.format(lastDate, DateUtil.PATTERN_YYYYMM), zclb);
+		//获取本月数据
+		List<XmAssetEntity> thisMonthList = baseMapper.selectXmFixedAssetByYearAndMonth(yearAndMonth, zclb);
+
+		List<String> zcbmList = thisMonthList.stream().map(XmAssetEntity::getZcbm).toList();
 		if (!CollectionUtil.isEmpty(lastMonthList)) {
 			//复制上个月数据到本月
 			List<XmAssetEntity> insertList = new ArrayList<>();
 			for (XmAssetEntity dbAsset : lastMonthList) {
+				//dbAsset已存在,则跳过
+				if (CollectionUtil.isNotEmpty(zcbmList) && zcbmList.contains(dbAsset.getZcbm())) {
+					continue;
+				}
 				XmAssetEntity asset = new XmAssetEntity();
 				asset.setYearAndMonth(yearAndMonth);
 				asset.setXmId(dbAsset.getXmId());
 				asset.setAssetId(dbAsset.getAssetId());
+				asset.setZcbm(dbAsset.getZcbm());
 				insertList.add(asset);
 			}
-			return this.saveBatch(insertList);
+			if (CollectionUtil.isNotEmpty(insertList)) {
+				return this.saveBatch(insertList);
+			}
 		} else {
 			//若无,则获取预算表中的科研仪器设备,研发项目周期(含变更)包含本月的
-			List<YsZjfyycqdtfyEntity> ysZjfyycqdtfyEntities = ysZjfyycqdtfyMapper.selectByYearAndMonth(yearAndMonth, zclb);
-			if (CollectionUtil.isEmpty(ysZjfyycqdtfyEntities)) {
-				throw new ServiceException("未能从项目预算表中读取科研仪器设备");
+			List<YsZjfyycqdtfyEntity> ysList = ysZjfyycqdtfyMapper.selectByYearAndMonth(yearAndMonth, zclb);
+			if (CollectionUtil.isEmpty(ysList)) {
+				throw new ServiceException("项目预算表中无科研仪器设备");
 			}
 			List<XmAssetEntity> insertList = new ArrayList<>();
-			for (YsZjfyycqdtfyEntity ysZjfyycqdtfyEntity : ysZjfyycqdtfyEntities) {
+			for (YsZjfyycqdtfyEntity ys : ysList) {
+				if (CollectionUtil.isNotEmpty(zcbmList) && zcbmList.contains(ys.getZcbm())) {
+					continue;
+				}
 				XmAssetEntity asset = new XmAssetEntity();
 				asset.setYearAndMonth(yearAndMonth);
-				asset.setXmId(ysZjfyycqdtfyEntity.getXmId());
-				asset.setAssetId(ysZjfyycqdtfyEntity.getAssetId());
+				asset.setXmId(ys.getXmId());
+				asset.setAssetId(ys.getAssetId());
+				asset.setZcbm(ys.getZcbm());
 				insertList.add(asset);
 			}
-			return this.saveBatch(insertList);
+			if (CollectionUtil.isNotEmpty(insertList)) {
+				return this.saveBatch(insertList);
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public void xmFixAssetImport(MultipartFile file, String yearAndMonth, String zclb) {
+		if (StringUtil.isBlank(yearAndMonth)) {
+			throw new ServiceException("参数yearAndMonth不能为空");
+		}
+
+		List<XmFixedAssetExcel> data = ExcelUtil.read(file, XmFixedAssetExcel.class);
+		if (CollectionUtil.isEmpty(data)) {
+			throw new ServiceException("导入数据为空");
+		}
+		//获取本月数据
+		List<XmAssetEntity> thisMonthList = baseMapper.selectXmFixedAssetByYearAndMonth(yearAndMonth, zclb);
+		List<String> zcbmList = thisMonthList.stream().map(XmAssetEntity::getZcbm).toList();
+
+		List<XmAssetEntity> insertList = new ArrayList<>();
+		Map<String, Long> xmIdMap = new HashMap<>();
+		Map<String, AssetEntity> assetIdMap = new HashMap<>();
+		for (XmFixedAssetExcel excel : data) {
+			if (CollectionUtil.isNotEmpty(zcbmList) && zcbmList.contains(excel.getZcbm())) {
+				continue;
+			}
+			if (StringUtil.isAllBlank(excel.getXmmc(), excel.getXmbh())) {
+				throw new ServiceException("序号为[" + excel.getXh() + "]的项目研发编号和项目研发名称都为空");
+			}
+			String xmkey = "xm:" + excel.getXmbh() + ":" + excel.getXmmc();
+			Long xmId = xmIdMap.get(xmkey);
+			if(xmId == null){
+				xmId = xmMapper.getXmIdByXmmcOrXmbh(yearAndMonth, excel.getZcmc(), excel.getZcbm());
+				if (xmId == null) {
+					throw new ServiceException("序号为[" + excel.getXh() + "]的项目不存在");
+				}
+			}
+			xmIdMap.put(xmkey, xmId);
+
+			if (StringUtil.isAllBlank(excel.getXmmc(), excel.getXmbh())) {
+				throw new ServiceException("序号为[" + excel.getXh() + "]的资产编码和资产名称都为空");
+			}
+
+			String assetkey = "asset:" + excel.getZcbm() + ":" + excel.getZcmc();
+			AssetEntity dbAsset = assetIdMap.get(assetkey);
+			if(dbAsset == null){
+				dbAsset = assetMapper.selectByYearAndMonthAndBmOrMc(yearAndMonth, excel.getZcbm(), excel.getZcmc());
+				if (dbAsset == null) {
+					throw new ServiceException("序号为[" + excel.getXh() + "]的资产不存在");
+				}
+			}
+			assetIdMap.put(assetkey, dbAsset);
+
+			XmAssetEntity xmAsset = new XmAssetEntity();
+			xmAsset.setYearAndMonth(yearAndMonth);
+			xmAsset.setXmId(xmId);
+			xmAsset.setAssetId(dbAsset.getId());
+			xmAsset.setZcbm(dbAsset.getZcbm());
+			insertList.add(xmAsset);
+		}
+		if (CollectionUtil.isEmpty(insertList)) {
+			throw new ServiceException("数据已存在,导入失败");
+		} else {
+			this.saveBatch(insertList);
+		}
+	}
+
+	@Override
+	public boolean physicalDeleteByIds(List<Long> ids) {
+		return baseMapper.physicalDeleteByIds(ids);
+	}
+
+	@Override
+	public boolean saveXmFixedAsset(XmAssetEntity xmAsset, String zclb) {
+		if (StringUtil.isBlank(xmAsset.getYearAndMonth())) {
+			throw new ServiceException("参数yearAndMonth不能为空");
+		}
+		//获取本月数据
+		List<XmAssetEntity> thisMonthList = baseMapper.selectXmFixedAssetByYearAndMonth(xmAsset.getYearAndMonth(), zclb);
+		List<String> zcbmList = thisMonthList.stream().map(XmAssetEntity::getZcbm).toList();
+
+		if (CollectionUtil.isNotEmpty(zcbmList) && zcbmList.contains(xmAsset.getZcbm())) {
+			throw new ServiceException("资产已配置到项目中");
 		}
+		return this.save(xmAsset);
 	}
 }