Ver Fonte

学习计划管理 - 查询课件列表、批量添加计划、查询计划列表、修改计划、删除计划、导出签名表

Wang Zi Wen há 2 anos atrás
pai
commit
ff742c098e

+ 138 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/branch/TBranchLearningController.java

@@ -0,0 +1,138 @@
+package com.ruoyi.web.controller.branch;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.common.core.domain.entity.SysDictData;
+import com.ruoyi.system.service.ISysDictTypeService;
+import com.ruoyi.web.controller.branch.vo.AddPlanVO;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.branch.domain.TBranchLearning;
+import com.ruoyi.branch.service.ITBranchLearningService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 学习计划Controller
+ * 
+ * @author ruoyi
+ * @date 2023-09-21
+ */
+@RestController
+@RequestMapping("/branch/learning")
+public class TBranchLearningController extends BaseController
+{
+    @Autowired
+    private ITBranchLearningService tBranchLearningService;
+
+    @Autowired
+    private ISysDictTypeService sysDictTypeService;
+
+    /**
+     * 添加计划
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:add')")
+    @Log(title = "学习计划", businessType = BusinessType.INSERT)
+    @PostMapping("/addPlan")
+    public AjaxResult addPlan(@RequestBody AddPlanVO addPlanVO)
+    {
+        for (Long userId : addPlanVO.getUserIds()) {
+            TBranchLearning tBranchLearning = new TBranchLearning();
+            tBranchLearning.setUserId(userId);
+            tBranchLearning.setFileId(addPlanVO.getFileId());
+            tBranchLearning.setLearningDeadline(addPlanVO.getLearningDeadline());
+            tBranchLearning.setLearningTimeRequired(addPlanVO.getLearningTimeRequired());
+            tBranchLearning.setDeptId(getDeptId());
+            tBranchLearningService.insertTBranchLearning(tBranchLearning);
+        }
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * 查询学习计划列表
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:list')")
+    @GetMapping("/list")
+    public AjaxResult list(TBranchLearning tBranchLearning)
+    {
+        return AjaxResult.success(tBranchLearningService.selectTBranchLearningList(tBranchLearning));
+    }
+
+    /**
+     * 导出签名表
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:export')")
+    @Log(title = "学习计划", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, TBranchLearning tBranchLearning)
+    {
+        List<SysDictData> learningStatus = sysDictTypeService.selectDictDataByType("learning_status");
+        List<TBranchLearning> list = tBranchLearningService.selectTBranchLearningList(tBranchLearning);
+        for (TBranchLearning branchLearning : list) {
+            for (SysDictData data : learningStatus) {
+                if (data.getDictValue().equals(branchLearning.getLearningStatus())) {
+                    branchLearning.setLearningStatus(data.getDictLabel());
+                }
+            }
+        }
+        ExcelUtil<TBranchLearning> util = new ExcelUtil<TBranchLearning>(TBranchLearning.class);
+        util.exportExcel(response, list, "签名表数据");
+    }
+
+    /**
+     * 获取学习计划详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:query')")
+    @GetMapping(value = "/{learningId}")
+    public AjaxResult getInfo(@PathVariable("learningId") Long learningId)
+    {
+        return success(tBranchLearningService.selectTBranchLearningByLearningId(learningId));
+    }
+
+    /**
+     * 新增学习计划
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:add')")
+    @Log(title = "学习计划", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody TBranchLearning tBranchLearning)
+    {
+        return toAjax(tBranchLearningService.insertTBranchLearning(tBranchLearning));
+    }
+
+    /**
+     * 修改学习计划
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:edit')")
+    @Log(title = "学习计划", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody TBranchLearning tBranchLearning)
+    {
+        return toAjax(tBranchLearningService.updateTBranchLearning(tBranchLearning));
+    }
+
+    /**
+     * 删除学习计划
+     */
+    @PreAuthorize("@ss.hasPermi('branch:learning:remove')")
+    @Log(title = "学习计划", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{learningIds}")
+    public AjaxResult remove(@PathVariable Long[] learningIds)
+    {
+        return toAjax(tBranchLearningService.deleteTBranchLearningByLearningIds(learningIds));
+    }
+}

+ 56 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/branch/vo/AddPlanVO.java

@@ -0,0 +1,56 @@
+package com.ruoyi.web.controller.branch.vo;
+
+import java.util.Date;
+
+/**
+ * 添加计划VO
+ *
+ * @author Wang Zi Wen
+ * @email wangggziwen@163.com
+ * @date 2023/09/21 14:38:51
+ */
+public class AddPlanVO {
+    /** 文件id */
+    private Long fileId;
+
+    /** 截止日期 */
+    private Date learningDeadline;
+
+    /** 学习时长 */
+    private Long learningTimeRequired;
+
+    /** 学员 */
+    private Long[] userIds;
+
+    public Long getFileId() {
+        return fileId;
+    }
+
+    public void setFileId(Long fileId) {
+        this.fileId = fileId;
+    }
+
+    public Date getLearningDeadline() {
+        return learningDeadline;
+    }
+
+    public void setLearningDeadline(Date learningDeadline) {
+        this.learningDeadline = learningDeadline;
+    }
+
+    public Long getLearningTimeRequired() {
+        return learningTimeRequired;
+    }
+
+    public void setLearningTimeRequired(Long learningTimeRequired) {
+        this.learningTimeRequired = learningTimeRequired;
+    }
+
+    public Long[] getUserIds() {
+        return userIds;
+    }
+
+    public void setUserIds(Long[] userIds) {
+        this.userIds = userIds;
+    }
+}

+ 1 - 1
ruoyi-generator/src/main/resources/vm/vue/index.vue.vm

@@ -566,7 +566,7 @@ export default {
         this.download('${moduleName}/${businessName}/export', {
             ...this.queryParams
         }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
-    }
+    },
       /** 导入按钮操作 */
       handleImport() {
           this.upload.title = "用户导入";

+ 196 - 0
ruoyi-system/src/main/java/com/ruoyi/branch/domain/TBranchLearning.java

@@ -0,0 +1,196 @@
+package com.ruoyi.branch.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+import java.util.Date;
+
+/**
+ * 学习计划对象 t_branch_learning
+ * 
+ * @author ruoyi
+ * @date 2023-09-21
+ */
+public class TBranchLearning extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键id */
+    private Long learningId;
+
+    /** 用户id */
+    private Long userId;
+
+    /** 姓名 */
+    @Excel(name = "姓名")
+    private String nickName;
+
+    /** 文件id */
+    private Long fileId;
+
+    /** 课件名称 */
+    @Excel(name = "课件名称")
+    private String fileName;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private String learningStatus;
+
+    /** 规定学习时长 */
+    @Excel(name = "规定学习时长(min)")
+    private Long learningTimeRequired;
+
+    /** 累计学习时长 */
+    @Excel(name = "累计学习时长(min)")
+    private Long learningTimeStudied;
+
+    /** 截止日期 */
+    @Excel(name = "截止日期", dateFormat = "yyyy-MM-dd")
+    private Date learningDeadline;
+
+    /** 进度 */
+    @Excel(name = "进度")
+    private Long learningProgress;
+
+    /** 删除标志(0代表存在 2代表删除) */
+    private String delFlag;
+
+    /** 部门id */
+    private Long deptId;
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
+    public String getNickName() {
+        return nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public Date getLearningDeadline() {
+        return learningDeadline;
+    }
+
+    public void setLearningDeadline(Date learningDeadline) {
+        this.learningDeadline = learningDeadline;
+    }
+
+    public void setLearningId(Long learningId)
+    {
+        this.learningId = learningId;
+    }
+
+    public Long getLearningId() 
+    {
+        return learningId;
+    }
+
+    public void setUserId(Long userId) 
+    {
+        this.userId = userId;
+    }
+
+    public Long getUserId() 
+    {
+        return userId;
+    }
+
+    public void setFileId(Long fileId) 
+    {
+        this.fileId = fileId;
+    }
+
+    public Long getFileId() 
+    {
+        return fileId;
+    }
+
+    public void setLearningStatus(String learningStatus) 
+    {
+        this.learningStatus = learningStatus;
+    }
+
+    public String getLearningStatus() 
+    {
+        return learningStatus;
+    }
+
+    public void setLearningTimeRequired(Long learningTimeRequired)
+    {
+        this.learningTimeRequired = learningTimeRequired;
+    }
+
+    public Long getLearningTimeRequired()
+    {
+        return learningTimeRequired;
+    }
+
+    public void setLearningTimeStudied(Long learningTimeStudied)
+    {
+        this.learningTimeStudied = learningTimeStudied;
+    }
+
+    public Long getLearningTimeStudied()
+    {
+        return learningTimeStudied;
+    }
+
+    public void setLearningProgress(Long learningProgress)
+    {
+        this.learningProgress = learningProgress;
+    }
+
+    public Long getLearningProgress()
+    {
+        return learningProgress;
+    }
+
+    public void setDelFlag(String delFlag) 
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag() 
+    {
+        return delFlag;
+    }
+
+    public void setDeptId(Long deptId) 
+    {
+        this.deptId = deptId;
+    }
+
+    public Long getDeptId() 
+    {
+        return deptId;
+    }
+
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("learningId", getLearningId())
+            .append("userId", getUserId())
+            .append("fileId", getFileId())
+            .append("learningStatus", getLearningStatus())
+            .append("learningTimeRequired", getLearningTimeRequired())
+            .append("learningTimeStudied", getLearningTimeStudied())
+            .append("learningProgress", getLearningProgress())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("deptId", getDeptId())
+            .toString();
+    }
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/branch/mapper/TBranchLearningMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.branch.mapper;
+
+import java.util.List;
+import com.ruoyi.branch.domain.TBranchLearning;
+
+/**
+ * 学习计划Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2023-09-21
+ */
+public interface TBranchLearningMapper 
+{
+    /**
+     * 查询学习计划
+     * 
+     * @param learningId 学习计划主键
+     * @return 学习计划
+     */
+    public TBranchLearning selectTBranchLearningByLearningId(Long learningId);
+
+    /**
+     * 查询学习计划列表
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 学习计划集合
+     */
+    public List<TBranchLearning> selectTBranchLearningList(TBranchLearning tBranchLearning);
+
+    /**
+     * 新增学习计划
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 结果
+     */
+    public int insertTBranchLearning(TBranchLearning tBranchLearning);
+
+    /**
+     * 修改学习计划
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 结果
+     */
+    public int updateTBranchLearning(TBranchLearning tBranchLearning);
+
+    /**
+     * 删除学习计划
+     * 
+     * @param learningId 学习计划主键
+     * @return 结果
+     */
+    public int deleteTBranchLearningByLearningId(Long learningId);
+
+    /**
+     * 批量删除学习计划
+     * 
+     * @param learningIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteTBranchLearningByLearningIds(Long[] learningIds);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/branch/service/ITBranchLearningService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.branch.service;
+
+import java.util.List;
+import com.ruoyi.branch.domain.TBranchLearning;
+
+/**
+ * 学习计划Service接口
+ * 
+ * @author ruoyi
+ * @date 2023-09-21
+ */
+public interface ITBranchLearningService 
+{
+    /**
+     * 查询学习计划
+     * 
+     * @param learningId 学习计划主键
+     * @return 学习计划
+     */
+    public TBranchLearning selectTBranchLearningByLearningId(Long learningId);
+
+    /**
+     * 查询学习计划列表
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 学习计划集合
+     */
+    public List<TBranchLearning> selectTBranchLearningList(TBranchLearning tBranchLearning);
+
+    /**
+     * 新增学习计划
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 结果
+     */
+    public int insertTBranchLearning(TBranchLearning tBranchLearning);
+
+    /**
+     * 修改学习计划
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 结果
+     */
+    public int updateTBranchLearning(TBranchLearning tBranchLearning);
+
+    /**
+     * 批量删除学习计划
+     * 
+     * @param learningIds 需要删除的学习计划主键集合
+     * @return 结果
+     */
+    public int deleteTBranchLearningByLearningIds(Long[] learningIds);
+
+    /**
+     * 删除学习计划信息
+     * 
+     * @param learningId 学习计划主键
+     * @return 结果
+     */
+    public int deleteTBranchLearningByLearningId(Long learningId);
+}

+ 99 - 0
ruoyi-system/src/main/java/com/ruoyi/branch/service/impl/TBranchLearningServiceImpl.java

@@ -0,0 +1,99 @@
+package com.ruoyi.branch.service.impl;
+
+import java.util.List;
+
+import com.ruoyi.common.annotation.DataScope;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.branch.mapper.TBranchLearningMapper;
+import com.ruoyi.branch.domain.TBranchLearning;
+import com.ruoyi.branch.service.ITBranchLearningService;
+
+/**
+ * 学习计划Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2023-09-21
+ */
+@Service
+public class TBranchLearningServiceImpl implements ITBranchLearningService 
+{
+    @Autowired
+    private TBranchLearningMapper tBranchLearningMapper;
+
+    /**
+     * 查询学习计划
+     * 
+     * @param learningId 学习计划主键
+     * @return 学习计划
+     */
+    @Override
+    public TBranchLearning selectTBranchLearningByLearningId(Long learningId)
+    {
+        return tBranchLearningMapper.selectTBranchLearningByLearningId(learningId);
+    }
+
+    /**
+     * 查询学习计划列表
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 学习计划
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<TBranchLearning> selectTBranchLearningList(TBranchLearning tBranchLearning)
+    {
+        return tBranchLearningMapper.selectTBranchLearningList(tBranchLearning);
+    }
+
+    /**
+     * 新增学习计划
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 结果
+     */
+    @Override
+    public int insertTBranchLearning(TBranchLearning tBranchLearning)
+    {
+        tBranchLearning.setCreateTime(DateUtils.getNowDate());
+        return tBranchLearningMapper.insertTBranchLearning(tBranchLearning);
+    }
+
+    /**
+     * 修改学习计划
+     * 
+     * @param tBranchLearning 学习计划
+     * @return 结果
+     */
+    @Override
+    public int updateTBranchLearning(TBranchLearning tBranchLearning)
+    {
+        tBranchLearning.setUpdateTime(DateUtils.getNowDate());
+        return tBranchLearningMapper.updateTBranchLearning(tBranchLearning);
+    }
+
+    /**
+     * 批量删除学习计划
+     * 
+     * @param learningIds 需要删除的学习计划主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTBranchLearningByLearningIds(Long[] learningIds)
+    {
+        return tBranchLearningMapper.deleteTBranchLearningByLearningIds(learningIds);
+    }
+
+    /**
+     * 删除学习计划信息
+     * 
+     * @param learningId 学习计划主键
+     * @return 结果
+     */
+    @Override
+    public int deleteTBranchLearningByLearningId(Long learningId)
+    {
+        return tBranchLearningMapper.deleteTBranchLearningByLearningId(learningId);
+    }
+}

+ 129 - 0
ruoyi-system/src/main/resources/mapper/branch/TBranchLearningMapper.xml

@@ -0,0 +1,129 @@
+<?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.branch.mapper.TBranchLearningMapper">
+    
+    <resultMap type="TBranchLearning" id="TBranchLearningResult">
+        <result property="learningId"    column="learning_id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="nickName"    column="nick_name"    />
+        <result property="fileId"    column="file_id"    />
+        <result property="fileName"    column="file_name"    />
+        <result property="learningStatus"    column="learning_status"    />
+        <result property="learningTimeRequired"    column="learning_time_required"    />
+        <result property="learningTimeStudied"    column="learning_time_studied"    />
+        <result property="learningProgress"    column="learning_progress"    />
+        <result property="learningDeadline"    column="learning_deadline"    />
+        <result property="delFlag"    column="del_flag"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="deptId"    column="dept_id"    />
+    </resultMap>
+
+    <sql id="selectTBranchLearningVo">
+        select u.learning_id, u.user_id, u.file_id, u.learning_status, u.learning_time_required, u.learning_time_studied, u.learning_progress, u.learning_deadline, u.del_flag, u.create_by, u.create_time, u.update_by, u.update_time, u.dept_id,
+        us.nick_name,
+        f.name as file_name
+        from t_branch_learning u
+        left join sys_dept d on u.dept_id = d.dept_id
+        left join sys_user us on u.user_id = us.user_id
+        left join t_file f on f.id = u. file_id
+    </sql>
+
+    <select id="selectTBranchLearningList" parameterType="TBranchLearning" resultMap="TBranchLearningResult">
+        <include refid="selectTBranchLearningVo"/>
+        <where>  
+            <if test="learningId != null "> and u.learning_id = #{learningId}</if>
+            <if test="userId != null "> and u.user_id = #{userId}</if>
+            <if test="fileId != null "> and u.file_id = #{fileId}</if>
+            <if test="learningStatus != null  and learningStatus != ''"> and u.learning_status = #{learningStatus}</if>
+            <if test="learningTimeRequired != null  and learningTimeRequired != ''"> and u.learning_time_required = #{learningTimeRequired}</if>
+            <if test="learningTimeStudied != null  and learningTimeStudied != ''"> and u.learning_time_studied = #{learningTimeStudied}</if>
+            <if test="learningProgress != null  and learningProgress != ''"> and u.learning_progress = #{learningProgress}</if>
+            <if test="learningDeadline != null  and learningDeadline != ''"> and u.learning_deadline = #{learningDeadline}</if>
+            <if test="deptId != null "> and u.dept_id = #{deptId}</if>
+            and u.del_flag = 0
+        </where>
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+    </select>
+    
+    <select id="selectTBranchLearningByLearningId" parameterType="Long" resultMap="TBranchLearningResult">
+        <include refid="selectTBranchLearningVo"/>
+        where u.learning_id = #{learningId}
+        and u.del_flag = 0
+    </select>
+        
+    <insert id="insertTBranchLearning" parameterType="TBranchLearning">
+        <selectKey keyProperty="learningId" resultType="long" order="BEFORE">
+            SELECT seq_t_branch_learning.NEXTVAL as learningId FROM DUAL
+        </selectKey>
+        insert into t_branch_learning
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="learningId != null">learning_id,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="fileId != null">file_id,</if>
+            <if test="learningStatus != null">learning_status,</if>
+            <if test="learningTimeRequired != null">learning_time_required,</if>
+            <if test="learningTimeStudied != null">learning_time_studied,</if>
+            <if test="learningProgress != null">learning_progress,</if>
+            <if test="learningDeadline != null">learning_deadline,</if>
+            <if test="delFlag != null">del_flag,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="deptId != null">dept_id,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="learningId != null">#{learningId},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="fileId != null">#{fileId},</if>
+            <if test="learningStatus != null">#{learningStatus},</if>
+            <if test="learningTimeRequired != null">#{learningTimeRequired},</if>
+            <if test="learningTimeStudied != null">#{learningTimeStudied},</if>
+            <if test="learningProgress != null">#{learningProgress},</if>
+            <if test="learningDeadline != null">#{learningDeadline},</if>
+            <if test="delFlag != null">#{delFlag},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="deptId != null">#{deptId},</if>
+         </trim>
+    </insert>
+
+    <update id="updateTBranchLearning" parameterType="TBranchLearning">
+        update t_branch_learning
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="fileId != null">file_id = #{fileId},</if>
+            <if test="learningStatus != null">learning_status = #{learningStatus},</if>
+            <if test="learningTimeRequired != null">learning_time_required = #{learningTimeRequired},</if>
+            <if test="learningTimeStudied != null">learning_time_studied = #{learningTimeStudied},</if>
+            <if test="learningProgress != null">learning_progress = #{learningProgress},</if>
+            <if test="learningDeadline != null">learning_deadline = #{learningDeadline},</if>
+            <if test="delFlag != null">del_flag = #{delFlag},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+        </trim>
+        where learning_id = #{learningId}
+    </update>
+
+    <update id="deleteTBranchLearningByLearningId" parameterType="Long">
+        update t_branch_learning set del_flag = 2 where learning_id = #{learningId}
+    </update>
+
+    <update id="deleteTBranchLearningByLearningIds" parameterType="String">
+        update t_branch_learning set del_flag = 2 where learning_id in
+        <foreach item="learningId" collection="array" open="(" separator="," close=")">
+            #{learningId}
+        </foreach>
+    </update>
+</mapper>

+ 53 - 0
ruoyi-ui/src/api/branch/learning.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 添加计划
+export function addPlan(data) {
+  return request({
+    url: '/branch/learning/addPlan',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询学习计划列表
+export function listLearning(query) {
+  return request({
+    url: '/branch/learning/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询学习计划详细
+export function getLearning(learningId) {
+  return request({
+    url: '/branch/learning/' + learningId,
+    method: 'get'
+  })
+}
+
+// 新增学习计划
+export function addLearning(data) {
+  return request({
+    url: '/branch/learning',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改学习计划
+export function updateLearning(data) {
+  return request({
+    url: '/branch/learning',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除学习计划
+export function delLearning(learningId) {
+  return request({
+    url: '/branch/learning/' + learningId,
+    method: 'delete'
+  })
+}

+ 608 - 0
ruoyi-ui/src/views/branch/xxyd/learning/index.vue

@@ -0,0 +1,608 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" size="small" v-show="showSearch" label-width="68px">
+      <el-form-item label="主键id" prop="learningId">
+        <el-input
+          v-model="queryParams.learningId"
+          placeholder="请输入主键id"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="用户id" prop="userId">
+        <el-input
+          v-model="queryParams.userId"
+          placeholder="请输入用户id"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="文件id" prop="fileId">
+        <el-input
+          v-model="queryParams.fileId"
+          placeholder="请输入文件id"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="learningStatus">
+        <el-select v-model="queryParams.learningStatus" placeholder="请选择状态" clearable size="small">
+          <el-option
+            v-for="dict in learningStatusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="规定学习时长" prop="learningTimeRequired">
+        <el-input
+          v-model="queryParams.learningTimeRequired"
+          placeholder="请输入规定学习时长"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="累计学习时长" prop="learningTimeStudied">
+        <el-input
+          v-model="queryParams.learningTimeStudied"
+          placeholder="请输入累计学习时长"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="进度" prop="learningProgress">
+        <el-input
+          v-model="queryParams.learningProgress"
+          placeholder="请输入进度"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="部门id" prop="deptId">
+        <el-input
+          v-model="queryParams.deptId"
+          placeholder="请输入部门id"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['branch:learning:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['branch:learning:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['branch:learning:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="info"
+          plain
+          icon="el-icon-upload2"
+          size="mini"
+          @click="handleImport"
+          v-hasPermi="['branch:learning:edit']"
+        >导入</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['branch:learning:export']"
+        >导出</el-button>
+      </el-col>
+	  <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="learningList" @selection-change="handleSelectionChange" :height="clientHeight" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="主键id" align="center" prop="learningId" />
+      <el-table-column label="用户id" align="center" prop="userId" />
+      <el-table-column label="文件id" align="center" prop="fileId" />
+      <el-table-column label="状态" align="center" prop="learningStatus" />
+      <el-table-column label="规定学习时长" align="center" prop="learningTimeRequired" />
+      <el-table-column label="累计学习时长" align="center" prop="learningTimeStudied" />
+      <el-table-column label="进度" align="center" prop="learningProgress" />
+      <el-table-column label="部门id" align="center" prop="deptId" />
+      <el-table-column label="操作" align="center" fixed="right" width="120" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['branch:learning:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['branch:learning:remove']"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改学习计划对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="主键id" prop="learningId">
+          <el-input v-model="form.learningId" placeholder="请输入主键id" />
+        </el-form-item>
+        <el-form-item label="用户id" prop="userId">
+          <el-input v-model="form.userId" placeholder="请输入用户id" />
+        </el-form-item>
+        <el-form-item label="文件id" prop="fileId">
+          <el-input v-model="form.fileId" placeholder="请输入文件id" />
+        </el-form-item>
+        <el-form-item label="状态">
+          <el-radio-group v-model="form.learningStatus">
+            <el-radio
+              v-for="dict in learningStatusOptions"
+              :key="dict.dictValue"
+:label="dict.dictValue"
+            >{{dict.dictLabel}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="规定学习时长" prop="learningTimeRequired">
+          <el-input v-model="form.learningTimeRequired" placeholder="请输入规定学习时长" />
+        </el-form-item>
+        <el-form-item label="累计学习时长" prop="learningTimeStudied">
+          <el-input v-model="form.learningTimeStudied" placeholder="请输入累计学习时长" />
+        </el-form-item>
+        <el-form-item label="进度" prop="learningProgress">
+          <el-input v-model="form.learningProgress" placeholder="请输入进度" />
+        </el-form-item>
+        <el-form-item label="删除标志" prop="delFlag">
+          <el-input v-model="form.delFlag" placeholder="请输入删除标志" />
+        </el-form-item>
+        <el-form-item label="部门id" prop="deptId">
+          <el-input v-model="form.deptId" placeholder="请输入部门id" />
+        </el-form-item>
+          <el-form-item label="归属部门" prop="deptId">
+              <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+          </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+    <!-- 用户导入对话框 -->
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+        <el-upload
+                ref="upload"
+                :limit="1"
+                accept=".xlsx, .xls"
+                :headers="upload.headers"
+                :action="upload.url + '?updateSupport=' + upload.updateSupport"
+                :disabled="upload.isUploading"
+                :on-progress="handleFileUploadProgress"
+                :on-success="handleFileSuccess"
+                :auto-upload="false"
+                drag
+        >
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">
+                将文件拖到此处,或
+                <em>点击上传</em>
+            </div>
+            <div class="el-upload__tip" slot="tip">
+                <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
+                <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
+            </div>
+            <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+        </el-upload>
+        <div slot="footer" class="dialog-footer">
+            <el-button type="primary" @click="submitFileForm">确 定</el-button>
+            <el-button @click="upload.open = false">取 消</el-button>
+        </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listLearning, getLearning, delLearning, addLearning, updateLearning, exportLearning, importTemplate} from "@/api/branch/learning";
+import { treeselect } from "@/api/system/dept";
+import { getToken } from "@/utils/auth";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+  name: "Learning",
+  components: { Treeselect },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: false,
+      // 总条数
+      total: 0,
+      // 学习计划表格数据
+      learningList: [],
+      // 弹出层标题
+      title: "",
+      // 部门树选项
+      deptOptions: undefined,
+      clientHeight:300,
+      // 是否显示弹出层
+      open: false,
+      // 主键id字典
+      learningIdOptions: [],
+      // 用户id字典
+      userIdOptions: [],
+      // 文件id字典
+      fileIdOptions: [],
+      // 状态字典
+      learningStatusOptions: [],
+      // 规定学习时长字典
+      learningTimeRequiredOptions: [],
+      // 累计学习时长字典
+      learningTimeStudiedOptions: [],
+      // 进度字典
+      learningProgressOptions: [],
+      // 删除标志字典
+      delFlagOptions: [],
+      // 创建者字典
+      createByOptions: [],
+      // 创建时间字典
+      createTimeOptions: [],
+      // 更新者字典
+      updateByOptions: [],
+      // 更新时间字典
+      updateTimeOptions: [],
+      // 部门id字典
+      deptIdOptions: [],
+        // 用户导入参数
+        upload: {
+            // 是否显示弹出层(用户导入)
+            open: false,
+            // 弹出层标题(用户导入)
+            title: "",
+            // 是否禁用上传
+            isUploading: false,
+            // 是否更新已经存在的用户数据
+            updateSupport: 0,
+            // 设置上传的请求头部
+            headers: { Authorization: "Bearer " + getToken() },
+            // 上传的地址
+            url: process.env.VUE_APP_BASE_API + "/branch/learning/importData"
+        },
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 20,
+        learningId: null,
+        userId: null,
+        fileId: null,
+        learningStatus: null,
+        learningTimeRequired: null,
+        learningTimeStudied: null,
+        learningProgress: null,
+        deptId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        learningId: [
+          { required: true, message: "主键id不能为空", trigger: "blur" }
+        ],
+        userId: [
+          { required: true, message: "用户id不能为空", trigger: "blur" }
+        ],
+        fileId: [
+          { required: true, message: "文件id不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  watch: {
+        // 根据名称筛选部门树
+        deptName(val) {
+            this.$refs.tree.filter(val);
+        }
+   },
+  created() {
+      //设置表格高度对应屏幕高度
+      this.$nextTick(() => {
+          this.clientHeight = document.body.clientHeight -250
+      })
+    this.getList();
+    this.getTreeselect();
+    this.getDicts("${column.dictType}").then(response => {
+      this.learningIdOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.userIdOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.fileIdOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.learningStatusOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.learningTimeRequiredOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.learningTimeStudiedOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.learningProgressOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.delFlagOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.createByOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.createTimeOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.updateByOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.updateTimeOptions = response.data;
+    });
+    this.getDicts("${column.dictType}").then(response => {
+      this.deptIdOptions = response.data;
+    });
+  },
+  methods: {
+    /** 查询学习计划列表 */
+    getList() {
+      this.loading = true;
+      listLearning(this.queryParams).then(response => {
+        this.learningList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+     /** 查询部门下拉树结构 */
+     getTreeselect() {
+          treeselect().then(response => {
+              this.deptOptions = response.data;
+          });
+     },
+    // 主键id字典翻译
+    learningIdFormat(row, column) {
+      return this.selectDictLabel(this.learningIdOptions, row.learningId);
+    },
+    // 用户id字典翻译
+    userIdFormat(row, column) {
+      return this.selectDictLabel(this.userIdOptions, row.userId);
+    },
+    // 文件id字典翻译
+    fileIdFormat(row, column) {
+      return this.selectDictLabel(this.fileIdOptions, row.fileId);
+    },
+    // 状态字典翻译
+    learningStatusFormat(row, column) {
+      return this.selectDictLabel(this.learningStatusOptions, row.learningStatus);
+    },
+    // 规定学习时长字典翻译
+    learningTimeRequiredFormat(row, column) {
+      return this.selectDictLabel(this.learningTimeRequiredOptions, row.learningTimeRequired);
+    },
+    // 累计学习时长字典翻译
+    learningTimeStudiedFormat(row, column) {
+      return this.selectDictLabel(this.learningTimeStudiedOptions, row.learningTimeStudied);
+    },
+    // 进度字典翻译
+    learningProgressFormat(row, column) {
+      return this.selectDictLabel(this.learningProgressOptions, row.learningProgress);
+    },
+    // 删除标志字典翻译
+    delFlagFormat(row, column) {
+      return this.selectDictLabel(this.delFlagOptions, row.delFlag);
+    },
+    // 创建者字典翻译
+    createByFormat(row, column) {
+      return this.selectDictLabel(this.createByOptions, row.createBy);
+    },
+    // 创建时间字典翻译
+    createTimeFormat(row, column) {
+      return this.selectDictLabel(this.createTimeOptions, row.createTime);
+    },
+    // 更新者字典翻译
+    updateByFormat(row, column) {
+      return this.selectDictLabel(this.updateByOptions, row.updateBy);
+    },
+    // 更新时间字典翻译
+    updateTimeFormat(row, column) {
+      return this.selectDictLabel(this.updateTimeOptions, row.updateTime);
+    },
+    // 部门id字典翻译
+    deptIdFormat(row, column) {
+      return this.selectDictLabel(this.deptIdOptions, row.deptId);
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        learningId: null,
+        userId: null,
+        fileId: null,
+        learningStatus: "0",
+        learningTimeRequired: null,
+        learningTimeStudied: null,
+        learningProgress: null,
+        delFlag: null,
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null,
+        deptId: null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.learningId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加学习计划";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const learningId = row.learningId || this.ids
+      getLearning(learningId).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改学习计划";
+      });
+    },
+      /** 提交按钮 */
+      submitForm() {
+          this.$refs["form"].validate(valid => {
+              if (valid) {
+                  if (this.form.learningId != null) {
+                      updateLearning(this.form).then(response => {
+                          this.$modal.msgSuccess("修改成功");
+                          this.open = false;
+                          this.getList();
+                      });
+                  } else {
+                      addLearning(this.form).then(response => {
+                          this.$modal.msgSuccess("新增成功");
+                          this.open = false;
+                          this.getList();
+                      });
+                  }
+              }
+          });
+      },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const learningIds = row.learningId || this.ids;
+      this.$confirm('是否确认删除?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delLearning(learningIds);
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        })
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+        this.download('branch/learning/export', {
+            ...this.queryParams
+        }, `learning_${new Date().getTime()}.xlsx`)
+    },
+      /** 导入按钮操作 */
+      handleImport() {
+          this.upload.title = "用户导入";
+          this.upload.open = true;
+      },
+      /** 下载模板操作 */
+      importTemplate() {
+          importTemplate().then(response => {
+              this.download(response.msg);
+          });
+      },
+      // 文件上传中处理
+      handleFileUploadProgress(event, file, fileList) {
+          this.upload.isUploading = true;
+      },
+      // 文件上传成功处理
+      handleFileSuccess(response, file, fileList) {
+          this.upload.open = false;
+          this.upload.isUploading = false;
+          this.$refs.upload.clearFiles();
+          this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
+          this.getList();
+      },
+      // 提交上传文件
+      submitFileForm() {
+          this.$refs.upload.submit();
+      }
+  }
+};
+</script>
+
+<style>
+    /** 文本换行符处理 */
+    .el-table .cell{
+        white-space: pre-wrap;
+    }
+    /** textarea字体 */
+    textarea {
+        font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
+    }
+</style>

+ 608 - 0
ruoyi-ui/src/views/branch/xxyd/studyplan/index.vue

@@ -0,0 +1,608 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" size="small" v-show="showSearch" label-width="68px">
+      <el-form-item label="时间" prop="year">
+        <el-date-picker size="small" style="width: 200px"
+                        v-model="queryParams.monthYear"
+                        type="month"
+                        placeholder="选择时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-table :data="file.dataList" border>
+      <el-table-column label="课件名称" align="center">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-document"
+            @click="handleSee(scope.row.url)">
+            {{ scope.row.name }}
+          </el-button>
+        </template>
+      </el-table-column>
+      <el-table-column label="上传人" align="center" prop="creater" width="100"/>
+      <el-table-column label="上传时间" align="center" prop="createdate" width="100">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createdate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="250" fixed="right">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" @click="handleAddPlan(scope.row)">添加计划</el-button>
+          <el-button size="mini" type="text" @click="handleSeePlan(scope.row)">查看计划</el-button>
+          <el-button size="mini" type="text" @click="handleExportPlan(scope.row)">导出签名表</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-dialog :title="addPlanTitle" :visible.sync="addPlanOpen" width="60%" append-to-body>
+          <el-form ref="addForm" :model="addForm" :rules="addRules" label-width="80px">
+            <el-form-item label="学员" prop="userIds">
+              <el-transfer v-model="addForm.userIds" :data="data" :titles="['全部人员列表', '选中人员列表']"></el-transfer>
+            </el-form-item>
+            <el-form-item label="学习时长" prop="learningTimeRequired">
+              <el-input-number v-model="addForm.learningTimeRequired" label="请输入学习时长"></el-input-number>&nbsp;min
+            </el-form-item>
+            <el-form-item label="截止日期" prop="learningDeadline">
+              <el-date-picker clearable size="small" style="width: 200px"
+                              v-model="addForm.learningDeadline"
+                              type="date"
+                              value-format="yyyy-MM-dd"
+                              placeholder="选择截止日期">
+              </el-date-picker>
+            </el-form-item>
+          </el-form>
+          <div slot="footer" class="dialog-footer">
+            <el-button type="primary" @click="submitAddPlan">确 定</el-button>
+            <el-button @click="cancelAddPlan">取 消</el-button>
+          </div>
+    </el-dialog>
+    <el-dialog :title="seePlanTitle" :visible.sync="seePlanOpen" width="60%" append-to-body>
+      <el-table :data="learningList" border>
+        <el-table-column label="学员姓名" align="center" prop="nickName" />
+        <el-table-column label="状态" align="center" prop="learningStatus" :formatter="learningStatusFormat"/>
+        <el-table-column label="规定学习时长(min)" width="150" align="center" prop="learningTimeRequired">
+          <template slot-scope="scope">
+            <span v-if="!scope.row.isEdit">{{scope.row.learningTimeRequired}}</span>
+            <span v-if="scope.row.isEdit"><el-input v-model="scope.row.learningTimeRequired"/></span>
+          </template>
+        </el-table-column>
+        <el-table-column label="累计学习时长(min)" width="150" align="center" prop="learningTimeStudied">
+          <template slot-scope="scope">
+            {{ scope.row.learningTimeStudied == null ? "-" : scope.row.learningTimeStudied }}
+          </template>
+        </el-table-column>
+        <el-table-column label="进度" align="center" prop="learningProgress">
+          <template slot-scope="scope">
+            {{ scope.row.learningProgress == null ? "-" : scope.row.learningProgress }}
+          </template>
+        </el-table-column>
+        <el-table-column label="截止日期" align="center" prop="learningDeadline" width="160">
+          <template slot-scope="scope">
+            <span v-if="!scope.row.isEdit">{{ parseTime(scope.row.learningDeadline, '{y}-{m}-{d}') }}</span>
+            <span v-if="scope.row.isEdit">
+              <el-date-picker
+                size="small"
+                style="width: 130px"
+                v-model="scope.row.learningDeadline"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="选择截止日期">
+            </el-date-picker>
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" fixed="right" width="120" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdateLearning(scope.row)"
+              v-if="!scope.row.isEdit"
+              v-hasPermi="['branch:learning:edit']"
+            >修改</el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleConfirmUpdateLearning(scope.row)"
+              v-if="scope.row.isEdit"
+              v-hasPermi="['branch:learning:edit']"
+            >确定</el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              @click="handleDeleteLearning(scope.row)"
+              v-hasPermi="['branch:learning:remove']"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { addManage, delManage, exportManage, getManage, importTemplate, listManage, updateManage } from "@/api/branch/manage";
+import {treeselect} from "@/api/system/dept";
+import {getToken} from "@/utils/auth";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import {delFile, listFile} from "@/api/branch/file";
+import {delManageFile} from "@/api/branch/manage";
+import {listUserNoPage} from "@/api/system/user";
+import { addPlan, listLearning, getLearning, delLearning, addLearning, updateLearning } from "@/api/branch/learning";
+
+export default {
+  name: "StudyPlan",
+  components: {Treeselect},
+  data() {
+    return {
+      file: {
+        id: null,
+        open: false,
+        fileList: [],
+        dataList: [],
+        doc: {
+          file: "",
+          // 是否显示弹出层(报告附件)
+          open: false,
+          // 弹出层标题(报告附件)
+          title: "",
+          // 是否禁用上传
+          isUploading: false,
+          // 设置上传的请求头部
+          headers: {Authorization: "Bearer " + getToken()},
+          // 上传的地址
+          tableId: 0,
+          url: process.env.VUE_APP_BASE_API + "/branch/file/uploadFile",
+        },
+      },
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 支部党课学习资料管理表格数据
+      manageList: [],
+      // 弹出层标题
+      title: "",
+      addPlanTitle: "",
+      seePlanTitle: "",
+      // 部门树选项
+      deptOptions: [],
+      clientHeight: 300,
+      // 是否显示弹出层
+      open: false,
+      addPlanOpen: false,
+      seePlanOpen: false,
+      // 主键id字典
+      manageIdOptions: [],
+      // 月度字典
+      monthlyOptions: [],
+      // 年份字典
+      yearOptions: [],
+      // 课件描述字典
+      describeOptions: [],
+      // 备注字典
+      remarksOptions: [],
+      // 删除标志字典
+      delFlagOptions: [],
+      // 创建者字典
+      createByOptions: [],
+      // 创建时间字典
+      createTimeOptions: [],
+      // 更新者字典
+      updateByOptions: [],
+      // 更新时间字典
+      updateTimeOptions: [],
+      // 部门id字典
+      deptIdOptions: [],
+      // 附件id字典
+      filesIdOptions: [],
+      // 用户导入参数
+      upload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 设置上传的请求头部
+        headers: {Authorization: "Bearer " + getToken()},
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/branch/manage/importData"
+      },
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 20,
+        manageId: null,
+        monthly: null,
+        year: null,
+        monthYear: new Date(),
+        describe: null,
+        remarks: null,
+        deptId: null,
+        filesId: null,
+      },
+      planQueryParams: {
+        fileId: null
+      },
+      // 表单参数
+      form: {},
+      addForm: {
+        fileId: null,
+        userIds: [],
+        learningTimeRequired: 60,
+        learningDeadline: null
+      },
+      // 表单校验
+      rules: {
+        date: [
+          {required: true, message: "月度不能为空", trigger: "blur"}
+        ],
+        deptId: [
+          {required: true, message: "归属部门不能为空", trigger: "blur"}
+        ],
+      },
+      addRules: {
+        userIds: [
+          {required: true, message: "学员不能为空", trigger: "blur"}
+        ],
+        learningTimeRequired: [
+          {required: true, message: "学习时长不能为空", trigger: "blur"}
+        ],
+        learningDeadline: [
+          {required: true, message: "截止日期不能为空", trigger: "blur"}
+        ],
+      },
+      // 用户列表
+      userList: [],
+      data: [],
+      // 学习计划表格数据
+      learningList: [],
+      // 状态字典
+      learningStatusOptions: [],
+    };
+  },
+  watch: {
+    // 根据名称筛选部门树
+    deptName(val) {
+      this.$refs.tree.filter(val);
+    }
+  },
+  created() {
+    this.getDicts("learning_status").then(response => {
+      this.learningStatusOptions = response.data;
+    });
+    //设置表格高度对应屏幕高度
+    this.$nextTick(() => {
+      this.clientHeight = document.body.clientHeight - 270
+    })
+    this.getList();
+    this.getTreeselect();
+    this.getUserList();
+  },
+  methods: {
+    // 状态字典翻译
+    learningStatusFormat(row, column) {
+      return this.selectDictLabel(this.learningStatusOptions, row.learningStatus);
+    },
+    /** 修改按钮操作 */
+    handleUpdateLearning(row) {
+      row.isEdit = true;
+    },
+    handleConfirmUpdateLearning(row) {
+      row.isEdit = false;
+      updateLearning(row).then(response => {
+        this.$modal.msgSuccess("修改成功");
+      });
+    },
+    /** 删除按钮操作 */
+    handleDeleteLearning(row) {
+      const learningIds = row.learningId || this.ids;
+      this.$confirm('是否确认删除?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return delLearning(learningIds);
+      }).then(() => {
+        listLearning(this.planQueryParams).then(response => {
+          this.learningList = response.data;
+          this.learningList.forEach(function (element) {
+            element.isEdit = false;
+          });
+        });
+        this.$modal.msgSuccess("删除成功");
+      })
+    },
+    cancelAddPlan() {
+      this.addPlanOpen = false;
+      this.resetAddPlan();
+    },
+    submitAddPlan() {
+      this.$refs["addForm"].validate(valid => {
+        if (valid) {
+          addPlan(this.addForm).then(response => {
+            this.$modal.msgSuccess("新增成功");
+            this.addPlanOpen = false;
+            this.getList();
+          });
+        }
+      });
+    },
+    resetAddPlan() {
+      this.addForm = {
+        userIds: [],
+        learningTimeRequired: 60,
+        learningDeadline: null
+      };
+    },
+    /** 查询用户列表 */
+    getUserList() {
+      listUserNoPage().then(response => {
+        let rows = response.data;
+        let userList = [];
+        for (let i = 0; i < rows.length; i++) {
+          if (rows[i].userName != "admin") {
+            let user = {
+              key: rows[i].userId,
+              label: rows[i].nickName,
+              disabled: false
+            };
+            userList.push(user);
+          }
+        }
+        this.data = userList;
+      });
+    },
+    handleAddPlan(row) {
+      this.addForm.fileId = row.id;
+      this.addPlanTitle = "添加计划(" + row.name + ")";
+      this.addPlanOpen = true;
+    },
+    handleSeePlan(row) {
+      this.planQueryParams.fileId = row.id;
+      listLearning(this.planQueryParams).then(response => {
+        response.data.forEach(function (element) {
+          element.isEdit = false;
+        });
+        this.learningList = response.data;
+      });
+      this.seePlanTitle = "查看计划(" + row.name + ")";
+      this.seePlanOpen = true;
+    },
+    handleExportPlan(row) {
+      this.planQueryParams.fileId = row.id;
+      this.download('branch/learning/export', {
+        ...this.planQueryParams
+      }, `签名表_${new Date().getTime()}.xlsx`)
+    },
+    handleSee(url) {
+      window.open(process.env.VUE_APP_BASE_API + url);
+    },
+    handleFileDelete(id) {
+      this.$confirm('是否确认删除?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return delFile(id);
+      }).then(() => {
+        this.getFileList();
+        this.msgSuccess("删除成功");
+      })
+    },
+    //附件上传中处理
+    handleFileDocProgress(event, file, fileList) {
+      this.file.doc.file = file;
+    },
+    //附件上传成功处理
+    handleFileDocSuccess(response, file, fileList) {
+      updateManage({filesId: response.data, manageId: this.file.id}).then(response => {
+        this.$modal.msgSuccess("上传成功");
+        this.getFileList();
+        this.$refs.doc.clearFiles();
+      });
+    },
+    openFileDialog(row) {
+      this.file.open = true;
+      this.file.id = row.manageId;
+      this.file.doc.tableId = row.manageId;
+      this.getFileList(row.manageId);
+    },
+    getFileList() {
+      listFile({tableId: this.file.doc.tableId, tableName: 'branchManage'}).then(res => {
+        this.file.dataList = res.data
+      })
+    },
+    /** 查询支部党课学习资料管理列表 */
+    getList() {
+      this.file.dataList = [];
+      this.loading = true;
+      listManage({
+        "monthly": this.queryParams.monthYear.getMonth() + 1,
+        "year": this.queryParams.monthYear.getFullYear(),
+      }).then(response => {
+        if (response.rows.length != 0) {
+          listFile({tableId: response.rows[0].manageId, tableName: 'branchManage'}).then(res => {
+            this.file.dataList = res.data
+          })
+        }
+        this.loading = false;
+      });
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      treeselect().then(response => {
+        this.deptOptions = response.data;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        manageId: null,
+        monthly: null,
+        year: null,
+        describe: null,
+        remarks: null,
+        delFlag: null,
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null,
+        deptId: null,
+        filesId: null,
+        date : new Date(),
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.manageId)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加支部党课学习资料管理";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const manageId = row.manageId || this.ids
+      getManage(manageId).then(response => {
+        this.form = response.data;
+        this.form.date=new Date();
+        this.form.date.setMonth(response.data.monthly - 1);
+        this.form.date.setFullYear(response.data.year);
+        this.open = true;
+        this.title = "修改支部党课学习资料管理";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.form.year = this.form.date.getFullYear();
+      this.form.monthly = (this.form.date.getMonth() + 1);
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.manageId != null) {
+            updateManage(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addManage(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const manageIds = row.manageId || this.ids;
+      this.$confirm('是否确认删除?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return delManage(manageIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      })
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有支部党课学习资料管理数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return exportManage(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+      })
+    },
+    /** 导入按钮操作 */
+    handleImport() {
+      this.upload.title = "用户导入";
+      this.upload.open = true;
+    },
+    /** 下载模板操作 */
+    importTemplate() {
+      importTemplate().then(response => {
+        this.download(response.msg);
+      });
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(response.msg, "导入结果", {dangerouslyUseHTMLString: true});
+      this.getList();
+    },
+    // 提交上传文件
+    submitFileForm() {
+      this.$refs.upload.submit();
+    }
+  }
+};
+</script>
+
+<style>
+/** 文本换行符处理 */
+.el-table .cell {
+  white-space: pre-wrap;
+}
+
+/** textarea字体 */
+textarea {
+  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
+}
+</style>