Update docs: 将类,api方法使用文档注释规范化开发

develop
王奕辉 2 days ago
parent f36eed33fd
commit c9c6dc27ee

@ -12,12 +12,21 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
*
*/
@Configuration
public class IntercepterConfig implements WebMvcConfigurer {
/**
* LoginInterceptor
*/
@Autowired
private LoginInterceptor loginInterceptor;
/**
*
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 拦截user下的api

@ -7,12 +7,22 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
/**
* Servlet
*/
@Configuration
public class ServletConfig {
/**
* WebServerFactoryCustomizer beanWeb
* @return WebServerFactoryCustomizer<ConfigurableWebServerFactory>
*/
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer() {
// 返回一个lambda表达式用于自定义Web服务器的工厂
return factory -> {
// 创建一个ErrorPage对象用于处理404错误
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/");
// 将ErrorPage对象添加到Web服务器的工厂中
factory.addErrorPages(error404Page);
};
}

@ -23,12 +23,18 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* Swagger2
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
/**
* Docket bean
* @return Docket
*/
@Bean
public Docket api() {
ParameterBuilder ticketPar = new ParameterBuilder();
List<Parameter> pars = new ArrayList<>();
ticketPar.name("Access-Token").description("Rest接口权限认证token,无需鉴权可为空")
@ -48,6 +54,10 @@ public class Swagger2Config {
.globalOperationParameters(pars);
}
/**
* ApiInfo
* @return ApiInfo
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("online exam by springboot")
@ -57,4 +67,4 @@ public class Swagger2Config {
.contact(new Contact("liangshanguang", "https://github.com/lsgwr/spring-boot-online-exam", "liangshanguang2@gmail.com"))
.build();
}
}
}

@ -40,51 +40,79 @@ public class UploadDownloadController {
// return FileTransUtil.uploadFile(uploadfile, "/root/" + File.separator + uploadfile.getOriginalFilename());
// }
/**
*
*
* @param dir
* @param uploadfile
* @return String
*/
@ApiOperation("单文件上传,支持同时传入参数")
@PostMapping("/api/upload/singleAndparas")
// 单文件上传。
public String uploadFileSingle(@RequestParam("dir") String dir, @RequestParam("file") MultipartFile uploadfile) {
// 调用FileTransUtil工具类中的uploadFile方法将上传的文件和目录作为参数传入。
public String uploadFileSingle(@RequestParam("dir") String dir, @RequestParam("file") MultipartFile uploadfile) {
return FileTransUtil.uploadFile(uploadfile, dir);
}
// 单文件上传支持同时传入参数Model。
/**
* Model
*
* @param model UploadModel2
* @return String
*/
@ApiOperation("单文件上传,支持同时传入参数,Model")
@PostMapping("/upload/single/model")
public String singleUploadFileModel(@ModelAttribute("model") UploadModel2 model) {
// 调用FileTransUtil工具类中的uploadFile方法将上传的文件和目录作为参数传入。
return FileTransUtil.uploadFile(model.getFile(), model.getDir());
}
// 多文件上传,支持同时传入参数。
/**
*
*
* @param dir
* @param uploadfiles
* @return String
*/
@ApiOperation("多文件上传,支持同时传入参数")
@PostMapping("upload/multiAndparas")
public String uploadFileMulti(@RequestParam("dir") String dir, @RequestParam("files") MultipartFile[] uploadfiles) {
// 调用FileTransUtil工具类中的uploadFiles方法将上传的文件数组和目录作为参数传入。
return FileTransUtil.uploadFiles(uploadfiles, dir);
}
// 多文件上传,支持同时传入参数。
/**
*
*
* @param model UploadModel
* @return String
*/
@ApiOperation("多文件上传,支持同时传入参数")
@PostMapping(value = "/upload/multi/model")
public String multiUploadFileModel(@ModelAttribute(("model")) UploadModel model) {
// 调用FileTransUtil工具类中的uploadFiles方法将上传的文件数组和目录作为参数传入。
return FileTransUtil.uploadFiles(model.getFiles(), model.getDir());
}
// Get下载文件
/**
* Get
*
* @param filePath
* @return ResponseEntity<InputStreamResource>
* @throws IOException
*/
@ApiOperation("Get下载文件")
@GetMapping(value = "/download/get")
public ResponseEntity<InputStreamResource> downloadFileGet(@RequestParam String filePath) throws IOException {
// 调用FileTransUtil工具类中的downloadFile方法将文件路径作为参数传入。
return FileTransUtil.downloadFile(filePath);
}
// Post下载文件
/**
* Post
*
* @param downloadQo DownloadQo
* @return ResponseEntity<InputStreamResource>
* @throws IOException
*/
@ApiOperation("Post下载文件")
@PostMapping(value = "/download/post")
public ResponseEntity<InputStreamResource> downloadFilePost(@RequestBody DownloadQo downloadQo) throws IOException {
// 调用FileTransUtil工具类中的downloadFile方法将文件路径作为参数传入。
return FileTransUtil.downloadFile(downloadQo.getPath());
}
}

@ -29,6 +29,12 @@ public class UserController {
@Autowired
private UserService userService;
/**
*
*
* @param registerDTO RegisterDTO
* @return ResultVO<User>
*/
@PostMapping("/register")
@ApiOperation("注册")
ResultVO<User> register(@RequestBody RegisterDTO registerDTO) {
@ -44,6 +50,12 @@ public class UserController {
return resultVO;
}
/**
* ,token
*
* @param loginQo LoginQo
* @return ResultVO<String>
*/
@PostMapping("/login")
@ApiOperation("根据用户名或邮箱登录,登录成功返回token")
ResultVO<String> login(@RequestBody LoginQo loginQo) { // 这里不用手机号是因为手机号和用户名难以进行格式区分,而用户名和
@ -60,6 +72,12 @@ public class UserController {
return resultVO;
}
/**
*
*
* @param request HttpServletRequest
* @return ResultVO<UserVo>
*/
@GetMapping("/user-info")
@ApiOperation("获取用户信息")
// 根据请求获取用户信息
@ -72,6 +90,12 @@ public class UserController {
return new ResultVO<>(ResultEnum.GET_INFO_SUCCESS.getCode(), ResultEnum.GET_INFO_SUCCESS.getMessage(), userVo);
}
/**
*
*
* @param request HttpServletRequest
* @return ResultVO<UserInfoVo>
*/
@GetMapping("/info")
@ApiOperation("获取用户的详细信息,包括个人信息页面和操作权限")
// 获取用户信息的接口
@ -86,6 +110,12 @@ public class UserController {
return new ResultVO<>(ResultEnum.GET_INFO_SUCCESS.getCode(), ResultEnum.GET_INFO_SUCCESS.getMessage(), userInfoVo);
}
/**
*
*
* @param request HttpServletRequest
* @return String
*/
@GetMapping("/test")
@ApiOperation("测试接口")
String test(HttpServletRequest request) {

@ -8,11 +8,26 @@ package lsgwr.exam.dto;
import lombok.Data;
/**
*
*/
@Data
public class RegisterDTO {
/**
*
*/
private String email;
/**
*
*/
private String password;
/**
*
*/
private String password2;
/**
*
*/
private String mobile;
/**
*

@ -23,37 +23,85 @@ import java.util.Date;
@Entity
@Data
@DynamicUpdate
/**
*
*/
public class Exam {
// 使用JPA的@Id注解声明该字段为主键
/**
* ID
*/
@Id
private String examId;// 考试ID唯一标识一场考试
private String examName;// 考试名称
private String examAvatar; // 考试头像或图标
private String examDescription;// 考试描述或简介
private String examQuestionIds;// 存储所有问题ID的字符串可能是逗号分隔的ID列表
private String examQuestionIdsRadio;// 存储所有单选题ID的字符串
private String examQuestionIdsCheck;// 存储所有多选题ID的字符串
private String examQuestionIdsJudge;// 存储所有判断题ID的字符串
private Integer examScore;// 考试总分
private Integer examScoreRadio;// 单选题总分
private Integer examScoreCheck;// 多选题总分
private Integer examScoreJudge;// 判断题总分
private String examCreatorId;// 创建者ID标识谁创建了这场考试
private Integer examTimeLimit;// 考试时间限制,单位可能是分钟
// 考试开始时间使用Jackson的@JsonFormat注解自定义日期格式
private String examId;
/**
*
*/
private String examName;
/**
*
*/
private String examAvatar;
/**
*
*/
private String examDescription;
/**
* IDID
*/
private String examQuestionIds;
/**
* ID
*/
private String examQuestionIdsRadio;
/**
* ID
*/
private String examQuestionIdsCheck;
/**
* ID
*/
private String examQuestionIdsJudge;
/**
*
*/
private Integer examScore;
/**
*
*/
private Integer examScoreRadio;
/**
*
*/
private Integer examScoreCheck;
/**
*
*/
private Integer examScoreJudge;
/**
* ID
*/
private String examCreatorId;
/**
*
*/
private Integer examTimeLimit;
/**
* 使Jackson@JsonFormat
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date examStartDate;
// 考试结束时间
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date examEndDate;
/**
/**
* Java
* 使Jackson@JsonFormat便
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
/**
* Java
* 使Hibernate@DynamicUpdate

@ -16,13 +16,22 @@ import javax.persistence.Id;// 引入JPA中的@Id注解标识实体类的主
@Data
// 使用@Entity注解标识这是一个JPA实体类
@Entity
public class ExamRecordLevel {
// 考试记录等级的ID是主键通过@Id注解标识并通过@GeneratedValue注解指定主键生成策略
/**
*
*/
public class ExamRecordLevel {
/**
* ID@Id@GeneratedValue
*/
@Id
@GeneratedValue
private Integer examRecordLevelId;
// 考试记录等级的名称,用于标识等级,如“优秀”、“良好”等
/**
*
*/
private String examRecordLevelName;
// 考试记录等级的描述,用于对等级进行更详细的说明
/**
*
*/
private String examRecordLevelDescription;
}

@ -12,16 +12,28 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
*
*/
@Data
@Entity
public class Page {
/**
* ID@Id@GeneratedValue
*/
@Id
@GeneratedValue
private Integer pageId;
/**
*
*/
private String pageName;
/**
*
*/
private String pageDescription;
/**
* ID
*/
private String actionIds;
}

@ -9,20 +9,34 @@ package lsgwr.exam.exception;
import lsgwr.exam.enums.ResultEnum;
import lombok.Getter;
/**
*
*/
@Getter
public class ExamException extends RuntimeException {
// 定义异常码
/**
*
*/
private Integer code;
// 构造函数,传入枚举类型
/**
*
*
* @param resultEnum ResultEnum
*/
public ExamException(ResultEnum resultEnum) {
super(resultEnum.getMessage());
this.code = resultEnum.getCode();
}
// 构造函数,传入异常码和异常信息
/**
*
*
* @param code
* @param message
*/
public ExamException( Integer code, String message) {
super(message);
this.code = code;
}
}
}

@ -23,6 +23,10 @@ import java.io.PrintWriter;
*
* @author liangshanguang
*/
/**
* Token
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@ -84,9 +88,9 @@ public class LoginInterceptor implements HandlerInterceptor {
/**
*
*
* @param response
* @param obj
* @throws Exception
* @param response
* @param obj
* @throws Exception
*/
public static void sendJsonMessage(HttpServletResponse response, Object obj) throws Exception {
Gson g = new Gson();

@ -10,6 +10,9 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor

@ -11,7 +11,10 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
/**
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor

@ -12,6 +12,9 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
/**
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor

@ -9,6 +9,8 @@ package lsgwr.exam.repository;
import lsgwr.exam.entity.ExamRecordLevel;
import org.springframework.data.jpa.repository.JpaRepository;
// ExamRecordLevelRepository接口继承JpaRepository接口用于操作ExamRecordLevel实体类
/**
* ExamRecordLevelRepositoryJpaRepositoryExamRecordLevel
*/
public interface ExamRecordLevelRepository extends JpaRepository<ExamRecordLevel, Integer> {
}

@ -5,6 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
*
*/
public interface ExamRecordRepository extends JpaRepository<ExamRecord, String> {
/**
*

@ -12,7 +12,9 @@ import org.springframework.data.jpa.repository.Query;
import java.util.List;
// ExamRepository接口继承JpaRepository接口用于操作Exam实体类
/**
* ExamRepositoryJpaRepositoryExam
*/
public interface ExamRepository extends JpaRepository<Exam, String> {
// 使用JPQL查询语句查询Exam实体类按照updateTime降序排列
@Query("select e from Exam e order by e.updateTime desc")

@ -15,7 +15,18 @@ import java.util.List;
*
*/
public interface QuestionRepository extends JpaRepository<Question, String> {
/**
* ID
*
* @param id ID
* @return
*/
List<Question> findByQuestionTypeId(Integer id);
/**
*
*
* @return
*/
@Query("select q from Question q order by q.updateTime desc")
List<Question> findAll();
}

@ -19,6 +19,9 @@ import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.*;
/**
*
*/
@Service
@Transactional
public class ExamServiceImpl implements ExamService {
@ -39,10 +42,21 @@ public class ExamServiceImpl implements ExamService {
private final QuestionOptionRepository questionOptionRepository;
/**
*
* @param questionRepository
* @param userRepository
* @param questionLevelRepository
* @param questionTypeRepository
* @param questionCategoryRepository
* @param questionOptionRepository
* @param examRepository
* @param examRecordRepository
*/
public ExamServiceImpl(QuestionRepository questionRepository, UserRepository userRepository, QuestionLevelRepository questionLevelRepository, QuestionTypeRepository questionTypeRepository, QuestionCategoryRepository questionCategoryRepository, QuestionOptionRepository questionOptionRepository, ExamRepository examRepository, ExamRecordRepository examRecordRepository) {
this.questionRepository = questionRepository;//
this.userRepository = userRepository;//
this.questionLevelRepository = questionLevelRepository;//
this.questionRepository = questionRepository;
this.userRepository = userRepository;
this.questionLevelRepository = questionLevelRepository;
this.questionTypeRepository = questionTypeRepository;
this.questionCategoryRepository = questionCategoryRepository;
this.questionOptionRepository = questionOptionRepository;
@ -50,12 +64,22 @@ public class ExamServiceImpl implements ExamService {
this.examRecordRepository = examRecordRepository;
}
/**
* @decription :
* return List<QuestionVo>
*/
@Override
public List<QuestionVo> getQuestionAll() {
List<Question> questionList = questionRepository.findAll();
return getQuestionVos(questionList);
}
/**
* Vo
*
* @param questionList
* @return Vo
*/
private List<QuestionVo> getQuestionVos(List<Question> questionList) {
// 需要自定义的question列表
List<QuestionVo> questionVoList = new ArrayList<>();

@ -86,6 +86,12 @@ public class UserServiceImpl implements UserService {
}
}
/**
*
*
* @param loginQo
* @return tokennull
*/
@Override
public String login(LoginQo loginQo) {
User user;

@ -5,7 +5,7 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: aA111111
url: jdbc:mysql://localhost:3306/exam?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
url: jdbc:mysql://localhost:3306/exam?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&&allowPublicKeyRetrieval=true
jpa:
# 调试的时候用用于打印完成SQL语句(但是不打印参数),联合下面的logging.level一同打印最完整的SQL信息(语句+参数)
show-sql: false

File diff suppressed because one or more lines are too long

@ -1,12 +1,15 @@
import enquireJs from 'enquire.js'
// 定义设备类型的常量
export const DEVICE_TYPE = {
DESKTOP: 'desktop',
TABLET: 'tablet',
MOBILE: 'mobile'
}
// 检测设备类型的函数
export const deviceEnquire = function (callback) {
// 定义每个设备类型的匹配函数
const matchDesktop = {
match: () => {
callback && callback(DEVICE_TYPE.DESKTOP)
@ -25,6 +28,7 @@ export const deviceEnquire = function (callback) {
}
}
// 为每个设备类型注册媒体查询
// screen and (max-width: 1087.99px)
enquireJs
.register('screen and (max-width: 576px)', matchMobile)

@ -1,8 +1,8 @@
import Vue from 'vue'
import moment from 'moment'
import 'moment/locale/zh-cn'
import $ from 'jquery'
moment.locale('zh-cn')
import Vue from 'vue' // 引入Vue
import moment from 'moment' // 引入moment库
import 'moment/locale/zh-cn' // 引入moment的中文语言包
import $ from 'jquery' // 引入jQuery
moment.locale('zh-cn') // 设置moment的语言为中文
Vue.filter('NumberFormat', function (value) {
if (!value) {

@ -1,3 +1,4 @@
// 定义权限枚举
const PERMISSION_ENUM = {
'add': { key: 'add', label: '新增' },
'delete': { key: 'delete', label: '删除' },
@ -10,21 +11,30 @@ const PERMISSION_ENUM = {
'export': { key: 'export', label: '导出' }
}
// 定义插件
function plugin (Vue) {
// 如果插件已经安装,则返回
if (plugin.installed) {
return
}
// 如果Vue实例中没有$auth属性则定义$auth属性
!Vue.prototype.$auth && Object.defineProperties(Vue.prototype, {
$auth: {
get () {
// 获取当前实例
const _this = this
// 返回一个函数,用于判断权限
return (permissions) => {
// 将权限字符串分割成permission和action
const [permission, action] = permissions.split('.')
// 获取当前用户的权限列表
const permissionList = _this.$store.getters.roles.permissions
// 在权限列表中查找对应的permission
return permissionList.find((val) => {
return val.permissionId === permission
}).actionList.findIndex((val) => {
// 在actionList中查找对应的action
return val === action
}) > -1
}
@ -32,15 +42,21 @@ function plugin (Vue) {
}
})
// 如果Vue实例中没有$enum属性则定义$enum属性
!Vue.prototype.$enum && Object.defineProperties(Vue.prototype, {
$enum: {
get () {
// const _this = this;
// 返回一个函数,用于获取枚举值
return (val) => {
// 初始化result为PERMISSION_ENUM
let result = PERMISSION_ENUM
// 如果val存在则将val按'.'分割成数组
val && val.split('.').forEach(v => {
// 在result中查找对应的值
result = result && result[v] || null
})
// 返回result
return result
}
}
@ -48,4 +64,5 @@ function plugin (Vue) {
})
}
// 导出插件
export default plugin

@ -1,9 +1,13 @@
// import Vue from 'vue'
// 引入Vue
import { deviceEnquire, DEVICE_TYPE } from '../utils/device'
// 引入设备检测工具和设备类型
import { mapState } from 'vuex'
// 引入Vuex的mapState方法
// const mixinsComputed = Vue.config.optionMergeStrategies.computed
// const mixinsMethods = Vue.config.optionMergeStrategies.methods
// 定义Vue的computed和methods的合并策略
const mixin = {
computed: {
@ -72,5 +76,5 @@ const AppDeviceEnquire = {
})
}
}
// 导出mixin、AppDeviceEnquire、mixinDevice
export { mixin, AppDeviceEnquire, mixinDevice }

@ -1,8 +1,12 @@
// 导出一个函数将json字符串转换为对象
export function actionToObject (json) {
try {
// 尝试将json字符串转换为对象
return JSON.parse(json)
} catch (e) {
// 如果转换失败,打印错误信息
console.log('err', e.message)
}
// 返回一个空数组
return []
}

@ -15,6 +15,7 @@ const service = axios.create({
timeout: 6000 // 请求超时时间
})
// 错误处理函数
const err = (error) => {
if (error.response) {
const data = error.response.data

@ -6,17 +6,22 @@
* @param maxAge
*/
export const setStore = (name, content, maxAge = null) => {
// 如果没有全局window对象或者没有传入name则返回
if (!global.window || !name) {
return
}
// 如果content不是字符串则将其转换为字符串
if (typeof content !== 'string') {
content = JSON.stringify(content)
}
// 获取localStorage对象
const storage = global.window.localStorage
// 将content存储到localStorage中
storage.setItem(name, content)
// 如果maxAge存在且为数字则将过期时间存储到localStorage中
if (maxAge && !isNaN(parseInt(maxAge))) {
const timeout = parseInt(new Date().getTime() / 1000)
storage.setItem(`${name}_expire`, timeout + maxAge)
@ -30,13 +35,17 @@ export const setStore = (name, content, maxAge = null) => {
* @returns {*}
*/
export const getStore = name => {
// 如果没有全局window对象或者没有传入name则返回
if (!global.window || !name) {
return
}
// 获取localStorage中存储的content
const content = window.localStorage.getItem(name)
// 获取localStorage中存储的过期时间
const _expire = window.localStorage.getItem(`${name}_expire`)
// 如果过期时间存在,则判断当前时间是否超过过期时间
if (_expire) {
const now = parseInt(new Date().getTime() / 1000)
if (now > _expire) {
@ -44,9 +53,11 @@ export const getStore = name => {
}
}
// 尝试将content解析为JSON对象
try {
return JSON.parse(content)
} catch (e) {
// 如果解析失败则返回content
return content
}
}
@ -57,11 +68,14 @@ export const getStore = name => {
* @param name
*/
export const clearStore = name => {
// 如果没有全局window对象或者没有传入name则返回
if (!global.window || !name) {
return
}
// 从localStorage中移除content
window.localStorage.removeItem(name)
// 从localStorage中移除过期时间
window.localStorage.removeItem(`${name}_expire`)
}
@ -69,9 +83,11 @@ export const clearStore = name => {
* Clear all storage
*/
export const clearAll = () => {
// 如果没有全局window对象或者没有传入name则返回
if (!global.window || !name) {
return
}
// 清空localStorage
window.localStorage.clear()
}
}

@ -1,9 +1,11 @@
// 导出一个函数,用于获取当前时间并返回相应的问候语
export function timeFix () {
const time = new Date()
const hour = time.getHours()
return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
}
// 导出一个函数,用于随机返回一个问候语
export function welcome () {
const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 DOTA', '我猜你可能累了']
const index = Math.floor(Math.random() * arr.length)
@ -13,6 +15,7 @@ export function welcome () {
/**
* 触发 window.resize
*/
// 导出一个函数,用于触发 window.resize 事件
export function triggerWindowResizeEvent () {
const event = document.createEvent('HTMLEvents')
event.initEvent('resize', true, true)
@ -20,6 +23,7 @@ export function triggerWindowResizeEvent () {
window.dispatchEvent(event)
}
// 导出一个函数,用于监听页面滚动事件
export function handleScrollHeader (callback) {
let timer = 0
@ -50,6 +54,7 @@ export function handleScrollHeader (callback) {
* @param id parent element id or class
* @param timeout
*/
// 导出一个函数,用于移除加载动画
export function removeLoadingAnimate (id = '', timeout = 1500) {
if (id === '') {
return

@ -1,11 +1,14 @@
<template>
<!-- 这是 Vue 组件的模板部分 -->
<exception-page type="403" />
</template>
<script>
// components ExceptionPage
import { ExceptionPage } from '../../components'
export default {
// ExceptionPage
components: {
ExceptionPage
}

@ -1,18 +1,28 @@
<template>
<div class="card-list" ref="content">
<!-- 使用a-list组件设置grid属性gutter为24lg为3md为2sm为1xs为1 -->
<a-list
:grid="{gutter: 24, lg: 3, md: 2, sm: 1, xs: 1}"
:dataSource="dataSource"
>
<!-- 使用a-list-item组件设置slot为renderItemslot-scope为item -->
<a-list-item slot="renderItem" slot-scope="item">
<!-- 使用a-card组件设置hoverable为true点击事件为joinExam -->
<a-card :hoverable="true" @click="joinExam(item.id)">
<!-- 使用a-card-meta组件设置slot为titleavatardescription -->
<a-card-meta>
<!-- 设置title为item.title -->
<div style="margin-bottom: 3px" slot="title">{{ item.title }}</div>
<!-- 设置avatar为item.avatar使用imgSrcFilter过滤器 -->
<a-avatar class="card-avatar" slot="avatar" :src="item.avatar | imgSrcFilter" size="large" />
<!-- 设置description为item.content -->
<div class="meta-content" slot="description">{{ item.content }}</div>
</a-card-meta>
<!-- 使用template组件设置slot为actions -->
<template class="ant-card-actions" slot="actions">
<!-- 设置a为满分item.score分 -->
<a>满分{{ item.score }}</a>
<!-- 设置a为限时item.elapse分钟 -->
<a>限时{{ item.elapse }}分钟</a>
</template>
</a-card>
@ -34,6 +44,7 @@ export default {
}
},
methods: {
//
joinExam (id) {
const routeUrl = this.$router.resolve({
path: `/exam/${id}`

@ -85,15 +85,15 @@ export default {
},
data () {
return {
//
//
examDetail: {},
// id, currentQuestion(answersidids),
// id, currentQuestion(answersidids),
answersMap: {},
//
currentQuestion: '',
// answersMap
// answersMap
radioValue: '',
// answersMap
// answersMap
checkValues: [],
optionStyle: {
display: 'block',
@ -106,7 +106,7 @@ export default {
mounted () {
this.answersMap = new Map()
const that = this
//
//
getExamDetail(this.$route.params.id)
.then(res => {
if (res.code === 0) {
@ -122,26 +122,26 @@ export default {
})
},
methods: {
// ,
//
...mapGetters(['nickname', 'avatar']),
getQuestionDetail (questionId) {
// content
// content
const that = this
//
//
this.radioValue = ''
this.checkValues = []
getQuestionDetail(questionId)
.then(res => {
if (res.code === 0) {
//
//
that.currentQuestion = res.data
// answersMapid
// answersMapid
if (that.answersMap.get(that.currentQuestion.id)) {
//
//
if (that.currentQuestion.type === '单选题' || that.currentQuestion.type === '判断题') {
that.radioValue = that.answersMap.get(that.currentQuestion.id)[0]
} else if (that.currentQuestion.type === '多选题') {
//
//
Object.assign(that.checkValues, that.answersMap.get(that.currentQuestion.id))
}
}

Loading…
Cancel
Save