feat(publicity): 公示页支持/执行意向 (匿名提交 + 管理审核)

- 新增 biz_publicity_support_intent / biz_publicity_execution_intent 两张独立表
  (与已登录视角的 biz_support_intent / biz_execution_intent 解耦, 避免匿名数据污染强绑表)
- 后端 BizPublicityIntentController: 公开提交 + 公开查重 (按 project_id+phone+source) + 管理 CRUD
  已登录直接取 user_id, 未登录但 phone 命中 sys_user 仍自动关联 user_id (不回强制登录)
- /business/publicity/** 加 Spring Security permitAll
- 前端 PublicityDetail.vue: 右侧 2 个意向按钮 (已登录/匿名都弹 dialog 填 5 字段),
  已提交状态用 hasPublicityIntent 按 phonenumber 持久化查回
- 重写 manager/SupportIntent.vue + manager/ExecIntent.vue: 列表/筛选/CSV导出/状态变更/批量删除
This commit is contained in:
郭庆泰
2026-08-17 01:15:16 +08:00
parent a1c54842e2
commit b41cf77cac
16 changed files with 1168 additions and 42 deletions
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.business.mapper.BizPublicityExecutionIntentMapper">
<resultMap type="BizPublicityExecutionIntent" id="BizPublicityExecutionIntentResult">
<id property="intentId" column="intent_id" />
<result property="projectId" column="project_id" />
<result property="projectNo" column="project_no" />
<result property="projectName" column="project_name" />
<result property="userId" column="user_id" />
<result property="name" column="name" />
<result property="phone" column="phone" />
<result property="workUnit" column="work_unit" />
<result property="department" column="department" />
<result property="position" column="position" />
<result property="source" column="source" />
<result property="intentStatus" column="intent_status" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectFields">
select intent_id, project_id, project_no, project_name, user_id, name, phone, work_unit, department, position, source, intent_status, remark, create_by, create_time, update_by, update_time
from biz_publicity_execution_intent
</sql>
<select id="selectByPrimaryKey" resultMap="BizPublicityExecutionIntentResult" parameterType="Long">
<include refid="selectFields"/>
where intent_id = #{intentId}
</select>
<select id="selectList" resultMap="BizPublicityExecutionIntentResult" parameterType="BizPublicityExecutionIntent">
<include refid="selectFields"/>
<where>
<if test="projectId != null"> and project_id = #{projectId}</if>
<if test="projectNo != null and projectNo != ''"> and project_no = #{projectNo}</if>
<if test="projectName != null and projectName != ''"> and project_name like concat('%', #{projectName}, '%')</if>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="phone != null and phone != ''"> and phone = #{phone}</if>
<if test="workUnit != null and workUnit != ''"> and work_unit like concat('%', #{workUnit}, '%')</if>
<if test="intentStatus != null and intentStatus != ''"> and intent_status = #{intentStatus}</if>
<if test="source != null and source != ''"> and source = #{source}</if>
</where>
order by intent_id desc
</select>
<!-- 查重 -->
<select id="selectDuplicate" resultMap="BizPublicityExecutionIntentResult" parameterType="BizPublicityExecutionIntent">
<include refid="selectFields"/>
where project_id = #{projectId}
and phone = #{phone}
and source = #{source}
limit 1
</select>
<insert id="insert" parameterType="BizPublicityExecutionIntent" useGeneratedKeys="true" keyProperty="intentId">
insert into biz_publicity_execution_intent
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="intentId != null">intent_id,</if>
<if test="projectId != null">project_id,</if>
<if test="projectNo != null and projectNo != ''">project_no,</if>
<if test="projectName != null and projectName != ''">project_name,</if>
<if test="userId != null">user_id,</if>
<if test="name != null and name != ''">name,</if>
<if test="phone != null and phone != ''">phone,</if>
<if test="workUnit != null and workUnit != ''">work_unit,</if>
<if test="department != null and department != ''">department,</if>
<if test="position != null and position != ''">position,</if>
<if test="source != null and source != ''">source,</if>
<if test="intentStatus != null and intentStatus != ''">intent_status,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
create_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="intentId != null">#{intentId},</if>
<if test="projectId != null">#{projectId},</if>
<if test="projectNo != null and projectNo != ''">#{projectNo},</if>
<if test="projectName != null and projectName != ''">#{projectName},</if>
<if test="userId != null">#{userId},</if>
<if test="name != null and name != ''">#{name},</if>
<if test="phone != null and phone != ''">#{phone},</if>
<if test="workUnit != null and workUnit != ''">#{workUnit},</if>
<if test="department != null and department != ''">#{department},</if>
<if test="position != null and position != ''">#{position},</if>
<if test="source != null and source != ''">#{source},</if>
<if test="intentStatus != null and intentStatus != ''">#{intentStatus},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
sysdate(),
</trim>
</insert>
<update id="updateByPrimaryKey" parameterType="BizPublicityExecutionIntent">
update biz_publicity_execution_intent
<trim prefix="SET" suffixOverrides=",">
<if test="intentStatus != null and intentStatus != ''">intent_status = #{intentStatus},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="name != null and name != ''">name = #{name},</if>
<if test="phone != null and phone != ''">phone = #{phone},</if>
<if test="workUnit != null and workUnit != ''">work_unit = #{workUnit},</if>
<if test="department != null">department = #{department},</if>
<if test="position != null">position = #{position},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate(),
</trim>
where intent_id = #{intentId}
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_publicity_execution_intent where intent_id = #{intentId}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="Long">
delete from biz_publicity_execution_intent where intent_id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.business.mapper.BizPublicitySupportIntentMapper">
<resultMap type="BizPublicitySupportIntent" id="BizPublicitySupportIntentResult">
<id property="intentId" column="intent_id" />
<result property="projectId" column="project_id" />
<result property="projectNo" column="project_no" />
<result property="projectName" column="project_name" />
<result property="userId" column="user_id" />
<result property="name" column="name" />
<result property="phone" column="phone" />
<result property="workUnit" column="work_unit" />
<result property="department" column="department" />
<result property="position" column="position" />
<result property="source" column="source" />
<result property="intentStatus" column="intent_status" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectFields">
select intent_id, project_id, project_no, project_name, user_id, name, phone, work_unit, department, position, source, intent_status, remark, create_by, create_time, update_by, update_time
from biz_publicity_support_intent
</sql>
<select id="selectByPrimaryKey" resultMap="BizPublicitySupportIntentResult" parameterType="Long">
<include refid="selectFields"/>
where intent_id = #{intentId}
</select>
<select id="selectList" resultMap="BizPublicitySupportIntentResult" parameterType="BizPublicitySupportIntent">
<include refid="selectFields"/>
<where>
<if test="projectId != null"> and project_id = #{projectId}</if>
<if test="projectNo != null and projectNo != ''"> and project_no = #{projectNo}</if>
<if test="projectName != null and projectName != ''"> and project_name like concat('%', #{projectName}, '%')</if>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="phone != null and phone != ''"> and phone = #{phone}</if>
<if test="workUnit != null and workUnit != ''"> and work_unit like concat('%', #{workUnit}, '%')</if>
<if test="intentStatus != null and intentStatus != ''"> and intent_status = #{intentStatus}</if>
<if test="source != null and source != ''"> and source = #{source}</if>
</where>
order by intent_id desc
</select>
<!-- 查重: 同一项目同一手机号同一来源只能提交一次 -->
<select id="selectDuplicate" resultMap="BizPublicitySupportIntentResult" parameterType="BizPublicitySupportIntent">
<include refid="selectFields"/>
where project_id = #{projectId}
and phone = #{phone}
and source = #{source}
limit 1
</select>
<insert id="insert" parameterType="BizPublicitySupportIntent" useGeneratedKeys="true" keyProperty="intentId">
insert into biz_publicity_support_intent
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="intentId != null">intent_id,</if>
<if test="projectId != null">project_id,</if>
<if test="projectNo != null and projectNo != ''">project_no,</if>
<if test="projectName != null and projectName != ''">project_name,</if>
<if test="userId != null">user_id,</if>
<if test="name != null and name != ''">name,</if>
<if test="phone != null and phone != ''">phone,</if>
<if test="workUnit != null and workUnit != ''">work_unit,</if>
<if test="department != null and department != ''">department,</if>
<if test="position != null and position != ''">position,</if>
<if test="source != null and source != ''">source,</if>
<if test="intentStatus != null and intentStatus != ''">intent_status,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
create_time,
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="intentId != null">#{intentId},</if>
<if test="projectId != null">#{projectId},</if>
<if test="projectNo != null and projectNo != ''">#{projectNo},</if>
<if test="projectName != null and projectName != ''">#{projectName},</if>
<if test="userId != null">#{userId},</if>
<if test="name != null and name != ''">#{name},</if>
<if test="phone != null and phone != ''">#{phone},</if>
<if test="workUnit != null and workUnit != ''">#{workUnit},</if>
<if test="department != null and department != ''">#{department},</if>
<if test="position != null and position != ''">#{position},</if>
<if test="source != null and source != ''">#{source},</if>
<if test="intentStatus != null and intentStatus != ''">#{intentStatus},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
sysdate(),
</trim>
</insert>
<update id="updateByPrimaryKey" parameterType="BizPublicitySupportIntent">
update biz_publicity_support_intent
<trim prefix="SET" suffixOverrides=",">
<if test="intentStatus != null and intentStatus != ''">intent_status = #{intentStatus},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="name != null and name != ''">name = #{name},</if>
<if test="phone != null and phone != ''">phone = #{phone},</if>
<if test="workUnit != null and workUnit != ''">work_unit = #{workUnit},</if>
<if test="department != null">department = #{department},</if>
<if test="position != null">position = #{position},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate(),
</trim>
where intent_id = #{intentId}
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_publicity_support_intent where intent_id = #{intentId}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="Long">
delete from biz_publicity_support_intent where intent_id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>