小熊家务帮day8-day9 客户管理模块2 (用户定位,地址簿,实名认证,银行卡信息上传等功能)

客户管理模块

  • 0.用户定位功能
    • 0.1 需求
    • 0.2 接口分析
    • 0.3 接口开发
      • Controller层开发
      • Service层开发
  • 1.我的地址簿功能
    • 1.1 需求
    • 1.2 数据库设计
    • 1.3 新增地址簿
      • 1.3.1 接口设计
      • 1.3.2 接口开发
        • Controller层开发
        • Service层开发
        • 测试功能
    • 1.4 地址簿查询
      • 1.4.1 接口设计
      • 1.4.2 接口开发
        • Controller层开发
        • Service层开发
        • 功能测试
    • 1.4 地址簿编辑
      • 1.4.1 需求
        • 1.4.2 根据地址薄id查询地址薄
          • 接口分析
          • Controller
        • 1.4.3 修改地址薄信息
          • 接口分析
          • Controller
          • Service层开发
        • 1.4.4 功能测试
    • 1.5 地址簿删除
      • 1.5.1 接口设计
      • 1.5.2 接口开发
        • Controller层开发
    • 1.6 设置/取消默认地址
      • 1.6.1 接口分析
      • 1.6.2 接口开发
        • Controller层开发
        • Service层开发
      • 1.6.3 功能测试
    • 1.7 获取默认地址接口
      • 1.7.1 接口分析
      • 1.7.2 接口设计
        • Controller层开发
        • Service层开发
  • 2.我的账户设置
    • 2.1 需求
    • 2.1 机构端设置银行账号
      • 2.1.1 新增或更新银行账号信息
        • 2.1.1.0 数据库表设计
        • 2.1.1.1 接口分析
        • 2.1.1.2 接口开发
          • Controller层开发
          • Service层开发
        • 2.1.1.3 功能测试
      • 2.1.2 查询银行账号信息
        • 2.1.2.1 接口分析
        • 2.1.2.2 接口开发
          • Controller层开发
    • 2.2 服务端设置银行账号
      • 2.2.1 服务端新增/更新银行账户
        • 2.2.1.1 接口分析
        • 2.2.1.2 接口开发
          • Controller层开发
        • 2.2.1.3 功能测试
      • 2.2.2 服务端获取当前用户银行账号接口
        • 2.2.2.1 接口分析
        • 2.2.2.2 接口开发
          • Controller层开发
        • 2.2.2.3 功能测试
  • 3.机构/服务人员认证模块
    • 3.1 需求
      • 3.1.1 服务端认证
      • 3.1.2 机构端认证
      • 3.1.1 运营端审核认证
    • 3.2 服务端提交认证
      • 3.2.0 服务人员认证审核表设计
      • 3.2.1 接口设计
      • 3.2.2 接口开发
        • Controller层开发
        • Service层开发
      • 3.2.3 功能测试
      • 3.2.4 服务人员查询认证驳回原因设计
        • 接口分析
        • Controller层
        • Service层
    • 3.3 机构端提交认证
      • 3.3.1 表设计
      • 3.3.2 接口设计
      • 3.3.3 接口开发
        • Controller层开发
        • Service层开发
      • 3.3.4 功能测试
      • 3.3.5 查询最新的驳回原因
        • 接口分析
        • 接口设计
          • Controller层
          • Service层
  • 4.运营端审核认证模块
    • 4.1 需求
    • 4.1审核服务人员
      • 4.1.1 分页查询审核信息
        • 4.1.1.1 接口分析
        • 4.1.1.2 接口开发
          • Controller层
          • Service层
        • 4.1.1.3 功能测试
      • 4.1.2 审核信息
        • 4.1.2.1 接口分析
        • 4.1.2.2 接口开发
          • Controller层
          • Service层
    • 4.2 审核机构人员
      • 4.2.1 分页查询审核信息
        • 2.2.1.1 接口分析
        • 2.2.1.2 接口开发
          • Controller层
          • Service层
      • 4.2.2 审核信息
        • 4.2.2.1接口分析
        • 4.2.2.2 接口开发
          • Controller层
          • Service层

0.用户定位功能

0.1 需求

用户端在小程序认证通过后会自动进行定位,也可以在首页手动定位,定位成功后用户在查询家政服务项目时会根据定位的城市查询该城市有哪些服务项目。
手动定位过程如下图:
在这里插入图片描述
点击下图箭头位置进行手动定位。
在这里插入图片描述
定位成功再次进入首页发现位置变为新地址

小程序端的定位是通过手机的定位模块进行定位,定位成功获取经纬度坐标,平台根据经纬度坐标请求地图服务获取经纬度坐标对应的具体位置。
在这里插入图片描述

小程序首先通过微信提供的方法拿到经纬度坐标,然后请求后端获取具体的位置,后端会请求高德地图根据经纬度获取具体的城市信息。

0.2 接口分析

当用户进入小程序后,批准小程序获取位置,则会发出以下请求:
在这里插入图片描述
后端会请求高德地图根据经纬度获取具体的cityCode

0.3 接口开发

Controller层开发

@RestController
@RequestMapping("/inner/map")
@Api(tags = "内部接口 - 地图服务相关接口")
public class InnerMapController implements MapApi {
    @Resource
    private MapService mapService;

    @Override
    @GetMapping("/getLocationByAddress")
    @ApiOperation("根据地址查询经纬度")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "address", value = "地址", required = true, dataTypeClass = String.class)
    })
    public LocationResDTO getLocationByAddress(@RequestParam("address") String address) {
        String location = mapService.getLocationByAddress(address);
        return new LocationResDTO(location);
    }
}

Service层开发

首先就是存一下经纬度以及高德开发api的key,其中高德开发者key存在了nacos配置中心中,之后调用高德api获取到cityCode进行返回即可:
在这里插入图片描述

    public String getLocationByAddress(String address) {
        Map<String, Object> params = new HashMap();
        params.put("address", address);
        params.put("key", this.amapProperties.getKey());
        String jsonStr = HttpRequest.get("https://restapi.amap.com/v3/geocode/geo?").form(params).execute().body();
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        JSONArray geocodes = JSONUtil.parseArray(jsonObject.get("geocodes"));
        Object location = JSONUtil.parseObj(geocodes.get(0)).get("location");
        return location.toString();
    }

1.我的地址簿功能

1.1 需求

用户下单时需要选择服务地址(相当于收货地址),在“我的”–》“我的地址”界面维护地址簿信息。
在这里插入图片描述
点击“我的地址”即可进入地址簿管理界面
因此,需要完成以下功能:

  • 新增地址簿
  • 地址簿编辑
  • 地址簿删除
  • 地址簿查询
  • 批量删除
  • 设置默认地址

1.2 数据库设计

create table `jzo2o-customer`.address_book
(
    id          bigint                             not null comment '主键'
        constraint `PRIMARY`
        primary key,
    user_id     bigint                             not null comment '用户id',
    name        varchar(255)                       not null comment '名称',
    phone       varchar(255)                       not null comment '电话',
    province    varchar(255)                       not null comment '省份',
    city        varchar(255)                       not null comment '市级',
    county      varchar(255)                       not null comment '区/县',
    address     varchar(255)                       not null comment '详细地址',
    lon         double(10, 5)                      null comment '经度',
    lat         double(10, 5)                      null comment '纬度',
    is_default  int      default 0                 not null comment '是否为默认地址,0:否,1:是',
    is_deleted  int      default 0                 not null comment '是否已删除,0:未删除,1:已删除',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    create_by   bigint                             null comment '创建者',
    update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    update_by   bigint                             null comment '更新者'
)

1.3 新增地址簿

1.3.1 接口设计

接口路径:POST/customer/consumer/address-book
请求数据类型 application/json
在这里插入图片描述在这里插入图片描述

1.3.2 接口开发

Controller层开发
@RestController("consumerAddressBookController")
@RequestMapping("/consumer/address-book")
@Api(tags = "用户端 - 地址薄相关接口")
public class AddressBookCotroller {

    @Autowired
    private IAddressBookService addressBookService;

    @RequestMapping("/address-book")
    @ApiOperation("地址薄新增")
    public void add(@RequestBody AddressBookUpsertReqDTO addressBookUpsertReqDTO){
        IAddressBookService.add(addressBookUpsertReqDTO);
    }
}

Service层开发

大概业务逻辑就是:

  • 从Threadlocal中获取userId
  • 若请求中该新增地址设为默认,则取消之前的默认地址
  • 拼接地址
  • 写入数据库

取消之前的默认地址如下:

    /**
     * 取消默认地址
     * @param userId
     */
    private void cancelDefault(Long userId) {
        lambdaUpdate().eq(AddressBook::getId,userId)
                .set(AddressBook::getIsDefault,0).update();
        
    }

Service层代码:

    /**
     * 新增地址簿
     * @param addressBookUpsertReqDTO
     */
    @Override
    public void add(AddressBookUpsertReqDTO addressBookUpsertReqDTO){
        //1.从Threadlocal中获取当前用户id
        Long userId = UserContext.currentUserId();
        //2.如果新增中设为默认地址,取消其他默认地址
        if (1 == addressBookUpsertReqDTO.getIsDefault()) {
            cancelDefault(userId);
        }
        AddressBook addressBook = BeanUtil.toBean(addressBookUpsertReqDTO, AddressBook.class);
        addressBook.setId(userId);
        //3.组装详细地址
        String completeAddress = addressBookUpsertReqDTO.getProvince() +
                addressBookUpsertReqDTO.getCity() +
                addressBookUpsertReqDTO.getCounty() +
                addressBookUpsertReqDTO.getAddress();
        //4.如果请求体中没有经纬度,需要调用第三方api根据详细地址获取经纬度
        if(ObjectUtils.isEmpty(addressBookUpsertReqDTO.getLocation())){
            //调用高德接口获得经纬度
            LocationResDTO locationDto = mapApi.getLocationByAddress(completeAddress);
            //经纬度(字符串格式:经度,纬度),经度在前,纬度在后
            String location = locationDto.getLocation();
            addressBookUpsertReqDTO.setLocation(location);
        }
        if(StringUtils.isNotEmpty(addressBookUpsertReqDTO.getLocation())) {
            // 经度
            addressBook.setLon(NumberUtils.parseDouble(addressBookUpsertReqDTO.getLocation().split(",")[0]));
            // 纬度
            addressBook.setLat(NumberUtils.parseDouble(addressBookUpsertReqDTO.getLocation().split(",")[1]));
        }
        addressBookService.save(addressBook);
    }
测试功能

输入信息:
在这里插入图片描述
请求正常被收到并且处理:
在这里插入图片描述
数据库也插入了:
在这里插入图片描述

1.4 地址簿查询

1.4.1 接口设计

接口路径:GET/customer/consumer/address-book/page
请求数据类型 application/x-www-form-urlencoded
在这里插入图片描述
在这里插入图片描述

1.4.2 接口开发

Controller层开发
    @GetMapping("/page")
    @ApiOperation("地址薄分页查询")
    public PageResult<AddressBookResDTO> page(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO){
        return addressBookService.page(addressBookPageQueryReqDTO);
    }
Service层开发
    /**
     * 地址簿分页查询
     * @param addressBookPageQueryReqDTO
     * @return
     */
    @Override
    public PageResult<AddressBookResDTO> page(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO) {
        Page<AddressBook> page = PageUtils.parsePageQuery(addressBookPageQueryReqDTO, AddressBook.class);
        LambdaQueryWrapper<AddressBook> lambdaQueryWrapper = Wrappers.lambdaQuery(AddressBook.class).eq(AddressBook::getUserId, UserContext.currentUserId());
        Page<AddressBook> page1 = addressBookService.page(page, lambdaQueryWrapper);
        return PageUtils.toPage(page1, AddressBookResDTO.class);
    }
功能测试

在这里插入图片描述

1.4 地址簿编辑

1.4.1 需求

实现点击编辑按钮,应该首先显示出当前地址信息,之后修改后数据写回数据库,因此,这个功能包含两部分:

  • 根据地址薄id查询信息
  • 修改地址薄
1.4.2 根据地址薄id查询地址薄
接口分析

接口路径:GET/customer/consumer/address-book/{id}在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Controller
    @GetMapping("/#{id}")
    @ApiOperation("地址薄详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "地址薄id", required = true, dataTypeClass = Long.class)
    })
    public AddressBookResDTO detail(@PathVariable("id") Long id){
        AddressBook addressBook = addressBookService.getById(id);
        return BeanUtil.toBean(addressBook, AddressBookResDTO.class);
    }
1.4.3 修改地址薄信息
接口分析

接口路径:PUT/customer/consumer/address-book/{id}
请求数据类型 application/json
在这里插入图片描述
在这里插入图片描述

Controller
    @PutMapping("/{id}")
    @ApiOperation("地址薄修改")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "地址薄id", required = true, dataTypeClass = Long.class)
    })
    public void update(@PathVariable("id") Long id,@RequestBody AddressBookUpsertReqDTO addressBookUpsertReqDTO){
        addressBookService.update(id,addressBookUpsertReqDTO);
    }
Service层开发
    @Override
    public void update(Long id, AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
        //1.判断是否取消默认
        if(addressBookUpsertReqDTO.getIsDefault() == 1){
            cancelDefault(id);
        }
        AddressBook addressBook = BeanUtil.toBean(addressBookUpsertReqDTO, AddressBook.class);
        addressBook.setId(id);


        //调用第三方,根据地址获取经纬度坐标
        String completeAddress = addressBookUpsertReqDTO.getProvince() +
                addressBookUpsertReqDTO.getCity() +
                addressBookUpsertReqDTO.getCounty() +
                addressBookUpsertReqDTO.getAddress();
        //远程请求高德获取经纬度
        LocationResDTO locationDto = mapApi.getLocationByAddress(completeAddress);
        //经纬度(字符串格式:经度,纬度),经度在前,纬度在后
        String location = locationDto.getLocation();
        if(StringUtils.isNotEmpty(location)) {
            // 经度
            addressBook.setLon(NumberUtils.parseDouble(locationDto.getLocation().split(",")[0]));
            // 纬度
            addressBook.setLat(NumberUtils.parseDouble(locationDto.getLocation().split(",")[1]));
        }
        addressBookMapper.updateById(addressBook);
    }
1.4.4 功能测试

首先点击了编辑:
在这里插入图片描述
之后开始编辑并且确定:
在这里插入图片描述
功能已经实现:
在这里插入图片描述

1.5 地址簿删除

1.5.1 接口设计

接口路径:DELETE/customer/consumer/address-book/batch
在这里插入图片描述
在这里插入图片描述

1.5.2 接口开发

Controller层开发

实现比较简单,直接在controller调用mp的方法即可:

    @DeleteMapping("/batch")
    @ApiOperation("地址薄批量删除")
    @ApiImplicitParam(name = "ids", value = "地址薄id列表", required = true, dataTypeClass = List.class)
    public void batch(@RequestBody List<Long> ids){
        addressBookService.removeByIds(ids);
    }

1.6 设置/取消默认地址

1.6.1 接口分析

接口路径:PUT/customer/consumer/address-book/default
请求数据类型 application/x-www-form-urlencoded
在这里插入图片描述
在这里插入图片描述

1.6.2 接口开发

Controller层开发
    @PutMapping("/default")
    @ApiOperation("地址薄设为默认/取消默认")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "地址薄id", required = true, dataTypeClass = Long.class),
            @ApiImplicitParam(name = "flag", value = "是否为默认地址,0:否,1:是", required = true, dataTypeClass = Integer.class)
    })
    public void updateDefaultStatus(@NotNull(message = "id不能为空") @RequestParam("id") Long id,
                                    @NotNull(message = "状态值不能为空") @RequestParam("flag") Integer flag) {
        //当前登录用户id
        Long userId = UserContext.currentUserId();
        addressBookService.updateDefaultStatus(userId,id, flag);
    }
Service层开发
    /**
     * 设置/取消默认地址
     * @param userId
     * @param id
     * @param flag
     */
    @Override
    public void updateDefaultStatus(Long userId, Long id, Integer flag) {
        if (1 == flag) {
            //如果设默认地址,先把其他地址取消默认
            cancelDefault(userId);
        }
        AddressBook addressBook = new AddressBook();
        addressBook.setId(id);
        addressBook.setIsDefault(flag);
        addressBookMapper.updateById(addressBook);
    }

1.6.3 功能测试

一开始:
在这里插入图片描述
之后我们李浩111设为默认地址:
在这里插入图片描述
功能测试成功

1.7 获取默认地址接口

在下单界面先获取当前用户的默认地址,如果有默认地址则直接显示在页面中,因此需要提前设计好这个接口

1.7.1 接口分析

接口路径:GET/customer/consumer/address-book/defaultAddress
请求数据类型 application/x-www-form-urlencoded
请求参数:无
在这里插入图片描述
在这里插入图片描述

1.7.2 接口设计

Controller层开发
    @GetMapping("/defaultAddress")
    @ApiOperation("获取默认地址")
    public AddressBookResDTO defaultAddress(){
        return addressBookService.defaultAddress();
    }
Service层开发
    /**
     * 获取默认地址信息
     * @return
     */
    @Override
    public AddressBookResDTO defaultAddress() {
        LambdaQueryWrapper<AddressBook> lambdaQueryWrapper = Wrappers.lambdaQuery(AddressBook.class);
        lambdaQueryWrapper.eq(AddressBook::getUserId,UserContext.currentUserId())
                .eq(AddressBook::getIsDefault,1);
        AddressBook addressBook = addressBookMapper.selectOne(lambdaQueryWrapper);
        return BeanUtil.toBean(addressBook,AddressBookResDTO.class);
    }

2.我的账户设置

2.1 需求

需要完成以下功能:

  • 服务端设置银行卡
  • 机构端设置银行卡
  • 新增或者更新以上设置的银行卡
  • 获取银行卡信息的接口

本模块在维护银行账户信息时需要上传银行卡照片,本项目的图片服务器使用阿里的OSS存储。

2.1 机构端设置银行账号

2.1.1 新增或更新银行账号信息

2.1.1.0 数据库表设计
CREATE TABLE `bank_account` (
  `id` bigint DEFAULT NULL COMMENT '服务人员/机构id',
  `type` int DEFAULT NULL COMMENT '类型,2:服务人员,3:服务机构',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '户名',
  `bank_name` varchar(50) DEFAULT NULL COMMENT '银行名称',
  `province` varchar(50) DEFAULT NULL COMMENT '省',
  `city` varchar(50) DEFAULT NULL COMMENT '市',
  `district` varchar(50) DEFAULT NULL COMMENT '区',
  `branch` varchar(50) DEFAULT NULL COMMENT '网点',
  `account` varchar(50) DEFAULT NULL COMMENT '银行账号',
  `account_certification` varchar(100) DEFAULT NULL COMMENT '开户证明',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
)
2.1.1.1 接口分析

接口路径:POST/customer/agency/bank-account
请求类型:application/json
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.1.2 接口开发
Controller层开发
@RestController("agencyBankAccountController")
@RequestMapping("/agency/bank-account")
@Api(tags = "机构端 - 银行账户信息相关接口")
public class BankAccountController {

    @Autowired
    private IBankAccountService bankAccountService;

    @PostMapping
    @ApiOperation("新增或更新银行账号信息")
    public void queryByServeProviderId(@RequestBody BankAccountUpsertReqDTO bankAccountUpsertReqDTO){
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        bankAccountUpsertReqDTO.setId(currentUserInfo.getId());
        bankAccountUpsertReqDTO.setType(currentUserInfo.getUserType());
        bankAccountService.queryAndUpdate(bankAccountUpsertReqDTO);
    }
}

Service层开发
public class BankAccountServiceImpl extends ServiceImpl<BankAccountMapper, BankAccount> implements IBankAccountService {
    /**
     * 更新或新增银行账户
     * @param bankAccountUpsertReqDTO
     */
    @Override
    public void queryAndUpdate(BankAccountUpsertReqDTO bankAccountUpsertReqDTO) {
        BankAccount bankAccount = BeanUtil.toBean(bankAccountUpsertReqDTO, BankAccount.class);
        super.saveOrUpdate(bankAccount);
    }
}
2.1.1.3 功能测试

点击账户设置,之后填好信息:
在这里插入图片描述
点击提交:
在这里插入图片描述
在这里插入图片描述
功能测试成功

2.1.2 查询银行账号信息

2.1.2.1 接口分析

接口路径:GET/customer/worker/bank-account/currentUserBankAccount
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.2.2 接口开发
Controller层开发
    @GetMapping("/currentUserBankAccount")
    @ApiOperation("获取当前用户银行账号")
    public BankAccountResDTO queryCurrentUserBankAccount() {
        BankAccount bankAccount = bankAccountService.getById(UserContext.currentUserId());
        return BeanUtil.toBean(bankAccount, BankAccountResDTO.class);
    }

2.2 服务端设置银行账号

2.2.1 服务端新增/更新银行账户

2.2.1.1 接口分析

接口路径:POST/customer/worker/bank-account
请求类型:application/json
在这里插入图片描述
在这里插入图片描述

2.2.1.2 接口开发
Controller层开发
@RestController("workerBankAccountController")
@RequestMapping("/worker/bank-account")
@Api(tags = "服务端 - 银行账户信息相关接口")
public class BankAccountController {
    
    @Autowired
    private IBankAccountService bankAccountService;
    
    @PostMapping
    @ApiOperation("新增或更新银行账号信息")
    public void queryByServeProviderId(@RequestBody BankAccountUpsertReqDTO bankAccountUpsertReqDTO){
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        bankAccountUpsertReqDTO.setId(currentUserInfo.getId());
        bankAccountUpsertReqDTO.setType(currentUserInfo.getUserType());
        bankAccountService.queryAndUpdate(bankAccountUpsertReqDTO);
    }
}
2.2.1.3 功能测试

填入银行账户信息:
在这里插入图片描述
点击提交:
在这里插入图片描述
在这里插入图片描述
功能测试成功

2.2.2 服务端获取当前用户银行账号接口

2.2.2.1 接口分析

接口路径:GET/customer/worker/bank-account/currentUserBankAccount
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.2.2 接口开发
Controller层开发
    @PostMapping("/currentUserBankAccount")
    @ApiOperation("查询银行账户信息")
    public BankAccountResDTO queryCurrentUserBankAccount(){
        BankAccount bankAccount = bankAccountService.getById(UserContext.currentUserId());
        return BeanUtil.toBean(bankAccount,BankAccountResDTO.class);
    }
2.2.2.3 功能测试

当我们提交了一次服务端账户信息后,再次点击账户信息:
在这里插入图片描述
在这里插入图片描述
此功能处理成功

3.机构/服务人员认证模块

3.1 需求

3.1.1 服务端认证

当服务端的服务者注册成功账户,并登录后,会强制进行实名认证:
在这里插入图片描述
点击去认证:
在这里插入图片描述

3.1.2 机构端认证

当新注册的机构账户进行登录后:
在这里插入图片描述
再点击资质认证:
在这里插入图片描述

3.1.1 运营端审核认证

在这里插入图片描述

3.2 服务端提交认证

3.2.0 服务人员认证审核表设计

认证审核表:

CREATE TABLE `worker_certification_audit` (
  `id` bigint NOT NULL COMMENT '主键',
  `serve_provider_id` bigint DEFAULT NULL COMMENT '服务人员id',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '姓名',
  `id_card_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '身份证号',
  `front_img` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '身份证正面',
  `back_img` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '身份证反面',
  `certification_material` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '证明资料',
  `audit_status` int DEFAULT '0' COMMENT '审核状态,0:未审核,1:已审核',
  `auditor_id` bigint DEFAULT NULL COMMENT '审核人id',
  `auditor_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '审核人姓名',
  `audit_time` datetime DEFAULT NULL COMMENT '审核时间',
  `certification_status` int DEFAULT '1' COMMENT '认证状态,1:认证中,2:认证成功,3认证失败',
  `reject_reason` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '驳回原因',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
)

认证表:

create table worker_certification
(
    id                     bigint   default 0                 not null comment '服务人员id'
        primary key,
    name                   varchar(50)                        null comment '姓名',
    id_card_no             varchar(50)                        null comment '身份证号',
    front_img              varchar(100)                       null comment '身份证正面',
    back_img               varchar(100)                       null comment '身份证反面',
    certification_material varchar(100)                       null comment '证明资料',
    certification_status   int      default 0                 not null comment '认证状态,0:初始态,1:认证中,2:认证成功,3认证失败',
    certification_time     datetime                           null comment '认证时间',
    create_time            datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time            datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
)

3.2.1 接口设计

接口路径:POST/customer/worker/worker-certification-audit
请求数据类型: application/json
请求参数:
在这里插入图片描述
响应参数:
在这里插入图片描述

3.2.2 接口开发

Controller层开发
@RestController("workerWorkerCertificationAuditController")
@RequestMapping("/worker/worker-certification-audit")
@Api(tags = "服务端人员认证接口")
public class workerWorkerCertificationAuditController {

    @Autowired
    private WorkCertificationAuditService workCertificationAuditService;

    @PostMapping
    @ApiOperation("提交认证申请")
    public void auditCertification(@RequestBody WorkerCertificationAuditResDTO workerCertificationAuditResDTO){
        workerCertificationAuditResDTO.setServeProviderId(UserContext.currentUserId());
        workCertificationAuditService.applyCertification(workerCertificationAuditResDTO);
    }
}

Service层开发
@Service
public class WorkCertificationAuditServiceImpl extends ServiceImpl<WorkerCertificationAuditMapper,WorkerCertificationAudit> implements WorkCertificationAuditService {

    @Autowired
    private WorkerCertificationAuditMapper workerCertificationAuditMapper;

    @Autowired
    private IWorkerCertificationService workerCertificationService;
    /**
     * 服务人员提交申请
     * @param workerCertificationAuditResDTO
     */
    @Override
    public void applyCertification(WorkerCertificationAuditResDTO workerCertificationAuditResDTO) {
        WorkerCertificationAudit workerCertificationAudit = BeanUtil.toBean(workerCertificationAuditResDTO, WorkerCertificationAudit.class);
        //默认未审核
        workerCertificationAudit.setAuditStatus(0);
        workerCertificationAuditMapper.insert(workerCertificationAudit);
        //查询认证状态并且将认证信息存入认证表中
        Long serveProviderId = workerCertificationAuditResDTO.getServeProviderId();
        WorkerCertification workerCertification = workerCertificationService.getById(serveProviderId);
        if(ObjectUtil.isNotEmpty(workerCertification)){
            //不为空说明之前审核过,只需要修改为审核中即可
            workerCertification.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            workerCertificationService.updateById(workerCertification);
        }else{
            //为空则说明第一次审核,需要将审核信息存入表中
            WorkerCertification workerCertification1 = new WorkerCertification();
            workerCertification1.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            workerCertification1.setId(serveProviderId);
            workerCertificationService.save(workerCertification1);
        }
    }
}

3.2.3 功能测试

服务端新建账号后点击实名:
在这里插入图片描述
点击提交:
在这里插入图片描述
在这里插入图片描述
功能完成

3.2.4 服务人员查询认证驳回原因设计

接口分析

接口路径:GET/customer/worker/worker-certification-audit/rejectReason
请求数据类型: application/x-www-form-urlencoded
请求参数:

响应参数:
[图片]

Controller层
    @GetMapping("/rejectReason")
    @ApiOperation("服务人员查询驳回原因")
    public RejectReasonResDTO queryRejectReason(){
        return workCertificationAuditService.queryRejectReason();
    }
Service层
    /**
     * 查询驳回理由
     * @return
     */
    @Override
    public RejectReasonResDTO queryRejectReason() {
        LambdaQueryWrapper<WorkerCertificationAudit> queryWrapper = Wrappers.lambdaQuery(WorkerCertificationAudit.class);
        queryWrapper.eq(WorkerCertificationAudit::getServeProviderId, UserContext.currentUserId())
                .orderByDesc(WorkerCertificationAudit::getCreateTime)
                .last("limit 1");
        WorkerCertificationAudit workerCertificationAudit = workerCertificationAuditMapper.selectOne(queryWrapper);
        return new RejectReasonResDTO(workerCertificationAudit.getRejectReason());

    }

3.3 机构端提交认证

3.3.1 表设计

认证信息提交表:

CREATE TABLE `agency_certification_audit` (
  `id` bigint NOT NULL COMMENT '主键',
  `serve_provider_id` bigint DEFAULT NULL COMMENT '机构id',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '企业名称',
  `id_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '统一社会信用代码',
  `legal_person_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '法人姓名',
  `legal_person_id_card_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '法人身份证号',
  `business_license` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '营业执照',
  `audit_status` int NOT NULL DEFAULT '0' COMMENT '审核状态,0:未审核,1:已审核',
  `auditor_id` bigint DEFAULT NULL COMMENT '审核人id',
  `auditor_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '审核人姓名',
  `audit_time` datetime DEFAULT NULL COMMENT '审核时间',
  `certification_status` int NOT NULL DEFAULT '1' COMMENT '认证状态,1:认证中,2:认证成功,3:认证失败',
  `reject_reason` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '驳回原因',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) 

认证信息表:

create table agency_certification
(
    id                      bigint auto_increment comment '机构id'
        primary key,
    name                    varchar(50)                        null comment '企业名称',
    id_number               varchar(50)                        null comment '统一社会信用代码',
    legal_person_name       varchar(50)                        null comment '法人姓名',
    legal_person_id_card_no varchar(50)                        null comment '法人身份证号',
    business_license        varchar(100)                       null comment '营业执照',
    certification_status    int      default 0                 not null comment '认证状态,0:初始态,1:认证中,2:认证成功,3认证失败',
    certification_time      datetime                           null comment '认证时间',
    create_time             datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time             datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
)

3.3.2 接口设计

接口路径:POST/customer/agency/agency-certification-audit
请求数据类型: application/json
在这里插入图片描述
在这里插入图片描述

3.3.3 接口开发

Controller层开发
@RestController("AgencyCertificationAuditController")
@RequestMapping("/agency/agency-certification-audit")
@Api("机构端认证审核相关接口")
public class AgencyCertificationAuditController {
    
    @Autowired
    private IAgencyCertificationAuditService applyCertification;
    
    @PostMapping
    @ApiOperation("提交认证申请")
    public void auditCertification(@RequestBody AgencyCertificationAuditAddReqDTO agencyCertificationAuditAddReqDTO) {
        agencyCertificationAuditAddReqDTO.setServeProviderId(UserContext.currentUserId());
        applyCertification.applyCertification(agencyCertificationAuditAddReqDTO);
    }
}

Service层开发
    /**
     * 机构端提交认证申请
     * @param agencyCertificationAuditAddReqDTO
     */
    @Override
    public void applyCertification(AgencyCertificationAuditAddReqDTO agencyCertificationAuditAddReqDTO) {
        AgencyCertificationAudit agencyCertificationAudit = BeanUtil.toBean(agencyCertificationAuditAddReqDTO, AgencyCertificationAudit.class);
        baseMapper.insert(agencyCertificationAudit);
        //查询认证记录
        Long serveProviderId = agencyCertificationAudit.getServeProviderId();
        AgencyCertification agencyCertification = agencyCertificationService.getById(serveProviderId);
        if(ObjectUtil.isNotEmpty(agencyCertification)){
            //不是第一次认证
            agencyCertification.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            agencyCertificationService.updateById(agencyCertification);
        }else{
            //是第一次认证
            AgencyCertification agencyCertification1 = new AgencyCertification();
            agencyCertification1.setCertificationStatus(CertificationStatusEnum.PROGRESSING.getStatus());
            agencyCertification1.setId(serveProviderId);
            agencyCertificationService.save(agencyCertification1);
        }
    }

3.3.4 功能测试

点击认证之后输入:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
功能开发完成

3.3.5 查询最新的驳回原因

接口分析

接口路径:GET/customer/agency/agency-certification-audit/rejectReason
请求数据类型: application/x-www-form-urlencoded
请求参数:

响应参数:
在这里插入图片描述

接口设计
Controller层
    @GetMapping("/rejectReason")
    @ApiOperation("查询最新的驳回原因")
    public RejectReasonResDTO queryCurrentUserLastRejectReason() {
        return applyCertification.queryCurrentUserLastRejectReason();
    }
Service层
    /**
     * 机构端查询最新驳回原因
     * @return
     */
    @Override
    public RejectReasonResDTO queryCurrentUserLastRejectReason() {
        LambdaQueryWrapper<AgencyCertificationAudit> queryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                .eq(AgencyCertificationAudit::getServeProviderId, UserContext.currentUserId())
                .orderByDesc(AgencyCertificationAudit::getCreateTime)
                .last("limit 1");
        AgencyCertificationAudit agencyCertificationAudit = baseMapper.selectOne(queryWrapper);
        return new RejectReasonResDTO(agencyCertificationAudit.getRejectReason());
    }

4.运营端审核认证模块

4.1 需求

运营端管理员需要在后台申请服务人员/机构的认证申请,可以驳回或者通过,驳回后,其可以继续申请,大概就是这样

4.1审核服务人员

4.1.1 分页查询审核信息

4.1.1.1 接口分析

接口路径:GET/customer/operation/worker-certification-audit/page
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.1.1.2 接口开发
Controller层
@RestController("operationWorkerCertificationAuditController")
@RequestMapping("/operation/worker-certification-audit")
@Api(tags = "运营端 - 服务端认证审核接口")
public class WorkerCertificationAuditController {
    
    @Autowired
    private WorkCertificationAuditService workCertificationAuditService;

    @GetMapping("/page")
    @ApiOperation("服务人员认证信息分页查询")
    public PageResult<WorkerCertificationAuditResDTO> page(WorkerCertificationAuditPageQueryReqDTO workerCertificationAuditPageQueryReqDTO){
        return workCertificationAuditService.pageQuery(workerCertificationAuditPageQueryReqDTO);
    }
}
Service层
    /**
     * 服务人员认证的分页查询
     * @param workerCertificationAuditPageQueryReqDTO
     * @return
     */
    @Override
    public PageResult<WorkerCertificationAuditResDTO> pageQuery(WorkerCertificationAuditPageQueryReqDTO workerCertificationAuditPageQueryReqDTO) {
        Page<WorkerCertificationAudit> workerCertificationAuditPage = PageUtils.parsePageQuery(workerCertificationAuditPageQueryReqDTO, WorkerCertificationAudit.class);
        LambdaQueryWrapper<WorkerCertificationAudit> queryWrapper = Wrappers.lambdaQuery(WorkerCertificationAudit.class);
        queryWrapper.like(ObjectUtil.isNotEmpty(workerCertificationAuditPageQueryReqDTO.getName()), WorkerCertificationAudit::getName, workerCertificationAuditPageQueryReqDTO.getName())
                .eq(ObjectUtil.isNotEmpty(workerCertificationAuditPageQueryReqDTO.getIdCardNo()), WorkerCertificationAudit::getIdCardNo, workerCertificationAuditPageQueryReqDTO.getIdCardNo())
                .eq(ObjectUtil.isNotEmpty(workerCertificationAuditPageQueryReqDTO.getAuditStatus()), WorkerCertificationAudit::getAuditStatus, workerCertificationAuditPageQueryReqDTO.getAuditStatus())
                .eq(ObjectUtil.isNotEmpty(workerCertificationAuditPageQueryReqDTO.getCertificationStatus()), WorkerCertificationAudit::getCertificationStatus, workerCertificationAuditPageQueryReqDTO.getCertificationStatus());
        Page<WorkerCertificationAudit> workerCertificationAuditPage1 = baseMapper.selectPage(workerCertificationAuditPage, queryWrapper);
        return PageUtils.toPage(workerCertificationAuditPage1,WorkerCertificationAuditResDTO.class);
    }
4.1.1.3 功能测试

在这里插入图片描述

4.1.2 审核信息

4.1.2.1 接口分析

PUT/customer/operation/worker-certification-audit/audit/{id}
在这里插入图片描述
在这里插入图片描述

4.1.2.2 接口开发
Controller层

    @PutMapping("/audit/{id}")
    @ApiOperation("审核服务人员认证信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "认证申请id",required = true,dataTypeClass = Long.class)
    })
    public void auditCertification(@PathVariable("id") Long id, CertificationAuditReqDTO certificationAuditReqDTO){
        workCertificationAuditService.auditCertification(id,certificationAuditReqDTO);
    }
Service层
    /**
     * 审核服务人员信息
     * @param id
     * @param certificationAuditReqDTO
     */
    @Override
    @Transactional
    public void auditCertification(Long id, CertificationAuditReqDTO certificationAuditReqDTO) {
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        LambdaUpdateWrapper<WorkerCertificationAudit> updateWrapper = Wrappers.lambdaUpdate(WorkerCertificationAudit.class);
        updateWrapper.eq(WorkerCertificationAudit::getId,id)
                .set(WorkerCertificationAudit::getAuditStatus,1)
                .set(WorkerCertificationAudit::getAuditorId,currentUserInfo.getId())
                .set(WorkerCertificationAudit::getAuditorName,currentUserInfo.getName())
                .set(WorkerCertificationAudit::getAuditTime, LocalDateTime.now())
                .set(WorkerCertificationAudit::getCertificationStatus,certificationAuditReqDTO.getCertificationStatus())
                .set(ObjectUtil.isNotEmpty(certificationAuditReqDTO.getRejectReason()),WorkerCertificationAudit::getRejectReason,certificationAuditReqDTO.getRejectReason());
        super.update(updateWrapper);
    }

4.2 审核机构人员

4.2.1 分页查询审核信息

2.2.1.1 接口分析

接口路径:GET/customer/operation/agency-certification-audit/page
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.1.2 接口开发
Controller层
@RestController("operationAgencyCertificationAuditController")
@RequestMapping("/operation/agency-certification-audit")
@Api(tags = "运营端 - 机构认证审核相关接口")
public class AgencyCertificationAuditController {

    @Resource
    private IAgencyCertificationAuditService agencyCertificationAuditService;

    @GetMapping("/page")
    @ApiOperation("机构认证审核信息分页查询")
    public PageResult<AgencyCertificationAuditResDTO> page(AgencyCertificationAuditPageQueryReqDTO agencyCertificationAuditPageQueryReqDTO) {
        return agencyCertificationAuditService.pageQuery(agencyCertificationAuditPageQueryReqDTO);
    }
    
}
Service层

    /**
     * 审核服务人员信息
     * @param id
     * @param certificationAuditReqDTO
     */
    @Override
    @Transactional
    public void auditCertification(Long id, CertificationAuditReqDTO certificationAuditReqDTO) {
        //1.更新申请记录
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        LambdaUpdateWrapper<WorkerCertificationAudit> updateWrapper = Wrappers.lambdaUpdate(WorkerCertificationAudit.class);
        updateWrapper.eq(WorkerCertificationAudit::getId,id)
                .set(WorkerCertificationAudit::getAuditStatus,1)
                .set(WorkerCertificationAudit::getAuditorId,currentUserInfo.getId())
                .set(WorkerCertificationAudit::getAuditorName,currentUserInfo.getName())
                .set(WorkerCertificationAudit::getAuditTime, LocalDateTime.now())
                .set(WorkerCertificationAudit::getCertificationStatus,certificationAuditReqDTO.getCertificationStatus())
                .set(ObjectUtil.isNotEmpty(certificationAuditReqDTO.getRejectReason()),WorkerCertificationAudit::getRejectReason,certificationAuditReqDTO.getRejectReason());
        super.update(updateWrapper);
        //2.更新认证信息,如果认证成功,需要将各认证属性也更新
        WorkerCertificationAudit workerCertificationAudit = baseMapper.selectById(id);
        WorkerCertificationUpdateDTO workerCertificationUpdateDTO = new WorkerCertificationUpdateDTO();
        workerCertificationUpdateDTO.setId(workerCertificationAudit.getServeProviderId());
        workerCertificationUpdateDTO.setCertificationStatus(certificationAuditReqDTO.getCertificationStatus());
        if (ObjectUtil.equal(CertificationStatusEnum.SUCCESS.getStatus(), certificationAuditReqDTO.getCertificationStatus())) {
            //如果认证成功,需要更新服务人员/机构名称
            serveProviderService.updateNameById(workerCertificationAudit.getServeProviderId(), workerCertificationAudit.getName());

            workerCertificationUpdateDTO.setName(workerCertificationAudit.getName());
            workerCertificationUpdateDTO.setIdCardNo(workerCertificationAudit.getIdCardNo());
            workerCertificationUpdateDTO.setFrontImg(workerCertificationAudit.getFrontImg());
            workerCertificationUpdateDTO.setBackImg(workerCertificationAudit.getBackImg());
            workerCertificationUpdateDTO.setCertificationMaterial(workerCertificationAudit.getCertificationMaterial());
            workerCertificationUpdateDTO.setCertificationTime(workerCertificationAudit.getAuditTime());
        }
        workerCertificationService.updateById(workerCertificationUpdateDTO);
    }

4.2.2 审核信息

4.2.2.1接口分析
4.2.2.2 接口开发
Controller层
    @PutMapping("/audit/{id}")
    @ApiOperation("审核机构认证信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "认证申请id", required = true, dataTypeClass = Long.class)
    })
    public void auditCertification(@PathVariable("id") Long id, CertificationAuditReqDTO certificationAuditReqDTO) {
        agencyCertificationAuditService.auditCertification(id, certificationAuditReqDTO);
    }
Service层
    /**
     * 审核机构认证信息
     * @param id
     * @param certificationAuditReqDTO
     */
    @Override
    public void auditCertification(Long id, CertificationAuditReqDTO certificationAuditReqDTO) {
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        LambdaUpdateWrapper<AgencyCertificationAudit> updateWrapper = Wrappers.<AgencyCertificationAudit>lambdaUpdate()
                .eq(AgencyCertificationAudit::getId, id)
                .set(AgencyCertificationAudit::getAuditStatus, EnableStatusEnum.ENABLE.getStatus())
                .set(AgencyCertificationAudit::getAuditorId, currentUserInfo.getId())
                .set(AgencyCertificationAudit::getAuditorName, currentUserInfo.getName())
                .set(AgencyCertificationAudit::getAuditTime, LocalDateTime.now())
                .set(AgencyCertificationAudit::getCertificationStatus, certificationAuditReqDTO.getCertificationStatus())
                .set(ObjectUtil.isNotEmpty(certificationAuditReqDTO.getRejectReason()), AgencyCertificationAudit::getRejectReason, certificationAuditReqDTO.getRejectReason());
        super.update(updateWrapper);

        //更新认证信息,如果认证成功,需要将各认证属性也更新
        AgencyCertificationAudit agencyCertificationAudit = baseMapper.selectById(id);
        AgencyCertificationUpdateDTO agencyCertificationUpdateDTO = new AgencyCertificationUpdateDTO();
        agencyCertificationUpdateDTO.setId(agencyCertificationAudit.getServeProviderId());
        agencyCertificationUpdateDTO.setCertificationStatus(certificationAuditReqDTO.getCertificationStatus());

        if (ObjectUtil.equal(CertificationStatusEnum.SUCCESS.getStatus(), certificationAuditReqDTO.getCertificationStatus())) {
            //如果认证成功,需要更新服务人员/机构名称
            serveProviderService.updateNameById(agencyCertificationAudit.getServeProviderId(), agencyCertificationAudit.getName());

            agencyCertificationUpdateDTO.setName(agencyCertificationAudit.getName());
            agencyCertificationUpdateDTO.setIdNumber(agencyCertificationAudit.getIdNumber());
            agencyCertificationUpdateDTO.setLegalPersonName(agencyCertificationAudit.getLegalPersonName());
            agencyCertificationUpdateDTO.setLegalPersonIdCardNo(agencyCertificationAudit.getLegalPersonIdCardNo());
            agencyCertificationUpdateDTO.setBusinessLicense(agencyCertificationAudit.getBusinessLicense());
            agencyCertificationUpdateDTO.setCertificationTime(agencyCertificationAudit.getAuditTime());
        }
        agencyCertificationService.updateByServeProviderId(agencyCertificationUpdateDTO);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/669368.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

游戏主播到底是为游戏宣传还是蹭游戏带来的热度

易采游戏网6月1日最新消息&#xff1a;近日知名游戏主播周淑怡在社交平台上发表了自己对《地下城与勇士》手游(简称DNF手游)的点评。作为一款拥有庞大粉丝基础的端游改编作品&#xff0c;DNF手游自发布以来便受到了广泛关注。而周淑怡的点评不仅聚焦于游戏体验本身&#xff0c;…

visual studis 安装教程

1、下载软件 2、直接安装。根据自己的需求选择需要的模板类型。 如果是.net环境&#xff0c;可以选择.net项目&#xff1b; 如果是c环境&#xff0c;可以选择c项目模板&#xff0c;多个模板可以同时并存。 3、选择C模板&#xff0c;然后重新启动项目。 我是小路&#xff0c;一枚…

Flutter基础 -- Dart 语言 -- 列表集合枚举

目录 1. 列表 List 1.1 初始 1.2 声明 1.2.1 自动 1.2.2 定长 1.2.3 生成数据 1.3 属性 1.4 方法 1.4.1 添加 1.4.2 查询 1.4.3 删除 1.4.4 Range 1.4.5 洗牌 1.4.6 排序 1.4.7 复制子列表 1.4.8 操作符 2. 集合 Map 2.1 初始 2.2 声明 2.2.1 松散 2.2.2 …

7、架构-架构的安全性

即使只限定在“软件架构设计”这个语境下&#xff0c;系统安全仍然是一 个很大的话题。我们谈论的计算机系统安全&#xff0c;不仅仅是指“防御系统 被黑客攻击”这样狭隘的安全&#xff0c;还至少应包括&#xff08;不限于&#xff09;以下这些问 题的具体解决方案。 认证&am…

小白教你搭建测试环境(docker部署版)

如何使用docker创建多数据库端口&#xff08;云服务器版&#xff09; 背景&#xff1a; 需要搭建一个测试环境&#xff0c;同时还需要不同的端口映射mysql端口。那么我采用的docker拉取mysql镜像&#xff0c;通过宿主机和docker容器端口映射完成。 准备一台云服务器服务器安装…

[书生·浦语大模型实战营]——训练自己的小助手认知+应用部署到 OpenXLab+复现多模态微调

1.训练自己的小助手认知 微调后的回答&#xff1a; 微调前的回答&#xff1a; 2.应用部署到 OpenXLab 上传的自我认知模型 应用部署在OpenXLab&#xff08;比上次部署方便不少&#xff0c;文档写的更清楚了&#xff0c;棒棒&#xff09;,链接如下应用链接 3.复现多模态…

SLAM精度评估—evo

evo是一款用于SLAM轨迹精度的评估工具。核心功能是&#xff08;1&#xff09;能够绘制&#xff08;传感器运动&#xff09;轨迹&#xff0c;&#xff08;2&#xff09;评估估计轨迹与真值&#xff08;ground truth&#xff09;的误差。evo支持多种数据集的轨迹格式(TUM、KITT、…

php之文件操作代码审计

1 PHP文件操作函数 1.1 PHP文件操作函数 文件包含 include/require/include_once/require_once 文件读取 file_get_contents/fread/readfile/file 文件写入 file_put_contents/fwrite/mkdir/fputs 文件删除 unlink/rmdir 文件上传 move_uploaded_file/copy/rename 1.2 文…

Error CREATEing SolrCore ‘new_core‘ Unable to create core [new_core]

Error CREATEing SolrCore new_core: Unable to create core [new_core] Caused by: Cant find resource solrconfig.xml in classpath or F:\Document_Solr.apache.org\solr-8.11.3\server\solr\new_core

VHDL/CPLD硬件描述语言:2022年做的万年历实验

之前接触过一些硬件描述语言以及VHDL/CPLD的单片机的设计实验&#xff0c;那时是2022年了 这里补写一篇笔记,以记录一下那十多个小时 万年历实验 研究中的心得体会&#xff1a; 说明解释都是个人理解&#xff0c;与标准描述有较大出入...... 目录 输入输出器件的编写: 分频器…

年中汇报季?——一文教会你如何进行数据分析

一、常见的数据分析报告类型 数据分析报告通常可以分为三类&#xff1a;日常分析报告、专题型分析报告和综合性分析报告。前两者是以数据结论建议的格式去撰写&#xff0c;综合性分析报告则是&#xff1a;行业环境调研&#xff08;竞品类产品数据分析&#xff09;自身产品数据…

张大哥笔记:你卖什么,就反着来卖

普通人打工的一生&#xff0c;就是努力工作&#xff0c;买房&#xff0c;买车&#xff0c;送孩子上好的学校&#xff0c;为了孩子不要输在起跑线上&#xff0c;拼命报各种补习班等&#xff0c;这些都是普通人认为的主流价值观文化&#xff0c;也造就了一批批的赚钱机器&#xf…

深度解析 Spring 源码:探秘 CGLIB 代理的奥秘

文章目录 一、CGLIB 代理简介1.1 CGLIB 代理的基本原理和特点1.2 分析 CGLIB 如何通过字节码技术创建代理类 二、深入分析 CglibAopProxy 类的结构2.1 CglibAopProxy 类结构2.2 CglibAopProxy 类源码 三、CGLIB 代理对象的创建过程3.1 配置 Enhancer 生成代理对象3.2 探讨如何通…

【斯坦福因果推断课程全集】1_随机对照试验1

目录 The average treatment effect Difference-in-means estimation IID Sampling and Population Asymptotics Example: The linear model Regression adjustments with a linear model 随机对照试验&#xff08;RCT&#xff09;是统计因果推论的基础。如果有的话&#…

Linux - 文件管理高级 sed

3.处理字符 sed ① sed 默认情况下不会修改原文件内容 ② sed 是一种非交互式的编辑器 3.1 工作原理 将原文件一行一行的进行处理&#xff0c;取出一行&#xff0c;放入“模式空间进行处理”&#xff0c;处理完成之后将结果输出到屏幕上&#xff0c;然后读取下一行&#xf…

瓦罗兰特国际服 外服游玩教程 瓦罗兰特外服下载注册游玩指南

瓦罗兰特国际服 外服游玩教程 瓦罗兰特外服下载注册游玩指南 瓦罗兰特作为当今游戏圈顶流的一款热门FPS。游戏&#xff0c;作为拳头游戏公司划时代的一款游戏。游戏不仅延续了传统FPS游戏的玩法&#xff0c;还添加许多新玩法&#xff0c;这也是游戏可以吸引大批量玩家的原因之…

vulnhub靶场之FunBox-10

一.环境搭建 1.靶场描述 As always, its a very easy box for beginners. This works better on VitualBox rather than VMware 2.靶场下载 Funbox: Under Construction! ~ VulnHub 3.靶场启动 靶场IP地址我们不知道&#xff0c;但是网段我们知道是192.168.2.0/24 二.信息…

Filter和ServletContext和Listener

目录 Filter案例 解决全站乱码问题 登录权限校验 ServletContext对象 Listener&#xff08;监听器&#xff09; Filter案例 解决全站乱码问题 我们每次访问每个servlet都要书写处理请求和响应乱码的代码&#xff0c;这样代码十分冗余&#xff0c;所以我们可以在过滤中 We…

python列表的进阶

小结&#xff1a; # 列表的删除小结&#xff1a; # 删除列表的最后一列 punished students.pop() print(被罚站的人是&#xff1a; punished &#xff0c;同学们引以为戒。)# 根据下标删除 del students[0]#根据名称删除 students.remove(王熙凤)在今天的课程里&#xff0c…

k8s自定义资源你会创建吗

创建自定义资源定义 CustomResourceDefinition 当你创建新的 CustomResourceDefinition&#xff08;CRD&#xff09;时&#xff0c;Kubernetes API 服务器会为你所 指定的每一个版本生成一个 RESTful 的 资源路径。CRD 可以是名字空间作用域的&#xff0c;也可以是集群作用域的…