huminmin
2026-05-11 bd424ceae9e38a0a50418f71093becd1430cc83b
生产班组
已添加16个文件
988 ■■■■■ 文件已修改
doc/20260511_create_table_production_team.sql 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/dto/ProductionTeamDto.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/vo/ProductionTeamVo.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionTeamController.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionTeamUserRelController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionTeamMapper.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionTeamUserRelMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionTeam.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionTeamUserRel.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionTeamService.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionTeamUserRelService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionTeamServiceImpl.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionTeamUserRelServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-qllx.yml 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionTeamMapper.xml 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionTeamUserRelMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260511_create_table_production_team.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
#生产班组表
drop table if exists production_team;
create table production_team
(
    id          bigint auto_increment primary key,
    team_name   varchar(100) not null comment '班组名称',
    remark      text null comment '备注',
    tenant_id   bigint       not null comment '租户id',
    create_time datetime null comment '创建时间',
    update_time datetime null comment '更新时间',
    index       idx_team_name (team_name),
);
#班组台账与用户关联表
drop table if exists production_team_user_rel;
create table production_team_user_rel
(
    id                 bigint auto_increment primary key,
    production_team_id bigint  not null comment '生产班组id',
    sys_user_id        bigint  not null comment '系统用户id',
    is_leader          tinyint not null default 0 comment '是否为班组长 0否 1是',
    tenant_id          bigint  not null comment '租户id',
    create_time        datetime null comment '创建时间',
    update_time        datetime null comment '更新时间',
    index              idx_production_team_id (production_team_id),
    index              idx_sys_user_id (sys_user_id),
    unique idx_production_team_user (production_team_id, sys_user_id)
);
src/main/java/com/ruoyi/production/bean/dto/ProductionTeamDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.production.bean.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(name = "ProductionTeamDto", description = "生产班组请求参数")
public class ProductionTeamDto {
    @Schema(description = "班组ID")
    private Long id;
    @Schema(description = "班组名称")
    private String teamName;
    @Schema(description = "班组长ID")
    private Long leaderId;
    @Schema(description = "班组成员ID列表")
    private List<Long> memberIds;
    @Schema(description = "备注")
    private String remark;
}
src/main/java/com/ruoyi/production/bean/vo/ProductionTeamVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.ruoyi.production.bean.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Schema(name = "ProductionTeamVo", description = "生产班组响应数据")
public class ProductionTeamVo {
    @Schema(description = "班组ID")
    private Long id;
    @Schema(description = "班组名称")
    private String teamName;
    @Schema(description = "班组长ID")
    private Long leaderId;
    @Schema(description = "班组长姓名")
    private String leaderName;
    @Schema(description = "班组成员列表")
    private List<MemberVo> members;
    @Schema(description = "创建日期")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @Schema(description = "备注")
    private String remark;
    @Data
    @Schema(name = "MemberVo", description = "班组成员信息")
    public static class MemberVo {
        @Schema(description = "用户ID")
        private Long userId;
        @Schema(description = "用户昵称")
        private String nickName;
        @Schema(description = "是否为班组长")
        private Boolean isLeader;
    }
}
src/main/java/com/ruoyi/production/controller/ProductionTeamController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.bean.dto.ProductionTeamDto;
import com.ruoyi.production.bean.vo.ProductionTeamVo;
import com.ruoyi.production.service.ProductionTeamService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * ç”Ÿäº§ç­ç»„控制器
 */
@RestController
@RequestMapping("/production_team")
@Tag(name = "生产班组管理", description = "生产班组增删改查接口")
public class ProductionTeamController {
    private final ProductionTeamService productionTeamService;
    public ProductionTeamController(ProductionTeamService productionTeamService) {
        this.productionTeamService = productionTeamService;
    }
    /**
     * åˆ›å»ºç­ç»„
     */
    @PostMapping
    @Operation(summary = "创建班组", description = "创建生产班组,包含班组长和成员")
    public R createTeam(@Validated @RequestBody ProductionTeamDto dto) {
        boolean success = productionTeamService.createTeam(dto);
        return success ? R.ok("创建成功") : R.fail("创建失败");
    }
    /**
     * æ›´æ–°ç­ç»„
     */
    @PutMapping
    @Operation(summary = "更新班组", description = "更新生产班组信息")
    public R updateTeam(@Validated @RequestBody ProductionTeamDto dto) {
        if (dto.getId() == null) {
            return R.fail("班组ID不能为空");
        }
        boolean success = productionTeamService.updateTeam(dto);
        return success ? R.ok("更新成功") : R.fail("更新失败");
    }
    /**
     * åˆ é™¤ç­ç»„
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除班组", description = "删除生产班组")
    public R deleteTeam(@PathVariable Long id) {
        boolean success = productionTeamService.deleteTeam(id);
        return success ? R.ok("删除成功") : R.fail("删除失败");
    }
    /**
     * æŸ¥è¯¢ç­ç»„详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询班组详情", description = "根据ID查询班组详细信息,包含成员列表")
    public R<ProductionTeamVo> getTeamDetail(@PathVariable Long id) {
        ProductionTeamVo vo = productionTeamService.getTeamDetail(id);
        return vo != null ? R.ok(vo) : R.fail("班组不存在");
    }
    /**
     * æŸ¥è¯¢ç­ç»„列表
     */
    @GetMapping("/list")
    @Operation(summary = "查询班组列表", description = "查询生产班组列表,支持按班组名称搜索")
    public R<List<ProductionTeamVo>> getTeamList(ProductionTeamDto dto) {
        List<ProductionTeamVo> list = productionTeamService.getTeamList(dto);
        return R.ok(list);
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢ç­ç»„列表
     */
    @GetMapping("/listPage")
    @Operation(summary = "分页查询班组列表", description = "分页查询生产班组列表,支持按班组名称搜索")
    public R<IPage<ProductionTeamVo>> listPage(Page<ProductionTeamDto> page, ProductionTeamDto dto) {
        return R.ok(productionTeamService.listPage(page, dto));
    }
}
src/main/java/com/ruoyi/production/controller/ProductionTeamUserRelController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.production.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 *  å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-11 11:15:05
 */
@RestController
@RequestMapping("/productionTeamUserRel")
public class ProductionTeamUserRelController {
}
src/main/java/com/ruoyi/production/mapper/ProductionTeamMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.production.bean.dto.ProductionTeamDto;
import com.ruoyi.production.bean.vo.ProductionTeamVo;
import com.ruoyi.production.pojo.ProductionTeam;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ProductionTeamMapper extends BaseMapper<ProductionTeam> {
    /**
     * æŸ¥è¯¢ç­ç»„详情(包含成员信息)
     */
    ProductionTeamVo selectTeamDetail(@Param("id") Long id);
    /**
     * æŸ¥è¯¢ç­ç»„列表(包含成员信息)
     */
    List<ProductionTeamVo> selectTeamList(@Param("dto") ProductionTeamDto dto);
    /**
     * åˆ†é¡µæŸ¥è¯¢ç­ç»„列表
     */
    IPage<ProductionTeamVo> selectTeamPage(Page<ProductionTeamDto> page, @Param("dto") ProductionTeamDto dto);
    /**
     * æŸ¥è¯¢ç­ç»„成员列表
     */
    List<ProductionTeamVo.MemberVo> selectTeamMembers(@Param("teamId") Long teamId);
}
src/main/java/com/ruoyi/production/mapper/ProductionTeamUserRelMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.production.pojo.ProductionTeamUserRel;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 *  Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-11 11:15:05
 */
@Mapper
public interface ProductionTeamUserRelMapper extends BaseMapper<ProductionTeamUserRel> {
}
src/main/java/com/ruoyi/production/pojo/ProductionTeam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * <p>
 *
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-11 11:15:05
 */
@Getter
@Setter
@ToString
@TableName("production_team")
@ApiModel(value = "ProductionTeam对象", description = "")
public class ProductionTeam implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * ç­ç»„名称
     */
    @ApiModelProperty("班组名称")
    private String teamName;
    /**
     * å¤‡æ³¨
     */
    @ApiModelProperty("备注")
    private String remark;
    /**
     * ç§Ÿæˆ·id
     */
    @ApiModelProperty("租户id")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/production/pojo/ProductionTeamUserRel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * <p>
 *
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-11 11:15:05
 */
@Getter
@Setter
@ToString
@TableName("production_team_user_rel")
@ApiModel(value = "ProductionTeamUserRel对象", description = "")
public class ProductionTeamUserRel implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * ç”Ÿäº§ç­ç»„id
     */
    @ApiModelProperty("生产班组id")
    private Long productionTeamId;
    /**
     * ç³»ç»Ÿç”¨æˆ·id
     */
    @ApiModelProperty("系统用户id")
    private Long sysUserId;
    /**
     * æ˜¯å¦ä¸ºç­ç»„é•¿ 0否 1是
     */
    @ApiModelProperty("是否为班组长 0否 1是")
    private Byte isLeader;
    /**
     * ç§Ÿæˆ·id
     */
    @ApiModelProperty("租户id")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/production/service/ProductionTeamService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.bean.dto.ProductionTeamDto;
import com.ruoyi.production.bean.vo.ProductionTeamVo;
import com.ruoyi.production.pojo.ProductionTeam;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface ProductionTeamService extends IService<ProductionTeam> {
    /**
     * åˆ›å»ºç­ç»„(包含成员关系)
     */
    boolean createTeam(ProductionTeamDto dto);
    /**
     * æ›´æ–°ç­ç»„(包含成员关系)
     */
    boolean updateTeam(ProductionTeamDto dto);
    /**
     * åˆ é™¤ç­ç»„(级联删除成员关系)
     */
    boolean deleteTeam(Long id);
    /**
     * æŸ¥è¯¢ç­ç»„详情
     */
    ProductionTeamVo getTeamDetail(Long id);
    /**
     * æŸ¥è¯¢ç­ç»„列表
     */
    List<ProductionTeamVo> getTeamList(ProductionTeamDto dto);
    /**
     * åˆ†é¡µæŸ¥è¯¢ç­ç»„列表
     */
    IPage<ProductionTeamVo> listPage(Page<ProductionTeamDto> page, ProductionTeamDto dto);
}
src/main/java/com/ruoyi/production/service/ProductionTeamUserRelService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.production.service;
import com.ruoyi.production.pojo.ProductionTeamUserRel;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 *  æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-11 11:15:05
 */
public interface ProductionTeamUserRelService extends IService<ProductionTeamUserRel> {
}
src/main/java/com/ruoyi/production/service/impl/ProductionTeamServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,137 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.bean.dto.ProductionTeamDto;
import com.ruoyi.production.bean.vo.ProductionTeamVo;
import com.ruoyi.production.mapper.ProductionTeamMapper;
import com.ruoyi.production.pojo.ProductionTeam;
import com.ruoyi.production.pojo.ProductionTeamUserRel;
import com.ruoyi.production.service.ProductionTeamService;
import com.ruoyi.production.service.ProductionTeamUserRelService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ProductionTeamServiceImpl extends ServiceImpl<ProductionTeamMapper, ProductionTeam> implements ProductionTeamService {
    private final ProductionTeamUserRelService teamUserRelService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createTeam(ProductionTeamDto dto) {
        // åˆ›å»ºç­ç»„
        ProductionTeam team = new ProductionTeam();
        team.setTeamName(dto.getTeamName());
        team.setRemark(dto.getRemark());
        this.save(team);
        // ä¿å­˜æˆå‘˜å…³ç³»
        saveTeamUserRel(team.getId(), dto.getLeaderId(), dto.getMemberIds());
        return true;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTeam(ProductionTeamDto dto) {
        // æ›´æ–°ç­ç»„
        ProductionTeam team = new ProductionTeam();
        team.setId(dto.getId());
        team.setTeamName(dto.getTeamName());
        team.setRemark(dto.getRemark());
        this.updateById(team);
        // åˆ é™¤åŽŸæœ‰æˆå‘˜å…³ç³»
        QueryWrapper<ProductionTeamUserRel> wrapper = new QueryWrapper<>();
        wrapper.eq("production_team_id", dto.getId());
        teamUserRelService.remove(wrapper);
        // ä¿å­˜æ–°çš„æˆå‘˜å…³ç³»
        saveTeamUserRel(dto.getId(), dto.getLeaderId(), dto.getMemberIds());
        return true;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTeam(Long id) {
        // åˆ é™¤æˆå‘˜å…³ç³»
        QueryWrapper<ProductionTeamUserRel> wrapper = new QueryWrapper<>();
        wrapper.eq("production_team_id", id);
        teamUserRelService.remove(wrapper);
        // åˆ é™¤ç­ç»„
        return this.removeById(id);
    }
    @Override
    public ProductionTeamVo getTeamDetail(Long id) {
        ProductionTeamVo teamVo = getBaseMapper().selectTeamDetail(id);
        if (teamVo != null) {
            // åŠ è½½æˆå‘˜åˆ—è¡¨
            List<ProductionTeamVo.MemberVo> members = getBaseMapper().selectTeamMembers(id);
            teamVo.setMembers(members);
        }
        return teamVo;
    }
    @Override
    public List<ProductionTeamVo> getTeamList(ProductionTeamDto dto) {
        List<ProductionTeamVo> teamList = getBaseMapper().selectTeamList(dto);
        // ä¸ºæ¯ä¸ªç­ç»„加载成员列表
        for (ProductionTeamVo teamVo : teamList) {
            List<ProductionTeamVo.MemberVo> members = getBaseMapper().selectTeamMembers(teamVo.getId());
            teamVo.setMembers(members);
        }
        return teamList;
    }
    @Override
    public IPage<ProductionTeamVo> listPage(Page<ProductionTeamDto> page, ProductionTeamDto dto) {
        IPage<ProductionTeamVo> resultPage = getBaseMapper().selectTeamPage(page, dto);
        // ä¸ºæ¯ä¸ªç­ç»„加载成员列表
        for (ProductionTeamVo teamVo : resultPage.getRecords()) {
            List<ProductionTeamVo.MemberVo> members = getBaseMapper().selectTeamMembers(teamVo.getId());
            teamVo.setMembers(members);
        }
        return resultPage;
    }
    /**
     * ä¿å­˜ç­ç»„用户关系
     */
    private void saveTeamUserRel(Long teamId, Long leaderId, List<Long> memberIds) {
        // ä¿å­˜ç­ç»„é•¿
        if (leaderId != null) {
            ProductionTeamUserRel leaderRel = new ProductionTeamUserRel();
            leaderRel.setProductionTeamId(teamId);
            leaderRel.setSysUserId(leaderId);
            leaderRel.setIsLeader((byte) 1);
            teamUserRelService.save(leaderRel);
        }
        // ä¿å­˜æˆå‘˜
        if (!CollectionUtils.isEmpty(memberIds)) {
            for (Long memberId : memberIds) {
                // è·³è¿‡ç­ç»„长(已保存)
                if (leaderId != null && leaderId.equals(memberId)) {
                    continue;
                }
                ProductionTeamUserRel memberRel = new ProductionTeamUserRel();
                memberRel.setProductionTeamId(teamId);
                memberRel.setSysUserId(memberId);
                memberRel.setIsLeader((byte) 0);
                teamUserRelService.save(memberRel);
            }
        }
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionTeamUserRelServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.production.service.impl;
import com.ruoyi.production.pojo.ProductionTeamUserRel;
import com.ruoyi.production.mapper.ProductionTeamUserRelMapper;
import com.ruoyi.production.service.ProductionTeamUserRelService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
 * <p>
 *  æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-05-11 11:15:05
 */
@Service
@RequiredArgsConstructor
public class ProductionTeamUserRelServiceImpl extends ServiceImpl<ProductionTeamUserRelMapper, ProductionTeamUserRel> implements ProductionTeamUserRelService {
}
src/main/resources/application-qllx.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,266 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: D:/ruoyi/uploadPath
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
  # ååŒå®¡æ‰¹ç¼–号前缀(配置文件后缀命名)
  approvalNumberPrefix: DEV
  # ä¸ªæŽ¨ Unipush é…ç½®
  getui:
    appId: PfjyAAE0FK64FaO1w2CMb1
    appKey: zTMb831OEL6J4GK1uE3Ob4
    masterSecret: K1GFtsv42v61tXGnF7SGE5
    domain: https://restapi.getui.cn/v2/
    # ç¦»çº¿æŽ¨é€ä½¿ç”¨çš„包名/组件名
    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 7003
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    max-swallow-size: -1          # -1 è¡¨ç¤ºä¸é™åˆ¶
    max-http-form-post-size: -1   # POST è¯·æ±‚体不限制
    connection-timeout: 60000     # è¿žæŽ¥è¶…æ—¶æ—¶é—´(毫秒)
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    org.quartz: DEBUG
    com.ruoyi: warn
    org.springframework: warn
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  main:
    allow-circular-references: true # å…è®¸å¾ªçŽ¯ä¾èµ–
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://localhost:3306/product-inventory-management-qllx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  data:
    mongodb:
      uri: mongodb://114.132.189.42:9028/chat_memory_db
    # redis é…ç½®
    redis:
      # åœ°å€
      host: 127.0.0.1
      #    host: 172.17.0.1
      # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
      port: 6379
      # æ•°æ®åº“索引
      database: 0
      # å¯†ç 
      #    password: root2022!
      password:
      # è¿žæŽ¥è¶…æ—¶æ—¶é—´
      timeout: 10s
      lettuce:
        pool:
          # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
          min-idle: 0
          # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
          max-idle: 8
          # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
          max-active: 8
          # #连接池最大阻塞等待时间(使用负值表示没有限制)
          max-wait: -1ms
  # Quartz定时任务配置(新增部分)
  quartz:
    job-store-type: jdbc  # ä½¿ç”¨æ•°æ®åº“存储
    jdbc:
      initialize-schema: never  # é¦–次运行时自动创建表结构,成功后改为never
      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL表结构脚本
    properties:
      org:
        quartz:
          scheduler:
            instanceName: RuoYiScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL适配
            tablePrefix: qrtz_  # è¡¨åå‰ç¼€ï¼Œä¸Žè„šæœ¬ä¸€è‡´
            isClustered: false  # å•节点模式(集群需改为true)
            clusterCheckinInterval: 10000
            txIsolationLevelSerializable: true
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10  # çº¿ç¨‹æ± å¤§å°
            threadPriority: 5
            makeThreadsDaemons: true
          updateCheck: false  # å…³é—­ç‰ˆæœ¬æ£€æŸ¥
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥ æ–°ç‰ˆjwt密钥长度必须64位以上
  secret: xpAVjhCjQDaDB7mjPAzMDSbQWXNu2zYkTdDNUsPMS5Xx8QMmQVYN7n74eZrYJxDJ
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
# æ–‡ä»¶ä¸Šä¼ é…ç½®
file:
  temp-dir: D:/ruoyi/temp/uploads   # ä¸´æ—¶ç›®å½• åŽæœŸåˆ é™¤
  upload-dir: D:/ruoyi/prod/uploads # æ­£å¼ç›®å½• åŽæœŸåˆ é™¤
  path: C:/Users/12631/Desktop/download/uploads # ä¸Šä¼ ç›®å½•
  urlPrefix: /common # é“¾æŽ¥å‰ç¼€
  domain: http://127.0.0.1:7003 # åŸŸåå‰ç¼€
  expired: 120 # è¿‡æœŸæ—¶é—´(单位:分钟)
  useLimit: 10 # ä½¿ç”¨æ¬¡æ•°
  compress: true # æ˜¯å¦åŽ‹ç¼©
  needCompressSize: 10MB # åŽ‹ç¼©é˜ˆå€¼
  compressQuality: 0.5 # åŽ‹ç¼©è´¨é‡(0.0-1.0)
src/main/resources/mapper/production/ProductionTeamMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
<?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="com.ruoyi.production.mapper.ProductionTeamMapper">
    <resultMap id="TeamDetailMap" type="com.ruoyi.production.bean.vo.ProductionTeamVo">
        <id property="id" column="id"/>
        <result property="teamName" column="team_name"/>
        <result property="leaderId" column="leader_id"/>
        <result property="leaderName" column="leader_name"/>
        <result property="remark" column="remark"/>
        <result property="createTime" column="create_time"/>
    </resultMap>
    <select id="selectTeamDetail" resultMap="TeamDetailMap">
        SELECT
        t.id,
        t.team_name,
        leader.sys_user_id as leader_id,
        u.nick_name as leader_name,
        t.remark,
        t.create_time
        FROM production_team t
        LEFT JOIN production_team_user_rel leader ON t.id = leader.production_team_id AND leader.is_leader = 1
        LEFT JOIN sys_user u ON leader.sys_user_id = u.user_id
        WHERE t.id = #{id}
    </select>
    <select id="selectTeamMembers" resultType="com.ruoyi.production.bean.vo.ProductionTeamVo$MemberVo">
        SELECT
        rel.sys_user_id as userId,
        u.nick_name as nickName,
        rel.is_leader as isLeader
        FROM production_team_user_rel rel
        LEFT JOIN sys_user u ON rel.sys_user_id = u.user_id
        WHERE rel.production_team_id = #{teamId}
        ORDER BY rel.is_leader DESC
    </select>
    <select id="selectTeamList" resultMap="TeamDetailMap">
        SELECT
        t.id,
        t.team_name,
        leader.sys_user_id as leader_id,
        u.nick_name as leader_name,
        t.remark,
        t.create_time
        FROM production_team t
        LEFT JOIN production_team_user_rel leader ON t.id = leader.production_team_id AND leader.is_leader = 1
        LEFT JOIN sys_user u ON leader.sys_user_id = u.user_id
        <where>
            <if test="dto.teamName != null and dto.teamName != ''">
                AND t.team_name LIKE CONCAT('%', #{dto.teamName}, '%')
            </if>
        </where>
        ORDER BY t.create_time DESC
    </select>
    <select id="selectTeamPage" resultMap="TeamDetailMap">
        SELECT
        t.id,
        t.team_name,
        leader.sys_user_id as leader_id,
        u.nick_name as leader_name,
        t.remark,
        t.create_time
        FROM production_team t
        LEFT JOIN production_team_user_rel leader ON t.id = leader.production_team_id AND leader.is_leader = 1
        LEFT JOIN sys_user u ON leader.sys_user_id = u.user_id
        <where>
            <if test="dto.teamName != null and dto.teamName != ''">
                AND t.team_name LIKE CONCAT('%', #{dto.teamName}, '%')
            </if>
        </where>
        ORDER BY t.create_time DESC
    </select>
</mapper>
src/main/resources/mapper/production/ProductionTeamUserRelMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
<?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="com.ruoyi.production.mapper.ProductionTeamUserRelMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductionTeamUserRel">
        <id column="id" property="id" />
        <result column="production_team_id" property="productionTeamId" />
        <result column="sys_user_id" property="sysUserId" />
        <result column="is_leader" property="isLeader" />
        <result column="tenant_id" property="tenantId" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
    </resultMap>
</mapper>