@ -0,0 +1,274 @@ | |||
package org.jeecg.modules.demo.appletPaper.controller; | |||
import java.io.UnsupportedEncodingException; | |||
import java.io.IOException; | |||
import java.net.URLDecoder; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.HashMap; | |||
import java.util.stream.Collectors; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import org.jeecgframework.poi.excel.ExcelImportUtil; | |||
import org.jeecgframework.poi.excel.def.NormalExcelConstants; | |||
import org.jeecgframework.poi.excel.entity.ExportParams; | |||
import org.jeecgframework.poi.excel.entity.ImportParams; | |||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; | |||
import org.jeecg.common.system.vo.LoginUser; | |||
import org.apache.shiro.SecurityUtils; | |||
import org.jeecg.common.api.vo.Result; | |||
import org.jeecg.common.system.query.QueryGenerator; | |||
import org.jeecg.common.system.query.QueryRuleEnum; | |||
import org.jeecg.common.util.oConvertUtils; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestions; | |||
import org.jeecg.modules.demo.appletPaper.vo.AppletQuestionsPage; | |||
import org.jeecg.modules.demo.appletPaper.service.IAppletQuestionsService; | |||
import org.jeecg.modules.demo.appletPaper.service.IAppletQuestionsOptionsService; | |||
import org.springframework.beans.BeanUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.*; | |||
import org.springframework.web.servlet.ModelAndView; | |||
import org.springframework.web.multipart.MultipartFile; | |||
import org.springframework.web.multipart.MultipartHttpServletRequest; | |||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
import com.baomidou.mybatisplus.core.metadata.IPage; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
import lombok.extern.slf4j.Slf4j; | |||
import com.alibaba.fastjson.JSON; | |||
import io.swagger.v3.oas.annotations.tags.Tag; | |||
import io.swagger.v3.oas.annotations.Operation; | |||
import org.jeecg.common.aspect.annotation.AutoLog; | |||
import org.apache.shiro.authz.annotation.RequiresPermissions; | |||
/** | |||
* @Description: 题目 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Tag(name="题目") | |||
@RestController | |||
@RequestMapping("/appletPaper/appletQuestions") | |||
@Slf4j | |||
public class AppletQuestionsController { | |||
@Autowired | |||
private IAppletQuestionsService appletQuestionsService; | |||
@Autowired | |||
private IAppletQuestionsOptionsService appletQuestionsOptionsService; | |||
/** | |||
* 分页列表查询 | |||
* | |||
* @param appletQuestions | |||
* @param pageNo | |||
* @param pageSize | |||
* @param req | |||
* @return | |||
*/ | |||
//@AutoLog(value = "题目-分页列表查询") | |||
@Operation(summary="题目-分页列表查询") | |||
@GetMapping(value = "/list") | |||
public Result<IPage<AppletQuestions>> queryPageList(AppletQuestions appletQuestions, | |||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, | |||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, | |||
HttpServletRequest req) { | |||
// 自定义查询规则 | |||
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>(); | |||
// 自定义多选的查询规则为:LIKE_WITH_OR | |||
customeRuleMap.put("type", QueryRuleEnum.LIKE_WITH_OR); | |||
QueryWrapper<AppletQuestions> queryWrapper = QueryGenerator.initQueryWrapper(appletQuestions, req.getParameterMap(),customeRuleMap); | |||
Page<AppletQuestions> page = new Page<AppletQuestions>(pageNo, pageSize); | |||
IPage<AppletQuestions> pageList = appletQuestionsService.page(page, queryWrapper); | |||
return Result.OK(pageList); | |||
} | |||
/** | |||
* 添加 | |||
* | |||
* @param appletQuestionsPage | |||
* @return | |||
*/ | |||
@AutoLog(value = "题目-添加") | |||
@Operation(summary="题目-添加") | |||
@RequiresPermissions("appletPaper:applet_questions:add") | |||
@PostMapping(value = "/add") | |||
public Result<String> add(@RequestBody AppletQuestionsPage appletQuestionsPage) { | |||
AppletQuestions appletQuestions = new AppletQuestions(); | |||
BeanUtils.copyProperties(appletQuestionsPage, appletQuestions); | |||
appletQuestionsService.saveMain(appletQuestions, appletQuestionsPage.getAppletQuestionsOptionsList()); | |||
return Result.OK("添加成功!"); | |||
} | |||
/** | |||
* 编辑 | |||
* | |||
* @param appletQuestionsPage | |||
* @return | |||
*/ | |||
@AutoLog(value = "题目-编辑") | |||
@Operation(summary="题目-编辑") | |||
@RequiresPermissions("appletPaper:applet_questions:edit") | |||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) | |||
public Result<String> edit(@RequestBody AppletQuestionsPage appletQuestionsPage) { | |||
AppletQuestions appletQuestions = new AppletQuestions(); | |||
BeanUtils.copyProperties(appletQuestionsPage, appletQuestions); | |||
AppletQuestions appletQuestionsEntity = appletQuestionsService.getById(appletQuestions.getId()); | |||
if(appletQuestionsEntity==null) { | |||
return Result.error("未找到对应数据"); | |||
} | |||
appletQuestionsService.updateMain(appletQuestions, appletQuestionsPage.getAppletQuestionsOptionsList()); | |||
return Result.OK("编辑成功!"); | |||
} | |||
/** | |||
* 通过id删除 | |||
* | |||
* @param id | |||
* @return | |||
*/ | |||
@AutoLog(value = "题目-通过id删除") | |||
@Operation(summary="题目-通过id删除") | |||
@RequiresPermissions("appletPaper:applet_questions:delete") | |||
@DeleteMapping(value = "/delete") | |||
public Result<String> delete(@RequestParam(name="id",required=true) String id) { | |||
appletQuestionsService.delMain(id); | |||
return Result.OK("删除成功!"); | |||
} | |||
/** | |||
* 批量删除 | |||
* | |||
* @param ids | |||
* @return | |||
*/ | |||
@AutoLog(value = "题目-批量删除") | |||
@Operation(summary="题目-批量删除") | |||
@RequiresPermissions("appletPaper:applet_questions:deleteBatch") | |||
@DeleteMapping(value = "/deleteBatch") | |||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) { | |||
this.appletQuestionsService.delBatchMain(Arrays.asList(ids.split(","))); | |||
return Result.OK("批量删除成功!"); | |||
} | |||
/** | |||
* 通过id查询 | |||
* | |||
* @param id | |||
* @return | |||
*/ | |||
//@AutoLog(value = "题目-通过id查询") | |||
@Operation(summary="题目-通过id查询") | |||
@GetMapping(value = "/queryById") | |||
public Result<AppletQuestions> queryById(@RequestParam(name="id",required=true) String id) { | |||
AppletQuestions appletQuestions = appletQuestionsService.getById(id); | |||
if(appletQuestions==null) { | |||
return Result.error("未找到对应数据"); | |||
} | |||
return Result.OK(appletQuestions); | |||
} | |||
/** | |||
* 通过id查询 | |||
* | |||
* @param id | |||
* @return | |||
*/ | |||
//@AutoLog(value = "题目选项-通过主表ID查询") | |||
@Operation(summary="题目选项-通过主表ID查询") | |||
@GetMapping(value = "/queryAppletQuestionsOptionsByMainId") | |||
public Result<IPage<AppletQuestionsOptions>> queryAppletQuestionsOptionsListByMainId(@RequestParam(name="id",required=true) String id) { | |||
List<AppletQuestionsOptions> appletQuestionsOptionsList = appletQuestionsOptionsService.selectByMainId(id); | |||
IPage <AppletQuestionsOptions> page = new Page<>(); | |||
page.setRecords(appletQuestionsOptionsList); | |||
page.setTotal(appletQuestionsOptionsList.size()); | |||
return Result.OK(page); | |||
} | |||
/** | |||
* 导出excel | |||
* | |||
* @param request | |||
* @param appletQuestions | |||
*/ | |||
@RequiresPermissions("appletPaper:applet_questions:exportXls") | |||
@RequestMapping(value = "/exportXls") | |||
public ModelAndView exportXls(HttpServletRequest request, AppletQuestions appletQuestions) { | |||
// Step.1 组装查询条件查询数据 | |||
QueryWrapper<AppletQuestions> queryWrapper = QueryGenerator.initQueryWrapper(appletQuestions, request.getParameterMap()); | |||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); | |||
//配置选中数据查询条件 | |||
String selections = request.getParameter("selections"); | |||
if(oConvertUtils.isNotEmpty(selections)) { | |||
List<String> selectionList = Arrays.asList(selections.split(",")); | |||
queryWrapper.in("id",selectionList); | |||
} | |||
//Step.2 获取导出数据 | |||
List<AppletQuestions> appletQuestionsList = appletQuestionsService.list(queryWrapper); | |||
// Step.3 组装pageList | |||
List<AppletQuestionsPage> pageList = new ArrayList<AppletQuestionsPage>(); | |||
for (AppletQuestions main : appletQuestionsList) { | |||
AppletQuestionsPage vo = new AppletQuestionsPage(); | |||
BeanUtils.copyProperties(main, vo); | |||
List<AppletQuestionsOptions> appletQuestionsOptionsList = appletQuestionsOptionsService.selectByMainId(main.getId()); | |||
vo.setAppletQuestionsOptionsList(appletQuestionsOptionsList); | |||
pageList.add(vo); | |||
} | |||
// Step.4 AutoPoi 导出Excel | |||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); | |||
mv.addObject(NormalExcelConstants.FILE_NAME, "题目列表"); | |||
mv.addObject(NormalExcelConstants.CLASS, AppletQuestionsPage.class); | |||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("题目数据", "导出人:"+sysUser.getRealname(), "题目")); | |||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList); | |||
return mv; | |||
} | |||
/** | |||
* 通过excel导入数据 | |||
* | |||
* @param request | |||
* @param response | |||
* @return | |||
*/ | |||
@RequiresPermissions("appletPaper:applet_questions:importExcel") | |||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST) | |||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) { | |||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; | |||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); | |||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) { | |||
// 获取上传文件对象 | |||
MultipartFile file = entity.getValue(); | |||
ImportParams params = new ImportParams(); | |||
params.setTitleRows(2); | |||
params.setHeadRows(1); | |||
params.setNeedSave(true); | |||
try { | |||
List<AppletQuestionsPage> list = ExcelImportUtil.importExcel(file.getInputStream(), AppletQuestionsPage.class, params); | |||
for (AppletQuestionsPage page : list) { | |||
AppletQuestions po = new AppletQuestions(); | |||
BeanUtils.copyProperties(page, po); | |||
appletQuestionsService.saveMain(po, page.getAppletQuestionsOptionsList()); | |||
} | |||
return Result.OK("文件导入成功!数据行数:" + list.size()); | |||
} catch (Exception e) { | |||
log.error(e.getMessage(),e); | |||
return Result.error("文件导入失败:"+e.getMessage()); | |||
} finally { | |||
try { | |||
file.getInputStream().close(); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
return Result.OK("文件导入失败!"); | |||
} | |||
} |
@ -0,0 +1,76 @@ | |||
package org.jeecg.modules.demo.appletPaper.entity; | |||
import java.io.Serializable; | |||
import java.io.UnsupportedEncodingException; | |||
import java.util.Date; | |||
import com.baomidou.mybatisplus.annotation.IdType; | |||
import com.baomidou.mybatisplus.annotation.TableId; | |||
import com.baomidou.mybatisplus.annotation.TableName; | |||
import com.baomidou.mybatisplus.annotation.TableLogic; | |||
import org.jeecg.common.constant.ProvinceCityArea; | |||
import org.jeecg.common.util.SpringContextUtils; | |||
import lombok.Data; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import org.springframework.format.annotation.DateTimeFormat; | |||
import org.jeecgframework.poi.excel.annotation.Excel; | |||
import org.jeecg.common.aspect.annotation.Dict; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
/** | |||
* @Description: 题目 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Schema(description="题目") | |||
@Data | |||
@TableName("applet_questions") | |||
public class AppletQuestions implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
/**主键*/ | |||
@TableId(type = IdType.ASSIGN_ID) | |||
@Schema(description = "主键") | |||
private java.lang.String id; | |||
/**创建人*/ | |||
@Schema(description = "创建人") | |||
private java.lang.String createBy; | |||
/**创建日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "创建日期") | |||
private java.util.Date createTime; | |||
/**更新人*/ | |||
@Schema(description = "更新人") | |||
private java.lang.String updateBy; | |||
/**更新日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "更新日期") | |||
private java.util.Date updateTime; | |||
/**所属部门*/ | |||
@Schema(description = "所属部门") | |||
private java.lang.String sysOrgCode; | |||
/**类型*/ | |||
@Excel(name = "类型", width = 15, dicCode = "applett_topic_type") | |||
@Dict(dicCode = "applett_topic_type") | |||
@Schema(description = "类型") | |||
private java.lang.String type; | |||
/**标题*/ | |||
@Excel(name = "标题", width = 15) | |||
@Schema(description = "标题") | |||
private java.lang.String text; | |||
/**描述*/ | |||
@Excel(name = "描述", width = 15) | |||
@Schema(description = "描述") | |||
private java.lang.String content; | |||
/**必填*/ | |||
@Excel(name = "必填", width = 15,replace = {"是_Y","否_N"} ) | |||
@Schema(description = "必填") | |||
private java.lang.String required; | |||
/**备注*/ | |||
@Excel(name = "备注", width = 15) | |||
@Schema(description = "备注") | |||
private java.lang.String remark; | |||
} |
@ -0,0 +1,73 @@ | |||
package org.jeecg.modules.demo.appletPaper.entity; | |||
import java.io.Serializable; | |||
import com.baomidou.mybatisplus.annotation.IdType; | |||
import com.baomidou.mybatisplus.annotation.TableId; | |||
import com.baomidou.mybatisplus.annotation.TableName; | |||
import com.baomidou.mybatisplus.annotation.TableLogic; | |||
import org.jeecg.common.constant.ProvinceCityArea; | |||
import org.jeecg.common.util.SpringContextUtils; | |||
import lombok.Data; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import org.springframework.format.annotation.DateTimeFormat; | |||
import org.jeecgframework.poi.excel.annotation.Excel; | |||
import java.util.Date; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
import java.io.UnsupportedEncodingException; | |||
/** | |||
* @Description: 题目分类 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Schema(description="题目分类") | |||
@Data | |||
@TableName("applet_questions_category") | |||
public class AppletQuestionsCategory implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
/**主键*/ | |||
@TableId(type = IdType.ASSIGN_ID) | |||
@Schema(description = "主键") | |||
private java.lang.String id; | |||
/**创建人*/ | |||
@Schema(description = "创建人") | |||
private java.lang.String createBy; | |||
/**创建日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "创建日期") | |||
private java.util.Date createTime; | |||
/**更新人*/ | |||
@Schema(description = "更新人") | |||
private java.lang.String updateBy; | |||
/**更新日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "更新日期") | |||
private java.util.Date updateTime; | |||
/**所属部门*/ | |||
@Schema(description = "所属部门") | |||
private java.lang.String sysOrgCode; | |||
/**分类名称*/ | |||
@Excel(name = "分类名称", width = 15) | |||
@Schema(description = "分类名称") | |||
private java.lang.String title; | |||
/**英文名称*/ | |||
@Excel(name = "英文名称", width = 15) | |||
@Schema(description = "英文名称") | |||
private java.lang.String enTitle; | |||
/**排序*/ | |||
@Excel(name = "排序", width = 15) | |||
@Schema(description = "排序") | |||
private java.lang.Integer sort; | |||
/**试卷*/ | |||
@Schema(description = "试卷") | |||
private java.lang.String paperId; | |||
/**题目*/ | |||
@Excel(name = "题目", width = 15, dictTable = "applet_questions", dicText = "text", dicCode = "id") | |||
@Schema(description = "题目") | |||
private java.lang.String questionsId; | |||
} |
@ -0,0 +1,78 @@ | |||
package org.jeecg.modules.demo.appletPaper.entity; | |||
import java.io.Serializable; | |||
import com.baomidou.mybatisplus.annotation.IdType; | |||
import com.baomidou.mybatisplus.annotation.TableId; | |||
import com.baomidou.mybatisplus.annotation.TableName; | |||
import com.baomidou.mybatisplus.annotation.TableLogic; | |||
import org.jeecg.common.constant.ProvinceCityArea; | |||
import org.jeecg.common.util.SpringContextUtils; | |||
import lombok.Data; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import org.springframework.format.annotation.DateTimeFormat; | |||
import org.jeecgframework.poi.excel.annotation.Excel; | |||
import java.util.Date; | |||
import org.jeecg.common.aspect.annotation.Dict; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
import java.io.UnsupportedEncodingException; | |||
/** | |||
* @Description: 题目选项 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Schema(description="题目选项") | |||
@Data | |||
@TableName("applet_questions_options") | |||
public class AppletQuestionsOptions implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
/**主键*/ | |||
@TableId(type = IdType.ASSIGN_ID) | |||
@Schema(description = "主键") | |||
private java.lang.String id; | |||
/**创建人*/ | |||
@Schema(description = "创建人") | |||
private java.lang.String createBy; | |||
/**创建日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "创建日期") | |||
private java.util.Date createTime; | |||
/**更新人*/ | |||
@Schema(description = "更新人") | |||
private java.lang.String updateBy; | |||
/**更新日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "更新日期") | |||
private java.util.Date updateTime; | |||
/**所属部门*/ | |||
@Schema(description = "所属部门") | |||
private java.lang.String sysOrgCode; | |||
/**选项内容*/ | |||
@Excel(name = "选项内容", width = 15) | |||
@Schema(description = "选项内容") | |||
private java.lang.String content; | |||
/**绑定题目*/ | |||
@Schema(description = "绑定题目") | |||
private java.lang.String questionId; | |||
/**前缀文字*/ | |||
@Excel(name = "前缀文字", width = 15) | |||
@Schema(description = "前缀文字") | |||
private java.lang.String prefix; | |||
/**后缀文字*/ | |||
@Excel(name = "后缀文字", width = 15) | |||
@Schema(description = "后缀文字") | |||
private java.lang.String suffix; | |||
/**选中前图片*/ | |||
@Excel(name = "选中前图片", width = 15) | |||
@Schema(description = "选中前图片") | |||
private java.lang.String image; | |||
/**选中后图片*/ | |||
@Excel(name = "选中后图片", width = 15) | |||
@Schema(description = "选中后图片") | |||
private java.lang.String imageAfter; | |||
} |
@ -0,0 +1,31 @@ | |||
package org.jeecg.modules.demo.appletPaper.mapper; | |||
import java.util.List; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory; | |||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
import org.apache.ibatis.annotations.Param; | |||
/** | |||
* @Description: 题目分类 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface AppletQuestionsCategoryMapper extends BaseMapper<AppletQuestionsCategory> { | |||
/** | |||
* 通过主表id删除子表数据 | |||
* | |||
* @param mainId 主表id | |||
* @return boolean | |||
*/ | |||
public boolean deleteByMainId(@Param("mainId") String mainId); | |||
/** | |||
* 通过主表id查询子表数据 | |||
* | |||
* @param mainId 主表id | |||
* @return List<AppletQuestionsCategory> | |||
*/ | |||
public List<AppletQuestionsCategory> selectByMainId(@Param("mainId") String mainId); | |||
} |
@ -0,0 +1,17 @@ | |||
package org.jeecg.modules.demo.appletPaper.mapper; | |||
import java.util.List; | |||
import org.apache.ibatis.annotations.Param; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestions; | |||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
/** | |||
* @Description: 题目 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface AppletQuestionsMapper extends BaseMapper<AppletQuestions> { | |||
} |
@ -0,0 +1,31 @@ | |||
package org.jeecg.modules.demo.appletPaper.mapper; | |||
import java.util.List; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
import org.apache.ibatis.annotations.Param; | |||
/** | |||
* @Description: 题目选项 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface AppletQuestionsOptionsMapper extends BaseMapper<AppletQuestionsOptions> { | |||
/** | |||
* 通过主表id删除子表数据 | |||
* | |||
* @param mainId 主表id | |||
* @return boolean | |||
*/ | |||
public boolean deleteByMainId(@Param("mainId") String mainId); | |||
/** | |||
* 通过主表id查询子表数据 | |||
* | |||
* @param mainId 主表id | |||
* @return List<AppletQuestionsOptions> | |||
*/ | |||
public List<AppletQuestionsOptions> selectByMainId(@Param("mainId") String mainId); | |||
} |
@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsCategoryMapper"> | |||
<delete id="deleteByMainId" parameterType="java.lang.String"> | |||
DELETE | |||
FROM applet_questions_category | |||
WHERE | |||
paper_id = #{mainId} </delete> | |||
<select id="selectByMainId" parameterType="java.lang.String" resultType="org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory"> | |||
SELECT * | |||
FROM applet_questions_category | |||
WHERE | |||
paper_id = #{mainId} </select> | |||
</mapper> |
@ -0,0 +1,5 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsMapper"> | |||
</mapper> |
@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsOptionsMapper"> | |||
<delete id="deleteByMainId" parameterType="java.lang.String"> | |||
DELETE | |||
FROM applet_questions_options | |||
WHERE | |||
question_id = #{mainId} </delete> | |||
<select id="selectByMainId" parameterType="java.lang.String" resultType="org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions"> | |||
SELECT * | |||
FROM applet_questions_options | |||
WHERE | |||
question_id = #{mainId} </select> | |||
</mapper> |
@ -1,14 +1,48 @@ | |||
package org.jeecg.modules.demo.appletPaper.service; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletPaper; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
import java.io.Serializable; | |||
import java.util.Collection; | |||
import java.util.List; | |||
/** | |||
* @Description: 试卷 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-19 | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface IAppletPaperService extends IService<AppletPaper> { | |||
/** | |||
* 添加一对多 | |||
* | |||
* @param appletPaper | |||
* @param appletQuestionsCategoryList | |||
*/ | |||
public void saveMain(AppletPaper appletPaper,List<AppletQuestionsCategory> appletQuestionsCategoryList) ; | |||
/** | |||
* 修改一对多 | |||
* | |||
* @param appletPaper | |||
* @param appletQuestionsCategoryList | |||
*/ | |||
public void updateMain(AppletPaper appletPaper,List<AppletQuestionsCategory> appletQuestionsCategoryList); | |||
/** | |||
* 删除一对多 | |||
* | |||
* @param id | |||
*/ | |||
public void delMain (String id); | |||
/** | |||
* 批量删除一对多 | |||
* | |||
* @param idList | |||
*/ | |||
public void delBatchMain (Collection<? extends Serializable> idList); | |||
} |
@ -0,0 +1,22 @@ | |||
package org.jeecg.modules.demo.appletPaper.service; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
import java.util.List; | |||
/** | |||
* @Description: 题目分类 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface IAppletQuestionsCategoryService extends IService<AppletQuestionsCategory> { | |||
/** | |||
* 通过主表id查询子表数据 | |||
* | |||
* @param mainId 主表id | |||
* @return List<AppletQuestionsCategory> | |||
*/ | |||
public List<AppletQuestionsCategory> selectByMainId(String mainId); | |||
} |
@ -0,0 +1,22 @@ | |||
package org.jeecg.modules.demo.appletPaper.service; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
import java.util.List; | |||
/** | |||
* @Description: 题目选项 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface IAppletQuestionsOptionsService extends IService<AppletQuestionsOptions> { | |||
/** | |||
* 通过主表id查询子表数据 | |||
* | |||
* @param mainId 主表id | |||
* @return List<AppletQuestionsOptions> | |||
*/ | |||
public List<AppletQuestionsOptions> selectByMainId(String mainId); | |||
} |
@ -0,0 +1,48 @@ | |||
package org.jeecg.modules.demo.appletPaper.service; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestions; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
import java.io.Serializable; | |||
import java.util.Collection; | |||
import java.util.List; | |||
/** | |||
* @Description: 题目 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
public interface IAppletQuestionsService extends IService<AppletQuestions> { | |||
/** | |||
* 添加一对多 | |||
* | |||
* @param appletQuestions | |||
* @param appletQuestionsOptionsList | |||
*/ | |||
public void saveMain(AppletQuestions appletQuestions,List<AppletQuestionsOptions> appletQuestionsOptionsList) ; | |||
/** | |||
* 修改一对多 | |||
* | |||
* @param appletQuestions | |||
* @param appletQuestionsOptionsList | |||
*/ | |||
public void updateMain(AppletQuestions appletQuestions,List<AppletQuestionsOptions> appletQuestionsOptionsList); | |||
/** | |||
* 删除一对多 | |||
* | |||
* @param id | |||
*/ | |||
public void delMain (String id); | |||
/** | |||
* 批量删除一对多 | |||
* | |||
* @param idList | |||
*/ | |||
public void delBatchMain (Collection<? extends Serializable> idList); | |||
} |
@ -1,19 +1,77 @@ | |||
package org.jeecg.modules.demo.appletPaper.service.impl; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletPaper; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory; | |||
import org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsCategoryMapper; | |||
import org.jeecg.modules.demo.appletPaper.mapper.AppletPaperMapper; | |||
import org.jeecg.modules.demo.appletPaper.service.IAppletPaperService; | |||
import org.springframework.stereotype.Service; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.transaction.annotation.Transactional; | |||
import java.io.Serializable; | |||
import java.util.List; | |||
import java.util.Collection; | |||
/** | |||
* @Description: 试卷 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-19 | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Service | |||
public class AppletPaperServiceImpl extends ServiceImpl<AppletPaperMapper, AppletPaper> implements IAppletPaperService { | |||
@Autowired | |||
private AppletPaperMapper appletPaperMapper; | |||
@Autowired | |||
private AppletQuestionsCategoryMapper appletQuestionsCategoryMapper; | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void saveMain(AppletPaper appletPaper, List<AppletQuestionsCategory> appletQuestionsCategoryList) { | |||
appletPaperMapper.insert(appletPaper); | |||
if(appletQuestionsCategoryList!=null && appletQuestionsCategoryList.size()>0) { | |||
for(AppletQuestionsCategory entity:appletQuestionsCategoryList) { | |||
//外键设置 | |||
entity.setPaperId(appletPaper.getId()); | |||
appletQuestionsCategoryMapper.insert(entity); | |||
} | |||
} | |||
} | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void updateMain(AppletPaper appletPaper,List<AppletQuestionsCategory> appletQuestionsCategoryList) { | |||
appletPaperMapper.updateById(appletPaper); | |||
//1.先删除子表数据 | |||
appletQuestionsCategoryMapper.deleteByMainId(appletPaper.getId()); | |||
//2.子表数据重新插入 | |||
if(appletQuestionsCategoryList!=null && appletQuestionsCategoryList.size()>0) { | |||
for(AppletQuestionsCategory entity:appletQuestionsCategoryList) { | |||
//外键设置 | |||
entity.setPaperId(appletPaper.getId()); | |||
appletQuestionsCategoryMapper.insert(entity); | |||
} | |||
} | |||
} | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void delMain(String id) { | |||
appletQuestionsCategoryMapper.deleteByMainId(id); | |||
appletPaperMapper.deleteById(id); | |||
} | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void delBatchMain(Collection<? extends Serializable> idList) { | |||
for(Serializable id:idList) { | |||
appletQuestionsCategoryMapper.deleteByMainId(id.toString()); | |||
appletPaperMapper.deleteById(id); | |||
} | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
package org.jeecg.modules.demo.appletPaper.service.impl; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory; | |||
import org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsCategoryMapper; | |||
import org.jeecg.modules.demo.appletPaper.service.IAppletQuestionsCategoryService; | |||
import org.springframework.stereotype.Service; | |||
import java.util.List; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
/** | |||
* @Description: 题目分类 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Service | |||
public class AppletQuestionsCategoryServiceImpl extends ServiceImpl<AppletQuestionsCategoryMapper, AppletQuestionsCategory> implements IAppletQuestionsCategoryService { | |||
@Autowired | |||
private AppletQuestionsCategoryMapper appletQuestionsCategoryMapper; | |||
@Override | |||
public List<AppletQuestionsCategory> selectByMainId(String mainId) { | |||
return appletQuestionsCategoryMapper.selectByMainId(mainId); | |||
} | |||
} |
@ -0,0 +1,27 @@ | |||
package org.jeecg.modules.demo.appletPaper.service.impl; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsOptionsMapper; | |||
import org.jeecg.modules.demo.appletPaper.service.IAppletQuestionsOptionsService; | |||
import org.springframework.stereotype.Service; | |||
import java.util.List; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
/** | |||
* @Description: 题目选项 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Service | |||
public class AppletQuestionsOptionsServiceImpl extends ServiceImpl<AppletQuestionsOptionsMapper, AppletQuestionsOptions> implements IAppletQuestionsOptionsService { | |||
@Autowired | |||
private AppletQuestionsOptionsMapper appletQuestionsOptionsMapper; | |||
@Override | |||
public List<AppletQuestionsOptions> selectByMainId(String mainId) { | |||
return appletQuestionsOptionsMapper.selectByMainId(mainId); | |||
} | |||
} |
@ -0,0 +1,77 @@ | |||
package org.jeecg.modules.demo.appletPaper.service.impl; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestions; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsOptionsMapper; | |||
import org.jeecg.modules.demo.appletPaper.mapper.AppletQuestionsMapper; | |||
import org.jeecg.modules.demo.appletPaper.service.IAppletQuestionsService; | |||
import org.springframework.stereotype.Service; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.transaction.annotation.Transactional; | |||
import java.io.Serializable; | |||
import java.util.List; | |||
import java.util.Collection; | |||
/** | |||
* @Description: 题目 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Service | |||
public class AppletQuestionsServiceImpl extends ServiceImpl<AppletQuestionsMapper, AppletQuestions> implements IAppletQuestionsService { | |||
@Autowired | |||
private AppletQuestionsMapper appletQuestionsMapper; | |||
@Autowired | |||
private AppletQuestionsOptionsMapper appletQuestionsOptionsMapper; | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void saveMain(AppletQuestions appletQuestions, List<AppletQuestionsOptions> appletQuestionsOptionsList) { | |||
appletQuestionsMapper.insert(appletQuestions); | |||
if(appletQuestionsOptionsList!=null && appletQuestionsOptionsList.size()>0) { | |||
for(AppletQuestionsOptions entity:appletQuestionsOptionsList) { | |||
//外键设置 | |||
entity.setQuestionId(appletQuestions.getId()); | |||
appletQuestionsOptionsMapper.insert(entity); | |||
} | |||
} | |||
} | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void updateMain(AppletQuestions appletQuestions,List<AppletQuestionsOptions> appletQuestionsOptionsList) { | |||
appletQuestionsMapper.updateById(appletQuestions); | |||
//1.先删除子表数据 | |||
appletQuestionsOptionsMapper.deleteByMainId(appletQuestions.getId()); | |||
//2.子表数据重新插入 | |||
if(appletQuestionsOptionsList!=null && appletQuestionsOptionsList.size()>0) { | |||
for(AppletQuestionsOptions entity:appletQuestionsOptionsList) { | |||
//外键设置 | |||
entity.setQuestionId(appletQuestions.getId()); | |||
appletQuestionsOptionsMapper.insert(entity); | |||
} | |||
} | |||
} | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void delMain(String id) { | |||
appletQuestionsOptionsMapper.deleteByMainId(id); | |||
appletQuestionsMapper.deleteById(id); | |||
} | |||
@Override | |||
@Transactional(rollbackFor = Exception.class) | |||
public void delBatchMain(Collection<? extends Serializable> idList) { | |||
for(Serializable id:idList) { | |||
appletQuestionsOptionsMapper.deleteByMainId(id.toString()); | |||
appletQuestionsMapper.deleteById(id); | |||
} | |||
} | |||
} |
@ -0,0 +1,72 @@ | |||
package org.jeecg.modules.demo.appletPaper.vo; | |||
import java.util.List; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletPaper; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsCategory; | |||
import lombok.Data; | |||
import org.jeecgframework.poi.excel.annotation.Excel; | |||
import org.jeecgframework.poi.excel.annotation.ExcelEntity; | |||
import org.jeecgframework.poi.excel.annotation.ExcelCollection; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import org.springframework.format.annotation.DateTimeFormat; | |||
import java.util.Date; | |||
import org.jeecg.common.aspect.annotation.Dict; | |||
import org.jeecg.common.constant.ProvinceCityArea; | |||
import org.jeecg.common.util.SpringContextUtils; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
/** | |||
* @Description: 试卷 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Data | |||
@Schema(description="试卷") | |||
public class AppletPaperPage { | |||
/**主键*/ | |||
@Schema(description = "主键") | |||
private java.lang.String id; | |||
/**创建人*/ | |||
@Schema(description = "创建人") | |||
private java.lang.String createBy; | |||
/**创建日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "创建日期") | |||
private java.util.Date createTime; | |||
/**更新人*/ | |||
@Schema(description = "更新人") | |||
private java.lang.String updateBy; | |||
/**更新日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "更新日期") | |||
private java.util.Date updateTime; | |||
/**所属部门*/ | |||
@Schema(description = "所属部门") | |||
private java.lang.String sysOrgCode; | |||
/**试卷名称*/ | |||
@Excel(name = "试卷名称", width = 15) | |||
@Schema(description = "试卷名称") | |||
private java.lang.String title; | |||
/**英文名称*/ | |||
@Excel(name = "英文名称", width = 15) | |||
@Schema(description = "英文名称") | |||
private java.lang.String enTitle; | |||
/**小提示*/ | |||
@Excel(name = "小提示", width = 15) | |||
@Schema(description = "小提示") | |||
private java.lang.String tips; | |||
/**总分*/ | |||
@Excel(name = "总分", width = 15) | |||
@Schema(description = "总分") | |||
private java.lang.String score; | |||
@ExcelCollection(name="题目分类") | |||
@Schema(description = "题目分类") | |||
private List<AppletQuestionsCategory> appletQuestionsCategoryList; | |||
} |
@ -0,0 +1,77 @@ | |||
package org.jeecg.modules.demo.appletPaper.vo; | |||
import java.util.List; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestions; | |||
import org.jeecg.modules.demo.appletPaper.entity.AppletQuestionsOptions; | |||
import lombok.Data; | |||
import org.jeecgframework.poi.excel.annotation.Excel; | |||
import org.jeecgframework.poi.excel.annotation.ExcelEntity; | |||
import org.jeecgframework.poi.excel.annotation.ExcelCollection; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import org.springframework.format.annotation.DateTimeFormat; | |||
import java.util.Date; | |||
import org.jeecg.common.aspect.annotation.Dict; | |||
import org.jeecg.common.constant.ProvinceCityArea; | |||
import org.jeecg.common.util.SpringContextUtils; | |||
import io.swagger.v3.oas.annotations.media.Schema; | |||
/** | |||
* @Description: 题目 | |||
* @Author: jeecg-boot | |||
* @Date: 2025-08-20 | |||
* @Version: V1.0 | |||
*/ | |||
@Data | |||
@Schema(description="题目") | |||
public class AppletQuestionsPage { | |||
/**主键*/ | |||
@Schema(description = "主键") | |||
private java.lang.String id; | |||
/**创建人*/ | |||
@Schema(description = "创建人") | |||
private java.lang.String createBy; | |||
/**创建日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "创建日期") | |||
private java.util.Date createTime; | |||
/**更新人*/ | |||
@Schema(description = "更新人") | |||
private java.lang.String updateBy; | |||
/**更新日期*/ | |||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") | |||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") | |||
@Schema(description = "更新日期") | |||
private java.util.Date updateTime; | |||
/**所属部门*/ | |||
@Schema(description = "所属部门") | |||
private java.lang.String sysOrgCode; | |||
/**类型*/ | |||
@Excel(name = "类型", width = 15, dicCode = "applett_topic_type") | |||
@Dict(dicCode = "applett_topic_type") | |||
@Schema(description = "类型") | |||
private java.lang.String type; | |||
/**标题*/ | |||
@Excel(name = "标题", width = 15) | |||
@Schema(description = "标题") | |||
private java.lang.String text; | |||
/**描述*/ | |||
@Excel(name = "描述", width = 15) | |||
@Schema(description = "描述") | |||
private java.lang.String content; | |||
/**必填*/ | |||
@Schema(description = "必填") | |||
@Excel(name = "必填", width = 15,replace = {"是_Y","否_N"} ) | |||
private java.lang.String required; | |||
/**备注*/ | |||
@Excel(name = "备注", width = 15) | |||
@Schema(description = "备注") | |||
private java.lang.String remark; | |||
@ExcelCollection(name="题目选项") | |||
@Schema(description = "题目选项") | |||
private List<AppletQuestionsOptions> appletQuestionsOptionsList; | |||
} |
@ -0,0 +1,77 @@ | |||
import {defHttp} from '/@/utils/http/axios'; | |||
import { useMessage } from "/@/hooks/web/useMessage"; | |||
const { createConfirm } = useMessage(); | |||
enum Api { | |||
list = '/appletPaper/appletQuestions/list', | |||
save='/appletPaper/appletQuestions/add', | |||
edit='/appletPaper/appletQuestions/edit', | |||
deleteOne = '/appletPaper/appletQuestions/delete', | |||
deleteBatch = '/appletPaper/appletQuestions/deleteBatch', | |||
importExcel = '/appletPaper/appletQuestions/importExcel', | |||
exportXls = '/appletPaper/appletQuestions/exportXls', | |||
appletQuestionsOptionsList = '/appletPaper/appletQuestions/queryAppletQuestionsOptionsByMainId', | |||
} | |||
/** | |||
* 导出api | |||
* @param params | |||
*/ | |||
export const getExportUrl = Api.exportXls; | |||
/** | |||
* 导入api | |||
*/ | |||
export const getImportUrl = Api.importExcel; | |||
/** | |||
* 子表单查询接口 | |||
* @param params | |||
*/ | |||
export const queryAppletQuestionsOptions = Api.appletQuestionsOptionsList | |||
/** | |||
* 列表接口 | |||
* @param params | |||
*/ | |||
export const list = (params) => | |||
defHttp.get({url: Api.list, params}); | |||
/** | |||
* 删除单个 | |||
*/ | |||
export const deleteOne = (params,handleSuccess) => { | |||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { | |||
handleSuccess(); | |||
}); | |||
} | |||
/** | |||
* 批量删除 | |||
* @param params | |||
*/ | |||
export const batchDelete = (params, handleSuccess) => { | |||
createConfirm({ | |||
iconType: 'warning', | |||
title: '确认删除', | |||
content: '是否删除选中数据', | |||
okText: '确认', | |||
cancelText: '取消', | |||
onOk: () => { | |||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { | |||
handleSuccess(); | |||
}); | |||
} | |||
}); | |||
} | |||
/** | |||
* 保存或者更新 | |||
* @param params | |||
*/ | |||
export const saveOrUpdate = (params, isUpdate) => { | |||
let url = isUpdate ? Api.edit : Api.save; | |||
return defHttp.post({url: url, params}); | |||
} | |||
/** | |||
* 子表列表接口 | |||
* @param params | |||
*/ | |||
export const appletQuestionsOptionsList = (params) => | |||
defHttp.get({url: Api.appletQuestionsOptionsList, params},{isTransformResponse:false}); |
@ -0,0 +1,194 @@ | |||
import {BasicColumn} from '/@/components/Table'; | |||
import {FormSchema} from '/@/components/Table'; | |||
import { rules} from '/@/utils/helper/validator'; | |||
import { render } from '/@/utils/common/renderUtils'; | |||
import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types' | |||
import { getWeekMonthQuarterYear } from '/@/utils'; | |||
//列表数据 | |||
export const columns: BasicColumn[] = [ | |||
{ | |||
title: '类型', | |||
align:"center", | |||
dataIndex: 'type_dictText' | |||
}, | |||
{ | |||
title: '标题', | |||
align:"center", | |||
dataIndex: 'text' | |||
}, | |||
{ | |||
title: '描述', | |||
align:"center", | |||
dataIndex: 'content', | |||
}, | |||
{ | |||
title: '必填', | |||
align:"center", | |||
dataIndex: 'required', | |||
customRender:({text}) => { | |||
return render.renderSwitch(text, [{text:'是',value:'Y'},{text:'否',value:'N'}]) | |||
}, | |||
}, | |||
{ | |||
title: '备注', | |||
align:"center", | |||
dataIndex: 'remark' | |||
}, | |||
]; | |||
//查询数据 | |||
export const searchFormSchema: FormSchema[] = [ | |||
{ | |||
label: "类型", | |||
field: 'type', | |||
component: 'JSelectMultiple', | |||
componentProps:{ | |||
dictCode:"applett_topic_type" | |||
}, | |||
//colProps: {span: 6}, | |||
}, | |||
]; | |||
//表单数据 | |||
export const formSchema: FormSchema[] = [ | |||
{ | |||
label: '类型', | |||
field: 'type', | |||
component: 'JDictSelectTag', | |||
componentProps:{ | |||
dictCode:"applett_topic_type" | |||
}, | |||
}, | |||
{ | |||
label: '标题', | |||
field: 'text', | |||
component: 'Input', | |||
}, | |||
{ | |||
label: '描述', | |||
field: 'content', | |||
component: 'JEditor', | |||
}, | |||
{ | |||
label: '必填', | |||
field: 'required', | |||
component: 'JSwitch', | |||
componentProps:{ | |||
}, | |||
}, | |||
{ | |||
label: '备注', | |||
field: 'remark', | |||
component: 'Input', | |||
}, | |||
// TODO 主键隐藏字段,目前写死为ID | |||
{ | |||
label: '', | |||
field: 'id', | |||
component: 'Input', | |||
show: false | |||
}, | |||
]; | |||
//子表单数据 | |||
//子表列表数据 | |||
export const appletQuestionsOptionsColumns: BasicColumn[] = [ | |||
{ | |||
title: '选项内容', | |||
align:"center", | |||
dataIndex: 'content' | |||
}, | |||
{ | |||
title: '前缀文字', | |||
align:"center", | |||
dataIndex: 'prefix' | |||
}, | |||
{ | |||
title: '后缀文字', | |||
align:"center", | |||
dataIndex: 'suffix' | |||
}, | |||
{ | |||
title: '选中前图片', | |||
align:"center", | |||
dataIndex: 'image', | |||
customRender:render.renderImage, | |||
}, | |||
{ | |||
title: '选中后图片', | |||
align:"center", | |||
dataIndex: 'imageAfter' | |||
}, | |||
]; | |||
//子表表格配置 | |||
export const appletQuestionsOptionsJVxeColumns: JVxeColumn[] = [ | |||
{ | |||
title: '选项内容', | |||
key: 'content', | |||
type: JVxeTypes.input, | |||
width:"200px", | |||
placeholder: '请输入${title}', | |||
defaultValue:'', | |||
}, | |||
{ | |||
title: '前缀文字', | |||
key: 'prefix', | |||
type: JVxeTypes.input, | |||
width:"200px", | |||
placeholder: '请输入${title}', | |||
defaultValue:'', | |||
}, | |||
{ | |||
title: '后缀文字', | |||
key: 'suffix', | |||
type: JVxeTypes.input, | |||
width:"200px", | |||
placeholder: '请输入${title}', | |||
defaultValue:'', | |||
}, | |||
{ | |||
title: '选中前图片', | |||
key: 'image', | |||
type: JVxeTypes.image, | |||
token:true, | |||
responseName:"message", | |||
width:"200px", | |||
placeholder: '请输入${title}', | |||
defaultValue:'', | |||
}, | |||
{ | |||
title: '选中后图片', | |||
key: 'imageAfter', | |||
type: JVxeTypes.input, | |||
width:"200px", | |||
placeholder: '请输入${title}', | |||
defaultValue:'', | |||
}, | |||
] | |||
// 高级查询数据 | |||
export const superQuerySchema = { | |||
type: {title: '类型',order: 0,view: 'list', type: 'string',dictCode: 'applett_topic_type',}, | |||
text: {title: '标题',order: 1,view: 'text', type: 'string',}, | |||
content: {title: '描述',order: 2,view: 'umeditor', type: 'string',}, | |||
required: {title: '必填',order: 3,view: 'switch', type: 'string',}, | |||
remark: {title: '备注',order: 4,view: 'text', type: 'string',}, | |||
//子表高级查询 | |||
appletQuestionsOptions: { | |||
title: '题目选项', | |||
view: 'table', | |||
fields: { | |||
content: {title: '选项内容',order: 0,view: 'text', type: 'string',}, | |||
prefix: {title: '前缀文字',order: 1,view: 'text', type: 'string',}, | |||
suffix: {title: '后缀文字',order: 2,view: 'text', type: 'string',}, | |||
image: {title: '选中前图片',order: 3,view: 'image', type: 'string',}, | |||
imageAfter: {title: '选中后图片',order: 4,view: 'text', type: 'string',}, | |||
} | |||
}, | |||
}; | |||
/** | |||
* 流程表单调用这个方法获取formSchema | |||
* @param param | |||
*/ | |||
export function getBpmFormSchema(_formData): FormSchema[]{ | |||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema | |||
return formSchema; | |||
} |
@ -0,0 +1,231 @@ | |||
<template> | |||
<div> | |||
<!--引用表格--> | |||
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand"> | |||
<!-- 内嵌table区域 begin --> | |||
<template #expandedRowRender="{record}"> | |||
<a-tabs tabPosition="top"> | |||
<a-tab-pane tab="题目选项" key="appletQuestionsOptions" forceRender> | |||
<appletQuestionsOptionsSubTable v-if="expandedRowKeys.includes(record.id)" :id="record.id" /> | |||
</a-tab-pane> | |||
</a-tabs> | |||
</template> | |||
<!-- 内嵌table区域 end --> | |||
<!--插槽:table标题--> | |||
<template #tableTitle> | |||
<a-button type="primary" v-auth="'appletPaper:applet_questions:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button> | |||
<a-button type="primary" v-auth="'appletPaper:applet_questions:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button> | |||
<j-upload-button type="primary" v-auth="'appletPaper:applet_questions:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button> | |||
<a-dropdown v-if="selectedRowKeys.length > 0"> | |||
<template #overlay> | |||
<a-menu> | |||
<a-menu-item key="1" @click="batchHandleDelete"> | |||
<Icon icon="ant-design:delete-outlined"></Icon> | |||
删除 | |||
</a-menu-item> | |||
</a-menu> | |||
</template> | |||
<a-button v-auth="'appletPaper:applet_questions:deleteBatch'">批量操作 | |||
<Icon icon="mdi:chevron-down"></Icon> | |||
</a-button> | |||
</a-dropdown> | |||
<!-- 高级查询 --> | |||
<super-query :config="superQueryConfig" @search="handleSuperQuery" /> | |||
</template> | |||
<!--操作栏--> | |||
<template #action="{ record }"> | |||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/> | |||
</template> | |||
<!--字段回显插槽--> | |||
<template v-slot:bodyCell="{ column, record, index, text }"> | |||
<template v-if="column.dataIndex==='content'"> | |||
<!--富文本件字段回显插槽--> | |||
<div v-html="text"></div> | |||
</template> | |||
</template> | |||
</BasicTable> | |||
<!-- 表单区域 --> | |||
<AppletQuestionsModal @register="registerModal" @success="handleSuccess"></AppletQuestionsModal> | |||
</div> | |||
</template> | |||
<script lang="ts" name="appletPaper-appletQuestions" setup> | |||
import {ref, reactive, computed, unref} from 'vue'; | |||
import {BasicTable, useTable, TableAction} from '/@/components/Table'; | |||
import { useListPage } from '/@/hooks/system/useListPage' | |||
import {useModal} from '/@/components/Modal'; | |||
import { useMessage } from '/@/hooks/web/useMessage'; | |||
import AppletQuestionsModal from './components/AppletQuestionsModal.vue' | |||
import AppletQuestionsOptionsSubTable from './subTables/AppletQuestionsOptionsSubTable.vue' | |||
import {columns, searchFormSchema, superQuerySchema} from './AppletQuestions.data'; | |||
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './AppletQuestions.api'; | |||
import {downloadFile} from '/@/utils/common/renderUtils'; | |||
import { getDateByPicker } from '/@/utils'; | |||
//日期个性化选择 | |||
const fieldPickers = reactive({ | |||
}); | |||
import { useUserStore } from '/@/store/modules/user'; | |||
const queryParam = reactive<any>({}); | |||
// 展开key | |||
const expandedRowKeys = ref<any[]>([]); | |||
//注册model | |||
const [registerModal, {openModal}] = useModal(); | |||
const { createMessage } = useMessage(); | |||
const userStore = useUserStore(); | |||
//注册table数据 | |||
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({ | |||
tableProps:{ | |||
title: '题目', | |||
api: list, | |||
columns, | |||
canResize:true, | |||
formConfig: { | |||
//labelWidth: 120, | |||
schemas: searchFormSchema, | |||
autoSubmitOnEnter:true, | |||
showAdvancedButton:true, | |||
fieldMapToNumber: [ | |||
], | |||
fieldMapToTime: [ | |||
], | |||
}, | |||
actionColumn: { | |||
width: 120, | |||
fixed:'right' | |||
}, | |||
beforeFetch: (params) => { | |||
if (params && fieldPickers) { | |||
for (let key in fieldPickers) { | |||
if (params[key]) { | |||
params[key] = getDateByPicker(params[key], fieldPickers[key]); | |||
} | |||
} | |||
} | |||
return Object.assign(params, queryParam); | |||
}, | |||
}, | |||
exportConfig: { | |||
name:"题目", | |||
url: getExportUrl, | |||
params: queryParam, | |||
}, | |||
importConfig: { | |||
url: getImportUrl, | |||
success: handleSuccess | |||
}, | |||
}) | |||
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext | |||
// 高级查询配置 | |||
const superQueryConfig = reactive(superQuerySchema); | |||
/** | |||
* 高级查询事件 | |||
*/ | |||
function handleSuperQuery(params) { | |||
Object.keys(params).map((k) => { | |||
queryParam[k] = params[k]; | |||
}); | |||
reload(); | |||
} | |||
/** | |||
* 展开事件 | |||
* */ | |||
function handleExpand(expanded, record){ | |||
expandedRowKeys.value=[]; | |||
if (expanded === true) { | |||
expandedRowKeys.value.push(record.id) | |||
} | |||
} | |||
/** | |||
* 新增事件 | |||
*/ | |||
function handleAdd() { | |||
openModal(true, { | |||
isUpdate: false, | |||
showFooter: true, | |||
}); | |||
} | |||
/** | |||
* 编辑事件 | |||
*/ | |||
function handleEdit(record: Recordable) { | |||
openModal(true, { | |||
record, | |||
isUpdate: true, | |||
showFooter: true, | |||
}); | |||
} | |||
/** | |||
* 详情 | |||
*/ | |||
function handleDetail(record: Recordable) { | |||
openModal(true, { | |||
record, | |||
isUpdate: true, | |||
showFooter: false, | |||
}); | |||
} | |||
/** | |||
* 删除事件 | |||
*/ | |||
async function handleDelete(record) { | |||
await deleteOne({id: record.id}, handleSuccess); | |||
} | |||
/** | |||
* 批量删除事件 | |||
*/ | |||
async function batchHandleDelete() { | |||
await batchDelete({ids: selectedRowKeys.value},handleSuccess); | |||
} | |||
/** | |||
* 成功回调 | |||
*/ | |||
function handleSuccess() { | |||
(selectedRowKeys.value = []) && reload(); | |||
} | |||
/** | |||
* 操作栏 | |||
*/ | |||
function getTableAction(record){ | |||
return [ | |||
{ | |||
label: '编辑', | |||
onClick: handleEdit.bind(null, record), | |||
auth: 'appletPaper:applet_questions:edit' | |||
} | |||
] | |||
} | |||
/** | |||
* 下拉操作栏 | |||
*/ | |||
function getDropDownAction(record){ | |||
return [ | |||
{ | |||
label: '详情', | |||
onClick: handleDetail.bind(null, record), | |||
}, { | |||
label: '删除', | |||
popConfirm: { | |||
title: '是否确认删除', | |||
confirm: handleDelete.bind(null, record), | |||
placement: 'topLeft' | |||
}, | |||
auth: 'appletPaper:applet_questions:delete' | |||
} | |||
] | |||
} | |||
</script> | |||
<style lang="less" scoped> | |||
:deep(.ant-picker),:deep(.ant-input-number){ | |||
width: 100%; | |||
} | |||
</style> |
@ -0,0 +1,26 @@ | |||
-- 注意:该页面对应的前台目录为views/appletPaper文件夹下 | |||
-- 如果你想更改到其他目录,请修改sql中component字段对应的值 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external) | |||
VALUES ('2025082004218580380', NULL, '试卷', '/appletPaper/appletPaperList', 'appletPaper/AppletPaperList', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0); | |||
-- 权限控制sql | |||
-- 新增 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004218580381', '2025082004218580380', '添加试卷', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_paper:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0, 0, '1', 0); | |||
-- 编辑 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004218580382', '2025082004218580380', '编辑试卷', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_paper:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0, 0, '1', 0); | |||
-- 删除 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004218580383', '2025082004218580380', '删除试卷', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_paper:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0, 0, '1', 0); | |||
-- 批量删除 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004218580384', '2025082004218580380', '批量删除试卷', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_paper:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0, 0, '1', 0); | |||
-- 导出excel | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004218580385', '2025082004218580380', '导出excel_试卷', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_paper:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0, 0, '1', 0); | |||
-- 导入excel | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004218580386', '2025082004218580380', '导入excel_试卷', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_paper:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:21:38', NULL, NULL, 0, 0, '1', 0); |
@ -0,0 +1,26 @@ | |||
-- 注意:该页面对应的前台目录为views/appletPaper文件夹下 | |||
-- 如果你想更改到其他目录,请修改sql中component字段对应的值 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external) | |||
VALUES ('2025082004325090560', NULL, '题目', '/appletPaper/appletQuestionsList', 'appletPaper/AppletQuestionsList', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0); | |||
-- 权限控制sql | |||
-- 新增 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004325090561', '2025082004325090560', '添加题目', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_questions:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0, 0, '1', 0); | |||
-- 编辑 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004325090562', '2025082004325090560', '编辑题目', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_questions:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0, 0, '1', 0); | |||
-- 删除 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004325090563', '2025082004325090560', '删除题目', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_questions:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0, 0, '1', 0); | |||
-- 批量删除 | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004325090564', '2025082004325090560', '批量删除题目', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_questions:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0, 0, '1', 0); | |||
-- 导出excel | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004325100565', '2025082004325090560', '导出excel_题目', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_questions:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0, 0, '1', 0); | |||
-- 导入excel | |||
INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) | |||
VALUES ('2025082004325100566', '2025082004325090560', '导入excel_题目', NULL, NULL, 0, NULL, NULL, 2, 'appletPaper:applet_questions:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-08-20 16:32:56', NULL, NULL, 0, 0, '1', 0); |
@ -1,70 +1,171 @@ | |||
<template> | |||
<div style="min-height: 400px"> | |||
<BasicForm @register="registerForm"></BasicForm> | |||
<div style="width: 100%;text-align: center" v-if="!formDisabled"> | |||
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button> | |||
</div> | |||
<div> | |||
<!-- 子表单区域 --> | |||
<a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs"> | |||
<!--主表区域 --> | |||
<a-tab-pane tab="试卷" :key="refKeys[0]" :forceRender="true" :style="tabsStyle"> | |||
<BasicForm @register="registerForm" ref="formRef"/> | |||
</a-tab-pane> | |||
<!--子表单区域 --> | |||
<a-tab-pane tab="题目分类" key="appletQuestionsCategory" :forceRender="true" :style="tabsStyle"> | |||
<JVxeTable | |||
keep-source | |||
resizable | |||
ref="appletQuestionsCategory" | |||
v-if="appletQuestionsCategoryTable.show" | |||
:loading="appletQuestionsCategoryTable.loading" | |||
:columns="appletQuestionsCategoryTable.columns" | |||
:dataSource="appletQuestionsCategoryTable.dataSource" | |||
:height="340" | |||
:disabled="formDisabled" | |||
:rowNumber="true" | |||
:rowSelection="true" | |||
:toolbar="true" | |||
/> | |||
</a-tab-pane> | |||
</a-tabs> | |||
<div style="width: 100%;text-align: center;margin-top: 10px;" v-if="showFlowSubmitButton"> | |||
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="handleSubmit">提 交</a-button> | |||
</div> | |||
</div> | |||
</template> | |||
<script lang="ts"> | |||
<script lang="ts" setup> | |||
import { defHttp } from '/@/utils/http/axios'; | |||
import {ref, computed, unref,reactive, onMounted, defineProps } from 'vue'; | |||
import {BasicForm, useForm} from '/@/components/Form/index'; | |||
import {computed, defineComponent} from 'vue'; | |||
import {defHttp} from '/@/utils/http/axios'; | |||
import { propTypes } from '/@/utils/propTypes'; | |||
import {getBpmFormSchema} from '../AppletPaper.data'; | |||
import {saveOrUpdate} from '../AppletPaper.api'; | |||
import { JVxeTable } from '/@/components/jeecg/JVxeTable' | |||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts' | |||
import {formSchema,appletQuestionsCategoryColumns} from '../AppletPaper.data'; | |||
import {saveOrUpdate,appletQuestionsCategoryList} from '../AppletPaper.api'; | |||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils' | |||
const refKeys = ref(['appletPaper','appletQuestionsCategory', ]); | |||
const activeKey = ref('appletPaper'); | |||
const appletQuestionsCategory = ref(); | |||
const tableRefs = {appletQuestionsCategory, }; | |||
const appletQuestionsCategoryTable = reactive({ | |||
loading: false, | |||
dataSource: [], | |||
columns:appletQuestionsCategoryColumns, | |||
show: false | |||
}) | |||
const props = defineProps({ | |||
formData: { type: Object, default: ()=>{} }, | |||
formBpm: { type: Boolean, default: true } | |||
}); | |||
const formDisabled = computed(()=>{ | |||
if(props.formBpm === true){ | |||
if(props.formData.disabled === false){ | |||
return false; | |||
} | |||
} | |||
return true; | |||
}); | |||
// 是否显示提交按钮 | |||
const showFlowSubmitButton = computed(()=>{ | |||
if(props.formBpm === true){ | |||
if(props.formData.disabled === false){ | |||
return true | |||
} | |||
} | |||
return false | |||
}); | |||
export default defineComponent({ | |||
name: "AppletPaperForm", | |||
components:{ | |||
BasicForm | |||
}, | |||
props:{ | |||
formData: propTypes.object.def({}), | |||
formBpm: propTypes.bool.def(true), | |||
}, | |||
setup(props){ | |||
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({ | |||
labelWidth: 150, | |||
schemas: getBpmFormSchema(props.formData), | |||
showActionButtonGroup: false, | |||
baseColProps: {span: 24} | |||
}); | |||
//表单配置 | |||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({ | |||
labelWidth: 150, | |||
schemas: formSchema, | |||
showActionButtonGroup: false, | |||
baseColProps: {span: 24} | |||
}); | |||
const formDisabled = computed(()=>{ | |||
if(props.formData.disabled === false){ | |||
return false; | |||
} | |||
return true; | |||
}); | |||
onMounted(()=>{ | |||
initFormData(); | |||
}); | |||
//渲染流程表单数据 | |||
const queryByIdUrl = '/appletPaper/appletPaper/queryById'; | |||
async function initFormData(){ | |||
if(props.formBpm === true){ | |||
await reset(); | |||
let params = {id: props.formData.dataId}; | |||
const data = await defHttp.get({url: queryByIdUrl, params}); | |||
//表单赋值 | |||
await setFieldsValue({ | |||
...data | |||
}); | |||
requestSubTableData(appletQuestionsCategoryList, {id: data.id}, appletQuestionsCategoryTable, ()=>{ | |||
appletQuestionsCategoryTable.show = true; | |||
}) | |||
// 隐藏底部时禁用整个表单 | |||
setProps({ disabled: formDisabled.value }) | |||
} | |||
} | |||
let formData = {}; | |||
const queryByIdUrl = '/appletPaper/appletPaper/queryById'; | |||
async function initFormData(){ | |||
let params = {id: props.formData.dataId}; | |||
const data = await defHttp.get({url: queryByIdUrl, params}); | |||
formData = {...data} | |||
//设置表单的值 | |||
await setFieldsValue(formData); | |||
//默认是禁用 | |||
await setProps({disabled: formDisabled.value}) | |||
} | |||
//方法配置 | |||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys); | |||
// 弹窗tabs滚动区域的高度 | |||
const tabsStyle = computed(() => { | |||
let height: Nullable<string> = null | |||
let minHeight = '100px' | |||
// 弹窗wrapper | |||
let overflow = 'auto'; | |||
return {height, minHeight, overflow}; | |||
}) | |||
async function submitForm() { | |||
let data = getFieldsValue(); | |||
let params = Object.assign({}, formData, data); | |||
console.log('表单数据', params) | |||
await saveOrUpdate(params, true) | |||
} | |||
async function reset(){ | |||
await resetFields(); | |||
activeKey.value = 'appletPaper'; | |||
appletQuestionsCategoryTable.dataSource = []; | |||
} | |||
function classifyIntoFormData(allValues) { | |||
let main = Object.assign({}, allValues.formValue) | |||
return { | |||
...main, // 展开 | |||
appletQuestionsCategoryList: allValues.tablesValue[0].tableData, | |||
} | |||
} | |||
//表单提交事件 | |||
async function requestAddOrEdit(values) { | |||
//提交表单 | |||
await saveOrUpdate(values, true); | |||
} | |||
</script> | |||
initFormData(); | |||
return { | |||
registerForm, | |||
formDisabled, | |||
submitForm, | |||
} | |||
} | |||
}); | |||
</script> | |||
<style lang="less" scoped> | |||
/** 时间和数字输入框样式 */ | |||
:deep(.ant-input-number) { | |||
width: 100%; | |||
} | |||
:deep(.ant-calendar-picker) { | |||
width: 100%; | |||
} | |||
</style> | |||
<style lang="less"> | |||
// Online表单Tab风格专属样式 | |||
.j-cgform-tab-modal { | |||
.ant-modal-header { | |||
padding-top: 8px; | |||
padding-bottom: 8px; | |||
border-bottom: none !important; | |||
} | |||
.ant-modal .ant-modal-body > .scrollbar, | |||
.ant-tabs-nav .ant-tabs-tab { | |||
padding-top: 0; | |||
} | |||
.ant-tabs-top-bar { | |||
width: calc(100% - 55px); | |||
position: relative; | |||
left: -14px; | |||
} | |||
.ant-tabs .ant-tabs-top-content > .ant-tabs-tabpane { | |||
overflow: hidden auto; | |||
} | |||
} | |||
</style> |
@ -0,0 +1,134 @@ | |||
<template> | |||
<div> | |||
<BasicForm @register="registerForm" ref="formRef"/> | |||
<!-- 子表单区域 --> | |||
<a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs"> | |||
<a-tab-pane tab="题目选项" key="appletQuestionsOptions" :forceRender="true"> | |||
<JVxeTable | |||
v-if="appletQuestionsOptionsTable.show" | |||
keep-source | |||
resizable | |||
ref="appletQuestionsOptions" | |||
:loading="appletQuestionsOptionsTable.loading" | |||
:columns="appletQuestionsOptionsTable.columns" | |||
:dataSource="appletQuestionsOptionsTable.dataSource" | |||
:height="340" | |||
:disabled="formDisabled" | |||
:rowNumber="true" | |||
:rowSelection="true" | |||
:toolbar="true" | |||
/> | |||
</a-tab-pane> | |||
</a-tabs> | |||
<div style="width: 100%;text-align: center;margin-top: 10px;" v-if="showFlowSubmitButton"> | |||
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="handleSubmit">提 交</a-button> | |||
</div> | |||
</div> | |||
</template> | |||
<script lang="ts" setup> | |||
import { defHttp } from '/@/utils/http/axios'; | |||
import {ref, computed, unref,reactive, onMounted, defineProps } from 'vue'; | |||
import {BasicForm, useForm} from '/@/components/Form/index'; | |||
import { JVxeTable } from '/@/components/jeecg/JVxeTable' | |||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts' | |||
import {formSchema,appletQuestionsOptionsJVxeColumns} from '../AppletQuestions.data'; | |||
import {saveOrUpdate,queryAppletQuestionsOptions} from '../AppletQuestions.api'; | |||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils' | |||
const isUpdate = ref(true); | |||
const refKeys = ref(['appletQuestionsOptions', ]); | |||
const activeKey = ref('appletQuestionsOptions'); | |||
const appletQuestionsOptions = ref(); | |||
const tableRefs = {appletQuestionsOptions, }; | |||
const appletQuestionsOptionsTable = reactive({ | |||
loading: false, | |||
dataSource: [], | |||
columns:appletQuestionsOptionsJVxeColumns, | |||
show: false | |||
}) | |||
const props = defineProps({ | |||
formData: { type: Object, default: ()=>{} }, | |||
formBpm: { type: Boolean, default: true } | |||
}); | |||
const formDisabled = computed(()=>{ | |||
if(props.formBpm === true){ | |||
if(props.formData.disabled === false){ | |||
return false; | |||
} | |||
} | |||
return true; | |||
}); | |||
// 是否显示提交按钮 | |||
const showFlowSubmitButton = computed(()=>{ | |||
if(props.formBpm === true){ | |||
if(props.formData.disabled === false){ | |||
return true | |||
} | |||
} | |||
return false | |||
}); | |||
//表单配置 | |||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({ | |||
labelWidth: 150, | |||
schemas: formSchema, | |||
showActionButtonGroup: false, | |||
baseColProps: {span: 24} | |||
}); | |||
onMounted(()=>{ | |||
initFormData(); | |||
}); | |||
//渲染流程表单数据 | |||
const queryByIdUrl = '/appletPaper/appletQuestions/queryById'; | |||
async function initFormData(){ | |||
if(props.formBpm === true){ | |||
await reset(); | |||
let params = {id: props.formData.dataId}; | |||
const data = await defHttp.get({url: queryByIdUrl, params}); | |||
//表单赋值 | |||
await setFieldsValue({ | |||
...data | |||
}); | |||
requestSubTableData(queryAppletQuestionsOptions, {id: data.id}, appletQuestionsOptionsTable, ()=>{ | |||
appletQuestionsOptionsTable.show = true; | |||
}); | |||
// 隐藏底部时禁用整个表单 | |||
setProps({ disabled: formDisabled.value }) | |||
} | |||
} | |||
//方法配置 | |||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys); | |||
async function reset(){ | |||
await resetFields(); | |||
activeKey.value = 'appletQuestionsOptions'; | |||
appletQuestionsOptionsTable.dataSource = []; | |||
} | |||
function classifyIntoFormData(allValues) { | |||
let main = Object.assign({}, allValues.formValue) | |||
return { | |||
...main, // 展开 | |||
appletQuestionsOptionsList: allValues.tablesValue[0].tableData, | |||
} | |||
} | |||
//表单提交事件 | |||
async function requestAddOrEdit(values) { | |||
//提交表单 | |||
await saveOrUpdate(values, true); | |||
} | |||
</script> | |||
<style lang="less" scoped> | |||
/** 时间和数字输入框样式 */ | |||
:deep(.ant-input-number) { | |||
width: 100%; | |||
} | |||
:deep(.ant-calendar-picker) { | |||
width: 100%; | |||
} | |||
</style> |
@ -0,0 +1,148 @@ | |||
<template> | |||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit"> | |||
<BasicForm @register="registerForm" ref="formRef" name="AppletQuestionsForm" /> | |||
<!-- 子表单区域 --> | |||
<a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs"> | |||
<a-tab-pane tab="题目选项" key="appletQuestionsOptions" :forceRender="true"> | |||
<JVxeTable | |||
keep-source | |||
resizable | |||
ref="appletQuestionsOptions" | |||
:loading="appletQuestionsOptionsTable.loading" | |||
:columns="appletQuestionsOptionsTable.columns" | |||
:dataSource="appletQuestionsOptionsTable.dataSource" | |||
:height="340" | |||
:disabled="formDisabled" | |||
:rowNumber="true" | |||
:rowSelection="true" | |||
:toolbar="true" | |||
/> | |||
</a-tab-pane> | |||
</a-tabs> | |||
</BasicModal> | |||
</template> | |||
<script lang="ts" setup> | |||
import {ref, computed, unref,reactive} from 'vue'; | |||
import {BasicModal, useModalInner} from '/@/components/Modal'; | |||
import {BasicForm, useForm} from '/@/components/Form/index'; | |||
import { JVxeTable } from '/@/components/jeecg/JVxeTable' | |||
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts' | |||
import {formSchema,appletQuestionsOptionsJVxeColumns} from '../AppletQuestions.data'; | |||
import {saveOrUpdate,queryAppletQuestionsOptions} from '../AppletQuestions.api'; | |||
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils' | |||
import { useMessage } from '/@/hooks/web/useMessage'; | |||
import { getDateByPicker } from '/@/utils'; | |||
//日期个性化选择 | |||
const fieldPickers = reactive({ | |||
}); | |||
const appletQuestionsOptionsFieldPickers = reactive({ | |||
}); | |||
const { createMessage } = useMessage(); | |||
// Emits声明 | |||
const emit = defineEmits(['register','success']); | |||
const isUpdate = ref(true); | |||
const formDisabled = ref(false); | |||
const refKeys = ref(['appletQuestionsOptions', ]); | |||
const activeKey = ref('appletQuestionsOptions'); | |||
const appletQuestionsOptions = ref(); | |||
const tableRefs = {appletQuestionsOptions, }; | |||
const appletQuestionsOptionsTable = reactive({ | |||
loading: false, | |||
dataSource: [], | |||
columns:appletQuestionsOptionsJVxeColumns | |||
}) | |||
//表单配置 | |||
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({ | |||
labelWidth: 150, | |||
schemas: formSchema, | |||
showActionButtonGroup: false, | |||
baseColProps: {span: 24} | |||
}); | |||
//表单赋值 | |||
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { | |||
//重置表单 | |||
await reset(); | |||
setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter}); | |||
isUpdate.value = !!data?.isUpdate; | |||
formDisabled.value = !data?.showFooter; | |||
if (unref(isUpdate)) { | |||
//表单赋值 | |||
await setFieldsValue({ | |||
...data.record, | |||
}); | |||
requestSubTableData(queryAppletQuestionsOptions, {id:data?.record?.id}, appletQuestionsOptionsTable) | |||
} | |||
// 隐藏底部时禁用整个表单 | |||
setProps({ disabled: !data?.showFooter }) | |||
}); | |||
//方法配置 | |||
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys); | |||
//设置标题 | |||
const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(formDisabled) ? '编辑' : '详情')); | |||
async function reset(){ | |||
await resetFields(); | |||
activeKey.value = 'appletQuestionsOptions'; | |||
appletQuestionsOptionsTable.dataSource = []; | |||
} | |||
function classifyIntoFormData(allValues) { | |||
let main = Object.assign({}, allValues.formValue) | |||
return { | |||
...main, // 展开 | |||
appletQuestionsOptionsList: allValues.tablesValue[0].tableData, | |||
} | |||
} | |||
//表单提交事件 | |||
async function requestAddOrEdit(values) { | |||
try { | |||
// 预处理日期数据 | |||
changeDateValue(values); | |||
setModalProps({confirmLoading: true}); | |||
//提交表单 | |||
await saveOrUpdate(values, isUpdate.value); | |||
//关闭弹窗 | |||
closeModal(); | |||
//刷新列表 | |||
emit('success'); | |||
} finally { | |||
setModalProps({confirmLoading: false}); | |||
} | |||
} | |||
/** | |||
* 处理日期值 | |||
* @param formData 表单数据 | |||
*/ | |||
const changeDateValue = (formData) => { | |||
if (formData && fieldPickers) { | |||
for (let key in fieldPickers) { | |||
if (formData[key]) { | |||
formData[key] = getDateByPicker(formData[key], fieldPickers[key]); | |||
} | |||
} | |||
} | |||
if(formData && formData.appletQuestionsOptionsList && formData.appletQuestionsOptionsList.length > 0){ | |||
formData.appletQuestionsOptionsList.forEach(subFormData=>{ | |||
for (let key in appletQuestionsOptionsFieldPickers) { | |||
if (subFormData[key]) { | |||
subFormData[key] = getDateByPicker(subFormData[key], appletQuestionsOptionsFieldPickers[key]); | |||
} | |||
} | |||
}) | |||
} | |||
}; | |||
</script> | |||
<style lang="less" scoped> | |||
/** 时间和数字输入框样式 */ | |||
:deep(.ant-input-number) { | |||
width: 100%; | |||
} | |||
:deep(.ant-calendar-picker) { | |||
width: 100%; | |||
} | |||
</style> |
@ -0,0 +1,44 @@ | |||
<template> | |||
<div> | |||
<!--引用表格--> | |||
<BasicTable bordered size="middle" :loading="loading" rowKey="id" :canResize="true" :columns="appletQuestionsOptionsColumns" :dataSource="dataSource" :pagination="false"> | |||
<!--字段回显插槽--> | |||
<template v-slot:bodyCell="{ column, record, index, text }"> | |||
</template> | |||
</BasicTable> | |||
</div> | |||
</template> | |||
<script lang="ts" setup> | |||
import {ref,watchEffect} from 'vue'; | |||
import {BasicTable} from '/@/components/Table'; | |||
import {appletQuestionsOptionsColumns} from '../AppletQuestions.data'; | |||
import {appletQuestionsOptionsList} from '../AppletQuestions.api'; | |||
import { downloadFile } from '/@/utils/common/renderUtils'; | |||
const props = defineProps({ | |||
id: { | |||
type: String, | |||
default: '', | |||
}, | |||
}) | |||
const loading = ref(false); | |||
const dataSource = ref([]); | |||
watchEffect(() => { | |||
props.id && loadData(props.id); | |||
}); | |||
function loadData(id) { | |||
dataSource.value = [] | |||
loading.value = true | |||
appletQuestionsOptionsList({id}).then((res) => { | |||
if (res.success) { | |||
dataSource.value = res.result.records | |||
} | |||
}).finally(() => { | |||
loading.value = false | |||
}) | |||
} | |||
</script> |