| | |
| | | */ |
| | | //@PreAuthorize("@ss.hasPermi('hosp:question:query')") |
| | | @GetMapping(value = "/{qid}") |
| | | public AjaxResult getInfo(@PathVariable("qid") Long qid) { |
| | | public AjaxResult getInfo(@PathVariable("qid") String qid) { |
| | | return success(tjSurveyQuestionService.selectTjSurveyQuestionByQid(qid)); |
| | | } |
| | | |
| | |
| | | //@PreAuthorize("@ss.hasPermi('hosp:question:remove')") |
| | | @Log(title = "问卷问题", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{qids}") |
| | | public AjaxResult remove(@PathVariable Long[] qids) { |
| | | public AjaxResult remove(@PathVariable String[] qids) { |
| | | return toAjax(tjSurveyQuestionService.deleteTjSurveyQuestionByQids(qids)); |
| | | } |
| | | } |
| | |
| | | import java.util.Map; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | import cn.hutool.core.date.DateTime; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ltkj.hosp.domain.TjSurveyOptions; |
| | | import com.ltkj.hosp.domain.TjSurveyQuestion; |
| | | import com.ltkj.hosp.domain.TjSurveyTempQues; |
| | | import com.ltkj.hosp.service.ITjSurveyQuestionService; |
| | | import com.ltkj.system.service.ISysConfigService; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | import com.ltkj.tduck.enums.FormSourceTypeEnum; |
| | | import com.ltkj.tduck.enums.FormStatusEnum; |
| | | import com.ltkj.tduck.service.UserFormService; |
| | | import com.ltkj.tduck.utils.ShortIdUtils; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | |
| | | |
| | | @Autowired |
| | | private ITjSurveyQuestionService tjSurveyQuestionService; |
| | | @Autowired |
| | | private ISysConfigService configService; |
| | | |
| | | @Autowired |
| | | private UserFormService formService; |
| | | |
| | | |
| | | /** |
| | | * 判断是否开启填鸭表单设计 |
| | | */ |
| | | @ApiOperation(value = "判断是否开启填鸭表单设计") |
| | | @GetMapping(value = "/needDesign") |
| | | public AjaxResult needDesign() { |
| | | final String call = configService.selectConfigByKey("need_design"); |
| | | return AjaxResult.success(call); |
| | | } |
| | | |
| | | /** |
| | | * 判断该模板是否可删除 |
| | | */ |
| | | @ApiOperation(value = "判断该模板是否可删除") |
| | | @GetMapping(value = "/canDelete") |
| | | public AjaxResult canDelete(Long id) { |
| | | // List<FwdPlanInfoVo> fwdPlanInfoVos = fwdSqlMapper.canDelete(id); |
| | | // if (fwdPlanInfoVos!=null && fwdPlanInfoVos.size()>0){ |
| | | // return AjaxResult.success(false); |
| | | // } |
| | | return AjaxResult.success(false); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 查询问卷模板列表 |
| | |
| | | return success(tjSurveyTemplateService.selectTjSurveyTemplateByMid(mid)); |
| | | } |
| | | |
| | | /** |
| | | * 获取问卷模板 |
| | | */ |
| | | // /** |
| | | // * 获取问卷模板 |
| | | // */ |
| | | // @GetMapping("/getQuesByMid") |
| | | // @ApiOperation(value = "获取问卷模板信息") |
| | | // public AjaxResult getQuesByMid(@RequestParam Long mid) { |
| | | // List<TjSurveyQuestion> l1=new ArrayList<>(); |
| | | // TjSurveyTemplate byId = tjSurveyTemplateService.selectTjSurveyTemplateByMid(mid); |
| | | // List<TjSurveyTempQues> tjSurveyTempQuesList = byId.getTjSurveyTempQuesList(); |
| | | // if (tjSurveyTempQuesList!=null){ |
| | | // for (TjSurveyTempQues tjSurveyTempQues : tjSurveyTempQuesList) { |
| | | // TjSurveyQuestion byId1 = tjSurveyQuestionService.selectTjSurveyQuestionByQid(tjSurveyTempQues.getQid()); |
| | | // if (byId1!=null){ |
| | | // l1.add(byId1); |
| | | // } |
| | | // } |
| | | // return AjaxResult.success(l1); |
| | | // } |
| | | // return AjaxResult.success("暂无信息"); |
| | | // } |
| | | |
| | | @GetMapping("/getQuesByMid") |
| | | @ApiOperation(value = "获取问卷模板信息") |
| | | public AjaxResult getQuesByMid(@RequestParam Long mid) { |
| | | List<TjSurveyQuestion> l1=new ArrayList<>(); |
| | | TjSurveyTemplate byId = tjSurveyTemplateService.selectTjSurveyTemplateByMid(mid); |
| | | List<TjSurveyTempQues> tjSurveyTempQuesList = byId.getTjSurveyTempQuesList(); |
| | | if (tjSurveyTempQuesList!=null){ |
| | | for (TjSurveyTempQues tjSurveyTempQues : tjSurveyTempQuesList) { |
| | | TjSurveyQuestion byId1 = tjSurveyQuestionService.selectTjSurveyQuestionByQid(tjSurveyTempQues.getQid()); |
| | | if (byId1!=null){ |
| | | l1.add(byId1); |
| | | TjSurveyTemplate byId = tjSurveyTemplateService.selectTemplateByMid1(Long.valueOf(mid)); |
| | | if(null !=byId){ |
| | | if ("1".equals(byId.getQybz())){ |
| | | return AjaxResult.success("该问卷模板不存在或已停用"); |
| | | } |
| | | //判断是否有问题 |
| | | if(byId.getDesignId()!=null){ |
| | | return AjaxResult.success(byId.getDesignId()); |
| | | } |
| | | return AjaxResult.success(l1); |
| | | LambdaQueryWrapper<TjSurveyQuestion> wq1=new LambdaQueryWrapper<>(); |
| | | wq1.eq(TjSurveyQuestion::getMid,byId.getMid()); |
| | | final List<TjSurveyQuestion> list1 = tjSurveyQuestionService.list(wq1); |
| | | for (TjSurveyQuestion tjSurveyQuestion : list1) { |
| | | final List<TjSurveyOptions> tjSurveyOptions = tjSurveyQuestionService.selectOptionsByQid(tjSurveyQuestion.getQid()); |
| | | tjSurveyQuestion.setTjSurveyOptionsList(tjSurveyOptions); |
| | | } |
| | | return AjaxResult.success(list1); |
| | | |
| | | } |
| | | return AjaxResult.success("暂无信息"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 新增问卷模板 |
| | |
| | | @Log(title = "问卷模板", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public AjaxResult add(@RequestBody TjSurveyTemplate tjSurveyTemplate) { |
| | | return toAjax(tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate)); |
| | | // return toAjax(tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate)); |
| | | final String call = configService.selectConfigByKey("need_design"); |
| | | //判断是否开启填鸭表单设计 |
| | | if ("true".equals(call)){ |
| | | UserFormEntity form=new UserFormEntity(); |
| | | form.setFormKey(ShortIdUtils.genId()); |
| | | form.setName("<h2 style=\"text-align: center;\">"+tjSurveyTemplate.getTempName()+"</h2>"); |
| | | form.setStatus(1); |
| | | form.setSourceType(1); |
| | | form.setCreateTime(new DateTime()); |
| | | form.setType("1"); |
| | | form.setDeleted(false); |
| | | final boolean save = formService.save(form); |
| | | if (save){ |
| | | tjSurveyTemplate.setDesignId(form.getFormKey()); |
| | | final int i = tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate); |
| | | if (i==1) { |
| | | return AjaxResult.success(form); |
| | | } |
| | | } |
| | | }else{ |
| | | final int i = tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate); |
| | | if (i==1) { |
| | | return AjaxResult.success(false); |
| | | } |
| | | } |
| | | return AjaxResult.success(false); |
| | | } |
| | | |
| | | /** |
| | |
| | | public AjaxResult remove(@PathVariable Long[] mids) { |
| | | return toAjax(tjSurveyTemplateService.deleteTjSurveyTemplateByMids(mids)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 问卷启用禁用 |
| | | */ |
| | | @GetMapping("/updateQybz") |
| | | @ApiOperation(value = "问卷启用禁用") |
| | | public AjaxResult updateQybz(@RequestParam Long mid,@RequestParam String qybz) { |
| | | final TjSurveyTemplate byId = tjSurveyTemplateService.selectTemplateByMid1(mid); |
| | | byId.setQybz(qybz); |
| | | if ("0".equals(qybz) && tjSurveyTemplateService.qybzTjSurveyTemplateByQy(byId.getMid())==1){ |
| | | return AjaxResult.success("启用成功!"); |
| | | }else if ("1".equals(qybz) && tjSurveyTemplateService.qybzTjSurveyTemplateByJy(byId.getMid())==1){ |
| | | return AjaxResult.success("禁用成功!"); |
| | | }else { |
| | | return AjaxResult.error("出错了,请联系工作人员!"); |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.web.tduck; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.json.JSONObject; |
| | | import cn.hutool.json.JSONUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.ltkj.common.core.domain.AjaxResult; |
| | | import com.ltkj.tduck.constant.CommonConstants; |
| | | import com.ltkj.tduck.domain.*; |
| | | import com.ltkj.tduck.enums.FormStatusEnum; |
| | | import com.ltkj.tduck.enums.FormTypeEnum; |
| | | import com.ltkj.tduck.request.QueryFormItemRequest; |
| | | import com.ltkj.tduck.request.QueryFormRequest; |
| | | import com.ltkj.tduck.request.QueryFormTemplateTypeRequest; |
| | | import com.ltkj.tduck.request.SortFormItemRequest; |
| | | import com.ltkj.tduck.service.*; |
| | | import com.ltkj.tduck.utils.FormDataUtils; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import com.ltkj.tduck.utils.SortUtils; |
| | | import com.ltkj.tduck.utils.ValidatorUtils; |
| | | import com.ltkj.tduck.vo.FormFieldVO; |
| | | import com.ltkj.tduck.vo.OperateFormItemVO; |
| | | import com.ltkj.tduck.vo.UserFormDetailVO; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.annotation.security.PermitAll; |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.util.ArrayList; |
| | | import java.util.Comparator; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * 用户表单 |
| | | **/ |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @Slf4j |
| | | //@RequestMapping("/tduck-api") |
| | | public class UserFormController { |
| | | @Resource |
| | | private final UserFormService formService; |
| | | @Resource |
| | | private final UserFormItemService formItemService; |
| | | @Resource |
| | | private final FormTemplateCategoryService formTemplateCategoryService; |
| | | @Resource |
| | | private final SortUtils sortUtils; |
| | | |
| | | private final UserFormThemeService userFormThemeService; |
| | | private final UserFormLogicService userFormLogicService; |
| | | |
| | | |
| | | /** |
| | | * 查询表单 |
| | | */ |
| | | @GetMapping("/user/form/{key}") |
| | | public AjaxResult queryFormByKey(@PathVariable @NotBlank String key) { |
| | | return AjaxResult.success(formService.getByKey(key)); |
| | | } |
| | | |
| | | /** |
| | | * 项目表单项查询 |
| | | */ |
| | | @GetMapping("/user/form/item/list") |
| | | public AjaxResult queryFormItems(QueryFormItemRequest request) { |
| | | ValidatorUtils.validateEntity(request); |
| | | // FormAuthUtils.hasPermission(request.getKey()); |
| | | List<UserFormItemEntity> itemEntityList = formItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getKey()).eq(ObjectUtil.isNotNull(request.getDisplayType()), UserFormItemEntity::getDisplayType, request.getDisplayType())); |
| | | itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort)); |
| | | return AjaxResult.success(itemEntityList); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 分页查询项目分类 |
| | | * |
| | | * @return |
| | | */ |
| | | @GetMapping("/form/template/type/list") |
| | | public AjaxResult queryFormTemplateTypes(QueryFormTemplateTypeRequest.List request) { |
| | | return AjaxResult.success(formTemplateCategoryService.list(Wrappers.<FormTemplateCategoryEntity>lambdaQuery() |
| | | .orderByDesc(FormTemplateCategoryEntity::getSort))); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 表单更新 |
| | | * |
| | | * @param form |
| | | */ |
| | | @PostMapping("/user/form/update") |
| | | public AjaxResult updateForm(@RequestBody UserFormEntity form) { |
| | | // ValidatorUtils.validateEntity(form, AddGroup.class); |
| | | UserFormEntity oldForm = formService.getByKey(form.getFormKey()); |
| | | if (ObjectUtil.isNotNull(oldForm)) { |
| | | form.setId(oldForm.getId()); |
| | | formService.updateById(form); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 项目表单项创建 |
| | | * |
| | | * @param entity |
| | | */ |
| | | @PostMapping("/user/form/item/create") |
| | | public AjaxResult createFormItem(@RequestBody UserFormItemEntity entity) { |
| | | // ValidatorUtils.validateEntity(entity, AddGroup.class); |
| | | if (ObjectUtil.isNull(entity.getDisplayType())) { |
| | | entity.setDisplayType(false); |
| | | } |
| | | if (ObjectUtil.isNull(entity.getHideType())) { |
| | | entity.setHideType(false); |
| | | } |
| | | //排序下标计算 |
| | | entity.setSort(sortUtils.getInitialSortPosition(entity.getFormKey())); |
| | | entity.setSpecialType(formItemService.isSpecialTypeItem(entity)); |
| | | entity.setCreateTime(new Date()); |
| | | boolean save = formItemService.save(entity); |
| | | return AjaxResult.success(new OperateFormItemVO(entity.getSort(), entity.getId(), save, false)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 批量项目表单项创建 |
| | | */ |
| | | @PostMapping("/user/form/item/batch/create") |
| | | public AjaxResult batchCreateFormItem(@RequestBody List<UserFormItemEntity> itemEntityList) { |
| | | //排序下标计算 |
| | | itemEntityList.forEach(item -> item.setSort(sortUtils.getInitialSortPosition(item.getFormKey()))); |
| | | itemEntityList.forEach(item -> item.setDisplayType(false)); |
| | | itemEntityList.forEach(item -> item.setHideType(false)); |
| | | itemEntityList.forEach(item -> item.setSpecialType(false)); |
| | | boolean save = formItemService.saveBatch(itemEntityList); |
| | | AjaxResult ajaxResult = new AjaxResult(); |
| | | ajaxResult.put("code", 200); |
| | | ajaxResult.put("data", null); |
| | | ajaxResult.put("msg", null); |
| | | return ajaxResult; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 表单项删除 |
| | | */ |
| | | @PostMapping("/user/form/item/delete") |
| | | public AjaxResult deleteFormItem(@RequestBody UserFormItemEntity request) { |
| | | // FormAuthUtils.hasPermission(request.getFormKey()); |
| | | boolean delete = formItemService.remove(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).eq(UserFormItemEntity::getFormItemId, request.getFormItemId())); |
| | | return AjaxResult.success(delete); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 表单项更新 |
| | | * |
| | | * @param request |
| | | */ |
| | | @PostMapping("/user/form/item/update") |
| | | public AjaxResult updateFormItem(@RequestBody UserFormItemEntity request) { |
| | | // FormAuthUtils.hasPermission(request.getFormKey()); |
| | | // ValidatorUtils.validateEntity(request, UpdateGroup.class); |
| | | request.setSpecialType(formItemService.isSpecialTypeItem(request)); |
| | | boolean update = formItemService.update(request, Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).eq(UserFormItemEntity::getFormItemId, request.getFormItemId())); |
| | | return AjaxResult.success(update); |
| | | } |
| | | |
| | | /** |
| | | * 表单项排序 |
| | | * |
| | | * @param request |
| | | */ |
| | | @PostMapping("/user/form/item/sort") |
| | | public AjaxResult sortFormItem(@RequestBody SortFormItemRequest request) { |
| | | // ValidatorUtils.validateEntity(request); |
| | | if (ObjectUtil.isNull(request.getAfterPosition()) && ObjectUtil.isNull(request.getBeforePosition())) { |
| | | return AjaxResult.success(); |
| | | } |
| | | UserFormItemEntity itemEntity = formItemService.getOne(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).eq(UserFormItemEntity::getFormItemId, request.getFormItemId())); |
| | | Long sort = sortUtils.calcSortPosition(request.getBeforePosition(), request.getAfterPosition(), request.getFormKey()); |
| | | if (sortUtils.sortAllList(request.getBeforePosition(), request.getAfterPosition(), request.getFormKey(), sort)) { |
| | | return AjaxResult.success(new OperateFormItemVO(itemEntity.getSort(), itemEntity.getId(), true, true)); |
| | | } |
| | | itemEntity.setSort(sort); |
| | | boolean b = formItemService.updateById(itemEntity); |
| | | return AjaxResult.success(new OperateFormItemVO(itemEntity.getSort(), itemEntity.getId(), b, false)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询表单详情 |
| | | * 包含表单信息 表单字段信息 表单主题 |
| | | * |
| | | * @param key |
| | | */ |
| | | @GetMapping("/user/form/details/{key}") |
| | | @PermitAll |
| | | public AjaxResult queryFormDetails(@PathVariable @NotBlank String key) { |
| | | UserFormEntity form = formService.getByKey(key); |
| | | if (ObjectUtil.isNull(form)) { |
| | | return AjaxResult.success(); |
| | | } |
| | | List<UserFormItemEntity> formItemList = formItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().ne(UserFormItemEntity::getHideType, 1).eq(UserFormItemEntity::getFormKey, key)); |
| | | formItemList.sort(Comparator.comparing(UserFormItemEntity::getSort)); |
| | | UserFormThemeEntity theme = userFormThemeService.getByKey(key); |
| | | UserFormLogicEntity formLogic = userFormLogicService.getOne(Wrappers.<UserFormLogicEntity>lambdaQuery().eq(UserFormLogicEntity::getFormKey, key)); |
| | | // 如果是考试 移除正确答案 避免把正确答案返回到前端 |
| | | if (form.getType() == FormTypeEnum.EXAM.getValue().toString()) { |
| | | formItemList.forEach(item -> { |
| | | JSONObject schemeJson = JSONUtil.parseObj(item.getScheme()); |
| | | if (schemeJson.containsKey("examConfig")) { |
| | | schemeJson.getJSONObject("examConfig").remove("answer"); |
| | | } |
| | | item.setScheme(schemeJson); |
| | | }); |
| | | } |
| | | return AjaxResult.success(new UserFormDetailVO(new UserFormDetailVO.UserForm(form), formItemList, theme, formLogic)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 发布表单 |
| | | */ |
| | | @PostMapping("/user/form/publish") |
| | | public AjaxResult publishForm(@RequestBody UserFormEntity request) { |
| | | // FormAuthUtils.hasPermission(request.getFormKey()); |
| | | long count = formItemService.count(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey())); |
| | | if (count == CommonConstants.ConstantNumber.ZERO) { |
| | | return AjaxResult.error("无有效表单项,无法发布"); |
| | | } |
| | | UserFormEntity entity = formService.getByKey(request.getFormKey()); |
| | | entity.setStatus(2); |
| | | return AjaxResult.success(formService.updateById(entity)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 停止收集 |
| | | * |
| | | * @param request |
| | | */ |
| | | @PostMapping("/user/form/stop") |
| | | public Result stopForm(@RequestBody UserFormEntity request) { |
| | | // FormAuthUtils.hasPermission(request.getFormKey()); |
| | | UserFormEntity entity = formService.getByKey(request.getFormKey()); |
| | | entity.setStatus(3); |
| | | return Result.success(formService.updateById(entity)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询我的表单分页 |
| | | */ |
| | | @GetMapping("/user/form/page") |
| | | public Result queryMyForms(@RequestAttribute Long userId, QueryFormRequest.Page request) { |
| | | LambdaQueryWrapper<UserFormEntity> queryWrapper = Wrappers.<UserFormEntity>lambdaQuery().eq(UserFormEntity::getUserId, userId) |
| | | .eq(ObjectUtil.isNotNull(request.getFolder()), UserFormEntity::getFolder, request.getFolder()) |
| | | .eq(ObjectUtil.isNotNull(request.getType()), UserFormEntity::getType, request.getType()) |
| | | .eq(UserFormEntity::getDeleted, 0).func(i -> { |
| | | // 通过文件名搜索时 可以搜索到子文件夹下的表单 |
| | | if (StrUtil.isNotBlank(request.getName()) && request.getFolderId() == 0) { |
| | | } else { |
| | | i.eq(UserFormEntity::getFolderId, request.getFolderId()); |
| | | } |
| | | }).eq(ObjectUtil.isNotNull(request.getStatus()), UserFormEntity::getStatus, request.getStatus()).like(StrUtil.isNotBlank(request.getName()), |
| | | UserFormEntity::getName, request.getName()).le(ObjectUtil.isNotNull(request.getEndDateTime()), UserFormEntity::getUpdateTime, |
| | | request.getEndDateTime()).ge(ObjectUtil.isNotNull(request.getBeginDateTime()), UserFormEntity::getUpdateTime, |
| | | request.getBeginDateTime()).orderByDesc(UserFormEntity::getFolder) |
| | | // .orderByDesc(TBaseEntity::getCreateTime) |
| | | ; |
| | | return Result.success(formService.page(request.toMybatisPage(), queryWrapper)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取表单字段 包括系统默认字段 |
| | | */ |
| | | @GetMapping("/user/form/fields/{formKey}") |
| | | public Result queryUserFormFields(@PathVariable String formKey) { |
| | | return Result.success(formItemService.listAllFormFields(formKey)); |
| | | } |
| | | |
| | | /** |
| | | * 获取表单固定字段 |
| | | * 所有表单都包含 用于查看详情右侧显示 |
| | | */ |
| | | @GetMapping("/user/form/fixed/fields/{formKey}") |
| | | public Result queryUserFormFixedFields(@PathVariable String formKey) { |
| | | // 查询表单类型 |
| | | UserFormEntity userFormEntity = formService.getByKey(formKey); |
| | | List<FormFieldVO> fields = new ArrayList<>(); |
| | | FormDataUtils.addFormBaseDataField(fields); |
| | | fields.add(new FormFieldVO("submitUaOs", "操作系统")); |
| | | fields.add(new FormFieldVO("submitUaDevice", "设备")); |
| | | fields.add(new FormFieldVO(UserFormDataEntity.Fields.submitBrowser, "浏览器")); |
| | | fields.add(new FormFieldVO(UserFormDataEntity.Fields.submitAddress, "地址")); |
| | | fields.add(new FormFieldVO(UserFormDataEntity.Fields.submitRequestIp, "IP")); |
| | | fields.add(new FormFieldVO(UserFormDataEntity.Fields.wxUserInfo, "微信用户")); |
| | | return Result.success(fields); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.web.tduck; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ltkj.common.core.domain.AjaxResult; |
| | | import com.ltkj.common.utils.SecurityUtils; |
| | | import com.ltkj.common.utils.http.HttpUtils; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import com.ltkj.tduck.domain.UserFormViewCountEntity; |
| | | import com.ltkj.tduck.request.QueryFormResultRequest; |
| | | import com.ltkj.tduck.service.UserFormDataService; |
| | | import com.ltkj.tduck.service.UserFormViewCountService; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import com.ltkj.tduck.utils.ValidatorUtils; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.security.PermitAll; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | |
| | | /** |
| | | * 表单数据 |
| | | * |
| | | * @author : smalljop |
| | | * @description : 表单数据页 当前用户自己使用接口 |
| | | * @create : 2020-11-18 18:17 |
| | | **/ |
| | | |
| | | @Slf4j |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/user/form/data") |
| | | public class UserFormResultController { |
| | | private final UserFormDataService formResultService; |
| | | // private final UserFormSettingService userFormSettingService; |
| | | // private final FormDataImportUtils formDataImportUtils; |
| | | // private final FormDataExportUtils formDataExportUtils; |
| | | // private final UserFormService userFormService; |
| | | private final UserFormViewCountService userFormViewCountService; |
| | | // private final MailService mailService; |
| | | // private final WxMpUserMsgService userMsgService; |
| | | private final ConcurrentMap<String, Integer> viewFormMap = new ConcurrentHashMap<>(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * 根据体检号获取问卷记录 |
| | | */ |
| | | @GetMapping("getRecordByTjNumber") |
| | | public AjaxResult getRecordByTjNumber(String tjNumber) { |
| | | LambdaQueryWrapper<UserFormDataEntity> wq=new LambdaQueryWrapper<>(); |
| | | wq.eq(UserFormDataEntity::getTjNumber,tjNumber); |
| | | final List<UserFormDataEntity> list = formResultService.list(wq); |
| | | AjaxResult ajaxResult = new AjaxResult(); |
| | | ajaxResult.put("code", 200); |
| | | ajaxResult.put("data", list); |
| | | ajaxResult.put("msg", null); |
| | | return ajaxResult; |
| | | } |
| | | |
| | | |
| | | /*** |
| | | * 查看表单 |
| | | * 记录查看的IP 统计查看用户数 |
| | | */ |
| | | @GetMapping("view/{formKey}") |
| | | @PermitAll |
| | | public Result<Void> viewForm(HttpServletRequest request, @PathVariable("formKey") String formKey) { |
| | | if (viewFormMap.containsKey(formKey)) { |
| | | userFormViewCountService.increment(formKey); |
| | | } else { |
| | | // 不存在则添加 |
| | | Long count = userFormViewCountService.count(formKey); |
| | | if (count == 0) { |
| | | UserFormViewCountEntity entity = new UserFormViewCountEntity(); |
| | | entity.setFormKey(formKey); |
| | | entity.setCount(1L); |
| | | userFormViewCountService.save(entity); |
| | | } |
| | | viewFormMap.put(formKey, 1); |
| | | } |
| | | return Result.success(); |
| | | } |
| | | |
| | | /** |
| | | * 查询数据 |
| | | * |
| | | * @param request 查询条件 |
| | | * @return 数据 |
| | | */ |
| | | @PostMapping("query") |
| | | public Result queryFormDataTable(@RequestBody QueryFormResultRequest request) { |
| | | // FormAuthUtils.hasPermission(request.getFormKey()); |
| | | return Result.success(formResultService.listFormDataTable(request)); |
| | | } |
| | | |
| | | /** |
| | | * 获取某条数据详情 |
| | | * |
| | | * @param dataId 数据ID |
| | | * @return 数据详情 |
| | | */ |
| | | @GetMapping("details/{dataId}") |
| | | @PermitAll |
| | | public Result getFormDataDetails(@PathVariable("dataId") String dataId) { |
| | | return formResultService.getFormDataDetails(dataId); |
| | | } |
| | | // |
| | | // |
| | | // /** |
| | | // * 填写附件导出 |
| | | // * |
| | | // * @param request 请求 |
| | | // * @return 文件 |
| | | // */ |
| | | // @PostMapping("/download/file") |
| | | // public Result downloadFormResultFile(@RequestBody QueryFormResultRequest request) { |
| | | // return formResultService.downloadFormResultFile(request); |
| | | // } |
| | | |
| | | /** |
| | | * 填写 |
| | | * |
| | | * @param entity 填写数据 |
| | | * @param request 请求 |
| | | * @return |
| | | */ |
| | | @PostMapping("/create") |
| | | public AjaxResult createFormResult(@RequestBody UserFormDataEntity entity, HttpServletRequest request) { |
| | | ValidatorUtils.validateEntity(entity); |
| | | entity.setSubmitRequestIp(HttpUtils.getIpAddr(request)); |
| | | // 如果已经登陆了也记录用户信息 try catch 避免抛出异常 |
| | | entity.setCreateBy(SecurityUtils.getUserId() != null ? String.valueOf(SecurityUtils.getUserId()) : null); |
| | | Map<String, Object> result = formResultService.saveFormResult(entity); |
| | | return AjaxResult.success(result); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 公开填写 |
| | | * |
| | | * @param entity 填写数据 |
| | | * @param request 请求 |
| | | */ |
| | | @PostMapping("/public/create") |
| | | @PermitAll |
| | | public Result<Map<String, Object>> createPublicFormResult(@RequestBody UserFormDataEntity entity, HttpServletRequest request) { |
| | | |
| | | ValidatorUtils.validateEntity(entity); |
| | | entity.setSubmitRequestIp(HttpUtils.getIpAddr(request)); |
| | | // Result<Boolean> userFormSettingStatus = userFormSettingService.getUserFormWriteSettingStatus(entity.getFormKey(), entity.getSubmitRequestIp(), entity.getWxOpenId(), CommonConstants.ConstantNumber.ONE); |
| | | // if (StrUtil.isNotBlank(userFormSettingStatus.getMsg())) { |
| | | // return Result.failed(userFormSettingStatus.getMsg()); |
| | | // } |
| | | // 如果已经登陆了也记录用户信息 try catch 避免抛出异常 |
| | | entity.setCreateBy(SecurityUtils.getUserId() != null ? String.valueOf(SecurityUtils.getUserId()) : null); |
| | | Map<String, Object> result = formResultService.saveFormResult(entity); |
| | | // ThreadUtil.execAsync(() -> { |
| | | // sendWriteResultNotify(entity.getFormKey()); |
| | | // }); |
| | | return Result.success(result); |
| | | // return Result.success(); |
| | | } |
| | | |
| | | // |
| | | // /** |
| | | // * 批量删除 |
| | | // * |
| | | // * @param formKey 表单key |
| | | // * @param dataIdList 数据ID |
| | | // * @return Result |
| | | // */ |
| | | // @PostMapping("/delete/{formKey}") |
| | | // public Result deleteFormData(@RequestBody List<String> dataIdList, @PathVariable("formKey") String formKey) { |
| | | // formResultService.deleteByIds(dataIdList, formKey); |
| | | // return Result.success(); |
| | | // } |
| | | |
| | | |
| | | // /** |
| | | // * 更新 |
| | | // * |
| | | // * @param entity 填写数据 |
| | | // * @param request 请求 |
| | | // * @return Result |
| | | // */ |
| | | // @PostMapping("/update") |
| | | // @PermitAll |
| | | // public Result<Void> updateFormResult(@RequestBody UserFormDataEntity entity, HttpServletRequest request) { |
| | | // ValidatorUtils.validateEntity(entity); |
| | | // try { |
| | | // entity.setUpdateBy(String.valueOf(SecurityUtils.getUserId())); |
| | | // } catch (Exception ignored) { |
| | | // } |
| | | // formResultService.updateFormResult(entity); |
| | | // return Result.success(); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 下载导入模板 |
| | | // * |
| | | // * @param response 响应 |
| | | // * @param formKey 表单key |
| | | // */ |
| | | // @GetMapping("/import/template") |
| | | // public void downloadImportTemplate(HttpServletResponse response, String formKey) { |
| | | // formDataImportUtils.importTemplateExcel(response, formKey); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 导出表单数据 |
| | | // */ |
| | | // @PostMapping("export") |
| | | // public void exportFormData(@RequestBody ExportRequest.FormData exportRequest) { |
| | | // formDataExportUtils.exportData(exportRequest); |
| | | // } |
| | | // |
| | | // /** |
| | | // * 导入表单数据 |
| | | // * |
| | | // * @param file 文件 |
| | | // * @return Result |
| | | // */ |
| | | // @PostMapping("import") |
| | | // public Result importFormData(@RequestParam("file") MultipartFile file, UserFormDataEntity dataEntity) throws IOException { |
| | | // return Result.success(formDataImportUtils.importFile(file.getInputStream(), dataEntity.getFormKey())); |
| | | // } |
| | | // |
| | | // |
| | | // private void sendWriteResultNotify(String formKey) { |
| | | // FormSettingSchemaStruct formSettingSchema = userFormSettingService.getFormSettingSchema(formKey); |
| | | // if (ObjectUtil.isNull(formSettingSchema)) { |
| | | // return; |
| | | // } |
| | | // UserFormEntity form = userFormService.getByKey(formKey); |
| | | // if (StrUtil.isNotBlank(formSettingSchema.getNewWriteNotifyEmail())) { |
| | | // mailService.sendTemplateHtmlMail(formSettingSchema.getNewWriteNotifyEmail(), "新回复通知", "mail/form-write-notify", MapUtil.of("projectName", form.getName())); |
| | | // } |
| | | // |
| | | // if (StrUtil.isNotBlank(formSettingSchema.getNewWriteNotifyWx())) { |
| | | // List<String> openIdList = StrUtil.splitTrim(formSettingSchema.getNewWriteNotifyWx(), ";"); |
| | | // openIdList.stream().forEach(openId -> { |
| | | // userMsgService.sendKfTextMsg("", openId, "收到新的反馈,请去Pc端查看"); |
| | | // }); |
| | | // } |
| | | // } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.web.tduck; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ltkj.common.utils.http.HttpUtils; |
| | | import com.ltkj.tduck.domain.UserFormSettingEntity; |
| | | import com.ltkj.tduck.request.CheckWritePwdRequest; |
| | | import com.ltkj.tduck.service.UserFormSettingService; |
| | | import com.ltkj.tduck.utils.CacheUtils; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.security.PermitAll; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单设置 |
| | | * |
| | | * @author : smalljop |
| | | * @description : 表单设置 |
| | | * @create : 2020-11-18 18:17 |
| | | **/ |
| | | @Slf4j |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | public class UserFormSettingController { |
| | | |
| | | private final UserFormSettingService userFormSettingService; |
| | | // private final WxMpUserService wxMpUserService; |
| | | private final CacheUtils cacheUtils; |
| | | // private final WxMpService wxMpService; |
| | | |
| | | |
| | | /** |
| | | * 保存表单设置 |
| | | */ |
| | | @PostMapping("/user/form/setting/save") |
| | | public Result<Boolean> saveFormSetting(@RequestBody Map<String, Object> setting) { |
| | | String formKey = setting.get("formKey").toString(); |
| | | // FormAuthUtils.hasPermission(formKey); |
| | | return Result.success(userFormSettingService.saveFormSetting(setting)); |
| | | } |
| | | |
| | | /** |
| | | * 表单提交设置查询 |
| | | */ |
| | | @GetMapping("/user/form/setting/{key}") |
| | | public Result<Map<String, Object>> queryFormSettingByKey(@PathVariable("key") String formKey) { |
| | | UserFormSettingEntity setting = userFormSettingService.getFormSettingByKey(formKey); |
| | | if (ObjectUtil.isNull(setting)) { |
| | | return Result.success(); |
| | | } |
| | | Map<String, Object> settings = setting.getSettings(); |
| | | settings.put(UserFormSettingEntity.Fields.formKey, formKey); |
| | | return Result.success(settings); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 当前填写设置的状态 |
| | | * |
| | | * @param formKey 表单key |
| | | * @param wxOpenId 微信openid |
| | | * @param type 类型 1公开填写 2.指定填写 |
| | | */ |
| | | @GetMapping("/user/form/setting-status") |
| | | @PermitAll |
| | | public Result<Boolean> querySettingStatus(@RequestParam String formKey, @RequestParam(required = false) String wxOpenId, @RequestParam(required = false) Integer type, HttpServletRequest request) { |
| | | return userFormSettingService.getUserFormWriteSettingStatus(formKey, HttpUtils.getIpAddr(request), wxOpenId, type); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 填写微信通知二维码 |
| | | */ |
| | | @GetMapping("/user/form/wx/notify-qrcode") |
| | | public Result<String> getWxNotifyQrCode(@RequestParam("key") String formKey) throws Exception { |
| | | // String loginSceneStr = JsonUtils.objToJson(new WxMpQrCodeGenRequest(WxMpQrCodeGenRequest.QrCodeType.SUB_NOTIFY, formKey)); |
| | | // //5分钟有效 |
| | | // WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(loginSceneStr, 10 * 60); |
| | | // String subNotifyQrcodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket()); |
| | | // return Result.success(subNotifyQrcodeUrl); |
| | | return Result.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 填写微信通知二维码 |
| | | */ |
| | | @PostMapping("/user/form/wx/delete/notify-user") |
| | | public Result<Boolean> deleteWxNotifyQrCode(@RequestParam("key") String key, @RequestParam("openId") String openId) { |
| | | // cacheUtils.removeList(StrUtil.format(WxMpRedisKeyConstants.WX_MP_SUB_NOTIFY, key), openId); |
| | | return Result.success(true); |
| | | } |
| | | |
| | | /** |
| | | * 获取表单微信通知用户 |
| | | */ |
| | | @GetMapping("/user/form/wx/notify-user") |
| | | public Result getWxNotifyUser(@RequestParam("key") String formKey, @RequestParam(required = false) String openIdStr) { |
| | | // Set<Object> subNotifyUsers = null; |
| | | // if (StrUtil.isNotBlank(openIdStr)) { |
| | | // subNotifyUsers = Sets.newHashSet(StrUtil.splitTrim(openIdStr, ";")); |
| | | // } else { |
| | | // List coll = cacheUtils.getList(StrUtil.format(WxMpRedisKeyConstants.WX_MP_SUB_NOTIFY, formKey), String.class); |
| | | // subNotifyUsers = Collections.singleton(coll.stream().collect(Collectors.toSet())); |
| | | // } |
| | | // return Result.success(wxMpUserService.listWxMpUserByOpenId(subNotifyUsers).stream().map(item -> new WxMpUserVO(item.getNickname(), item.getHeadImgUrl(), item.getOpenId())).collect(Collectors.toList())); |
| | | return Result.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 公开接口 |
| | | * 表单填写时需要的设置 |
| | | */ |
| | | @GetMapping("/user/form/public/settings/{key}") |
| | | @PermitAll |
| | | public Result queryPublicFormSettingByKey(@PathVariable("key") String formKey) { |
| | | // FormSettingSchemaStruct formSettingSchema = userFormSettingService.getFormSettingSchema(formKey); |
| | | return Result.success(); |
| | | } |
| | | |
| | | /** |
| | | * 公开接口 |
| | | * 检查填写密码是否正确 |
| | | */ |
| | | @PostMapping("/user/form/public/checkWritePwd") |
| | | @PermitAll |
| | | public Result<Boolean> checkWritePwd(@RequestBody @Validated CheckWritePwdRequest request) { |
| | | // FormSettingSchemaStruct formSettingSchema = userFormSettingService.getFormSettingSchema(request.getFormKey()); |
| | | // if (formSettingSchema.getWritePassword().equals(request.getPassword())) { |
| | | // return Result.success(true); |
| | | // } |
| | | // return Result.failed("密码输入错误"); |
| | | return Result.success(true); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.web.tduck; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.core.util.URLUtil; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.annotation.security.PermitAll; |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 微信公众号网页 |
| | | * @create : 2020-12-02 13:40 |
| | | **/ |
| | | @AllArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/wx/jsapi/") |
| | | public class WxJsApiController { |
| | | // private final WxMpService wxService; |
| | | |
| | | |
| | | /** |
| | | * 用户授权url |
| | | * |
| | | * @return hcah |
| | | */ |
| | | @GetMapping("/authorization/url") |
| | | @PermitAll |
| | | public Result getAuthorizationUrl(@RequestParam @NotBlank String url) { |
| | | String appId = "11111"; |
| | | String authorizationUrl = StrUtil.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={}&redirect_uri={}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect", appId, URLUtil.encode(url)); |
| | | return Result.success(authorizationUrl); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据code获取用户信息 |
| | | * |
| | | * @param code |
| | | * @return |
| | | */ |
| | | @GetMapping("/authorization/user/info") |
| | | @PermitAll |
| | | public Result greetUser(@RequestParam @NotBlank String code) { |
| | | // WxOAuth2UserInfo userInfo = null; |
| | | // try { |
| | | // WxOAuth2AccessToken accessToken = wxService.getOAuth2Service().getAccessToken(code); |
| | | // userInfo = wxService.getOAuth2Service().getUserInfo(accessToken, null); |
| | | // } catch (WxErrorException e) { |
| | | // return Result.success(); |
| | | // } |
| | | // return Result.success(userInfo); |
| | | return Result.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取jsapi签名 |
| | | */ |
| | | @GetMapping("/signature") |
| | | @PermitAll |
| | | public Result getSignature(@RequestParam String url) throws Exception { |
| | | // WxJsapiSignature signature = wxService.createJsapiSignature(url); |
| | | // return Result.success(signature); |
| | | return Result.success(); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | restart: |
| | | # 热部署开关 |
| | | enabled: true |
| | | cache: |
| | | type: ehcache |
| | | ehcache: |
| | | config: classpath:config/ehcache.xml |
| | | # redis 配置 |
| | | # redis: |
| | | # # 地址 |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:noNamespaceSchemaLocation="ehcache.xsd"> |
| | | <!--timeToIdleSeconds 当缓存闲置n秒后销毁 --> |
| | | <!--timeToLiveSeconds 当缓存存活n秒后销毁 --> |
| | | <!-- 缓存配置 |
| | | name:缓存名称。 |
| | | maxElementsInMemory:缓存最大个数。 |
| | | eternal:对象是否永久有效,一但设置了,timeout将不起作用。 |
| | | timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 |
| | | timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 |
| | | overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 |
| | | maxElementsOnDisk:硬盘最大缓存个数。 |
| | | diskPersistent:是否缓存虚拟机重启期数据 Whether the disk |
| | | store persists between restarts of the Virtual Machine. The default value |
| | | is false. |
| | | diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是 |
| | | LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 |
| | | clearOnFlush:内存数量最大时是否清除。 --> |
| | | <!-- 磁盘缓存位置 --> |
| | | <diskStore path="java.io.tmpdir"/> |
| | | <!-- 默认缓存 --> |
| | | <defaultCache |
| | | maxElementsInMemory="10000" |
| | | eternal="false" |
| | | timeToIdleSeconds="120" |
| | | timeToLiveSeconds="120" |
| | | maxElementsOnDisk="10000000" |
| | | diskExpiryThreadIntervalSeconds="120" |
| | | memoryStoreEvictionPolicy="LRU"> |
| | | |
| | | <persistence strategy="localTempSwap"/> |
| | | </defaultCache> |
| | | |
| | | <!-- 持久化cache--> |
| | | <cache name="eternal_cache" |
| | | maxElementsInMemory="10000" |
| | | eternal="true" |
| | | timeToIdleSeconds="120" |
| | | timeToLiveSeconds="120" |
| | | overflowToDisk="true" |
| | | diskPersistent="true" |
| | | diskExpiryThreadIntervalSeconds="10"/> |
| | | |
| | | <!-- 临时cache --> |
| | | <cache name="temp_cache" |
| | | maxElementsInMemory="10000" |
| | | eternal="false" |
| | | timeToIdleSeconds="300" |
| | | timeToLiveSeconds="300" |
| | | maxElementsOnDisk="10000000" |
| | | diskExpiryThreadIntervalSeconds="120" |
| | | memoryStoreEvictionPolicy="LRU"> |
| | | <persistence strategy="localTempSwap"/> |
| | | </cache> |
| | | |
| | | </ehcache> |
| | |
| | | <!-- </repository>--> |
| | | <!-- </repositories>--> |
| | | <dependencies> |
| | | |
| | | <!--以下tduck--> |
| | | <dependency> |
| | | <groupId>com.aventrix.jnanoid</groupId> |
| | | <artifactId>jnanoid</artifactId> |
| | | <version>2.0.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.datatype</groupId> |
| | | <artifactId>jackson-datatype-jsr310</artifactId> |
| | | <version>2.16.0</version> |
| | | </dependency> |
| | | <!-- ehcache缓存 --> |
| | | <dependency> |
| | | <groupId>net.sf.ehcache</groupId> |
| | | <artifactId>ehcache</artifactId> |
| | | <version>2.9.1</version><!--$NO-MVN-MAN-VER$ --> |
| | | </dependency> |
| | | <!--以上tduck--> |
| | | |
| | | |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>e-iceblue</groupId>--> |
| | | <!-- <artifactId>spire.pdf</artifactId>--> |
| | |
| | | import javax.net.ssl.SSLSession; |
| | | import javax.net.ssl.TrustManager; |
| | | import javax.net.ssl.X509TrustManager; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | import cn.hutool.core.util.CharUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.ltkj.common.constant.Constants; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取请求IP地址 |
| | | * |
| | | * @param request |
| | | * @return |
| | | */ |
| | | public static String getIpAddr(HttpServletRequest request) { |
| | | if (request == null) { |
| | | return "unknown"; |
| | | } |
| | | String ip = request.getHeader("x-forwarded-for"); |
| | | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
| | | ip = request.getHeader("Proxy-Client-IP"); |
| | | } |
| | | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
| | | ip = request.getHeader("X-Forwarded-For"); |
| | | } |
| | | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
| | | ip = request.getHeader("WL-Proxy-Client-IP"); |
| | | } |
| | | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
| | | ip = request.getHeader("X-Real-IP"); |
| | | } |
| | | |
| | | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
| | | ip = request.getRemoteAddr(); |
| | | } |
| | | //"***.***.***.***".length() = 15 |
| | | if (StrUtil.isNotBlank(ip) && ip.length() > 15) { |
| | | if (ip.indexOf(CharUtil.COMMA) > 0) { |
| | | ip = ip.substring(0, ip.indexOf(",")); |
| | | } |
| | | } |
| | | //处理获取多个ip地址情况 nginx多层代理会出现多个ip 第一个为真实ip地址 |
| | | return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; |
| | | } |
| | | } |
| | |
| | | */ |
| | | @ApiModelProperty(value = "问题") |
| | | @Excel(name = "问题") |
| | | private Long qid; |
| | | private String qid; |
| | | |
| | | /** |
| | | * 选项 |
| | |
| | | private String score; |
| | | |
| | | |
| | | public void setOid(Long oid) { |
| | | this.oid = oid; |
| | | } |
| | | |
| | | public Long getOid() { |
| | | return oid; |
| | | } |
| | | |
| | | public void setQid(Long qid) { |
| | | this.qid = qid; |
| | | } |
| | | |
| | | public Long getQid() { |
| | | return qid; |
| | | } |
| | | |
| | | public void setOoption(String ooption) { |
| | | this.ooption = ooption; |
| | | } |
| | | |
| | | public String getOoption() { |
| | | return ooption; |
| | | } |
| | | |
| | | public void setScore(String score) { |
| | | this.score = score; |
| | | } |
| | | |
| | | public String getScore() { |
| | | return score; |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | /** |
| | | * id |
| | | */ |
| | | @ApiModelProperty(value = "主键id") |
| | | @TableId |
| | | @JsonSerialize(using = ToStringSerializer.class) |
| | | private Long qid; |
| | | // @ApiModelProperty(value = "主键id") |
| | | // @TableId |
| | | // @JsonSerialize(using = ToStringSerializer.class) |
| | | private String qid; |
| | | |
| | | /** |
| | | * 问题 |
| | |
| | | @Excel(name = "是否必填",dictType="sys_yes_no") |
| | | private String isRequired; |
| | | |
| | | |
| | | private String keywords; |
| | | |
| | | private String sort; |
| | | |
| | | private Long mid; |
| | | |
| | | @TableField(exist = false) |
| | | private TjSurveyTemplate template; |
| | | |
| | | /** |
| | | * 问卷选项信息 |
| | | */ |
| | |
| | | @TableField(exist = false) |
| | | private List<TjSurveyOptions> tjSurveyOptionsList; |
| | | |
| | | public void setQid(Long qid) { |
| | | this.qid = qid; |
| | | } |
| | | |
| | | public Long getQid() { |
| | | return qid; |
| | | } |
| | | |
| | | public void setQuestion(String question) { |
| | | this.question = question; |
| | | } |
| | | |
| | | public String getQuestion() { |
| | | return question; |
| | | } |
| | | |
| | | public void setType(String type) { |
| | | this.type = type; |
| | | } |
| | | |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | |
| | | public void setIsRequired(String isRequired) { |
| | | this.isRequired = isRequired; |
| | | } |
| | | |
| | | public String getIsRequired() { |
| | | return isRequired; |
| | | } |
| | | |
| | | |
| | | |
| | | public List<TjSurveyOptions> getTjSurveyOptionsList() { |
| | | return tjSurveyOptionsList; |
| | | } |
| | | |
| | | public void setTjSurveyOptionsList(List<TjSurveyOptions> tjSurveyOptionsList) { |
| | | this.tjSurveyOptionsList = tjSurveyOptionsList; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | |
| | | @Excel(name = "标志") |
| | | private String fromBy; |
| | | |
| | | private Long fmId; |
| | | |
| | | /** |
| | | * 问卷记录详情信息 |
| | | */ |
| | | @ApiModelProperty(value = "问卷记录详情信息") |
| | | @TableField(exist = false) |
| | | private List<TjSurveyRecordDetail> tjSurveyRecordDetailList; |
| | | |
| | | public void setRid(Long rid) { |
| | | this.rid = rid; |
| | | } |
| | | |
| | | public Long getRid() { |
| | | return rid; |
| | | } |
| | | |
| | | public void setTjnumber(Long tjnumber) { |
| | | this.tjnumber = tjnumber; |
| | | } |
| | | |
| | | public Long getTjnumber() { |
| | | return tjnumber; |
| | | } |
| | | |
| | | public void setPhone(String phone) { |
| | | this.phone = phone; |
| | | } |
| | | |
| | | public String getPhone() { |
| | | return phone; |
| | | } |
| | | |
| | | public void setUserName(String userName) { |
| | | this.userName = userName; |
| | | } |
| | | |
| | | public String getUserName() { |
| | | return userName; |
| | | } |
| | | |
| | | public void setMid(Long mid) { |
| | | this.mid = mid; |
| | | } |
| | | |
| | | public Long getMid() { |
| | | return mid; |
| | | } |
| | | |
| | | public void setMname(String mname) { |
| | | this.mname = mname; |
| | | } |
| | | |
| | | public String getMname() { |
| | | return mname; |
| | | } |
| | | |
| | | public void setQid(Long qid) { |
| | | this.qid = qid; |
| | | } |
| | | |
| | | public Long getQid() { |
| | | return qid; |
| | | } |
| | | |
| | | public void setQname(String qname) { |
| | | this.qname = qname; |
| | | } |
| | | |
| | | public String getQname() { |
| | | return qname; |
| | | } |
| | | |
| | | |
| | | |
| | | public List<TjSurveyRecordDetail> getTjSurveyRecordDetailList() { |
| | | return tjSurveyRecordDetailList; |
| | | } |
| | | |
| | | public void setTjSurveyRecordDetailList(List<TjSurveyRecordDetail> tjSurveyRecordDetailList) { |
| | | this.tjSurveyRecordDetailList = tjSurveyRecordDetailList; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | |
| | | */ |
| | | @ApiModelProperty(value = "问题id") |
| | | @Excel(name = "问题id") |
| | | private Long qid; |
| | | private String qid; |
| | | |
| | | /** |
| | | * 问题名 |
| | |
| | | private String qname; |
| | | |
| | | |
| | | public void setTqid(Long tqid) { |
| | | this.tqid = tqid; |
| | | } |
| | | |
| | | public Long getTqid() { |
| | | return tqid; |
| | | } |
| | | |
| | | public void setMid(Long mid) { |
| | | this.mid = mid; |
| | | } |
| | | |
| | | public Long getMid() { |
| | | return mid; |
| | | } |
| | | |
| | | public void setQid(Long qid) { |
| | | this.qid = qid; |
| | | } |
| | | |
| | | public Long getQid() { |
| | | return qid; |
| | | } |
| | | |
| | | public void setQname(String qname) { |
| | | this.qname = qname; |
| | | } |
| | | |
| | | public String getQname() { |
| | | return qname; |
| | | } |
| | | |
| | | |
| | | @Override |
| | |
| | | |
| | | |
| | | /** |
| | | * 表单设计绑定 |
| | | */ |
| | | private String designId; |
| | | |
| | | |
| | | /*启用标志*/ |
| | | private String qybz; |
| | | |
| | | |
| | | /** |
| | | * 问卷模板问题信息 |
| | | */ |
| | | @ApiModelProperty(value = "问卷模板问题信息") |
| | | @TableField(exist = false) |
| | | private List<TjSurveyTempQues> tjSurveyTempQuesList; |
| | | |
| | | public void setMid(Long mid) { |
| | | this.mid = mid; |
| | | } |
| | | |
| | | public Long getMid() { |
| | | return mid; |
| | | } |
| | | |
| | | public void setTempName(String tempName) { |
| | | this.tempName = tempName; |
| | | } |
| | | |
| | | public String getTempName() { |
| | | return tempName; |
| | | } |
| | | |
| | | public void setTempType(String tempType) { |
| | | this.tempType = tempType; |
| | | } |
| | | |
| | | public String getTempType() { |
| | | return tempType; |
| | | } |
| | | |
| | | |
| | | public List<TjSurveyTempQues> getTjSurveyTempQuesList() { |
| | | return tjSurveyTempQuesList; |
| | | } |
| | | |
| | | public void setTjSurveyTempQuesList(List<TjSurveyTempQues> tjSurveyTempQuesList) { |
| | | this.tjSurveyTempQuesList = tjSurveyTempQuesList; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | |
| | | package com.ltkj.hosp.mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.hosp.domain.TjSurveyQuestion; |
| | | import com.ltkj.hosp.domain.TjSurveyOptions; |
| | | import com.ltkj.hosp.domain.TjSurveyQuestion; |
| | | import com.ltkj.hosp.domain.TjSurveyTempQues; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Select; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 问卷问题Mapper接口 |
| | |
| | | * @param qid 问卷问题主键 |
| | | * @return 问卷问题 |
| | | */ |
| | | public TjSurveyQuestion selectTjSurveyQuestionByQid(Long qid); |
| | | public TjSurveyQuestion selectTjSurveyQuestionByQid(String qid); |
| | | |
| | | |
| | | /*根据问题查询选项集合*/ |
| | | public List<TjSurveyOptions> selectOptionsByQid(String qid); |
| | | |
| | | |
| | | /** |
| | | * 查询问卷问题列表 |
| | |
| | | */ |
| | | public int insertTjSurveyQuestion(TjSurveyQuestion tjSurveyQuestion); |
| | | |
| | | |
| | | /** |
| | | * 新增问卷 |
| | | * |
| | | * @param tjSurveyOptions 问卷 |
| | | * @return 结果 |
| | | */ |
| | | public int insertTjSurveyOptions(TjSurveyOptions tjSurveyOptions); |
| | | |
| | | /** |
| | | * 修改问卷问题 |
| | | * |
| | |
| | | * @param qid 问卷问题主键 |
| | | * @return 结果 |
| | | */ |
| | | public int deleteTjSurveyQuestionByQid(Long qid); |
| | | public int deleteTjSurveyQuestionByQid(String qid); |
| | | |
| | | |
| | | public int deleteTjSurveyQuestionByMid(Long mid); |
| | | |
| | | /** |
| | | * 批量删除问卷问题 |
| | |
| | | * @param qids 需要删除的数据主键集合 |
| | | * @return 结果 |
| | | */ |
| | | public int deleteTjSurveyQuestionByQids(Long[] qids); |
| | | public int deleteTjSurveyQuestionByQids(String[] qids); |
| | | |
| | | /** |
| | | * 批量删除问卷选项 |
| | |
| | | * @param qids 需要删除的数据主键集合 |
| | | * @return 结果 |
| | | */ |
| | | public int deleteTjSurveyOptionsByQids(Long[] qids); |
| | | public int deleteTjSurveyOptionsByQids(String[] qids); |
| | | |
| | | /** |
| | | * 批量新增问卷选项 |
| | |
| | | * @param qid 问卷问题ID |
| | | * @return 结果 |
| | | */ |
| | | public int deleteTjSurveyOptionsByQid(Long qid); |
| | | public int deleteTjSurveyOptionsByQid(String qid); |
| | | |
| | | |
| | | @Select("SELECT * FROM tj_survey_temp_ques a WHERE a.mid=#{mid} AND a.deleted=0") |
| | | List<TjSurveyTempQues> selectOptionsByMid(String mid); |
| | | |
| | | |
| | | List<TjSurveyQuestion> getOptionsByMid(String mid); |
| | | } |
| | |
| | | */ |
| | | public TjSurveyTemplate selectTjSurveyTemplateByMid(Long mid); |
| | | |
| | | public TjSurveyTemplate selectTemplateByMid1(Long mid); |
| | | public int qybzTjSurveyTemplateByQy(Long mid); |
| | | public int qybzTjSurveyTemplateByJy(Long mid); |
| | | |
| | | |
| | | /** |
| | | * 查询问卷模板列表 |
| | | * |
| | |
| | | package com.ltkj.hosp.service; |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.hosp.domain.TjSurveyOptions; |
| | | import com.ltkj.hosp.domain.TjSurveyQuestion; |
| | | import com.ltkj.hosp.domain.TjTeamSelectRecord; |
| | | import com.ltkj.hosp.domain.TjSurveyTempQues; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 问卷问题Service接口 |
| | |
| | | * @param qid 问卷问题主键 |
| | | * @return 问卷问题 |
| | | */ |
| | | public TjSurveyQuestion selectTjSurveyQuestionByQid(Long qid); |
| | | public TjSurveyQuestion selectTjSurveyQuestionByQid(String qid); |
| | | |
| | | public List<TjSurveyOptions> selectOptionsByQid(String qid); |
| | | /** |
| | | * 查询问卷问题列表 |
| | | * |
| | |
| | | * @param qids 需要删除的问卷问题主键集合 |
| | | * @return 结果 |
| | | */ |
| | | public int deleteTjSurveyQuestionByQids(Long[] qids); |
| | | public int deleteTjSurveyQuestionByQids(String[] qids); |
| | | |
| | | /** |
| | | * 删除问卷问题信息 |
| | |
| | | * @param qid 问卷问题主键 |
| | | * @return 结果 |
| | | */ |
| | | public int deleteTjSurveyQuestionByQid(Long qid); |
| | | public int deleteTjSurveyQuestionByQid(String qid); |
| | | |
| | | |
| | | List<TjSurveyTempQues> selectOptionsByMid(String mid); |
| | | |
| | | List<TjSurveyQuestion> getOptionsByMid(String mid); |
| | | } |
| | |
| | | */ |
| | | public TjSurveyTemplate selectTjSurveyTemplateByMid(Long mid); |
| | | |
| | | public TjSurveyTemplate selectTemplateByMid1(Long mid); |
| | | |
| | | public int qybzTjSurveyTemplateByQy(Long mid); |
| | | public int qybzTjSurveyTemplateByJy(Long mid); |
| | | |
| | | /** |
| | | * 查询问卷模板列表 |
| | | * |
| | |
| | | package com.ltkj.hosp.service.impl; |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.common.utils.DateUtils; |
| | | import com.ltkj.hosp.domain.TjTeamSelectRecord; |
| | | import com.ltkj.hosp.mapper.TjTeamSelectRecordMapper; |
| | | import com.ltkj.common.utils.SecurityUtils; |
| | | import com.ltkj.common.utils.StringUtils; |
| | | import com.ltkj.hosp.domain.TjSurveyOptions; |
| | | import com.ltkj.hosp.domain.TjSurveyQuestion; |
| | | import com.ltkj.hosp.domain.TjSurveyTempQues; |
| | | import com.ltkj.hosp.mapper.TjSurveyQuestionMapper; |
| | | import com.ltkj.hosp.service.ITjSurveyQuestionService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | |
| | | import com.ltkj.common.utils.StringUtils; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import com.ltkj.hosp.domain.TjSurveyOptions; |
| | | import com.ltkj.hosp.mapper.TjSurveyQuestionMapper; |
| | | import com.ltkj.hosp.domain.TjSurveyQuestion; |
| | | import com.ltkj.hosp.service.ITjSurveyQuestionService; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 问卷问题Service业务层处理 |
| | |
| | | * @return 问卷问题 |
| | | */ |
| | | @Override |
| | | public TjSurveyQuestion selectTjSurveyQuestionByQid(Long qid) { |
| | | public TjSurveyQuestion selectTjSurveyQuestionByQid(String qid) { |
| | | return tjSurveyQuestionMapper.selectTjSurveyQuestionByQid(qid); |
| | | } |
| | | |
| | | @Override |
| | | public List<TjSurveyOptions> selectOptionsByQid(String qid) { |
| | | return tjSurveyQuestionMapper.selectOptionsByQid(qid); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public int insertTjSurveyQuestion(TjSurveyQuestion tjSurveyQuestion) { |
| | | tjSurveyQuestion.setCreateTime(DateUtils.getNowDate()); |
| | | tjSurveyQuestion.setCreateBy(SecurityUtils.getLoginUser().getUsername()); |
| | | int rows = tjSurveyQuestionMapper.insertTjSurveyQuestion(tjSurveyQuestion); |
| | | System.out.println(tjSurveyQuestion); |
| | | insertTjSurveyOptions(tjSurveyQuestion); |
| | | return rows; |
| | | } |
| | |
| | | @Override |
| | | public int updateTjSurveyQuestion(TjSurveyQuestion tjSurveyQuestion) { |
| | | tjSurveyQuestion.setUpdateTime(DateUtils.getNowDate()); |
| | | tjSurveyQuestionMapper.deleteTjSurveyOptionsByQid(tjSurveyQuestion.getQid()) |
| | | ; |
| | | tjSurveyQuestionMapper.deleteTjSurveyOptionsByQid(tjSurveyQuestion.getQid()); |
| | | insertTjSurveyOptions(tjSurveyQuestion); |
| | | return tjSurveyQuestionMapper.updateTjSurveyQuestion(tjSurveyQuestion); |
| | | } |
| | |
| | | */ |
| | | @Transactional |
| | | @Override |
| | | public int deleteTjSurveyQuestionByQids(Long[] qids) { |
| | | public int deleteTjSurveyQuestionByQids(String[] qids) { |
| | | tjSurveyQuestionMapper.deleteTjSurveyOptionsByQids(qids); |
| | | return tjSurveyQuestionMapper.deleteTjSurveyQuestionByQids(qids); |
| | | } |
| | |
| | | */ |
| | | @Transactional |
| | | @Override |
| | | public int deleteTjSurveyQuestionByQid(Long qid) { |
| | | public int deleteTjSurveyQuestionByQid(String qid) { |
| | | tjSurveyQuestionMapper.deleteTjSurveyOptionsByQid(qid); |
| | | return tjSurveyQuestionMapper.deleteTjSurveyQuestionByQid(qid); |
| | | } |
| | | |
| | | @Override |
| | | public List<TjSurveyTempQues> selectOptionsByMid(String mid) { |
| | | return tjSurveyQuestionMapper.selectOptionsByMid(mid); |
| | | } |
| | | |
| | | @Override |
| | | public List<TjSurveyQuestion> getOptionsByMid(String mid) { |
| | | return tjSurveyQuestionMapper.getOptionsByMid(mid); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public void insertTjSurveyOptions(TjSurveyQuestion tjSurveyQuestion) { |
| | | List<TjSurveyOptions> tjSurveyOptionsList = tjSurveyQuestion.getTjSurveyOptionsList(); |
| | | Long qid = tjSurveyQuestion.getQid(); |
| | | String qid = tjSurveyQuestion.getQid(); |
| | | if (StringUtils.isNotNull(tjSurveyOptionsList)) { |
| | | List<TjSurveyOptions> list = new ArrayList<TjSurveyOptions>(); |
| | | for (TjSurveyOptions tjSurveyOptions : tjSurveyOptionsList) { |
| | | tjSurveyOptions.setQid(qid); |
| | | tjSurveyOptions.setDeleted(0); |
| | | tjSurveyOptions.setCreateBy(SecurityUtils.getLoginUser().getUsername()); |
| | | tjSurveyOptions.setCreateTime(DateUtils.getNowDate()); |
| | | list.add(tjSurveyOptions); |
| | | } |
| | | if (list.size() > 0) { |
| | | for (TjSurveyOptions tjSurveyOptions : list) { |
| | | tjSurveyOptions.setDeleted(0); |
| | | tjSurveyQuestionMapper.insertTjSurveyOptions(tjSurveyOptions); |
| | | } |
| | | tjSurveyQuestionMapper.batchTjSurveyOptions(list); |
| | | } |
| | | } |
| | | } |
| | |
| | | return tjSurveyTemplateMapper.selectTjSurveyTemplateByMid(mid); |
| | | } |
| | | |
| | | @Override |
| | | public TjSurveyTemplate selectTemplateByMid1(Long mid) { |
| | | return tjSurveyTemplateMapper.selectTemplateByMid1(mid); |
| | | } |
| | | |
| | | @Override |
| | | public int qybzTjSurveyTemplateByQy(Long mid) { |
| | | return tjSurveyTemplateMapper.qybzTjSurveyTemplateByQy(mid); |
| | | } |
| | | |
| | | @Override |
| | | public int qybzTjSurveyTemplateByJy(Long mid) { |
| | | return tjSurveyTemplateMapper.qybzTjSurveyTemplateByJy(mid); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询问卷模板列表 |
| | | * |
| | |
| | | <result property="updateBy" column="update_by"/> |
| | | <result property="updateTime" column="update_time"/> |
| | | <result property="deleted" column="deleted"/> |
| | | <result property="keywords" column="keywords"/> |
| | | <result property="sort" column="sort"/> |
| | | <result property="mid" column="mid"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="TjSurveyQuestionTjSurveyOptionsResult" type="TjSurveyQuestion" extends="TjSurveyQuestionResult"> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | deleted |
| | | deleted, |
| | | keywords, |
| | | sort, |
| | | mid |
| | | from tj_survey_question |
| | | </sql> |
| | | |
| | |
| | | </where> |
| | | </select> |
| | | |
| | | <select id="selectTjSurveyQuestionByQid" parameterType="Long" |
| | | <select id="selectTjSurveyQuestionByQid" parameterType="String" |
| | | resultMap="TjSurveyQuestionTjSurveyOptionsResult"> |
| | | select a.qid, |
| | | a.question, |
| | |
| | | a.update_by, |
| | | a.update_time, |
| | | a.deleted, |
| | | a.keywords, |
| | | a.sort, |
| | | b.oid as |
| | | sub_oid, |
| | | b.qid as |
| | |
| | | where a.qid = #{qid} |
| | | </select> |
| | | |
| | | <insert id="insertTjSurveyQuestion" parameterType="TjSurveyQuestion" useGeneratedKeys="true" |
| | | keyProperty="qid"> |
| | | |
| | | <select id="getOptionsByMid" parameterType="String" |
| | | resultMap="TjSurveyQuestionTjSurveyOptionsResult"> |
| | | select a.qid, |
| | | a.question, |
| | | a.type, |
| | | a.is_required, |
| | | a.remark, |
| | | a.create_by, |
| | | a.create_time, |
| | | a.update_by, |
| | | a.update_time, |
| | | a.deleted, |
| | | a.keywords, |
| | | a.sort, |
| | | b.oid as |
| | | sub_oid, |
| | | b.qid as |
| | | sub_qid, |
| | | b.ooption as |
| | | sub_ooption, |
| | | b.score as |
| | | sub_score, |
| | | b.remark as |
| | | sub_remark, |
| | | b.create_by as |
| | | sub_create_by, |
| | | b.create_time as |
| | | sub_create_time, |
| | | b.update_by as |
| | | sub_update_by, |
| | | b.update_time as |
| | | sub_update_time, |
| | | b.deleted as |
| | | sub_deleted |
| | | from tj_survey_question a |
| | | left join tj_survey_options b on b.qid = a.qid |
| | | where a.mid = #{mid} |
| | | </select> |
| | | |
| | | |
| | | <select id="selectOptionsByQid" parameterType="String" resultType="TjSurveyOptions"> |
| | | select oid,qid,ooption,score,remark,create_by,create_time,update_by,update_time,deleted from tj_survey_options |
| | | where qid = #{qid} |
| | | </select> |
| | | |
| | | <!-- <insert id="insertTjSurveyQuestion" parameterType="TjSurveyQuestion" useGeneratedKeys="true"--> |
| | | <!-- keyProperty="qid">--> |
| | | <!-- insert into tj_survey_question--> |
| | | <!-- <trim prefix="(" suffix=")" suffixOverrides=",">--> |
| | | <!-- <if test="question != null and question != ''">question,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="type != null and type != ''">type,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="isRequired != null and isRequired != ''">is_required,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="remark != null">remark,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="createBy != null">create_by,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="createTime != null">create_time,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="updateBy != null">update_by,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="updateTime != null">update_time,--> |
| | | <!-- </if>--> |
| | | <!-- <if test="deleted != null">deleted,--> |
| | | <!-- </if>--> |
| | | <!-- </trim>--> |
| | | <!-- <trim prefix="values (" suffix=")" suffixOverrides=",">--> |
| | | <!-- <if test="question != null and question != ''">#{question},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="type != null and type != ''">#{type},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="isRequired != null and isRequired != ''">#{isRequired},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="remark != null">#{remark},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="createBy != null">#{createBy},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="createTime != null">#{createTime},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="updateBy != null">#{updateBy},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="updateTime != null">#{updateTime},--> |
| | | <!-- </if>--> |
| | | <!-- <if test="deleted != null">#{deleted},--> |
| | | <!-- </if>--> |
| | | <!-- </trim>--> |
| | | <!-- </insert>--> |
| | | |
| | | |
| | | <insert id="insertTjSurveyQuestion" parameterType="TjSurveyQuestion"> |
| | | insert into tj_survey_question |
| | | <trim prefix="(" suffix=")" suffixOverrides=","> |
| | | <if test="qid != null and qid != ''">qid, |
| | | </if> |
| | | <if test="question != null and question != ''">question, |
| | | </if> |
| | | <if test="type != null and type != ''">type, |
| | |
| | | </if> |
| | | <if test="updateTime != null">update_time, |
| | | </if> |
| | | <if test="deleted != null">deleted, |
| | | <if test="keywords != null">keywords, |
| | | </if> |
| | | <if test="sort != null">sort, |
| | | </if> |
| | | <if test="mid != null">mid, |
| | | </if> |
| | | |
| | | </trim> |
| | | <trim prefix="values (" suffix=")" suffixOverrides=","> |
| | | <if test="qid != null and qid != ''">#{qid}, |
| | | </if> |
| | | <if test="question != null and question != ''">#{question}, |
| | | </if> |
| | | <if test="type != null and type != ''">#{type}, |
| | |
| | | </if> |
| | | <if test="updateTime != null">#{updateTime}, |
| | | </if> |
| | | <if test="deleted != null">#{deleted}, |
| | | <if test="keywords != null">#{keywords}, |
| | | </if> |
| | | <if test="sort != null">#{sort},</if> |
| | | <if test="mid != null">#{mid},</if> |
| | | |
| | | </trim> |
| | | </insert> |
| | | |
| | | |
| | | <update id="updateTjSurveyQuestion" parameterType="TjSurveyQuestion"> |
| | | update tj_survey_question |
| | |
| | | <if test="deleted != null">deleted = |
| | | #{deleted}, |
| | | </if> |
| | | <if test="mid != null">mid = |
| | | #{mid}, |
| | | </if> |
| | | |
| | | <if test="keywords != null">keywords = |
| | | #{keywords}, |
| | | </if> |
| | | <if test="sort != null">sort = |
| | | #{sort}, |
| | | </if> |
| | | </trim> |
| | | where qid = #{qid} |
| | | </update> |
| | | |
| | | <delete id="deleteTjSurveyQuestionByQid" parameterType="Long"> |
| | | delete |
| | | from tj_survey_question |
| | | where qid = #{qid} |
| | | </delete> |
| | | <update id="deleteTjSurveyQuestionByQid" parameterType="TjSurveyQuestion"> |
| | | update tj_survey_question SET deleted = 1 where qid = #{qid} |
| | | </update> |
| | | |
| | | <delete id="deleteTjSurveyQuestionByQids" parameterType="String"> |
| | | delete from tj_survey_question where qid in |
| | | |
| | | <update id="deleteTjSurveyQuestionByMid" parameterType="Long"> |
| | | update tj_survey_question SET deleted = 1 where mid = #{mid} |
| | | </update> |
| | | |
| | | |
| | | <!-- <delete id="deleteTjSurveyQuestionByQid" parameterType="String">--> |
| | | <!-- delete--> |
| | | <!-- from tj_survey_question--> |
| | | <!-- where qid = #{qid}--> |
| | | <!-- </delete>--> |
| | | |
| | | <update id="deleteTjSurveyQuestionByQids" parameterType="Long"> |
| | | update tj_survey_question set deleted=1 where mid in |
| | | <foreach item="mid" collection="array" open="(" separator="," close=")"> |
| | | #{mid} |
| | | </foreach> |
| | | </update> |
| | | |
| | | <update id="deleteTjSurveyOptionsByQids" parameterType="Long"> |
| | | update tj_survey_options set deleted=1 where qid in |
| | | <foreach item="qid" collection="array" open="(" separator="," close=")"> |
| | | #{qid} |
| | | </foreach> |
| | | </delete> |
| | | </update> |
| | | |
| | | <delete id="deleteTjSurveyOptionsByQids" parameterType="String"> |
| | | delete from tj_survey_options where qid in |
| | | <foreach item="qid" collection="array" open="(" separator="," close=")"> |
| | | #{qid} |
| | | </foreach> |
| | | </delete> |
| | | <!-- <delete id="deleteTjSurveyQuestionByQids" parameterType="String">--> |
| | | <!-- delete from tj_survey_question where qid in--> |
| | | <!-- <foreach item="qid" collection="array" open="(" separator="," close=")">--> |
| | | <!-- #{qid}--> |
| | | <!-- </foreach>--> |
| | | <!-- </delete>--> |
| | | |
| | | <delete id="deleteTjSurveyOptionsByQid" parameterType="Long"> |
| | | delete |
| | | from tj_survey_options |
| | | where qid = #{qid} |
| | | </delete> |
| | | <!-- <delete id="deleteTjSurveyOptionsByQids" parameterType="String">--> |
| | | <!-- delete from tj_survey_options where qid in--> |
| | | <!-- <foreach item="qid" collection="array" open="(" separator="," close=")">--> |
| | | <!-- #{qid}--> |
| | | <!-- </foreach>--> |
| | | <!-- </delete>--> |
| | | |
| | | <insert id="batchTjSurveyOptions"> |
| | | <!-- <delete id="deleteTjSurveyOptionsByQid" parameterType="String">--> |
| | | <!-- delete--> |
| | | <!-- from tj_survey_options--> |
| | | <!-- where qid = #{qid}--> |
| | | <!-- </delete>--> |
| | | |
| | | <update id="deleteTjSurveyOptionsByQid" parameterType="TjSurveyOptions"> |
| | | update tj_survey_options SET deleted = 1 where qid = #{qid} |
| | | </update> |
| | | |
| | | |
| | | |
| | | <insert id="insertTjSurveyOptions" parameterType="TjSurveyOptions"> |
| | | insert into tj_survey_options |
| | | ( oid , qid , ooption , score , remark , create_by , create_time , update_by , update_time , deleted) values |
| | | <foreach item="item" index="index" collection="list" separator=","> |
| | | ( #{item.oid |
| | | }, #{item.qid |
| | | }, #{item.ooption |
| | | }, #{item.score |
| | | }, #{item.remark |
| | | }, #{item.createBy |
| | | }, #{item.createTime |
| | | }, #{item.updateBy |
| | | }, #{item.updateTime |
| | | }, #{item.deleted |
| | | }) |
| | | </foreach> |
| | | <trim prefix="(" suffix=")" suffixOverrides=","> |
| | | <if test="qid != null and qid != ''">qid, |
| | | </if> |
| | | <if test="ooption != null and ooption != ''">ooption, |
| | | </if> |
| | | <if test="score != null and score != ''">score, |
| | | </if> |
| | | <if test="remark != null">remark, |
| | | </if> |
| | | <if test="createBy != null">create_by, |
| | | </if> |
| | | <if test="createTime != null">create_time, |
| | | </if> |
| | | <if test="updateBy != null">update_by, |
| | | </if> |
| | | <if test="updateTime != null">update_time, |
| | | </if> |
| | | </trim> |
| | | <trim prefix="values (" suffix=")" suffixOverrides=","> |
| | | <if test="qid != null and qid != ''">#{qid}, |
| | | </if> |
| | | <if test="ooption != null and ooption != ''">#{ooption}, |
| | | </if> |
| | | <if test="score != null and score != ''">#{score}, |
| | | </if> |
| | | <if test="remark != null">#{remark}, |
| | | </if> |
| | | <if test="createBy != null">#{createBy}, |
| | | </if> |
| | | <if test="createTime != null">#{createTime}, |
| | | </if> |
| | | <if test="updateBy != null">#{updateBy}, |
| | | </if> |
| | | <if test="updateTime != null">#{updateTime}, |
| | | </if> |
| | | |
| | | </trim> |
| | | </insert> |
| | | |
| | | <!-- <insert id="batchTjSurveyOptions">--> |
| | | <!-- insert into tj_survey_options--> |
| | | <!-- ( oid , qid , ooption , score , remark , create_by , create_time , update_by , update_time , deleted) values--> |
| | | <!-- <foreach item="item" index="index" collection="list" separator=",">--> |
| | | <!-- ( #{item.oid--> |
| | | <!-- }, #{item.qid--> |
| | | <!-- }, #{item.ooption--> |
| | | <!-- }, #{item.score--> |
| | | <!-- }, #{item.remark--> |
| | | <!-- }, #{item.createBy--> |
| | | <!-- }, #{item.createTime--> |
| | | <!-- }, #{item.updateBy--> |
| | | <!-- }, #{item.updateTime--> |
| | | <!-- }, #{item.deleted--> |
| | | <!-- })--> |
| | | <!-- </foreach>--> |
| | | <!-- </insert>--> |
| | | </mapper> |
| | |
| | | <result property="updateBy" column="update_by"/> |
| | | <result property="updateTime" column="update_time"/> |
| | | <result property="deleted" column="deleted"/> |
| | | <result property="designId" column="design_id"/> |
| | | <result property="qybz" column="qybz"/> |
| | | </resultMap> |
| | | |
| | | <resultMap id="TjSurveyTemplateTjSurveyTempQuesResult" type="TjSurveyTemplate" extends="TjSurveyTemplateResult"> |
| | |
| | | </resultMap> |
| | | |
| | | <sql id="selectTjSurveyTemplateVo"> |
| | | select mid, temp_name, temp_type, remark, create_by, create_time, update_by, update_time, deleted |
| | | select mid, |
| | | temp_name, |
| | | temp_type, |
| | | remark, |
| | | create_by, |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | deleted, |
| | | qybz, |
| | | design_id |
| | | from tj_survey_template |
| | | </sql> |
| | | |
| | |
| | | |
| | | <select id="selectTjSurveyTemplateByMid" parameterType="Long" |
| | | resultMap="TjSurveyTemplateTjSurveyTempQuesResult"> |
| | | select a.mid, a.temp_name, a.temp_type, a.remark, a.create_by, a.create_time, a.update_by, a.update_time, a.deleted, |
| | | select a.mid, |
| | | a.temp_name, |
| | | a.temp_type, |
| | | a.remark, |
| | | a.create_by, |
| | | a.create_time, |
| | | a.update_by, |
| | | a.update_time, |
| | | a.deleted, |
| | | a.design_id, |
| | | a.qybz, |
| | | b.tqid as |
| | | sub_tqid, b.mid as |
| | | sub_mid, b.qid as |
| | | sub_qid, b.qname as |
| | | sub_qname, b.create_by as |
| | | sub_create_by, b.create_time as |
| | | sub_create_time, b.update_by as |
| | | sub_update_by, b.update_time as |
| | | sub_update_time, b.deleted as |
| | | sub_tqid, |
| | | b.mid as |
| | | sub_mid, |
| | | b.qid as |
| | | sub_qid, |
| | | b.qname as |
| | | sub_qname, |
| | | b.create_by as |
| | | sub_create_by, |
| | | b.create_time as |
| | | sub_create_time, |
| | | b.update_by as |
| | | sub_update_by, |
| | | b.update_time as |
| | | sub_update_time, |
| | | b.deleted as |
| | | sub_deleted |
| | | from tj_survey_template a |
| | | left join tj_survey_temp_ques b on b.mid = a.mid |
| | | where a.mid = #{mid} |
| | | </select> |
| | | |
| | | <update id="qybzTjSurveyTemplateByQy" parameterType="Long"> |
| | | update tj_survey_template |
| | | set qybz=0 |
| | | where mid = #{mid} |
| | | </update> |
| | | |
| | | <update id="qybzTjSurveyTemplateByJy" parameterType="Long"> |
| | | update tj_survey_template |
| | | set qybz=1 |
| | | where mid = #{mid} |
| | | </update> |
| | | |
| | | |
| | | <select id="selectTemplateByMid1" parameterType="Long" |
| | | resultType="TjSurveyTemplate"> |
| | | select mid, |
| | | temp_name, |
| | | temp_type, |
| | | remark, |
| | | create_by, |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | deleted, |
| | | qybz, |
| | | design_id |
| | | from tj_survey_template |
| | | where mid = #{mid} |
| | | AND deleted = 0 |
| | | </select> |
| | | |
| | | <insert id="insertTjSurveyTemplate" parameterType="TjSurveyTemplate" useGeneratedKeys="true" |
| | |
| | | </if> |
| | | <if test="deleted != null">deleted, |
| | | </if> |
| | | <if test="designId != null">design_id, |
| | | </if> |
| | | <if test="qybz != null">qybz, |
| | | </if> |
| | | </trim> |
| | | <trim prefix="values (" suffix=")" suffixOverrides=","> |
| | | <if test="tempName != null">#{tempName}, |
| | |
| | | <if test="updateTime != null">#{updateTime}, |
| | | </if> |
| | | <if test="deleted != null">#{deleted}, |
| | | </if> |
| | | <if test="designId != null">#{designId}, |
| | | </if> |
| | | <if test="qybz != null">#{qybz}, |
| | | </if> |
| | | </trim> |
| | | </insert> |
| | |
| | | <if test="deleted != null">deleted = |
| | | #{deleted}, |
| | | </if> |
| | | <if test="designId != null">design_id = |
| | | #{designId}, |
| | | </if> |
| | | <if test="qybz != null">qybz = |
| | | #{qybz}, |
| | | </if> |
| | | </trim> |
| | | where mid = #{mid} |
| | | </update> |
| | | |
| | | <delete id="deleteTjSurveyTemplateByMid" parameterType="Long"> |
| | | delete |
| | | from tj_survey_template where mid = #{mid} |
| | | from tj_survey_template |
| | | where mid = #{mid} |
| | | </delete> |
| | | |
| | | <delete id="deleteTjSurveyTemplateByMids" parameterType="String"> |
| | |
| | | |
| | | <delete id="deleteTjSurveyTempQuesByMid" parameterType="Long"> |
| | | delete |
| | | from tj_survey_temp_ques where mid = #{mid} |
| | | from tj_survey_temp_ques |
| | | where mid = #{mid} |
| | | </delete> |
| | | |
| | | <insert id="batchTjSurveyTempQues"> |
| | |
| | | }) |
| | | </foreach> |
| | | </insert> |
| | | |
| | | |
| | | </mapper> |
New file |
| | |
| | | package com.ltkj.tduck.constant; |
| | | |
| | | /** |
| | | * @description: 通用的常亮 |
| | | * @author: smalljop |
| | | * @create: 2018-09-27 13:25 |
| | | **/ |
| | | public interface CommonConstants { |
| | | |
| | | |
| | | /** |
| | | * 超级管理员id |
| | | */ |
| | | Long SUPER_ADMIN_ID = 1L; |
| | | |
| | | |
| | | String USER_KEY = "userId"; |
| | | /** |
| | | * 用户正常状态 |
| | | * 1:正常 0 :禁用 |
| | | */ |
| | | Integer USER_NORMAL_STATUS = 1; |
| | | /** |
| | | * 文件下载content_type |
| | | */ |
| | | String FILE_DOWNLOAD_CONTENT_TYPE = "application/octet-stream;charset=UTF-8"; |
| | | |
| | | |
| | | /** |
| | | * 数字常量 |
| | | */ |
| | | interface ConstantNumber { |
| | | /** |
| | | * @Fields NEGATIVE : ( -1 ) |
| | | */ |
| | | Integer NEGATIVE = -1; |
| | | |
| | | /** |
| | | * @Fields ZERO : ( 0 ) |
| | | */ |
| | | Integer ZERO = 0; |
| | | |
| | | /** |
| | | * @Fields ONE : ( 1 ) |
| | | */ |
| | | Integer ONE = 1; |
| | | |
| | | /** |
| | | * @Fields TOW : ( 2 ) |
| | | */ |
| | | Integer TOW = 2; |
| | | |
| | | /** |
| | | * @Fields THREE : ( 3 ) |
| | | */ |
| | | Integer THREE = 3; |
| | | |
| | | /** |
| | | * @Fields FOUR : ( 4 ) |
| | | */ |
| | | Integer FOUR = 4; |
| | | |
| | | /** |
| | | * @Fields FIVE : ( 5 ) |
| | | */ |
| | | Integer FIVE = 5; |
| | | |
| | | /** |
| | | * @Fields FIVE : ( 6 ) |
| | | */ |
| | | Integer SIX = 6; |
| | | |
| | | /** |
| | | * @Fields FIVE : ( 7 ) |
| | | */ |
| | | Integer Seven = 7; |
| | | |
| | | /** |
| | | * @Fields FIVE : ( 8 ) |
| | | */ |
| | | Integer Eight = 8; |
| | | |
| | | /** |
| | | * @Fields FIVE : ( 9 ) |
| | | */ |
| | | Integer Nine = 9; |
| | | |
| | | /** |
| | | * @Fields FIVE : ( 10 ) |
| | | */ |
| | | Integer Ten = 10; |
| | | |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.constant; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : |
| | | * @create : 2020-11-11 18:16 |
| | | **/ |
| | | public interface FormConstants { |
| | | |
| | | /** |
| | | * 选择性组件保存会创建两个字段 一个存放Id 一个存放选项名 |
| | | */ |
| | | String FIELD_SUFFIX_LABEL = "label"; |
| | | |
| | | |
| | | /** |
| | | * 表单Item排序位置自增 |
| | | */ |
| | | String FORM_ITEM_POS_DELTA = "form:item:pos:{}"; |
| | | |
| | | |
| | | /** |
| | | * 手机号验证码 |
| | | */ |
| | | String PHONE_NUMBER_CODE = "form:mobile:code:{}"; |
| | | |
| | | |
| | | /** |
| | | * 查看表单数 |
| | | */ |
| | | String FORM_VIEW_COUNT = "form:view:count:{}"; |
| | | |
| | | String FORM_RESULT_NUMBER = "form:view:result:{}"; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.constant; |
| | | |
| | | /** |
| | | * @description: redis key常量 |
| | | **/ |
| | | public interface FormRedisKeyConstants { |
| | | /** |
| | | * 表单Item排序位置自增 |
| | | */ |
| | | String FORM_ITEM_POS_DELTA = "form:item:pos:{}"; |
| | | |
| | | |
| | | /** |
| | | * 手机号验证码 |
| | | */ |
| | | String PHONE_NUMBER_CODE = "form:mobile:code:{}"; |
| | | /** |
| | | * 表单Item排序位置自增 |
| | | */ |
| | | String FORM_RESULT_NUMBER = "form:result:number:{}"; |
| | | |
| | | /** |
| | | * 查看表单IP记录列表 |
| | | */ |
| | | String FORM_VIEW_IP_LIST = "form:view:ip:list:{}"; |
| | | |
| | | /** |
| | | * 表单查看次数 |
| | | */ |
| | | String FORM_VIEW_COUNT_KEY = "form:view:count:{}"; |
| | | |
| | | /** |
| | | * 表单预约人数 |
| | | */ |
| | | String FORM_RESERVE_COUNT = "form:reserve:count:{}:{}:{}"; |
| | | |
| | | /** |
| | | * 商品卖出数量 |
| | | */ |
| | | String FORM_GOODS_SELL_QUANTITY = "form:goods:sell:quantity:{}:{}"; |
| | | |
| | | /** |
| | | * 商品是否支付状态 |
| | | */ |
| | | String FORM_GOODS_PAY_STATUS = "form:goods:pay:status:{}"; |
| | | |
| | | /** |
| | | * 商品待提交表单数据 |
| | | */ |
| | | String FORM_GOODS_SUBMIT_DATA = "form:goods:submit:data:{}"; |
| | | |
| | | /** |
| | | * 商品支付金额 |
| | | */ |
| | | String FORM_GOODS_PAY_PRICE = "form:goods:pay:price:{}"; |
| | | |
| | | /** |
| | | * 表单投票数量 {formKey}:{formItemId} |
| | | */ |
| | | String FORM_VOTE_COUNT = "form:vote:count:{}:{}"; |
| | | |
| | | /** |
| | | * 表单单选名额 {formKey}:{formItemId} |
| | | */ |
| | | String FORM_OPTION_QUANTITY = "form:option:count:{}:{}"; |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.constant; |
| | | |
| | | /** |
| | | * @author : wangqing |
| | | * @description : 表单设置项常量 |
| | | * @create : 2022/07/07 11:49 |
| | | **/ |
| | | public interface FormSettingConstants { |
| | | |
| | | /** |
| | | * 表单提交后显示类型字段名称 |
| | | */ |
| | | String SUBMIT_SHOW_TYPE_KEY = "submitShowType"; |
| | | |
| | | /** |
| | | * 自定义提示页面内容 |
| | | */ |
| | | String SUBMIT_SHOW_CUSTOM_PAGE_KEY = "submitShowCustomPage"; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.constant; |
| | | |
| | | /** |
| | | * @description: 响应状态码 |
| | | * @author: smalljop |
| | | * @create: 2020-02-10 15:46 |
| | | **/ |
| | | public interface ResponseCodeConstants { |
| | | /** |
| | | * 接口成功 |
| | | */ |
| | | int SUCCESS = 200; |
| | | /** |
| | | * 接口失败 发生异常 |
| | | */ |
| | | int FAIL = 500; |
| | | |
| | | /** |
| | | * 未登录 |
| | | */ |
| | | int UNAUTHORIZED = 401; |
| | | |
| | | /** |
| | | * 需要验证的请求 |
| | | */ |
| | | int NEED_VERIFICATION = 416; |
| | | |
| | | /** |
| | | * 找不到该请求 |
| | | */ |
| | | int NOT_FOUND = 404; |
| | | |
| | | /** |
| | | * 非法签名 |
| | | */ |
| | | Integer SIGN_FAIL_CODE = 405; |
| | | |
| | | /** |
| | | * 非法签名 |
| | | */ |
| | | String SIGN_FAIL_MSG = "非法访问,请检查请求信息"; |
| | | |
| | | |
| | | String VALIDATE_CODE_FAIL_MSG = "验证码验证失败"; |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | |
| | | /** |
| | | * 表单主题分类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2021-01-06 10:50:51 |
| | | */ |
| | | |
| | | @Data |
| | | @TableName(value = "fm_form_template_category", autoResultMap = true) |
| | | public class FormTemplateCategoryEntity { |
| | | /** |
| | | * 主题名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 排序 |
| | | */ |
| | | private Integer sort; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import lombok.experimental.FieldNameConstants; |
| | | |
| | | |
| | | /** |
| | | * 表单主题外观模板(FormTheme)表实体类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 18:33:50 |
| | | */ |
| | | @Data |
| | | @TableName(value = "fm_form_theme", autoResultMap = true) |
| | | @FieldNameConstants |
| | | public class FormThemeEntity { |
| | | |
| | | /** |
| | | * 主题名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 主题风格 |
| | | */ |
| | | private Long style; |
| | | /** |
| | | * 头部图片 |
| | | */ |
| | | private String headImgUrl; |
| | | |
| | | /** |
| | | * 背景图片 |
| | | */ |
| | | private String backgroundImg; |
| | | |
| | | |
| | | /** |
| | | * 主题颜色 |
| | | */ |
| | | private String themeColor; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 分页 |
| | | * @create : 2020-12-09 10:47 |
| | | **/ |
| | | @Data |
| | | public class PageRequest { |
| | | |
| | | private long current = 1; |
| | | private long size = 50; |
| | | |
| | | |
| | | public Page toMybatisPage() { |
| | | return new Page(current, size); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import lombok.Data; |
| | | import lombok.experimental.FieldNameConstants; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Entity基类 |
| | | * |
| | | * @author smalljop |
| | | */ |
| | | @Data |
| | | @FieldNameConstants |
| | | public class SysBaseEntity extends TBaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 搜索值 |
| | | */ |
| | | @TableField(exist = false) |
| | | private String searchValue; |
| | | |
| | | /** |
| | | * 创建者 |
| | | */ |
| | | private String createBy; |
| | | |
| | | /** |
| | | * 更新者 |
| | | */ |
| | | private String updateBy; |
| | | |
| | | |
| | | /** |
| | | * 请求参数 |
| | | */ |
| | | @TableField(exist = false) |
| | | private Map<String, Object> params; |
| | | |
| | | public Map<String, Object> getParams() { |
| | | if (params == null) { |
| | | params = new HashMap<>(); |
| | | } |
| | | return params; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import cn.hutool.core.date.DatePattern; |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.extension.activerecord.Model; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; |
| | | import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
| | | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
| | | import com.ltkj.tduck.utils.LongToStringSerializer; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.experimental.FieldNameConstants; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @description: 实体类基类 |
| | | * @author: smalljop |
| | | * @create: 2020-02-15 22:57 |
| | | **/ |
| | | @Data |
| | | @FieldNameConstants |
| | | @EqualsAndHashCode(callSuper = false) |
| | | public class TBaseEntity<T> extends Model { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | |
| | | /** |
| | | * 主键 避免超出长度 前端丢失精度 |
| | | */ |
| | | @JsonSerialize(using= LongToStringSerializer.class) |
| | | private Long id; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | **/ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | // @JsonDeserialize(using = LocalDateTimeDeserializer.class) |
| | | // @JsonSerialize(using = LocalDateTimeSerializer.class) |
| | | @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) |
| | | protected Date createTime; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | **/ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) |
| | | // @JsonDeserialize(using = LocalDateTimeDeserializer.class) |
| | | // @JsonSerialize(using = LocalDateTimeSerializer.class) |
| | | protected Date updateTime; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.FieldStrategy; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ltkj.common.annotation.Excel; |
| | | import com.ltkj.tduck.enums.FormTypeEnum; |
| | | import com.ltkj.tduck.handler.JacksonTypeHandler; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import lombok.experimental.Accessors; |
| | | import lombok.experimental.FieldNameConstants; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.util.Date; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单数据(FormResult)表实体类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 14:09:20 |
| | | */ |
| | | @Data |
| | | @Accessors(chain = true) |
| | | @FieldNameConstants |
| | | @TableName(value = "fm_user_form_data", autoResultMap = true) |
| | | public class UserFormDataEntity extends SysBaseEntity { |
| | | |
| | | /** |
| | | * 表单key |
| | | */ |
| | | @NotBlank(message = "错误请求") |
| | | private String formKey; |
| | | |
| | | |
| | | /** |
| | | * 提交序号 |
| | | */ |
| | | private Long serialNumber; |
| | | |
| | | /** |
| | | * 填写结果原始数据 |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private Map<String, Object> originalData; |
| | | |
| | | |
| | | @TableField(exist = false) |
| | | private FormTypeEnum formType; |
| | | |
| | | /** |
| | | * 填写用户Ua |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private Map<String, Object> submitUa; |
| | | |
| | | /** |
| | | * 提交系统 |
| | | */ |
| | | private String submitOs; |
| | | |
| | | |
| | | /** |
| | | * 提交浏览器 |
| | | */ |
| | | private String submitBrowser; |
| | | |
| | | /** |
| | | * 提交ip |
| | | */ |
| | | private String submitRequestIp; |
| | | |
| | | |
| | | /** |
| | | * 提交ip |
| | | */ |
| | | private String submitAddress; |
| | | |
| | | /** |
| | | * 完成时间 |
| | | */ |
| | | private Long completeTime; |
| | | |
| | | /** |
| | | * 微信openID |
| | | */ |
| | | private String wxOpenId; |
| | | |
| | | /** |
| | | * 微信用户信息 |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private Map<String, Object> wxUserInfo; |
| | | |
| | | /** |
| | | * 扩展字段 |
| | | */ |
| | | private String extValue; |
| | | |
| | | |
| | | /** |
| | | * 体检号 |
| | | */ |
| | | private String tjNumber; |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ltkj.tduck.enums.FormSourceTypeEnum; |
| | | import com.ltkj.tduck.enums.FormStatusEnum; |
| | | import com.ltkj.tduck.utils.HtmlUtils; |
| | | import lombok.Data; |
| | | import lombok.experimental.FieldNameConstants; |
| | | import org.apache.ibatis.type.BooleanTypeHandler; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 用户表单表(Form)表实体类 |
| | | */ |
| | | @Data |
| | | @FieldNameConstants |
| | | @TableName(value = "fm_user_form", autoResultMap = true) |
| | | public class UserFormEntity{ |
| | | |
| | | /** |
| | | * 主键 避免超出长度 前端丢失精度 |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | **/ |
| | | protected Date createTime; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | **/ |
| | | protected Date updateTime; |
| | | |
| | | /** |
| | | * 表单code |
| | | */ |
| | | @NotBlank(message = "错误请求") |
| | | private String formKey; |
| | | /** |
| | | * 表单名称 |
| | | */ |
| | | @NotBlank(message = "表单名称不能为空") |
| | | private String name; |
| | | /** |
| | | * 表单描述 |
| | | */ |
| | | private String description; |
| | | |
| | | |
| | | /** |
| | | * 表单来源 |
| | | */ |
| | | private Integer sourceType; |
| | | |
| | | /** |
| | | * 来源ID |
| | | */ |
| | | private String sourceId; |
| | | |
| | | /** |
| | | * 用户ID |
| | | */ |
| | | private Long userId; |
| | | |
| | | /*** |
| | | * 状态 |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * 表单类型 |
| | | */ |
| | | private String type; |
| | | |
| | | @TableField(value = "is_deleted", typeHandler = BooleanTypeHandler.class) |
| | | private Boolean deleted; |
| | | |
| | | /** |
| | | * 是否是文件夹 |
| | | */ |
| | | @TableField(value = "is_folder", typeHandler = BooleanTypeHandler.class) |
| | | private Boolean folder; |
| | | /** |
| | | * 父级文件夹ID |
| | | */ |
| | | private Long folderId; |
| | | |
| | | |
| | | /** |
| | | * 移除html标签 |
| | | * @return 文本 |
| | | */ |
| | | public String getTextName() { |
| | | if (StrUtil.isBlank(name)) { |
| | | return null; |
| | | } |
| | | // 标题是富文本 去除html 标签 |
| | | return HtmlUtils.cleanHtmlTag(name); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldStrategy; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; |
| | | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| | | import com.ltkj.tduck.enums.FormItemTypeEnum; |
| | | import com.ltkj.tduck.utils.HtmlUtils; |
| | | import lombok.Data; |
| | | import lombok.experimental.Accessors; |
| | | import lombok.experimental.FieldNameConstants; |
| | | import org.apache.ibatis.type.BooleanTypeHandler; |
| | | import org.apache.ibatis.type.EnumTypeHandler; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单表单项(FormItem)表实体类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-19 10:49:16 |
| | | */ |
| | | @Data |
| | | @Accessors(chain = true) |
| | | @FieldNameConstants |
| | | @JsonIgnoreProperties(ignoreUnknown = true) |
| | | @TableName(value = "fm_user_form_item", autoResultMap = true) |
| | | public class UserFormItemEntity { |
| | | |
| | | /** |
| | | * 主键 避免超出长度 前端丢失精度 |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | **/ |
| | | protected Date createTime; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | **/ |
| | | protected Date updateTime; |
| | | |
| | | |
| | | /** |
| | | * 表单Id |
| | | */ |
| | | @NotNull(message = "key请求异常") |
| | | private String formKey; |
| | | /** |
| | | * 表单项Id 类型 + 时间戳 |
| | | */ |
| | | @NotNull(message = "Id请求错误") |
| | | private String formItemId; |
| | | /** |
| | | * 表单项类型 |
| | | */ |
| | | @NotNull(message = "类型请求错误") |
| | | @TableField(typeHandler = EnumTypeHandler.class) |
| | | private FormItemTypeEnum type; |
| | | /** |
| | | * 表单项标题 |
| | | */ |
| | | @NotNull(message = "标题不能为空") |
| | | private String label; |
| | | |
| | | |
| | | /** |
| | | * 展示类型组件 只在表单填写页查询到 |
| | | */ |
| | | @TableField(value = "is_display_type", typeHandler = BooleanTypeHandler.class) |
| | | private Boolean displayType; |
| | | |
| | | /** |
| | | * 隐藏类型组件 在表单填写页面无法查看到 |
| | | */ |
| | | @TableField(value = "is_hide_type", typeHandler = BooleanTypeHandler.class) |
| | | private Boolean hideType; |
| | | |
| | | /** |
| | | * 需要在入库前特殊处理的组件 比如随机编码等 验重 |
| | | */ |
| | | @TableField(value = "is_special_type", typeHandler = BooleanTypeHandler.class) |
| | | private Boolean specialType; |
| | | /** |
| | | * 是否显示标签 |
| | | */ |
| | | @TableField(typeHandler = BooleanTypeHandler.class) |
| | | private Boolean showLabel; |
| | | |
| | | /** |
| | | * 表单项默认值 |
| | | */ |
| | | @TableField(updateStrategy = FieldStrategy.IGNORED) |
| | | private String defaultValue; |
| | | |
| | | |
| | | /** |
| | | * 是否必填 |
| | | */ |
| | | @TableField(typeHandler = BooleanTypeHandler.class) |
| | | private Boolean required; |
| | | /** |
| | | * 输入型提示文字 |
| | | */ |
| | | private String placeholder; |
| | | /** |
| | | * 排序 |
| | | */ |
| | | private Long sort; |
| | | |
| | | /** |
| | | * 栅格宽度 |
| | | */ |
| | | private int span; |
| | | |
| | | /** |
| | | * 扩展字段 表单项独有字段 |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private Map<String, Object> scheme; |
| | | |
| | | /** |
| | | * 正则表达式 |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private List<Map<String, Object>> regList; |
| | | |
| | | |
| | | /** |
| | | * 去除html格式 |
| | | * |
| | | * @return |
| | | */ |
| | | public String getTextLabel() { |
| | | return HtmlUtils.cleanHtmlTag(this.label); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; |
| | | import lombok.Data; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 表单逻辑(UserFormLogic)表实体类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-05-01 13:36:27 |
| | | */ |
| | | @Data |
| | | @Accessors(chain = true) |
| | | @TableName(value = "fm_user_form_logic", autoResultMap = true) |
| | | public class UserFormLogicEntity { |
| | | /** |
| | | * 表单key |
| | | */ |
| | | @NotBlank(message = "formKey不能为空") |
| | | private String formKey; |
| | | |
| | | |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private List<Definition> scheme; |
| | | |
| | | /** |
| | | * 逻辑定义对象 |
| | | */ |
| | | @Data |
| | | public static class Definition { |
| | | |
| | | /** |
| | | * 触发内容 |
| | | */ |
| | | private Set<Trigger> triggerList; |
| | | /** |
| | | * 条件 |
| | | */ |
| | | private Set<Condition> conditionList; |
| | | } |
| | | |
| | | |
| | | @Data |
| | | public static class Trigger { |
| | | /** |
| | | * 表单项Id |
| | | */ |
| | | private String formItemId; |
| | | /** |
| | | * 类型 |
| | | */ |
| | | private String type = "show"; |
| | | } |
| | | |
| | | /** |
| | | * 条件 |
| | | */ |
| | | @Data |
| | | public static class Condition { |
| | | /** |
| | | * 表单项Id |
| | | */ |
| | | private String formItemId; |
| | | /** |
| | | * 表达式 |
| | | */ |
| | | private String expression; |
| | | /** |
| | | * 选项 |
| | | */ |
| | | private Object optionValue; |
| | | |
| | | |
| | | /** |
| | | * AND OR |
| | | */ |
| | | private String relation; |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ltkj.common.core.domain.BaseEntity; |
| | | import com.ltkj.tduck.handler.JacksonTypeHandler; |
| | | import lombok.Data; |
| | | import lombok.experimental.FieldNameConstants; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单设置对象 |
| | | * |
| | | * @author tduck |
| | | * @date 2021-08-12 16:19:57 |
| | | */ |
| | | @Data |
| | | @FieldNameConstants |
| | | @TableName(value = "fm_user_form_setting", autoResultMap = true) |
| | | public class UserFormSettingEntity extends BaseEntity { |
| | | |
| | | |
| | | @NotBlank |
| | | private String formKey; |
| | | |
| | | |
| | | /** |
| | | * 设置具体内容 |
| | | */ |
| | | @TableField(typeHandler = JacksonTypeHandler.class) |
| | | private Map<String, Object> settings; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| | | import lombok.Data; |
| | | import org.apache.ibatis.type.BooleanTypeHandler; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * 表单表单项(UserFormTheme)表实体类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-25 13:36:27 |
| | | */ |
| | | @Data |
| | | @JsonIgnoreProperties(ignoreUnknown = true) |
| | | @TableName(value = "fm_user_form_theme", autoResultMap = true) |
| | | public class UserFormThemeEntity { |
| | | /** |
| | | * 表单key |
| | | */ |
| | | @NotBlank(message = "formKey不能为空") |
| | | private String formKey; |
| | | |
| | | /** |
| | | * logo图片 |
| | | */ |
| | | private String logoImg; |
| | | |
| | | /** |
| | | * logo位置 |
| | | */ |
| | | private String logoPosition; |
| | | |
| | | /** |
| | | * 头部图片 |
| | | */ |
| | | private String headImgUrl; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 主题颜色 |
| | | */ |
| | | private String themeColor; |
| | | |
| | | /** |
| | | * 提交按钮文字 |
| | | */ |
| | | private String submitBtnText; |
| | | |
| | | |
| | | /** |
| | | * 背景 |
| | | */ |
| | | private String backgroundColor; |
| | | |
| | | /** |
| | | * 背景 |
| | | */ |
| | | private String backgroundImg; |
| | | /** |
| | | * 是否显示标题 |
| | | */ |
| | | @TableField(typeHandler = BooleanTypeHandler.class) |
| | | private Boolean showTitle; |
| | | /** |
| | | * 是否显示描述语 |
| | | */ |
| | | @TableField(typeHandler = BooleanTypeHandler.class) |
| | | private Boolean showDescribe; |
| | | /** |
| | | * 显示序号 |
| | | */ |
| | | @TableField(typeHandler = BooleanTypeHandler.class) |
| | | private Boolean showNumber; |
| | | |
| | | /** |
| | | * 显示提交按钮 |
| | | */ |
| | | @TableField(typeHandler = BooleanTypeHandler.class) |
| | | private Boolean showSubmitBtn; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ltkj.common.core.domain.BaseEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 用户表单查看次数对象 fm_user_form_view_count |
| | | * |
| | | * @author tduck |
| | | * @date 2023-04-04 21:29:39 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("fm_user_form_view_count") |
| | | public class UserFormViewCountEntity extends BaseEntity { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | /** |
| | | * 表单唯一标识 |
| | | */ |
| | | private String formKey; |
| | | /** |
| | | * |
| | | */ |
| | | private Long count; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * ElasticSearch的字段类型 |
| | | */ |
| | | @AllArgsConstructor |
| | | @Getter |
| | | public enum EsTypeEnum { |
| | | |
| | | STRING("string", "字符串类型"), |
| | | TEXT("text", "字符串类型"), |
| | | KEYWORD("keyword", "字符串类型"), |
| | | INTEGER("integer", "整数类型"), |
| | | LONG("long", "整数类型"), |
| | | SHORT("short", "整数类型"), |
| | | BYTE("byte", "整数类型"), |
| | | DOUBLE("double", "浮点类型"), |
| | | FLOAT("float", "浮点类型"), |
| | | HALF_FLOAT("half_float", "浮点类型"), |
| | | SCALED_FLOAT("scaled_float", "浮点类型"), |
| | | BOOLEAN("boolean", "逻辑类型"), |
| | | DATE("date", "日期类型"); |
| | | |
| | | private String type; |
| | | private String name; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IEnum; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 表单项类型枚举 |
| | | * @create : 2020-11-19 10:51 |
| | | **/ |
| | | @AllArgsConstructor |
| | | @Getter |
| | | public enum FormItemTypeEnum implements IEnum<String> { |
| | | |
| | | INPUT("单行文本"), |
| | | NUMBER("数字"), |
| | | TEXTAREA("多行文本"), |
| | | SELECT("下拉框"), |
| | | CASCADER("级联选择"), |
| | | SORT("排序"), |
| | | SLIDER("滑块"), |
| | | RADIO("单选框"), |
| | | CHECKBOX("多选框"), |
| | | DATE("日期选择"), |
| | | DATE_RANGE("日期范围"), |
| | | RATE("评分"), |
| | | IMAGE_UPLOAD("图片上传"), |
| | | UPLOAD("文件上传组件"), |
| | | IMAGE("图片展示"), |
| | | IMAGE_SELECT("图片选择"), |
| | | IMAGE_CAROUSEL("图片轮播"), |
| | | DESC_TEXT("文字描述"), |
| | | SIGN_PAD("手写签名"), |
| | | PAGINATION("分页"), |
| | | DIVIDER("分割线"), |
| | | PROVINCE_CITY("省市联动"), |
| | | PHONE_VERIFICATION("手机号验证"), |
| | | SUB_FORM("子表单"), |
| | | INPUT_MAP("地理位置"), |
| | | MATRIX_INPUT("矩阵填空"), |
| | | MATRIX_SCALE("矩阵量表"), |
| | | HORIZONTAL_INPUT("横向填空"), |
| | | MATRIX_SELECT("矩阵选择"), |
| | | USER_SELECT("成员选择"), |
| | | DEPT_SELECT("部门选择"), |
| | | OCR("文字识别"), |
| | | RANDOM_NUMBER("随机编号"), |
| | | FUNCTION_CALC("函数计算"), |
| | | GOODS_SELECT("商品选择"), |
| | | RESERVE_DAY("预约日期"), |
| | | RESERVE_TIME_RANGE("预约时段"); |
| | | private String desc; |
| | | |
| | | |
| | | @Override |
| | | public String getValue() { |
| | | return this.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.EnumValue; |
| | | import com.fasterxml.jackson.annotation.JsonValue; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description :逻辑条件 |
| | | * @create : 2020-12-04 13:35 |
| | | **/ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum FormLogicConditionExpressionEnum { |
| | | |
| | | EQ("eq", "等于"), |
| | | NE("ne", "不等于"); |
| | | |
| | | |
| | | @EnumValue |
| | | @JsonValue |
| | | private String value; |
| | | |
| | | private String desc; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | |
| | | /** |
| | | * 表单按钮权限类型 |
| | | */ |
| | | @AllArgsConstructor |
| | | public enum FormPermsBtnTypeEnum { |
| | | DETAIL("detail", "查看"), |
| | | ADD("add", "新增"), |
| | | IMPORT("import", "导入"), |
| | | EXPORT("export", "导出"), |
| | | QUERY("query", "结构查询"), |
| | | BATCH_ACTION("batchAction", "批量操作"), |
| | | CUSTOM_COLUMN("customColumn", "自定义列"), |
| | | UPDATE("update", "编辑"), |
| | | DELETE("delete", "删除"); |
| | | |
| | | |
| | | private final String code; |
| | | private final String desc; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.EnumValue; |
| | | import com.fasterxml.jackson.annotation.JsonValue; |
| | | import com.ltkj.tduck.utils.IDictEnum; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 表单来源 |
| | | * @create : 2020-12-04 13:35 |
| | | **/ |
| | | |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum FormSourceTypeEnum implements IDictEnum { |
| | | |
| | | BLANK(1, "空白创建"), |
| | | TEMPLATE(2, "模板"); |
| | | |
| | | |
| | | @EnumValue |
| | | @JsonValue |
| | | private Integer value; |
| | | |
| | | private String desc; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.EnumValue; |
| | | import com.fasterxml.jackson.annotation.JsonValue; |
| | | import com.ltkj.tduck.utils.IDictEnum; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 表单状态 |
| | | * @create : 2020-12-04 13:35 |
| | | **/ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public enum FormStatusEnum implements IDictEnum<Integer> { |
| | | |
| | | CREATE(1, "未发布"), |
| | | RELEASE(2, "收集中"), |
| | | STOP(3, "停止发布"); |
| | | |
| | | |
| | | @EnumValue |
| | | @JsonValue |
| | | private Integer value; |
| | | |
| | | private String desc; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | import com.ltkj.tduck.utils.IDictEnum; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 表单类型 |
| | | * @create : 2020-12-04 13:35 |
| | | **/ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum FormTypeEnum implements IDictEnum { |
| | | |
| | | |
| | | /** |
| | | * 普通表单 |
| | | */ |
| | | ORDINARY(1, "普通表单"), |
| | | /** |
| | | * 流程表单 |
| | | */ |
| | | WORKFLOW(2, "流程表单"), |
| | | /** |
| | | * 文件夹 |
| | | */ |
| | | FOLDER(3, "文件夹"), |
| | | /** |
| | | * 考试 |
| | | */ |
| | | EXAM(4, "考试"); |
| | | |
| | | private Integer value; |
| | | private String desc; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | |
| | | package com.ltkj.tduck.enums; |
| | | |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : 时间范围枚举 |
| | | * @create : 2022/10/11 11:12 |
| | | **/ |
| | | @NoArgsConstructor |
| | | @Getter |
| | | public enum TimeRangeEnum { |
| | | /** |
| | | * 今天 |
| | | */ |
| | | TODAY, |
| | | /** |
| | | * 昨天 |
| | | */ |
| | | YESTERDAY, |
| | | /** |
| | | * 近7天 |
| | | */ |
| | | WEEK, |
| | | /** |
| | | * 上周 |
| | | */ |
| | | LAST_WEEK, |
| | | /** |
| | | * 本月 |
| | | */ |
| | | MONTH, |
| | | /** |
| | | * 上月 |
| | | */ |
| | | LAST_MONTH, |
| | | /** |
| | | * 本季度 |
| | | */ |
| | | QUARTER, |
| | | /** |
| | | * 上季度 |
| | | */ |
| | | LAST_QUARTER, |
| | | /** |
| | | * 本年 |
| | | */ |
| | | YEAR, |
| | | /** |
| | | * 去年 |
| | | */ |
| | | LAST_YEAR; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | //package com.ltkj.tduck.handler; |
| | | // |
| | | //import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
| | | //import com.ltkj.tduck.domain.TBaseEntity; |
| | | //import lombok.extern.slf4j.Slf4j; |
| | | //import org.apache.ibatis.reflection.MetaObject; |
| | | //import org.springframework.stereotype.Component; |
| | | // |
| | | //import java.time.LocalDateTime; |
| | | // |
| | | ///** |
| | | // * @author smalljop |
| | | // * mybatis 自动填充插件 |
| | | // * @link https://baomidou.com/guide/typehandler.html |
| | | // */ |
| | | //@Slf4j |
| | | //@Component |
| | | //public class AutoFillMetaInfoHandler implements MetaObjectHandler { |
| | | // |
| | | // @Override |
| | | // public void insertFill(MetaObject metaObject) { |
| | | // this.setFieldValByName(TBaseEntity.Fields.createTime, LocalDateTime.now(), metaObject); |
| | | // this.setFieldValByName(TBaseEntity.Fields.updateTime, LocalDateTime.now(), metaObject); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public void updateFill(MetaObject metaObject) { |
| | | // this.setFieldValByName(TBaseEntity.Fields.updateTime, LocalDateTime.now(), metaObject); |
| | | // } |
| | | //} |
New file |
| | |
| | | |
| | | package com.ltkj.tduck.handler; |
| | | |
| | | import org.apache.ibatis.type.BaseTypeHandler; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | |
| | | import java.sql.CallableStatement; |
| | | import java.sql.PreparedStatement; |
| | | import java.sql.ResultSet; |
| | | import java.sql.SQLException; |
| | | |
| | | /** |
| | | * 处理布尔转换 mysql能自动转换 |
| | | * 有的数据库不支持自动转换 pgsql不行 干脆统一处理了 |
| | | * |
| | | * @author tduck |
| | | */ |
| | | public class BooleanTypeHandler extends BaseTypeHandler<Boolean> { |
| | | |
| | | public BooleanTypeHandler() { |
| | | } |
| | | |
| | | @Override |
| | | public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException { |
| | | ps.setInt(i, parameter ? 1 : 0); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException { |
| | | boolean result = rs.getInt(columnName) != 0; |
| | | return !result && rs.wasNull() ? null : result; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException { |
| | | boolean result = rs.getInt(columnIndex) != 0; |
| | | return !result && rs.wasNull() ? null : result; |
| | | } |
| | | |
| | | @Override |
| | | public Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { |
| | | boolean result = cs.getInt(columnIndex) != 0; |
| | | return !result && cs.wasNull() ? null : result; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.handler; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Assert; |
| | | import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.ltkj.tduck.utils.JsonUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | import org.apache.ibatis.type.MappedJdbcTypes; |
| | | import org.apache.ibatis.type.MappedTypes; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * Jackson 实现 JSON 字段类型处理器 |
| | | * |
| | | * @author hubin |
| | | * @since 2019-08-25 |
| | | */ |
| | | @Slf4j |
| | | @MappedTypes({Object.class}) |
| | | @MappedJdbcTypes(JdbcType.VARCHAR) |
| | | public class JacksonTypeHandler extends AbstractJsonTypeHandler<Object> { |
| | | private static ObjectMapper objectMapper = new ObjectMapper(); |
| | | private Class<?> type; |
| | | |
| | | public JacksonTypeHandler(Class<?> type) { |
| | | if (log.isTraceEnabled()) { |
| | | log.trace("JacksonTypeHandler(" + type + ")"); |
| | | } |
| | | Assert.notNull(type, "Type argument cannot be null"); |
| | | this.type = type; |
| | | } |
| | | |
| | | public static void setObjectMapper(ObjectMapper objectMapper) { |
| | | Assert.notNull(objectMapper, "ObjectMapper should not be null"); |
| | | JacksonTypeHandler.objectMapper = JsonUtils.getInstance(); |
| | | } |
| | | |
| | | @Override |
| | | protected Object parse(String json) { |
| | | try { |
| | | if (StrUtil.isBlank(json)) { |
| | | return null; |
| | | } |
| | | return objectMapper.readValue(json, type); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected String toJson(Object obj) { |
| | | try { |
| | | return JsonUtils.objToJsonIgnoreNull(obj); |
| | | } catch (JsonProcessingException e) { |
| | | throw new RuntimeException(e); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.handler; |
| | | |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.JsonSerializer; |
| | | import com.fasterxml.jackson.databind.SerializerProvider; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * @author : wangqing |
| | | * @description : Long转string 避免返回前端丢失精度 |
| | | * @create : 2022/03/10 15:07 |
| | | **/ |
| | | |
| | | public class LongToStringSerializer extends JsonSerializer<Long> { |
| | | |
| | | |
| | | /** |
| | | * Method that can be called to ask implementation to serialize |
| | | * values of type this serializer handles. |
| | | * |
| | | * @param value Value to serialize; can <b>not</b> be null. |
| | | * @param gen Generator used to output resulting Json content |
| | | * @param serializers Provider that can be used to get serializers for |
| | | */ |
| | | @Override |
| | | public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { |
| | | if (value != null && value.toString().length() > 16) { |
| | | gen.writeString(value.toString()); |
| | | } else { |
| | | gen.writeNumber(value); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.FormTemplateCategoryEntity; |
| | | |
| | | /** |
| | | * 表单模板分类(FormTemplateType)表数据库访问层 |
| | | * |
| | | * @author smalljop |
| | | * @since 2021-01-06 10:51:05 |
| | | */ |
| | | public interface FormTemplateCategoryMapper extends BaseMapper<FormTemplateCategoryEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.FormThemeEntity; |
| | | |
| | | /** |
| | | * 表单主题外观模板(FormTheme)表数据库访问层 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 18:33:54 |
| | | */ |
| | | public interface FormThemeMapper extends BaseMapper<FormThemeEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.apache.ibatis.annotations.Result; |
| | | import org.apache.ibatis.annotations.Results; |
| | | import org.apache.ibatis.annotations.Select; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 表单表单数据(FormResult)表数据库访问层 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 14:09:21 |
| | | */ |
| | | public interface UserFormDataMapper extends BaseMapper<UserFormDataEntity> { |
| | | |
| | | /** |
| | | * 查询表单字段值是否存在 |
| | | * @param formKey 表单key |
| | | * @param field 字段 |
| | | * @param value 值 |
| | | * @return 是否存在 |
| | | */ |
| | | @Select("SELECT COUNT(id) FROM fm_user_form_data WHERE form_key = #{formKey} AND JSON_EXTRACT(original_data, '$.\"${field}\"') = #{value}") |
| | | Long selectOriginalDataValueCount(@Param("formKey") String formKey, @Param("field") String field, @Param("value") Object value); |
| | | |
| | | |
| | | /** |
| | | * 查询表单数据 |
| | | * @param sql sql |
| | | * @return |
| | | */ |
| | | @Results(id="queryRowsResultMap", |
| | | value = { |
| | | @Result(property = "originalData", column = "original_data",typeHandler = JacksonTypeHandler.class), |
| | | @Result(property = "wxUserInfo", column = "wx_user_info",typeHandler = JacksonTypeHandler.class)}) |
| | | @Select("${sql}") |
| | | List<UserFormDataEntity> selectRowsBySql(@Param("sql") String sql); |
| | | |
| | | |
| | | /** |
| | | * 查询表单数据条数 |
| | | * @param sql |
| | | * @return |
| | | */ |
| | | @Select("${sql}") |
| | | Long selectCountBySql(@Param("sql") String sql); |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.UserFormItemEntity; |
| | | |
| | | /** |
| | | * 表单项(FormItem)表数据库访问层 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-19 10:49:17 |
| | | */ |
| | | public interface UserFormItemMapper extends BaseMapper<UserFormItemEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.UserFormLogicEntity; |
| | | |
| | | /** |
| | | * 用户表单逻辑表(UserFormLogic)表数据库访问层 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-18 18:16:17 |
| | | */ |
| | | public interface UserFormLogicMapper extends BaseMapper<UserFormLogicEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | |
| | | /** |
| | | * 表单表(Form)表数据库访问层 |
| | | */ |
| | | public interface UserFormMapper extends BaseMapper<UserFormEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.UserFormSettingEntity; |
| | | |
| | | /** |
| | | * 表单设置 |
| | | * |
| | | * @author tduck |
| | | * @date 2021-08-12 16:19:57 |
| | | */ |
| | | public interface UserFormSettingMapper extends BaseMapper<UserFormSettingEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.UserFormThemeEntity; |
| | | |
| | | /** |
| | | * 表单主题(UserFormTheme)表数据库访问层 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-25 13:36:31 |
| | | */ |
| | | public interface UserFormThemeMapper extends BaseMapper<UserFormThemeEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ltkj.tduck.domain.UserFormViewCountEntity; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.apache.ibatis.annotations.Update; |
| | | |
| | | /** |
| | | * 用户表单查看次数Mapper接口 |
| | | * |
| | | * @author tduck |
| | | * @date 2023-04-04 21:29:39 |
| | | */ |
| | | public interface UserFormViewCountMapper extends BaseMapper<UserFormViewCountEntity> { |
| | | |
| | | |
| | | /** |
| | | * 查看次数自增 |
| | | * |
| | | * @param formKey 表单key |
| | | */ |
| | | @Update("update fm_user_form_view_count set count = count + 1 , update_time=now() where form_key = #{formKey}") |
| | | void incrementCount(@Param("formKey") String formKey); |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.request; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | @Data |
| | | public class CheckWritePwdRequest { |
| | | |
| | | @NotBlank |
| | | private String formKey; |
| | | @NotBlank |
| | | private String password; |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.request; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 查询表单问题 |
| | | * @create : 2021/06/03 14:45 |
| | | **/ |
| | | @Data |
| | | public class QueryFormItemRequest { |
| | | |
| | | /** |
| | | * 表单key |
| | | */ |
| | | @NotBlank |
| | | private String key; |
| | | /** |
| | | * 是显示类型 |
| | | */ |
| | | private Boolean displayType; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.request; |
| | | |
| | | import cn.hutool.core.date.DatePattern; |
| | | import com.ltkj.tduck.domain.PageRequest; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 查询表单 |
| | | * @create : 2020-12-10 15:04 |
| | | **/ |
| | | @Data |
| | | public class QueryFormRequest { |
| | | |
| | | |
| | | @Data |
| | | public static class List { |
| | | private Integer status; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 分页查询 |
| | | */ |
| | | @Data |
| | | public static class Page extends PageRequest { |
| | | private Long folderId; |
| | | |
| | | |
| | | private Integer type; |
| | | private Integer status; |
| | | |
| | | private String name; |
| | | |
| | | /** |
| | | * 是否包含文件夹 |
| | | */ |
| | | private Boolean folder; |
| | | |
| | | @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) |
| | | private LocalDateTime beginDateTime; |
| | | |
| | | @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) |
| | | private LocalDateTime endDateTime; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.request; |
| | | |
| | | import cn.hutool.core.date.DatePattern; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.experimental.FieldNameConstants; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 表单结果查询 |
| | | * @create : 2020-12-08 15:55 |
| | | **/ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | @FieldNameConstants |
| | | public class QueryFormResultRequest { |
| | | |
| | | /** |
| | | * 当前页 |
| | | */ |
| | | private Integer current; |
| | | /** |
| | | * 大小 |
| | | */ |
| | | private Integer size; |
| | | |
| | | /** |
| | | * 固定字段 |
| | | */ |
| | | @NotBlank |
| | | private String formKey; |
| | | |
| | | @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) |
| | | private LocalDateTime beginDateTime; |
| | | @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) |
| | | private LocalDateTime endDateTime; |
| | | |
| | | /** |
| | | * 被查询的字段 |
| | | */ |
| | | private String[] filterFields; |
| | | |
| | | /** |
| | | * 数据id 集合 |
| | | */ |
| | | private List<String> dataIds; |
| | | |
| | | |
| | | private Long inCode; |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.request; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 查询表单模板分页 |
| | | * @create : 2020-12-10 15:04 |
| | | **/ |
| | | @Data |
| | | public class QueryFormTemplateTypeRequest { |
| | | |
| | | |
| | | @Data |
| | | public static class List { |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.request; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 排序表单项 |
| | | * @create : 2020-11-20 10:14 |
| | | **/ |
| | | @Data |
| | | public class SortFormItemRequest { |
| | | /** |
| | | * 表单Id |
| | | */ |
| | | @NotNull(message = "key请求异常") |
| | | private String formKey; |
| | | |
| | | |
| | | private Long beforePosition; |
| | | |
| | | private Long afterPosition; |
| | | @NotBlank(message = "formItemId请求异常") |
| | | private String formItemId; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.FormTemplateCategoryEntity; |
| | | |
| | | /** |
| | | * 表单模板分类(FormTemplateType)表服务接口 |
| | | * |
| | | * @author smalljop |
| | | * @since 2021-01-06 10:51:06 |
| | | */ |
| | | public interface FormTemplateCategoryService extends IService<FormTemplateCategoryEntity> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.FormThemeEntity; |
| | | |
| | | /** |
| | | * 表单主题外观模板(FormTheme)表服务接口 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 18:33:55 |
| | | */ |
| | | public interface FormThemeService extends IService<FormThemeEntity> { |
| | | |
| | | // /** |
| | | // * 获取主题分类 |
| | | // * |
| | | // * @return |
| | | // */ |
| | | // List<FormThemeCategoryEntity> listThemeCategories(); |
| | | // |
| | | // /** |
| | | // * 获取表单分类 |
| | | // * |
| | | // * @param categoryId |
| | | // * @return |
| | | // */ |
| | | // FormThemeCategoryEntity getThemeCategory(Long categoryId); |
| | | // |
| | | // /** |
| | | // * 保存主题分类 |
| | | // * |
| | | // * @param entity |
| | | // * @return |
| | | // */ |
| | | // Boolean saveThemeCategory(FormThemeCategoryEntity entity); |
| | | // |
| | | // /** |
| | | // * 修改主题分类 |
| | | // * |
| | | // * @param entity |
| | | // * @return |
| | | // */ |
| | | // Boolean updateThemeCategory(FormThemeCategoryEntity entity); |
| | | // |
| | | // /** |
| | | // * 删除主题分类 |
| | | // * |
| | | // * @param categoryId |
| | | // * @return |
| | | // */ |
| | | // Boolean deleteThemeCategory(List<Long> categoryIds); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import com.ltkj.tduck.request.QueryFormResultRequest; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import com.ltkj.tduck.vo.FormDataTableVO; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单表单项(FormResult)表服务接口 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 14:09:22 |
| | | */ |
| | | public interface UserFormDataService extends IService<UserFormDataEntity> { |
| | | |
| | | |
| | | /** |
| | | * 保存结果 |
| | | * |
| | | * @param entity 表单数据 |
| | | * @return 结果 |
| | | */ |
| | | Map<String, Object> saveFormResult(UserFormDataEntity entity); |
| | | |
| | | // /** |
| | | // * 下载表单结果中的附件 |
| | | // * |
| | | // * @param request 请求 |
| | | // * @return |
| | | // */ |
| | | // Result downloadFormResultFile(QueryFormResultRequest request); |
| | | |
| | | |
| | | /** |
| | | * 查询表单数据 |
| | | * |
| | | * @param request |
| | | * @return |
| | | */ |
| | | FormDataTableVO listFormDataTable(QueryFormResultRequest request); |
| | | |
| | | // /** |
| | | // * 根据Id删除 |
| | | // * |
| | | // * @param dataIdList |
| | | // * @param formKey |
| | | // * @return |
| | | // */ |
| | | // Boolean deleteByIds(List<String> dataIdList, String formKey); |
| | | // |
| | | // /** |
| | | // * 修改 |
| | | // * |
| | | // * @param entity |
| | | // * @return |
| | | // */ |
| | | // Boolean updateFormResult(UserFormDataEntity entity); |
| | | // |
| | | /** |
| | | * 获取数据详情 |
| | | * |
| | | * @param dataId |
| | | * @return |
| | | */ |
| | | Result getFormDataDetails(String dataId); |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormItemEntity; |
| | | import com.ltkj.tduck.vo.FormFieldVO; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 表单表单项(FormItem)表服务接口 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-19 10:49:17 |
| | | */ |
| | | public interface UserFormItemService extends IService<UserFormItemEntity> { |
| | | |
| | | |
| | | // /** |
| | | // * 根据key查询 |
| | | // * |
| | | // * @param key |
| | | // * @return |
| | | // */ |
| | | // List<UserFormItemEntity> listByFormKey(String key); |
| | | // |
| | | /** |
| | | * 查询自定义字段 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 自定义字段 |
| | | */ |
| | | List<FormFieldVO> listFormFields(String formKey); |
| | | |
| | | /** |
| | | * 查询全部字段 包含默认字段 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 自定义字段 |
| | | */ |
| | | List<FormFieldVO> listAllFormFields(String formKey); |
| | | |
| | | |
| | | /** |
| | | * 查询最后一个字段的排序值 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 排序值 |
| | | */ |
| | | Long getLastItemSort(String formKey); |
| | | // |
| | | /** |
| | | * 检查字段是否是需要特殊处理字段 比如随机编号 |
| | | * |
| | | * @param userFormItemEntity 字段 |
| | | * @return true 需要特殊处理 |
| | | */ |
| | | Boolean isSpecialTypeItem(UserFormItemEntity userFormItemEntity); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormLogicEntity; |
| | | |
| | | public interface UserFormLogicService extends IService<UserFormLogicEntity> { |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | |
| | | /** |
| | | * 表单表(Form)表服务接口 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-18 18:16:18 |
| | | */ |
| | | public interface UserFormService extends IService<UserFormEntity> { |
| | | |
| | | |
| | | /** |
| | | * 根据key获取 |
| | | * |
| | | * @param key key |
| | | * @return UserFormEntity |
| | | */ |
| | | UserFormEntity getByKey(final String key); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormSettingEntity; |
| | | import com.ltkj.tduck.struct.FormSettingSchemaStruct; |
| | | import com.ltkj.tduck.utils.Result; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单设置 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-30 14:00:52 |
| | | */ |
| | | public interface UserFormSettingService extends IService<UserFormSettingEntity> { |
| | | /** |
| | | * 保存表单设置 |
| | | */ |
| | | Boolean saveFormSetting(Map<String, Object> params); |
| | | |
| | | |
| | | /** |
| | | * 表单设置 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 设置项 |
| | | */ |
| | | UserFormSettingEntity getFormSettingByKey(String formKey); |
| | | |
| | | /** |
| | | * 设置具体定义设置项 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 设置项 |
| | | */ |
| | | FormSettingSchemaStruct getFormSettingSchema(String formKey); |
| | | |
| | | /** |
| | | * 获取当前项目设置的状态 |
| | | * 是否可以填写等 |
| | | * |
| | | * @param formKey 表单key |
| | | * @param requestIp 请求ip |
| | | * @param wxOpenId 微信openid |
| | | * @param type 类型 1公开填写 2.指定填写 |
| | | * @return 是否可以填写 |
| | | */ |
| | | Result<Boolean> getUserFormWriteSettingStatus(String formKey, String requestIp, String wxOpenId, Integer type); |
| | | |
| | | |
| | | /** |
| | | * 删除表单所有设置 |
| | | * |
| | | * @param key 表单key |
| | | * @return 是否删除成功 |
| | | */ |
| | | Boolean deleteAllSetting(String key); |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormThemeEntity; |
| | | |
| | | /** |
| | | * 表单表单项(UserFormTheme)表服务接口 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-25 13:36:31 |
| | | */ |
| | | public interface UserFormThemeService extends IService<UserFormThemeEntity> { |
| | | |
| | | /** |
| | | * 获取表单主题详情 |
| | | * |
| | | * @param key |
| | | * @return |
| | | */ |
| | | UserFormThemeEntity getByKey(String key); |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ltkj.tduck.domain.UserFormViewCountEntity; |
| | | |
| | | /** |
| | | * 用户表单查看次数Service接口 |
| | | * |
| | | * @author tduck |
| | | * @date 2023-04-04 21:29:39 |
| | | */ |
| | | public interface UserFormViewCountService extends IService<UserFormViewCountEntity> { |
| | | |
| | | /** |
| | | * 查看次数自增 |
| | | * |
| | | * @param formKey 表单key |
| | | */ |
| | | void increment(String formKey); |
| | | |
| | | /** |
| | | * 查看次数 |
| | | * |
| | | * @param formKey 表单key |
| | | */ |
| | | Long count(String formKey); |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.data; |
| | | |
| | | import com.ltkj.tduck.request.QueryFormResultRequest; |
| | | import com.ltkj.tduck.vo.FormDataTableVO; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : 表单数据基础服务 |
| | | * @create : 2022/07/04 13:50 |
| | | **/ |
| | | public abstract class FormDataBaseService { |
| | | |
| | | |
| | | /*** |
| | | * 表单字段值是否存在 |
| | | * @param formKey 表单key |
| | | * @param formItemId 表单字段id |
| | | * @param value 字段值 |
| | | * @return true 存在 false 不存在 |
| | | */ |
| | | public abstract Boolean valueExist(String formKey, String formItemId, Object value); |
| | | |
| | | |
| | | /** |
| | | * 同步表单数据 |
| | | * |
| | | * @param result 表单数据 |
| | | * @return 是否同步成功 |
| | | */ |
| | | // public abstract Boolean syncSaveData(UserFormDataEntity result); |
| | | // |
| | | // /** |
| | | // * 同步更新数据 |
| | | // * |
| | | // * @param result 表单数据 |
| | | // */ |
| | | // public abstract Boolean asyncUpdateData(UserFormDataEntity result); |
| | | // |
| | | // /** |
| | | // * 删除表单数据 |
| | | // * |
| | | // * @param idList 表单数据id列表 |
| | | // * @param formKey 表单key |
| | | // */ |
| | | // public abstract void asyncDeleteData(List<String> idList, String formKey); |
| | | // |
| | | /** |
| | | * 查询表单数据 |
| | | * |
| | | * @param request 查询内容 |
| | | */ |
| | | public abstract FormDataTableVO search(QueryFormResultRequest request); |
| | | // |
| | | // |
| | | // /** |
| | | // * 查询全部数据 |
| | | // */ |
| | | // public abstract List<Map> searchAll(QueryFormResultRequest request); |
| | | // |
| | | // |
| | | // /** |
| | | // * 构造时间范围查询 |
| | | // * |
| | | // * @param condition 条件 |
| | | // * @return 时间范围 |
| | | // */ |
| | | // protected Map<String, DateTime> getRangDateTime(FormDataFilterStruct.Condition condition) { |
| | | // if (ObjectUtil.isNull(condition.getValue())) { |
| | | // return null; |
| | | // } |
| | | // DateTime beginDate = null; |
| | | // DateTime endDate = null; |
| | | // TimeRangeEnum timeRangeEnum = TimeRangeEnum.valueOf(condition.getValue().toString()); |
| | | // switch (timeRangeEnum) { |
| | | // case TODAY: |
| | | // beginDate = DateUtil.beginOfDay(new Date()); |
| | | // endDate = DateUtil.endOfDay(new Date()); |
| | | // break; |
| | | // case YESTERDAY: |
| | | // beginDate = DateUtil.beginOfDay(DateUtil.yesterday()); |
| | | // endDate = DateUtil.endOfDay(DateUtil.yesterday()); |
| | | // break; |
| | | // case WEEK: |
| | | // beginDate = DateUtil.beginOfWeek(new Date()); |
| | | // endDate = DateUtil.endOfWeek(new Date()); |
| | | // break; |
| | | // case LAST_WEEK: |
| | | // beginDate = DateUtil.beginOfWeek(DateUtil.lastWeek()); |
| | | // endDate = DateUtil.endOfWeek(DateUtil.lastWeek()); |
| | | // break; |
| | | // case MONTH: |
| | | // beginDate = DateUtil.beginOfMonth(new Date()); |
| | | // endDate = DateUtil.endOfMonth(new Date()); |
| | | // break; |
| | | // case LAST_MONTH: |
| | | // beginDate = DateUtil.beginOfMonth(DateUtil.lastMonth()); |
| | | // endDate = DateUtil.endOfMonth(DateUtil.lastMonth()); |
| | | // break; |
| | | // case YEAR: |
| | | // beginDate = DateUtil.beginOfYear(new Date()); |
| | | // endDate = DateUtil.endOfYear(new Date()); |
| | | // break; |
| | | // case LAST_YEAR: |
| | | // Date lastYear = DateUtil.offset(new Date(), DateField.YEAR, -1); |
| | | // beginDate = DateUtil.beginOfYear(lastYear); |
| | | // endDate = DateUtil.endOfYear(lastYear); |
| | | // break; |
| | | // default: |
| | | // beginDate = DateUtil.date(); |
| | | // endDate = DateUtil.date(); |
| | | // break; |
| | | // } |
| | | // Map<String, DateTime> result = MapUtil.newHashMap(); |
| | | // result.put("beginDate", beginDate); |
| | | // result.put("endDate", endDate); |
| | | // return result; |
| | | // } |
| | | // |
| | | // |
| | | // public static Map<String, Object> convertDocument(UserFormDataEntity result) { |
| | | // Map<String, Object> processData = result.getOriginalData(); |
| | | // Map<String, Object> resultMap = BeanUtil.beanToMap(result); |
| | | // //格式化时间 |
| | | // |
| | | //// resultMap.put(BaseEntity.Fields.updateTime, LocalDateTimeUtil.formatNormal(result.getUpdateTime())); |
| | | //// resultMap.put(BaseEntity.Fields.createTime, LocalDateTimeUtil.formatNormal(result.getCreateTime())); |
| | | // resultMap.remove(UserFormDataEntity.Fields.originalData); |
| | | // processData.putAll(resultMap); |
| | | // processData.remove(SysBaseEntity.Fields.searchValue); |
| | | // processData.remove(SysBaseEntity.Fields.params); |
| | | // return processData; |
| | | // } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.data; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.ltkj.system.service.ISysConfigService; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import com.ltkj.tduck.mapper.UserFormDataMapper; |
| | | import com.ltkj.tduck.request.QueryFormResultRequest; |
| | | import com.ltkj.tduck.vo.FormDataTableVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * @author : wangqing |
| | | * @description : 表单数据基础服务 |
| | | * @create : 2022/07/04 14:25 |
| | | **/ |
| | | @Service |
| | | @Slf4j |
| | | public class FormDataMysqlService extends FormDataBaseService { |
| | | |
| | | @Autowired |
| | | private UserFormDataMapper userFormDataMapper; |
| | | |
| | | |
| | | |
| | | @Autowired |
| | | private ISysConfigService configService; |
| | | |
| | | // @Autowired(required = false) |
| | | // private TduckMongoTemplate mongoTemplate; |
| | | // |
| | | // |
| | | @Override |
| | | public Boolean valueExist(String formKey, String formItemId, Object value) { |
| | | return userFormDataMapper.selectOriginalDataValueCount(formKey, formItemId, value) > 0; |
| | | } |
| | | // |
| | | // @Override |
| | | // public Boolean syncSaveData(UserFormDataEntity result) { |
| | | // if (null == mongoTemplate) { |
| | | // return true; |
| | | // } |
| | | // mongoTemplate.save(convertDocument(result), result.getFormKey()); |
| | | // return true; |
| | | // } |
| | | // |
| | | // |
| | | // @Override |
| | | // public Boolean asyncUpdateData(UserFormDataEntity result) { |
| | | // if (null == mongoTemplate) { |
| | | // return true; |
| | | // } |
| | | // mongoTemplate.updateById(convertDocument(result), result.getId(), result.getFormKey()); |
| | | // return true; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public void asyncDeleteData(List<String> idList, String formKey) { |
| | | // if (null == mongoTemplate) { |
| | | // return; |
| | | // } |
| | | // mongoTemplate.deleteByIds(idList, formKey); |
| | | // } |
| | | |
| | | |
| | | @Override |
| | | public FormDataTableVO search(QueryFormResultRequest request) { |
| | | // 拼接sql |
| | | StringBuilder sqlBuilder = new StringBuilder(); |
| | | sqlBuilder.append("select * from fm_user_form_data where form_key = '").append(request.getFormKey()).append("'"); |
| | | |
| | | //1. 拼接条件 查询条件 用大括号包起来 里面的条件会拼接 OR 或者 AND 不能影响其他默认附带条件 比如form_key 否则会错误查询 |
| | | StringBuilder whereBuilder = new StringBuilder(); |
| | | |
| | | // 查询指定id数据 |
| | | if (ObjectUtil.isNotNull(request.getDataIds()) && 0 != request.getDataIds().size()) { |
| | | whereBuilder.append(" and id in (").append(CollUtil.join(request.getDataIds(), ",")).append(")"); |
| | | } |
| | | // 先查询总数,查询总数后再进行拼接order by 及 limit 语句 |
| | | StringBuilder countBuilder = new StringBuilder("select count(1) from fm_user_form_data where form_key = '").append(request.getFormKey()).append("'"); |
| | | countBuilder.append(whereBuilder); |
| | | Long total = userFormDataMapper.selectCountBySql(countBuilder.toString()); |
| | | |
| | | whereBuilder.append(" ORDER BY id DESC"); |
| | | // 分页 |
| | | if (ObjectUtil.isNotNull(request.getCurrent()) && ObjectUtil.isNotNull(request.getSize())) { |
| | | whereBuilder.append(" limit ").append(request.getCurrent() * request.getSize()).append(",").append(request.getSize()); |
| | | } |
| | | sqlBuilder.append(whereBuilder); |
| | | List<UserFormDataEntity> userFormDataEntities = userFormDataMapper.selectRowsBySql(sqlBuilder.toString()); |
| | | |
| | | // 过滤指定字段 |
| | | List<Map> maps = expandData(userFormDataEntities, request.getFilterFields()); |
| | | return new FormDataTableVO(maps, total); |
| | | } |
| | | |
| | | // @Override |
| | | // public List<Map> searchAll(QueryFormResultRequest request) { |
| | | // // 拼接sql |
| | | // List<UserFormDataEntity> userFormDataEntities = userFormDataMapper.selectRowsBySql("select * from fm_user_form_data where form_key = '" + request.getFormKey() + "'"); |
| | | // return expandData(userFormDataEntities, null); |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * 展开数据为一级 |
| | | */ |
| | | public List<Map> expandData(List<UserFormDataEntity> userFormDataEntities, String[] filterFields) { |
| | | return userFormDataEntities.stream().map(item -> { |
| | | Map<String, Object> processData = item.getOriginalData(); |
| | | Map<String, Object> resultMap = BeanUtil.beanToMap(item); |
| | | resultMap.remove(UserFormDataEntity.Fields.originalData); |
| | | // resultMap.put(BaseEntity.Fields.createTime, LocalDateTimeUtil.formatNormal(item.getCreateTime())); |
| | | // resultMap.put(BaseEntity.Fields.updateTime, LocalDateTimeUtil.formatNormal(item.getUpdateTime())); |
| | | processData.putAll(resultMap); |
| | | // 只过滤指定字段 |
| | | if (filterFields != null) { |
| | | Map<String, Object> filterMap = MapUtil.newHashMap(); |
| | | for (String filterField : filterFields) { |
| | | filterMap.put(filterField, processData.get(filterField)); |
| | | } |
| | | return filterMap; |
| | | } |
| | | return processData; |
| | | }).collect(Collectors.toList()); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.FormTemplateCategoryEntity; |
| | | import com.ltkj.tduck.mapper.FormTemplateCategoryMapper; |
| | | import com.ltkj.tduck.service.FormTemplateCategoryService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * 表单模板分类(FormTemplateType)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2021-01-06 10:51:06 |
| | | */ |
| | | @Service |
| | | public class FormTemplateCategoryServiceImpl extends ServiceImpl<FormTemplateCategoryMapper, FormTemplateCategoryEntity> implements FormTemplateCategoryService { |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.FormThemeEntity; |
| | | import com.ltkj.tduck.mapper.FormThemeMapper; |
| | | import com.ltkj.tduck.service.FormThemeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * 表单主题外观模板(FormTheme)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 18:33:56 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class FormThemeServiceImpl extends ServiceImpl<FormThemeMapper, FormThemeEntity> implements FormThemeService { |
| | | |
| | | // private final FormThemeCategoryMapper formThemeCategoryMapper; |
| | | // |
| | | // @Override |
| | | // public List<FormThemeCategoryEntity> listThemeCategories() { |
| | | // return formThemeCategoryMapper.selectList(null); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public FormThemeCategoryEntity getThemeCategory(Long categoryId) { |
| | | // return formThemeCategoryMapper.selectById(categoryId); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public Boolean saveThemeCategory(FormThemeCategoryEntity entity) { |
| | | // return formThemeCategoryMapper.insert(entity) > 0; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public Boolean updateThemeCategory(FormThemeCategoryEntity entity) { |
| | | // return formThemeCategoryMapper.updateById(entity) > 0; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public Boolean deleteThemeCategory(List<Long> categoryIds) { |
| | | // return formThemeCategoryMapper.deleteBatchIds(categoryIds) > 0; |
| | | // } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.map.MapUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.common.utils.ip.AddressUtils; |
| | | import com.ltkj.tduck.constant.CommonConstants; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import com.ltkj.tduck.mapper.UserFormDataMapper; |
| | | import com.ltkj.tduck.request.QueryFormResultRequest; |
| | | import com.ltkj.tduck.service.UserFormDataService; |
| | | import com.ltkj.tduck.service.UserFormItemService; |
| | | import com.ltkj.tduck.utils.CacheUtils; |
| | | import com.ltkj.tduck.utils.FormDataUtils; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import com.ltkj.tduck.vo.FormDataTableVO; |
| | | import com.ltkj.tduck.vo.FormFieldVO; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static com.ltkj.tduck.constant.FormRedisKeyConstants.FORM_RESULT_NUMBER; |
| | | |
| | | |
| | | /** |
| | | * 表单表单项(FormResult)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-23 14:09:22 |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class UserFormDataServiceImpl extends ServiceImpl<UserFormDataMapper, UserFormDataEntity> implements UserFormDataService { |
| | | |
| | | private final UserFormItemService userFormItemService; |
| | | private final CacheUtils redisUtils; |
| | | private final FormDataUtils formDataUtils; |
| | | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Map<String, Object> saveFormResult(UserFormDataEntity entity) { |
| | | HashMap<String, Object> result = MapUtil.newHashMap(); |
| | | String formKey = entity.getFormKey(); |
| | | entity.setSubmitAddress(AddressUtils.getRealAddressByIP(entity.getSubmitRequestIp())); |
| | | entity.setSerialNumber(redisUtils.incr(StrUtil.format(FORM_RESULT_NUMBER, formKey), CommonConstants.ConstantNumber.ONE)); |
| | | this.save(entity); |
| | | // formDataUtils.syncSaveFormData(entity); |
| | | result.put("id", entity.getId()); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 下载表单结果中的附件 |
| | | * |
| | | * @param request |
| | | * @return |
| | | */ |
| | | // @Override |
| | | // public Result downloadFormResultFile(QueryFormResultRequest request) { |
| | | // String uuid = IdUtil.simpleUUID(); |
| | | // List<UserFormItemEntity> userFormItemEntityList = userFormItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).in(UserFormItemEntity::getType, CollUtil.newArrayList(FormItemTypeEnum.UPLOAD.toString(), FormItemTypeEnum.IMAGE_UPLOAD.toString()))); |
| | | // //结果 |
| | | // List<Map> rows = null; |
| | | // if (ObjectUtil.isNull(request.getCurrent()) && ObjectUtil.isNull(request.getSize())) { |
| | | // rows = formDataUtils.searchAll(request); |
| | | // } else { |
| | | // FormDataTableVO formDataTableVO = this.listFormDataTable(request); |
| | | // rows = formDataTableVO.getRows(); |
| | | // } |
| | | // if (CollectionUtil.isEmpty(rows) || CollectionUtil.isEmpty(userFormItemEntityList)) { |
| | | // return Result.failed("暂无收集附件,无法下载"); |
| | | // } |
| | | // List<Map> finalRows = rows; |
| | | // ThreadUtil.execAsync(() -> { |
| | | // TimeInterval timer = DateUtil.timer(); |
| | | // List<String> paths = new ArrayList<>(); |
| | | // List<InputStream> ins = new ArrayList<>(); |
| | | // try { |
| | | // finalRows.forEach(result -> { |
| | | // int index = 0; |
| | | // userFormItemEntityList.forEach(item -> { |
| | | // List<UploadResultStruct> uploadResults = JsonUtils.jsonToList(JsonUtils.objToJson(MapUtil.get(result, item.getFormItemId(), List.class)), UploadResultStruct.class); |
| | | // if (CollectionUtil.isNotEmpty(uploadResults)) { |
| | | // uploadResults.forEach(uFile -> { |
| | | // if (StrUtil.isNotBlank(uFile.getUrl())) { |
| | | // paths.add(FileNameUtil.getName(uFile.getUrl())); |
| | | // byte[] bytes = HttpUtil.downloadBytes(uFile.getUrl()); |
| | | // ins.add(IoUtil.toStream(bytes)); |
| | | // } |
| | | // }); |
| | | // } |
| | | // }); |
| | | // AsyncProcessUtils.setProcess(uuid, ++index / finalRows.size()); |
| | | // }); |
| | | // // 压缩上传oss |
| | | // ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); |
| | | // ZipUtil.zip(zipOutputStream, paths.toArray(new String[]{}), ins.toArray(new InputStream[]{})); |
| | | // String downloadUrl = OssStorageFactory.getStorageService().upload(zipOutputStream.toByteArray(), StorageUtils.generateFileName("download", ".zip")); |
| | | // AsyncProcessUtils.setProcess(uuid, downloadUrl); |
| | | // log.info("export file cost time: {}", timer.interval()); |
| | | // } catch (Exception e) { |
| | | // log.error("download file", e); |
| | | // } |
| | | // }); |
| | | // return Result.success(uuid); |
| | | // } |
| | | // |
| | | // |
| | | @Override |
| | | public FormDataTableVO listFormDataTable(QueryFormResultRequest request) { |
| | | return formDataUtils.search(request); |
| | | } |
| | | // |
| | | // |
| | | // @Override |
| | | // public Boolean deleteByIds(List<String> dataIdList, String formKey) { |
| | | // baseMapper.deleteBatchIds(dataIdList); |
| | | // formDataUtils.asyncDeleteEsDocument(dataIdList, formKey); |
| | | // return true; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public Boolean updateFormResult(UserFormDataEntity entity) { |
| | | // UserFormDataEntity dataEntity = this.getById(entity.getId()); |
| | | // dataEntity.setOriginalData(entity.getOriginalData()); |
| | | // dataEntity.setUpdateBy(entity.getUpdateBy()); |
| | | // boolean update = this.updateById(dataEntity); |
| | | // // 查询数据 同步到es 避免数据变空被覆盖 |
| | | // formDataUtils.asyncUpdateEsDocument(dataEntity); |
| | | // return update; |
| | | // } |
| | | |
| | | @Override |
| | | public Result getFormDataDetails(String dataId) { |
| | | Map<String, Object> result =new HashMap<>(); |
| | | UserFormDataEntity dataEntity = this.getById(dataId); |
| | | List<FormFieldVO> formFields = userFormItemService.listFormFields(dataEntity.getFormKey()); |
| | | // 表单字段 |
| | | result.put("formFields", formFields); |
| | | // 表单填写数据 |
| | | if (ObjectUtil.isNotNull(dataEntity)) { |
| | | Map<String, Object> originalData = dataEntity.getOriginalData(); |
| | | dataEntity.setOriginalData(null); |
| | | originalData.putAll(BeanUtil.beanToMap(dataEntity, false, true)); |
| | | result.put("formData", originalData); |
| | | } |
| | | return Result.success(result); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | import com.ltkj.tduck.domain.UserFormItemEntity; |
| | | import com.ltkj.tduck.enums.FormItemTypeEnum; |
| | | import com.ltkj.tduck.mapper.UserFormItemMapper; |
| | | import com.ltkj.tduck.service.UserFormItemService; |
| | | import com.ltkj.tduck.service.UserFormService; |
| | | import com.ltkj.tduck.struct.CheckboxSchemaStruct; |
| | | import com.ltkj.tduck.struct.InputResultStruct; |
| | | import com.ltkj.tduck.utils.FormDataUtils; |
| | | import com.ltkj.tduck.vo.FormFieldVO; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 表单表单项(FormItem)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-19 10:49:18 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class UserFormItemServiceImpl extends ServiceImpl<UserFormItemMapper, UserFormItemEntity> implements UserFormItemService { |
| | | |
| | | |
| | | private final UserFormService userFormService; |
| | | |
| | | // @Override |
| | | // public List<UserFormItemEntity> listByFormKey(String key) { |
| | | // List<UserFormItemEntity> list = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, key)); |
| | | // list.sort(Comparator.comparing(UserFormItemEntity::getSort)); |
| | | // return list; |
| | | // } |
| | | // |
| | | @Override |
| | | public List<FormFieldVO> listFormFields(String formKey) { |
| | | List<UserFormItemEntity> itemEntityList = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey).eq(UserFormItemEntity::getDisplayType, 0)); |
| | | itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort)); |
| | | // FormFieldVO 处理了部份组价默认显示label字段 |
| | | List<FormFieldVO> fields = itemEntityList.stream().map(FormFieldVO::new).collect(Collectors.toList()); |
| | | return fields; |
| | | } |
| | | |
| | | @Override |
| | | public List<FormFieldVO> listAllFormFields(String formKey) { |
| | | // 查询表单类型 |
| | | UserFormEntity userFormEntity = userFormService.getByKey(formKey); |
| | | List<FormFieldVO> fields = this.listFormFields(formKey); |
| | | FormDataUtils.addFormDefaultDataField(userFormEntity, fields); |
| | | return fields; |
| | | } |
| | | |
| | | @Override |
| | | public Long getLastItemSort(String formKey) { |
| | | List<UserFormItemEntity> formItemEntityPage = baseMapper.selectList( |
| | | Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey) |
| | | .orderByDesc(UserFormItemEntity::getSort)); |
| | | |
| | | // 去取第一个元素 |
| | | UserFormItemEntity first = CollUtil.getFirst(formItemEntityPage); |
| | | return ObjectUtil.isNull(first) ? 0 : first.getSort(); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean isSpecialTypeItem(UserFormItemEntity userFormItemEntity) { |
| | | // 随机编号 |
| | | if (userFormItemEntity.getType() == FormItemTypeEnum.RANDOM_NUMBER) { |
| | | return true; |
| | | } |
| | | // 不允许重复 |
| | | if (userFormItemEntity.getType() == FormItemTypeEnum.INPUT) { |
| | | InputResultStruct builder = InputResultStruct.builder(userFormItemEntity.getScheme()); |
| | | return builder.isNotRepeat(); |
| | | } |
| | | // 商品 |
| | | if (userFormItemEntity.getType() == FormItemTypeEnum.GOODS_SELECT) { |
| | | return true; |
| | | } |
| | | // 预约时间 |
| | | if (userFormItemEntity.getType() == FormItemTypeEnum.RESERVE_DAY || userFormItemEntity.getType() == FormItemTypeEnum.RESERVE_TIME_RANGE) { |
| | | return true; |
| | | } |
| | | // 投票 |
| | | if (userFormItemEntity.getType() == FormItemTypeEnum.CHECKBOX || userFormItemEntity.getType() == FormItemTypeEnum.RADIO || userFormItemEntity.getType() == FormItemTypeEnum.IMAGE_SELECT) { |
| | | CheckboxSchemaStruct builder = CheckboxSchemaStruct.builder(userFormItemEntity.getScheme()); |
| | | // 单选多选带名额 |
| | | if (builder.getConfig().getOptions().stream().anyMatch(item -> ObjectUtil.isNotNull(item.getQuotaSetting()))) { |
| | | return true; |
| | | } |
| | | return builder.getConfig().isShowVoteResult(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.UserFormLogicEntity; |
| | | import com.ltkj.tduck.mapper.UserFormLogicMapper; |
| | | import com.ltkj.tduck.service.UserFormLogicService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * 表单逻辑 |
| | | */ |
| | | @Service |
| | | public class UserFormLogicServiceImpl extends ServiceImpl<UserFormLogicMapper, UserFormLogicEntity> implements UserFormLogicService { |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | import com.ltkj.tduck.mapper.UserFormMapper; |
| | | import com.ltkj.tduck.service.UserFormService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * 表单主表(Form)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-18 18:16:18 |
| | | */ |
| | | @Service |
| | | public class UserFormServiceImpl extends ServiceImpl<UserFormMapper, UserFormEntity> implements UserFormService { |
| | | |
| | | @Override |
| | | public UserFormEntity getByKey(final String key) { |
| | | if (StrUtil.isBlank(key)) { |
| | | return null; |
| | | } |
| | | return this.getOne(Wrappers.<UserFormEntity>lambdaQuery().eq(UserFormEntity::getFormKey, key)); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.common.utils.SecurityUtils; |
| | | import com.ltkj.tduck.constant.CommonConstants; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | import com.ltkj.tduck.domain.UserFormSettingEntity; |
| | | import com.ltkj.tduck.enums.FormStatusEnum; |
| | | import com.ltkj.tduck.mapper.UserFormSettingMapper; |
| | | import com.ltkj.tduck.service.UserFormDataService; |
| | | import com.ltkj.tduck.service.UserFormService; |
| | | import com.ltkj.tduck.service.UserFormSettingService; |
| | | import com.ltkj.tduck.struct.FormSettingSchemaStruct; |
| | | import com.ltkj.tduck.utils.Result; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.LocalTime; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 表单表单项(UserFormSetting)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-30 14:00:53 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class UserFormSettingServiceImpl extends ServiceImpl<UserFormSettingMapper, UserFormSettingEntity> implements UserFormSettingService { |
| | | private final UserFormService userFormService; |
| | | private final UserFormDataService userFormDataService; |
| | | |
| | | @Override |
| | | public Boolean saveFormSetting(Map<String, Object> params) { |
| | | String formKey = params.get("formKey").toString(); |
| | | UserFormSettingEntity entity = this.getOne(Wrappers.<UserFormSettingEntity>lambdaQuery().eq(UserFormSettingEntity::getFormKey, formKey)); |
| | | if (ObjectUtil.isNull(entity)) { |
| | | UserFormSettingEntity setting = new UserFormSettingEntity(); |
| | | setting.setFormKey(formKey); |
| | | setting.setSettings(params); |
| | | return this.save(setting); |
| | | } |
| | | Map<String, Object> settings = entity.getSettings(); |
| | | settings.putAll(params); |
| | | entity.setSettings(settings); |
| | | return this.updateById(entity); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public UserFormSettingEntity getFormSettingByKey(String formKey) { |
| | | return this.getOne(Wrappers.<UserFormSettingEntity>lambdaQuery().eq(UserFormSettingEntity::getFormKey, formKey)); |
| | | } |
| | | |
| | | @Override |
| | | public FormSettingSchemaStruct getFormSettingSchema(String formKey) { |
| | | UserFormSettingEntity settingEntity = getFormSettingByKey(formKey); |
| | | if (ObjectUtil.isNull(settingEntity)) { |
| | | return null; |
| | | } |
| | | return BeanUtil.toBean(settingEntity.getSettings(), FormSettingSchemaStruct.class); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public Result<Boolean> getUserFormWriteSettingStatus(String formKey, String requestIp, String wxOpenId, Integer type) { |
| | | UserFormEntity userFormEntity = userFormService.getByKey(formKey); |
| | | boolean checkPublish = Objects.equals(type, CommonConstants.ConstantNumber.ONE) && |
| | | (ObjectUtil.isNull(userFormEntity) || userFormEntity.getStatus() != 2); |
| | | // 非公开填写 不校验发布状态 |
| | | if (checkPublish) { |
| | | return Result.success(null, "表单暂时无法填写"); |
| | | } |
| | | UserFormSettingEntity settingEntity = getFormSettingByKey(formKey); |
| | | if (ObjectUtil.isNull(settingEntity)) { |
| | | return Result.success(true); |
| | | } |
| | | FormSettingSchemaStruct settingSchemaStruct = BeanUtil.toBean(settingEntity.getSettings(), FormSettingSchemaStruct.class); |
| | | // 填写时间限制 |
| | | boolean writeInterviewTime = isWriteInterviewTime(settingSchemaStruct); |
| | | if (!writeInterviewTime) { |
| | | return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getWriteInterviewTimeText(), "不在答题时间范围内,有问题请与表单发布者联系")); |
| | | } |
| | | // 每个微信答题次数限制 |
| | | if (settingSchemaStruct.isWxWriteCountLimitStatus()) { |
| | | LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey).eq(UserFormDataEntity::getWxOpenId, wxOpenId); |
| | | String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getWxWriteCountLimitDateType()); |
| | | wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql); |
| | | long writeCount = userFormDataService.count(wrapper); |
| | | if (writeCount >= settingSchemaStruct.getWxWriteCountLimit()) { |
| | | return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getWxWriteCountLimitText(), "该微信已经提交过数据,不可重复提交,有问题请与表单发布者联系")); |
| | | } |
| | | } |
| | | // 每个IP答题次数限制 |
| | | if (settingSchemaStruct.isIpWriteCountLimitStatus()) { |
| | | LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey).eq(UserFormDataEntity::getSubmitRequestIp, requestIp); |
| | | String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getIpWriteCountLimitDateType()); |
| | | wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql); |
| | | long writeCount = userFormDataService.count(wrapper); |
| | | if (writeCount >= settingSchemaStruct.getIpWriteCountLimit()) { |
| | | return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getIpWriteCountLimitText(), "该IP已经提交过数据,不可重复提交,有问题请与表单发布者联系")); |
| | | } |
| | | } |
| | | // 总答题次数限制 |
| | | if (settingSchemaStruct.isTotalWriteCountLimitStatus()) { |
| | | LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey); |
| | | String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getTotalWriteCountLimitDateType()); |
| | | wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql); |
| | | long writeCount = userFormDataService.count(wrapper); |
| | | if (writeCount >= settingSchemaStruct.getTotalWriteCountLimit()) { |
| | | return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getTotalWriteCountLimitText(), "该表单收集数据已经达到上限,有问题请与表单发布者联系")); |
| | | } |
| | | } |
| | | // 每个账号答题次数限制 |
| | | if (settingSchemaStruct.isAccountWriteCountLimitStatus()) { |
| | | LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey) |
| | | .eq(UserFormDataEntity::getCreateBy, SecurityUtils.getUserId()); |
| | | String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getAccountWriteCountLimitDateType()); |
| | | wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql); |
| | | long writeCount = userFormDataService.count(wrapper); |
| | | if (writeCount >= settingSchemaStruct.getAccountWriteCountLimit()) { |
| | | return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getAccountWriteCountLimitText(), "该账号已经提交过数据,不可重复提交,有问题请与表单发布者联系")); |
| | | } |
| | | } |
| | | return Result.success(true); |
| | | } |
| | | |
| | | /** |
| | | * 是否在设置的答题时间内 |
| | | * |
| | | * @return true 在答题时间内 |
| | | */ |
| | | private boolean isWriteInterviewTime(FormSettingSchemaStruct settingSchemaStruct) { |
| | | // 答题时间限制 |
| | | if (settingSchemaStruct.isWriteInterviewTimeStatus()) { |
| | | // 是否每天时间范围限制 |
| | | if (settingSchemaStruct.isWriteInterviewDayTimeStatus()) { |
| | | // 是否在允许访问的天内 |
| | | List<String> writeInterviewDateRange = settingSchemaStruct.getWriteInterviewDateRange(); |
| | | if (CollUtil.isEmpty(writeInterviewDateRange) || DateUtil.isIn(DateUtil.date(), DateUtil.parse(writeInterviewDateRange.get(0)), DateUtil.parse(writeInterviewDateRange.get(1)))) { |
| | | // 是否在允许访问的小时内 |
| | | List<String> writeInterviewTimeRange = settingSchemaStruct.getWriteInterviewTimeRange(); |
| | | LocalTime now = LocalTime.now(); |
| | | boolean isRange = CollUtil.isNotEmpty(writeInterviewDateRange) && now.isBefore(LocalTime.parse(writeInterviewTimeRange.get(0))) || now.isAfter(LocalTime.parse(writeInterviewTimeRange.get(1))); |
| | | if (isRange) { |
| | | return false; |
| | | } |
| | | } else { |
| | | return false; |
| | | } |
| | | } else { |
| | | // 是否在允许访问的天内 |
| | | List<String> writeInterviewDateTimeRange = settingSchemaStruct.getWriteInterviewDateTimeRange(); |
| | | if (CollUtil.isNotEmpty(writeInterviewDateTimeRange) && !DateUtil.isIn(DateUtil.date(), DateUtil.parse(writeInterviewDateTimeRange.get(0)), DateUtil.parse(writeInterviewDateTimeRange.get(1)))) { |
| | | return false; |
| | | } |
| | | } |
| | | // 是否是每周允许访问的周几 |
| | | List<String> writeInterviewTimeWhichDays = settingSchemaStruct.getWriteInterviewTimeWhichDays(); |
| | | if (CollUtil.isNotEmpty(writeInterviewTimeWhichDays)) { |
| | | // 获取今天是每周的第几天 |
| | | int day = DateUtil.dayOfWeek(DateUtil.date()); |
| | | return writeInterviewTimeWhichDays.contains(String.valueOf(day)); |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 删除全部的表单数据 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 删除结果 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = {Exception.class}) |
| | | public Boolean deleteAllSetting(String formKey) { |
| | | this.remove(Wrappers.<UserFormSettingEntity>lambdaQuery().eq(UserFormSettingEntity::getFormKey, formKey)); |
| | | return true; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.UserFormThemeEntity; |
| | | import com.ltkj.tduck.mapper.UserFormThemeMapper; |
| | | import com.ltkj.tduck.service.UserFormThemeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * 项目表单项(UserFormTheme)表服务实现类 |
| | | * |
| | | * @author smalljop |
| | | * @since 2020-11-25 13:36:32 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class UserFormThemeServiceImpl extends ServiceImpl<UserFormThemeMapper, UserFormThemeEntity> implements UserFormThemeService { |
| | | |
| | | |
| | | @Override |
| | | public UserFormThemeEntity getByKey(String key) { |
| | | UserFormThemeEntity userFormThemeEntity = this.getOne(Wrappers.<UserFormThemeEntity>lambdaQuery().eq(UserFormThemeEntity::getFormKey, key)); |
| | | return userFormThemeEntity; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ltkj.tduck.domain.UserFormViewCountEntity; |
| | | import com.ltkj.tduck.mapper.UserFormViewCountMapper; |
| | | import com.ltkj.tduck.service.UserFormViewCountService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * 用户表单查看次数Service业务层处理 |
| | | * |
| | | * @author tduck |
| | | * @date 2023-04-04 21:29:39 |
| | | */ |
| | | @Service |
| | | public class UserFormViewCountServiceImpl extends ServiceImpl<UserFormViewCountMapper, UserFormViewCountEntity> implements UserFormViewCountService { |
| | | |
| | | @Override |
| | | public void increment(String formKey) { |
| | | baseMapper.incrementCount(formKey); |
| | | } |
| | | |
| | | @Override |
| | | public Long count(String formKey) { |
| | | UserFormViewCountEntity viewCount = baseMapper.selectOne(Wrappers.<UserFormViewCountEntity>lambdaQuery().eq(UserFormViewCountEntity::getFormKey, formKey)); |
| | | return viewCount == null ? 0 : viewCount.getCount(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.struct; |
| | | |
| | | import com.ltkj.tduck.utils.JsonUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 选项结构 |
| | | * @create : 2021/06/07 16:37 |
| | | **/ |
| | | |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | @Data |
| | | public class CheckboxSchemaStruct { |
| | | |
| | | private Config config; |
| | | |
| | | |
| | | |
| | | @Data |
| | | public static class Config extends OptionQuotaListStruct{ |
| | | private boolean showVoteResult; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | public static CheckboxSchemaStruct builder(Map<String, Object> params) { |
| | | return JsonUtils.objToObj(params, CheckboxSchemaStruct.class); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.struct; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author : wangqing |
| | | * @description : 数据过滤对象结构 |
| | | * @create : 2021/10/13 14:49 |
| | | **/ |
| | | @Data |
| | | public class FormDataFilterStruct { |
| | | /** |
| | | * or and 逻辑连接符号 |
| | | */ |
| | | RelEnum rel; |
| | | |
| | | /** |
| | | * 过滤条件 |
| | | */ |
| | | List<Condition> conditionList; |
| | | |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum QueryMethodEnum { |
| | | /** |
| | | * 等于 |
| | | */ |
| | | EQ, |
| | | /** |
| | | * 不等于 |
| | | */ |
| | | NE, |
| | | /** |
| | | * 包含 |
| | | */ |
| | | INCLUDE, |
| | | /** |
| | | * 不包含 |
| | | */ |
| | | NOT_INCLUDE, |
| | | /** |
| | | * 为空 |
| | | */ |
| | | IS_NULL, |
| | | /** |
| | | * 不为空 |
| | | */ |
| | | NOT_NULL, |
| | | /** |
| | | * ; |
| | | * 大于 |
| | | */ |
| | | GT, |
| | | /** |
| | | * ; |
| | | * 大于等于 |
| | | */ |
| | | GE, |
| | | /** |
| | | * 小于 |
| | | */ |
| | | LT, |
| | | /** |
| | | * 小于等于 |
| | | */ |
| | | LE, |
| | | /** |
| | | * 范围 |
| | | */ |
| | | RANGE, |
| | | /** |
| | | * 时间范围 |
| | | */ |
| | | TIME_RANGE; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 默认值类型枚举 |
| | | */ |
| | | public enum DefaultValueTypeEnum { |
| | | /** |
| | | * 字符串 |
| | | */ |
| | | STRING, |
| | | /*** |
| | | * 数组 |
| | | */ |
| | | ARRAY |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 默认值类型枚举 |
| | | */ |
| | | public enum RelEnum { |
| | | AND, |
| | | OR |
| | | } |
| | | |
| | | @Data |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | // 忽略前端传的未定义参数 |
| | | @JsonIgnoreProperties(ignoreUnknown = true) |
| | | public static class Condition { |
| | | private String formItemId; |
| | | private QueryMethodEnum method; |
| | | private Object value; |
| | | private DefaultValueTypeEnum defaultValueType; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.struct; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : 设置结构定义 |
| | | * @create : 2021/06/07 16:37 |
| | | **/ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class FormSettingSchemaStruct extends WriteSettingSchemaStruct { |
| | | /** |
| | | * 自定义显示类型 1 系统默认 2 自定义页面 使用submitShowCustomPageContent内容 |
| | | */ |
| | | private int submitShowType; |
| | | /** |
| | | * 自定义显示内容 |
| | | */ |
| | | private String submitShowCustomPageContent; |
| | | private boolean submitJump; |
| | | private String submitJumpUrl; |
| | | |
| | | /** |
| | | * 显示分享图片 |
| | | */ |
| | | private boolean shareWxImg; |
| | | /** |
| | | * 分享图片地址 |
| | | */ |
| | | private String shareWxImgUrl; |
| | | /** |
| | | * 显示分享标题 |
| | | */ |
| | | private boolean shareWxTitle; |
| | | /** |
| | | * 分享标题内容 |
| | | */ |
| | | private String shareWxTitleContent; |
| | | /** |
| | | * 开启分享描述 |
| | | */ |
| | | private boolean shareWxDesc; |
| | | /** |
| | | * 分享描述内容 |
| | | */ |
| | | private String shareWxDescContent; |
| | | |
| | | /** |
| | | * 开启邮件通知 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean emailNotify; |
| | | /** |
| | | * 邮件通知账号 |
| | | */ |
| | | @JsonIgnore |
| | | private String newWriteNotifyEmail; |
| | | @JsonIgnore |
| | | private boolean wxNotify; |
| | | @JsonIgnore |
| | | private String newWriteNotifyWx; |
| | | |
| | | |
| | | /** |
| | | * 公开回复 |
| | | */ |
| | | private boolean openReply; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.struct; |
| | | |
| | | import com.ltkj.tduck.utils.JsonUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author : smalljop |
| | | * @description : 上传收集结果 |
| | | * @create : 2021/06/07 16:37 |
| | | **/ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class InputResultStruct { |
| | | |
| | | /** |
| | | * 不允许重复 |
| | | */ |
| | | private boolean notRepeat; |
| | | |
| | | |
| | | public static InputResultStruct builder(Map<String, Object> params) { |
| | | return JsonUtils.objToObj(params, InputResultStruct.class); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.struct; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : |
| | | * @create : 2022/09/26 16:14 |
| | | **/ |
| | | @Data |
| | | public class OptionQuotaListStruct { |
| | | private List<Option> options; |
| | | |
| | | |
| | | /** |
| | | * 剩余名额为0时,显示文案 |
| | | */ |
| | | private String quotaBlankWarning; |
| | | |
| | | |
| | | /** |
| | | * 名额重置 |
| | | */ |
| | | private String quotaCycleRule; |
| | | |
| | | |
| | | public enum QuotaCycleRule { |
| | | /** |
| | | * 不重置 |
| | | */ |
| | | FIXED, |
| | | /** |
| | | * 每天 |
| | | */ |
| | | PER_DAY, |
| | | /** |
| | | * 每周 |
| | | */ |
| | | PER_WEEK; |
| | | } |
| | | |
| | | |
| | | @Data |
| | | public static class Option { |
| | | private String label; |
| | | private String value; |
| | | private Integer quotaSetting; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.struct; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : 设置结构定义 @JsonIgnore 不给前端返回的字段添加这个 |
| | | * @create : 2021/06/07 16:37 |
| | | **/ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class WriteSettingSchemaStruct { |
| | | |
| | | /** |
| | | * 仅在微信填写 |
| | | */ |
| | | private boolean onlyWxWrite; |
| | | /** |
| | | * 记录微信用户信息 |
| | | */ |
| | | private boolean recordWxUser; |
| | | /** |
| | | * 本地保存未提交数据 |
| | | */ |
| | | private boolean saveSubmitStatus; |
| | | /** |
| | | * 本地保存未提交数据 |
| | | */ |
| | | private boolean saveNotSubmitStatus; |
| | | /** |
| | | * 开启密码填写 |
| | | */ |
| | | private boolean passwordWriteStatus; |
| | | /** |
| | | * 填写密码 |
| | | */ |
| | | @JsonIgnore |
| | | private String writePassword; |
| | | /** |
| | | * 开启每个微信答题次数限制 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean wxWriteCountLimitStatus; |
| | | /** |
| | | * 每个微信答题次数限制次数 |
| | | */ |
| | | @JsonIgnore |
| | | private int wxWriteCountLimit = 1; |
| | | /** |
| | | * 开启每个微信答题时间限制类型 具体查看DateRangeTypeEnum |
| | | */ |
| | | @JsonIgnore |
| | | private int wxWriteCountLimitDateType = 1; |
| | | /** |
| | | * 开启每个微信答题时间限制显示文案 |
| | | */ |
| | | @JsonIgnore |
| | | private String wxWriteCountLimitText; |
| | | /** |
| | | * 每个IP答题次数限制 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean ipWriteCountLimitStatus; |
| | | /** |
| | | * 每个IP答题次数限制次数 |
| | | */ |
| | | @JsonIgnore |
| | | private int ipWriteCountLimit = 1; |
| | | /** |
| | | * 开启每个IP答题时间限制类型 具体查看DateRangeTypeEnum |
| | | */ |
| | | @JsonIgnore |
| | | private int ipWriteCountLimitDateType = 1; |
| | | /** |
| | | * 开启每个IP答题时间限制显示文案 |
| | | */ |
| | | @JsonIgnore |
| | | private String ipWriteCountLimitText; |
| | | |
| | | |
| | | /** |
| | | * 每个账号答题限制 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean accountWriteCountLimitStatus; |
| | | /** |
| | | * 每个IP答题次数限制次数 |
| | | */ |
| | | @JsonIgnore |
| | | private int accountWriteCountLimit = 1; |
| | | /** |
| | | * 开启每个账号答题时间限制类型 具体查看DateRangeTypeEnum |
| | | */ |
| | | @JsonIgnore |
| | | private int accountWriteCountLimitDateType = 1; |
| | | /** |
| | | * 开启每个账号答题时间限制显示文案 |
| | | */ |
| | | @JsonIgnore |
| | | private String accountWriteCountLimitText; |
| | | |
| | | |
| | | /** |
| | | * 每个设备答题限制 |
| | | */ |
| | | private boolean deviceWriteCountLimitStatus; |
| | | /** |
| | | * 每个设备答题次数限制次数 |
| | | */ |
| | | private int deviceWriteCountLimit = 1; |
| | | |
| | | /** |
| | | * 每个设备答题文案 |
| | | */ |
| | | private String deviceWriteCountLimitText; |
| | | |
| | | |
| | | /** |
| | | * 累计答题数量 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean totalWriteCountLimitStatus; |
| | | /** |
| | | * 次数 |
| | | */ |
| | | @JsonIgnore |
| | | private int totalWriteCountLimit = 1; |
| | | /** |
| | | * 累计答题日期范围类型 |
| | | */ |
| | | @JsonIgnore |
| | | private int totalWriteCountLimitDateType = 1; |
| | | /** |
| | | * 累计答题日期范围显示文案 |
| | | */ |
| | | @JsonIgnore |
| | | private String totalWriteCountLimitText; |
| | | /** |
| | | * 开启答题时间限制 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean writeInterviewTimeStatus; |
| | | /** |
| | | * 访问时间是否是一天内的某些小时 |
| | | */ |
| | | @JsonIgnore |
| | | private boolean writeInterviewDayTimeStatus; |
| | | /** |
| | | * 允许访问访问时间范围 |
| | | */ |
| | | @JsonIgnore |
| | | private List<String> writeInterviewDateTimeRange; |
| | | /** |
| | | * 允许访问访问日期范围 |
| | | */ |
| | | @JsonIgnore |
| | | private List<String> writeInterviewDateRange; |
| | | /** |
| | | * 允许访问访问时间范围 |
| | | */ |
| | | @JsonIgnore |
| | | private List<String> writeInterviewTimeRange; |
| | | /** |
| | | * 允许访问访问时间范围显示文案 |
| | | */ |
| | | @JsonIgnore |
| | | private List<String> writeInterviewTimeWhichDays; |
| | | /** |
| | | * 不允许访问访问时间范围显示文案 |
| | | */ |
| | | @JsonIgnore |
| | | private String writeInterviewTimeText; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | @AllArgsConstructor |
| | | public static enum DateRangeType { |
| | | /** |
| | | * 总共 |
| | | */ |
| | | SUM(1), |
| | | /** |
| | | * 每天 |
| | | */ |
| | | DAY(2), |
| | | /** |
| | | * 每周 |
| | | */ |
| | | WEEK(3), |
| | | /** |
| | | * 每月 |
| | | */ |
| | | MONTH(4); |
| | | @Getter |
| | | private final int value; |
| | | |
| | | |
| | | /** |
| | | * 获取对应的日期范围类型 |
| | | * |
| | | * @param value 值 |
| | | * @return 日期范围类型sql |
| | | */ |
| | | public static String getDateSql(int value) { |
| | | Date now = new Date(); |
| | | String sql = " create_time>='{}' and create_time<='{}'"; |
| | | for (DateRangeType type : DateRangeType.values()) { |
| | | if (type.getValue() == value) { |
| | | switch (type) { |
| | | case DAY: |
| | | return StrUtil.format(sql, DateUtil.beginOfDay(now), DateUtil.endOfDay(now)); |
| | | case WEEK: |
| | | return StrUtil.format(sql, DateUtil.beginOfWeek(now), DateUtil.endOfWeek(now)); |
| | | case MONTH: |
| | | return StrUtil.format(sql, DateUtil.beginOfMonth(now), DateUtil.endOfMonth(now)); |
| | | default: |
| | | return ""; |
| | | } |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("不支持的日期范围类型"); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.compress.utils.Lists; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cache.Cache; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.cache.ehcache.EhCacheCacheManager; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : 基于ehcache实现 |
| | | * @create : 2022/01/06 10:40 |
| | | **/ |
| | | @Component |
| | | @Slf4j |
| | | @EnableCaching |
| | | public class CacheUtils { |
| | | private final String ETERNAL_CACHE_NAME = "eternal_cache"; |
| | | private final String TEMP_CACHE_NAME = "temp_cache"; |
| | | @Autowired |
| | | private EhCacheCacheManager cacheManager; |
| | | |
| | | /** |
| | | * 保存到Cache |
| | | */ |
| | | public void save(String key, String value) { |
| | | cacheManager.getCache(ETERNAL_CACHE_NAME).put(key, value); |
| | | } |
| | | |
| | | /** |
| | | * 获取 |
| | | * |
| | | * @param key |
| | | */ |
| | | public String get(String key) { |
| | | Cache.ValueWrapper valueWrapper = cacheManager.getCache(ETERNAL_CACHE_NAME).get(key); |
| | | if (ObjectUtil.isNotNull(valueWrapper) && ObjectUtil.isNotNull(valueWrapper.get())) { |
| | | return valueWrapper.get().toString(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 自增 |
| | | * |
| | | * @param key |
| | | * @param number |
| | | * @return |
| | | */ |
| | | public Long incr(String key, Integer number) { |
| | | String v = get(key); |
| | | if (StrUtil.isBlank(v)) { |
| | | v = "0"; |
| | | } |
| | | long finalValue = Convert.toLong(v) + number; |
| | | save(key, String.valueOf(finalValue)); |
| | | return finalValue; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 添加到集合缓存 |
| | | * |
| | | * @param key |
| | | * @param value |
| | | */ |
| | | public void addList(String key, Object value) { |
| | | List coll = this.getList(key, Object.class); |
| | | coll.add(value); |
| | | cacheManager.getCache(TEMP_CACHE_NAME).put(key, JsonUtils.objToJson(coll)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 从集合中移除 |
| | | * |
| | | * @param key |
| | | * @param value |
| | | */ |
| | | public void removeList(String key, Object value) { |
| | | List coll = this.getList(key, Object.class); |
| | | coll.remove(value); |
| | | cacheManager.getCache(TEMP_CACHE_NAME).put(key, JsonUtils.objToJson(coll)); |
| | | } |
| | | |
| | | /** |
| | | * 获取集合 |
| | | * |
| | | * @param key |
| | | */ |
| | | public List getList(String key, Class classz) { |
| | | String v = get(key); |
| | | if (ObjectUtil.isNotNull(v)) { |
| | | return JsonUtils.jsonToList(v, classz.getClass()); |
| | | } |
| | | return Lists.newArrayList(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 临时保存 默认5min |
| | | */ |
| | | public void tempSave(String key, String value) { |
| | | cacheManager.getCache(TEMP_CACHE_NAME).put(key, value); |
| | | } |
| | | |
| | | /** |
| | | * 获取临时存储变量 |
| | | * |
| | | * @param key |
| | | */ |
| | | public String getTemp(String key) { |
| | | Cache.ValueWrapper valueWrapper = cacheManager.getCache(TEMP_CACHE_NAME).get(key); |
| | | if (ObjectUtil.isNotNull(valueWrapper) && ObjectUtil.isNotNull(valueWrapper.get())) { |
| | | return valueWrapper.get().toString(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public void removeTemp(String key) { |
| | | cacheManager.getCache(TEMP_CACHE_NAME).evict(key); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.ltkj.tduck.domain.SysBaseEntity; |
| | | import com.ltkj.tduck.domain.TBaseEntity; |
| | | import com.ltkj.tduck.domain.UserFormDataEntity; |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | import com.ltkj.tduck.enums.FormItemTypeEnum; |
| | | import com.ltkj.tduck.request.QueryFormResultRequest; |
| | | import com.ltkj.tduck.service.data.FormDataBaseService; |
| | | import com.ltkj.tduck.vo.FormDataTableVO; |
| | | import com.ltkj.tduck.vo.FormFieldVO; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author : tduck |
| | | * @description : 表单收集结果工具类 |
| | | * @create : 2021/08/18 18:17 |
| | | **/ |
| | | @Slf4j |
| | | @Component |
| | | @RequiredArgsConstructor |
| | | public class FormDataUtils { |
| | | |
| | | |
| | | /** |
| | | * 特殊字段 会多出一个xxx label字段存放显示值 默认字段存放原始值 |
| | | */ |
| | | public static final List<FormItemTypeEnum> specialFields = CollUtil.newArrayList(FormItemTypeEnum.SELECT, FormItemTypeEnum.IMAGE_SELECT, FormItemTypeEnum.CHECKBOX, FormItemTypeEnum.RADIO, FormItemTypeEnum.CASCADER); |
| | | |
| | | private final static String FIELD_USER_TYPE = "USER"; |
| | | |
| | | private final FormDataBaseService formDataBaseService; |
| | | |
| | | /** |
| | | * 添加表单基础数据字段 |
| | | * 所有表单都包含的字段 |
| | | */ |
| | | public static void addFormBaseDataField(List<FormFieldVO> fields) { |
| | | fields.add(new FormFieldVO(UserFormDataEntity.Fields.serialNumber, "提交序号", UserFormDataEntity.Fields.serialNumber)); |
| | | fields.add(new FormFieldVO(UserFormDataEntity.Fields.extValue, "扩展字段", FormItemTypeEnum.INPUT.toString())); |
| | | fields.add(new FormFieldVO(SysBaseEntity.Fields.updateBy, "修改用户", FIELD_USER_TYPE)); |
| | | fields.add(new FormFieldVO(SysBaseEntity.Fields.createBy, "提交用户", FIELD_USER_TYPE)); |
| | | fields.add(new FormFieldVO(TBaseEntity.Fields.createTime, "提交时间", FormItemTypeEnum.DATE.toString())); |
| | | fields.add(new FormFieldVO(TBaseEntity.Fields.updateTime, "修改时间", FormItemTypeEnum.DATE.toString())); |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 添加系统默认字段 |
| | | */ |
| | | public static void addFormDefaultDataField(UserFormEntity entity, List<FormFieldVO> fields) { |
| | | addFormBaseDataField(fields); |
| | | } |
| | | |
| | | |
| | | /*** |
| | | * 表单字段值是否存在 |
| | | * @param formKey 表单key |
| | | * @param formItemId 表单字段id |
| | | * @param value 字段值 |
| | | */ |
| | | // public Boolean valueExist(String formKey, String formItemId, Object value) { |
| | | // return formDataBaseService.valueExist(formKey, formItemId, value); |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * 特殊字段添加复合字段 |
| | | */ |
| | | // public List<String> concatSpecialField(List<String> fields) { |
| | | // List<String> newFields = CollUtil.newArrayList("id"); |
| | | // if (CollUtil.isEmpty(fields)) { |
| | | // return newFields; |
| | | // } |
| | | // fields.forEach(field -> { |
| | | // newFields.add(field); |
| | | // boolean isSpecialField = StrUtil.startWithAny(field, specialFields.stream().map(item -> item.toString().toLowerCase()).collect(Collectors.joining(","))); |
| | | // if (isSpecialField) { |
| | | // newFields.add(field + "label"); |
| | | // } |
| | | // }); |
| | | // return newFields; |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * 保存数据到其他数据库 比如es MonggDB等 用来扩展查询 作报表等 |
| | | */ |
| | | // public Boolean syncSaveFormData(UserFormDataEntity result) { |
| | | // return formDataBaseService.syncSaveData(result); |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * 更新文档 |
| | | * |
| | | * @param result |
| | | */ |
| | | // public void asyncUpdateEsDocument(UserFormDataEntity result) { |
| | | // formDataBaseService.asyncUpdateData(result); |
| | | // } |
| | | |
| | | /** |
| | | * 删除索引文档 |
| | | * |
| | | * @param idList doc Id |
| | | * @param formKey index |
| | | */ |
| | | // public void asyncDeleteEsDocument(List<String> idList, String formKey) { |
| | | // formDataBaseService.asyncDeleteData(idList, formKey); |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * 查询表单分页数据 |
| | | * |
| | | * @param request 查询参数 |
| | | * @return 表单分页数据 |
| | | */ |
| | | public FormDataTableVO search(QueryFormResultRequest request) { |
| | | return formDataBaseService.search(request); |
| | | } |
| | | |
| | | /** |
| | | * 全部数据 |
| | | * |
| | | * @param request 请求 |
| | | * @return 表单数据 |
| | | */ |
| | | // public List<Map> searchAll(QueryFormResultRequest request) { |
| | | // return formDataBaseService.searchAll(request); |
| | | // } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import cn.hutool.http.HtmlUtil; |
| | | import lombok.experimental.UtilityClass; |
| | | |
| | | @UtilityClass |
| | | public class HtmlUtils extends HtmlUtil { |
| | | |
| | | |
| | | /** |
| | | * 清除标签 还原转义文本 |
| | | * @param content |
| | | * @return |
| | | */ |
| | | public static String cleanHtmlTag(String content) { |
| | | // 清除HTML标签和空格 html编码解码 |
| | | return HtmlUtil.unescape(content).replaceAll("(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)", "").replaceAll(NBSP, ""); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IEnum; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * @author : wangqing |
| | | * @description : 字典枚举基础接口 |
| | | * 继承该接口会在jackson默认增强显示字段 |
| | | * @create : 2021/12/21 10:19 |
| | | **/ |
| | | public interface IDictEnum<T extends Serializable> extends IEnum<T> { |
| | | |
| | | static <T extends IDictEnum> T getInstance(Class<T> clazz, String code) { |
| | | T[] constants = clazz.getEnumConstants(); |
| | | |
| | | for (T t : constants) { |
| | | if (String.valueOf(t.getValue()).equals(code)) { |
| | | return t; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 数据库中存储的值 |
| | | * |
| | | * @return 数据库中存储的值 |
| | | */ |
| | | @Override |
| | | T getValue(); |
| | | |
| | | |
| | | /** |
| | | * 获取枚举描述 |
| | | * |
| | | * @return 描述 |
| | | */ |
| | | String getDesc(); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import com.fasterxml.jackson.core.JsonParser; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.fasterxml.jackson.databind.*; |
| | | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author smalljop |
| | | * @description: json工具类 使用jackson |
| | | * @create: 2018-10-23 10:21 |
| | | **/ |
| | | public class JsonUtils { |
| | | |
| | | private final static ObjectMapper objectMapper = new ObjectMapper(); |
| | | |
| | | static { |
| | | objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); |
| | | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
| | | objectMapper.registerModule(new JavaTimeModule()); |
| | | } |
| | | |
| | | private JsonUtils() { |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取objectMapper实例 |
| | | */ |
| | | public static ObjectMapper getInstance() { |
| | | return objectMapper; |
| | | } |
| | | |
| | | /** |
| | | * javaBean、列表数组转换为json字符串 |
| | | */ |
| | | public static String objToJson(Object obj) { |
| | | try { |
| | | return objectMapper.writeValueAsString(obj); |
| | | } catch (JsonProcessingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * javaBean、列表数组转换为json字符串,忽略空值 |
| | | */ |
| | | public static String objToJsonIgnoreNull(Object obj) throws Exception { |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| | | return mapper.writeValueAsString(obj); |
| | | } |
| | | |
| | | /** |
| | | * json 转对象 |
| | | */ |
| | | public static <T> T jsonToObj(String jsonString, Class<T> clazz) { |
| | | if (StrUtil.isBlank(jsonString)) { |
| | | return null; |
| | | } |
| | | //允许出现单引号 |
| | | objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); |
| | | //接受只有一个元素的数组的反序列化 |
| | | objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); |
| | | try { |
| | | return objectMapper.readValue(jsonString, clazz); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * json字符串转换为map |
| | | */ |
| | | public static <T> Map<String, Object> jsonToMap(String jsonString) { |
| | | if (StrUtil.isBlank(jsonString)) { |
| | | return null; |
| | | } |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| | | try { |
| | | return mapper.readValue(jsonString, Map.class); |
| | | } catch (JsonProcessingException e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | public static <T> JsonNode jsonToJsonNode(String jsonString) { |
| | | if (StrUtil.isBlank(jsonString)) { |
| | | return null; |
| | | } |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| | | try { |
| | | return mapper.readValue(jsonString, JsonNode.class); |
| | | } catch (JsonProcessingException e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * json字符串转换为map |
| | | */ |
| | | public static <T> Map<String, T> jsonToMap(String jsonString, Class<T> clazz) throws Exception { |
| | | Map<String, Map<String, Object>> map = (Map<String, Map<String, Object>>) objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() { |
| | | }); |
| | | Map<String, T> result = new HashMap<String, T>(); |
| | | for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) { |
| | | result.put(entry.getKey(), mapToObj(entry.getValue(), clazz)); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 深度转换json成map |
| | | * |
| | | * @param json |
| | | * @return |
| | | */ |
| | | public static Map<String, Object> jsonToMapDeeply(String json) throws Exception { |
| | | return jsonToMapRecursion(json, objectMapper); |
| | | } |
| | | |
| | | /** |
| | | * 把json解析成list,如果list内部的元素存在jsonString,继续解析 |
| | | * |
| | | * @param json |
| | | * @param mapper 解析工具 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | private static List<Object> jsonToListRecursion(String json, ObjectMapper mapper) throws Exception { |
| | | if (json == null) { |
| | | return null; |
| | | } |
| | | |
| | | List<Object> list = mapper.readValue(json, List.class); |
| | | |
| | | for (Object obj : list) { |
| | | if (obj != null && obj instanceof String) { |
| | | String str = (String) obj; |
| | | if (str.startsWith("[")) { |
| | | obj = jsonToListRecursion(str, mapper); |
| | | } else if (obj.toString().startsWith("{")) { |
| | | obj = jsonToMapRecursion(str, mapper); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * 把json解析成map,如果map内部的value存在jsonString,继续解析 |
| | | * |
| | | * @param json |
| | | * @param mapper |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | private static Map<String, Object> jsonToMapRecursion(String json, ObjectMapper mapper) throws Exception { |
| | | if (json == null) { |
| | | return null; |
| | | } |
| | | |
| | | Map<String, Object> map = mapper.readValue(json, Map.class); |
| | | |
| | | for (Map.Entry<String, Object> entry : map.entrySet()) { |
| | | Object obj = entry.getValue(); |
| | | if (obj != null && obj instanceof String) { |
| | | String str = ((String) obj); |
| | | |
| | | if (str.startsWith("[")) { |
| | | List<?> list = jsonToListRecursion(str, mapper); |
| | | map.put(entry.getKey(), list); |
| | | } else if (str.startsWith("{")) { |
| | | Map<String, Object> mapRecursion = jsonToMapRecursion(str, mapper); |
| | | map.put(entry.getKey(), mapRecursion); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * 与javaBean json数组字符串转换为列表 |
| | | */ |
| | | public static <T> List<T> jsonToList(String jsonArrayStr, Class<T> clazz) { |
| | | |
| | | JavaType javaType = getCollectionType(ArrayList.class, clazz); |
| | | List<T> lst = null; |
| | | try { |
| | | lst = objectMapper.readValue(jsonArrayStr, javaType); |
| | | } catch (JsonProcessingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return lst; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取泛型的Collection Type |
| | | * |
| | | * @param collectionClass 泛型的Collection |
| | | * @param elementClasses 元素类 |
| | | * @return JavaType Java类型 |
| | | * @since 1.0 |
| | | */ |
| | | public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) { |
| | | return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * map 转JavaBean |
| | | */ |
| | | public static <T> T mapToObj(Map map, Class<T> clazz) { |
| | | return objectMapper.convertValue(map, clazz); |
| | | } |
| | | |
| | | /** |
| | | * map 转json |
| | | * |
| | | * @param map |
| | | * @return |
| | | */ |
| | | public static String mapToJson(Map map) { |
| | | try { |
| | | return objectMapper.writeValueAsString(map); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | /** |
| | | * map 转JavaBean |
| | | */ |
| | | public static <T> T objToObj(Object obj, Class<T> clazz) { |
| | | return objectMapper.convertValue(obj, clazz); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 是否是json格式 |
| | | */ |
| | | public static boolean isJson(String json) { |
| | | try { |
| | | if(StrUtil.isBlank(json)){ |
| | | return false; |
| | | } |
| | | objectMapper.readTree(json); |
| | | return true; |
| | | } catch (IOException e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.JsonSerializer; |
| | | import com.fasterxml.jackson.databind.SerializerProvider; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * @author : wangqing |
| | | * @description : Long转string 避免返回前端丢失精度 |
| | | * @create : 2022/03/10 15:07 |
| | | **/ |
| | | |
| | | public class LongToStringSerializer extends JsonSerializer<Long> { |
| | | |
| | | |
| | | /** |
| | | * Method that can be called to ask implementation to serialize |
| | | * values of type this serializer handles. |
| | | * |
| | | * @param value Value to serialize; can <b>not</b> be null. |
| | | * @param gen Generator used to output resulting Json content |
| | | * @param serializers Provider that can be used to get serializers for |
| | | */ |
| | | @Override |
| | | public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { |
| | | if (value != null && value.toString().length() > 16) { |
| | | gen.writeString(value.toString()); |
| | | } else { |
| | | gen.writeNumber(value); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.ltkj.tduck.constant.ResponseCodeConstants; |
| | | import lombok.*; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 响应信息主体 |
| | | * |
| | | * @param <T> |
| | | * @author smalljop |
| | | */ |
| | | @ToString |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | @Accessors(chain = true) |
| | | //@Schema(description = "响应信息主体") |
| | | public class Result<T> implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Getter |
| | | @Setter |
| | | // @Schema(description = "返回标记:成功标记=200,失败标记=500") |
| | | private int code = ResponseCodeConstants.SUCCESS; |
| | | |
| | | @Getter |
| | | @Setter |
| | | // @Schema(description = "返回信息") |
| | | private String msg; |
| | | |
| | | |
| | | @Getter |
| | | @Setter |
| | | // @Schema(description = "数据") |
| | | private T data; |
| | | |
| | | public static <T> Result<T> success() { |
| | | return restResult(null, ResponseCodeConstants.SUCCESS, null); |
| | | } |
| | | |
| | | public static <T> Result<T> success(T data) { |
| | | return restResult(data, ResponseCodeConstants.SUCCESS, null); |
| | | } |
| | | |
| | | public static <T> Result<T> success(T data, String msg) { |
| | | return restResult(data, ResponseCodeConstants.SUCCESS, msg); |
| | | } |
| | | |
| | | public static <T> Result<T> isSuccess(boolean flag) { |
| | | return flag ? success() : failed(); |
| | | } |
| | | |
| | | public static <T> Result<T> failed() { |
| | | return restResult(null, ResponseCodeConstants.FAIL, null); |
| | | } |
| | | |
| | | |
| | | public static <T> Result<T> failed(int code, String msg) { |
| | | return restResult(null, code, msg); |
| | | } |
| | | |
| | | public static <T> Result<T> failed(String msg) { |
| | | return restResult(null, ResponseCodeConstants.FAIL, msg); |
| | | } |
| | | |
| | | public static <T> Result<T> failed(String msg, T data) { |
| | | return restResult(data, ResponseCodeConstants.FAIL, msg); |
| | | } |
| | | |
| | | |
| | | public static <T> Result<T> restResult(T data, int code, String msg) { |
| | | Result<T> apiResult = new Result<>(); |
| | | apiResult.setCode(code); |
| | | apiResult.setData(data); |
| | | apiResult.setMsg(msg); |
| | | return apiResult; |
| | | } |
| | | |
| | | |
| | | @JsonIgnore |
| | | public Boolean isDataNull() { |
| | | return ObjectUtil.isNull(data); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import lombok.experimental.UtilityClass; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 短Id工具类 |
| | | */ |
| | | @UtilityClass |
| | | public class ShortIdUtils { |
| | | |
| | | /** |
| | | * 默认随机字母表,使用URL安全的Base64字符 |
| | | */ |
| | | private static final char[] DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); |
| | | |
| | | |
| | | /** |
| | | * 生成8位长度Id |
| | | * |
| | | * @return |
| | | */ |
| | | public String genId() { |
| | | // return NanoId.randomNanoId(null, DEFAULT_ALPHABET, 8); |
| | | return RandomUtil.randomString(8); |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | Map<Object, Object> of = new HashMap<>(); |
| | | for (int i = 0; i < 100000 ;i++) { |
| | | String s = genId(); |
| | | Object put = of.put(s, "1"); |
| | | if (null != put) { |
| | | System.out.println(s); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.ltkj.tduck.constant.FormRedisKeyConstants; |
| | | import com.ltkj.tduck.domain.UserFormItemEntity; |
| | | import com.ltkj.tduck.service.UserFormItemService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 两个前提:位置的信息记录在任务的模型上(pos字段);一般两个任务的pos值相差很大(默认是65536);现在假设有任务 A, B, C. |
| | | * 列举几个常见的场景:如果C要移到A的前面, 那么后端会把 C.pos 改为 A.pos/2;若果C要移到A和B之间, |
| | | * 那么后端会把 C.pos 改为 (A.pos + B.pos)/2;如果B要移到C的后面, 那么后端会把 B.pos 改为 C.pos + 65536; |
| | | * 当然这里会有个极端情况需要处理(假设pos是整数):如果 A.pos 是 1, B.pos 是 2, C想移到A和B之间, 其实是没有一个整数可以用的, |
| | | * 针对这种情况, 后端会重新给整个列表的任务重新刷一遍pos值. |
| | | * <p> |
| | | * 拖动排序工具类 |
| | | * 算法参考 @link https://www.zhihu.com/question/55789722 |
| | | * |
| | | * @author smalljop |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Component |
| | | public class SortUtils { |
| | | |
| | | private final CacheUtils cacheUtils; |
| | | |
| | | /** |
| | | * 排序默认自增因子 |
| | | */ |
| | | private final Long SORT_DEFAULT_INCR_FACT = 65536L; |
| | | |
| | | private final UserFormItemService formItemService; |
| | | |
| | | |
| | | /** |
| | | * 获取排序数值 |
| | | * |
| | | * @param formKey 表单key |
| | | * @return 初始排序数值 |
| | | */ |
| | | public Long getInitialSortPosition(String formKey) { |
| | | String redisKey = StrUtil.format(FormRedisKeyConstants.FORM_ITEM_POS_DELTA, formKey); |
| | | // 模板创建时 初始排序数值 |
| | | if (StrUtil.isBlank(cacheUtils.get(redisKey))) { |
| | | Long sort = formItemService.getLastItemSort(formKey); |
| | | cacheUtils.save(redisKey, String.valueOf(sort == null ? 1 : sort)); |
| | | } |
| | | return cacheUtils.incr(redisKey, SORT_DEFAULT_INCR_FACT.intValue()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * * 两个前提:位置的信息记录在任务的模型上(pos字段);一般两个任务的pos值相差很大(默认是65536);现在假设有任务 A, B, C. |
| | | * * 列举几个常见的场景:如果C要移到A的前面, 那么后端会把 C.pos 改为 A.pos/2;若果C要移到A和B之间, |
| | | * * 那么后端会把 C.pos 改为 (A.pos + B.pos)/2;如果B要移到C的后面, 那么后端会把 B.pos 改为 C.pos + 65536; |
| | | * * 当然这里会有个极端情况需要处理(假设pos是整数):如果 A.pos 是 1, B.pos 是 2, C想移到A和B之间, 其实是没有一个整数可以用的, |
| | | * * 针对这种情况, 后端会重新给整个列表的任务重新刷一遍pos值. |
| | | * 排序之后重新计算 |
| | | * |
| | | * @param beforePosition 之前的位置 |
| | | * @param afterPosition 之后的位置 |
| | | * @param formKey 表单key |
| | | * @return 最终位置 |
| | | */ |
| | | public Long calcSortPosition(Long beforePosition, Long afterPosition, String formKey) { |
| | | String redisKey = StrUtil.format(FormRedisKeyConstants.FORM_ITEM_POS_DELTA, formKey); |
| | | boolean isCenter = (ObjectUtil.isNotNull(beforePosition) && 0L != beforePosition) && (ObjectUtil.isNotNull(afterPosition) && 0L != afterPosition); |
| | | if (isCenter) { // 放到中间 |
| | | return (beforePosition + afterPosition) / 2; |
| | | } |
| | | if (ObjectUtil.isNull(beforePosition) || 0L == beforePosition) { // 放到最前面 |
| | | return afterPosition / 2; |
| | | } else { // 放到最后面 |
| | | return cacheUtils.incr(redisKey, SORT_DEFAULT_INCR_FACT.intValue()); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 极端情况刷新整个列表 |
| | | * |
| | | * @param beforePosition 之前的位置 |
| | | * @param afterPosition 之后的位置 |
| | | * @param formKey 表单key |
| | | * @param sort 排序数值 |
| | | */ |
| | | public Boolean sortAllList(Long beforePosition, Long afterPosition, String formKey, Long sort) { |
| | | // 即将没有整数,刷新全部列表排序值 |
| | | if ((ObjectUtil.isNotNull(beforePosition) && 0L != beforePosition && ObjectUtil.equal(sort, beforePosition + 1)) |
| | | || (ObjectUtil.isNotNull(afterPosition) && 0L != afterPosition && ObjectUtil.equal(sort, 1L))) { |
| | | List<UserFormItemEntity> itemEntityList = formItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey)); |
| | | itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort)); |
| | | for (int i = 0; i < itemEntityList.size(); i++) { |
| | | itemEntityList.get(i).setSort(SORT_DEFAULT_INCR_FACT * (i + 1)); |
| | | } |
| | | formItemService.updateBatchById(itemEntityList); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.utils; |
| | | |
| | | |
| | | |
| | | |
| | | import com.ltkj.common.exception.base.BaseException; |
| | | |
| | | import javax.validation.ConstraintViolation; |
| | | import javax.validation.Validation; |
| | | import javax.validation.Validator; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * @description: hibernate 校验工具类 |
| | | * 不通过注解使用 通过工具类返回自定义结果 |
| | | * @author: smalljop |
| | | * @create: 2018-10-12 10:20 |
| | | **/ |
| | | public class ValidatorUtils { |
| | | |
| | | private static Validator validator; |
| | | |
| | | static { |
| | | validator = Validation.buildDefaultValidatorFactory().getValidator(); |
| | | } |
| | | |
| | | /** |
| | | * 校验对象 |
| | | * |
| | | * @param object 待校验对象 |
| | | * @param groups 待校验的组 |
| | | * @throws BaseException 校验不通过,BaseException |
| | | */ |
| | | public static void validateEntity(Object object, Class<?>... groups) |
| | | throws BaseException { |
| | | Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups); |
| | | if (!constraintViolations.isEmpty()) { |
| | | StringBuilder msg = new StringBuilder(); |
| | | for (ConstraintViolation<Object> constraint : constraintViolations) { |
| | | msg.append(constraint.getMessage()); |
| | | } |
| | | throw new BaseException(msg.toString()); |
| | | } |
| | | } |
| | | |
| | | public static void validateEntity(Object object) |
| | | throws BaseException { |
| | | Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object); |
| | | if (!constraintViolations.isEmpty()) { |
| | | StringBuilder msg = new StringBuilder(); |
| | | for (ConstraintViolation<Object> constraint : constraintViolations) { |
| | | msg.append(constraint.getMessage()).append("<br>"); |
| | | } |
| | | throw new BaseException(msg.toString()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.vo; |
| | | |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 表单数据表格 |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | public class FormDataTableVO { |
| | | /** |
| | | * 数据列表 |
| | | */ |
| | | private List<Map> rows; |
| | | |
| | | private Long total; |
| | | |
| | | public FormDataTableVO(List<Map> rows, Long total) { |
| | | this.rows = rows; |
| | | this.total = total; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.vo; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.ltkj.tduck.domain.UserFormItemEntity; |
| | | import com.ltkj.tduck.utils.FormDataUtils; |
| | | import com.ltkj.tduck.utils.HtmlUtils; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import static com.ltkj.tduck.constant.FormConstants.FIELD_SUFFIX_LABEL; |
| | | |
| | | |
| | | /** |
| | | * 表单字段类 |
| | | */ |
| | | @Data |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class FormFieldVO { |
| | | |
| | | /** |
| | | * 字段Id |
| | | */ |
| | | protected String value; |
| | | /** |
| | | * 字段名称 |
| | | */ |
| | | protected String label; |
| | | /** |
| | | * 字段类型 |
| | | */ |
| | | protected String type; |
| | | |
| | | /** |
| | | * 配置 |
| | | */ |
| | | protected Object scheme; |
| | | |
| | | public FormFieldVO(String value, String label) { |
| | | this.value = value; |
| | | // 清除html里面的标签 |
| | | this.label = HtmlUtils.cleanHtmlTag(label); |
| | | } |
| | | |
| | | public FormFieldVO(String value, String label, String type) { |
| | | this.value = value; |
| | | this.label = HtmlUtils.cleanHtmlTag(label); |
| | | this.type = type; |
| | | } |
| | | |
| | | public FormFieldVO(UserFormItemEntity entity) { |
| | | this.label = HtmlUtils.cleanHtmlTag(entity.getLabel()); |
| | | this.type = entity.getType().toString(); |
| | | this.value = entity.getFormItemId(); |
| | | // 选择型组件特殊处理 |
| | | if (CollUtil.contains(FormDataUtils.specialFields, entity.getType())) { |
| | | this.value = entity.getFormItemId() + FIELD_SUFFIX_LABEL; |
| | | } |
| | | //获取配置项 |
| | | this.scheme = entity.getScheme(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.vo; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | |
| | | /** |
| | | * 操作返回数据 |
| | | */ |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class OperateFormItemVO { |
| | | |
| | | /** |
| | | * 排序号 |
| | | */ |
| | | private Long sort; |
| | | |
| | | /** |
| | | * 数据Id |
| | | */ |
| | | private Long itemDataId; |
| | | |
| | | /** |
| | | * 操作是否成功 |
| | | */ |
| | | private Boolean operateSuccess; |
| | | |
| | | |
| | | /** |
| | | * 刷新全部 |
| | | */ |
| | | private Boolean refreshAll; |
| | | |
| | | } |
New file |
| | |
| | | package com.ltkj.tduck.vo; |
| | | |
| | | import com.ltkj.tduck.domain.UserFormEntity; |
| | | import com.ltkj.tduck.domain.UserFormItemEntity; |
| | | import com.ltkj.tduck.domain.UserFormLogicEntity; |
| | | import com.ltkj.tduck.domain.UserFormThemeEntity; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author smalljop |
| | | */ |
| | | @Data |
| | | @AllArgsConstructor |
| | | public class UserFormDetailVO { |
| | | /** |
| | | * 表单基础信息 |
| | | */ |
| | | private UserForm form; |
| | | |
| | | /** |
| | | * 表单项 |
| | | */ |
| | | private List<UserFormItemEntity> formItems; |
| | | |
| | | /** |
| | | * 主题 |
| | | */ |
| | | private UserFormThemeEntity userFormTheme; |
| | | |
| | | /** |
| | | * 逻辑 |
| | | */ |
| | | private UserFormLogicEntity formLogic; |
| | | |
| | | |
| | | @Data |
| | | public static class UserForm { |
| | | private String formKey; |
| | | /** |
| | | * 表单名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 表单描述 |
| | | */ |
| | | private String description; |
| | | |
| | | |
| | | private String type; |
| | | |
| | | public UserForm(UserFormEntity entity) { |
| | | this.formKey = entity.getFormKey(); |
| | | this.name = entity.getName(); |
| | | this.description = entity.getDescription(); |
| | | this.type = entity.getType(); |
| | | } |
| | | |
| | | } |
| | | } |