<?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.user.mapper.AccountUserMapper">
|
|
<resultMap type="AccountUser" id="AccountUserResult">
|
<id property="userId" column="user_id" />
|
<result property="userName" column="username" />
|
<result property="phone" column="phone" />
|
<result property="password" column="password" />
|
<result property="nickname" column="nickname" />
|
<result property="avatar" column="avatar" />
|
<result property="gender" column="gender" />
|
<result property="birthday" column="birthday" />
|
<result property="status" column="status" />
|
<result property="systemLevel" column="system_level" />
|
<result property="subjectType" column="subject_type" />
|
<result property="authStatus" column="auth_status" />
|
<result property="companyAuthStatus" column="company_auth_status" />
|
<result property="city" column="city" />
|
<result property="referrerId" column="referrer_id" />
|
<result property="referrerBindTime" column="referrer_bind_time" />
|
<result property="supplierId" column="supplier_id" />
|
<result property="supplierBindTime" column="supplier_bind_time" />
|
<result property="buyOrderCount" column="buy_order_count" />
|
<result property="buyAmountTotal" column="buy_amount_total" />
|
<result property="sellOrderCount" column="sell_order_count" />
|
<result property="sellAmountTotal" column="sell_amount_total" />
|
<result property="purchaseOrderCount" column="purchase_order_count" />
|
<result property="purchaseAmountTotal" column="purchase_amount_total" />
|
<result property="sellProfitTotal" column="sell_profit_total" />
|
<result property="virtualStockQty" column="virtual_stock_qty" />
|
<result property="virtualStockValue" column="virtual_stock_value" />
|
<result property="delFlag" column="del_flag" />
|
<result property="myReferralCode" column="my_referral_code" />
|
<result property="providerFlag" column="provider_flag" />
|
<result property="createBy" column="create_by" />
|
<result property="createTime" column="create_time" />
|
<result property="updateBy" column="update_by" />
|
<result property="updateTime" column="update_time" />
|
<result property="remark" column="remark" />
|
</resultMap>
|
|
<!-- 详情专用:在 AccountUserResult 基础上追加推荐人/供货人的派生列 -->
|
<resultMap type="AccountUserVo" id="AccountUserVoResult" extends="AccountUserResult">
|
<result property="referrerPhone" column="referrer_phone" />
|
<result property="referrerLevel" column="referrer_level" />
|
<result property="referrerNickname" column="referrer_nickname" />
|
<result property="supplierPhone" column="supplier_phone" />
|
<result property="supplierLevel" column="supplier_level" />
|
<result property="supplierNickname" column="supplier_nickname" />
|
</resultMap>
|
|
<sql id="selectAccountUserVo">
|
select user_id, username, phone, password, nickname, avatar, gender, birthday, status,
|
system_level, subject_type, auth_status, company_auth_status, city,
|
referrer_id, referrer_bind_time, supplier_id, supplier_bind_time,
|
buy_order_count, buy_amount_total, sell_order_count, sell_amount_total,
|
purchase_order_count, purchase_amount_total, sell_profit_total,
|
virtual_stock_qty, virtual_stock_value,my_referral_code,
|
del_flag, provider_flag, create_by, create_time, update_by, update_time, remark
|
from account_user
|
</sql>
|
|
<select id="selectAccountUserList" parameterType="AccountUser" resultMap="AccountUserResult">
|
<include refid="selectAccountUserVo"/>
|
<where>
|
del_flag = '0'
|
<if test="userId != null"> and user_id = #{userId}</if>
|
<!-- 手机号按完整号码精确匹配:列表筛选是「用户手机」,C 端按全号检索是常态;
|
且 like '%x%' 的前缀通配会让 idx_account_user_phone 完全失效。 -->
|
<if test="phone != null and phone != ''"> and phone = #{phone}</if>
|
<if test="userName != null and userName != ''"> and username like concat('%', #{userName}, '%')</if>
|
<if test="nickname != null and nickname != ''"> and nickname like concat('%', #{nickname}, '%')</if>
|
<if test="gender != null and gender != ''"> and gender = #{gender}</if>
|
<if test="status != null and status != ''"> and status = #{status}</if>
|
<if test="systemLevel != null and systemLevel != ''"> and system_level = #{systemLevel}</if>
|
<if test="authStatus != null and authStatus != ''"> and auth_status = #{authStatus}</if>
|
<if test="subjectType != null and subjectType != ''"> and subject_type = #{subjectType}</if>
|
<!-- 城市按名称精确匹配,选项来自 account_city 的启用城市:
|
城市表按「省 + 市」两列存,但会员表只有 city(市级、无省份),故筛选口径就是市名。
|
原先那套「只选省时把该省全部市名拼成 IN」的逻辑随城市主数据扁平化一起去掉了。 -->
|
<if test="city != null and city != ''"> and city = #{city}</if>
|
<!-- 时间范围必须是 sargable 写法:原来的 date_format(create_time,'%y%m%d') 把列包在函数里,
|
create_time 上的索引用不上,数据量上来后是全表扫。 -->
|
<if test="params.beginTime != null and params.beginTime != ''">
|
and create_time >= #{params.beginTime}
|
</if>
|
<if test="params.endTime != null and params.endTime != ''">
|
and create_time < date_add(#{params.endTime}, interval 1 day)
|
</if>
|
</where>
|
order by user_id desc
|
</select>
|
|
<select id="selectAccountUserById" parameterType="Long" resultMap="AccountUserResult">
|
<include refid="selectAccountUserVo"/>
|
where del_flag = '0' and user_id = #{userId}
|
</select>
|
|
<select id="selectAccountUserByUsername" parameterType="String" resultMap="AccountUserResult">
|
<include refid="selectAccountUserVo"/>
|
where del_flag = '0' and username = #{userName}
|
</select>
|
|
<select id="selectAccountUserByPhone" parameterType="String" resultMap="AccountUserResult">
|
<include refid="selectAccountUserVo"/>
|
where del_flag = '0' and phone = #{phone}
|
</select>
|
|
<!--
|
详情查询:会员本体 + 推荐人/供货人的手机号、等级、昵称。
|
两次自连接都走 user_id 主键,成本极低。
|
条件里的 del_flag = '0' 不可省:推荐人可能已被逻辑删除(造数脚本的 user_id=125
|
引用已删除的 124 就是这种边界行),漏掉它会关联出已删除用户的信息。
|
仅供详情使用——列表带分页,挂 join 会干扰 PageHelper 的 count SQL。
|
-->
|
<select id="selectAccountUserVoById" parameterType="Long" resultMap="AccountUserVoResult">
|
select u.*,
|
r.phone as referrer_phone,
|
r.system_level as referrer_level,
|
r.nickname as referrer_nickname,
|
s.phone as supplier_phone,
|
s.system_level as supplier_level,
|
s.nickname as supplier_nickname
|
from account_user u
|
left join account_user r on r.user_id = u.referrer_id and r.del_flag = '0'
|
left join account_user s on s.user_id = u.supplier_id and s.del_flag = '0'
|
where u.del_flag = '0' and u.user_id = #{userId}
|
</select>
|
|
<insert id="insertAccountUser" parameterType="AccountUser" useGeneratedKeys="true" keyProperty="userId">
|
insert into account_user(
|
<if test="userName != null and userName != ''">username,</if>
|
<if test="phone != null and phone != ''">phone,</if>
|
<if test="password != null and password != ''">password,</if>
|
<if test="nickname != null and nickname != ''">nickname,</if>
|
<if test="avatar != null and avatar != ''">avatar,</if>
|
<if test="gender != null and gender != ''">gender,</if>
|
<if test="birthday != null">birthday,</if>
|
<if test="status != null and status != ''">status,</if>
|
<if test="myReferralCode != null and myReferralCode != ''">my_referral_code,</if>
|
<if test="systemLevel != null and systemLevel != ''">system_level,</if>
|
<if test="subjectType != null and subjectType != ''">subject_type,</if>
|
<if test="authStatus != null and authStatus != ''">auth_status,</if>
|
<if test="city != null and city != ''">city,</if>
|
<if test="referrerId != null">referrer_id,</if>
|
<if test="referrerBindTime != null">referrer_bind_time,</if>
|
<if test="supplierId != null">supplier_id,</if>
|
<if test="supplierBindTime != null">supplier_bind_time,</if>
|
<if test="remark != null">remark,</if>
|
<if test="createBy != null and createBy != ''">create_by,</if>
|
create_time
|
)values(
|
<if test="userName != null and userName != ''">#{userName},</if>
|
<if test="phone != null and phone != ''">#{phone},</if>
|
<if test="password != null and password != ''">#{password},</if>
|
<if test="nickname != null and nickname != ''">#{nickname},</if>
|
<if test="avatar != null and avatar != ''">#{avatar},</if>
|
<if test="gender != null and gender != ''">#{gender},</if>
|
<if test="birthday != null">#{birthday},</if>
|
<if test="status != null and status != ''">#{status},</if>
|
<if test="myReferralCode != null and myReferralCode != ''">#{myReferralCode},</if>
|
|
<if test="systemLevel != null and systemLevel != ''">#{systemLevel},</if>
|
<if test="subjectType != null and subjectType != ''">#{subjectType},</if>
|
<if test="authStatus != null and authStatus != ''">#{authStatus},</if>
|
<if test="city != null and city != ''">#{city},</if>
|
<if test="referrerId != null">#{referrerId},</if>
|
<if test="referrerBindTime != null">#{referrerBindTime},</if>
|
<if test="supplierId != null">#{supplierId},</if>
|
<if test="supplierBindTime != null">#{supplierBindTime},</if>
|
<if test="remark != null">#{remark},</if>
|
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
sysdate()
|
)
|
</insert>
|
|
<update id="updateAccountUser" parameterType="AccountUser">
|
update account_user
|
<set>
|
<if test="userName != null and userName != ''">username = #{userName},</if>
|
<if test="phone != null and phone != ''">phone = #{phone},</if>
|
<if test="password != null and password != ''">password = #{password},</if>
|
<if test="nickname != null">nickname = #{nickname},</if>
|
<if test="avatar != null">avatar = #{avatar},</if>
|
<if test="gender != null and gender != ''">gender = #{gender},</if>
|
<if test="birthday != null">birthday = #{birthday},</if>
|
<if test="status != null and status != ''">status = #{status},</if>
|
<if test="myReferralCode != null and myReferralCode != ''">my_referral_code = #{myReferralCode},</if>
|
<if test="systemLevel != null and systemLevel != ''">system_level = #{systemLevel},</if>
|
<if test="subjectType != null and subjectType != ''">subject_type = #{subjectType},</if>
|
<if test="authStatus != null and authStatus != ''">auth_status = #{authStatus},</if>
|
<if test="city != null">city = #{city},</if>
|
<if test="referrerId != null">referrer_id = #{referrerId},</if>
|
<if test="referrerBindTime != null">referrer_bind_time = #{referrerBindTime},</if>
|
<if test="supplierId != null">supplier_id = #{supplierId},</if>
|
<if test="supplierBindTime != null">supplier_bind_time = #{supplierBindTime},</if>
|
<if test="remark != null">remark = #{remark},</if>
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!--
|
关系修改专用。不能复用 updateAccountUser:一是那里按 <if> 拼列,传不全也没问题,
|
但业务上不该允许借这个口子改别的字段;二是 Controller 侧的统一校验链路
|
(@NotBlank userName、用户名/手机号查重)会拦下只传关系的请求。
|
referrerId / supplierId 传 null 即为解除绑定(<set> 里直接赋值,不走 <if>)。
|
-->
|
<update id="updateUserRelation" parameterType="AccountUser">
|
update account_user
|
<set>
|
referrer_id = #{referrerId},
|
referrer_bind_time = #{referrerBindTime},
|
supplier_id = #{supplierId},
|
supplier_bind_time = #{supplierBindTime},
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!-- 状态变更专用:同上,避免与整体编辑共用校验链路 -->
|
<update id="updateUserStatus" parameterType="AccountUser">
|
update account_user
|
<set>
|
status = #{status},
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!-- 主体认证审核通过/驳回后回写认证状态,只动 auth_status 一列 -->
|
<update id="updateUserAuthStatus" parameterType="AccountUser">
|
update account_user
|
<set>
|
auth_status = #{authStatus},
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!--
|
企业/个体认证审核通过/驳回后回写,只动 company_auth_status 一列;
|
与 updateUserAuthStatus 分开是因为企业认证状态与个人认证状态是两列,不能互相覆盖。
|
审核通过时服务层把 subjectType 一起带上(=2/3),此处 <if> 才写 subject_type;
|
驳回时服务层不传 subjectType,列保持不变——否则会把未通过审核的会员标成企业主体。
|
-->
|
<update id="updateUserCompanyAuthStatus" parameterType="AccountUser">
|
update account_user
|
<set>
|
company_auth_status = #{companyAuthStatus},
|
<if test="subjectType != null and subjectType != ''">subject_type = #{subjectType},</if>
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!--
|
头像更新专用:只动 avatar 一列。绝不能挂到共享的 updateAccountUser 上——
|
那是后台编辑接口(/account/user)的入口,挂上去等于请求体带个 avatar 就能改任意会员头像。
|
与 updateUserStatus / updateUserAuthStatus 同一套路,头像只能由会员本人在 C 端接口里改写。
|
-->
|
<update id="updateUserAvatar" parameterType="AccountUser">
|
update account_user
|
<set>
|
avatar = #{avatar},
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!--
|
服务商标识专用:与 updateUserAuthStatus 同一个套路——别的模块要给会员打标识,
|
就单开一条只写该列的语句,绝不挂到共享的 insertAccountUser / updateAccountUser 上
|
(那两个按 <if> 拼列,挂上去等于 /account/user 的请求体里带个 providerFlag 就能自己打标)。
|
当前唯一调用方是服务商模块。
|
-->
|
<update id="updateUserProviderFlag" parameterType="AccountUser">
|
update account_user
|
<set>
|
provider_flag = #{providerFlag},
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
update_time = sysdate()
|
</set>
|
where user_id = #{userId} and del_flag = '0'
|
</update>
|
|
<!-- 逻辑删除:保留行,仅置删除标志 -->
|
<update id="deleteAccountUserById" parameterType="Long">
|
update account_user set del_flag = '2' where user_id = #{userId}
|
</update>
|
|
<update id="deleteAccountUserByIds" parameterType="Long">
|
update account_user set del_flag = '2' where user_id in
|
<foreach item="userId" collection="array" open="(" separator="," close=")">
|
#{userId}
|
</foreach>
|
</update>
|
|
<!--
|
「我邀请的」列表:按 referrer_id 过滤 + referrer_bind_time 倒序,命中 idx_account_user_referrer。
|
显式列出所需列(禁 SELECT *);不挂 join,避免干扰 PageHelper 的 count SQL。
|
referrer_bind_time 为空的历史行,MySQL 中 NULL 视为最小值,倒序时自然排在最后。
|
-->
|
<select id="selectInvitees" parameterType="Long" resultMap="AccountUserResult">
|
select user_id, nickname, avatar, phone, system_level, referrer_bind_time, buy_amount_total
|
from account_user
|
where del_flag = '0' and referrer_id = #{referrerId}
|
order by referrer_bind_time desc
|
</select>
|
|
<resultMap type="MemberOptionVo" id="MemberOptionVoResult">
|
<id property="userId" column="user_id" />
|
<result property="memberName" column="member_name" />
|
<result property="phone" column="phone" />
|
<result property="systemLevel" column="system_level" />
|
</resultMap>
|
|
<!--
|
城市公司档案表单的「关联用户信息」下拉:只搜 L4(档案的准入条件)。
|
显示名取认证表的真实姓名,无认证资料时回落昵称;两者都为空则前端按会员编号展示。
|
limit 20 是必要的:下拉是随打随搜的,不设上限等于把「输一个 1」变成全表 like。
|
该查询不分页,故 join 不会干扰 PageHelper 的 count SQL。
|
-->
|
<select id="selectL4MemberOptions" resultMap="MemberOptionVoResult">
|
select u.user_id, u.phone, u.system_level,
|
coalesce(nullif(cert.real_name, ''), u.nickname) as member_name
|
from account_user u
|
left join account_certification cert on cert.user_id = u.user_id and cert.del_flag = '0'
|
where u.del_flag = '0' and u.system_level = 'L4'
|
<if test="keyword != null and keyword != ''">
|
and (u.phone like concat('%', #{keyword}, '%')
|
or u.nickname like concat('%', #{keyword}, '%')
|
or cert.real_name like concat('%', #{keyword}, '%')
|
<if test="keywordId != null"> or u.user_id = #{keywordId}</if>)
|
</if>
|
order by u.user_id desc
|
limit 20
|
</select>
|
|
<!--
|
修改供货人的「新供货人」下拉:只搜等级严格高于该会员的会员。
|
levels 由服务层按 AccountUser.levelsAbove 算好,且必须非空——空集合会拼成
|
in () 的语法错误(该会员已是最高等级时服务层提前返回,走不到这条语句)。
|
|
其余口径刻意与 selectL4MemberOptions 保持一致:显示名取认证表真实姓名、无认证
|
回落昵称;手机号/昵称/姓名模糊 + 纯数字 keywordId 等值命中编号;limit 20 是必要的
|
(随打随搜不设上限,等于把「输一个 1」变成全表 like)。
|
user_id != #{userId} 既保证不自环,也顺带把会员自己从候选里摘掉。
|
-->
|
<select id="selectSupplierCandidates" resultMap="MemberOptionVoResult">
|
select u.user_id, u.phone, u.system_level,
|
coalesce(nullif(cert.real_name, ''), u.nickname) as member_name
|
from account_user u
|
left join account_certification cert on cert.user_id = u.user_id and cert.del_flag = '0'
|
where u.del_flag = '0'
|
and u.user_id != #{userId}
|
and u.system_level in
|
<foreach item="level" collection="levels" open="(" separator="," close=")">
|
#{level}
|
</foreach>
|
<if test="keyword != null and keyword != ''">
|
and (u.phone like concat('%', #{keyword}, '%')
|
or u.nickname like concat('%', #{keyword}, '%')
|
or cert.real_name like concat('%', #{keyword}, '%')
|
<if test="keywordId != null"> or u.user_id = #{keywordId}</if>)
|
</if>
|
order by u.user_id desc
|
limit 20
|
</select>
|
|
</mapper>
|