From 57ca64b0f7e44fb8e48c12a916a3dc4e0a9de3cc Mon Sep 17 00:00:00 2001 From: Dftre <3066417822@qq.com> Date: Sun, 9 Jun 2024 11:54:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=82=AE=E7=AE=B1=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=AA=8C=E8=AF=81=E7=A0=81=E7=9A=84=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/application-middleware.yml | 8 - .../src/main/resources/application-oauth.yml | 8 + .../src/main/resources/application.yml | 7 + ruoyi-oauth/ruoyi-oauth-email/pom.xml | 18 +- .../email/controller/MailController.java | 19 ++ .../oauth/email/service/IMailService.java | 7 + .../email/service/impl/MailServiceImpl.java | 153 ++++++++++++ .../oauth/phone/service/DySmsService.java | 11 +- .../phone/service/Impl/DySmsServiceImpl.java | 4 +- .../pay/sqb/service/Impl/SQBServiceImpl.java | 2 + .../ruoyi/system/mapper/SysUserMapper.java | 15 +- .../ruoyi/system/service/ISysUserService.java | 8 + .../service/impl/SysUserServiceImpl.java | 13 +- .../resources/mapper/system/SysUserMapper.xml | 223 +++++++++--------- 14 files changed, 361 insertions(+), 135 deletions(-) create mode 100644 ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/controller/MailController.java create mode 100644 ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/IMailService.java create mode 100644 ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/impl/MailServiceImpl.java diff --git a/ruoyi-admin/src/main/resources/application-middleware.yml b/ruoyi-admin/src/main/resources/application-middleware.yml index 674ce2b..118ed25 100644 --- a/ruoyi-admin/src/main/resources/application-middleware.yml +++ b/ruoyi-admin/src/main/resources/application-middleware.yml @@ -1,12 +1,4 @@ spring: - cache: - redis: - # 指定存活时间(ms) - time-to-live: 86400000 - # 指定前缀 - use-key-prefix: true - # 是否缓存空值,可以防止缓存穿透 - cache-null-values: true data: # redis 配置 redis: diff --git a/ruoyi-admin/src/main/resources/application-oauth.yml b/ruoyi-admin/src/main/resources/application-oauth.yml index 764c5e1..1049064 100644 --- a/ruoyi-admin/src/main/resources/application-oauth.yml +++ b/ruoyi-admin/src/main/resources/application-oauth.yml @@ -16,3 +16,11 @@ oauth: dysms: appId: appId appSecret: appSecret + +spring: + mail: + host: smtp.qq.com + # 邮箱地址 + username: username + # 授权码 + password: password diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3f7998d..7cb7c8a 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -50,6 +50,13 @@ spring: cache: # 指定缓存类型 jcache 本地缓存 redis 缓存 type: redis + redis: + # 指定存活时间(ms) + time-to-live: 86400000 + # 指定前缀 + use-key-prefix: true + # 是否缓存空值,可以防止缓存穿透 + cache-null-values: true mvc: pathmatch: matching-strategy: ANT_PATH_MATCHER diff --git a/ruoyi-oauth/ruoyi-oauth-email/pom.xml b/ruoyi-oauth/ruoyi-oauth-email/pom.xml index 8bf344e..7d4d10e 100644 --- a/ruoyi-oauth/ruoyi-oauth-email/pom.xml +++ b/ruoyi-oauth/ruoyi-oauth-email/pom.xml @@ -1,7 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> ruoyi-oauth com.ruoyi @@ -22,6 +21,21 @@ com.ruoyi ruoyi-oauth-common + + org.springframework.boot + spring-boot-starter-mail + + + + jakarta.mail + jakarta.mail-api + 1.6.7 + + + com.sun.mail + jakarta.mail + 1.6.7 + diff --git a/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/controller/MailController.java b/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/controller/MailController.java new file mode 100644 index 0000000..cfeacee --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/controller/MailController.java @@ -0,0 +1,19 @@ +package com.ruoyi.oauth.email.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.oauth.email.service.IMailService; + +@RestController +@Anonymous +@RequestMapping("/mail") +public class MailController extends BaseController { + + @Autowired + IMailService serviceImpl; + +} diff --git a/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/IMailService.java b/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/IMailService.java new file mode 100644 index 0000000..3317426 --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/IMailService.java @@ -0,0 +1,7 @@ +package com.ruoyi.oauth.email.service; + +import com.ruoyi.oauth.common.service.OauthVerificationCodeService; + +public interface IMailService extends OauthVerificationCodeService { + public boolean sendMimeMail(String email, String code); +} diff --git a/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/impl/MailServiceImpl.java b/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/impl/MailServiceImpl.java new file mode 100644 index 0000000..a830133 --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-email/src/main/java/com/ruoyi/oauth/email/service/impl/MailServiceImpl.java @@ -0,0 +1,153 @@ +package com.ruoyi.oauth.email.service.impl; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.stereotype.Service; + +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.CacheUtils; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.framework.web.service.UserDetailsServiceImpl; +import com.ruoyi.oauth.common.enums.OauthVerificationUse; +import com.ruoyi.oauth.email.service.IMailService; +import com.ruoyi.system.service.ISysUserService; + +@Service +public class MailServiceImpl implements IMailService { + + public String CACHE_NAME = "mail_codes"; + + @Autowired + private JavaMailSenderImpl mailSender; + @Autowired + private ISysUserService userService; + @Autowired + private TokenService tokenService; + @Autowired + private UserDetailsServiceImpl userDetailsServiceImpl; + private static final Logger log = LoggerFactory.getLogger(MailServiceImpl.class); + // application.properties配置的值 + @Value("${spring.mail.username}") + private String from; + + public boolean beforeSendCode(String email, OauthVerificationUse use) throws Exception {// 1.查验手机号是否存在,分辨登录和删除用户以及注册用户 + boolean haveEmailFlag = userService.selectUserByEmail(email) != null; + if ((use.equals(OauthVerificationUse.LOGIN) || use.equals(OauthVerificationUse.DISABLE) + || use.equals(OauthVerificationUse.RESET_PASSWORD)) && !haveEmailFlag) { + throw new ServiceException("该邮箱未绑定用户"); + } else if ((use.equals(OauthVerificationUse.REGISTER) || use.equals(OauthVerificationUse.RESET_PHONE)) + && haveEmailFlag) { + throw new ServiceException("该邮箱已绑定用户"); + } + return true; + } + + /** + * 给前端输入的邮箱,发送验证码 + * + * @param email + * @param session + * @return + */ + @Override + public boolean sendMimeMail(String email, String code) { + try { + SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); + simpleMailMessage.setSubject("验证码邮件"); // 主题 + simpleMailMessage.setText("您收到的验证码是:" + code); // 内容 + simpleMailMessage.setFrom(from); // 发件人 + simpleMailMessage.setTo(email); // 收件人 + mailSender.send(simpleMailMessage); // 发送 + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 随机生成6位数的验证码 + * + * @return String code + */ + public static String generateRandomString(int n) { + String characters = "0123456789"; // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz + StringBuilder result = new StringBuilder(); + Random random = new Random(); + + for (int i = 0; i < n; i++) { + int index = random.nextInt(characters.length()); + result.append(characters.charAt(index)); + } + + return result.toString(); + } + + @Override + public boolean sendCode(String email, String code, OauthVerificationUse use) throws Exception { + // 限制短信一分钟只能发送一次短信 + if (CacheUtils.hasKey(CACHE_NAME, email + use.getValue())) { + throw new ServiceException("请在1分钟后再发送短信"); + } + + try { + sendMimeMail(email, code); + CacheUtils.put(CACHE_NAME, email + use.getValue(), code, 1, TimeUnit.MINUTES); + log.info("发送邮箱验证码成功:{ phone: " + email + " code:" + code + "}"); + return true; + } catch (Exception e) { + log.error("发送邮箱验证码异常:" + email); + throw e; + } + } + + @Override + public String checkCode(String email, String code, OauthVerificationUse use) throws Exception { + String cachedCode = CacheUtils.get(use.getValue(), use.getValue() + email, String.class); // 从缓存中获取验证码 + CacheUtils.remove(use.getValue(), use.getValue() + email); + boolean haveEmailFlag = userService.selectUserByEmail(email) != null; + if (use.equals(OauthVerificationUse.LOGIN) && haveEmailFlag) {// 登录校验 + if (code.equals(cachedCode)) { + SysUser sysUser = userService.selectUserByEmail(email); + LoginUser loginUser = (LoginUser) userDetailsServiceImpl.createLoginUser(sysUser); + return tokenService.createToken(loginUser); + } else { + throw new ServiceException("验证码错误"); + } + } else if (use.equals(OauthVerificationUse.REGISTER) && !haveEmailFlag) {// 注册校验 + if (code.equals(cachedCode)) { + return Boolean.toString(true); + } else { + throw new ServiceException("验证码错误"); + } + } else if (use.equals(OauthVerificationUse.DISABLE) && haveEmailFlag) {// 注销校验 + if (code.equals(cachedCode)) { + return Boolean.toString(true); + } else { + throw new ServiceException("验证码错误"); + } + } else if (use.equals(OauthVerificationUse.RESET_PASSWORD) && haveEmailFlag) {// 重置密码校验 + if (code.equals(cachedCode)) { + return Boolean.toString(true); + } else { + throw new ServiceException("验证码错误"); + } + } else if (use.equals(OauthVerificationUse.RESET_PHONE) && !haveEmailFlag) {// 重置账号校验 + if (code.equals(cachedCode)) { + return Boolean.toString(true); + } else { + throw new ServiceException("验证码错误"); + } + } + return Boolean.toString(false); + } +} diff --git a/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/DySmsService.java b/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/DySmsService.java index 17d3943..065b675 100644 --- a/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/DySmsService.java +++ b/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/DySmsService.java @@ -1,6 +1,6 @@ package com.ruoyi.oauth.phone.service; -import com.ruoyi.oauth.common.enums.OauthVerificationUse; +import com.ruoyi.oauth.common.service.OauthVerificationCodeService; /** * 手机号认证Servcie @@ -8,14 +8,7 @@ import com.ruoyi.oauth.common.enums.OauthVerificationUse; * @author zlh * @date 2024-04-16 */ -public interface DySmsService { +public interface DySmsService extends OauthVerificationCodeService { public String doLogin(String phone); - public boolean sendCode(String phone, String code, OauthVerificationUse use) throws Exception; - - public String checkCode(String phone, String code, OauthVerificationUse use) throws Exception; - -// public String doenroll(String phone,String username, String password); - - } diff --git a/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java b/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java index 7b4ed65..ff32b7c 100644 --- a/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java +++ b/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java @@ -16,7 +16,6 @@ import com.ruoyi.common.utils.CacheUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.framework.web.service.UserDetailsServiceImpl; import com.ruoyi.oauth.common.enums.OauthVerificationUse; -import com.ruoyi.oauth.common.service.OauthVerificationCodeService; import com.ruoyi.oauth.phone.enums.DySmsTemplate; import com.ruoyi.oauth.phone.service.DySmsService; import com.ruoyi.oauth.phone.utils.DySmsUtil; @@ -29,7 +28,7 @@ import com.ruoyi.system.service.ISysUserService; * @date 2024-04-16 */ @Service -public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeService { +public class DySmsServiceImpl implements DySmsService { @Autowired private DySmsUtil dySmsUtil; @@ -79,6 +78,7 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ @Override public String checkCode(String phone, String code, OauthVerificationUse use) throws Exception { String cachedCode = CacheUtils.get(use.getValue(), use.getValue() + phone, String.class); // 从缓存中获取验证码 + CacheUtils.remove(use.getValue(), use.getValue() + phone); boolean havePhoneFlag = userService.selectUserByPhone(phone) != null; if (use.equals(OauthVerificationUse.LOGIN) && havePhoneFlag) {// 登录校验 if (code.equals(cachedCode)) { diff --git a/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/pay/sqb/service/Impl/SQBServiceImpl.java b/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/pay/sqb/service/Impl/SQBServiceImpl.java index 6d53480..e8da683 100644 --- a/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/pay/sqb/service/Impl/SQBServiceImpl.java +++ b/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/pay/sqb/service/Impl/SQBServiceImpl.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; import com.alibaba.fastjson2.JSON; @@ -22,6 +23,7 @@ import com.ruoyi.pay.domain.PayOrder; import com.ruoyi.pay.sqb.config.SqbConfig; @Service +@ConditionalOnProperty(prefix = "pay.sqb", name = "enabled", havingValue = "true") public class SQBServiceImpl { @Autowired private SqbConfig sqbConfig; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java index e8b1a90..776dbaf 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java @@ -11,8 +11,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; * * @author ruoyi */ -public interface SysUserMapper -{ +public interface SysUserMapper { /** * 根据条件分页查询用户列表 * @@ -56,11 +55,19 @@ public interface SysUserMapper /** * 通过手机号查询用户 * - * @param userId 用户ID + * @param phone 手机号 * @return 用户对象信息 */ public SysUser selectUserByPhone(String phone); + /** + * 通过邮箱查询用户 + * + * @param email 邮箱 + * @return 用户对象信息 + */ + public SysUser selectUserByEmail(String email); + /** * 新增用户信息 * @@ -81,7 +88,7 @@ public interface SysUserMapper * 修改用户头像 * * @param userName 用户名 - * @param avatar 头像地址 + * @param avatar 头像地址 * @return 结果 */ public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java index 9f9424f..8536209 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java @@ -58,6 +58,14 @@ public interface ISysUserService { */ public SysUser selectUserByPhone(String phone); + /** + * 通过邮箱查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByEmail(String email); + /** * 根据用户ID查询用户所属角色组 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 298290c..f3ecf44 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -124,7 +124,7 @@ public class SysUserServiceImpl implements ISysUserService { /** * 通过手机号查询用户 * - * @param userId 用户ID + * @param phone 用户ID * @return 用户对象信息 */ @Override @@ -132,6 +132,17 @@ public class SysUserServiceImpl implements ISysUserService { return userMapper.selectUserByPhone(phone); } + /** + * 通过邮箱查询用户 + * + * @param email 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByEmail(String email){ + return userMapper.selectUserByEmail(email); + } + /** * 查询用户所属角色组 * diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index dd4d0b9..65529c1 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -4,48 +4,48 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, @@ -54,9 +54,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join sys_dept d on u.dept_id = d.dept_id left join sys_user_role ur on u.user_id = ur.user_id left join sys_role r on r.role_id = ur.role_id - - - select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u left join sys_dept d on u.dept_id = d.dept_id where u.del_flag = '0' @@ -72,10 +72,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND u.phonenumber like concat('%', #{phonenumber}, '%') - + AND date_format(u.create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d') - + AND date_format(u.create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d') @@ -84,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ${params.dataScope} - + - + - + - + - + + + - + - + - + insert into sys_user( - user_id, - dept_id, - user_name, - nick_name, - email, - avatar, - phonenumber, - sex, - password, - status, - create_by, - remark, + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, create_time )values( - #{userId}, - #{deptId}, - #{userName}, - #{nickName}, - #{email}, - #{avatar}, - #{phonenumber}, - #{sex}, - #{password}, - #{status}, - #{createBy}, - #{remark}, + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, sysdate() ) - + update sys_user - - dept_id = #{deptId}, - user_name = #{userName}, - nick_name = #{nickName}, - email = #{email}, - phonenumber = #{phonenumber}, - sex = #{sex}, - avatar = #{avatar}, - password = #{password}, - status = #{status}, - login_ip = #{loginIp}, - login_date = #{loginDate}, - update_by = #{updateBy}, - remark = #{remark}, + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, update_time = sysdate() - + where user_id = #{userId} - + update sys_user set status = #{status} where user_id = #{userId} - + update sys_user set avatar = #{avatar} where user_name = #{userName} - + update sys_user set password = #{password} where user_name = #{userName} - + update sys_user set del_flag = '2' where user_id = #{userId} - - - + + + update sys_user set del_flag = '2' where user_id in - + #{userId} - - - + + + \ No newline at end of file