| | |
| | | @Override |
| | | public VinManagementClient create(Throwable throwable) { |
| | | log.error("VIN 管理服务调用失败:{}", throwable.getMessage()); |
| | | return apppUserId -> R.fail("VIN 管理服务调用失败:" + throwable.getMessage()); |
| | | return appUserId -> R.fail("VIN 管理服务调用失败:" + throwable.getMessage()); |
| | | } |
| | | } |
| | |
| | | fallbackFactory = VinManagementFallbackFactory.class) |
| | | public interface VinManagementClient { |
| | | |
| | | @GetMapping("/t-vin-management/inner/ids-by-appp-user") |
| | | R<List<Long>> getVinIdsByApppUserId(@RequestParam("apppUserId") Long apppUserId); |
| | | @GetMapping("/t-vin-management/inner/ids-by-app-user") |
| | | R<List<Long>> getVinIdsByAppUserId(@RequestParam("appUserId") Long appUserId); |
| | | } |
| | |
| | | @Excel(name = "备注", width = 30) private String remark; |
| | | @Excel(name = "启用状态", readConverterExp = "1=启用,2=禁用") private Integer status; |
| | | @TableLogic(value = "0", delval = "2") private Integer delFlag; |
| | | @TableField("appp_user_id") private Long apppUserId; |
| | | @TableField("app_user_id") private Long appUserId; |
| | | @TableField(exist = false) private Integer chargingGunId; |
| | | @TableField(exist = false) private Boolean charging; |
| | | private LocalDateTime createTime; |
| | |
| | | return R.ok(service.unbindAppletVehicle(id, tokenService.getLoginUserApplet().getUserId())); |
| | | } |
| | | |
| | | @GetMapping("/inner/ids-by-appp-user") |
| | | public R<List<Long>> getVinIdsByApppUserId(@RequestParam Long apppUserId) { |
| | | return R.ok(service.getVinIdsByApppUserId(apppUserId)); |
| | | @GetMapping("/inner/ids-by-app-user") |
| | | public R<List<Long>> getVinIdsByAppUserId(@RequestParam Long appUserId) { |
| | | return R.ok(service.getVinIdsByAppUserId(appUserId)); |
| | | } |
| | | } |
| | |
| | | IPage<TVinManagement> selectPageList(Page<TVinManagement> page, @Param("query") VinManagementQueryDTO query); |
| | | List<VinManagementExcelDTO> selectExportList(@Param("query") VinManagementQueryDTO query); |
| | | int countByVin(@Param("vin") String vin, @Param("excludeId") Long excludeId); |
| | | List<TVinManagement> selectAppletVehicleList(@Param("apppUserId") Long apppUserId); |
| | | List<TVinManagement> selectAppletVehicleList(@Param("appUserId") Long appUserId); |
| | | TVinManagement selectEnabledVehicle(@Param("keyword") String keyword); |
| | | int bindAppletVehicle(@Param("id") Long id, @Param("apppUserId") Long apppUserId); |
| | | int unbindAppletVehicle(@Param("id") Long id, @Param("apppUserId") Long apppUserId); |
| | | List<Long> selectIdsByApppUserId(@Param("apppUserId") Long apppUserId); |
| | | int bindAppletVehicle(@Param("id") Long id, @Param("appUserId") Long appUserId); |
| | | int unbindAppletVehicle(@Param("id") Long id, @Param("appUserId") Long appUserId); |
| | | List<Long> selectIdsByAppUserId(@Param("appUserId") Long appUserId); |
| | | } |
| | |
| | | boolean updateStatus(Long id, Integer status); |
| | | List<VinManagementExcelDTO> selectExportList(VinManagementQueryDTO query); |
| | | String importVins(List<VinManagementExcelDTO> items); |
| | | List<TVinManagement> selectAppletVehicleList(Long apppUserId); |
| | | boolean bindAppletVehicle(Long apppUserId, String keyword); |
| | | boolean unbindAppletVehicle(Long id, Long apppUserId); |
| | | List<Long> getVinIdsByApppUserId(Long apppUserId); |
| | | List<TVinManagement> selectAppletVehicleList(Long appUserId); |
| | | boolean bindAppletVehicle(Long appUserId, String keyword); |
| | | boolean unbindAppletVehicle(Long id, Long appUserId); |
| | | List<Long> getVinIdsByAppUserId(Long appUserId); |
| | | } |
| | |
| | | @Override public boolean deleteVins(List<Long> ids) { if (ids == null || ids.isEmpty()) throw new ServiceException("请选择需要删除的VIN码"); List<Long> distinct = new ArrayList<>(new HashSet<>(ids)); if (listByIds(distinct).size() != distinct.size()) throw new ServiceException("部分VIN码不存在或已删除"); return removeByIds(distinct); } |
| | | @Override public boolean updateStatus(Long id, Integer status) { if (id == null || !validStatus(status)) throw new ServiceException("VIN码状态参数错误"); if (getById(id) == null) throw new ServiceException("VIN码不存在或已删除"); TVinManagement item = new TVinManagement(); item.setId(id); item.setStatus(status); item.setUpdateTime(LocalDateTime.now()); item.setUpdateBy(SecurityUtils.getUserId()); return updateById(item); } |
| | | @Override public List<VinManagementExcelDTO> selectExportList(VinManagementQueryDTO query) { return baseMapper.selectExportList(query == null ? new VinManagementQueryDTO() : query); } |
| | | @Override public List<TVinManagement> selectAppletVehicleList(Long apppUserId) { |
| | | List<TVinManagement> vehicles = baseMapper.selectAppletVehicleList(apppUserId); |
| | | @Override public List<TVinManagement> selectAppletVehicleList(Long appUserId) { |
| | | List<TVinManagement> vehicles = baseMapper.selectAppletVehicleList(appUserId); |
| | | if (vehicles == null || vehicles.isEmpty()) return vehicles; |
| | | vehicles.forEach(vehicle -> vehicle.setCharging(false)); |
| | | List<Long> vinIds = new ArrayList<>(); |
| | |
| | | } |
| | | } |
| | | } catch (Exception ex) { |
| | | log.warn("查询 VIN 车辆充电状态失败,按未充电返回,apppUserId={}", apppUserId, ex); |
| | | log.warn("查询 VIN 车辆充电状态失败,按未充电返回,appUserId={}", appUserId, ex); |
| | | } |
| | | return vehicles; |
| | | } |
| | | @Override @Transactional(rollbackFor = Exception.class) public boolean bindAppletVehicle(Long apppUserId, String keyword) { |
| | | @Override @Transactional(rollbackFor = Exception.class) public boolean bindAppletVehicle(Long appUserId, String keyword) { |
| | | String exactKeyword = trim(keyword); |
| | | if (StringUtils.isEmpty(exactKeyword)) throw new ServiceException("请输入VIN码或车牌号"); |
| | | TVinManagement vehicle = baseMapper.selectEnabledVehicle(exactKeyword); |
| | | if (vehicle == null) throw new ServiceException("该车辆不存在"); |
| | | if (apppUserId.equals(vehicle.getApppUserId())) throw new ServiceException("该车辆已绑定当前用户"); |
| | | if (vehicle.getApppUserId() != null) throw new ServiceException("该车辆已被其他用户绑定"); |
| | | if (baseMapper.bindAppletVehicle(vehicle.getId(), apppUserId) > 0) return true; |
| | | if (appUserId.equals(vehicle.getAppUserId())) throw new ServiceException("该车辆已绑定当前用户"); |
| | | if (vehicle.getAppUserId() != null) throw new ServiceException("该车辆已被其他用户绑定"); |
| | | if (baseMapper.bindAppletVehicle(vehicle.getId(), appUserId) > 0) return true; |
| | | TVinManagement latest = baseMapper.selectById(vehicle.getId()); |
| | | if (latest != null && apppUserId.equals(latest.getApppUserId())) throw new ServiceException("该车辆已绑定当前用户"); |
| | | if (latest != null && appUserId.equals(latest.getAppUserId())) throw new ServiceException("该车辆已绑定当前用户"); |
| | | throw new ServiceException("该车辆已被其他用户绑定"); |
| | | } |
| | | @Override @Transactional(rollbackFor = Exception.class) public boolean unbindAppletVehicle(Long id, Long apppUserId) { |
| | | if (id == null || baseMapper.unbindAppletVehicle(id, apppUserId) == 0) throw new ServiceException("该车辆不存在"); |
| | | @Override @Transactional(rollbackFor = Exception.class) public boolean unbindAppletVehicle(Long id, Long appUserId) { |
| | | if (id == null || baseMapper.unbindAppletVehicle(id, appUserId) == 0) throw new ServiceException("该车辆不存在"); |
| | | return true; |
| | | } |
| | | @Override public List<Long> getVinIdsByApppUserId(Long apppUserId) { return baseMapper.selectIdsByApppUserId(apppUserId); } |
| | | @Override public List<Long> getVinIdsByAppUserId(Long appUserId) { return baseMapper.selectIdsByAppUserId(appUserId); } |
| | | @Override @Transactional(rollbackFor = Exception.class) public String importVins(List<VinManagementExcelDTO> items) { if (items == null || items.isEmpty()) throw new ServiceException("导入数据不能为空"); Set<String> vins = new HashSet<>(); int row = 1; for (VinManagementExcelDTO item : items) { row++; if (item == null || StringUtils.isEmpty(item.getVin())) throw new ServiceException("第" + row + "行VIN码不能为空"); String vin = item.getVin().trim(); if (vin.length() > 64) throw new ServiceException("第" + row + "行VIN码不能超过64个字符"); if (!vins.add(vin) || baseMapper.countByVin(vin, null) > 0) throw new ServiceException("第" + row + "行VIN码已存在或重复"); parseStatus(item.getStatus(), row); } Long userId = SecurityUtils.getUserId(); LocalDateTime now = LocalDateTime.now(); for (VinManagementExcelDTO item : items) { TVinManagement v = new TVinManagement(); v.setVin(item.getVin().trim()); v.setPlateNumber(trim(item.getPlateNumber())); v.setPhone(trim(item.getPhone())); v.setCompanyName(trim(item.getCompanyName())); v.setRemark(trim(item.getRemark())); v.setStatus(parseStatus(item.getStatus(), 0)); v.setDelFlag(0); v.setCreateBy(userId); v.setCreateTime(now); save(v); } return "成功导入" + items.size() + "条VIN码数据"; } |
| | | private void validate(VinManagementSaveDTO dto, boolean update) { if (dto == null || StringUtils.isEmpty(dto.getVin())) throw new ServiceException("VIN码不能为空"); if (update && dto.getId() == null) throw new ServiceException("VIN码ID不能为空"); String vin = dto.getVin().trim(); if (vin.length() > 64) throw new ServiceException("VIN码不能超过64个字符"); if (!validStatus(dto.getStatus() == null ? ENABLED : dto.getStatus())) throw new ServiceException("VIN码状态参数错误"); if (baseMapper.countByVin(vin, dto.getId()) > 0) throw new ServiceException("VIN码已存在"); } |
| | | private TVinManagement from(VinManagementSaveDTO d) { TVinManagement v = new TVinManagement(); v.setVin(d.getVin().trim()); v.setPlateNumber(trim(d.getPlateNumber())); v.setPhone(trim(d.getPhone())); v.setCompanyName(trim(d.getCompanyName())); v.setRemark(trim(d.getRemark())); v.setStatus(d.getStatus() == null ? ENABLED : d.getStatus()); return v; } |
| | |
| | | </select> |
| | | <select id="countByVin" resultType="int">SELECT COUNT(1) FROM t_vin_management WHERE vin = #{vin}<if test="excludeId != null"> AND id != #{excludeId}</if></select> |
| | | <select id="selectAppletVehicleList" resultType="com.ruoyi.account.api.model.TVinManagement"> |
| | | SELECT id, vin, plate_number, phone, company_name, remark, status, del_flag, appp_user_id, create_time, create_by, update_time, update_by |
| | | SELECT id, vin, plate_number, phone, company_name, remark, status, del_flag, app_user_id, create_time, create_by, update_time, update_by |
| | | FROM t_vin_management |
| | | WHERE appp_user_id = #{apppUserId} AND status = 1 AND del_flag = 0 |
| | | WHERE app_user_id = #{appUserId} AND status = 1 AND del_flag = 0 |
| | | ORDER BY create_time DESC, id DESC |
| | | </select> |
| | | <select id="selectEnabledVehicle" resultType="com.ruoyi.account.api.model.TVinManagement"> |
| | | SELECT id, vin, plate_number, phone, company_name, remark, status, del_flag, appp_user_id, create_time, create_by, update_time, update_by |
| | | SELECT id, vin, plate_number, phone, company_name, remark, status, del_flag, app_user_id, create_time, create_by, update_time, update_by |
| | | FROM t_vin_management |
| | | WHERE status = 1 AND del_flag = 0 |
| | | AND (vin = #{keyword} OR plate_number = #{keyword}) |
| | |
| | | LIMIT 1 |
| | | </select> |
| | | <update id="bindAppletVehicle"> |
| | | UPDATE t_vin_management SET appp_user_id = #{apppUserId}, update_time = NOW() |
| | | WHERE id = #{id} AND appp_user_id IS NULL AND status = 1 AND del_flag = 0 |
| | | UPDATE t_vin_management SET app_user_id = #{appUserId}, update_time = NOW() |
| | | WHERE id = #{id} AND app_user_id IS NULL AND status = 1 AND del_flag = 0 |
| | | </update> |
| | | <update id="unbindAppletVehicle"> |
| | | UPDATE t_vin_management SET appp_user_id = NULL, update_time = NOW() |
| | | WHERE id = #{id} AND appp_user_id = #{apppUserId} AND status = 1 AND del_flag = 0 |
| | | UPDATE t_vin_management SET app_user_id = NULL, update_time = NOW() |
| | | WHERE id = #{id} AND app_user_id = #{appUserId} AND status = 1 AND del_flag = 0 |
| | | </update> |
| | | <select id="selectIdsByApppUserId" resultType="java.lang.Long"> |
| | | <select id="selectIdsByAppUserId" resultType="java.lang.Long"> |
| | | SELECT id FROM t_vin_management |
| | | WHERE appp_user_id = #{apppUserId} AND status = 1 AND del_flag = 0 |
| | | WHERE app_user_id = #{appUserId} AND status = 1 AND del_flag = 0 |
| | | ORDER BY id ASC |
| | | </select> |
| | | </mapper> |
| | |
| | | } |
| | | |
| | | @Test |
| | | void innerIdsEndpointDelegatesApppUserId() { |
| | | void innerIdsEndpointDelegatesAppUserId() { |
| | | TVinManagementService service = mock(TVinManagementService.class); |
| | | when(service.getVinIdsByApppUserId(88L)).thenReturn(Arrays.asList(1L, 2L)); |
| | | when(service.getVinIdsByAppUserId(88L)).thenReturn(Arrays.asList(1L, 2L)); |
| | | TVinManagementController controller = buildController(service); |
| | | assertEquals(Arrays.asList(1L, 2L), controller.getVinIdsByApppUserId(88L).getData()); |
| | | assertEquals(Arrays.asList(1L, 2L), controller.getVinIdsByAppUserId(88L).getData()); |
| | | } |
| | | |
| | | private MockMultipartFile vinExcelFile() throws Exception { |
| | |
| | | void bindAppletVehicleRejectsVehicleAlreadyBoundToCurrentUser() { |
| | | TVinManagement vehicle = new TVinManagement(); |
| | | vehicle.setId(9L); |
| | | vehicle.setApppUserId(88L); |
| | | vehicle.setAppUserId(88L); |
| | | when(mapper.selectEnabledVehicle("川A12345")).thenReturn(vehicle); |
| | | ServiceException ex = assertThrows(ServiceException.class, |
| | | () -> service.bindAppletVehicle(88L, "川A12345")); |
| | |
| | | void bindAppletVehicleDoesNotOverwriteOtherUser() { |
| | | TVinManagement vehicle = new TVinManagement(); |
| | | vehicle.setId(9L); |
| | | vehicle.setApppUserId(99L); |
| | | vehicle.setAppUserId(99L); |
| | | when(mapper.selectEnabledVehicle("川A12345")).thenReturn(vehicle); |
| | | ServiceException ex = assertThrows(ServiceException.class, |
| | | () -> service.bindAppletVehicle(88L, "川A12345")); |
| | |
| | | } |
| | | |
| | | @Test |
| | | void getVinIdsByApppUserIdReturnsMapperResult() { |
| | | when(mapper.selectIdsByApppUserId(88L)).thenReturn(Arrays.asList(1L, 2L)); |
| | | assertEquals(Arrays.asList(1L, 2L), service.getVinIdsByApppUserId(88L)); |
| | | void getVinIdsByAppUserIdReturnsMapperResult() { |
| | | when(mapper.selectIdsByAppUserId(88L)).thenReturn(Arrays.asList(1L, 2L)); |
| | | assertEquals(Arrays.asList(1L, 2L), service.getVinIdsByAppUserId(88L)); |
| | | } |
| | | |
| | | private String longVin(int length) { |
| | |
| | | page.setRecords(Collections.emptyList()); |
| | | return page; |
| | | } |
| | | Long apppUserId = tokenService.getLoginUserApplet().getUserId(); |
| | | R<List<Long>> vinIdResponse = vinManagementClient.getVinIdsByApppUserId(apppUserId); |
| | | Long appUserId = tokenService.getLoginUserApplet().getUserId(); |
| | | R<List<Long>> vinIdResponse = vinManagementClient.getVinIdsByAppUserId(appUserId); |
| | | List<Long> vinIds = vinIdResponse == null ? Collections.emptyList() |
| | | : Optional.ofNullable(vinIdResponse.getData()).orElse(Collections.emptyList()); |
| | | if (vinIds.isEmpty()) { |
| | |
| | | LoginUserApplet loginUser = new LoginUserApplet(); |
| | | loginUser.setUserId(88L); |
| | | when(tokenService.getLoginUserApplet()).thenReturn(loginUser); |
| | | when(vinManagementClient.getVinIdsByApppUserId(88L)).thenReturn(R.ok(Arrays.asList(11L, 22L))); |
| | | when(vinManagementClient.getVinIdsByAppUserId(88L)).thenReturn(R.ok(Arrays.asList(11L, 22L))); |
| | | when(mapper.countAppletOrders(Arrays.asList(11L, 22L))).thenReturn(1L); |
| | | MyVinChargingOrderList order = new MyVinChargingOrderList(); |
| | | order.setId(1001L); |
| | |
| | | |
| | | assertEquals(1L, result.getTotal()); |
| | | assertEquals(1001L, result.getRecords().get(0).getId()); |
| | | verify(vinManagementClient).getVinIdsByApppUserId(88L); |
| | | verify(vinManagementClient).getVinIdsByAppUserId(88L); |
| | | verify(mapper).pageAppletOrders(Arrays.asList(11L, 22L), 10L, 10L); |
| | | } |
| | | |
| | |
| | | LoginUserApplet loginUser = new LoginUserApplet(); |
| | | loginUser.setUserId(88L); |
| | | when(tokenService.getLoginUserApplet()).thenReturn(loginUser); |
| | | when(vinManagementClient.getVinIdsByApppUserId(88L)).thenReturn(R.ok(Collections.emptyList())); |
| | | when(vinManagementClient.getVinIdsByAppUserId(88L)).thenReturn(R.ok(Collections.emptyList())); |
| | | |
| | | PageInfo<MyVinChargingOrderList> result = service.pageAppletOrders(1, 10); |
| | | |
| | |
| | | |
| | | -- 中文字段注释 |
| | | -- 修正历史纯英文、乱码或空白字段注释 |
| | | ALTER TABLE `charging_pile_account`.`t_vin_management` MODIFY COLUMN `appp_user_id` bigint NULL DEFAULT NULL COMMENT '绑定的小程序用户ID(三个p)'; |
| | | ALTER TABLE `charging_pile_account`.`t_vin_management` MODIFY COLUMN `app_user_id` bigint NULL DEFAULT NULL COMMENT '绑定的小程序用户ID'; |
| | | ALTER TABLE `charging_pile_order`.`t_vip_order_refund` MODIFY COLUMN `pay_type` int NULL DEFAULT NULL COMMENT '支付方式:1微信,2支付宝'; |
| | | ALTER TABLE `charging_pile_order`.`t_shopping_order_refund` MODIFY COLUMN `pay_type` int NULL DEFAULT NULL COMMENT '支付方式:1微信,2支付宝'; |
| | | ALTER TABLE `charging_pile_order`.`t_charging_order_refund` MODIFY COLUMN `pay_type` int NULL DEFAULT NULL COMMENT '支付方式:1微信,2支付宝'; |
| | |
| | | -- VIN 小程序车辆绑定字段增量脚本,请使用 UTF-8 执行。 |
| | | USE `charging_pile_account`; |
| | | -- 小程序 VIN 车辆绑定字段(app_user_id) |
| | | -- 说明:绑定列统一命名为 app_user_id,脚本幂等可重复执行 |
| | | |
| | | SET @column_exists := ( |
| | | SELECT COUNT(1) |
| | | FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() |
| | | AND TABLE_NAME = 't_vin_management' |
| | | AND COLUMN_NAME = 'appp_user_id' |
| | | AND COLUMN_NAME = 'app_user_id' |
| | | ); |
| | | SET @column_sql := IF( |
| | | @column_exists = 0, |
| | | 'ALTER TABLE `t_vin_management` ADD COLUMN `appp_user_id` BIGINT NULL COMMENT ''绑定的小程序用户ID(三个p)'' AFTER `del_flag`', |
| | | 'ALTER TABLE `t_vin_management` ADD COLUMN `app_user_id` BIGINT NULL COMMENT ''绑定的小程序用户ID'' AFTER `del_flag`', |
| | | 'SELECT 1' |
| | | ); |
| | | PREPARE column_stmt FROM @column_sql; |
| | |
| | | FROM information_schema.STATISTICS |
| | | WHERE TABLE_SCHEMA = DATABASE() |
| | | AND TABLE_NAME = 't_vin_management' |
| | | AND INDEX_NAME = 'idx_appp_user_id' |
| | | AND INDEX_NAME = 'idx_app_user_id' |
| | | ); |
| | | SET @index_sql := IF( |
| | | @index_exists = 0, |
| | | 'ALTER TABLE `t_vin_management` ADD INDEX `idx_appp_user_id` (`appp_user_id`)', |
| | | 'ALTER TABLE `t_vin_management` ADD INDEX `idx_app_user_id` (`app_user_id`)', |
| | | 'SELECT 1' |
| | | ); |
| | | PREPARE index_stmt FROM @index_sql; |
| New file |
| | |
| | | -- VIN 车辆绑定字段统一改名:appp_user_id -> app_user_id(含索引与注释) |
| | | -- 背景:历史拼写错误(三个 p)已废弃,全链路统一为 app_user_id。 |
| | | -- 目标库:charging_pile_account.t_vin_management |
| | | -- 适用:MySQL(含 Mycat 代理下的 MySQL 8 后端)。Mycat 对 PREPARE/INFORMATION_SCHEMA 变量支持不稳定时, |
| | | -- 可直接执行下方「直接 DDL」小节并回查。 |
| | | -- 脚本幂等:列/索引若已是 app_user_id 则自动跳过。 |
| | | |
| | | USE `charging_pile_account`; |
| | | |
| | | SET @has_old_column := ( |
| | | SELECT COUNT(1) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = 'charging_pile_account' AND TABLE_NAME = 't_vin_management' AND COLUMN_NAME = 'appp_user_id' |
| | | ); |
| | | SET @has_new_column := ( |
| | | SELECT COUNT(1) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = 'charging_pile_account' AND TABLE_NAME = 't_vin_management' AND COLUMN_NAME = 'app_user_id' |
| | | ); |
| | | SET @rename_column_sql := IF( |
| | | @has_old_column = 1 AND @has_new_column = 0, |
| | | 'ALTER TABLE `t_vin_management` CHANGE COLUMN `appp_user_id` `app_user_id` bigint NULL DEFAULT NULL COMMENT ''绑定的小程序用户ID'' AFTER `del_flag`', |
| | | 'SELECT 1' |
| | | ); |
| | | PREPARE rename_column_stmt FROM @rename_column_sql; |
| | | EXECUTE rename_column_stmt; |
| | | DEALLOCATE PREPARE rename_column_stmt; |
| | | |
| | | SET @has_old_index := ( |
| | | SELECT COUNT(1) FROM information_schema.STATISTICS |
| | | WHERE TABLE_SCHEMA = 'charging_pile_account' AND TABLE_NAME = 't_vin_management' AND INDEX_NAME = 'idx_appp_user_id' |
| | | ); |
| | | SET @has_new_index := ( |
| | | SELECT COUNT(1) FROM information_schema.STATISTICS |
| | | WHERE TABLE_SCHEMA = 'charging_pile_account' AND TABLE_NAME = 't_vin_management' AND INDEX_NAME = 'idx_app_user_id' |
| | | ); |
| | | -- 旧索引改名(MySQL 8 / Mycat 透传不支持时改为 DROP+ADD 两条直接 DDL 手动执行) |
| | | SET @rename_index_sql := IF( |
| | | @has_old_index = 1 AND @has_new_index = 0, |
| | | 'ALTER TABLE `t_vin_management` RENAME INDEX `idx_appp_user_id` TO `idx_app_user_id`', |
| | | 'SELECT 1' |
| | | ); |
| | | PREPARE rename_index_stmt FROM @rename_index_sql; |
| | | EXECUTE rename_index_stmt; |
| | | DEALLOCATE PREPARE rename_index_stmt; |
| | | |
| | | -- 兜底:新列已存在但缺少索引时补建(兼容旧环境索引名不是 idx_app_user_id 的情况) |
| | | SET @ensure_index_sql := IF( |
| | | @has_new_column = 1 AND @has_new_index = 0, |
| | | 'ALTER TABLE `t_vin_management` ADD INDEX `idx_app_user_id` (`app_user_id`)', |
| | | 'SELECT 1' |
| | | ); |
| | | PREPARE ensure_index_stmt FROM @ensure_index_sql; |
| | | EXECUTE ensure_index_stmt; |
| | | DEALLOCATE PREPARE ensure_index_stmt; |
| | | |
| | | -- 注释兜底:确保 app_user_id 注释为「绑定的小程序用户ID」(无「三个p」字样) |
| | | SET @comment_exists := ( |
| | | SELECT COUNT(1) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = 'charging_pile_account' AND TABLE_NAME = 't_vin_management' |
| | | AND COLUMN_NAME = 'app_user_id' AND COLUMN_COMMENT LIKE '%三个p%' |
| | | ); |
| | | SET @fix_comment_sql := IF( |
| | | @has_new_column = 1 AND @comment_exists = 1, |
| | | 'ALTER TABLE `t_vin_management` MODIFY COLUMN `app_user_id` bigint NULL DEFAULT NULL COMMENT ''绑定的小程序用户ID'' AFTER `del_flag`', |
| | | 'SELECT 1' |
| | | ); |
| | | PREPARE fix_comment_stmt FROM @fix_comment_sql; |
| | | EXECUTE fix_comment_stmt; |
| | | DEALLOCATE PREPARE fix_comment_stmt; |
| | | |
| | | -- ========== 直接 DDL 小节(Mycat 下如上面 PREPARE 报错,可按序手工执行以下三条) ========== |
| | | -- ALTER TABLE `charging_pile_account`.`t_vin_management` |
| | | -- CHANGE COLUMN `appp_user_id` `app_user_id` bigint NULL DEFAULT NULL COMMENT '绑定的小程序用户ID' AFTER `del_flag`; |
| | | -- ALTER TABLE `charging_pile_account`.`t_vin_management` |
| | | -- ADD INDEX `idx_app_user_id` (`app_user_id`); |