diff --git a/pom.xml b/pom.xml index 906a5bc..35b33b5 100644 --- a/pom.xml +++ b/pom.xml @@ -215,6 +215,14 @@ 4.4.13 + + + + com.github.binarywang + weixin-java-miniapp + 4.6.0 + + diff --git a/sql/data.sql b/sql/data.sql index 59635b3..a8b7120 100644 --- a/sql/data.sql +++ b/sql/data.sql @@ -26,4 +26,9 @@ insert into "FXKH_TXL"."ADDRESS_BOOK"("NAME", "PHONE", "ORGANIZATION", "POSITION alter table "FXKH_TXL"."AB_INFO" add column("ADCD" VARCHAR(50)); - comment on column "FXKH_TXL"."AB_INFO"."ADCD" is '行政区划'; \ No newline at end of file + comment on column "FXKH_TXL"."AB_INFO"."ADCD" is '行政区划'; + +alter table "FXKH_TXL"."ADDRESS_BOOK" add column("IS_PASS" TINYINT default (FALSE)); + +comment on column "FXKH_TXL"."ADDRESS_BOOK"."IS_PASS" is '是否放行, 放行:true,拦截:false'; + diff --git a/src/main/java/com/whdc/config/WxMiniappConfiguration.java b/src/main/java/com/whdc/config/WxMiniappConfiguration.java new file mode 100644 index 0000000..abae8be --- /dev/null +++ b/src/main/java/com/whdc/config/WxMiniappConfiguration.java @@ -0,0 +1,56 @@ +package com.whdc.config; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import lombok.Data; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Description: + * Created by XuSan on 2024/6/3. + * 微信小程序 配置 + * + * @author XuSan + * @version 1.0 + */ +@Data +@Configuration +@ConditionalOnClass(WxMaService.class) +@ConfigurationProperties(prefix = "wx.miniapp.configs") +public class WxMiniappConfiguration { + /** + * 设置微信小程序的appId + */ + + private String appId; + + /** + * 设置微信小程序的Secret + */ + + private String secret; + + @Bean + @ConditionalOnMissingBean(WxMaService.class) + public WxMaService wxMaService() { + + WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); + + config.setAppid(this.getAppId()); + + config.setSecret(this.getSecret()); + + WxMaService service = new WxMaServiceImpl(); + + service.setWxMaConfig(config); + + return service; + + } + +} \ No newline at end of file diff --git a/src/main/java/com/whdc/controller/AddressBookController.java b/src/main/java/com/whdc/controller/AddressBookController.java index d0b4aad..c4921bb 100644 --- a/src/main/java/com/whdc/controller/AddressBookController.java +++ b/src/main/java/com/whdc/controller/AddressBookController.java @@ -403,6 +403,45 @@ public class AddressBookController { } + + @ApiOperation(value = "设置白名单") + @PostMapping(value = "setWhitelists") + public ResultJson setWhitelists(@RequestBody @Validated(Update.class) AddressBook model) { + + Integer loginId = Integer.valueOf(String.valueOf(StpUtil.getLoginId())); + User user = userService.getRole(loginId); + + switch (Objects.requireNonNull(Role.getByName(user.getRole()))) { + case R000: + case R001: + return ResultJson.error("权限不足"); + case R099: { + break; + } + default: + return ResultJson.error("权限不足!!"); + } + + AddressBook byId = service.getById(model.getId()); + if (Objects.isNull(byId)) { + return ResultJson.error("当前数据不存在"); + } + + byId.setIsPass(model.getIsPass()); + versionsService.saveInfo(model, VersionsType.WHITE, byId.getAdcd()); + + + boolean update = service.lambdaUpdate() + .set(AddressBook::getIsPass, model.getIsPass()) + .eq(AddressBook::getId, model.getId()) + .update(); + if (!update){ + throw new MyException("操作数据库失败"); + } + return ResultJson.ok(update); + } + + @ApiOperation(value = "删除") @GetMapping(value = "del/{id}") @CacheEvict(value = ADDRESS_BOOK_REDIS_KEY, allEntries = true) diff --git a/src/main/java/com/whdc/controller/AdinfoController.java b/src/main/java/com/whdc/controller/AdinfoController.java index feb09aa..b855b61 100644 --- a/src/main/java/com/whdc/controller/AdinfoController.java +++ b/src/main/java/com/whdc/controller/AdinfoController.java @@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -86,9 +87,21 @@ public class AdinfoController { // 确保查的是县 List list = service.lambdaQuery() - .likeRight(Adinfo::getAdcd, adcd.replace("00000000000", "")) - .likeLeft(Adinfo::getAdcd, "000000000") + .likeRight(Adinfo::getAdcd, adcd.substring(0,4)) + .ne(Adinfo::getAdcd,adcd.substring(0,4) + "00000000000") .list(); + if (CollectionUtils.isNotEmpty(list)){ + return ResultJson.ok(list.stream().map(ad -> { + if ("市辖区".equals(ad.getAdnm())){ + Adinfo adinfo = service.lambdaQuery().eq(Adinfo::getAdcd, ad.getAdcd().substring(0, 4) + "00000000000") + .one(); + if (Objects.nonNull(adinfo)){ + ad.setAdnm(adinfo.getAdnm()); + } + } + return ad; + }).sorted(Comparator.comparing(Adinfo::getAdcd)).collect(Collectors.toList())); + } return ResultJson.ok(list); } diff --git a/src/main/java/com/whdc/controller/UserController.java b/src/main/java/com/whdc/controller/UserController.java index 033d1cc..15fea4f 100644 --- a/src/main/java/com/whdc/controller/UserController.java +++ b/src/main/java/com/whdc/controller/UserController.java @@ -4,13 +4,13 @@ package com.whdc.controller; import cn.dev33.satoken.stp.StpUtil; import com.whdc.model.dto.LoginDto; import com.whdc.model.dto.UserDto; +import com.whdc.model.dto.VxLoginDto; import com.whdc.model.entity.User; import com.whdc.model.group.Insert; import com.whdc.model.group.Update; import com.whdc.model.vo.AuthToken; import com.whdc.model.vo.LoginVo; import com.whdc.service.IUserService; -import com.whdc.utils.HttpUtil; import com.whdc.service.impl.UserServiceImpl; import com.whdc.utils.ResultJson; import io.swagger.annotations.Api; @@ -23,7 +23,6 @@ import org.springframework.web.bind.annotation.*; import java.lang.reflect.InvocationTargetException; import java.util.Objects; -import java.util.UUID; import static com.whdc.service.impl.UserServiceImpl.getPassword; @@ -41,8 +40,8 @@ public class UserController { private IUserService service; - @ApiOperation(value = "登录", notes = "登录后,从 tokenInfo 中获取 token 相关信息。headers[tokenName] = tokenValue ") - @PostMapping("doLogin") +// @ApiOperation(value = "登录", notes = "登录后,从 tokenInfo 中获取 token 相关信息。headers[tokenName] = tokenValue ") +// @PostMapping("doLogin") public ResultJson doLogin(@RequestBody @Validated LoginDto obj) throws InvocationTargetException, IllegalAccessException { LoginVo loginVo = service.login(obj); @@ -60,6 +59,26 @@ public class UserController { } } + + @ApiOperation(value = "wx登录", notes = "登录后,从 tokenInfo 中获取 token 相关信息。headers[tokenName] = tokenValue ") + @PostMapping("wxLogin") + public ResultJson wxLogin(@RequestBody @Validated VxLoginDto obj) throws InvocationTargetException, IllegalAccessException { + LoginVo loginVo = service.wxLogin(obj); + + if (loginVo == null || loginVo.getId() == null) { + return ResultJson.error("登录失败"); + } else { + StpUtil.login(loginVo.getId()); // 使用 user id 登录 + // 获取 Token 相关参数 + loginVo.setTokenInfo(new AuthToken(StpUtil.getTokenInfo())); + + // 更新最后登录时间 + service.updateLastDate(loginVo.getId()); + + return ResultJson.ok(loginVo); + } + } + @ApiOperation(value = "查询登录状态") @PostMapping("isLogin") public ResultJson isLogin() { @@ -146,16 +165,16 @@ public class UserController { } - @ApiOperation(value = "修改密码") - @PostMapping(value = "updatePw") +// @ApiOperation(value = "修改密码") +// @PostMapping(value = "updatePw") public ResultJson updatePwd(@RequestBody UserDto dto) { return service.updatePwd(dto); } - @ApiOperation(value = "忘记密码") - @GetMapping(value = "forgotPassword/{username}") +// @ApiOperation(value = "忘记密码") +// @GetMapping(value = "forgotPassword/{username}") public ResultJson updatePwd(@PathVariable("username") String username) { User one = service.lambdaQuery().eq(User::getUsername, username) .one(); @@ -173,16 +192,16 @@ public class UserController { } - @ApiOperation(value = "发送验证码") - @GetMapping(value = "pushCode/{phone}") +// @ApiOperation(value = "发送验证码") +// @GetMapping(value = "pushCode/{phone}") public ResultJson pushCode(@PathVariable("phone") String phone) { return ResultJson.ok(service.pushCode(phone)); } - @ApiOperation(value = "手机验证码登录") - @GetMapping(value = "loginByCode/{phone}/{code}") +// @ApiOperation(value = "手机验证码登录") +// @GetMapping(value = "loginByCode/{phone}/{code}") public ResultJson loginByCode(@PathVariable("phone") String phone,@PathVariable("code") String code) throws InvocationTargetException, IllegalAccessException { LoginVo loginVo = service.loginByCode(phone, code.toUpperCase()); diff --git a/src/main/java/com/whdc/mapper/AddressBookMapper.java b/src/main/java/com/whdc/mapper/AddressBookMapper.java index 7a53351..3142aef 100644 --- a/src/main/java/com/whdc/mapper/AddressBookMapper.java +++ b/src/main/java/com/whdc/mapper/AddressBookMapper.java @@ -19,7 +19,7 @@ public interface AddressBookMapper extends BaseMapper { List find(@Param("dto") AddressBook dto); - List getListByAdnm(@Param("adnm") String adnm); + List getListByAdnm(@Param("adcd") String adcd); AddressBookVo getVoById(@Param("id") Integer id); } \ No newline at end of file diff --git a/src/main/java/com/whdc/model/dto/VxLoginDto.java b/src/main/java/com/whdc/model/dto/VxLoginDto.java new file mode 100644 index 0000000..f93a207 --- /dev/null +++ b/src/main/java/com/whdc/model/dto/VxLoginDto.java @@ -0,0 +1,22 @@ +package com.whdc.model.dto; + +import io.swagger.annotations.ApiParam; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; + +/** + * @author 李赛 + * @date 2022-07-01 1:21 + */ +@Data +public class VxLoginDto { + + @ApiParam(value = "微信编码") + @NotEmpty(message = "微信编码不能为空") + private String wxcode; + + @ApiParam(value = "手机编码") + @NotEmpty(message = "手机编码不能为空") + private String phoneCode; +} diff --git a/src/main/java/com/whdc/model/entity/AddressBook.java b/src/main/java/com/whdc/model/entity/AddressBook.java index 26ba040..76b0cb9 100644 --- a/src/main/java/com/whdc/model/entity/AddressBook.java +++ b/src/main/java/com/whdc/model/entity/AddressBook.java @@ -101,4 +101,9 @@ public class AddressBook extends Model implements Serializable { @TableField(exist = false) @ApiModelProperty(value = "0:组织,1:单位") private String type; + + @TableField("IS_PASS") + @ApiModelProperty(value = "是否放行, 放行:true,拦截:false") + private Boolean isPass; + } \ No newline at end of file diff --git a/src/main/java/com/whdc/model/enums/VersionsType.java b/src/main/java/com/whdc/model/enums/VersionsType.java index 729c877..00c7bfb 100644 --- a/src/main/java/com/whdc/model/enums/VersionsType.java +++ b/src/main/java/com/whdc/model/enums/VersionsType.java @@ -16,7 +16,8 @@ public enum VersionsType { ADD("0", "添加用户"), UPDATE("1", "修改用户"), UPDATE_ROLE("2", "修改权限"), - DEL("3", "删除用户"); + DEL("3", "删除用户"), + WHITE("4", "设置白名单"); private String name; diff --git a/src/main/java/com/whdc/service/IAddressBookService.java b/src/main/java/com/whdc/service/IAddressBookService.java index 7fbd89c..dab665a 100644 --- a/src/main/java/com/whdc/service/IAddressBookService.java +++ b/src/main/java/com/whdc/service/IAddressBookService.java @@ -24,7 +24,7 @@ public interface IAddressBookService extends IService { // 获取所有规则 List find(AddressBook dto); - List getListByAdnm(String adnm); + List getListByAdnm(String adcd); } \ No newline at end of file diff --git a/src/main/java/com/whdc/service/IUserService.java b/src/main/java/com/whdc/service/IUserService.java index 5795a1f..0023771 100644 --- a/src/main/java/com/whdc/service/IUserService.java +++ b/src/main/java/com/whdc/service/IUserService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.whdc.model.dto.LoginDto; import com.whdc.model.dto.UserDto; +import com.whdc.model.dto.VxLoginDto; import com.whdc.model.entity.User; import com.whdc.model.vo.LoginVo; import com.whdc.utils.ResultJson; @@ -27,6 +28,8 @@ public interface IUserService extends IService { LoginVo login(LoginDto obj); + LoginVo wxLogin(VxLoginDto obj); + boolean register(User entity); User getRole(Integer id); diff --git a/src/main/java/com/whdc/service/impl/AddressBookServiceImpl.java b/src/main/java/com/whdc/service/impl/AddressBookServiceImpl.java index ab2df4c..77c413c 100644 --- a/src/main/java/com/whdc/service/impl/AddressBookServiceImpl.java +++ b/src/main/java/com/whdc/service/impl/AddressBookServiceImpl.java @@ -32,6 +32,13 @@ public class AddressBookServiceImpl extends ServiceImpl getListByAdnm(String adnm) { - return baseMapper.getListByAdnm(adnm); + public List getListByAdnm(String adcd) { + return baseMapper.getListByAdnm(adcd); } diff --git a/src/main/java/com/whdc/service/impl/UserServiceImpl.java b/src/main/java/com/whdc/service/impl/UserServiceImpl.java index 670fab2..253fa54 100644 --- a/src/main/java/com/whdc/service/impl/UserServiceImpl.java +++ b/src/main/java/com/whdc/service/impl/UserServiceImpl.java @@ -1,5 +1,9 @@ package com.whdc.service.impl; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaUserService; +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -11,6 +15,7 @@ import com.whdc.mapper.AddressBookMapper; import com.whdc.mapper.UserMapper; import com.whdc.model.dto.LoginDto; import com.whdc.model.dto.UserDto; +import com.whdc.model.dto.VxLoginDto; import com.whdc.model.entity.AddressBook; import com.whdc.model.entity.User; import com.whdc.model.vo.AddressBookVo; @@ -19,6 +24,7 @@ import com.whdc.service.IUserService; import com.whdc.utils.HttpUtil; import com.whdc.utils.ResultJson; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpStatus; @@ -38,6 +44,7 @@ import static com.whdc.model.MyConstant.REDIS_KEY; *

* 服务实现类 *

+ * * @author xusan * @date 2024-05-11 */ @@ -53,6 +60,9 @@ public class UserServiceImpl extends ServiceImpl implements IU @Autowired private RedisTemplate stringRedisTemplate; + @Autowired + private WxMaService wxMaService; + @Override public IPage page(User dto) { return baseMapper.page(new Page<>(), dto); @@ -65,7 +75,6 @@ public class UserServiceImpl extends ServiceImpl implements IU } - @Override public LoginVo login(LoginDto dto) { @@ -75,12 +84,12 @@ public class UserServiceImpl extends ServiceImpl implements IU throw new MyException("用户名或密码错误"); } - if (getPassword(sysUser.getSalt() ,dto.getPassword()).equals(sysUser.getPassword())) { + if (getPassword(sysUser.getSalt(), dto.getPassword()).equals(sysUser.getPassword())) { LoginVo out = new LoginVo(); BeanUtils.copyProperties(sysUser, out); AddressBookVo book = addressBookMapper.getVoById(sysUser.getAbId()); - if (Objects.nonNull(book)){ + if (Objects.nonNull(book)) { String adcd = book.getAdcd(); if (StringUtils.isNotBlank(adcd)) { // if ("00000000000".equals(adcd.substring(4))) { // 市 @@ -93,12 +102,12 @@ public class UserServiceImpl extends ServiceImpl implements IU // out.setAdcd(adcd); // } out.setAdlevel(2); - out.setAdcd(adcd.substring(0,4)); + out.setAdcd(adcd.substring(0, 4)); } out.setName(book.getName()); out.setOname(book.getOname()); - if (StringUtils.isNotBlank(book.getAdnm())){ + if (StringUtils.isNotBlank(book.getAdnm())) { out.setOname(book.getAdnm()); } } @@ -109,6 +118,75 @@ public class UserServiceImpl extends ServiceImpl implements IU throw new MyException("用户名或密码错误"); } + @Override + public LoginVo wxLogin(VxLoginDto dto) { + + WxMaUserService userService = wxMaService.getUserService(); + + WxMaPhoneNumberInfo phoneNoInfo = null; + try { + phoneNoInfo = userService.getPhoneNoInfo(dto.getPhoneCode()); + } catch (WxErrorException e) { + throw new MyException("获取手机号失败," + e.getMessage(), e); + } + + if (phoneNoInfo == null) { + throw new MyException("获取微信数据为空1"); + } + + // 获取手机号 + String phone = phoneNoInfo.getPurePhoneNumber(); + + if (StringUtils.isBlank(phone)) { + throw new MyException("获取手机号失败"); + } + + WxMaJscode2SessionResult sessionInfo = null; + try { + sessionInfo = userService.getSessionInfo(dto.getWxcode()); + } catch (WxErrorException e) { + throw new RuntimeException(e); + } + if (sessionInfo == null) { + throw new MyException("获取微信数据为空2"); + } + + String openid = sessionInfo.getOpenid(); + if (StringUtils.isBlank(openid)) { + throw new MyException("获取微信openid失败"); + } + + User sysUser = findByLoginName(phone); + + if (sysUser == null) { + throw new MyException("用户名或密码错误"); + } + + LoginVo out = new LoginVo(); + BeanUtils.copyProperties(sysUser, out); + + AddressBookVo book = addressBookMapper.getVoById(sysUser.getAbId()); + if (Objects.nonNull(book)) { + if (!book.getIsPass()){ + throw new MyException("当前账号无法登录,请联系上级管理员!"); + } + String adcd = book.getAdcd(); + if (StringUtils.isNotBlank(adcd)) { + + out.setAdlevel(2); + out.setAdcd(adcd.substring(0, 4)); + + } + out.setName(book.getName()); + out.setOname(book.getOname()); + if (StringUtils.isNotBlank(book.getAdnm())) { + out.setOname(book.getAdnm()); + } + } + return out; + + } + @Override public boolean register(User entity) { // 生成盐值 @@ -123,7 +201,7 @@ public class UserServiceImpl extends ServiceImpl implements IU public User getRole(Integer id) { User byId = this.getById(id); - if (byId == null){ + if (byId == null) { throw new MyException("该用户不存在"); } @@ -142,8 +220,8 @@ public class UserServiceImpl extends ServiceImpl implements IU @Override public boolean updateLastDate(Integer id) { return this.lambdaUpdate() - .set(User::getLastLoginDate,new Date()) - .eq(User::getId,id) + .set(User::getLastLoginDate, new Date()) + .eq(User::getId, id) .update(); } @@ -214,14 +292,14 @@ public class UserServiceImpl extends ServiceImpl implements IU // out.setAdcd(adcd); // } out.setAdlevel(2); - out.setAdcd(adcd.substring(0,4)); + out.setAdcd(adcd.substring(0, 4)); } out.setName(addressBook.getName()); out.setOname(addressBook.getOname()); AddressBookVo book = addressBookMapper.getVoById(sysUser.getAbId()); - if (StringUtils.isNotBlank(book.getAdnm())){ + if (StringUtils.isNotBlank(book.getAdnm())) { out.setOname(book.getAdnm()); } return out; @@ -294,7 +372,7 @@ public class UserServiceImpl extends ServiceImpl implements IU String s = HttpUtil.sendPost("http://223.75.53.141:82/shpush/v1/push/", body); log.info("发送结果: " + s); JSONObject jsonObject = JSON.parseObject(s); - if (jsonObject.getInteger("code") != HttpStatus.SC_OK){ + if (jsonObject.getInteger("code") != HttpStatus.SC_OK) { throw new MyException(jsonObject.getString("message")); } } @@ -312,10 +390,10 @@ public class UserServiceImpl extends ServiceImpl implements IU } - if (getPassword(sysUser.getSalt() ,dto.getOldPassword()).equals(sysUser.getPassword())) { + if (getPassword(sysUser.getSalt(), dto.getOldPassword()).equals(sysUser.getPassword())) { // 更新密码 - sysUser.setPassword(getPassword(sysUser.getSalt() ,dto.getNewPassword())); - log.info("修改密码" + sysUser.getUsername() + "_" + dto.getNewPassword()); + sysUser.setPassword(getPassword(sysUser.getSalt(), dto.getNewPassword())); + log.info("修改密码" + sysUser.getUsername() + "_" + dto.getNewPassword()); return ResultJson.ok(sysUser.updateById()); } @@ -331,7 +409,7 @@ public class UserServiceImpl extends ServiceImpl implements IU } - public static String getPassword(String salt,String password) { + public static String getPassword(String salt, String password) { return DigestUtils.md5DigestAsHex((salt + password).getBytes()); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a9aa67f..c5ccf7d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -74,3 +74,9 @@ mybatis-plus: db-config: update-strategy: not_empty insert-strategy: not_empty + +wx: + miniapp: + configs: + appid: wxb9b07668d1ba20fe + secret: 99a1b89ac30e28bcc9bba8be973027f4 diff --git a/src/main/resources/mapper/AddressBookMapper.xml b/src/main/resources/mapper/AddressBookMapper.xml index 95f61b1..66b1e03 100644 --- a/src/main/resources/mapper/AddressBookMapper.xml +++ b/src/main/resources/mapper/AddressBookMapper.xml @@ -28,7 +28,7 @@ AND AB.NAME LIKE CONCAT('%', #{dto.name}, '%') - AND R.DICT_ID ${dto.v} #{dto.adcd} + AND AB.ADCD ${dto.v} #{dto.adcd} AND AB.PHONE LIKE CONCAT('', #{dto.phone}, '%') @@ -54,12 +54,12 @@ AB.*, A.ADNM FROM - ADINFO A - LEFT JOIN ADDRESS_BOOK AB ON AB.ADCD = A.ADCD AND AB.ADCD IS NOT NULL - LEFT JOIN AB_UD_R R ON R.AD_ID = AB.ID + ADDRESS_BOOK AB + LEFT JOIN ADINFO A ON AB.ADCD = A.ADCD AND AB.ADCD IS NOT NULL + LEFT JOIN AB_UD_R R ON R.AD_ID = AB.ID - - A.ADNM = #{adnm} + + A.ADCD = #{adcd} ORDER BY R.SORT