Compare commits
7 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
d7b44a7f7f | 10 months ago |
|
|
dd9d865edd | 10 months ago |
|
|
f4d593e992 | 10 months ago |
|
|
c1ae1ffb5e | 10 months ago |
|
|
800c4c2a0d | 10 months ago |
|
|
713ce39439 | 10 months ago |
|
|
811ea95957 | 10 months ago |
@ -0,0 +1,56 @@
|
||||
package com.yf.exam.modules.qu.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
///**
|
||||
// * <p>
|
||||
// * 候选答案请求类
|
||||
// * </p>
|
||||
// *
|
||||
// * @author 聪明笨狗
|
||||
// * @since 2020-05-25 13:23
|
||||
// */
|
||||
@Data
|
||||
@ApiModel(value="候选答案", description="候选答案")
|
||||
public class QuAnswerDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// /**
|
||||
// * 答案的唯一标识ID
|
||||
// */
|
||||
@ApiModelProperty(value = "答案ID", required=true)
|
||||
private String id;
|
||||
|
||||
// /**
|
||||
// * 所属问题的唯一标识ID
|
||||
// */
|
||||
@ApiModelProperty(value = "问题ID", required=true)
|
||||
private String quId;
|
||||
|
||||
// /**
|
||||
// * 表示该答案是否正确
|
||||
// */
|
||||
@ApiModelProperty(value = "是否正确", required=true)
|
||||
private Boolean isRight;
|
||||
|
||||
// /**
|
||||
// * 选项的图片URL
|
||||
// */
|
||||
@ApiModelProperty(value = "选项图片", required=true)
|
||||
private String image;
|
||||
|
||||
// /**
|
||||
// * 答案的具体内容
|
||||
// */
|
||||
@ApiModelProperty(value = "答案内容", required=true)
|
||||
private String content;
|
||||
|
||||
// /**
|
||||
// * 对该答案的分析说明
|
||||
// */
|
||||
@ApiModelProperty(value = "答案分析", required=true)
|
||||
private String analysis;
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.yf.exam.modules.qu.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
///**
|
||||
// * <p>
|
||||
// * 试题题库请求类
|
||||
// * </p>
|
||||
// *
|
||||
// * @author 聪明笨狗
|
||||
// * @since 2020-05-25 13:23
|
||||
// */
|
||||
@Data
|
||||
@ApiModel(value="试题题库", description="试题题库")
|
||||
public class QuRepoDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// /**
|
||||
// * 题库记录的唯一标识ID
|
||||
// */
|
||||
private String id;
|
||||
|
||||
// /**
|
||||
// * 关联试题的唯一标识ID
|
||||
// */
|
||||
@ApiModelProperty(value = "试题", required=true)
|
||||
private String quId;
|
||||
|
||||
// /**
|
||||
// * 归属题库的唯一标识ID
|
||||
// */
|
||||
@ApiModelProperty(value = "归属题库", required=true)
|
||||
private String repoId;
|
||||
|
||||
// /**
|
||||
// * 试题的类型
|
||||
// */
|
||||
@ApiModelProperty(value = "题目类型", required=true)
|
||||
private Integer quType;
|
||||
|
||||
// /**
|
||||
// * 试题在题库中的排序顺序
|
||||
// */
|
||||
@ApiModelProperty(value = "排序", required=true)
|
||||
private Integer sort;
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.yf.exam.modules.qu.dto.ext;
|
||||
|
||||
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
|
||||
import com.yf.exam.modules.qu.dto.QuDTO;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
// * <p>
|
||||
// * 问题题目请求类
|
||||
// * </p>
|
||||
// *
|
||||
// * @author 聪明笨狗
|
||||
// * @since 2020-05-25 13:23
|
||||
// */
|
||||
@Data
|
||||
@ApiModel(value="问题题目详情", description="问题题目详情")
|
||||
public class QuDetailDTO extends QuDTO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// /**
|
||||
// * 备选项列表
|
||||
// */
|
||||
@ApiModelProperty(value = "备选项列表", required=true)
|
||||
private List<QuAnswerDTO> answerList;
|
||||
|
||||
// /**
|
||||
// * 题库ID列表
|
||||
// */
|
||||
@ApiModelProperty(value = "题库列表", required=true)
|
||||
private List<String> repoIds;
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.yf.exam.modules.qu.dto.request;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
// * <p>
|
||||
// * 题目查询请求类
|
||||
// * </p>
|
||||
// *
|
||||
// * @author 聪明笨狗
|
||||
// * @since 2020-05-25 13:23
|
||||
// */
|
||||
@Data
|
||||
@ApiModel(value="题目查询请求类", description="题目查询请求类")
|
||||
public class QuQueryReqDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// /**
|
||||
// * 题目类型
|
||||
// */
|
||||
@ApiModelProperty(value = "题目类型")
|
||||
private Integer quType;
|
||||
|
||||
// /**
|
||||
// * 归属题库ID列表
|
||||
// */
|
||||
@ApiModelProperty(value = "归属题库")
|
||||
private List<String> repoIds;
|
||||
|
||||
// /**
|
||||
// * 题目内容的关键字
|
||||
// */
|
||||
@ApiModelProperty(value = "题目内容")
|
||||
private String content;
|
||||
|
||||
// /**
|
||||
// * 需要排除的题目ID列表
|
||||
// */
|
||||
@ApiModelProperty(value = "排除ID列表")
|
||||
private List<String> excludes;
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.yf.exam.modules.qu.entity;
|
||||
|
||||
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 com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 问题题目实体类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
@Data
|
||||
@TableName("el_qu")
|
||||
public class Qu extends Model<Qu> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// /**
|
||||
// * 题目ID
|
||||
// */
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
// /**
|
||||
// * 题目类型
|
||||
// */
|
||||
@TableField("qu_type")
|
||||
private Integer quType;
|
||||
|
||||
// /**
|
||||
// * 1普通,2较难
|
||||
// */
|
||||
private Integer level;
|
||||
|
||||
// /**
|
||||
// * 题目图片
|
||||
// */
|
||||
private String image;
|
||||
|
||||
// /**
|
||||
// * 题目内容
|
||||
// */
|
||||
private String content;
|
||||
|
||||
// /**
|
||||
// * 创建时间
|
||||
// */
|
||||
@TableField("create_time")
|
||||
private Date createTime;
|
||||
|
||||
// /**
|
||||
// * 更新时间
|
||||
// */
|
||||
@TableField("update_time")
|
||||
private Date updateTime;
|
||||
|
||||
// /**
|
||||
// * 题目备注
|
||||
// */
|
||||
private String remark;
|
||||
|
||||
// /**
|
||||
// * 整题解析
|
||||
// */
|
||||
private String analysis;
|
||||
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package com.yf.exam.modules.qu.entity;
|
||||
|
||||
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 com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import lombok.Data;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 候选答案实体类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
@Data
|
||||
@TableName("el_qu_answer")
|
||||
public class QuAnswer extends Model<QuAnswer> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// /**
|
||||
// * 答案ID
|
||||
// */
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
// /**
|
||||
// * 问题ID
|
||||
// */
|
||||
@TableField("qu_id")
|
||||
private String quId;
|
||||
|
||||
// /**
|
||||
// * 是否正确
|
||||
// */
|
||||
@TableField("is_right")
|
||||
private Boolean isRight;
|
||||
|
||||
// /**
|
||||
// * 选项图片
|
||||
// */
|
||||
private String image;
|
||||
|
||||
// /**
|
||||
// * 答案内容
|
||||
// */
|
||||
private String content;
|
||||
|
||||
|
||||
/**
|
||||
* 答案分析
|
||||
*/
|
||||
private String analysis;
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.yf.exam.modules.qu.entity;
|
||||
|
||||
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 com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import lombok.Data;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 试题题库实体类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
@Data
|
||||
@TableName("el_qu_repo")
|
||||
public class QuRepo extends Model<QuRepo> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
// /**
|
||||
// * 试题
|
||||
// */
|
||||
@TableField("qu_id")
|
||||
private String quId;
|
||||
|
||||
// /**
|
||||
// * 归属题库
|
||||
// */
|
||||
@TableField("repo_id")
|
||||
private String repoId;
|
||||
|
||||
// /**
|
||||
// * 题目类型
|
||||
// */
|
||||
@TableField("qu_type")
|
||||
private Integer quType;
|
||||
|
||||
// /**
|
||||
// * 排序
|
||||
// */
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.yf.exam.modules.qu.enums;
|
||||
|
||||
|
||||
///**
|
||||
// * 题目类型
|
||||
// * @author bool
|
||||
// * @date 2019-10-30 13:11
|
||||
// */
|
||||
public interface QuType {
|
||||
|
||||
// /**
|
||||
// * 单选题
|
||||
// */
|
||||
Integer RADIO = 1;
|
||||
|
||||
// /**
|
||||
// * 多选题
|
||||
// */
|
||||
Integer MULTI = 2;
|
||||
|
||||
// /**
|
||||
// * 判断题
|
||||
// */
|
||||
Integer JUDGE = 3;
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.yf.exam.modules.qu.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yf.exam.modules.qu.entity.QuAnswer;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 候选答案Mapper
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
public interface QuAnswerMapper extends BaseMapper<QuAnswer> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.yf.exam.modules.qu.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yf.exam.modules.qu.dto.QuDTO;
|
||||
import com.yf.exam.modules.qu.dto.export.QuExportDTO;
|
||||
import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO;
|
||||
import com.yf.exam.modules.qu.entity.Qu;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 问题题目Mapper
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
public interface QuMapper extends BaseMapper<Qu> {
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 随机抽取题库的数据
|
||||
// * @param repoId
|
||||
// * @param quType
|
||||
// * @param level
|
||||
// * @param excludes 要排除的ID列表
|
||||
// * @param size
|
||||
// * @return
|
||||
// */
|
||||
List<Qu> listByRandom(@Param("repoId") String repoId,
|
||||
@Param("quType") Integer quType,
|
||||
@Param("excludes") List<String> excludes,
|
||||
@Param("size") Integer size);
|
||||
|
||||
// /**
|
||||
// * 查找导出列表
|
||||
// * @param query
|
||||
// * @return
|
||||
// */
|
||||
List<QuExportDTO> listForExport(@Param("query") QuQueryReqDTO query);
|
||||
|
||||
// /**
|
||||
// * 分页查找
|
||||
// * @param page
|
||||
// * @param query
|
||||
// * @return
|
||||
// */
|
||||
IPage<QuDTO> paging(Page page, @Param("query") QuQueryReqDTO query);
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.yf.exam.modules.qu.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yf.exam.modules.qu.entity.QuRepo;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 试题题库Mapper
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
public interface QuRepoMapper extends BaseMapper<QuRepo> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.yf.exam.modules.qu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yf.exam.core.api.dto.PagingReqDTO;
|
||||
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
|
||||
import com.yf.exam.modules.qu.entity.QuAnswer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 候选答案业务类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
public interface QuAnswerService extends IService<QuAnswer> {
|
||||
|
||||
// /**
|
||||
// * 分页查询数据
|
||||
// * @param reqDTO
|
||||
// * @return
|
||||
// */
|
||||
IPage<QuAnswerDTO> paging(PagingReqDTO<QuAnswerDTO> reqDTO);
|
||||
//
|
||||
// /**
|
||||
// * 根据题目ID查询答案并随机
|
||||
// * @param quId
|
||||
// * @return
|
||||
// */
|
||||
List<QuAnswer> listAnswerByRandom(String quId);
|
||||
|
||||
// /**
|
||||
// * 根据问题查找答案
|
||||
// * @param quId
|
||||
// * @return
|
||||
// */
|
||||
List<QuAnswerDTO> listByQu(String quId);
|
||||
|
||||
// /**
|
||||
// * 保存试题
|
||||
// * @param quId
|
||||
// * @param list
|
||||
// */
|
||||
void saveAll(String quId, List<QuAnswerDTO> list);
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package com.yf.exam.modules.qu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yf.exam.core.api.dto.PagingReqDTO;
|
||||
import com.yf.exam.modules.qu.dto.QuRepoDTO;
|
||||
import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO;
|
||||
import com.yf.exam.modules.qu.entity.QuRepo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 试题题库业务类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
public interface QuRepoService extends IService<QuRepo> {
|
||||
|
||||
// /**
|
||||
// * 分页查询数据
|
||||
// * @param reqDTO
|
||||
// * @return
|
||||
// */
|
||||
IPage<QuRepoDTO> paging(PagingReqDTO<QuRepoDTO> reqDTO);
|
||||
|
||||
// /**
|
||||
// * 保存全部列表
|
||||
// * @param quId
|
||||
// * @param quType
|
||||
// * @param ids
|
||||
// */
|
||||
void saveAll(String quId, Integer quType, List<String> ids);
|
||||
|
||||
// /**
|
||||
// * 根据问题查找题库
|
||||
// * @param quId
|
||||
// * @return
|
||||
// */
|
||||
List<String> listByQu(String quId);
|
||||
|
||||
// /**
|
||||
// * 根据题库查找题目ID列表
|
||||
// * @param repoId
|
||||
// * @param quType
|
||||
// * @param rand
|
||||
// * @return
|
||||
// */
|
||||
List<String> listByRepo(String repoId, Integer quType, boolean rand);
|
||||
|
||||
// /**
|
||||
// * 批量操作
|
||||
// * @param reqDTO
|
||||
// */
|
||||
void batchAction(QuRepoBatchReqDTO reqDTO);
|
||||
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package com.yf.exam.modules.qu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yf.exam.core.api.dto.PagingReqDTO;
|
||||
import com.yf.exam.modules.qu.dto.QuDTO;
|
||||
import com.yf.exam.modules.qu.dto.export.QuExportDTO;
|
||||
import com.yf.exam.modules.qu.dto.ext.QuDetailDTO;
|
||||
import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO;
|
||||
import com.yf.exam.modules.qu.entity.Qu;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 问题题目业务类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
public interface QuService extends IService<Qu> {
|
||||
|
||||
// /**
|
||||
// * 分页查询数据
|
||||
// * @param reqDTO
|
||||
// * @return
|
||||
// */
|
||||
IPage<QuDTO> paging(PagingReqDTO<QuQueryReqDTO> reqDTO);
|
||||
|
||||
// /**
|
||||
// * 删除试题
|
||||
// * @param ids
|
||||
// */
|
||||
void delete(List<String> ids);
|
||||
|
||||
// /**
|
||||
// * 随机抽取题库的数据
|
||||
// * @param repoId
|
||||
// * @param quType
|
||||
// * @param excludes 要排除的ID列表
|
||||
// * @param size
|
||||
// * @return
|
||||
// */
|
||||
List<Qu> listByRandom(String repoId,
|
||||
Integer quType,
|
||||
List<String> excludes,
|
||||
Integer size);
|
||||
|
||||
// /**
|
||||
// * 问题详情
|
||||
// * @param id
|
||||
// * @return
|
||||
// */
|
||||
QuDetailDTO detail(String id);
|
||||
|
||||
// /**
|
||||
// * 保存试题
|
||||
// * @param reqDTO
|
||||
// */
|
||||
void save(QuDetailDTO reqDTO);
|
||||
|
||||
// /**
|
||||
// * 查找导出列表
|
||||
// * @param query
|
||||
// * @return
|
||||
// */
|
||||
List<QuExportDTO> listForExport(QuQueryReqDTO query);
|
||||
|
||||
// /**
|
||||
// * 导入Excel
|
||||
// * @param dtoList
|
||||
// * @return
|
||||
// */
|
||||
int importExcel(List<QuExportDTO> dtoList);
|
||||
}
|
||||
@ -0,0 +1,144 @@
|
||||
package com.yf.exam.modules.qu.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yf.exam.core.api.dto.PagingReqDTO;
|
||||
import com.yf.exam.core.utils.BeanMapper;
|
||||
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
|
||||
import com.yf.exam.modules.qu.entity.QuAnswer;
|
||||
import com.yf.exam.modules.qu.mapper.QuAnswerMapper;
|
||||
import com.yf.exam.modules.qu.service.QuAnswerService;
|
||||
import com.yf.exam.modules.qu.utils.ImageCheckUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 语言设置 服务实现类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
@Service
|
||||
public class QuAnswerServiceImpl extends ServiceImpl<QuAnswerMapper, QuAnswer> implements QuAnswerService {
|
||||
|
||||
@Autowired
|
||||
private ImageCheckUtils imageCheckUtils;
|
||||
|
||||
@Override
|
||||
public IPage<QuAnswerDTO> paging(PagingReqDTO<QuAnswerDTO> reqDTO) {
|
||||
|
||||
//创建分页对象
|
||||
IPage<QuAnswer> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
|
||||
|
||||
//查询条件
|
||||
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
|
||||
|
||||
//获得数据
|
||||
IPage<QuAnswer> page = this.page(query, wrapper);
|
||||
//转换结果
|
||||
IPage<QuAnswerDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<QuAnswerDTO>>(){});
|
||||
return pageData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuAnswer> listAnswerByRandom(String quId) {
|
||||
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(QuAnswer::getQuId, quId);
|
||||
wrapper.last(" ORDER BY RAND() ");
|
||||
|
||||
return this.list(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuAnswerDTO> listByQu(String quId) {
|
||||
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(QuAnswer::getQuId, quId);
|
||||
|
||||
List<QuAnswer> list = this.list(wrapper);
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
return BeanMapper.mapList(list, QuAnswerDTO.class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 查找已存在的列表
|
||||
// * @param quId
|
||||
// * @return
|
||||
// */
|
||||
public List<String> findExistsList(String quId) {
|
||||
//返回结果
|
||||
List<String> ids = new ArrayList<>();
|
||||
|
||||
QueryWrapper<QuAnswer> wrapper = new QueryWrapper();
|
||||
wrapper.lambda().eq(QuAnswer::getQuId, quId);
|
||||
List<QuAnswer> list = this.list(wrapper);
|
||||
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
for (QuAnswer item : list) {
|
||||
ids.add(item.getId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAll(String quId, List<QuAnswerDTO> list) {
|
||||
|
||||
//最终要保存的列表
|
||||
List<QuAnswer> saveList = new ArrayList<>();
|
||||
|
||||
//已存在的标签列表
|
||||
List<String> ids = this.findExistsList(quId);
|
||||
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
for(QuAnswerDTO item: list){
|
||||
|
||||
// 校验图片地址
|
||||
imageCheckUtils.checkImage(item.getImage(), "选项图片地址错误!");
|
||||
|
||||
//标签ID
|
||||
String id = item.getId();
|
||||
QuAnswer answer = new QuAnswer();
|
||||
BeanMapper.copy(item, answer);
|
||||
answer.setQuId(quId);
|
||||
|
||||
//补全ID避免新增
|
||||
if(ids.contains(id)){
|
||||
ids.remove(id);
|
||||
}
|
||||
|
||||
saveList.add(answer);
|
||||
}
|
||||
|
||||
//保存标签列表
|
||||
if(!CollectionUtils.isEmpty(saveList)) {
|
||||
this.saveOrUpdateBatch(saveList);
|
||||
}
|
||||
|
||||
//删除已移除
|
||||
if(!ids.isEmpty()){
|
||||
this.removeByIds(ids);
|
||||
}
|
||||
}else{
|
||||
|
||||
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(QuAnswer::getQuId, quId);
|
||||
this.remove(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
package com.yf.exam.modules.qu.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yf.exam.core.api.dto.PagingReqDTO;
|
||||
import com.yf.exam.modules.qu.dto.QuRepoDTO;
|
||||
import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO;
|
||||
import com.yf.exam.modules.qu.entity.Qu;
|
||||
import com.yf.exam.modules.qu.entity.QuRepo;
|
||||
import com.yf.exam.modules.qu.mapper.QuMapper;
|
||||
import com.yf.exam.modules.qu.mapper.QuRepoMapper;
|
||||
import com.yf.exam.modules.qu.service.QuRepoService;
|
||||
import com.yf.exam.modules.repo.service.RepoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
///**
|
||||
//* <p>
|
||||
//* 语言设置 服务实现类
|
||||
//* </p>
|
||||
//*
|
||||
//* @author 聪明笨狗
|
||||
//* @since 2020-05-25 13:23
|
||||
//*/
|
||||
@Service
|
||||
public class QuRepoServiceImpl extends ServiceImpl<QuRepoMapper, QuRepo> implements QuRepoService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private QuMapper quMapper;
|
||||
|
||||
@Autowired
|
||||
private RepoService repoService;
|
||||
|
||||
@Override
|
||||
public IPage<QuRepoDTO> paging(PagingReqDTO<QuRepoDTO> reqDTO) {
|
||||
|
||||
//创建分页对象
|
||||
IPage<QuRepo> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
|
||||
|
||||
//查询条件
|
||||
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
|
||||
|
||||
//获得数据
|
||||
IPage<QuRepo> page = this.page(query, wrapper);
|
||||
//转换结果
|
||||
IPage<QuRepoDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<QuRepoDTO>>(){});
|
||||
return pageData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAll(String quId, Integer quType, List<String> ids) {
|
||||
// 先删除
|
||||
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(QuRepo::getQuId, quId);
|
||||
this.remove(wrapper);
|
||||
|
||||
// 保存全部
|
||||
if(!CollectionUtils.isEmpty(ids)){
|
||||
List<QuRepo> list = new ArrayList<>();
|
||||
for(String id: ids){
|
||||
QuRepo ref = new QuRepo();
|
||||
ref.setQuId(quId);
|
||||
ref.setRepoId(id);
|
||||
ref.setQuType(quType);
|
||||
list.add(ref);
|
||||
}
|
||||
this.saveBatch(list);
|
||||
|
||||
|
||||
for(String id: ids){
|
||||
this.sortRepo(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listByQu(String quId) {
|
||||
// 先删除
|
||||
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(QuRepo::getQuId, quId);
|
||||
List<QuRepo> list = this.list(wrapper);
|
||||
List<String> ids = new ArrayList<>();
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
for(QuRepo item: list){
|
||||
ids.add(item.getRepoId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listByRepo(String repoId, Integer quType, boolean rand) {
|
||||
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda()
|
||||
.eq(QuRepo::getRepoId, repoId);
|
||||
|
||||
if(quType!=null){
|
||||
wrapper.lambda().eq(QuRepo::getQuType, quType);
|
||||
}
|
||||
|
||||
if(rand){
|
||||
wrapper.orderByAsc(" RAND() ");
|
||||
}else{
|
||||
wrapper.lambda().orderByAsc(QuRepo::getSort);
|
||||
}
|
||||
|
||||
List<QuRepo> list = this.list(wrapper);
|
||||
List<String> ids = new ArrayList<>();
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
for(QuRepo item: list){
|
||||
ids.add(item.getQuId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchAction(QuRepoBatchReqDTO reqDTO) {
|
||||
|
||||
// 移除的
|
||||
if(reqDTO.getRemove()!=null && reqDTO.getRemove()){
|
||||
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda()
|
||||
.in(QuRepo::getRepoId, reqDTO.getRepoIds())
|
||||
.in(QuRepo::getQuId, reqDTO.getQuIds());
|
||||
this.remove(wrapper);
|
||||
}else{
|
||||
|
||||
// 新增的
|
||||
for(String quId : reqDTO.getQuIds()){
|
||||
Qu q = quMapper.selectById(quId);
|
||||
this.saveAll(quId, q.getQuType(), reqDTO.getRepoIds());
|
||||
}
|
||||
}
|
||||
|
||||
for(String id: reqDTO.getRepoIds()){
|
||||
this.sortRepo(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 单个题库进行排序
|
||||
// * @param repoId
|
||||
// */
|
||||
private void sortRepo(String repoId){
|
||||
|
||||
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(QuRepo::getRepoId, repoId);
|
||||
|
||||
List<QuRepo> list = this.list(wrapper);
|
||||
if(CollectionUtils.isEmpty(list)){
|
||||
return;
|
||||
}
|
||||
|
||||
int sort = 1;
|
||||
for(QuRepo item: list){
|
||||
item.setSort(sort);
|
||||
sort++;
|
||||
}
|
||||
this.updateBatchById(list);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.yf.exam.modules.qu.utils;
|
||||
|
||||
import com.yf.exam.ability.upload.config.UploadConfig;
|
||||
import com.yf.exam.core.exception.ServiceException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ImageCheckUtils {
|
||||
|
||||
@Autowired
|
||||
private UploadConfig conf;
|
||||
|
||||
// /**
|
||||
// * 进行图片校验!
|
||||
// * @param image
|
||||
// * @param throwMsg
|
||||
// */
|
||||
public void checkImage(String image, String throwMsg) {
|
||||
|
||||
if(StringUtils.isBlank(image)){
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验图片地址
|
||||
if(!image.startsWith(conf.getUrl())){
|
||||
throw new ServiceException(throwMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import screenfull from 'screenfull'
|
||||
|
||||
export default {
|
||||
name: 'Screenfull',
|
||||
data() {
|
||||
return {
|
||||
isFullscreen: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.destroy()
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
if (!screenfull.enabled) {
|
||||
this.$message({
|
||||
message: 'you browser can not work',
|
||||
type: 'warning'
|
||||
})
|
||||
return false
|
||||
}
|
||||
screenfull.toggle()
|
||||
},
|
||||
change() {
|
||||
this.isFullscreen = screenfull.isFullscreen
|
||||
},
|
||||
init() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.on('change', this.change)
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.off('change', this.change)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.screenfull-svg {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
fill: #5a5e66;;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<el-dropdown trigger="click" @command="handleSetSize">
|
||||
<div>
|
||||
<svg-icon class-name="size-icon" icon-class="size" />
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">
|
||||
{{
|
||||
item.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sizeOptions: [
|
||||
{ label: '默认', value: 'default' },
|
||||
{ label: '中等', value: 'medium' },
|
||||
{ label: '小', value: 'small' },
|
||||
{ label: '极小', value: 'mini' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
size() {
|
||||
return this.$store.getters.size
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSetSize(size) {
|
||||
this.$ELEMENT.size = size
|
||||
this.$store.dispatch('app/setSize', size)
|
||||
this.refreshView()
|
||||
this.$message({
|
||||
message: '字体切换成功!',
|
||||
type: 'success'
|
||||
})
|
||||
},
|
||||
refreshView() {
|
||||
// In order to make the cached page re-rendered
|
||||
this.$store.dispatch('tagsView/delAllCachedViews', this.$route)
|
||||
|
||||
const { fullPath } = this.$route
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$router.replace({
|
||||
path: '/redirect' + fullPath
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||
<use :href="iconName" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
|
||||
import { isExternal } from '@/utils/validate'
|
||||
|
||||
export default {
|
||||
name: 'SvgIcon',
|
||||
props: {
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isExternal() {
|
||||
return isExternal(this.iconClass)
|
||||
},
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`
|
||||
},
|
||||
svgClass() {
|
||||
if (this.className) {
|
||||
return 'svg-icon ' + this.className
|
||||
} else {
|
||||
return 'svg-icon'
|
||||
}
|
||||
},
|
||||
styleExternalIcon() {
|
||||
return {
|
||||
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
|
||||
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.svg-external-icon {
|
||||
background-color: currentColor;
|
||||
mask-size: cover!important;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<el-color-picker
|
||||
v-model="theme"
|
||||
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
|
||||
class="theme-picker"
|
||||
popper-class="theme-picker-dropdown"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const version = require('element-ui/package.json').version // element-ui version from node_modules
|
||||
const ORIGINAL_THEME = '#409EFF' // default color
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chalk: '', // content of theme-chalk css
|
||||
theme: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
defaultTheme() {
|
||||
return this.$store.state.settings.theme
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
defaultTheme: {
|
||||
handler: function(val, oldVal) {
|
||||
this.theme = val
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
async theme(val) {
|
||||
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
|
||||
if (typeof val !== 'string') return
|
||||
const themeCluster = this.getThemeCluster(val.replace('#', ''))
|
||||
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
|
||||
console.log(themeCluster, originalCluster)
|
||||
|
||||
const $message = this.$message({
|
||||
message: ' Compiling the theme',
|
||||
customClass: 'theme-message',
|
||||
type: 'success',
|
||||
duration: 0,
|
||||
iconClass: 'el-icon-loading'
|
||||
})
|
||||
|
||||
const getHandler = (variable, id) => {
|
||||
return () => {
|
||||
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
|
||||
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
|
||||
|
||||
let styleTag = document.getElementById(id)
|
||||
if (!styleTag) {
|
||||
styleTag = document.createElement('style')
|
||||
styleTag.setAttribute('id', id)
|
||||
document.head.appendChild(styleTag)
|
||||
}
|
||||
styleTag.innerText = newStyle
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.chalk) {
|
||||
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
|
||||
await this.getCSSString(url, 'chalk')
|
||||
}
|
||||
|
||||
const chalkHandler = getHandler('chalk', 'chalk-style')
|
||||
|
||||
chalkHandler()
|
||||
|
||||
const styles = [].slice.call(document.querySelectorAll('style'))
|
||||
.filter(style => {
|
||||
const text = style.innerText
|
||||
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
|
||||
})
|
||||
styles.forEach(style => {
|
||||
const { innerText } = style
|
||||
if (typeof innerText !== 'string') return
|
||||
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
|
||||
})
|
||||
|
||||
this.$emit('change', val)
|
||||
|
||||
$message.close()
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateStyle(style, oldCluster, newCluster) {
|
||||
let newStyle = style
|
||||
oldCluster.forEach((color, index) => {
|
||||
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
|
||||
})
|
||||
return newStyle
|
||||
},
|
||||
|
||||
getCSSString(url, variable) {
|
||||
return new Promise(resolve => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
xhr.open('GET', url)
|
||||
xhr.send()
|
||||
})
|
||||
},
|
||||
|
||||
getThemeCluster(theme) {
|
||||
const tintColor = (color, tint) => {
|
||||
let red = parseInt(color.slice(0, 2), 16)
|
||||
let green = parseInt(color.slice(2, 4), 16)
|
||||
let blue = parseInt(color.slice(4, 6), 16)
|
||||
|
||||
if (tint === 0) { // when primary color is in its rgb space
|
||||
return [red, green, blue].join(',')
|
||||
} else {
|
||||
red += Math.round(tint * (255 - red))
|
||||
green += Math.round(tint * (255 - green))
|
||||
blue += Math.round(tint * (255 - blue))
|
||||
|
||||
red = red.toString(16)
|
||||
green = green.toString(16)
|
||||
blue = blue.toString(16)
|
||||
|
||||
return `#${red}${green}${blue}`
|
||||
}
|
||||
}
|
||||
|
||||
const shadeColor = (color, shade) => {
|
||||
let red = parseInt(color.slice(0, 2), 16)
|
||||
let green = parseInt(color.slice(2, 4), 16)
|
||||
let blue = parseInt(color.slice(4, 6), 16)
|
||||
|
||||
red = Math.round((1 - shade) * red)
|
||||
green = Math.round((1 - shade) * green)
|
||||
blue = Math.round((1 - shade) * blue)
|
||||
|
||||
red = red.toString(16)
|
||||
green = green.toString(16)
|
||||
blue = blue.toString(16)
|
||||
|
||||
return `#${red}${green}${blue}`
|
||||
}
|
||||
|
||||
const clusters = [theme]
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
|
||||
}
|
||||
clusters.push(shadeColor(theme, 0.1))
|
||||
return clusters
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.theme-message,
|
||||
.theme-picker-dropdown {
|
||||
z-index: 99999 !important;
|
||||
}
|
||||
|
||||
.theme-picker .el-color-picker__trigger {
|
||||
height: 26px !important;
|
||||
width: 26px !important;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.theme-picker-dropdown .el-color-dropdown__link-btn {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,78 @@
|
||||
// Inspired by https://github.com/Inndy/vue-clipboard2
|
||||
const Clipboard = require('clipboard')
|
||||
if (!Clipboard) {
|
||||
throw new Error('you should npm install `clipboard` --save at first ')
|
||||
}
|
||||
|
||||
export default {
|
||||
// /**
|
||||
// * 当指令绑定到元素时调用
|
||||
// * @param {Element} el 被绑定的元素
|
||||
// * @param {Object} binding 包含指令信息的对象
|
||||
// */
|
||||
bind(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
// 存储成功回调函数
|
||||
el._v_clipboard_success = binding.value
|
||||
} else if (binding.arg === 'error') {
|
||||
// 存储错误回调函数
|
||||
el._v_clipboard_error = binding.value
|
||||
} else {
|
||||
// 创建Clipboard实例并配置其行为
|
||||
const clipboard = new Clipboard(el, {
|
||||
text() { return binding.value }, // 返回需要复制的文本
|
||||
action() { return binding.arg === 'cut' ? 'cut' : 'copy' } // 根据指令参数决定是剪切还是复制
|
||||
})
|
||||
// 监听复制成功事件
|
||||
clipboard.on('success', e => {
|
||||
const callback = el._v_clipboard_success
|
||||
callback && callback(e) // 调用成功回调函数
|
||||
})
|
||||
// 监听复制错误事件
|
||||
clipboard.on('error', e => {
|
||||
const callback = el._v_clipboard_error
|
||||
callback && callback(e) // 调用错误回调函数
|
||||
})
|
||||
// 将Clipboard实例存储在元素上
|
||||
el._v_clipboard = clipboard
|
||||
}
|
||||
},
|
||||
|
||||
// /**
|
||||
// * 当指令所在的模板更新时调用
|
||||
// * @param {Element} el 被绑定的元素
|
||||
// * @param {Object} binding 包含指令信息的对象
|
||||
// */
|
||||
update(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
// 更新成功回调函数
|
||||
el._v_clipboard_success = binding.value
|
||||
} else if (binding.arg === 'error') {
|
||||
// 更新错误回调函数
|
||||
el._v_clipboard_error = binding.value
|
||||
} else {
|
||||
// 更新Clipboard实例的文本和行为
|
||||
el._v_clipboard.text = function() { return binding.value }
|
||||
el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||
}
|
||||
},
|
||||
|
||||
// /**
|
||||
// * 当指令与元素解绑时调用
|
||||
// * @param {Element} el 被绑定的元素
|
||||
// * @param {Object} binding 包含指令信息的对象
|
||||
// */
|
||||
unbind(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
// 删除成功回调函数
|
||||
delete el._v_clipboard_success
|
||||
} else if (binding.arg === 'error') {
|
||||
// 删除错误回调函数
|
||||
delete el._v_clipboard_error
|
||||
} else {
|
||||
// 销毁Clipboard实例并删除相关属性
|
||||
el._v_clipboard.destroy()
|
||||
delete el._v_clipboard
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
.waves-ripple {
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
background-clip: padding-box;
|
||||
pointer-events: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-transform: scale(0);
|
||||
-ms-transform: scale(0);
|
||||
transform: scale(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.waves-ripple.z-active {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(2);
|
||||
-ms-transform: scale(2);
|
||||
transform: scale(2);
|
||||
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
||||
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
||||
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
|
||||
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
|
||||
}
|
||||
Loading…
Reference in new issue