diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/controller/QsvActivityController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/controller/QsvActivityController.java index 1963338..10f9234 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/controller/QsvActivityController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/controller/QsvActivityController.java @@ -59,17 +59,11 @@ public class QsvActivityController { //保存问卷基础信息 @At @SaCheckPermission("qsv.activity") + @Aop(TransAop.READ_COMMITTED) @ApiOperation("保存问卷基础信息") @SLog(type = "qsv.activity", tag = "保存问卷基础信息", msg = "保存问卷基础信息") public Result save(QsvActivity qsvActivity) { - if (qsvActivity.getCategory().equals("QUIZ")) { - if (qsvActivity.getMode().equals("SCHEDULED")) { - qsvActivity.setRepeatMode("DAILY"); - } else if (qsvActivity.getMode().equals("REGULAR")) { - qsvActivity.setRepeatMode("TOTAL"); - } - } - dao.insertOrUpdate(qsvActivity); + qsvActivityService.saveActivity(qsvActivity); return Result.success(); } @@ -83,13 +77,25 @@ public class QsvActivityController { // 删除问卷 @At @SaCheckPermission("qsv.activity") + @Aop(TransAop.READ_COMMITTED) @ApiOperation("删除问卷") @SLog(type = "qsv.activity", tag = "删除问卷", msg = "删除问卷") public Result delete(@Valid String id) { - dao.delete(QsvActivity.class, id); + qsvActivityService.deleteActivity(id); return Result.success(); } + // 更新活动开启状态 + @At + @SaCheckPermission("qsv.activity") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("更新活动开启状态") + @SLog(type = "qsv.activity", tag = "更新活动开启状态", msg = "更新活动开启状态") + public Result updateEnabled(@Valid String id, Boolean enabled) { + qsvActivityService.updateEnabled(id, enabled); + return Result.success(enabled ? "开启成功" : "关闭成功"); + } + // 保存问卷题目 @At diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvController.java index 028b75e..09932d2 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvController.java @@ -36,6 +36,7 @@ public class H5QsvController { public Result pageData(@Valid PageForm pageForm, @Valid String category) { Cnd cnd = Cnd.NEW(); cnd.andEX("category", "=", category); + cnd.and(Cnd.exps("enabled", "=", true).or("enabled", "is", null)); cnd.desc("startTime"); Pagination pagination = qsvActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd); return Result.success(pagination); diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvSurveyController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvSurveyController.java index 8a922c0..12cdba8 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvSurveyController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/h5controller/H5QsvSurveyController.java @@ -46,6 +46,10 @@ public class H5QsvSurveyController { @Aop(TransAop.READ_COMMITTED) public Result subjects(String activityId) { QsvActivity activity = dao.fetch(QsvActivity.class, activityId); + Result activityStatusResult = checkActivityStatus(activity); + if (activityStatusResult != null) { + return activityStatusResult; + } int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getGroupId()) .and("userId", "=", SecurityUtil.getUserId())); @@ -82,6 +86,30 @@ public class H5QsvSurveyController { return Result.success(result); } + /** + * 校验调查活动是否处于可答题状态。activity 为空表示活动不存在; + * enabled 为 false 表示活动已关闭,当前时间早于 startTime 表示未开始,当前时间晚于 endTime 表示已结束。 + * + * @param activity 当前调查活动,包含开启状态、开始时间和结束时间 + * @return 状态或时间不允许答题时返回错误结果,允许答题时返回 null + */ + private Result checkActivityStatus(QsvActivity activity) { + if (activity == null) { + return Result.error("调查不存在"); + } + if (Boolean.FALSE.equals(activity.getEnabled())) { + return Result.error("活动已关闭,暂不能参与"); + } + Date now = new Date(); + if (activity.getStartTime() != null && activity.getStartTime().after(now)) { + return Result.error("调查尚未开始,请在开始后再参与"); + } + if (activity.getEndTime() != null && activity.getEndTime().before(now)) { + return Result.error("调查已结束"); + } + return null; + } + /** * 同步问卷当前题目到未完成答题记录。后台新增题目后,已进入过问卷的用户记录里没有新题ID, * 这里补齐 subjectIds 和 extJson,保证手机端能拿到最新题目并正常提交答案。 @@ -133,6 +161,12 @@ public class H5QsvSurveyController { @At @Aop(TransAop.READ_COMMITTED) public Result submitAnswer(@Valid @Param("answer") QsvAnswerParam qsvAnswerParam) { + QsvActivity activity = dao.fetch(QsvActivity.class, qsvAnswerParam.getActivityId()); + Result activityStatusResult = checkActivityStatus(activity); + if (activityStatusResult != null) { + return activityStatusResult; + } + QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, qsvAnswerParam.getAnswerRecordId()); JSONObject extJson = answerRecord.getExtJson(); diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/models/QsvActivity.java b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/models/QsvActivity.java index 3554147..ea94a8d 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/models/QsvActivity.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/models/QsvActivity.java @@ -1,6 +1,8 @@ package com.budwk.app.zhgh.dayofficework.qsv.models; import com.budwk.app.base.model.BaseModel; +import com.budwk.app.sys.models.Sys_home_activity; +import com.budwk.app.sys.services.SysHomeConvert; import lombok.Data; import lombok.EqualsAndHashCode; import org.nutz.dao.entity.annotation.*; @@ -14,7 +16,7 @@ import java.util.Date; @Table("qsv_activity") @TableMeta("{'mysql-charset':'utf8mb4'}") @Comment("问卷调查投票活动表") -public class QsvActivity extends BaseModel implements Serializable { +public class QsvActivity extends BaseModel implements Serializable, SysHomeConvert { @Name @Comment("ID") @ColDefine(type = ColType.VARCHAR, width = 32) @@ -46,6 +48,12 @@ public class QsvActivity extends BaseModel implements Serializable { @ColDefine(type = ColType.DATETIME) private Date endTime; + @Column + @Comment("是否开启") + @ColDefine(type = ColType.BOOLEAN) + @Default("1") + private Boolean enabled; + @Column @Comment("活动分组ID") @ColDefine(type = ColType.INT) @@ -107,4 +115,35 @@ public class QsvActivity extends BaseModel implements Serializable { @Comment("封面图片") @ColDefine(type = ColType.VARCHAR, width = 255) private String cover; + + @Override + public Sys_home_activity covertToSysHomeActivity() { + Sys_home_activity sysHomeActivity = new Sys_home_activity(); + sysHomeActivity.setId(this.getId()); + sysHomeActivity.setName(this.getTitle()); + sysHomeActivity.setCover(this.getCover()); + sysHomeActivity.setContent(this.getDescription()); + sysHomeActivity.setUrl("/platform/qsv/activity"); + sysHomeActivity.setH5Url(getH5Url()); + sysHomeActivity.setStartDate(this.getStartTime()); + sysHomeActivity.setEndDate(this.getEndTime()); + sysHomeActivity.setAllowUserGroupId(this.getGroupId()); + sysHomeActivity.setEnable(!Boolean.FALSE.equals(this.getEnabled())); + sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName()); + return sysHomeActivity; + } + + /** + * 根据活动类型生成移动端首页跳转地址。 + * QUIZ 跳转答题页,SURVEY 跳转调查页,VOTE 预留投票页地址,返回值为移动端路由字符串。 + */ + private String getH5Url() { + if ("SURVEY".equals(this.getCategory())) { + return "/platform/h5/qsv/survey?id=" + this.getId(); + } + if ("VOTE".equals(this.getCategory())) { + return "/platform/h5/qsv/vote?id=" + this.getId(); + } + return "/platform/h5/qsv/quiz?id=" + this.getId(); + } } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/QsvActivityService.java b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/QsvActivityService.java index 27278a2..2247bb0 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/QsvActivityService.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/QsvActivityService.java @@ -5,4 +5,10 @@ import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity; public interface QsvActivityService extends BaseService { + + void saveActivity(QsvActivity qsvActivity); + + void deleteActivity(String id); + + void updateEnabled(String id, Boolean enabled); } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/impl/QsvActivityServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/impl/QsvActivityServiceImpl.java index 1d77d6b..5dce6bb 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/impl/QsvActivityServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/qsv/service/impl/QsvActivityServiceImpl.java @@ -1,9 +1,13 @@ package com.budwk.app.zhgh.dayofficework.qsv.service.impl; import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.sys.models.Sys_home_activity; import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity; import com.budwk.app.zhgh.dayofficework.qsv.service.QsvActivityService; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Cnd; import org.nutz.dao.Dao; +import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.IocBean; @IocBean(args = {"refer:dao"}) @@ -12,4 +16,53 @@ public class QsvActivityServiceImpl extends BaseServiceImpl impleme public QsvActivityServiceImpl(Dao dao) { super(dao); } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void saveActivity(QsvActivity qsvActivity) { + fillQuizRepeatMode(qsvActivity); + dao().insertOrUpdate(qsvActivity); + syncHomeActivity(qsvActivity); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void deleteActivity(String id) { + dao().delete(QsvActivity.class, id); + dao().delete(Sys_home_activity.class, id); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void updateEnabled(String id, Boolean enabled) { + QsvActivity activity = dao().fetch(QsvActivity.class, id); + if (activity == null) { + return; + } + activity.setEnabled(enabled); + dao().update(activity); + syncHomeActivity(activity); + } + + /** + * 答题活动的重复模式由出题模式决定。定时定题按天统计,常规模式按活动总次数统计。 + */ + private void fillQuizRepeatMode(QsvActivity qsvActivity) { + if (!"QUIZ".equals(qsvActivity.getCategory())) { + return; + } + if ("SCHEDULED".equals(qsvActivity.getMode())) { + qsvActivity.setRepeatMode("DAILY"); + } else if ("REGULAR".equals(qsvActivity.getMode())) { + qsvActivity.setRepeatMode("TOTAL"); + } + } + + /** + * 同步移动端首页活动。问卷活动保存或启停后,都以活动自身 enabled、时间、人员范围生成首页记录。 + */ + private void syncHomeActivity(QsvActivity activity) { + Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity(); + dao().insertOrUpdate(sysHomeActivity); + } } diff --git a/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/basicForm.js b/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/basicForm.js index d19f6c0..187a63b 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/basicForm.js +++ b/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/basicForm.js @@ -58,6 +58,17 @@ const basicForm = { + + + + @@ -204,7 +204,8 @@ const basicForm = { return { dialogVisible: false, formData: { - category: '' + category: '', + cover: '' }, formRules: { category: [{ required: true, message: "请选择类型", trigger: "change" }], @@ -228,7 +229,9 @@ const basicForm = { } }) } else { - this.formData = {} + this.formData = { + cover: '' + } } }, onSubmit() { diff --git a/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/index.html b/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/index.html index 7c0ab1a..9996676 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/index.html +++ b/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/index.html @@ -31,11 +31,27 @@ layout("/layouts/platform.html"){ - + + + + @@ -94,6 +110,26 @@ layout("/layouts/platform.html"){ }) }, + // 开启或关闭活动,关闭后移动端首页不展示,直达手机端问卷也不能答题 + updateEnabled(row, enabled) { + const actionText = enabled ? "开启" : "关闭" + this.$confirm("您确认" + actionText + "该活动吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(() => { + $.post("/platform/qsv/activity/updateEnabled", { + id: row.id, + enabled + }).then((res) => { + if (res.code === 0) { + this.$message.success(res.msg) + this.pageData() + } + }) + }) + }, + // 删除 onDelete(id) { this.$confirm("您确认删除吗, 是否继续?", "提示", { diff --git a/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/subjectForm.js b/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/subjectForm.js index 91573e7..6e2c5fc 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/subjectForm.js +++ b/src/main/resources/views/platform/zhgh/dayofficework/qsv/activity/subjectForm.js @@ -12,19 +12,18 @@ const subjectForm = {
-
+
第 {{subjectIndex + 1}} 题 + placeholder="请输入题目"> 隐显逻辑 @@ -663,6 +662,21 @@ const subjectForm = { margin-bottom: 15px; } + /deep/ .subject-title-row { + display: flex; + align-items: center; + } + + /deep/ .subject-title-input { + flex: 1; + } + + /deep/ .subject-visible-btn { + height: 40px; + margin-left: 8px; + flex-shrink: 0; + } + /deep/ .subject-toolbar { display: flex; justify-content: space-between; diff --git a/src/main/resources/views/platform/zhghh5/dayofficework/qsv/survey/index.html b/src/main/resources/views/platform/zhghh5/dayofficework/qsv/survey/index.html index b137365..56aa09e 100644 --- a/src/main/resources/views/platform/zhghh5/dayofficework/qsv/survey/index.html +++ b/src/main/resources/views/platform/zhghh5/dayofficework/qsv/survey/index.html @@ -101,6 +101,12 @@ layout("/layouts/platform_h5.html"){ resize: none; width: 100%; } + + .required-star { + color: #ee0a24; + margin-left: 4px; + font-weight: bold; + }
@@ -109,7 +115,7 @@ layout("/layouts/platform_h5.html"){

{{ activity.title }}

-

{{index+1}}、{{ subject.title }}

+

{{index+1}}、{{ subject.title }}*

多选 单选