From c51b5b5069bfe4469b62295f8007809a049ff4f5 Mon Sep 17 00:00:00 2001 From: wang Date: Mon, 15 Jun 2026 11:21:13 +0800 Subject: [PATCH] =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=A4=84=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/sql/业务脚本.sql | 76 +- .../business/jwpy/constant/WtczConst.java | 35 + .../controller/SurveySampleController.java | 102 +++ .../jwpy/controller/WtczController.java | 7 + .../business/jwpy/dao/SurveySampleDao.java | 15 + .../jwpy/dao/SurveySampleGroupDao.java | 15 + .../business/jwpy/dao/SurveyTaskDao.java | 15 + .../domain/entity/SurveySampleEntity.java | 40 ++ .../entity/SurveySampleGroupEntity.java | 31 + .../jwpy/domain/entity/SurveyTaskEntity.java | 55 ++ .../jwpy/domain/entity/WtczYyEntity.java | 3 + .../jwpy/domain/form/SurveySampleAddForm.java | 26 + .../domain/form/SurveySampleBatchAddForm.java | 19 + .../domain/form/SurveySampleGroupAddForm.java | 14 + .../domain/form/SurveySampleQueryForm.java | 19 + .../domain/form/SurveyTaskCreateForm.java | 26 + .../jwpy/domain/form/SurveyTaskQueryForm.java | 19 + .../form/SurveyTaskSubmitAnswerForm.java | 19 + .../jwpy/domain/form/WtczAddForm.java | 3 +- .../jwpy/domain/form/WtczQueryForm.java | 3 + .../business/jwpy/domain/vo/WtczVO.java | 15 + .../business/jwpy/domain/vo/WtczYyVO.java | 3 + .../jwpy/service/SurveySampleService.java | 221 ++++++ .../business/jwpy/service/SurveyService.java | 9 +- .../business/jwpy/service/WtczService.java | 86 ++- .../module/business/jwpy/util/WtczUtil.java | 90 +++ .../api/business/jwpy/survey-sample-api.js | 115 +++ .../src/api/business/jwpy/wtcz-api.js | 7 + smart-flow-web/src/router/flow/flow.js | 6 + smart-flow-web/src/router/index.js | 2 +- .../views/flow/definition/definition-form.vue | 6 +- .../flow/components/BizClassificationForm.vue | 47 +- .../jwpy/flow/components/CallerInfoForm.vue | 47 +- .../flow/components/InvolvedTargetForm.vue | 73 +- .../src/views/jwpy/jwpy/flow/index.vue | 194 +++--- .../views/jwpy/jwpy/flow/utils/jwpy-util.js | 66 ++ .../src/views/jwpy/jwpy/flow/wtcz-detail.vue | 140 +++- .../src/views/jwpy/jwpy/flow/wtcz-form.vue | 58 +- .../components/SurveyFormRenderer.vue | 277 ++++++++ .../src/views/jwpy/mydc/my-survey/fill.vue | 491 +++++++++++++ .../src/views/jwpy/mydc/my-survey/index.vue | 493 +++++++++---- .../jwpy/mydc/questionnaire/designer.vue | 215 +++++- .../views/jwpy/mydc/questionnaire/index.vue | 163 ++--- .../src/views/jwpy/mydc/sample/index.vue | 657 +++++++++++++----- 44 files changed, 3394 insertions(+), 629 deletions(-) create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/constant/WtczConst.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/SurveySampleController.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleDao.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleGroupDao.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveyTaskDao.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleEntity.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleGroupEntity.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveyTaskEntity.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleAddForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleBatchAddForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleGroupAddForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleQueryForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskCreateForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskQueryForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskSubmitAnswerForm.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveySampleService.java create mode 100644 smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/util/WtczUtil.java create mode 100644 smart-flow-web/src/api/business/jwpy/survey-sample-api.js create mode 100644 smart-flow-web/src/views/jwpy/jwpy/flow/utils/jwpy-util.js create mode 100644 smart-flow-web/src/views/jwpy/mydc/my-survey/components/SurveyFormRenderer.vue create mode 100644 smart-flow-web/src/views/jwpy/mydc/my-survey/fill.vue diff --git a/docs/sql/业务脚本.sql b/docs/sql/业务脚本.sql index dba83a7..88c565e 100644 --- a/docs/sql/业务脚本.sql +++ b/docs/sql/业务脚本.sql @@ -52,4 +52,78 @@ CREATE INDEX idx_phone_record_call_start_time ON t_phone_record(call_start_time) CREATE INDEX idx_phone_record_call_status ON t_phone_record(call_status); -- 序列(用于主键自增) -CREATE SEQUENCE IF NOT EXISTS seq_phone_record_id START WITH 1 INCREMENT BY 1; \ No newline at end of file +CREATE SEQUENCE IF NOT EXISTS seq_phone_record_id START WITH 1 INCREMENT BY 1; + +-- ============================================= +-- 民意调查样本库与评议任务表结构(人大金仓 / PostgreSQL 兼容) +-- ============================================= + +-- 1. 样本分类分组表 +CREATE TABLE IF NOT EXISTS t_survey_sample_group ( + id BIGINT PRIMARY KEY, + name VARCHAR(100) NOT NULL, + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +COMMENT ON TABLE t_survey_sample_group IS '样本分类分组表'; +COMMENT ON COLUMN t_survey_sample_group.id IS '主键ID'; +COMMENT ON COLUMN t_survey_sample_group.name IS '分组名称 (如:高级精英人才库)'; +COMMENT ON COLUMN t_survey_sample_group.create_time IS '创建时间'; + +-- 2. 样本人员名单表 +CREATE TABLE IF NOT EXISTS t_survey_sample ( + id BIGINT PRIMARY KEY, + group_id BIGINT NOT NULL, + name VARCHAR(50) NOT NULL, + phone VARCHAR(20) NOT NULL, + remarks VARCHAR(255), + import_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +COMMENT ON TABLE t_survey_sample IS '样本人员表'; +COMMENT ON COLUMN t_survey_sample.id IS '主键ID'; +COMMENT ON COLUMN t_survey_sample.group_id IS '关联分组ID'; +COMMENT ON COLUMN t_survey_sample.name IS '姓名'; +COMMENT ON COLUMN t_survey_sample.phone IS '联系电话'; +COMMENT ON COLUMN t_survey_sample.remarks IS '分类备注'; +COMMENT ON COLUMN t_survey_sample.import_time IS '导入时间'; + +-- 3. 调查测评任务表 +CREATE TABLE IF NOT EXISTS t_survey_task ( + id BIGINT PRIMARY KEY, + title VARCHAR(200) NOT NULL, + name VARCHAR(50) NOT NULL, + phone VARCHAR(20) NOT NULL, + sjly_no VARCHAR(50), + call_count INTEGER DEFAULT 0, + status INTEGER DEFAULT 0, + survey_title VARCHAR(200), + survey_id BIGINT, + answers TEXT, + assign_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +COMMENT ON TABLE t_survey_task IS '调查测评任务表'; +COMMENT ON COLUMN t_survey_task.id IS '主键ID'; +COMMENT ON COLUMN t_survey_task.title IS '任务名称'; +COMMENT ON COLUMN t_survey_task.name IS '受访群众姓名'; +COMMENT ON COLUMN t_survey_task.phone IS '联系电话'; +COMMENT ON COLUMN t_survey_task.sjly_no IS '关联警务分类编码'; +COMMENT ON COLUMN t_survey_task.call_count IS '呼叫次数'; +COMMENT ON COLUMN t_survey_task.status IS '状态 (0待调查, 1调查成功, 2无人接听, 3明确拒访, 4已发送短信评议)'; +COMMENT ON COLUMN t_survey_task.survey_title IS '关联问卷模板名称'; +COMMENT ON COLUMN t_survey_task.survey_id IS '关联的问卷模板ID'; +COMMENT ON COLUMN t_survey_task.answers IS '群众填报的答卷JSON详情'; +COMMENT ON COLUMN t_survey_task.assign_time IS '生成时间'; + +-- 预置默认分组与测试样本数据 +INSERT INTO t_survey_sample_group (id, name, create_time) VALUES +(1001, '高级精英人才库', CURRENT_TIMESTAMP), +(1002, '警务窗口服务评议库', CURRENT_TIMESTAMP), +(1003, '110接处警抽样库', CURRENT_TIMESTAMP) +ON CONFLICT (id) DO NOTHING; + +INSERT INTO t_survey_sample (id, group_id, name, phone, remarks, import_time) VALUES +(2001, 1001, '张大胖', '18944445555', '高层次人才领军学者', CURRENT_TIMESTAMP), +(2002, 1001, '陈科研', '18655556666', '杰出青年科研人才', CURRENT_TIMESTAMP), +(2003, 1002, '韩梅梅', '13711112222', '户政大厅办事人员', CURRENT_TIMESTAMP), +(2004, 1002, '李雷', '13633334444', '出入境窗口满意度抽评', CURRENT_TIMESTAMP), +(2005, 1003, '王有才', '13899998888', '110处警受害者电话', CURRENT_TIMESTAMP) +ON CONFLICT (id) DO NOTHING; \ No newline at end of file diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/constant/WtczConst.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/constant/WtczConst.java new file mode 100644 index 0000000..c54100a --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/constant/WtczConst.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.jwpy.constant; + +/** + * 警务评议工单业务常量定义类 + * + * @Author Antigravity + * @Date 2026-06-14 + */ +public class WtczConst { + + /** + * 工单状态:已录入/暂存,待首访 + */ + public static final String GDZT_STASH = "0"; + + /** + * 工单状态:办结中/待二次回访反馈 + */ + public static final String GDZT_PROCESSING = "1"; + + /** + * 工单状态:已办结 + */ + public static final String GDZT_COMPLETED = "2"; + + /** + * 回访阶段:1首访通话 + */ + public static final String XFJD_FIRST = "1"; + + /** + * 回访阶段:3二次回访通话 + */ + public static final String XFJD_SECOND = "3"; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/SurveySampleController.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/SurveySampleController.java new file mode 100644 index 0000000..09f092e --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/SurveySampleController.java @@ -0,0 +1,102 @@ +package net.lab1024.sa.admin.module.business.jwpy.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveySampleEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveySampleGroupEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveyTaskEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.form.*; +import net.lab1024.sa.admin.module.business.jwpy.service.SurveySampleService; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 调查问卷样本库与评议任务 控制器 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@RestController +@Tag(name = "业务功能-调查样本与评议分发") +public class SurveySampleController { + + @Resource + private SurveySampleService sampleService; + + // ================= 分组管理 ================= + + @Operation(summary = "查询样本库分类列表") + @GetMapping("/mydc/sample/group/list") + public ResponseDTO> groupList() { + return ResponseDTO.ok(sampleService.groupList()); + } + + @Operation(summary = "创建新样本库分类") + @PostMapping("/mydc/sample/group/add") + public ResponseDTO addGroup(@RequestBody @Valid SurveySampleGroupAddForm form) { + return sampleService.addGroup(form); + } + + @Operation(summary = "移除样本库分类及其样本") + @GetMapping("/mydc/sample/group/delete/{id}") + public ResponseDTO deleteGroup(@PathVariable Long id) { + return sampleService.deleteGroup(id); + } + + // ================= 名单管理 ================= + + @Operation(summary = "分页筛选样本人员名单") + @PostMapping("/mydc/sample/queryPage") + public ResponseDTO> querySamplePage(@RequestBody @Valid SurveySampleQueryForm queryForm) { + return ResponseDTO.ok(sampleService.querySamplePage(queryForm)); + } + + @Operation(summary = "单条录入样本人员") + @PostMapping("/mydc/sample/add") + public ResponseDTO addSample(@RequestBody @Valid SurveySampleAddForm form) { + return sampleService.addSample(form); + } + + @Operation(summary = "粘贴多行文本批量解析导入") + @PostMapping("/mydc/sample/batchAdd") + public ResponseDTO batchAddSamples(@RequestBody @Valid SurveySampleBatchAddForm form) { + return sampleService.batchAddSamples(form); + } + + @Operation(summary = "移除样本库成员") + @GetMapping("/mydc/sample/delete/{id}") + public ResponseDTO deleteSample(@PathVariable Long id) { + return sampleService.deleteSample(id); + } + + // ================= 测评任务管理 ================= + + @Operation(summary = "分页查询测评任务列表") + @PostMapping("/mydc/task/queryPage") + public ResponseDTO> queryTaskPage(@RequestBody @Valid SurveyTaskQueryForm queryForm) { + return ResponseDTO.ok(sampleService.queryTaskPage(queryForm)); + } + + @Operation(summary = "查询单个测评任务详情") + @GetMapping("/mydc/task/detail/{id}") + public ResponseDTO getTaskDetail(@PathVariable Long id) { + return ResponseDTO.ok(sampleService.getTaskDetail(id)); + } + + @Operation(summary = "新建调查任务并批量推送生成名单") + @PostMapping("/mydc/task/create") + public ResponseDTO createSurveyTask(@RequestBody @Valid SurveyTaskCreateForm form) { + return sampleService.createSurveyTask(form); + } + + @Operation(summary = "H5填报端提交群众测评答案") + @PostMapping("/mydc/task/submitAnswer") + public ResponseDTO submitH5Answer(@RequestBody @Valid SurveyTaskSubmitAnswerForm form) { + return sampleService.submitH5Answer(form); + } +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/WtczController.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/WtczController.java index 3a19777..22c14aa 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/WtczController.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/controller/WtczController.java @@ -15,6 +15,7 @@ import net.lab1024.sa.base.common.util.SmartRequestUtil; import net.lab1024.sa.base.common.domain.PageResult; import net.lab1024.sa.base.common.domain.ResponseDTO; import net.lab1024.sa.base.common.domain.ValidateList; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczYyEntity; import org.springframework.web.bind.annotation.*; /** @@ -93,4 +94,10 @@ public class WtczController { Long employeeId = SmartRequestUtil.getRequestUserId(); return wtczService.claimRandom(employeeId); } + + @Operation(summary = "保存外呼通话录音流水") + @PostMapping("/jwpy/wtcz/addYy") + public ResponseDTO addYy(@RequestBody @Valid WtczYyEntity entity) { + return wtczService.addYy(entity); + } } diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleDao.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleDao.java new file mode 100644 index 0000000..c89e990 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleDao.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.business.jwpy.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveySampleEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 调查问卷样本人员 Dao 接口 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Mapper +public interface SurveySampleDao extends BaseMapper { +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleGroupDao.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleGroupDao.java new file mode 100644 index 0000000..c5ed797 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveySampleGroupDao.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.business.jwpy.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveySampleGroupEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 调查问卷样本分组 Dao 接口 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Mapper +public interface SurveySampleGroupDao extends BaseMapper { +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveyTaskDao.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveyTaskDao.java new file mode 100644 index 0000000..1f6a335 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/dao/SurveyTaskDao.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.business.jwpy.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveyTaskEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 调查测评任务 Dao 接口 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Mapper +public interface SurveyTaskDao extends BaseMapper { +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleEntity.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleEntity.java new file mode 100644 index 0000000..5172a99 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleEntity.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 调查问卷样本人员 实体类 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Data +@TableName("t_survey_sample") +@Schema(description = "调查问卷样本人员实体") +public class SurveySampleEntity { + + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "样本人ID") + private Long id; + + @Schema(description = "关联分组ID") + private Long groupId; + + @Schema(description = "群众/人才姓名") + private String name; + + @Schema(description = "手机号") + private String phone; + + @Schema(description = "备注说明") + private String remarks; + + @Schema(description = "录入时间") + private LocalDateTime importTime; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleGroupEntity.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleGroupEntity.java new file mode 100644 index 0000000..2b95df3 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveySampleGroupEntity.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 调查问卷样本分组 实体类 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Data +@TableName("t_survey_sample_group") +@Schema(description = "调查问卷样本分组实体") +public class SurveySampleGroupEntity { + + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "分组ID") + private Long id; + + @Schema(description = "分类/分组名称") + private String name; + + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveyTaskEntity.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveyTaskEntity.java new file mode 100644 index 0000000..260c215 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/SurveyTaskEntity.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 调查测评任务 实体类 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Data +@TableName("t_survey_task") +@Schema(description = "调查测评任务实体") +public class SurveyTaskEntity { + + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "任务ID") + private Long id; + + @Schema(description = "任务名称") + private String title; + + @Schema(description = "受访群众姓名") + private String name; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "关联警务分类编码") + private String sjlyNo; + + @Schema(description = "呼叫次数") + private Integer callCount; + + @Schema(description = "状态: 0待调查, 1调查成功, 2无人接听, 3明确拒访, 4已发送短信评议") + private Integer status; + + @Schema(description = "关联问卷模板名称") + private String surveyTitle; + + @Schema(description = "关联的问卷模板ID") + private Long surveyId; + + @Schema(description = "群众填报的答卷JSON详情") + private String answers; + + @Schema(description = "生成/分配时间") + private LocalDateTime assignTime; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/WtczYyEntity.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/WtczYyEntity.java index 02cf7d3..9d26c48 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/WtczYyEntity.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/entity/WtczYyEntity.java @@ -64,6 +64,9 @@ public class WtczYyEntity { @Schema(description = "语音通话记录表ID") private Long yyId; + + @Schema(description = "回访阶段:1首访通话,3二次回访通话") + private String xfjd; } diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleAddForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleAddForm.java new file mode 100644 index 0000000..cc60b5e --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleAddForm.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +@Schema(description = "新增单个样本人员表单") +public class SurveySampleAddForm { + + @Schema(description = "样本组ID") + @NotNull(message = "样本分组不能为空") + private Long groupId; + + @Schema(description = "姓名") + @NotBlank(message = "姓名不能为空") + private String name; + + @Schema(description = "联系电话") + @NotBlank(message = "电话不能为空") + private String phone; + + @Schema(description = "分类备注/描述") + private String remarks; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleBatchAddForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleBatchAddForm.java new file mode 100644 index 0000000..ad4f432 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleBatchAddForm.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +@Schema(description = "批量粘贴解析导入样本表单") +public class SurveySampleBatchAddForm { + + @Schema(description = "样本组ID") + @NotNull(message = "样本分组不能为空") + private Long groupId; + + @Schema(description = "粘贴的解析文本块") + @NotBlank(message = "粘贴的数据文本不能为空") + private String text; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleGroupAddForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleGroupAddForm.java new file mode 100644 index 0000000..8684d06 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleGroupAddForm.java @@ -0,0 +1,14 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +@Data +@Schema(description = "新增样本分组表单") +public class SurveySampleGroupAddForm { + + @Schema(description = "分类/分组名称") + @NotBlank(message = "分组名称不能为空") + private String name; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleQueryForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleQueryForm.java new file mode 100644 index 0000000..098fdab --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveySampleQueryForm.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +@Data +@Schema(description = "样本名单分页查询表单") +public class SurveySampleQueryForm extends PageParam { + + @Schema(description = "样本组ID") + private Long groupId; + + @Schema(description = "姓名/模糊查询") + private String name; + + @Schema(description = "手机号") + private String phone; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskCreateForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskCreateForm.java new file mode 100644 index 0000000..6984281 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskCreateForm.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +@Schema(description = "新建并推送调查测评任务表单") +public class SurveyTaskCreateForm { + + @Schema(description = "测评任务名称") + @NotBlank(message = "任务名称不能为空") + private String title; + + @Schema(description = "样本分组ID") + @NotNull(message = "请选择目标样本分组") + private Long groupId; + + @Schema(description = "关联的问卷模板ID") + @NotNull(message = "请选择关联的问卷模板") + private Long surveyId; + + @Schema(description = "推送通知方式: sms 短信, wx 微信") + private String pushType; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskQueryForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskQueryForm.java new file mode 100644 index 0000000..717a94c --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskQueryForm.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +@Data +@Schema(description = "测评任务分页查询表单") +public class SurveyTaskQueryForm extends PageParam { + + @Schema(description = "受访群众姓名/模糊查询") + private String name; + + @Schema(description = "任务状态: 0待调查, 1调查成功, 2无人接听, 3明确拒访, 4已发送") + private Integer status; + + @Schema(description = "是否只查询待回访的列表") + private Boolean isTodoView; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskSubmitAnswerForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskSubmitAnswerForm.java new file mode 100644 index 0000000..6139fce --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/SurveyTaskSubmitAnswerForm.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.jwpy.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +@Schema(description = "群众自助填报提交表单") +public class SurveyTaskSubmitAnswerForm { + + @Schema(description = "任务明细ID") + @NotNull(message = "任务ID不能为空") + private Long taskId; + + @Schema(description = "答卷反馈选项JSON内容") + @NotBlank(message = "答卷内容不能为空") + private String answers; +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczAddForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczAddForm.java index bd35f49..237336f 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczAddForm.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczAddForm.java @@ -15,8 +15,7 @@ import java.time.LocalDateTime; @Data public class WtczAddForm { - @Schema(description = "工单受理编号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotBlank(message = "工单受理编号 不能为空") + @Schema(description = "工单受理编号") private String slbh; @Schema(description = "地市4位数字编码") diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczQueryForm.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczQueryForm.java index f7a5b48..3e36249 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczQueryForm.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/form/WtczQueryForm.java @@ -40,4 +40,7 @@ public class WtczQueryForm extends PageParam { @Schema(description = "分派认领状态: 0未认领, 1已认领") private Integer assignStatus; + + @Schema(description = "菜单类型:all全部, to_handle待办, transferred已流转, completed已办结, about_to_expire即将超期, expired已超期, invalid已作废") + private String tabType; } diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczVO.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczVO.java index ceb7beb..d056480 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczVO.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczVO.java @@ -201,6 +201,21 @@ public class WtczVO { @Schema(description = "首访通话语音列表") private java.util.List czzxWtczYyList; + @Schema(description = "二访通话语音列表") + private java.util.List secondCallList; + @Schema(description = "二次回访记录列表") private java.util.List czzxWtczHfhcList; + + @Schema(description = "涉及业务小类名称") + private String sjlyNoName; + + @Schema(description = "诉求分类名称") + private String sqflName; + + @Schema(description = "群众满意度名称") + private String qzmyqkName; + + @Schema(description = "工单状态名称") + private String gdztName; } diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczYyVO.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczYyVO.java index bc6eed1..d29363b 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczYyVO.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/domain/vo/WtczYyVO.java @@ -62,4 +62,7 @@ public class WtczYyVO { @Schema(description = "语音通话记录表ID") private Long yyId; + + @Schema(description = "回访阶段:1首访通话,3二次回访通话") + private String xfjd; } diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveySampleService.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveySampleService.java new file mode 100644 index 0000000..d318f0a --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveySampleService.java @@ -0,0 +1,221 @@ +package net.lab1024.sa.admin.module.business.jwpy.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.jwpy.dao.SurveyDao; +import net.lab1024.sa.admin.module.business.jwpy.dao.SurveySampleDao; +import net.lab1024.sa.admin.module.business.jwpy.dao.SurveySampleGroupDao; +import net.lab1024.sa.admin.module.business.jwpy.dao.SurveyTaskDao; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveyEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveySampleEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveySampleGroupEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.entity.SurveyTaskEntity; +import net.lab1024.sa.admin.module.business.jwpy.domain.form.*; +import net.lab1024.sa.base.common.domain.PageResult; +import net.lab1024.sa.base.common.domain.ResponseDTO; +import net.lab1024.sa.base.common.util.SmartBeanUtil; +import net.lab1024.sa.base.common.util.SmartPageUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * 调查问卷样本库与评议任务 业务服务类 + * + * @Author Antigravity + * @Date 2026-06-15 + */ +@Service +@Slf4j +public class SurveySampleService { + + @Resource + private SurveySampleGroupDao groupDao; + + @Resource + private SurveySampleDao sampleDao; + + @Resource + private SurveyTaskDao surveyTaskDao; + + @Resource + private SurveyDao surveyDao; + + // ================= 分组管理 ================= + + public List groupList() { + return groupDao.selectList(Wrappers.lambdaQuery().orderByAsc(SurveySampleGroupEntity::getId)); + } + + public ResponseDTO addGroup(SurveySampleGroupAddForm form) { + SurveySampleGroupEntity entity = new SurveySampleGroupEntity(); + entity.setName(form.getName()); + entity.setCreateTime(LocalDateTime.now()); + groupDao.insert(entity); + return ResponseDTO.ok("分组创建成功"); + } + + public ResponseDTO deleteGroup(Long id) { + groupDao.deleteById(id); + // 联动删除该分组下的所有人员 + sampleDao.delete(Wrappers.lambdaQuery().eq(SurveySampleEntity::getGroupId, id)); + return ResponseDTO.ok("分类及下属样本删除成功"); + } + + // ================= 样本名单管理 ================= + + @SuppressWarnings("unchecked") + public PageResult querySamplePage(SurveySampleQueryForm queryForm) { + Page page = (Page) SmartPageUtil.convert2PageQuery(queryForm); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + + if (queryForm.getGroupId() != null) { + wrapper.eq(SurveySampleEntity::getGroupId, queryForm.getGroupId()); + } + if (StringUtils.isNotBlank(queryForm.getName())) { + wrapper.like(SurveySampleEntity::getName, queryForm.getName()); + } + if (StringUtils.isNotBlank(queryForm.getPhone())) { + wrapper.eq(SurveySampleEntity::getPhone, queryForm.getPhone()); + } + + wrapper.orderByDesc(SurveySampleEntity::getImportTime); + sampleDao.selectPage(page, wrapper); + return SmartPageUtil.convert2PageResult(page, page.getRecords(), SurveySampleEntity.class); + } + + public ResponseDTO addSample(SurveySampleAddForm form) { + SurveySampleEntity entity = SmartBeanUtil.copy(form, SurveySampleEntity.class); + entity.setImportTime(LocalDateTime.now()); + sampleDao.insert(entity); + return ResponseDTO.ok("录入样本成功"); + } + + @Transactional(rollbackFor = Exception.class) + public ResponseDTO batchAddSamples(SurveySampleBatchAddForm form) { + String text = form.getText(); + if (StringUtils.isBlank(text)) { + return ResponseDTO.userErrorParam("粘贴内容不能为空"); + } + String[] lines = text.split("\n"); + List list = new ArrayList<>(); + + for (String line : lines) { + if (StringUtils.isBlank(line)) continue; + String[] parts = line.split("[,,\\s]+"); + if (parts.length >= 2) { + String name = parts[0].trim(); + String phone = parts[1].trim(); + String remarks = parts.length >= 3 ? parts[2].trim() : ""; + + if (phone.matches("\\d{11}")) { + SurveySampleEntity s = new SurveySampleEntity(); + s.setGroupId(form.getGroupId()); + s.setName(name); + s.setPhone(phone); + s.setRemarks(remarks); + s.setImportTime(LocalDateTime.now()); + list.add(s); + } + } + } + + if (list.isEmpty()) { + return ResponseDTO.userErrorParam("解析失败,未提取到符合格式要求的人员信息"); + } + + for (SurveySampleEntity s : list) { + sampleDao.insert(s); + } + return ResponseDTO.ok("成功导入 " + list.size() + " 条样本数据"); + } + + public ResponseDTO deleteSample(Long id) { + sampleDao.deleteById(id); + return ResponseDTO.ok("移除样本人员成功"); + } + + // ================= 调查评议任务管理 ================= + + @SuppressWarnings("unchecked") + public PageResult queryTaskPage(SurveyTaskQueryForm queryForm) { + Page page = (Page) SmartPageUtil.convert2PageQuery(queryForm); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + + if (StringUtils.isNotBlank(queryForm.getName())) { + wrapper.like(SurveyTaskEntity::getName, queryForm.getName()); + } + + if (queryForm.getStatus() != null) { + wrapper.eq(SurveyTaskEntity::getStatus, queryForm.getStatus()); + } else { + // 待办/已发推送等自适应过滤 + if (queryForm.getIsTodoView() != null && queryForm.getIsTodoView()) { + wrapper.in(SurveyTaskEntity::getStatus, 0, 2, 4); // 待调查、未接听、已发送推送 + } + } + + wrapper.orderByDesc(SurveyTaskEntity::getAssignTime); + surveyTaskDao.selectPage(page, wrapper); + return SmartPageUtil.convert2PageResult(page, page.getRecords(), SurveyTaskEntity.class); + } + + public SurveyTaskEntity getTaskDetail(Long id) { + return surveyTaskDao.selectById(id); + } + + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createSurveyTask(SurveyTaskCreateForm form) { + // 1. 获取分组样本人员 + List samples = sampleDao.selectList( + Wrappers.lambdaQuery().eq(SurveySampleEntity::getGroupId, form.getGroupId()) + ); + if (samples.isEmpty()) { + return ResponseDTO.userErrorParam("所选的分组下没有任何样本人员,请先录入名单"); + } + + // 2. 获取关联问卷详情 + SurveyEntity survey = surveyDao.selectById(form.getSurveyId()); + if (survey == null) { + return ResponseDTO.userErrorParam("绑定的问卷模板不存在"); + } + if (survey.getStatus() == null || survey.getStatus() != 1) { + return ResponseDTO.userErrorParam("该问卷模板尚未启用,无法创建测评任务!"); + } + + // 3. 循环转换生成评议任务 + for (SurveySampleEntity s : samples) { + SurveyTaskEntity task = new SurveyTaskEntity(); + task.setTitle(form.getTitle()); + task.setName(s.getName()); + task.setPhone(s.getPhone()); + task.setSjlyNo(form.getGroupId() == 1001L ? "crj" : (form.getGroupId() == 1002L ? "hz" : "110")); // 业务分类标签颜色映射 + task.setCallCount(0); + task.setStatus(4); // 直接设置为已发推送评议状态 + task.setSurveyTitle(survey.getTitle()); + task.setSurveyId(survey.getSurveyId()); + task.setAssignTime(LocalDateTime.now()); + surveyTaskDao.insert(task); + } + + return ResponseDTO.ok("成功为 " + samples.size() + " 位群众生成评议任务并下发通知!"); + } + + public ResponseDTO submitH5Answer(SurveyTaskSubmitAnswerForm form) { + SurveyTaskEntity task = surveyTaskDao.selectById(form.getTaskId()); + if (task == null) { + return ResponseDTO.userErrorParam("测评任务明细不存在"); + } + task.setStatus(1); // 状态更新为“调查成功/已评议” + task.setAnswers(form.getAnswers()); + surveyTaskDao.updateById(task); + return ResponseDTO.ok("提交成功,感谢您的测评反馈!"); + } +} diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveyService.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveyService.java index 85bb0cf..e94ff54 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveyService.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/SurveyService.java @@ -14,7 +14,6 @@ import net.lab1024.sa.admin.module.business.jwpy.domain.form.SurveyAddForm; import net.lab1024.sa.admin.module.business.jwpy.domain.form.SurveyUpdateForm; import net.lab1024.sa.admin.module.business.jwpy.domain.form.SurveyAnswerAddForm; import net.lab1024.sa.admin.module.business.jwpy.domain.vo.SurveyVO; -import net.lab1024.sa.admin.module.business.jwpy.domain.vo.SurveyAnswerVO; import net.lab1024.sa.base.common.domain.PageResult; import net.lab1024.sa.base.common.domain.ResponseDTO; import net.lab1024.sa.base.common.util.SmartBeanUtil; @@ -119,7 +118,7 @@ public class SurveyService { public ResponseDTO submitAnswer(SurveyAnswerAddForm answerForm) { SurveyAnswerEntity entity = SmartBeanUtil.copy(answerForm, SurveyAnswerEntity.class); entity.setCreateTime(LocalDateTime.now()); - + // 如果满意度未指定且存在总分,做常规简易满意度划分:得分 >= 85 满意,70-84 基本满意,低于 70 不满意 if (StringUtils.isBlank(entity.getSatisfactionLevel()) && entity.getTotalScore() != null) { int score = entity.getTotalScore(); @@ -131,15 +130,15 @@ public class SurveyService { entity.setSatisfactionLevel("不满意"); } } - + surveyAnswerDao.insert(entity); - + // 闭环警示:如果不满意,可以打印特殊业务日志或联动处置逻辑 if ("不满意".equals(entity.getSatisfactionLevel())) { log.warn("民意调查警报:收到一份 [不满意] 的测评结果,答卷ID: {}, 工单关联ID: {}, 得分: {}", entity.getAnswerId(), entity.getWtczId(), entity.getTotalScore()); } - + return ResponseDTO.ok("答卷提报成功"); } } diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/WtczService.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/WtczService.java index a38ce73..de9b68b 100644 --- a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/WtczService.java +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/service/WtczService.java @@ -8,6 +8,8 @@ import lombok.extern.slf4j.Slf4j; import net.lab1024.sa.admin.module.business.jwpy.dao.WtczDao; import net.lab1024.sa.admin.module.business.jwpy.dao.WtczYyDao; import net.lab1024.sa.admin.module.business.jwpy.dao.WtczHfhcDao; +import net.lab1024.sa.admin.module.business.jwpy.constant.WtczConst; +import net.lab1024.sa.admin.module.business.jwpy.util.WtczUtil; import net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity; import net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczYyEntity; import net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczHfhcEntity; @@ -76,6 +78,9 @@ public class WtczService { @Resource private FlowTaskMapper flowTaskMapper; + @Resource + private net.lab1024.sa.base.module.support.dict.service.DictService dictService; + /** * 分页查询评议工单列表 * @@ -98,6 +103,9 @@ public class WtczService { wrapper.eq(WtczEntity::getSjlyNo, queryForm.getSjlyNo()); } + // 根据菜单类型(如 待办、已流转、已办结)统一织入状态过滤条件 + WtczUtil.buildTabTypeFilter(wrapper, queryForm.getTabType()); + // 工单状态 if (StringUtils.isNotBlank(queryForm.getGdzt())) { wrapper.eq(WtczEntity::getGdzt, queryForm.getGdzt()); @@ -134,6 +142,7 @@ public class WtczService { wtczDao.selectPage(page, wrapper); List voList = SmartBeanUtil.copyList(page.getRecords(), WtczVO.class); fillFlowInfo(voList); + fillDictNames(voList); PageResult pageResult = SmartPageUtil.convert2PageResult(page, voList); return ResponseDTO.ok(pageResult); } @@ -164,6 +173,33 @@ public class WtczService { } } + private void fillDictNames(List voList) { + if (CollectionUtils.isEmpty(voList)) { + return; + } + for (WtczVO vo : voList) { + if (StringUtils.isNotBlank(vo.getSjlyNo())) { + vo.setSjlyNoName(dictService.getDictDataLabel("BUSINESS_CLASSIFICATION", vo.getSjlyNo())); + } + if (StringUtils.isNotBlank(vo.getSqfl())) { + vo.setSqflName(dictService.getDictDataLabel("CZZX_SQFL", vo.getSqfl())); + } + if (StringUtils.isNotBlank(vo.getQzmyqk())) { + vo.setQzmyqkName(dictService.getDictDataLabel("CALLBACK_SATISFACTION", vo.getQzmyqk())); + } + if (StringUtils.isNotBlank(vo.getGdzt())) { + String gdzt = vo.getGdzt(); + if ("0".equals(gdzt)) { + vo.setGdztName("待首访"); + } else if ("1".equals(gdzt)) { + vo.setGdztName("办理中"); + } else if ("2".equals(gdzt)) { + vo.setGdztName("已办结"); + } + } + } + } + /** * 检测若该小类暂无数据,则自动往 t_czzx_wtcz、t_czzx_wtcz_yy、t_czzx_wtcz_hfhc 中注入 3 条 Mock 数据,方便流程联调与演示 * @@ -284,6 +320,10 @@ public class WtczService { */ @Transactional(rollbackFor = Exception.class) public ResponseDTO add(WtczAddForm addForm) { + if (StringUtils.isBlank(addForm.getSlbh())) { + addForm.setSlbh(WtczUtil.generateSlbh()); + } + // 校验受理编号是否唯一 long count = wtczDao.selectCount(Wrappers.lambdaQuery().eq(WtczEntity::getSlbh, addForm.getSlbh())); if (count > 0) { @@ -292,7 +332,7 @@ public class WtczService { WtczEntity entity = SmartBeanUtil.copy(addForm, WtczEntity.class); wtczDao.insert(entity); - return ResponseDTO.ok("添加成功"); + return ResponseDTO.ok(entity.getId().toString()); } /** @@ -365,16 +405,26 @@ public class WtczService { WtczVO vo = SmartBeanUtil.copy(entity, WtczVO.class); fillFlowInfo(List.of(vo)); + fillDictNames(List.of(vo)); - // 1. 查询并聚合首访通话语音列表 + // 1. 查询并聚合首访通话语音列表与二次回访语音列表 if (StringUtils.isNotBlank(vo.getSlbh())) { List yyEntities = wtczYyDao.selectList(Wrappers.lambdaQuery() .eq(WtczYyEntity::getSlbh, vo.getSlbh()) + .eq(WtczYyEntity::getXfjd, WtczConst.XFJD_FIRST) .orderByDesc(WtczYyEntity::getId)); if (CollectionUtils.isNotEmpty(yyEntities)) { vo.setCzzxWtczYyList(SmartBeanUtil.copyList(yyEntities, WtczYyVO.class)); } + List secondYyEntities = wtczYyDao.selectList(Wrappers.lambdaQuery() + .eq(WtczYyEntity::getSlbh, vo.getSlbh()) + .eq(WtczYyEntity::getXfjd, WtczConst.XFJD_SECOND) + .orderByDesc(WtczYyEntity::getId)); + if (CollectionUtils.isNotEmpty(secondYyEntities)) { + vo.setSecondCallList(SmartBeanUtil.copyList(secondYyEntities, WtczYyVO.class)); + } + // 2. 查询并聚合二次回访核实记录 List hfhcEntities = wtczHfhcDao.selectList(Wrappers.lambdaQuery() .eq(WtczHfhcEntity::getSlbh, vo.getSlbh()) @@ -408,7 +458,7 @@ public class WtczService { throw new BusinessException("当前工单没有可办理的流程任务,请检查流程定义节点配置"); } - if (CollectionUtils.isNotEmpty(taskList)) { + if (CollectionUtils.isNotEmpty(taskList) && action != WtczWorkflowAction.STASH) { FlowParams flowParams = new FlowParams(); flowParams.skipType(SkipType.PASS.getKey()); flowParams.flowCode(FLOW_CODE); @@ -554,6 +604,36 @@ public class WtczService { return ResponseDTO.userErrorParam("系统当前繁忙或工单已抢空,请稍后刷新重试"); } + /** + * 新增外呼通话录音记录,并根据当前工单流转状态,智能拦截并注入回访阶段 (xfjd) 属性。 + * + * @param entity 通话录音实体数据 + * @return 保存结果 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO addYy(WtczYyEntity entity) { + if (entity == null || StringUtils.isBlank(entity.getSlbh())) { + return ResponseDTO.userErrorParam("工单受理编号不能为空"); + } + // 1. 查询关联的评议工单主表信息 + WtczEntity wtcz = wtczDao.selectOne(Wrappers.lambdaQuery() + .eq(WtczEntity::getSlbh, entity.getSlbh())); + + // 2. 根据工单当前处理状态,智能推导当前回访阶段 + if (wtcz != null) { + entity.setXfjd(WtczUtil.determineXfjdByGdzt(wtcz.getGdzt())); + } else { + entity.setXfjd(WtczConst.XFJD_FIRST); // 默认首访 + } + + if (entity.getCreateTime() == null) { + entity.setCreateTime(LocalDateTime.now()); + } + + wtczYyDao.insert(entity); + return ResponseDTO.ok("通话录音流水保存成功"); + } + private enum WtczWorkflowAction { FIRST_CLOSE("firstClose", "2", "1", "1", "CZZX_MYD_01", null, null, null, true, "首访沟通清楚,群众表示满意,工单直接办结归档。"), diff --git a/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/util/WtczUtil.java b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/util/WtczUtil.java new file mode 100644 index 0000000..81da6e0 --- /dev/null +++ b/smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/jwpy/util/WtczUtil.java @@ -0,0 +1,90 @@ +package net.lab1024.sa.admin.module.business.jwpy.util; + +import net.lab1024.sa.admin.module.business.jwpy.constant.WtczConst; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 警务评议工单业务工具类 + * + * @Author Antigravity + * @Date 2026-06-14 + */ +public class WtczUtil { + + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + /** + * 根据工单当前处理状态,智能推导当前对应的回访阶段(首访或二访) + * + * @param gdzt 工单处理状态 + * @return 对应的回访阶段标识 + */ + public static String determineXfjdByGdzt(String gdzt) { + if (WtczConst.GDZT_STASH.equals(gdzt)) { + return WtczConst.XFJD_FIRST; + } else if (WtczConst.GDZT_PROCESSING.equals(gdzt)) { + return WtczConst.XFJD_SECOND; + } + // 默认归入首访 + return WtczConst.XFJD_FIRST; + } + + /** + * 生成唯一的工单受理编号 (slbh) + * 规则: SL + 毫秒时间戳 + 4位随机数 + * + * @return 唯一的工单受理编号 + */ + public static String generateSlbh() { + long timestamp = System.currentTimeMillis(); + int random = (int) ((Math.random() * 9 + 1) * 1000); // 1000 ~ 9999 + return "SL" + timestamp + random; + } + + /** + * 根据前端菜单传递的 tabType,向 Mybatis-Plus QueryWrapper 统一织入对应的状态过滤条件。 + * + * @param wrapper Mybatis-Plus 实体查询 Wrapper 容器 + * @param tabType 前端左侧三级菜单路由类型 + */ + public static void buildTabTypeFilter(com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper wrapper, String tabType) { + if (org.apache.commons.lang3.StringUtils.isBlank(tabType)) { + return; + } + switch (tabType) { + case "to_handle": + // 待办工单:包含暂存待首访(0)和办理中(1) + wrapper.in(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getGdzt, java.util.List.of(WtczConst.GDZT_STASH, WtczConst.GDZT_PROCESSING)); + break; + case "transferred": + // 已流转工单:已经在流程办理核查中的工单(1) + wrapper.eq(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getGdzt, WtczConst.GDZT_PROCESSING); + break; + case "completed": + // 已办结工单:(2) + wrapper.eq(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getGdzt, WtczConst.GDZT_COMPLETED); + break; + case "about_to_expire": + // 即将超期 (未办结 且 创建时间在 2天前 到 3天前 之间) + String twoDaysAgo = LocalDateTime.now().minusDays(2).format(DATE_TIME_FORMATTER); + String threeDaysAgoFor临期 = LocalDateTime.now().minusDays(3).format(DATE_TIME_FORMATTER); + wrapper.ne(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getGdzt, WtczConst.GDZT_COMPLETED) + .between(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getCreateTime, threeDaysAgoFor临期, twoDaysAgo); + break; + case "expired": + // 已超期 (未办结 且 创建时间早于 3天前,即 72 小时前) + String threeDaysAgo = LocalDateTime.now().minusDays(3).format(DATE_TIME_FORMATTER); + wrapper.ne(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getGdzt, WtczConst.GDZT_COMPLETED) + .le(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getCreateTime, threeDaysAgo); + break; + case "invalid": + // 已作废 (占位状态,避免正常查出数据) + wrapper.eq(net.lab1024.sa.admin.module.business.jwpy.domain.entity.WtczEntity::getGdzt, "9"); + break; + case "all": + default: + break; + } + } +} diff --git a/smart-flow-web/src/api/business/jwpy/survey-sample-api.js b/smart-flow-web/src/api/business/jwpy/survey-sample-api.js new file mode 100644 index 0000000..3a3b10a --- /dev/null +++ b/smart-flow-web/src/api/business/jwpy/survey-sample-api.js @@ -0,0 +1,115 @@ +/** + * 民意调查样本库与评议任务 api 封装 + * + * @Author: Antigravity + * @Date: 2026-06-15 + */ +import { postRequest, getRequest } from '/@/lib/axios'; + +export const surveySampleApi = { + + /** + * 获取样本库分组列表 + */ + queryGroupList: () => { + return getRequest('/mydc/sample/group/list'); + }, + + /** + * 新增样本分组 + */ + addGroup: (param) => { + return postRequest('/mydc/sample/group/add', param); + }, + + /** + * 删除样本分组及下属所有样本 + */ + deleteGroup: (id) => { + return getRequest(`/mydc/sample/group/delete/${id}`); + }, + + /** + * 分页查询当前分组样本人员名单 + */ + querySamplePage: (param) => { + return postRequest('/mydc/sample/queryPage', param); + }, + + /** + * 新增单条样本人员 + */ + addSample: (param) => { + return postRequest('/mydc/sample/add', param); + }, + + /** + * 粘贴文本批量解析导入样本人员 + */ + batchAddSamples: (param) => { + return postRequest('/mydc/sample/batchAdd', param); + }, + + /** + * 删除样本人员 + */ + deleteSample: (id) => { + return getRequest(`/mydc/sample/delete/${id}`); + }, + + /** + * 分页查询测评任务列表 + */ + queryTaskPage: (param) => { + return postRequest('/mydc/task/queryPage', param); + }, + + /** + * 获取测评任务详情 + */ + getTaskDetail: (id) => { + return getRequest(`/mydc/task/detail/${id}`); + }, + + /** + * 新建调查评议任务并批量向分组推送 + */ + createSurveyTask: (param) => { + return postRequest('/mydc/task/create', param); + }, + + /** + * H5填报端提交群众测评答案 + */ + submitH5Answer: (param) => { + return postRequest('/mydc/task/submitAnswer', param); + }, + + /** + * 查询已配置的问卷模板列表 + */ + querySurveys: (param) => { + return postRequest('/mydc/survey/queryPage', param); + }, + + /** + * 添加新问卷模板 + */ + addSurvey: (param) => { + return postRequest('/mydc/survey/add', param); + }, + + /** + * 修改/保存问卷设计及状态 + */ + updateSurvey: (param) => { + return postRequest('/mydc/survey/update', param); + }, + + /** + * 删除问卷模板 + */ + deleteSurvey: (id) => { + return getRequest(`/mydc/survey/delete/${id}`); + } +}; diff --git a/smart-flow-web/src/api/business/jwpy/wtcz-api.js b/smart-flow-web/src/api/business/jwpy/wtcz-api.js index 2603e63..7ded0d5 100644 --- a/smart-flow-web/src/api/business/jwpy/wtcz-api.js +++ b/smart-flow-web/src/api/business/jwpy/wtcz-api.js @@ -69,5 +69,12 @@ export const wtczApi = { */ getUnclaimedCount: () => { return getRequest('/jwpy/wtcz/unclaimedCount'); + }, + + /** + * 保存外呼通话录音流水 + */ + addYy: (param) => { + return postRequest('/jwpy/wtcz/addYy', param); } }; diff --git a/smart-flow-web/src/router/flow/flow.js b/smart-flow-web/src/router/flow/flow.js index 34d17da..0a0956b 100644 --- a/smart-flow-web/src/router/flow/flow.js +++ b/smart-flow-web/src/router/flow/flow.js @@ -67,5 +67,11 @@ export const flowRouters = [ meta: { title: '网络民意监测' } } ] + }, + { + path: '/survey/fill', + component: () => import('/@/views/jwpy/mydc/my-survey/fill.vue'), + name: 'SurveyFillPublic', + meta: { title: '群众自助评议填报' } } ] \ No newline at end of file diff --git a/smart-flow-web/src/router/index.js b/smart-flow-web/src/router/index.js index 4081a21..6e56ad4 100644 --- a/smart-flow-web/src/router/index.js +++ b/smart-flow-web/src/router/index.js @@ -33,7 +33,7 @@ router.beforeEach(async (to, from, next) => { nProgress.start(); // 公共页面,任何时候都可以跳转 - if (to.path === PAGE_PATH_404) { + if (to.path === PAGE_PATH_404 || to.path === '/survey/fill') { next(); return; } diff --git a/smart-flow-web/src/views/flow/definition/definition-form.vue b/smart-flow-web/src/views/flow/definition/definition-form.vue index 856bcdb..c21d7ab 100644 --- a/smart-flow-web/src/views/flow/definition/definition-form.vue +++ b/smart-flow-web/src/views/flow/definition/definition-form.vue @@ -57,8 +57,7 @@ :tree-data="categoryList" :field-names="{ value: 'id', label: 'name', children: 'children' }" placeholder="请选择流程类别" - tree-checkable - tree-check-strictly + allow-clear style="width: 100%" /> @@ -73,8 +72,7 @@ :tree-data="formPathList" :field-names="{ value: 'id', label: 'name', children: 'children' }" placeholder="请选择自定义表单" - tree-checkable - tree-check-strictly + allow-clear style="width: 100%" /> diff --git a/smart-flow-web/src/views/jwpy/jwpy/flow/components/BizClassificationForm.vue b/smart-flow-web/src/views/jwpy/jwpy/flow/components/BizClassificationForm.vue index 0ee8c6b..76a4076 100644 --- a/smart-flow-web/src/views/jwpy/jwpy/flow/components/BizClassificationForm.vue +++ b/smart-flow-web/src/views/jwpy/jwpy/flow/components/BizClassificationForm.vue @@ -138,6 +138,9 @@ const props = defineProps({ border: 1px solid #e2e8f0 !important; border-radius: 0 !important; } +:deep(.ant-descriptions-view table) { + table-layout: fixed !important; +} :deep(.ant-descriptions-row) { border-bottom: 1px solid #f1f5f9 !important; @@ -221,19 +224,49 @@ const props = defineProps({ border-color: #cbd5e1 !important; } -/* 错误红字绝对定位浮动,防止撑开网格高度 */ +/* 方案一:高级红色气泡悬浮提示效果(仅在悬停或聚焦时浮现) */ :deep(.ant-form-item-control) { position: relative !important; } :deep(.ant-form-item-explain) { position: absolute !important; - bottom: -4px !important; + bottom: 28px !important; left: 10px !important; - z-index: 10 !important; + z-index: 1000 !important; + opacity: 0; + pointer-events: none; + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); + + width: max-content !important; /* 宽度随字数自适应,不拉长 */ font-size: 11px !important; - color: #ef4444 !important; - line-height: 1 !important; - background: #ffffff !important; - padding: 0 4px !important; + color: #ffffff !important; + background: #f87171 !important; /* 柔和红 */ + padding: 3px 8px !important; + border-radius: 4px !important; + box-shadow: 0 4px 10px rgba(239, 68, 68, 0.2) !important; + white-space: nowrap !important; + line-height: 1.4 !important; +} +:deep(.ant-form-item-explain-error) { + color: #ffffff !important; /* 强制覆盖 Antd 默认的红色字,防止红底红字看不清 */ +} +/* 气泡小箭头 */ +:deep(.ant-form-item-explain)::after { + content: ''; + position: absolute; + bottom: -4px; + left: 15px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #f87171; +} +/* 触发显示状态 */ +:deep(.ant-form-item-has-error:hover .ant-form-item-explain), +:deep(.ant-form-item-has-error:focus-within .ant-form-item-explain) { + opacity: 1; + bottom: 34px !important; + pointer-events: auto; } diff --git a/smart-flow-web/src/views/jwpy/jwpy/flow/components/CallerInfoForm.vue b/smart-flow-web/src/views/jwpy/jwpy/flow/components/CallerInfoForm.vue index 8b4e6ad..138b8e3 100644 --- a/smart-flow-web/src/views/jwpy/jwpy/flow/components/CallerInfoForm.vue +++ b/smart-flow-web/src/views/jwpy/jwpy/flow/components/CallerInfoForm.vue @@ -118,6 +118,9 @@ const props = defineProps({ border: 1px solid #e2e8f0 !important; border-radius: 0 !important; } +:deep(.ant-descriptions-view table) { + table-layout: fixed !important; +} :deep(.ant-descriptions-row) { border-bottom: 1px solid #f1f5f9 !important; @@ -178,19 +181,49 @@ const props = defineProps({ border-color: #cbd5e1 !important; } -/* 错误红字绝对定位浮动,防止撑开网格高度 */ +/* 方案一:高级红色气泡悬浮提示效果(仅在悬停或聚焦时浮现) */ :deep(.ant-form-item-control) { position: relative !important; } :deep(.ant-form-item-explain) { position: absolute !important; - bottom: -4px !important; + bottom: 28px !important; left: 10px !important; - z-index: 10 !important; + z-index: 1000 !important; + opacity: 0; + pointer-events: none; + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); + + width: max-content !important; /* 宽度随字数自适应,不拉长 */ font-size: 11px !important; - color: #ef4444 !important; - line-height: 1 !important; - background: #ffffff !important; - padding: 0 4px !important; + color: #ffffff !important; + background: #f87171 !important; /* 柔和红 */ + padding: 3px 8px !important; + border-radius: 4px !important; + box-shadow: 0 4px 10px rgba(239, 68, 68, 0.2) !important; + white-space: nowrap !important; + line-height: 1.4 !important; +} +:deep(.ant-form-item-explain-error) { + color: #ffffff !important; /* 强制覆盖 Antd 默认的红色字,防止红底红字看不清 */ +} +/* 气泡小箭头 */ +:deep(.ant-form-item-explain)::after { + content: ''; + position: absolute; + bottom: -4px; + left: 15px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #f87171; +} +/* 触发显示状态 */ +:deep(.ant-form-item-has-error:hover .ant-form-item-explain), +:deep(.ant-form-item-has-error:focus-within .ant-form-item-explain) { + opacity: 1; + bottom: 34px !important; + pointer-events: auto; } diff --git a/smart-flow-web/src/views/jwpy/jwpy/flow/components/InvolvedTargetForm.vue b/smart-flow-web/src/views/jwpy/jwpy/flow/components/InvolvedTargetForm.vue index 15cda07..37bf47e 100644 --- a/smart-flow-web/src/views/jwpy/jwpy/flow/components/InvolvedTargetForm.vue +++ b/smart-flow-web/src/views/jwpy/jwpy/flow/components/InvolvedTargetForm.vue @@ -13,16 +13,19 @@ > - + + {{ formData.sjjzMc || '-' }} + + - + + {{ formData.sfsjfj == 2 ? '辅警' : (formData.sfsjfj == 1 ? '民警' : '-') }} + + 民警 辅警 @@ -45,13 +52,15 @@ - + {{ formData.sjfjxm || '-' }} + - + {{ formData.sjfjjh || '-' }} + @@ -63,6 +72,7 @@ @@ -115,6 +129,9 @@ const props = defineProps({ border: 1px solid #e2e8f0 !important; border-radius: 0 !important; } +:deep(.ant-descriptions-view table) { + table-layout: fixed !important; +} :deep(.ant-descriptions-row) { border-bottom: 1px solid #f1f5f9 !important; @@ -175,19 +192,49 @@ const props = defineProps({ border-color: #cbd5e1 !important; } -/* 错误红字绝对定位浮动,防止撑开网格高度 */ +/* 方案一:高级红色气泡悬浮提示效果(仅在悬停或聚焦时浮现) */ :deep(.ant-form-item-control) { position: relative !important; } :deep(.ant-form-item-explain) { position: absolute !important; - bottom: -4px !important; + bottom: 28px !important; left: 10px !important; - z-index: 10 !important; + z-index: 1000 !important; + opacity: 0; + pointer-events: none; + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); + + width: max-content !important; /* 宽度随字数自适应,不拉长 */ font-size: 11px !important; - color: #ef4444 !important; - line-height: 1 !important; - background: #ffffff !important; - padding: 0 4px !important; + color: #ffffff !important; + background: #f87171 !important; /* 柔和红 */ + padding: 3px 8px !important; + border-radius: 4px !important; + box-shadow: 0 4px 10px rgba(239, 68, 68, 0.2) !important; + white-space: nowrap !important; + line-height: 1.4 !important; +} +:deep(.ant-form-item-explain-error) { + color: #ffffff !important; /* 强制覆盖 Antd 默认的红色字,防止红底红字看不清 */ +} +/* 气泡小箭头 */ +:deep(.ant-form-item-explain)::after { + content: ''; + position: absolute; + bottom: -4px; + left: 15px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #f87171; +} +/* 触发显示状态 */ +:deep(.ant-form-item-has-error:hover .ant-form-item-explain), +:deep(.ant-form-item-has-error:focus-within .ant-form-item-explain) { + opacity: 1; + bottom: 34px !important; + pointer-events: auto; } diff --git a/smart-flow-web/src/views/jwpy/jwpy/flow/index.vue b/smart-flow-web/src/views/jwpy/jwpy/flow/index.vue index dcc3ec1..6ed929e 100644 --- a/smart-flow-web/src/views/jwpy/jwpy/flow/index.vue +++ b/smart-flow-web/src/views/jwpy/jwpy/flow/index.vue @@ -21,8 +21,8 @@ - 查询 - 重置 + 查询 + 重置 @@ -30,14 +30,14 @@
- + 新建工单 @@ -56,30 +56,35 @@ :loading="tableLoading" :pagination="false" :row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }" + :scroll="{ x: 1500 }" class="custom-table" >