| | |
| | | <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="delFlag" column="del_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" /> |
| | | <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="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="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, del_flag, create_by, create_time, update_by, update_time, remark |
| | | select user_id, username, phone, password, nickname, avatar, gender, birthday, status, |
| | | system_level, subject_type, 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, |
| | | del_flag, provider_flag, create_by, create_time, update_by, update_time, remark |
| | | from account_user |
| | | </sql> |
| | | |
| | |
| | | <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="phone != null and phone != ''"> and phone like concat('%', #{phone}, '%')</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 date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d') |
| | | and create_time >= #{params.beginTime} |
| | | </if> |
| | | <if test="params.endTime != null and params.endTime != ''"> |
| | | and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d') |
| | | and create_time < date_add(#{params.endTime}, interval 1 day) |
| | | </if> |
| | | </where> |
| | | order by user_id desc |
| | |
| | | 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="gender != null and gender != ''">gender,</if> |
| | | <if test="birthday != null">birthday,</if> |
| | | <if test="status != null and status != ''">status,</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 |
| | |
| | | <if test="gender != null and gender != ''">#{gender},</if> |
| | | <if test="birthday != null">#{birthday},</if> |
| | | <if test="status != null and status != ''">#{status},</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() |
| | |
| | | <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="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> |
| | | |
| | | <!-- |
| | | 服务商标识专用:与 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' |
| | |
| | | </foreach> |
| | | </update> |
| | | |
| | | <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> |