From 08cc6d5cf7e93b75cfabe7dcc2aeaa9afa1117eb Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 12 五月 2026 15:01:47 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.1

---
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/GroupUserPageQuery.java                                      |    3 
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestPointManagementController.java                                  |   33 
 xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java                           |   45 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java                           |   33 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/SysUserListQuery.java                                        |    4 
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java                    |  149 +
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java                             |  140 ++
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java                                 |   21 
 xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml                                            |    7 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/SysLogClientFallbackFactory.java                                    |   14 
 xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java                        |   36 
 xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/service/WebSocketUserChannelConnectionManager.java    |  282 ++++
 xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml                                                |    7 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/PropertiesAutoConfiguration.java                                      |   10 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaskOrderCancelUtil.java                                               |    3 
 xp-robotaxi-account-boot/src/main/resources/mapper/account/SysGroupMapper.xml                                                        |   14 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysUserServiceImpl.java                                     |  120 +
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAdminOperationLogController.java                        |   74 +
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java                                            |   52 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpAdminOperationLogMapper.java                                |   10 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java                                  |   42 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java                                |   21 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/BluetoothDebugConfig.java                                             |   50 
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java                                                  |    2 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java                     |   15 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java                               |    4 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java                                    |    2 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java                                 |   27 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java                       |   21 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java                                        |   41 
 xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml                                          |    7 
 xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/annotation/AdminOperationLog.java                             |   54 
 xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleExportQuery.java                         |    3 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java                                          |    6 
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java                         |   21 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpQualificationAuditServiceImpl.java                        |    3 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/vehicleConvoy/BluetoothDeliverVo.java                                              |    4 
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java                       |   27 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java                               |   21 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpQualificationAuditQuery.java                               |    4 
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java                            |   27 
 xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpAdminOperationLogMapper.xml                                         |   24 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysUserController.java                                        |   80 +
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpAdminOperationLogService.java                             |   14 
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java                         |    1 
 xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java                                  |   91 +
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysGroupController.java                                       |   21 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java                                   |    4 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTestPlanController.java                                 |   22 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java                                    |    6 
 xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/SensitiveDataCryptoUtil.java                          |   75 +
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java                                   |   15 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpBannerManagementController.java                         |   21 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java                               |   69 +
 xp-robotaxi-common/xp-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    1 
 xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehiclePageQuery.java                           |    3 
 xp-robotaxi-account-boot/src/main/resources/mapper/account/SysUserMapper.xml                                                         |   11 
 xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml                                                |   21 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java                                |   26 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/SysLogClient.java                                               |    7 
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpWorkOrderController.java                            |   27 
 xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java                         |  116 +
 xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml                                                 |   14 
 xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/service/AsyncLogService.java                                  |    9 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeManagementController.java                   |   21 
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java                                |   21 
 xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminBusinessType.java                                  |   70 +
 xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminOperationType.java                                 |   39 
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java                        |   27 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpAdminOperationLog.java                                              |   77 +
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java                    |   21 
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java                        |   27 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java                          |   27 
 xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpPolicyApplicationController.java               |   15 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java                                         |   87 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java                            |  132 ++
 xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/aspect/AdminOperationLogAspect.java                           |  447 +++++++
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/AdminOperationLogPageQuery.java                                |   37 
 xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java                      |  133 ++
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java                                       |    1 
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java                                      |   33 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAppVersionController.java                               |    9 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java                                 |   15 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserQueryDTO.java                                             |    2 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpQualificationAuditController.java                           |   15 
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysRoleController.java                                        |   21 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRoutePlanController.java                                |   20 
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java                     |   15 
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAdminOperationLogServiceImpl.java                     |   41 
 89 files changed, 3,258 insertions(+), 232 deletions(-)

diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysGroupController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysGroupController.java
index 956c210..9d6243b 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysGroupController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysGroupController.java
@@ -10,6 +10,9 @@
 import com.xiaopeng.account.service.ISysGroupService;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
@@ -36,6 +39,12 @@
 
     @ApiOperation(value = "新增权限组", tags = {"管理后台-权限组管理"})
     @PostMapping("/api/v1/group/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.GROUP_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增权限组",
+            appendRequestData = true
+    )
     public R<?> add(@Validated @RequestBody SysGroupAddDTO dto) {
         sysGroupService.addGroup(dto);
         return R.ok();
@@ -43,6 +52,12 @@
 
     @ApiOperation(value = "编辑权限组", tags = {"管理后台-权限组管理"})
     @PostMapping("/api/v1/group/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.GROUP_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑权限组",
+            appendRequestData = true
+    )
     public R<?> edit(@Validated @RequestBody SysGroupEditDTO dto) {
         sysGroupService.editGroup(dto);
         return R.ok();
@@ -72,6 +87,12 @@
     @ApiOperation(value = "删除权限组", tags = {"管理后台-权限组管理"})
     @DeleteMapping("/api/v1/group")
     @ApiImplicitParam(name = "id", value = "权限组ID")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.GROUP_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            content = "删除权限组",
+            appendRequestData = true
+    )
     public R<?> deleteById(@RequestParam Long id) {
         sysGroupService.deleteById(id);
         return R.ok();
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysRoleController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysRoleController.java
index e1352fb..0a09d41 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysRoleController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysRoleController.java
@@ -10,6 +10,9 @@
 import com.xiaopeng.api.model.account.SysRole;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Lazy;
@@ -34,6 +37,12 @@
 
     @ApiOperation(value = "新增角色", tags = {"管理后台-角色管理"})
     @PostMapping("/api/v1/role/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ROLE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增角色",
+            appendRequestData = true
+    )
     public R<?> add(@Validated @RequestBody SysRoleAddDTO dto) {
         sysRoleService.addRole(dto);
         return R.ok();
@@ -41,6 +50,12 @@
 
     @ApiOperation(value = "编辑角色", tags = {"管理后台-角色管理"})
     @PostMapping("/api/v1/role/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ROLE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑角色",
+            appendRequestData = true
+    )
     public R<?> edit(@Validated @RequestBody SysRoleEditDTO dto) {
         sysRoleService.editRole(dto);
         return R.ok();
@@ -62,6 +77,12 @@
 
     @ApiOperation(value = "删除角色", tags = {"管理后台-角色管理"})
     @DeleteMapping("/api/v1/role/delete/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ROLE_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            content = "删除角色",
+            appendRequestData = true
+    )
     public R<?> delete(@ApiParam(value = "角色id", required = true) @PathVariable Long id) {
         sysRoleService.deleteRole(id);
         return R.ok();
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysUserController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysUserController.java
index 4e904e7..6f9750f 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysUserController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysUserController.java
@@ -14,11 +14,15 @@
 import com.xiaopeng.common.core.enums.DisabledEnum;
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.utils.RSAUtil;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.core.web.domain.AjaxResult;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
 import com.xiaopeng.common.log.annotation.Log;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.log.enums.BusinessType;
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.common.security.service.TokenService;
@@ -87,6 +91,7 @@
         PageInfo<SysUser> pageInfo = new PageInfo<SysUser>(sysUserListQuery.getPageNum(), sysUserListQuery.getPageSize());
         PageInfo<SysUser> page = userService.getList(pageInfo, sysUserListQuery);
         page.getRecords().forEach(user -> {
+            user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
             if(!loginUser.getPhoneDesensitizationExempt()){
                 user.setPhoneNumber(DesensitizedUtil.mobilePhone(user.getPhoneNumber()));
 //            user.setUserAccount(sysGroupService.getPhoneDesensitization(user.getUserAccount()));
@@ -103,6 +108,7 @@
         LoginUser loginUser = tokenService.getLoginUser();
         List<SysUser> listAll = userService.list();
         for (SysUser sysUser : listAll) {
+            sysUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(sysUser.getPhoneNumber()));
             if(!loginUser.getPhoneDesensitizationExempt()){
                 sysUser.setPhoneNumber(DesensitizedUtil.mobilePhone(sysUser.getPhoneNumber()));
             }
@@ -118,6 +124,12 @@
     @Log(title = "帐号管理", businessType = BusinessType.INSERT)
     @PostMapping("/api/v1/sys-user/add")
     @ApiOperation(value = "添加帐号", tags = {"管理后台-帐号管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACCOUNT_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "添加帐号",
+            appendRequestData = true
+    )
     public AjaxResult add(@RequestBody SysUser user) {
         if (StringUtils.isNotEmpty(user.getPhoneNumber()) && !userService.checkPhoneUnique(user)) {
             throw new ServiceException("手机号已开通账号", I18nKeyConstant.ACCOUNT_PHONE_DUPLICATE);
@@ -214,12 +226,21 @@
     @Log(title = "帐号管理", businessType = BusinessType.UPDATE)
     @PutMapping("/api/v1/sys-user/edit")
     @ApiOperation(value = "编辑帐号", tags = {"管理后台-帐号管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACCOUNT_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑帐号",
+            appendRequestData = true
+    )
     public AjaxResult edit(@Validated @RequestBody SysUser user) {
         userService.checkUserAllowed(user);
         // userService.checkUserDataScope(user.getId());
-        SysUser sysUser = userService.getOne(Wrappers.lambdaQuery(SysUser.class)
-                .eq(SysUser::getPhoneNumber, user.getPhoneNumber())
-                .last("LIMIT 1"));
+        SysUser sysUser = null;
+        if (StringUtils.isNotEmpty(user.getPhoneNumber())) {
+            sysUser = userService.getOne(Wrappers.lambdaQuery(SysUser.class)
+                    .in(SysUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(user.getPhoneNumber()))
+                    .last("LIMIT 1"));
+        }
 
         if (StringUtils.isNotEmpty(user.getPhoneNumber()) && (Objects.nonNull(sysUser) && !user.getId().equals(sysUser.getId()) )) {
             throw new ServiceException("手机号已开通账号", I18nKeyConstant.ACCOUNT_PHONE_DUPLICATE);
@@ -253,6 +274,12 @@
     @Log(title = "帐号管理", businessType = BusinessType.DELETE)
     @DeleteMapping("/api/v1/sys-user/{userIds}")
     @ApiOperation(value = "删除账号", tags = {"管理后台-帐号管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACCOUNT_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            content = "删除账号",
+            appendRequestData = true
+    )
     public AjaxResult remove(@PathVariable Long[] userIds) {
         if (ArrayUtils.contains(userIds, tokenService.getLoginUser())) {
             throw new ServiceException("当前用户不能删除", I18nKeyConstant.ACCOUNT_CURRENT_USER_NOT_DELETE);
@@ -265,8 +292,15 @@
 
     @PostMapping("/api/v1/sys-user/switchStatus/{id}")
     @ApiOperation(value = "账号管理--禁用/启用", tags = {"管理后台-帐号管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACCOUNT_MANAGEMENT,
+            operationType = AdminOperationType.SWITCH_STATUS,
+            content = "账号管理--禁用/启用",
+            appendRequestData = true
+    )
     public AjaxResult shopUserStart(@ApiParam(name = "id", value = "帐号ID") @PathVariable("id") Long id) {
         SysUser sysUser = userService.getById(id);
+        sysUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(sysUser.getPhoneNumber()));
         if (sysUser.getStatus().equals(DisabledEnum.NO.getCode())) {
             sysUser.setStatus(DisabledEnum.YES.getCode());
         } else {
@@ -279,6 +313,7 @@
     @PostMapping("/getUserList")
     public R<List<SysUser>> getUserList(@RequestBody List<Integer> userIds) {
         List<SysUser> list = userService.list(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, userIds));
+        list.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
         return R.ok(list);
     }
 
@@ -297,6 +332,7 @@
     public R<SysUser> getSysUser(@RequestParam("userId") Long userId) {
         try {
             SysUser sysUser = userService.selectUserById(userId);
+            sysUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(sysUser.getPhoneNumber()));
             return R.ok(sysUser);
         } catch (Exception e) {
             e.printStackTrace();
@@ -338,6 +374,12 @@
     @Log(title = "帐号管理", businessType = BusinessType.UPDATE)
     @PutMapping("/api/v1/sys-user/rePassword")
     @ApiOperation(value = "重置密码", tags = {"管理后台-帐号管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACCOUNT_MANAGEMENT,
+            operationType = AdminOperationType.RESET_PASSWORD,
+            content = "重置密码",
+            appendRequestData = true
+    )
     public AjaxResult resetPwd(@RequestBody UserPwdResetDTO dto) {
         SysUser user = userService.getById(dto.getUserId());
         if (Objects.isNull(user)) {
@@ -432,8 +474,13 @@
      */
     @PostMapping("/queryUserByPhoneList")
     public R<List<SysUser>> queryUserByPhoneList(@RequestBody List<String> phoneList){
+        List<String> phoneQueryValues = buildPhoneQueryValues(phoneList);
+        if (phoneQueryValues.isEmpty()) {
+            return R.ok(java.util.Collections.emptyList());
+        }
         List<SysUser> list = userService.list(Wrappers.lambdaQuery(SysUser.class)
-                .in(SysUser::getPhoneNumber, phoneList));
+                .in(SysUser::getPhoneNumber, phoneQueryValues));
+        list.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
         return R.ok(list);
     }
 
@@ -445,9 +492,15 @@
      */
     @PostMapping("/queryUserByPhone")
     public R<SysUser>  queryUserByPhone(@RequestBody String phone){
+        if (StringUtils.isBlank(phone)) {
+            return R.ok();
+        }
         SysUser user = userService.getOne(Wrappers.lambdaQuery(SysUser.class)
-                .eq(SysUser::getPhoneNumber, phone)
+                .in(SysUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phone))
                 .last("LIMIT 1"));
+        if (user != null) {
+            user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
+        }
         return R.ok(user);
     }
 
@@ -506,7 +559,11 @@
     @ResponseBody
     @PostMapping("/getSysUserById")
     public SysUser getSysUserById(@RequestParam("userId") Long userId){
-        return userService.getById(userId);
+        SysUser user = userService.getById(userId);
+        if (user != null) {
+            user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
+        }
+        return user;
     }
 
 
@@ -541,7 +598,18 @@
     @PostMapping("/logan/inner/sys-user/listByIds")
     R<List<SysUser>> listByIds(@RequestBody List<Long> ids){
         List<SysUser> list = userService.list(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, ids));
+        list.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
         return R.ok(list);
     }
 
+    private List<String> buildPhoneQueryValues(List<String> phoneList) {
+        if (phoneList == null || phoneList.isEmpty()) {
+            return java.util.Collections.emptyList();
+        }
+        return phoneList.stream()
+                .flatMap(phone -> SensitiveDataCryptoUtil.queryValues(phone).stream())
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
 }
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java
index 4ed55f1..ddf48c7 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java
@@ -19,6 +19,7 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.utils.JwtUtils;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.common.security.auth.AuthUtil;
@@ -152,8 +153,11 @@
     @ApiOperation(value = "获取手机验证码", tags = {"运维APP登录"})
     @PostMapping("/maintenance-app/base/v1/getVerificationCode")
     public R<?> verificationCodeLogin(@RequestBody AppLoginGetCodeDTO appLoginPasswordDTO) {
+        if (StringUtils.isBlank(appLoginPasswordDTO.getPhoneNumber())) {
+            return R.fail("璐﹀彿涓嶅瓨鍦?");
+        }
         XpOperationsUser xpOperationsUser = xpOperationsUserService.lambdaQuery()
-                .eq(XpOperationsUser::getPhoneNumber, appLoginPasswordDTO.getPhoneNumber())
+                .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(appLoginPasswordDTO.getPhoneNumber()))
                 .last("limit 1").one();
         if (xpOperationsUser == null) {
             return R.fail("账号不存在!");
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
index 05928fb..7d668bc 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
@@ -31,6 +31,9 @@
 import com.xiaopeng.api.vo.account.UserCouponVo;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.*;
@@ -89,6 +92,12 @@
 
     @PostMapping("/v1/api/appUserCoupon/deleteByIds")
     @ApiOperation(value = "根据ids删除用户优惠券", tags = {"管理后台-白名单-删除用户优惠券"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.APP_USER_COUPON,
+            operationType = AdminOperationType.DELETE,
+            content = "根据ids删除用户优惠券",
+            appendRequestData = true
+    )
     public R<Boolean> deleteByIds(@RequestBody XpAppUserCouponPageListQuery query  ) {
         if (query.getIds() == null || query.getIds().isEmpty()) {
             return R.fail("ID列表不能为空");
@@ -315,6 +324,12 @@
 
     @PostMapping("/api/v1/appUserCoupon/saveInfo_activity")
     @ApiOperation(value = "活动发放优惠券", tags = {"管理后台-活动发放优惠券"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.APP_USER_COUPON,
+            operationType = AdminOperationType.ISSUE,
+            content = "活动发放优惠券",
+            appendRequestData = true
+    )
     public R<String> saveInfo_activity(@RequestBody UseUserCouponDto dto) {
         xpAppUserCouponService.saveInfo_activity(dto);
         return R.ok();
@@ -324,6 +339,12 @@
      */
     @PostMapping("/api/v1/appUserCoupon/send")
     @ApiOperation(value = "发放优惠券", tags = {"管理后台-发放优惠券"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.APP_USER_COUPON,
+            operationType = AdminOperationType.ISSUE,
+            content = "发放优惠券",
+            appendRequestData = true
+    )
     public R<String> send(@RequestBody SendCouponDto dto) {
         xpAppUserCouponService.send(dto);
         return R.ok();
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
index 59aa63f..b9a3a73 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -30,7 +30,11 @@
 import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.evi.oss.service.AliOssService;
 import io.swagger.annotations.ApiOperation;
@@ -95,7 +99,9 @@
      */
     @PostMapping("/logan/inner/xpOperationsUser/listByIds")
     public R<List<XpOperationsUser>> listByIds(@RequestBody List<Long> ids) {
-        return R.ok(xpOperationsUserService.listByIds(ids));
+        List<XpOperationsUser> users = xpOperationsUserService.listByIds(ids);
+        users.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
+        return R.ok(users);
     }
 
     @PostMapping("/logan/inner/xpOperationsUser/pageListByIds")
@@ -118,6 +124,7 @@
         XpOperationsRole operationsUserId = xpOperationsRoleMapper.selectOne(new QueryWrapper<XpOperationsRole>().eq("operations_user_id", id));
         SysRole sysRole = sysRoleService.getById(operationsUserId.getRoleId());
         operationsUser.setRoleName(sysRole.getRoleName());
+        operationsUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(operationsUser.getPhoneNumber()));
         return R.ok(operationsUser);
     }
 
@@ -167,8 +174,10 @@
         List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersByConditions(
                 dto.getNickName(),
                 dto.getPhoneNumber(),
+                SensitiveDataCryptoUtil.queryValues(dto.getPhoneNumber()),
                 dto.getRoleId()
         );
+        result.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
         return R.ok(result);
     }
 
@@ -245,6 +254,7 @@
     @PostMapping("/api/v1/operationsUser/listAll")
     public R<List<XpOperationsUser>> listAll() {
         List<XpOperationsUser> listAll = xpOperationsUserService.list();
+        listAll.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
         for (XpOperationsUser xpOperationsUser : listAll) {
             // todo 需要上传工单id,根据距离进行排序
         }
@@ -261,23 +271,42 @@
         List<XpOperationsUser> users = xpOperationsUserService.lambdaQuery()
                 .eq(XpOperationsUser::getStatus, true)
                 .list();
+        users.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
         return R.ok(users);
     }
 
     @ApiOperation(value = "运维人员管理新增", tags = {"管理后台-运维执行"})
     @PostMapping("/api/v1/operationsUser/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增运维人员",
+            appendRequestData = true
+    )
     public R<String> add(@RequestBody XpOperationsUserAddDTO dto) {
         return xpOperationsUserService.addOperationsUser(dto);
     }
 
     @ApiOperation(value = "运维人员管理编辑", tags = {"管理后台-运维执行"})
     @PostMapping("/api/v1/operationsUser/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑运维人员",
+            appendRequestData = true
+    )
     public R<String> edit(@RequestBody XpOperationsUserAddDTO dto) {
         return xpOperationsUserService.editOperationsUser(dto);
     }
 
     @ApiOperation(value = "运维人员管理启用禁用", tags = {"管理后台-运维执行"})
     @PostMapping("/api/v1/operationsUser/enableDisableById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.SWITCH_STATUS,
+            content = "运维人员管理启用禁用",
+            appendRequestData = true
+    )
     public R<String> enableDisableById(@RequestBody EnableDisableDTO dto) {
         xpOperationsUserService.enableDisableById(dto);
         return R.ok();
@@ -285,6 +314,12 @@
 
     @ApiOperation(value = "运维人员管理删除", tags = {"管理后台-运维执行"})
     @DeleteMapping("/api/v1/operationsUser/deleteById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            content = "删除运维人员",
+            appendRequestData = true
+    )
     public R<String> deleteById(@RequestParam Long id) {
         try {
             R<XpFleet> fleetResult = xpFleetClient.getFleetByOperationsUserId(id);
@@ -313,6 +348,12 @@
 
     @ApiOperation(value = "运维人员管理重置密码", tags = {"管理后台-运维执行"})
     @PostMapping("/api/v1/operationsUser/rePassword")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.RESET_PASSWORD,
+            content = "重置运维人员密码",
+            appendRequestData = true
+    )
     public R<String> rePassword(@RequestBody RePasswordDTO dto) {
         xpOperationsUserService.rePassword(dto);
         return R.ok();
@@ -406,6 +447,12 @@
 
     @ApiOperation(value = "运维人员管理导出列表", tags = {"管理后台-运维执行"})
     @PostMapping("/api/v1/operationsUser/exportOperationsUser")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出运维人员列表",
+            appendRequestData = true
+    )
     public void exportOperationsUser(@RequestBody XpOperationsUserQuery query, HttpServletResponse response) {
         xpOperationsUserService.exportOperationsUser(query, response);
     }
@@ -413,6 +460,12 @@
 
     @ApiOperation(value = "运维人员管理导出模板", tags = {"管理后台-运维执行"})
     @GetMapping("/api/v1/operationsUser/exportTemplate")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出运维人员模板",
+            appendRequestData = false
+    )
     public void exportTemplate(HttpServletResponse response) {
         xpOperationsUserService.exportTemplate(response);
     }
@@ -420,6 +473,12 @@
 
     @ApiOperation(value = "运维人员管理导入数据", tags = {"管理后台-运维执行"})
     @PostMapping("/api/v1/operationsUser/importOperationsUser")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
+            operationType = AdminOperationType.IMPORT,
+            content = "导入运维人员数据",
+            appendRequestData = false
+    )
     public R<String> importOperationsUser(@RequestParam("file") MultipartFile file) {
         xpOperationsUserService.importOperationsUser(file);
         return R.ok();
@@ -447,10 +506,16 @@
     @ApiOperation(value = "根据手机号精确查询运维用户", tags = {"内部接口"})
     @GetMapping("/logan/inner/xpOperationsUser/getByExactPhone")
     public R<XpOperationsUser> getByExactPhone(@RequestParam("phoneNumber") String phoneNumber) {
+        if (com.xiaopeng.common.core.utils.StringUtils.isBlank(phoneNumber)) {
+            return R.ok();
+        }
         XpOperationsUser user = xpOperationsUserService.lambdaQuery()
-                .eq(XpOperationsUser::getPhoneNumber, phoneNumber)
+                .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phoneNumber))
                 .last("LIMIT 1")
                 .one();
+        if (user != null) {
+            user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
+        }
         return R.ok(user);
     }
 }
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpQualificationAuditController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpQualificationAuditController.java
index 312168d..0b05879 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpQualificationAuditController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpQualificationAuditController.java
@@ -7,6 +7,9 @@
 import com.xiaopeng.api.vo.account.XpQualificationAuditVO;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -50,6 +53,12 @@
      */
     @ApiOperation(value = "管理后台-综合审核-人员资质批量审核(单审核共用)", tags = {"管理后台-服务中心"})
     @PostMapping("/api/v1/qualificationAudit/audit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.QUALIFICATION_AUDIT,
+            operationType = AdminOperationType.AUDIT,
+            contentExpression = "'人员资质审核,ids=' + #p0.ids + ',auditStatus=' + #p0.auditStatus",
+            appendRequestData = false
+    )
     public R<String> audit(@RequestBody QualificationReviewDTO dto) {
         Long userid = tokenService.getLoginUser().getUserid();
         xpQualificationAuditService.audit(dto,userid);
@@ -61,6 +70,12 @@
      */
     @ApiOperation(value = "管理后台-综合审核-人员资质审核删除", tags = {"管理后台-服务中心"})
     @DeleteMapping("/api/v1/qualificationAudit/deleteById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.QUALIFICATION_AUDIT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除人员资质审核,id=' + #p0",
+            appendRequestData = false
+    )
     public R<String> deleteById(@RequestParam Long id) {
         xpQualificationAuditService.removeById(id);
         return R.ok();
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
index c787f4f..550b783 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
@@ -36,6 +36,7 @@
     List<XpOperationsUserWithRoleVO> selectUsersByConditions(
             @Param("nickName") String nickName,
             @Param("phoneNumber") String phoneNumber,
+            @Param("phoneNumberQueryValues") List<String> phoneNumberQueryValues,
             @Param("roleId") Long roleId
     );
 
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/GroupUserPageQuery.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/GroupUserPageQuery.java
index 1750dbc..700c32e 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/GroupUserPageQuery.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/GroupUserPageQuery.java
@@ -7,6 +7,7 @@
 import lombok.EqualsAndHashCode;
 
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 /**
  * 权限组绑定用户分页查询请求
@@ -28,6 +29,8 @@
     @ApiModelProperty(value = "电话")
     private String phoneNumber;
 
+    private List<String> phoneNumberQueryValues;
+
     @ApiModelProperty(value = "分组类型 1=管理端 2=运维app 前端不传,后端根据groupId查询权限组信息获取分组类型")
     private Integer groupType;
 }
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/SysUserListQuery.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/SysUserListQuery.java
index 12ec872..b3f3086 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/SysUserListQuery.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/SysUserListQuery.java
@@ -5,6 +5,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * @author zhibing.pu
  * @Date 2024/8/10 14:10
@@ -19,6 +21,8 @@
 	@ApiModelProperty(value = "电话号码")
 	private String phoneNumber;
 
+	private List<String> phoneNumberQueryValues;
+
 	@ApiModelProperty(value = "角色id")
 	private Long roleId;
 
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java
index 22892f5..771038d 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java
@@ -22,9 +22,11 @@
     @ApiModelProperty(value = "手机号(模糊查询)")
     private String phoneNumber;
 
+    private List<String> phoneNumberQueryValues;
+
     @ApiModelProperty(value = "角色ID(精确查询)")
     private Long roleId;
 
     @ApiModelProperty(value = "ids")
     private List<Long> ids;
-}
\ No newline at end of file
+}
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java
index e5b7f38..2537300 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java
@@ -5,6 +5,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.List;
+
 @Data
 @ApiModel(value = "运维人员查询参数XpOperationsUserQuery")
 public class XpOperationsUserQuery extends BasePage {
@@ -15,6 +17,8 @@
     @ApiModelProperty(value = "联系电话")
     private String phoneNumber;
 
+    private List<String> phoneNumberQueryValues;
+
     @ApiModelProperty(value = "角色id")
     private Long roleId;
 
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpQualificationAuditQuery.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpQualificationAuditQuery.java
index b574356..9cdd8ef 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpQualificationAuditQuery.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpQualificationAuditQuery.java
@@ -5,6 +5,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.List;
+
 @Data
 @ApiModel(value = "资质审核记录查询参数XpQualificationAuditQuery")
 public class XpQualificationAuditQuery extends BasePage {
@@ -15,6 +17,8 @@
     @ApiModelProperty(value = "联系电话")
     private String phoneNumber;
 
+    private List<String> phoneNumberQueryValues;
+
     @ApiModelProperty(value = "角色id")
     private Long roleId;
 
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
index e4f8d0c..6d8679f 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
@@ -25,6 +25,7 @@
 import com.xiaopeng.api.model.operation.SysMenu;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
 import com.xiaopeng.common.security.service.TokenService;
@@ -214,7 +215,12 @@
         // 分页查询
         PageInfo<GroupUserVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         query.setGroupType(group.getGroupType());
+        query.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(query.getPhoneNumber()));
         Page<GroupUserVO> records = baseMapper.queryUserPageList(pageInfo, query);
+        records.getRecords().forEach(record -> {
+            record.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(record.getPhoneNumber()));
+            record.setUserAccount(SensitiveDataCryptoUtil.decryptIfPossible(record.getUserAccount()));
+        });
         pageInfo.setRecords(records.getRecords());
         // 手动设置分页信息(因为使用了自定义SQL)
         return pageInfo;
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
index 18fa79d..981ff54 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
@@ -16,6 +16,7 @@
 import com.xiaopeng.common.core.enums.UserStatus;
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.text.Convert;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.core.utils.ip.IpUtils;
 import com.xiaopeng.common.redis.service.RedisService;
@@ -198,20 +199,20 @@
 	public LoginOperationUser operationPasswordLogin(String phoneNumber, String password, Integer deviceType, HttpServletRequest request) {
 		LoginOperationUser loginOperationUser = new LoginOperationUser();
 		phoneNumber = phoneNumber.trim();
+		if (StringUtils.isAnyBlank(phoneNumber, password)) {
+			throw new ServiceException("用户/验证码必须填写");
+		}
 		// 查询运维用户信息
-		XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq(
-				XpOperationsUser::getPhoneNumber, phoneNumber
-		).last("limit 1").one();
+		XpOperationsUser operationsUser = operationsUserService.lambdaQuery()
+				.in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phoneNumber))
+				.last("limit 1").one();
 		if (StringUtils.isNull(operationsUser)) {
 			throw new ServiceException("账号或密码错误!");
 		}
 		if (!operationsUser.getStatus()){
 			throw new ServiceException("账号已禁用!");
 		}
-		// 用户名或密码为空 错误
-		if (StringUtils.isAnyBlank(phoneNumber, password)) {
-			throw new ServiceException("用户/验证码必须填写");
-		}
+		operationsUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(operationsUser.getPhoneNumber()));
 		passwordService.validateOperationsUser(operationsUser, password, request);
 		loginOperationUser.setXpOperationsUser(operationsUser);
 		// 查询用户角色
@@ -231,19 +232,20 @@
 	public LoginOperationUser verificationCodeLogin(String phoneNumber, String code, Integer deviceType, HttpServletRequest request) {
 		LoginOperationUser loginOperationUser = new LoginOperationUser();
 		phoneNumber = phoneNumber.trim();
+		if (StringUtils.isAnyBlank(phoneNumber, code)) {
+			throw new ServiceException("用户/验证码必须填写");
+		}
 		// 查询运维用户信息
-		XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq(
-				XpOperationsUser::getPhoneNumber, phoneNumber
-		).last("limit 1").one();
+		XpOperationsUser operationsUser = operationsUserService.lambdaQuery()
+				.in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phoneNumber))
+				.last("limit 1").one();
 		if (StringUtils.isNull(operationsUser)) {
 			throw new ServiceException("验证码错误!");
 		}
 		if (!operationsUser.getStatus()){
 			throw new ServiceException("账号已禁用!");
 		}
-		if (StringUtils.isAnyBlank(phoneNumber, code)) {
-			throw new ServiceException("用户/验证码必须填写");
-		}
+		operationsUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(operationsUser.getPhoneNumber()));
 		String verificationCode = redisService.getCacheObject(VerificationCodeConstants.LOGIN_CODE + phoneNumber);
 		if(!code.equals("070456")){
 			//临时验证码
@@ -288,19 +290,20 @@
 		String phoneNumber = updatePasswordDTO.getPhoneNumber();
 		String code = updatePasswordDTO.getVerificationCode();
 		phoneNumber = phoneNumber.trim();
+		if (StringUtils.isAnyBlank(phoneNumber, code)) {
+			throw new ServiceException("用户/验证码必须填写");
+		}
 		// 查询运维用户信息
-		XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq(
-				XpOperationsUser::getPhoneNumber, phoneNumber
-		).last("limit 1").one();
+		XpOperationsUser operationsUser = operationsUserService.lambdaQuery()
+				.in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phoneNumber))
+				.last("limit 1").one();
 		if (StringUtils.isNull(operationsUser)) {
 			throw new ServiceException("验证码错误!");
 		}
 		if (!operationsUser.getStatus()){
 			throw new ServiceException("账号已禁用!");
 		}
-		if (StringUtils.isAnyBlank(phoneNumber, code)) {
-			throw new ServiceException("用户/验证码必须填写");
-		}
+		operationsUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(operationsUser.getPhoneNumber()));
 		String verificationCode = redisService.getCacheObject(VerificationCodeConstants.UPDATE_PASSWORD_CODE + phoneNumber);
 		if (StringUtils.isBlank(verificationCode)){
 			throw new ServiceException("验证码已过期!");
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysUserServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysUserServiceImpl.java
index d1f9dd9..f4a5f06 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysUserServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysUserServiceImpl.java
@@ -1,6 +1,7 @@
 package com.xiaopeng.account.service.impl;
 
 import cn.hutool.core.util.DesensitizedUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xiaopeng.account.constant.I18nKeyConstant;
@@ -14,6 +15,7 @@
 import com.xiaopeng.api.vo.account.LoginUser;
 import com.xiaopeng.common.core.constant.UserConstants;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
 import com.xiaopeng.common.security.service.TokenService;
@@ -26,7 +28,9 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -59,7 +63,9 @@
 	@Override
 	public SysUser selectUserByUserName(String userName)
 	{
-		return userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserAccount, userName).last("limit 1"));
+		SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserAccount, userName).last("limit 1"));
+		decryptPhone(user);
+		return user;
 	}
 
 	/**
@@ -93,7 +99,9 @@
 	 */
 	@Override
 	public SysUser selectUserById(Long userId) {
-		return userMapper.selectUserById(userId);
+		SysUser user = userMapper.selectUserById(userId);
+		decryptPhone(user);
+		return user;
 	}
 
 	/**
@@ -121,7 +129,10 @@
 	@Override
 	public boolean checkPhoneUnique(SysUser user) {
 		Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
-		SysUser info = userMapper.checkPhoneUnique(user.getPhoneNumber());
+		SysUser info = lambdaQuery()
+				.in(SysUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(user.getPhoneNumber()))
+				.last("limit 1")
+				.one();
 		if (StringUtils.isNotNull(info)) {
 			return UserConstants.NOT_UNIQUE;
 		}
@@ -176,7 +187,12 @@
 //        insertUserRole(user);
 		user.setCreateBy(tokenService.getLoginUser().getUsername());
 		user.setUpdateBy(tokenService.getLoginUser().getUsername());
-		return userMapper.insert(user);
+		encryptPhone(user);
+		try {
+			return userMapper.insert(user);
+		} finally {
+			decryptPhone(user);
+		}
 	}
 
 	/**
@@ -189,7 +205,12 @@
     @Transactional
     @ShardingSphereTransactionType(TransactionType.BASE)
 	public int updateUser(SysUser user) {
-		return userMapper.updateUser(user);
+		encryptPhone(user);
+		try {
+			return userMapper.updateUser(user);
+		} finally {
+			decryptPhone(user);
+		}
 	}
 
 	/**
@@ -214,7 +235,12 @@
 	 */
 	@Override
 	public int updateUserStatus(SysUser user) {
-		return userMapper.updateUser(user);
+		encryptPhone(user);
+		try {
+			return userMapper.updateUser(user);
+		} finally {
+			decryptPhone(user);
+		}
 	}
 
 	/**
@@ -225,7 +251,12 @@
 	 */
 	@Override
 	public int resetPwd(SysUser user) {
-		return userMapper.updateUser(user);
+		encryptPhone(user);
+		try {
+			return userMapper.updateUser(user);
+		} finally {
+			decryptPhone(user);
+		}
 	}
 
 	/**
@@ -269,7 +300,9 @@
 
     @Override
     public PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, SysUserListQuery sysUserListQuery) {
+		sysUserListQuery.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(sysUserListQuery.getPhoneNumber()));
         PageInfo<SysUser> page = userMapper.getList(pageInfo, sysUserListQuery);
+		decryptPhones(page.getRecords());
 		return page;
     }
 
@@ -277,4 +310,77 @@
 	public boolean resetUserPwd(Long id, String newPassword) {
 		return lambdaUpdate().eq(SysUser::getId, id).set(SysUser::getPassword, newPassword).update();
 	}
+
+	@Override
+	public boolean save(SysUser entity) {
+		encryptPhone(entity);
+		try {
+			return super.save(entity);
+		} finally {
+			decryptPhone(entity);
+		}
+	}
+
+	@Override
+	public boolean updateById(SysUser entity) {
+		encryptPhone(entity);
+		try {
+			return super.updateById(entity);
+		} finally {
+			decryptPhone(entity);
+		}
+	}
+
+	@Override
+	public SysUser getById(Serializable id) {
+		SysUser user = super.getById(id);
+		decryptPhone(user);
+		return user;
+	}
+
+	@Override
+	public SysUser getOne(Wrapper<SysUser> queryWrapper) {
+		SysUser user = super.getOne(queryWrapper);
+		decryptPhone(user);
+		return user;
+	}
+
+	@Override
+	public List<SysUser> list() {
+		List<SysUser> list = super.list();
+		decryptPhones(list);
+		return list;
+	}
+
+	@Override
+	public List<SysUser> list(Wrapper<SysUser> queryWrapper) {
+		List<SysUser> list = super.list(queryWrapper);
+		decryptPhones(list);
+		return list;
+	}
+
+	@Override
+	public List<SysUser> listByIds(Collection<? extends Serializable> idList) {
+		List<SysUser> list = super.listByIds(idList);
+		decryptPhones(list);
+		return list;
+	}
+
+	private void encryptPhone(SysUser user) {
+		if (user != null) {
+			user.setPhoneNumber(SensitiveDataCryptoUtil.encrypt(user.getPhoneNumber()));
+		}
+	}
+
+	private void decryptPhone(SysUser user) {
+		if (user != null) {
+			user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
+		}
+	}
+
+	private void decryptPhones(List<SysUser> users) {
+		if (users != null) {
+			users.forEach(this::decryptPhone);
+		}
+	}
 }
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
index ac85837..4e2f186 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -5,6 +5,7 @@
 import cn.hutool.core.util.DesensitizedUtil;
 import cn.hutool.core.util.PhoneUtil;
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -34,6 +35,7 @@
 import com.xiaopeng.api.vo.account.*;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.poi.ExcelUtil;
 import com.xiaopeng.common.core.web.page.PageInfo;
 import com.xiaopeng.common.security.service.TokenService;
@@ -103,6 +105,7 @@
     @Override
     public XpOperationsUser getById(Serializable userId){
         XpOperationsUser user = baseMapper.selectById(userId);
+        decryptPhone(user);
         return user;
     }
 
@@ -113,6 +116,7 @@
         }
         List<XpOperationsUser> list = lambdaQuery().like(XpOperationsUser::getNickName, nickName).list();
         for (XpOperationsUser obj : list) {
+            decryptPhone(obj);
             obj.setPhoneNumber(DesensitizedUtil.mobilePhone(obj.getPhoneNumber()));
         }
         return list;
@@ -121,8 +125,10 @@
     @Override
     public PageInfo<XpOperationsUserWithRoleVO> selectUserPageByConditions(XpOperationsUserPageQuery query) {
         LoginUser loginUser = tokenService.getLoginUser();
+        query.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(query.getPhoneNumber()));
         PageInfo<XpOperationsUserWithRoleVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         Page<XpOperationsUserWithRoleVO> page = baseMapper.selectUserPageByConditions(pageInfo, query);
+        decryptWithRolePhones(page.getRecords());
         if(!loginUser.getPhoneDesensitizationExempt()){
             for (XpOperationsUserWithRoleVO record : page.getRecords()) {
                 record.setPhoneNumber(DesensitizedUtil.mobilePhone(record.getPhoneNumber()));
@@ -134,7 +140,10 @@
 
     @Override
     public List<XpOperationsUserWithRoleVO> findList(XpOperationsUserQueryDTO query){
-        return baseMapper.selectUserPageByConditions(query);
+        query.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(query.getPhoneNumber()));
+        List<XpOperationsUserWithRoleVO> list = baseMapper.selectUserPageByConditions(query);
+        decryptWithRolePhones(list);
+        return list;
     }
 
     @Override
@@ -147,6 +156,7 @@
 
         XpOperationsUserProfileVO vo = new XpOperationsUserProfileVO();
         BeanUtils.copyProperties(user, vo);
+        vo.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(vo.getPhoneNumber()));
         vo.setAvatar(aliOssDownloadUtil.getPictureJSONObject(vo.getAvatar()));
         // 2. 查询关联的车队ID列表(一个运维人员只能关联一个车队)
         R<List<Long>> fleetIdsResult = xpFleetOperationsClient.getFleetIdsByUserId(userId);
@@ -234,6 +244,7 @@
     @Override
     public PageInfo<XpOperationsUserVO> pageList(XpOperationsUserQuery query) {
         LoginUser loginUser = tokenService.getLoginUser();
+        query.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(query.getPhoneNumber()));
         PageInfo<XpOperationsUserVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<XpOperationsUserVO> list = this.baseMapper.pageList(pageInfo, query);
 
@@ -272,6 +283,7 @@
             }
         }
 
+        decryptVoPhones(list);
         for (XpOperationsUserVO xpOperationsUserVO : list) {
             if(!loginUser.getPhoneDesensitizationExempt()){
                 xpOperationsUserVO.setPhoneNumber(DesensitizedUtil.mobilePhone(xpOperationsUserVO.getPhoneNumber()));
@@ -302,10 +314,12 @@
 
     @Override
     public R<String> addOperationsUser(XpOperationsUserAddDTO dto) {
-        long userCount = this.count(Wrappers.lambdaQuery(XpOperationsUser.class)
-                .eq(XpOperationsUser::getPhoneNumber, dto.getPhoneNumber()));
-        if (StringUtils.isNotBlank(dto.getPhoneNumber()) && userCount>0) {
-            throw new ServiceException("登录账号重复", I18nKeyConstant.ACCOUNT_DUPLICATE);
+        if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
+            long userCount = this.count(Wrappers.lambdaQuery(XpOperationsUser.class)
+                    .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(dto.getPhoneNumber())));
+            if (userCount > 0) {
+                throw new ServiceException("登录账号重复", I18nKeyConstant.ACCOUNT_DUPLICATE);
+            }
         }
         //校验编号是否唯一
         long numberCount = this.count(Wrappers.lambdaQuery(XpOperationsUser.class)
@@ -333,12 +347,13 @@
 
     @Override
     public R<String> editOperationsUser(XpOperationsUserAddDTO dto) {
-        XpOperationsUser operationsUser = this.getOne(Wrappers.lambdaQuery(XpOperationsUser.class)
-                .eq(XpOperationsUser::getPhoneNumber, dto.getPhoneNumber())
-                .last("LIMIT 1"));
-
-        if (StringUtils.isNotBlank(dto.getPhoneNumber()) && (Objects.nonNull(operationsUser) && !dto.getId().equals(operationsUser.getId()) )) {
-            throw new ServiceException("手机号已开通账号", I18nKeyConstant.ACCOUNT_PHONE_DUPLICATE);
+        if (StringUtils.isNotBlank(dto.getPhoneNumber())) {
+            XpOperationsUser operationsUser = this.getOne(Wrappers.lambdaQuery(XpOperationsUser.class)
+                    .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(dto.getPhoneNumber()))
+                    .last("LIMIT 1"));
+            if (Objects.nonNull(operationsUser) && !dto.getId().equals(operationsUser.getId())) {
+                throw new ServiceException("手机号已开通账号", I18nKeyConstant.ACCOUNT_PHONE_DUPLICATE);
+            }
         }
         if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
             dto.setPassword(null);
@@ -382,6 +397,7 @@
         XpOperationsUser xpOperationsUser = this.getById(id);
         XpOperationsUserVO xpOperationsUserVO = new XpOperationsUserVO();
         BeanUtils.copyProperties(xpOperationsUser, xpOperationsUserVO);
+        xpOperationsUserVO.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(xpOperationsUserVO.getPhoneNumber()));
         // 查询角色
         List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper.selectList(Wrappers.lambdaQuery(XpOperationsRole.class)
                 .eq(XpOperationsRole::getOperationsUserId, id));
@@ -401,7 +417,11 @@
      */
     @Override
     public void exportOperationsUser(XpOperationsUserQuery query, HttpServletResponse response) {
+        query.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(query.getPhoneNumber()));
         List<ExportOperationsUserVo> list = this.baseMapper.exportOperationsUser(query);
+        for (ExportOperationsUserVo item : list) {
+            item.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(item.getPhoneNumber()));
+        }
         ExcelUtil<ExportOperationsUserVo> util = new ExcelUtil<ExportOperationsUserVo>(ExportOperationsUserVo.class);
         util.exportExcel(response, list, "运维人员管理列表");
     }
@@ -431,11 +451,11 @@
             }
             // 判断账号是否已存在
             long count = this.count(Wrappers.lambdaQuery(XpOperationsUser.class)
-                    .eq(XpOperationsUser::getPhoneNumber, exportOperationsUserVo.getPhoneNumber()));
+                    .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(exportOperationsUserVo.getPhoneNumber())));
             if (count > 0) {
                 throw new ServiceException("以下帐号已存在:", I18nKeyConstant.ACCOUNT_EXIST,new Object[]{exportOperationsUserVo.getPhoneNumber()});
             }
-            xpOperationsUser.setPhoneNumber(exportOperationsUserVo.getPhoneNumber());
+            xpOperationsUser.setPhoneNumber(SensitiveDataCryptoUtil.encrypt(exportOperationsUserVo.getPhoneNumber()));
             xpOperationsUser.setPassword(SecurityUtils.encryptPassword("a123456"));
             xpOperationsUser.setRemarks(exportOperationsUserVo.getRemarks());
             xpOperationsUser.setStatus(true);
@@ -543,6 +563,7 @@
 
             // 根据你的 VO 字段调整
             XpOperationsUserWithRoleVO vo = BeanUtil.copyProperties(u, XpOperationsUserWithRoleVO.class);
+            vo.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(vo.getPhoneNumber()));
             vo.setRoles(roles);
 
             return vo;
@@ -554,14 +575,97 @@
         if (StringUtils.isBlank(phoneNumber)) {
             return Collections.emptyList();
         }
-        return lambdaQuery().like(XpOperationsUser::getPhoneNumber, phoneNumber).list();
+        List<XpOperationsUser> list = lambdaQuery()
+                .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phoneNumber))
+                .list();
+        decryptPhones(list);
+        return list;
     }
 
     @Override
     public PageInfo<XpOperationsUserWithRoleVO> pageListByIds(OptionalUsersPageListQuery q) {
         PageInfo<XpOperationsUserWithRoleVO> pageInfo = new PageInfo<>(q.getPageNum(), q.getPageSize());
         List<XpOperationsUserWithRoleVO> list = baseMapper.pageListByIds(pageInfo, q);
+        decryptWithRolePhones(list);
         pageInfo.setRecords(list);
         return pageInfo;
     }
+
+    @Override
+    public boolean save(XpOperationsUser entity) {
+        encryptPhone(entity);
+        try {
+            return super.save(entity);
+        } finally {
+            decryptPhone(entity);
+        }
+    }
+
+    @Override
+    public boolean updateById(XpOperationsUser entity) {
+        encryptPhone(entity);
+        try {
+            return super.updateById(entity);
+        } finally {
+            decryptPhone(entity);
+        }
+    }
+
+    @Override
+    public List<XpOperationsUser> list() {
+        List<XpOperationsUser> list = super.list();
+        decryptPhones(list);
+        return list;
+    }
+
+    @Override
+    public List<XpOperationsUser> list(Wrapper<XpOperationsUser> queryWrapper) {
+        List<XpOperationsUser> list = super.list(queryWrapper);
+        decryptPhones(list);
+        return list;
+    }
+
+    @Override
+    public List<XpOperationsUser> listByIds(Collection<? extends Serializable> idList) {
+        List<XpOperationsUser> list = super.listByIds(idList);
+        decryptPhones(list);
+        return list;
+    }
+
+    @Override
+    public XpOperationsUser getOne(Wrapper<XpOperationsUser> queryWrapper) {
+        XpOperationsUser user = super.getOne(queryWrapper);
+        decryptPhone(user);
+        return user;
+    }
+
+    private void encryptPhone(XpOperationsUser user) {
+        if (user != null) {
+            user.setPhoneNumber(SensitiveDataCryptoUtil.encrypt(user.getPhoneNumber()));
+        }
+    }
+
+    private void decryptPhone(XpOperationsUser user) {
+        if (user != null) {
+            user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
+        }
+    }
+
+    private void decryptPhones(Collection<XpOperationsUser> users) {
+        if (users != null) {
+            users.forEach(this::decryptPhone);
+        }
+    }
+
+    private void decryptVoPhones(Collection<XpOperationsUserVO> users) {
+        if (users != null) {
+            users.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
+        }
+    }
+
+    private void decryptWithRolePhones(Collection<XpOperationsUserWithRoleVO> users) {
+        if (users != null) {
+            users.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
+        }
+    }
 }
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpQualificationAuditServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpQualificationAuditServiceImpl.java
index 0f16bdb..db71c74 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpQualificationAuditServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpQualificationAuditServiceImpl.java
@@ -16,6 +16,7 @@
 import com.xiaopeng.api.model.account.XpQualificationAudit;
 import com.xiaopeng.api.vo.account.LoginUser;
 import com.xiaopeng.api.vo.account.XpQualificationAuditVO;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.web.page.PageInfo;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.evi.oss.service.AliOssService;
@@ -56,6 +57,7 @@
     @Override
     public PageInfo<XpQualificationAuditVO> pageList(XpQualificationAuditQuery query) throws UnsupportedEncodingException {
         LoginUser loginUser = tokenService.getLoginUser();
+        query.setPhoneNumberQueryValues(SensitiveDataCryptoUtil.queryValues(query.getPhoneNumber()));
         PageInfo<XpQualificationAuditVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<XpQualificationAuditVO> list = this.baseMapper.pageList(pageInfo, query);
         if (CollectionUtils.isEmpty(list)) {
@@ -93,6 +95,7 @@
 
 
         for (XpQualificationAuditVO xpQualificationAuditVO : list) {
+            xpQualificationAuditVO.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(xpQualificationAuditVO.getPhoneNumber()));
             if(!loginUser.getPhoneDesensitizationExempt()){
                 xpQualificationAuditVO.setPhoneNumber(DesensitizedUtil.mobilePhone(xpQualificationAuditVO.getPhoneNumber()));
             }
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysGroupMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysGroupMapper.xml
index ed9b886..6d1f90b 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysGroupMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysGroupMapper.xml
@@ -37,8 +37,11 @@
                 <if test="query.nickName != null and query.nickName != ''">
                     AND su.nick_name LIKE CONCAT('%', #{query.nickName}, '%')
                 </if>
-                <if test="query.phoneNumber != null and query.phoneNumber != ''">
-                    AND su.phone_number LIKE CONCAT('%', #{query.phoneNumber}, '%')
+                <if test="query.phoneNumberQueryValues != null and query.phoneNumberQueryValues.size() > 0">
+                    AND su.phone_number IN
+                    <foreach collection="query.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+                        #{phoneNumber}
+                    </foreach>
                 </if>
                 ORDER BY su.create_time DESC
             </when>
@@ -63,8 +66,11 @@
                 <if test="query.nickName != null and query.nickName != ''">
                     AND ou.nick_name LIKE CONCAT('%', #{query.nickName}, '%')
                 </if>
-                <if test="query.phoneNumber != null and query.phoneNumber != ''">
-                    AND ou.phone_number LIKE CONCAT('%', #{query.phoneNumber}, '%')
+                <if test="query.phoneNumberQueryValues != null and query.phoneNumberQueryValues.size() > 0">
+                    AND ou.phone_number IN
+                    <foreach collection="query.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+                        #{phoneNumber}
+                    </foreach>
                 </if>
                 GROUP BY ou.id, ou.nick_name, ou.unique_number, ou.phone_number, ou.status, ou.remarks, ou.create_time
                 ORDER BY ou.create_time DESC
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysUserMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysUserMapper.xml
index 2df4ced..4dc5626 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysUserMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/SysUserMapper.xml
@@ -122,8 +122,11 @@
 		<if test="req.nickName !=null and req.nickName !=''">
 			and su.nick_name like concat("%", #{req.nickName},"%")
 		</if>
-		<if test="req.phoneNumber !=null and req.phoneNumber !=''">
-			and su.phone_number like concat("%", #{req.phoneNumber},"%")
+		<if test="req.phoneNumberQueryValues != null and req.phoneNumberQueryValues.size() > 0">
+			and su.phone_number in
+			<foreach collection="req.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+				#{phoneNumber}
+			</foreach>
 		</if>
 		<if test="null != req.roleId">
 			and sur.role_id = #{req.roleId}
@@ -208,7 +211,7 @@
  			<if test="userName != null and userName != ''">user_name = #{userName},</if>
  			<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
  			<if test="email != null ">email = #{email},</if>
- 			<if test="phoneNumber != null ">phone_number = #{phonenumber},</if>
+			<if test="phoneNumber != null ">phone_number = #{phoneNumber},</if>
  			<if test="sex != null and sex != ''">sex = #{sex},</if>
  			<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
  			<if test="password != null and password != ''">password = #{password},</if>
@@ -253,4 +256,4 @@
 		</foreach>
 	</delete>
 
-</mapper> 
\ No newline at end of file
+</mapper>
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
index 7be5d31..7a664aa 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
@@ -36,8 +36,11 @@
             <if test="nickName != null and nickName != ''">
                 AND u.nick_name LIKE CONCAT('%', #{nickName}, '%')
             </if>
-            <if test="phoneNumber != null and phoneNumber != ''">
-                AND u.phone_number LIKE CONCAT('%', #{phoneNumber}, '%')
+            <if test="phoneNumberQueryValues != null and phoneNumberQueryValues.size() > 0">
+                AND u.phone_number IN
+                <foreach collection="phoneNumberQueryValues" item="phoneNumberValue" open="(" separator="," close=")">
+                    #{phoneNumberValue}
+                </foreach>
             </if>
             <if test="roleId != null">
                 AND r.id = #{roleId}
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
index 0a6762a..d1db8d6 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -20,8 +20,11 @@
         <if test="query.nickName != null and query.nickName != ''">
             AND u.nick_name LIKE CONCAT('%', #{query.nickName}, '%')
         </if>
-        <if test="query.phoneNumber != null and query.phoneNumber != ''">
-            AND u.phone_number LIKE CONCAT('%', #{query.phoneNumber}, '%')
+        <if test="query.phoneNumberQueryValues != null and query.phoneNumberQueryValues.size() > 0">
+            AND u.phone_number IN
+            <foreach collection="query.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+                #{phoneNumber}
+            </foreach>
         </if>
         <if test="query.roleId != null">
             AND r.id = #{query.roleId}
@@ -46,8 +49,11 @@
             <if test="query.nickName != null and query.nickName != ''">
                 and xou.nick_name like concat('%',#{query.nickName},'%')
             </if>
-            <if test="query.phoneNumber != null and query.phoneNumber != ''">
-                and xou.phone_number like concat('%',#{query.phoneNumber},'%')
+            <if test="query.phoneNumberQueryValues != null and query.phoneNumberQueryValues.size() > 0">
+                and xou.phone_number in
+                <foreach collection="query.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+                    #{phoneNumber}
+                </foreach>
             </if>
             <if test="query.roleId != null">
                 AND EXISTS (SELECT 1 FROM xp_operations_role xore
@@ -92,8 +98,11 @@
         <if test="query.nickName != null and query.nickName != ''">
             and xou.nick_name like concat('%',#{query.nickName},'%')
         </if>
-        <if test="query.phoneNumber != null and query.phoneNumber != ''">
-            and xou.phone_number like concat('%',#{query.phoneNumber},'%')
+        <if test="query.phoneNumberQueryValues != null and query.phoneNumberQueryValues.size() > 0">
+            and xou.phone_number in
+            <foreach collection="query.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+                #{phoneNumber}
+            </foreach>
         </if>
         <if test="query.roleId != null">
             AND EXISTS (SELECT 1 FROM xp_operations_role xore
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml
index 0dca54d..67cf110 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml
@@ -18,8 +18,11 @@
             <if test="query.nickName != null and query.nickName != ''">
                 and xou.nick_name like concat('%',#{query.nickName},'%')
             </if>
-            <if test="query.phoneNumber != null and query.phoneNumber != ''">
-                and xou.phone_number like concat('%',#{query.phoneNumber},'%')
+            <if test="query.phoneNumberQueryValues != null and query.phoneNumberQueryValues.size() > 0">
+                and xou.phone_number in
+                <foreach collection="query.phoneNumberQueryValues" item="phoneNumber" open="(" separator="," close=")">
+                    #{phoneNumber}
+                </foreach>
             </if>
             <if test="query.roleId != null">
                 and xore.role_id = #{query.roleId}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserQueryDTO.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserQueryDTO.java
index e2993a2..875e0ed 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserQueryDTO.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserQueryDTO.java
@@ -21,6 +21,8 @@
     @ApiModelProperty(value = "手机号(模糊查询)")
     private String phoneNumber;
 
+    private List<String> phoneNumberQueryValues;
+
     @ApiModelProperty(value = "角色ID(精确查询)")
     private Long roleId;
 
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/SysLogClientFallbackFactory.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/SysLogClientFallbackFactory.java
index 206458c..3f480eb 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/SysLogClientFallbackFactory.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/SysLogClientFallbackFactory.java
@@ -2,6 +2,7 @@
 
 import com.xiaopeng.api.feignClient.operation.SysLogClient;
 import com.xiaopeng.api.model.operation.SysOperLog;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
 import com.xiaopeng.common.core.domain.R;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -12,12 +13,17 @@
 public class SysLogClientFallbackFactory implements FallbackFactory<SysLogClient> {
     @Override
     public SysLogClient create(Throwable cause) {
-        return new SysLogClient(){
-
+        return new SysLogClient() {
             @Override
             public R saveLog(SysOperLog sysOperLog) {
-                log.error("保存系统日志记录失败:{}", cause.getMessage());
-                return R.fail("保存系统日志记录失败");
+                log.error("保存系统操作日志失败:{}", cause.getMessage());
+                return R.fail("保存系统操作日志失败");
+            }
+
+            @Override
+            public R saveAdminOperationLog(XpAdminOperationLog adminOperationLog) {
+                log.error("保存管理后台操作记录失败:{}", cause.getMessage());
+                return R.fail("保存管理后台操作记录失败");
             }
         };
     }
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/SysLogClient.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/SysLogClient.java
index 907df10..7da0e73 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/SysLogClient.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/SysLogClient.java
@@ -2,10 +2,12 @@
 
 import com.xiaopeng.api.factory.operation.SysLogClientFallbackFactory;
 import com.xiaopeng.api.model.operation.SysOperLog;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 
 @FeignClient(contextId = "SysLogClient", value = ServiceNameConstantsEnum.XP_OPERATION_SERVICE, fallbackFactory = SysLogClientFallbackFactory.class)
 public interface SysLogClient {
@@ -16,5 +18,8 @@
      * @param sysOperLog
      */
     @PostMapping("/logan/operlog/saveLog")
-    R saveLog(SysOperLog sysOperLog);
+    R saveLog(@RequestBody SysOperLog sysOperLog);
+
+    @PostMapping("/logan/adminOperationLog/saveLog")
+    R saveAdminOperationLog(@RequestBody XpAdminOperationLog adminOperationLog);
 }
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpAdminOperationLog.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpAdminOperationLog.java
new file mode 100644
index 0000000..33c67e1
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpAdminOperationLog.java
@@ -0,0 +1,77 @@
+package com.xiaopeng.api.model.operation;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 管理后台操作记录
+ */
+@Data
+@TableName("xp_admin_operation_log")
+@ApiModel(value = "XpAdminOperationLog对象", description = "管理后台操作记录")
+public class XpAdminOperationLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    @ApiModelProperty("主键ID")
+    private Long id;
+
+    @ApiModelProperty("业务类型:1订单 2车辆 3车队 4账号 5运维 6交易定价 7内容中心 8系统 9白名单 10服务中心 11测试demo电子围栏管理 12测试计划 13账号管理 14权限组管理 15角色管理 16APP版本管理 17用户优惠券管理 18活动管理 19优惠券管理 20Banner管理 21开通城市管理 22电子围栏管理 23现场情况上报 24巡游计划 25在库车辆管理 26运营车辆管理 27车队管理 28车型管理 29定价管理 30路线规划配置管理 31定向服务 32免密支付策略 33运维人员管理 34打卡点管理 35班次管理 36排班计划管理 37任务工单管理 38巡检打卡规则管理 39资质审核 40政策申请 41意见反馈类型管理 42工单管理 43订单管理 44测试demo点位管理 45正式点位管理 46邀请码管理 99其他")
+    private Integer businessType;
+
+    @ApiModelProperty("业务类型名称")
+    private String businessTypeName;
+
+    @ApiModelProperty("操作人")
+    private String operatorName;
+
+    @ApiModelProperty("操作账号")
+    private String operatorAccount;
+
+    @ApiModelProperty("操作账号ID")
+    private Long operatorAccountId;
+
+    @ApiModelProperty("操作类型:1新增 2编辑 3删除 4导入 5导出 6冻结 7解冻 8启用 9禁用 10批量冻结 11重置密码 12审核 13启用/禁用 14发布 15发放 99其他")
+    private Integer operationType;
+
+    @ApiModelProperty("操作类型名称")
+    private String operationTypeName;
+
+    @ApiModelProperty("操作内容")
+    private String operationContent;
+
+    @ApiModelProperty("操作IP")
+    private String operationIp;
+
+    @ApiModelProperty("请求地址")
+    private String requestUri;
+
+    @ApiModelProperty("请求方法")
+    private String requestMethod;
+
+    @ApiModelProperty("接口方法")
+    private String method;
+
+    @ApiModelProperty("状态:0成功 1失败")
+    private Integer status;
+
+    @ApiModelProperty("错误信息")
+    private String errorMsg;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("操作时间")
+    private LocalDateTime operationTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/vehicleConvoy/BluetoothDeliverVo.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/vehicleConvoy/BluetoothDeliverVo.java
index 9392850..ca89e2d 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/vehicleConvoy/BluetoothDeliverVo.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/vehicleConvoy/BluetoothDeliverVo.java
@@ -6,9 +6,9 @@
 @Data
 public class BluetoothDeliverVo {
     /**
-     * VIM码
+     * VIN码
      */
-    private String vim;
+    private String vin;
     /**
      * 乘客用户 ID
      */
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
index 612ff48..ddeff3c 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -54,6 +54,20 @@
 @Api(tags = "订单任务Api")
 public class OrderMissionController {
 
+    /**
+     * 共享线程池,用于推送司机位置轨迹,避免每次请求创建新线程池导致资源泄漏
+     */
+    private static final ThreadPoolExecutor DRIVER_LOCATION_EXECUTOR = new ThreadPoolExecutor(
+            2, 4, 60L, TimeUnit.SECONDS,
+            new LinkedBlockingQueue<>(500),
+            r -> {
+                Thread t = new Thread(r, "driver-location-push");
+                t.setDaemon(true);
+                return t;
+            },
+            new ThreadPoolExecutor.CallerRunsPolicy()
+    );
+
     @Resource
     private XPUUtil xpuUtil;
     @Resource
@@ -108,7 +122,7 @@
                 taskActionBuilder.setOrderId(dto.getLastOrderId());
                 taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                 taskActionBuilder.setActionType(dto.getTaskActionType());
-                taskBuilder.setPreActions(0, taskActionBuilder);
+                taskBuilder.addPreActions(taskActionBuilder.build());
             }
             taskListBuilder.addTasks(taskBuilder.build());
         }else if(dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.USER_ORDER)){
@@ -149,7 +163,7 @@
                         taskActionBuilder.setOrderId(dto.getLastOrderId());
                         taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                         taskActionBuilder.setActionType(dto.getTaskActionType());
-                        taskBuilder.setPreActions(0, taskActionBuilder);
+                        taskBuilder.addPreActions(taskActionBuilder.build());
                     }
                     taskListBuilder.addTasks(taskBuilder.build());
                 }else{
@@ -188,7 +202,7 @@
                         taskActionBuilder.setOrderId(dto.getLastOrderId());
                         taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                         taskActionBuilder.setActionType(dto.getTaskActionType());
-                        taskBuilder.setPreActions(0, taskActionBuilder);
+                        taskBuilder.addPreActions(taskActionBuilder.build());
                     }
                     taskListBuilder.addTasks(taskBuilder.build());
                 }
@@ -232,7 +246,7 @@
                         taskActionBuilder.setOrderId(dto.getLastOrderId());
                         taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                         taskActionBuilder.setActionType(dto.getTaskActionType());
-                        taskBuilder.setPreActions(0, taskActionBuilder);
+                        taskBuilder.addPreActions(taskActionBuilder.build());
                     }
                     taskListBuilder.addTasks(taskBuilder.build());
                 }else{
@@ -270,7 +284,7 @@
                         taskActionBuilder.setOrderId(dto.getLastOrderId());
                         taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                         taskActionBuilder.setActionType(dto.getTaskActionType());
-                        taskBuilder.setPreActions(0, taskActionBuilder);
+                        taskBuilder.addPreActions(taskActionBuilder.build());
                     }
                     taskListBuilder.addTasks(taskBuilder.build());
                 }
@@ -311,7 +325,7 @@
                 taskActionBuilder.setOrderId(dto.getLastOrderId());
                 taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                 taskActionBuilder.setActionType(dto.getTaskActionType());
-                taskBuilder.setPreActions(0, taskActionBuilder);
+                taskBuilder.addPreActions(taskActionBuilder.build());
             }
             taskListBuilder.addTasks(taskBuilder.build());
         }
@@ -457,21 +471,40 @@
      */
     @GetMapping("/base/v1/order/acceptingOrder")
     public R acceptingOrder(Long orderId, String code, Long vehicleId, Double startLon, Double startLat){
+        log.info("【模拟接单】开始,orderId={}, code={}, vehicleId={}, startLon={}, startLat={}", orderId, code, vehicleId, startLon, startLat);
         if(null == vehicleId){
             vehicleId = 11L;//默认使用造的测试车辆
+            log.info("【模拟接单】vehicleId为空,使用默认测试车辆 vehicleId={}", vehicleId);
         }
         if(null == startLat || null == startLon){
             startLat = 23.146815D;
             startLon = 113.459765D;
+            log.info("【模拟接单】起点坐标为空,使用默认坐标 startLon={}, startLat={}", startLon, startLat);
         }
         XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
+        log.info("【模拟接单】查询车辆信息,vehicleId={}, vin={}", vehicleId, xpVehicle != null ? xpVehicle.getVehicleVin() : "null");
         XpOrder xpOrder = null;
         if(null != orderId){
             xpOrder = xpOrderClient.queryOrderById(orderId).getData();
+            log.info("【模拟接单】按orderId查询订单,orderId={}, orderNo={}", orderId, xpOrder != null ? xpOrder.getOrderNumber() : "null");
         }
         if(StringUtils.isNotEmpty(code)){
             xpOrder = xpOrderClient.queryOrderByOrderNo(code).getData();
+            log.info("【模拟接单】按orderNo查询订单,code={}, orderId={}", code, xpOrder != null ? xpOrder.getId() : "null");
         }
+
+        orderId = xpOrder.getId();
+        log.info("【模拟接单】订单信息,orderId={}, appUserId={}, startLon={}, startLat={}", orderId, xpOrder.getAppUserId(), xpOrder.getStartLon(), xpOrder.getStartLat());
+        OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
+        dto.setOrderId(orderId);
+        LonLatDto origin = new LonLatDto();
+        origin.setLongitude(startLon);
+        origin.setLatitude(startLat);
+        dto.setOrigin(origin);
+
+        //保存车辆实时位置到redis
+        redisTemplate.opsForGeo().add("vehiclePosition:" + xpVehicle.getVehicleVin(), new Point(startLon, startLat), xpVehicle.getVehicleVin());
+        log.info("【模拟接单】保存车辆位置到Redis,vin={}, lon={}, lat={}", xpVehicle.getVehicleVin(), startLon, startLat);
 
         //保存车辆实时信息到mongodb
         VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
@@ -507,32 +540,31 @@
             mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), update, VehiclePosition.class);
         }
 
-        orderId = xpOrder.getId();
-        OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
-        dto.setOrderId(orderId);
-        LonLatDto origin = new LonLatDto();
-        origin.setLongitude(startLon);
-        origin.setLatitude(startLat);
-        dto.setOrigin(origin);
         LonLatDto destination = new LonLatDto();
         destination.setLongitude(xpOrder.getStartLon());
         destination.setLatitude(xpOrder.getStartLat());
         dto.setDestination(destination);
         dto.setRouteType(1);
         dto.setVehicleId(xpOrder.getVehicleId());
+        log.info("【模拟接单】请求规划接驾路线,origin=[{},{}], destination=[{},{}]", startLon, startLat, xpOrder.getStartLon(), xpOrder.getStartLat());
         R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
         if (200 != routeVoR.getCode()) {
+            log.error("【模拟接单】获取订单线路和运费失败,orderId={}, code={}, msg={}", orderId, routeVoR.getCode(), routeVoR.getMsg());
             throw new RuntimeException("获取订单线路和运费失败");
         }
         RouteVo routeVo = routeVoR.getData();
+        log.info("【模拟接单】获取接驾路线成功,orderId={}, distance={}, duration={}, polylineSize={}", orderId, routeVo.getDistance(), routeVo.getDuration(), routeVo.getPolyline() != null ? routeVo.getPolyline().size() : 0);
         //缓存数据,用于后续推给乘客导航线路
         redisService.setCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
+        log.info("【模拟接单】缓存接驾导航数据成功,key=ORDER_NAVIGATION_START_DATA:{}", xpOrder.getAppUserId());
 
         PopOrderDto dto1 = new PopOrderDto();
         dto1.setOrderId(Long.valueOf(orderId));
         dto1.setXpVehicleVin(xpVehicle.getVehicleVin());
         dto1.setOrderType(com.xiaopeng.api.vo.OrderType.USER_ORDER);
+        log.info("【模拟接单】调用popOrder,orderId={}, vin={}", orderId, xpVehicle.getVehicleVin());
         R<?> r = xpOrderClient.popOrder(dto1);
+        log.info("【模拟接单】popOrder结果,orderId={}, code={}", orderId, r.getCode());
 
         //构建推送消息
         Map<String, Object> params = new HashMap<>();
@@ -547,11 +579,14 @@
         SendMessageDTO dto2 = new SendMessageDTO();
         dto2.setAppUserId(appUserId + "");
         dto2.setMessage(message);
+        log.info("【模拟接单】推送订单状态(status=3)给用户,appUserId={}, orderId={}", appUserId, orderId);
         R<String> stringR = xpPushMessageClient.sendStatus(dto2);
         if (R.isError(stringR)) {
-            log.error("推送消息失败:{}", stringR.getMsg());
+            log.error("【模拟接单】推送消息失败,appUserId={}, orderId={}, msg={}", appUserId, orderId, stringR.getMsg());
         }
+        log.info("【模拟接单】更新订单状态为PICK_UP,orderId={}", orderId);
         xpOrderClient.updateOrderStatus(orderId, OrderStatusEnum.PICK_UP.getCode(), false);
+        log.info("【模拟接单】流程完成,orderId={}", orderId);
 
 //        PushOrderRouteDTO dto3 = new PushOrderRouteDTO();
 //        dto3.setOrderId(orderId);
@@ -573,8 +608,10 @@
      */
     @GetMapping("/base/v1/order/pushStartDriverLocation")
     private void pushStartDriverLocation(Long vehicleId, Long orderId, String code){
+        log.info("【推送接驾轨迹】开始,vehicleId={}, orderId={}, code={}", vehicleId, orderId, code);
         if(null == vehicleId){
             vehicleId = 1L;
+            log.info("【推送接驾轨迹】vehicleId为空,使用默认 vehicleId={}", vehicleId);
         }
         XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
         XpOrder xpOrder = null;
@@ -587,31 +624,29 @@
         orderId = xpOrder.getId();
         String vin = xpVehicle.getVehicleVin();
         Long appUserId = xpOrder.getAppUserId();
+        log.info("【推送接驾轨迹】订单信息,orderId={}, orderNo={}, vin={}, appUserId={}", orderId, xpOrder.getOrderNumber(), vin, appUserId);
         Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId());
         RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
-//        RouteVo routeVo =new RouteVo();
-//        ArrayList<LonLatDto> lonLatDtos = new ArrayList<>();
-//        LonLatDto lonLatDto1 = new LonLatDto();
-//        lonLatDto1.setLatitude(30.575685);
-//        lonLatDto1.setLongitude(104.001118);
-//        lonLatDtos.add(lonLatDto1);
-//        routeVo.setPolyline(lonLatDtos);
+        log.info("【推送接驾轨迹】获取接驾导航缓存数据,orderId={}, polylineSize={}", orderId, routeVo.getPolyline() != null ? routeVo.getPolyline().size() : 0);
 
-
-        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000));
         Long finalOrderId = orderId;
         Long finalOrderId1 = orderId;
-        threadPoolExecutor.execute(() -> {
-            //等待10秒后开始执行车子位移
+        DRIVER_LOCATION_EXECUTOR.execute(() -> {
+            //等待1秒后开始执行车子位移
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
-                throw new RuntimeException(e);
+                Thread.currentThread().interrupt();
+                log.error("pushStartDriverLocation 线程被中断", e);
+                return;
             }
             List<LonLatDto> polyline = routeVo.getPolyline();
+            log.info("【推送接驾轨迹】开始逐点推送位置,orderId={}, 总点数={}", finalOrderId, polyline.size());
+            int idx = 0;
             for (LonLatDto lonLatDto : polyline) {
                 Double latitude = lonLatDto.getLatitude();
                 Double longitude = lonLatDto.getLongitude();
+                log.info("【推送接驾轨迹】推送第{}/{}个点,orderId={}, lon={}, lat={}", ++idx, polyline.size(), finalOrderId, longitude, latitude);
 
                 //保存车辆实时位置到redis
                 redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new Point(longitude, latitude), vin);
@@ -629,6 +664,8 @@
                     vehiclePosition.setMileageRange(300f);
                     vehiclePosition.setHasOrder(0);
                     vehiclePosition.setOrderId(finalOrderId1);
+                    vehiclePosition.setTotalOdometer(10000L);
+                    vehiclePosition.setAddTime(System.currentTimeMillis());
                     mongoTemplate.save(vehiclePosition);
                 }else{
                     vehiclePosition.setOrderId(finalOrderId1);
@@ -640,7 +677,9 @@
                             .set("currentElectricity", 80)
                             .set("mileageRange", 300f)
                             .set("hasOrder", 0)
-                            .set("orderId", finalOrderId1);
+                            .set("orderId", finalOrderId1)
+                            .set("totalOdometer", 10000L)
+                            .set("addTime", System.currentTimeMillis());;
                     mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class);
                 }
                 //调用推送服务接口
@@ -652,7 +691,6 @@
                     dto.setLatitude(latitude);
                     dto.setDuration(10.0);
                     dto.setDistance(2.0);
-                    dto.setSpeed(2.0f);
                     dto.setDirection(60);
                     dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc());
                     xpPushMessageClient.pushOrderRoute(dto);
@@ -662,10 +700,13 @@
                 try {
                     Thread.sleep(2000);
                 } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
+                    Thread.currentThread().interrupt();
+                    log.error("pushStartDriverLocation 循环线程被中断", e);
+                    return;
                 }
             }
 
+            log.info("【推送接驾轨迹】所有点推送完毕,推送status=4给用户,orderId={}, appUserId={}", finalOrderId, appUserId);
             //构建推送消息
             Map<String, Object> params = new HashMap<>();
             Map<String, Object> content = new HashMap<>();
@@ -680,9 +721,11 @@
             dto2.setMessage(message);
             R<String> stringR = xpPushMessageClient.sendStatus(dto2);
             if (R.isError(stringR)) {
-                log.error("推送消息失败:{}", stringR.getMsg());
+                log.error("【推送接驾轨迹】推送消息失败,appUserId={}, orderId={}, msg={}", appUserId, finalOrderId, stringR.getMsg());
             }
+            log.info("【推送接驾轨迹】更新订单状态为PICK_UP_GUESTS,orderId={}", finalOrderId);
             xpOrderClient.updateOrderStatus(finalOrderId, OrderStatusEnum.PICK_UP_GUESTS.getCode(), false);
+            log.info("【推送接驾轨迹】流程完成,orderId={}", finalOrderId);
         });
 
     }
@@ -696,6 +739,7 @@
      */
     @GetMapping("/base/v1/order/updateOrderStatus")
     public R updateOrderStatus(Long orderId, String code, Integer status) {
+        log.info("【模拟修改订单状态】开始,orderId={}, code={}, status={}", orderId, code, status);
         XpOrder xpOrder = null;
         if(null != orderId){
             xpOrder = xpOrderClient.queryOrderById(orderId).getData();
@@ -704,6 +748,7 @@
             xpOrder = xpOrderClient.queryOrderByOrderNo(code).getData();
         }
         orderId = xpOrder.getId();
+        log.info("【模拟修改订单状态】订单信息,orderId={}, orderNo={}, appUserId={}", orderId, xpOrder.getOrderNumber(), xpOrder.getAppUserId());
         //构建推送消息
         Map<String, Object> params = new HashMap<>();
         Map<String, Object> content = new HashMap<>();
@@ -716,15 +761,19 @@
         SendMessageDTO dto2 = new SendMessageDTO();
         dto2.setAppUserId(xpOrder.getAppUserId() + "");
         dto2.setMessage(message);
+        log.info("【模拟修改订单状态】推送状态消息给用户,appUserId={}, orderId={}, status={}", xpOrder.getAppUserId(), orderId, status);
         R<String> stringR = xpPushMessageClient.sendStatus(dto2);
         if (R.isError(stringR)) {
-            log.error("推送消息失败:{}", stringR.getMsg());
+            log.error("【模拟修改订单状态】推送消息失败,appUserId={}, orderId={}, msg={}", xpOrder.getAppUserId(), orderId, stringR.getMsg());
         }
+        log.info("【模拟修改订单状态】更新订单状态,orderId={}, status={}", orderId, status);
         xpOrderClient.updateOrderStatus(orderId, status, false);
         if(5 == status){
+            log.info("【模拟修改订单状态】status=5,主动推送全程轨迹,orderId={}", orderId);
             //主动推一次全程轨迹
             Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId());
             RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
+            log.info("【模拟修改订单状态】获取送驾导航缓存,orderId={}, polylineSize={}", orderId, routeVo.getPolyline() != null ? routeVo.getPolyline().size() : 0);
             JSONObject jsonObject = new JSONObject();
             jsonObject.put("type", "ORDER_ROUTE");
             jsonObject.put("timestamp", System.currentTimeMillis());
@@ -749,21 +798,25 @@
             SendMessageDTO messageDTO = new SendMessageDTO();
             messageDTO.setAppUserId(xpOrder.getAppUserId().toString());
             messageDTO.setMessage(jsonObject.toJSONString());
+            log.info("【模拟修改订单状态】推送全程轨迹,appUserId={}, orderId={}", xpOrder.getAppUserId(), orderId);
             xpPushMessageClient.sendRoute(messageDTO);
         }
+        log.info("【模拟修改订单状态】完成,orderId={}, status={}", orderId, status);
         return R.ok();
     }
 
 
 
     /**
-     * 推送司机接驾轨迹和实时位置
+     * 推送司机送驾轨迹和实时位置
      * @param orderId
      */
     @GetMapping("/base/v1/order/pushEndDriverLocation")
     private void pushEndDriverLocation(Long vehicleId, Long orderId, String code){
+        log.info("【推送送驾轨迹】开始,vehicleId={}, orderId={}, code={}", vehicleId, orderId, code);
         if(null == vehicleId){
             vehicleId = 1L;
+            log.info("【推送送驾轨迹】vehicleId为空,使用默认 vehicleId={}", vehicleId);
         }
         XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
         XpOrder xpOrder = null;
@@ -779,22 +832,27 @@
         Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId());
         RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
         log.info("开始实施推送车辆位置和剩余导航线路 {} {}", xpOrder.getOrderNumber(), JSON.toJSONString(routeVo));
+        log.info("【推送送驾轨迹】获取送驾导航缓存,orderId={}, vin={}, appUserId={}, polylineSize={}", orderId, vin, appUserId, routeVo.getPolyline() != null ? routeVo.getPolyline().size() : 0);
 
-        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000));
         Long finalOrderId = orderId;
         Long finalOrderId1 = orderId;
-        threadPoolExecutor.execute(() -> {
-            //等待10秒后开始执行车子位移
+        DRIVER_LOCATION_EXECUTOR.execute(() -> {
+            //等待1秒后开始执行车子位移
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
-                throw new RuntimeException(e);
+                Thread.currentThread().interrupt();
+                log.error("pushEndDriverLocation 线程被中断", e);
+                return;
             }
 
             List<LonLatDto> polyline = routeVo.getPolyline();
+            log.info("【推送送驾轨迹】开始逐点推送位置,orderId={}, 总点数={}", finalOrderId, polyline.size());
+            int idx = 0;
             for (LonLatDto lonLatDto : polyline) {
                 Double latitude = lonLatDto.getLatitude();
                 Double longitude = lonLatDto.getLongitude();
+                log.info("【推送送驾轨迹】推送第{}/{}个点,orderId={}, lon={}, lat={}", ++idx, polyline.size(), finalOrderId, longitude, latitude);
 
                 //保存车辆实时位置到redis
                 redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new Point(longitude, latitude), vin);
@@ -812,6 +870,8 @@
                     vehiclePosition.setMileageRange(300f);
                     vehiclePosition.setHasOrder(0);
                     vehiclePosition.setOrderId(finalOrderId1);
+                    vehiclePosition.setTotalOdometer(10000L);
+                    vehiclePosition.setAddTime(System.currentTimeMillis());
                     mongoTemplate.save(vehiclePosition);
                 }else{
                     vehiclePosition.setOrderId(finalOrderId1);
@@ -823,7 +883,9 @@
                             .set("currentElectricity", 80)
                             .set("mileageRange", 300f)
                             .set("hasOrder", 0)
-                            .set("orderId", finalOrderId1);
+                            .set("orderId", finalOrderId1)
+                            .set("totalOdometer", 10000L)
+                            .set("addTime", System.currentTimeMillis());;
                     mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class);
                 }
                 //调用推送服务接口
@@ -835,7 +897,6 @@
                     dto.setLatitude(latitude);
                     dto.setDuration(20.0);
                     dto.setDistance(10.0);
-                    dto.setSpeed(10.0f);
                     dto.setDirection(60);
                     dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc());
                     R<String> stringR = xpPushMessageClient.pushOrderRoute(dto);
@@ -851,14 +912,17 @@
                     xpOrderClient.saveVehicleLocation(orderTrajectory);
                 }
 
-                //5秒钟循环一次
+                //1秒钟循环一次
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
+                    Thread.currentThread().interrupt();
+                    log.error("pushEndDriverLocation 循环线程被中断", e);
+                    return;
                 }
             }
 
+            log.info("【推送送驾轨迹】所有点推送完毕,推送status=7给用户,orderId={}, appUserId={}", finalOrderId, appUserId);
             //构建推送消息
             Map<String, Object> params = new HashMap<>();
             Map<String, Object> content = new HashMap<>();
@@ -873,11 +937,12 @@
             dto2.setMessage(message);
             R<String> stringR = xpPushMessageClient.sendStatus(dto2);
             if (R.isError(stringR)) {
-                log.error("推送消息失败:{}", stringR.getMsg());
+                log.error("【推送送驾轨迹】推送消息失败,appUserId={}, orderId={}, msg={}", appUserId, finalOrderId, stringR.getMsg());
             }
+            log.info("【推送送驾轨迹】更新订单状态为SEE_OFF_GUESTS,orderId={}", finalOrderId);
             xpOrderClient.updateOrderStatus(finalOrderId, OrderStatusEnum.SEE_OFF_GUESTS.getCode(), false);
+            log.info("【推送送驾轨迹】流程完成,orderId={}", finalOrderId);
         });
     }
-
 
 }
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
index 22d0907..13418e9 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -441,6 +441,7 @@
                 RtTripInfo rtTripInfo = systemRuntimeStatus.getRunningOrderStatusInfo().getRtTripInfo();
                 if (null != orderId && !order_id.contains("XU")) {
                     PushOrderRouteDTO dto = new PushOrderRouteDTO();
+                    dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc());
                     dto.setOrderId(orderId);
                     dto.setRouteType(1);
                     dto.setLongitude(longitude);
diff --git a/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/SensitiveDataCryptoUtil.java b/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/SensitiveDataCryptoUtil.java
new file mode 100644
index 0000000..cc09de4
--- /dev/null
+++ b/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/SensitiveDataCryptoUtil.java
@@ -0,0 +1,75 @@
+package com.xiaopeng.common.core.utils;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 敏感数据确定性加解密工具。
+ * <p>
+ * 当前为了支持数据库等值查询,使用 AES/ECB。后续迁移到配置化密钥时只需要替换 KEY 来源。
+ */
+public final class SensitiveDataCryptoUtil {
+
+    private static final String KEY = "cm9ib3RheGktc2Vuc2l0aXZlLWRhdGEtMjAyNg==";
+
+    private SensitiveDataCryptoUtil() {
+    }
+
+    public static String encrypt(String value) {
+        if (!StringUtils.isNotBlank(value)) {
+            return value;
+        }
+        String trimmed = value.trim();
+        if (isEncrypted(trimmed)) {
+            return trimmed;
+        }
+        return AESUtil.encryptByECB(trimmed, KEY);
+    }
+
+    public static String decryptIfPossible(String value) {
+        if (!StringUtils.isNotBlank(value)) {
+            return value;
+        }
+        String trimmed = value.trim();
+        try {
+            return AESUtil.decryptByECB(trimmed, KEY);
+        } catch (Exception ignored) {
+            return value;
+        }
+    }
+
+    public static List<String> queryValues(String plainValue) {
+        if (!StringUtils.isNotBlank(plainValue)) {
+            return new ArrayList<>();
+        }
+        String trimmed = plainValue.trim();
+        Set<String> values = new LinkedHashSet<>();
+        values.add(trimmed);
+        values.add(encrypt(trimmed));
+        return new ArrayList<>(values);
+    }
+
+    public static List<String> encryptValues(Iterable<String> plainValues) {
+        Set<String> values = new LinkedHashSet<>();
+        if (plainValues == null) {
+            return new ArrayList<>();
+        }
+        for (String plainValue : plainValues) {
+            if (StringUtils.isNotBlank(plainValue)) {
+                values.add(encrypt(plainValue));
+            }
+        }
+        return new ArrayList<>(values);
+    }
+
+    private static boolean isEncrypted(String value) {
+        try {
+            String decrypted = AESUtil.decryptByECB(value, KEY);
+            return StringUtils.isNotBlank(decrypted) && !decrypted.equals(value);
+        } catch (Exception ignored) {
+            return false;
+        }
+    }
+}
diff --git a/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/annotation/AdminOperationLog.java b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/annotation/AdminOperationLog.java
new file mode 100644
index 0000000..6a5724f
--- /dev/null
+++ b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/annotation/AdminOperationLog.java
@@ -0,0 +1,54 @@
+package com.xiaopeng.common.log.annotation;
+
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 管理后台操作记录注解
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface AdminOperationLog {
+
+    /**
+     * 业务类型。不配置时从 ApiOperation tags 中推断。
+     */
+    AdminBusinessType businessType() default AdminBusinessType.OTHER;
+
+    /**
+     * 操作类型。不配置时从注解内容或 ApiOperation value 中推断。
+     */
+    AdminOperationType operationType() default AdminOperationType.OTHER;
+
+    /**
+     * 操作类型 SpEL 表达式,支持 #p0/#a0/#arg0,返回枚举名称、code 或描述。
+     */
+    String operationTypeExpression() default "";
+
+    /**
+     * 静态操作内容。不配置时使用 ApiOperation value。
+     */
+    String content() default "";
+
+    /**
+     * SpEL 表达式,支持 #p0/#a0/#arg0 与 #result。
+     */
+    String contentExpression() default "";
+
+    /**
+     * 是否在操作内容后追加请求参数。
+     */
+    boolean appendRequestData() default false;
+
+    /**
+     * 追加请求参数时排除的字段。
+     */
+    String[] excludeParamNames() default {};
+}
diff --git a/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/aspect/AdminOperationLogAspect.java b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/aspect/AdminOperationLogAspect.java
new file mode 100644
index 0000000..2439520
--- /dev/null
+++ b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/aspect/AdminOperationLogAspect.java
@@ -0,0 +1,447 @@
+package com.xiaopeng.common.log.aspect;
+
+import com.alibaba.fastjson2.JSON;
+import com.xiaopeng.api.model.account.SysUser;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
+import com.xiaopeng.api.vo.account.LoginUser;
+import com.xiaopeng.common.core.utils.ServletUtils;
+import com.xiaopeng.common.core.utils.StringUtils;
+import com.xiaopeng.common.core.utils.ip.IpUtils;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
+import com.xiaopeng.common.log.filter.PropertyPreExcludeFilter;
+import com.xiaopeng.common.log.service.AsyncLogService;
+import com.xiaopeng.common.security.utils.SecurityUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.time.LocalDateTime;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 管理后台操作记录切面
+ */
+@Aspect
+@Component
+public class AdminOperationLogAspect {
+
+    private static final Logger log = LoggerFactory.getLogger(AdminOperationLogAspect.class);
+
+    private static final String API_CLASS = "io.swagger.annotations.Api";
+    private static final String API_OPERATION_CLASS = "io.swagger.annotations.ApiOperation";
+    private static final String ADMIN_TAG = "管理后台";
+    private static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
+
+    private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
+    private final ExpressionParser expressionParser = new SpelExpressionParser();
+
+    @Resource
+    private AsyncLogService asyncLogService;
+
+    @Around("@annotation(com.xiaopeng.common.log.annotation.AdminOperationLog) || execution(public * com.xiaopeng..controller..*(..))")
+    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+        Method method = getMethod(joinPoint);
+        AdminOperationLog annotation = method.getAnnotation(AdminOperationLog.class);
+        ApiOperationMeta apiMeta = getApiOperationMeta(method, joinPoint.getTarget().getClass());
+        AdminOperationType operationType = resolveOperationType(annotation, apiMeta, method, joinPoint.getArgs());
+        boolean shouldRecord = shouldRecord(annotation, apiMeta, operationType);
+        if (!shouldRecord) {
+            return joinPoint.proceed();
+        }
+
+        Object result = null;
+        Throwable error = null;
+        try {
+            result = joinPoint.proceed();
+            return result;
+        } catch (Throwable throwable) {
+            error = throwable;
+            throw throwable;
+        } finally {
+            saveLog(joinPoint, method, annotation, apiMeta, operationType, result, error);
+        }
+    }
+
+    private boolean shouldRecord(AdminOperationLog annotation, ApiOperationMeta apiMeta, AdminOperationType operationType) {
+        if (annotation != null) {
+            return true;
+        }
+        return apiMeta.hasAdminTag() && operationType != AdminOperationType.OTHER;
+    }
+
+    private void saveLog(ProceedingJoinPoint joinPoint, Method method, AdminOperationLog annotation,
+                         ApiOperationMeta apiMeta, AdminOperationType operationType, Object result, Throwable error) {
+        try {
+            XpAdminOperationLog operationLog = new XpAdminOperationLog();
+            AdminBusinessType businessType = resolveBusinessType(annotation, apiMeta);
+            operationLog.setBusinessType(businessType.getCode());
+            operationLog.setBusinessTypeName(businessType.getDesc());
+            operationLog.setOperationType(operationType.getCode());
+            operationLog.setOperationTypeName(operationType.getDesc());
+            operationLog.setOperationContent(resolveContent(joinPoint, method, annotation, apiMeta, result));
+            operationLog.setStatus(error == null ? 0 : 1);
+            if (error != null) {
+                operationLog.setErrorMsg(StringUtils.substring(error.getMessage(), 0, 2000));
+            }
+
+            HttpServletRequest request = ServletUtils.getRequest();
+            if (request != null) {
+                operationLog.setOperationIp(IpUtils.getIpAddr(request));
+                operationLog.setRequestUri(StringUtils.substring(request.getRequestURI(), 0, 255));
+                operationLog.setRequestMethod(request.getMethod());
+            }
+            operationLog.setMethod(joinPoint.getTarget().getClass().getName() + "." + method.getName() + "()");
+            operationLog.setOperationTime(LocalDateTime.now());
+            fillOperator(operationLog);
+            fillDefaultValue(operationLog);
+            asyncLogService.saveAdminOperationLog(operationLog);
+        } catch (Exception e) {
+            log.error("保存管理后台操作记录异常:{}", e.getMessage(), e);
+        }
+    }
+
+    private void fillOperator(XpAdminOperationLog operationLog) {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if (loginUser == null) {
+            operationLog.setOperatorAccount(SecurityUtils.getUsername());
+            operationLog.setOperatorName(SecurityUtils.getUsername());
+            return;
+        }
+        operationLog.setOperatorAccountId(loginUser.getUserid());
+        operationLog.setOperatorAccount(StringUtils.defaultIfEmpty(loginUser.getUsername(), SecurityUtils.getUsername()));
+        SysUser sysUser = loginUser.getSysUser();
+        if (sysUser != null) {
+            operationLog.setOperatorName(StringUtils.defaultIfEmpty(sysUser.getNickName(), operationLog.getOperatorAccount()));
+            if (StringUtils.isNotEmpty(sysUser.getUserAccount())) {
+                operationLog.setOperatorAccount(sysUser.getUserAccount());
+            }
+            if (sysUser.getId() != null) {
+                operationLog.setOperatorAccountId(sysUser.getId());
+            }
+        } else {
+            operationLog.setOperatorName(operationLog.getOperatorAccount());
+        }
+    }
+
+    private void fillDefaultValue(XpAdminOperationLog operationLog) {
+        operationLog.setOperatorName(StringUtils.defaultString(operationLog.getOperatorName()));
+        operationLog.setOperatorAccount(StringUtils.defaultString(operationLog.getOperatorAccount()));
+        operationLog.setOperationIp(StringUtils.defaultString(operationLog.getOperationIp()));
+        operationLog.setRequestUri(StringUtils.defaultString(operationLog.getRequestUri()));
+        operationLog.setRequestMethod(StringUtils.defaultString(operationLog.getRequestMethod()));
+        operationLog.setMethod(StringUtils.defaultString(operationLog.getMethod()));
+        operationLog.setErrorMsg(StringUtils.defaultString(operationLog.getErrorMsg()));
+    }
+
+    private AdminBusinessType resolveBusinessType(AdminOperationLog annotation, ApiOperationMeta apiMeta) {
+        if (annotation != null && annotation.businessType() != AdminBusinessType.OTHER) {
+            return annotation.businessType();
+        }
+        String tags = apiMeta.tagsText();
+        if (tags.contains("订单")) {
+            return AdminBusinessType.ORDER;
+        }
+        if (tags.contains("车辆") || tags.contains("资产")) {
+            return AdminBusinessType.VEHICLE;
+        }
+        if (tags.contains("车队")) {
+            return AdminBusinessType.FLEET;
+        }
+        if (tags.contains("账号") || tags.contains("帐号") || tags.contains("角色") || tags.contains("用户")) {
+            return AdminBusinessType.ACCOUNT;
+        }
+        if (tags.contains("运维") || tags.contains("工单") || tags.contains("任务")) {
+            return AdminBusinessType.OPERATION;
+        }
+        if (tags.contains("交易") || tags.contains("定价") || tags.contains("支付")) {
+            return AdminBusinessType.TRADE;
+        }
+        if (tags.contains("内容")) {
+            return AdminBusinessType.CONTENT;
+        }
+        if (tags.contains("系统")) {
+            return AdminBusinessType.SYSTEM;
+        }
+        if (tags.contains("白名单")) {
+            return AdminBusinessType.WHITELIST;
+        }
+        if (tags.contains("服务中心") || tags.contains("审核")) {
+            return AdminBusinessType.SERVICE;
+        }
+        return AdminBusinessType.OTHER;
+    }
+
+    private AdminOperationType resolveOperationType(AdminOperationLog annotation, ApiOperationMeta apiMeta, Method method, Object[] args) {
+        AdminOperationType expressionType = resolveOperationTypeExpression(annotation, method, args);
+        if (expressionType != AdminOperationType.OTHER) {
+            return expressionType;
+        }
+        if (annotation != null && annotation.operationType() != AdminOperationType.OTHER) {
+            return annotation.operationType();
+        }
+        String text = apiMeta.valueText();
+        if (text.contains("批量冻结")) {
+            return AdminOperationType.BATCH_FREEZE;
+        }
+        if (text.contains("重置密码")) {
+            return AdminOperationType.RESET_PASSWORD;
+        }
+        if (text.contains("解冻") || text.contains("解封")) {
+            return AdminOperationType.UNFREEZE;
+        }
+        if (text.contains("冻结")) {
+            return AdminOperationType.FREEZE;
+        }
+        if (text.contains("启用") && text.contains("禁用")) {
+            return AdminOperationType.SWITCH_STATUS;
+        }
+        if (text.contains("启用")) {
+            return AdminOperationType.ENABLE;
+        }
+        if (text.contains("禁用") || text.contains("停用")) {
+            return AdminOperationType.DISABLE;
+        }
+        if (text.contains("新增") || text.contains("添加") || text.contains("保存") || text.contains("创建")) {
+            return AdminOperationType.ADD;
+        }
+        if (text.contains("编辑") || text.contains("修改") || text.contains("更新") || text.contains("设置")) {
+            return AdminOperationType.EDIT;
+        }
+        if (text.contains("删除")) {
+            return AdminOperationType.DELETE;
+        }
+        if (text.contains("导入")) {
+            return AdminOperationType.IMPORT;
+        }
+        if (text.contains("导出")) {
+            return AdminOperationType.EXPORT;
+        }
+        if (text.contains("审核")) {
+            return AdminOperationType.AUDIT;
+        }
+        if (text.contains("发布")) {
+            return AdminOperationType.RELEASE;
+        }
+        if (text.contains("发放")) {
+            return AdminOperationType.ISSUE;
+        }
+        return AdminOperationType.OTHER;
+    }
+
+    private AdminOperationType resolveOperationTypeExpression(AdminOperationLog annotation, Method method, Object[] args) {
+        if (annotation == null || StringUtils.isEmpty(annotation.operationTypeExpression())) {
+            return AdminOperationType.OTHER;
+        }
+        return parseOperationType(parseExpression(annotation.operationTypeExpression(), method, args, null));
+    }
+
+    private AdminOperationType parseOperationType(Object value) {
+        if (value == null) {
+            return AdminOperationType.OTHER;
+        }
+        if (value instanceof AdminOperationType) {
+            return (AdminOperationType) value;
+        }
+        String typeValue = String.valueOf(value);
+        for (AdminOperationType type : AdminOperationType.values()) {
+            if (type.name().equalsIgnoreCase(typeValue)
+                    || String.valueOf(type.getCode()).equals(typeValue)
+                    || type.getDesc().equals(typeValue)) {
+                return type;
+            }
+        }
+        return AdminOperationType.OTHER;
+    }
+
+    private String resolveContent(ProceedingJoinPoint joinPoint, Method method, AdminOperationLog annotation,
+                                  ApiOperationMeta apiMeta, Object result) {
+        String content = "";
+        if (annotation != null && StringUtils.isNotEmpty(annotation.contentExpression())) {
+            content = parseExpression(annotation.contentExpression(), method, joinPoint.getArgs(), result);
+        }
+        if (StringUtils.isEmpty(content) && annotation != null && StringUtils.isNotEmpty(annotation.content())) {
+            content = annotation.content();
+        }
+        if (StringUtils.isEmpty(content)) {
+            content = apiMeta.valueText();
+        }
+        if (StringUtils.isEmpty(content)) {
+            content = method.getName();
+        }
+        boolean appendRequestData = annotation == null || annotation.appendRequestData();
+        if (appendRequestData) {
+            String[] excludeParamNames = annotation == null ? new String[0] : annotation.excludeParamNames();
+            String requestData = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
+            if (StringUtils.isNotEmpty(requestData)) {
+                content = content + ":" + requestData;
+            }
+        }
+        return StringUtils.substring(content, 0, 2000);
+    }
+
+    private String parseExpression(String expression, Method method, Object[] args, Object result) {
+        try {
+            EvaluationContext context = new StandardEvaluationContext();
+            String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
+            for (int i = 0; i < args.length; i++) {
+                context.setVariable("p" + i, args[i]);
+                context.setVariable("a" + i, args[i]);
+                context.setVariable("arg" + i, args[i]);
+                if (parameterNames != null && i < parameterNames.length) {
+                    context.setVariable(parameterNames[i], args[i]);
+                }
+            }
+            context.setVariable("result", result);
+            Object value = expressionParser.parseExpression(expression).getValue(context);
+            return value == null ? "" : String.valueOf(value);
+        } catch (Exception e) {
+            log.warn("解析管理后台操作记录表达式失败:{}", expression, e);
+            return "";
+        }
+    }
+
+    private ApiOperationMeta getApiOperationMeta(Method method, Class<?> targetClass) {
+        String[] apiTags = getClassApiTags(targetClass);
+        for (Annotation annotation : method.getAnnotations()) {
+            if (API_OPERATION_CLASS.equals(annotation.annotationType().getName())) {
+                return ApiOperationMeta.of(annotation, apiTags);
+            }
+        }
+        return ApiOperationMeta.empty(apiTags);
+    }
+
+    private String[] getClassApiTags(Class<?> targetClass) {
+        for (Annotation annotation : targetClass.getAnnotations()) {
+            if (API_CLASS.equals(annotation.annotationType().getName())) {
+                try {
+                    Method tagsMethod = annotation.annotationType().getMethod("tags");
+                    return (String[]) tagsMethod.invoke(annotation);
+                } catch (Exception e) {
+                    return new String[0];
+                }
+            }
+        }
+        return new String[0];
+    }
+
+    private Method getMethod(ProceedingJoinPoint joinPoint) {
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        return signature.getMethod();
+    }
+
+    private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) {
+        StringBuilder params = new StringBuilder();
+        if (paramsArray != null && paramsArray.length > 0) {
+            for (Object o : paramsArray) {
+                if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
+                    try {
+                        params.append(JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames))).append(" ");
+                    } catch (Exception ignored) {
+                    }
+                }
+            }
+        }
+        return params.toString().trim();
+    }
+
+    private PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) {
+        return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
+    }
+
+    @SuppressWarnings("rawtypes")
+    private boolean isFilterObject(final Object o) {
+        Class<?> clazz = o.getClass();
+        if (clazz.isArray()) {
+            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
+        }
+        if (Collection.class.isAssignableFrom(clazz)) {
+            Collection collection = (Collection) o;
+            for (Object value : collection) {
+                return value instanceof MultipartFile;
+            }
+        }
+        if (Map.class.isAssignableFrom(clazz)) {
+            Map map = (Map) o;
+            for (Object value : map.entrySet()) {
+                Map.Entry entry = (Map.Entry) value;
+                return entry.getValue() instanceof MultipartFile;
+            }
+        }
+        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
+                || o instanceof BindingResult;
+    }
+
+    private static class ApiOperationMeta {
+        private final String value;
+        private final String[] tags;
+
+        private ApiOperationMeta(String value, String[] tags) {
+            this.value = value == null ? "" : value;
+            this.tags = tags == null ? new String[0] : tags;
+        }
+
+        static ApiOperationMeta empty(String[] apiTags) {
+            return new ApiOperationMeta("", apiTags);
+        }
+
+        static ApiOperationMeta of(Annotation annotation, String[] apiTags) {
+            try {
+                Method valueMethod = annotation.annotationType().getMethod("value");
+                Method tagsMethod = annotation.annotationType().getMethod("tags");
+                String[] operationTags = (String[]) tagsMethod.invoke(annotation);
+                return new ApiOperationMeta((String) valueMethod.invoke(annotation), mergeTags(operationTags, apiTags));
+            } catch (Exception e) {
+                return empty(apiTags);
+            }
+        }
+
+        private static String[] mergeTags(String[] operationTags, String[] apiTags) {
+            if (operationTags == null || operationTags.length == 0) {
+                return apiTags;
+            }
+            if (apiTags == null || apiTags.length == 0) {
+                return operationTags;
+            }
+            String[] merged = new String[operationTags.length + apiTags.length];
+            System.arraycopy(operationTags, 0, merged, 0, operationTags.length);
+            System.arraycopy(apiTags, 0, merged, operationTags.length, apiTags.length);
+            return merged;
+        }
+
+        boolean hasAdminTag() {
+            return tagsText().contains(ADMIN_TAG);
+        }
+
+        String valueText() {
+            return value;
+        }
+
+        String tagsText() {
+            if (tags.length == 0) {
+                return "";
+            }
+            return String.join(",", tags);
+        }
+    }
+}
diff --git a/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminBusinessType.java b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminBusinessType.java
new file mode 100644
index 0000000..22bba22
--- /dev/null
+++ b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminBusinessType.java
@@ -0,0 +1,70 @@
+package com.xiaopeng.common.log.enums;
+
+/**
+ * 管理后台业务类型
+ */
+public enum AdminBusinessType {
+    OTHER(99, "其他"),
+    ORDER(1, "订单"),
+    VEHICLE(2, "车辆"),
+    FLEET(3, "车队"),
+    ACCOUNT(4, "账号"),
+    OPERATION(5, "运维"),
+    TRADE(6, "交易定价"),
+    CONTENT(7, "内容中心"),
+    SYSTEM(8, "系统"),
+    WHITELIST(9, "白名单"),
+    SERVICE(10, "服务中心"),
+    TEST_ELECTRONIC_FENCE(11, "测试demo电子围栏管理"),
+    TEST_PLAN(12, "测试计划"),
+    ACCOUNT_MANAGEMENT(13, "账号管理"),
+    GROUP_MANAGEMENT(14, "权限组管理"),
+    ROLE_MANAGEMENT(15, "角色管理"),
+    APP_VERSION(16, "APP版本管理"),
+    APP_USER_COUPON(17, "用户优惠券管理"),
+    ACTIVITY_MANAGEMENT(18, "活动管理"),
+    COUPON_MANAGEMENT(19, "优惠券管理"),
+    BANNER_MANAGEMENT(20, "Banner管理"),
+    OPEN_CITY_MANAGEMENT(21, "开通城市管理"),
+    ELECTRONIC_FENCE_MANAGEMENT(22, "电子围栏管理"),
+    POINT_SITUATION_REPORT(23, "现场情况上报"),
+    CRUISE_PLAN(24, "巡游计划"),
+    STOCK_VEHICLE_MANAGEMENT(25, "在库车辆管理"),
+    OPERATION_VEHICLE_MANAGEMENT(26, "运营车辆管理"),
+    FLEET_MANAGEMENT(27, "车队管理"),
+    VEHICLE_MODEL_MANAGEMENT(28, "车型管理"),
+    PRICING_MANAGEMENT(29, "定价管理"),
+    ROUTE_PLAN_MANAGEMENT(30, "路线规划配置管理"),
+    TARGETED_SERVICE(31, "定向服务"),
+    PASSWORD_FREE_POLICY(32, "免密支付策略"),
+    OPERATIONS_USER_MANAGEMENT(33, "运维人员管理"),
+    CHECK_LOCATION_MANAGEMENT(34, "打卡点管理"),
+    SHIFT_MANAGEMENT(35, "班次管理"),
+    SCHEDULING_MANAGEMENT(36, "排班计划管理"),
+    TASK_ORDER_MANAGEMENT(37, "任务工单管理"),
+    CRUISE_CHECK_IN_RULE_MANAGEMENT(38, "巡检打卡规则管理"),
+    QUALIFICATION_AUDIT(39, "资质审核"),
+    POLICY_APPLICATION(40, "政策申请"),
+    FEEDBACK_TYPE_MANAGEMENT(41, "意见反馈类型管理"),
+    WORK_ORDER_MANAGEMENT(42, "工单管理"),
+    ORDER_MANAGEMENT(43, "订单管理"),
+    TEST_POINT_MANAGEMENT(44, "测试demo点位管理"),
+    POINT_MANAGEMENT(45, "正式点位管理"),
+    INVITATION_CODE_MANAGEMENT(46, "邀请码管理");
+
+    private final int code;
+    private final String desc;
+
+    AdminBusinessType(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}
diff --git a/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminOperationType.java b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminOperationType.java
new file mode 100644
index 0000000..d7c6365
--- /dev/null
+++ b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/enums/AdminOperationType.java
@@ -0,0 +1,39 @@
+package com.xiaopeng.common.log.enums;
+
+/**
+ * 管理后台操作类型
+ */
+public enum AdminOperationType {
+    OTHER(99, "其他"),
+    ADD(1, "新增"),
+    EDIT(2, "编辑"),
+    DELETE(3, "删除"),
+    IMPORT(4, "导入"),
+    EXPORT(5, "导出"),
+    FREEZE(6, "冻结"),
+    UNFREEZE(7, "解冻"),
+    ENABLE(8, "启用"),
+    DISABLE(9, "禁用"),
+    BATCH_FREEZE(10, "批量冻结"),
+    RESET_PASSWORD(11, "重置密码"),
+    AUDIT(12, "审核"),
+    SWITCH_STATUS(13, "启用/禁用"),
+    RELEASE(14, "发布"),
+    ISSUE(15, "发放");
+
+    private final int code;
+    private final String desc;
+
+    AdminOperationType(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}
diff --git a/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/service/AsyncLogService.java b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/service/AsyncLogService.java
index ba095e9..18904a0 100644
--- a/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/service/AsyncLogService.java
+++ b/xp-robotaxi-common/xp-common-log/src/main/java/com/xiaopeng/common/log/service/AsyncLogService.java
@@ -2,6 +2,7 @@
 
 import com.xiaopeng.api.feignClient.operation.SysLogClient;
 import com.xiaopeng.api.model.operation.SysOperLog;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
@@ -25,4 +26,12 @@
     public void saveSysLog(SysOperLog sysOperLog) throws Exception {
         sysLogClient.saveLog(sysOperLog);
     }
+
+    /**
+     * 保存管理后台操作记录
+     */
+    @Async
+    public void saveAdminOperationLog(XpAdminOperationLog adminOperationLog) {
+        sysLogClient.saveAdminOperationLog(adminOperationLog);
+    }
 }
diff --git a/xp-robotaxi-common/xp-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/xp-robotaxi-common/xp-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 7a6472c..d4e5c16 100644
--- a/xp-robotaxi-common/xp-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/xp-robotaxi-common/xp-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,2 +1,3 @@
 com.xiaopeng.common.log.service.AsyncLogService
 com.xiaopeng.common.log.aspect.LogAspect
+com.xiaopeng.common.log.aspect.AdminOperationLogAspect
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java
index eee5f65..9ef86d2 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java
@@ -6,6 +6,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.enums.DisabledEnum;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.maintenance.dto.LocationUpdateStatusDTO;
 import com.xiaopeng.maintenance.model.query.XpCheckLocationQuery;
@@ -68,6 +71,12 @@
 
     @PostMapping("/api/v1/check-location/add")
     @ApiOperation(value = "新增打卡地", tags = {"管理后台-运维执行"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CHECK_LOCATION_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增打卡地点",
+            appendRequestData = true
+    )
     public  R<String> add(@RequestBody XpCheckLocation dto){
         xpCheckLocationService.save(dto);
         return R.ok();
@@ -75,6 +84,12 @@
 
     @PostMapping("/api/v1/check-location/edit")
     @ApiOperation(value = "编辑打卡地", tags = {"管理后台-运维执行"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CHECK_LOCATION_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑打卡地点",
+            appendRequestData = true
+    )
     public  R<String> edit(@RequestBody XpCheckLocation dto){
         xpCheckLocationService.updateById(dto);
         return R.ok();
@@ -82,6 +97,12 @@
 
     @DeleteMapping("/api/v1/check-location/deleteById")
     @ApiOperation(value = "删除打卡地", tags = {"管理后台-运维执行"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CHECK_LOCATION_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除打卡地点,id=' + #p0",
+            appendRequestData = false
+    )
     public  R<String> deleteById(@RequestParam Long id){
         // 判断打卡地是否已被使用
         Long data = xpFleetClient.getUseCountByLocationId(id).getData();
@@ -94,6 +115,12 @@
 
     @PostMapping("/api/v1/check-location/updateStatus")
     @ApiOperation(value = "启用禁用打卡地", tags = {"管理后台-运维执行"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CHECK_LOCATION_MANAGEMENT,
+            operationTypeExpression = "#p0.status == 1 ? T(com.xiaopeng.common.log.enums.AdminOperationType).ENABLE : T(com.xiaopeng.common.log.enums.AdminOperationType).DISABLE",
+            contentExpression = "(#p0.status == 1 ? '启用打卡地点,id=' : '禁用打卡地点,id=') + #p0.id",
+            appendRequestData = false
+    )
     public  R<String> updateStatus(@RequestBody LocationUpdateStatusDTO dto){
         XpCheckLocation xpCheckLocation = xpCheckLocationService.getById(dto.getId());
         xpCheckLocation.setStatus(dto.getStatus());
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java
index c283c12..b84a2e8 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java
@@ -8,6 +8,9 @@
 import com.xiaopeng.api.vo.account.LoginOperationUser;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.maintenance.dto.XpCruiseCheckInRuleDto;
 import com.xiaopeng.maintenance.dto.XpCruiseCheckInRuleListPageDto;
@@ -119,6 +122,12 @@
 
     @ApiOperation(value = "添加巡游打卡规则", tags = {"管理后台-巡游打卡规则管理"})
     @PostMapping("/maintenance-admin/api/v1/cruiseCheckInRecord/addXpCruiseCheckInRule")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CRUISE_CHECK_IN_RULE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "添加巡游打卡规则",
+            appendRequestData = true
+    )
     public R<?> addXpCruiseCheckInRule(@RequestBody XpCruiseCheckInRuleDto dto){
         xpCruiseCheckInRuleService.addXpCruiseCheckInRule(dto);
         return R.ok();
@@ -126,6 +135,12 @@
 
     @ApiOperation(value = "删除巡游打卡规则", tags = {"管理后台-巡游打卡规则管理"})
     @PostMapping("/maintenance-admin/api/v1/cruiseCheckInRecord/delXpCruiseCheckInRule/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CRUISE_CHECK_IN_RULE_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除巡游打卡规则,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> delXpCruiseCheckInRule(@PathVariable("id") Integer id){
         xpCruiseCheckInRuleService.removeById(id);
         return R.ok();
@@ -164,6 +179,12 @@
 
     @ApiOperation(value = "查询巡游打卡记录列表导出", tags = {"管理后台-巡游打卡管理"})
     @PostMapping("/maintenance-admin/api/v1/cruiseCheckInRecord/export")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CRUISE_CHECK_IN_RULE_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出巡游打卡记录",
+            appendRequestData = true
+    )
     public R<PageInfo<XpCruiseCheckInRecordVO>> pageListExport(@RequestBody XpCruiseCheckInRecordQuery query, HttpServletResponse response) {
         List<XpCruiseCheckInRecordVO> list = xpCruiseCheckInRecordService.all(query);
         Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpCruiseCheckInRecordVO.class, list);
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
index f6a794d..b3a52dc 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
@@ -4,6 +4,9 @@
 import com.xiaopeng.api.model.account.SysUser;import com.xiaopeng.api.model.maintenance.XpErrorType;
 import com.xiaopeng.api.vo.account.LoginUser;import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.common.security.utils.SecurityUtils;
 import com.xiaopeng.maintenance.dto.SchedulingDetailDto;
@@ -60,6 +63,12 @@
 
     @ApiOperation(value = "排班考勤-排班计划管理-保存排班数据", response = XpErrorType.class, tags = "管理后台-运维执行")
     @PostMapping("/api/v1/scheduling/saveSchedulingDetail")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.SCHEDULING_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'保存排班数据,month=' + #p0.month",
+            appendRequestData = false
+    )
     public R<?> saveSchedulingDetail(@RequestBody SaveSchedulingVo vo){
         SysUser sysUser = tokenService.getLoginUser().getSysUser();
         return xpSchedulingDetailService.saveSchedulingDetail(vo, sysUser.getId());
@@ -69,6 +78,12 @@
 
     @ApiOperation(value = "排班考勤-排班计划管理-导出排班数据", response = XpErrorType.class, tags = "管理后台-运维执行")
     @GetMapping("/api/v1/scheduling/exportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.SCHEDULING_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            contentExpression = "'导出排班数据,month=' + #p0",
+            appendRequestData = false
+    )
     public void exportExcel(@RequestParam("month") String month, HttpServletResponse response) {
         xpSchedulingDetailService.exportExcel(month, response);
     }
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java
index f01353c..5693730 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java
@@ -4,6 +4,9 @@
 import com.xiaopeng.api.model.maintenance.XpShift;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.maintenance.dto.VerifyRangeDTO;
 import com.xiaopeng.maintenance.model.query.XpShiftQuery;
@@ -43,18 +46,36 @@
 
     @ApiOperation(value = "班次管理新增", tags = "管理后台-运维执行")
     @PostMapping("/api/v1/shift/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.SHIFT_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增班次",
+            appendRequestData = true
+    )
     public R<String> add(@RequestBody XpShift dto) {
         return xpShiftService.add(dto);
     }
 
     @ApiOperation(value = "班次管理编辑", tags = "管理后台-运维执行")
     @PostMapping("/api/v1/shift/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.SHIFT_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑班次",
+            appendRequestData = true
+    )
     public R<String> edit(@RequestBody XpShift dto) {
         return xpShiftService.edit(dto);
     }
 
     @ApiOperation(value = "班次管理删除", tags = "管理后台-运维执行")
     @DeleteMapping("/api/v1/shift/deleteById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.SHIFT_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除班次,id=' + #p0",
+            appendRequestData = false
+    )
     public R<String> deleteById(@RequestParam Long id) {
         xpShiftService.removeById(id);
         return R.ok();
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
index 40847e7..a72e04b 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -27,6 +27,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.evi.oss.service.AliOssService;
 import com.xiaopeng.maintenance.dto.HandleVehicleAccidentDto;
@@ -283,6 +286,12 @@
      */
     @ApiOperation(value = "删除删除任务/事故", tags = {"管理后台-车辆管理-运营车辆管理"})
     @DeleteMapping("/api/v1/task/delete/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除任务/事故,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteTaskById(@ApiParam(name = "id", value = "任务ID") @PathVariable Long id) {
         xpTaskService.deleteTaskById(id);
         return R.ok();
@@ -333,6 +342,12 @@
 
     @ApiOperation(value = "待改派的工单导出", tags = {"管理后台-运维执行-任务工单-待改派工单"})
     @PostMapping("/api/v1/task/reassign/export")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出待改派工单",
+            appendRequestData = true
+    )
     public R<?> export(@RequestBody TaskPageListQuery query, HttpServletResponse response) {
         List<XpTaskVO> list = xpTaskService.exportList(query);
         Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpCruiseCheckInRecordVO.class, list);
@@ -454,6 +469,12 @@
 
     @ApiOperation(value = "运营后台改派工单", tags = {"管理后台-运维执行-任务工单-待改派工单"})
     @PostMapping("/api/v1/task/reassign/taskReassignment")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'运营后台改派工单,taskId=' + #p0.taskId + ',newOperationsUserId=' + #p0.newOperationsUserId",
+            appendRequestData = false
+    )
     public R<?> taskReassignment(@RequestBody TaskReassignmentVo vo){
         xpTaskService.taskReassignment(vo);
         return R.ok();
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java
index f02022d..c00377d 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskManagementController.java
@@ -18,6 +18,9 @@
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.utils.ip.IpUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.evi.oss.service.AliOssService;
 import com.xiaopeng.maintenance.dto.HandleVehicleAccidentDto;
@@ -96,6 +99,12 @@
 
     @ApiOperation(value = "任务工单导出")
     @PostMapping(value = "/exportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出任务工单",
+            appendRequestData = true
+    )
     public void exportExcel(@RequestBody TaskManagementPageListQuery query) {
         List<TaskManagementPageListVO> exportList = xpTaskService.exportList(query);
         List<XpTaskExportExcel> taskExportExcels = new ArrayList<>();
@@ -158,6 +167,12 @@
      */
     @ApiOperation(value = "删除任务/事故")
     @DeleteMapping("/deleteTaskById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除任务/事故,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteTaskById(@ApiParam(name = "id", value = "任务ID") Long id) {
         xpTaskService.deleteTaskById(id);
         return R.ok();
@@ -165,6 +180,12 @@
 
     @ApiOperation(value = "任务分配")
     @GetMapping("/assigneeTask")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'任务分配,id=' + #p0 + ',handlerUserId=' + #p1",
+            appendRequestData = false
+    )
     public R assigneeTask(@ApiParam(name = "id", value = "任务ID") Long id, @ApiParam(name = "handlerUserId", value = "处理人id") Long handlerUserId) {
         Long assigneeUserId = tokenService.getLoginUser().getSysUser().getId();
         return xpTaskService.assigneeTask(id, handlerUserId, assigneeUserId);
@@ -172,6 +193,12 @@
 
     @ApiOperation(value = "创建任务事故")
     @PostMapping("/saveTask")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TASK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            contentExpression = "'创建任务事故,vehicleIds=' + #p0.vehicleIds + ',taskTypeId=' + #p0.taskTypeId",
+            appendRequestData = false
+    )
     public R saveTask(@RequestBody SaveErrorTaskDto dto) {
         Long reportUserId = tokenService.getLoginUser().getSysUser().getId();
         xpTaskService.saveTask(dto, reportUserId);
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java
index 5ae6545..aed701c 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java
@@ -5,6 +5,9 @@
 import com.xiaopeng.api.model.maintenance.XpVehicleModel;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.maintenance.model.query.XpVehicleModelPageQuery;
 import com.xiaopeng.maintenance.service.IXpVehicleModelService;
 import io.swagger.annotations.Api;
@@ -66,6 +69,12 @@
     
     @ApiOperation(value = "车型新增", tags = "管理后台-资产-车型管理")
     @PostMapping("/logan/inner/xpVehicleModel/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.VEHICLE_MODEL_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "车型新增",
+            appendRequestData = true
+    )
     public R<String> add(@RequestBody @Valid XpVehicleModel dto) {
         // 根据名称查询车辆型号,验证是否已存在
         List<XpVehicleModel> existingModel = xpVehicleModelService.queryByName(dto.getName());
@@ -81,6 +90,12 @@
 
     @ApiOperation(value = "车型编辑", tags = "管理后台-资产-车型管理")
     @PostMapping("/logan/inner/xpVehicleModel/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.VEHICLE_MODEL_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "车型编辑",
+            appendRequestData = true
+    )
     public R<String> edit(@RequestBody @Valid XpVehicleModel dto) {
         if(dto.getId() == null){
             return R.fail("参数错误");
@@ -104,6 +119,12 @@
 
     @ApiOperation(value = "车型删除", tags = "管理后台-资产-车型管理")
     @DeleteMapping("/logan/inner/xpVehicleModel/deleteById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.VEHICLE_MODEL_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'车型删除,id=' + #p0",
+            appendRequestData = false
+    )
     public R<String> deleteById(@RequestParam Long id) {
         /*
         1.判断车型是否被 车辆 xp_vehicle使用。
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpWorkOrderController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpWorkOrderController.java
index ea0e80b..921db35 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpWorkOrderController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpWorkOrderController.java
@@ -8,6 +8,9 @@
 import com.xiaopeng.api.model.maintenance.XpWorkOrderLog;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.evi.oss.service.AliOssService;
 import com.xiaopeng.maintenance.model.query.WorkOrderPageListQuery;
@@ -54,6 +57,12 @@
     }
     @ApiOperation(value = "创建工单")
     @PostMapping("/saveWorkOrder")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.WORK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            contentExpression = "'创建工单,feedbackTypeId=' + #p0.feedbackTypeId + ',priority=' + #p0.priority",
+            appendRequestData = false
+    )
     public R saveWordOrder(@RequestBody XpWorkOrder workOrder) {
         workOrder.setCreateById(tokenService.getLoginUser().getSysUser().getId());
         workOrderService.save(workOrder);
@@ -61,18 +70,36 @@
     }
     @ApiOperation(value = "编辑工单")
     @PostMapping("/updateWorkOrder")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.WORK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'编辑工单,id=' + #p0.id + ',feedbackTypeId=' + #p0.feedbackTypeId + ',priority=' + #p0.priority",
+            appendRequestData = false
+    )
     public R updateWordOrder(@RequestBody XpWorkOrder workOrder) {
         workOrderService.updateById(workOrder);
         return R.ok();
     }
     @ApiOperation(value = "处理工单")
     @PostMapping("/handleWorkOrder")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.WORK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'处理工单,workOrderId=' + #p0.workOrderId + ',handleType=' + #p0.handleType",
+            appendRequestData = false
+    )
     public R handleWorkOrder(@RequestBody XpWorkOrderLog workOrderLog) {
         workOrderService.handleWorkOrder(workOrderLog);
         return R.ok();
     }
     @ApiOperation(value = "删除工单")
     @DeleteMapping("/deleteWorkOrder")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.WORK_ORDER_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除工单,id=' + #p0",
+            appendRequestData = false
+    )
     public R deleteWordOrder(Long id) {
         workOrderService.removeById(id);
         return R.ok();
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
index ea7a72d..b1ddae2 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
@@ -21,6 +21,9 @@
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.utils.bean.BeanUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.map.constant.I18nKeyConstant;
 import com.xiaopeng.map.service.*;
 import com.xiaopeng.map.service.serviceimpl.BootCommonService;
@@ -129,6 +132,12 @@
      */
     @PostMapping("/add")
     @ApiOperation(value = "新增电子围栏")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ELECTRONIC_FENCE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增电子围栏",
+            appendRequestData = true
+    )
     public R add(@Valid @RequestBody ElectronicFenceAddDto dto) {
         validateFenceTime(dto.getStatus(), dto.getEffectType(), dto.getEffectTime(), dto.getFailureType(), dto.getFailureTime());
         return xpElectronicFenceService.addElectronic(dto);
@@ -142,6 +151,12 @@
     @PostMapping("/updateStatus")
     @ResponseBody
     @ApiOperation(value = "修改状态")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ELECTRONIC_FENCE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "修改电子围栏状态",
+            appendRequestData = true
+    )
     public R updateStatus(@RequestBody ElectronicFenceAreaUpdateStatusDto dto) {
         XpElectronicFenceArea electronicFenceArea = xpElectronicFenceAreaService.getById(dto.getId());
         if (electronicFenceArea == null) {
@@ -247,6 +262,12 @@
     @ApiOperation(value = "编辑电子围栏")
     @Transactional
     @ShardingSphereTransactionType(TransactionType.BASE)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ELECTRONIC_FENCE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑电子围栏",
+            appendRequestData = true
+    )
     public R edit(@Validated @RequestBody ElectronicFenceUpdateDto dto) {
         validateFenceTime(dto.getStatus(), dto.getEffectType(), dto.getEffectTime(), dto.getFailureType(), dto.getFailureTime());
         return xpElectronicFenceService.editElectronic(dto);
@@ -341,6 +362,12 @@
     @ApiOperation(value = "复制电子围栏")
     @Transactional
     @ShardingSphereTransactionType(TransactionType.BASE)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ELECTRONIC_FENCE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            contentExpression = "'复制电子围栏,id=' + #p0",
+            appendRequestData = false
+    )
     public R<Long> copy(@RequestParam("id") Integer id) {
         XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
         if (electronicFence.getStatus()==2){
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
index a9a0a76..dee2018 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
@@ -271,6 +271,7 @@
     }
 
 
+
     @Value("${map.urls.weather:https://restapi.amap.com/v3/weather/weatherInfo?key=%s&city=%s}")
     String WEATHER_URL;
 
@@ -300,4 +301,5 @@
         return R.fail("获取天气信息失败");
     }
 
+
 }
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
index 105e9b2..bfe73d4 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -23,6 +23,9 @@
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.map.constant.I18nKeyConstant;
 import com.xiaopeng.map.exportExcel.XpPointExportExcel;
 import com.xiaopeng.map.mangodb.service.XpGeoFencingPolygonService;
@@ -118,6 +121,12 @@
 
     @ApiOperation(value = "点位导出")
     @PostMapping("/exportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出正式点位",
+            appendRequestData = true
+    )
     public void exportExcel(@RequestBody XpPointExportExcelQuery query) {
         List<Long> pointIds = query == null ? Collections.emptyList() : query.getPointIds();
         List<Long> distinctIds = pointIds == null
@@ -165,6 +174,12 @@
     @PostMapping("/add")
     @ResponseBody
     @ApiOperation(value = "新增点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增正式点位",
+            appendRequestData = true
+    )
     public R<?> add(@Validated @RequestBody PointAddDto pointAddDto) {
         if (xpGeoFencingPolygonService.isInFence(pointAddDto.getPointLon(), pointAddDto.getPointLat(), pointAddDto.getFenceId(), "prohibited_area")) {
             return R.ok("in_prohibited_area");
@@ -179,6 +194,12 @@
     @GetMapping("/deletePoint")
     @ResponseBody
     @ApiOperation(value = "删除点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除正式点位,ids=' + #p0",
+            appendRequestData = false
+    )
     public R deletePoint(@RequestParam("ids") String ids) {
         List<Long> pointIds = Arrays.stream(ids.split(","))
                 .map(String::trim)
@@ -205,6 +226,12 @@
      */
     @PostMapping("/edit")
     @ApiOperation(value = "编辑点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑正式点位",
+            appendRequestData = true
+    )
     @Transactional
     @ShardingSphereTransactionType(TransactionType.BASE)
     public R edit(@Validated @RequestBody PointUpdateDto pointAddDto) {
@@ -304,6 +331,12 @@
      */
     @PostMapping("/enableDisable")
     @ApiOperation(value = "启用/禁用")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_MANAGEMENT,
+            operationType = AdminOperationType.SWITCH_STATUS,
+            content = "启用/禁用正式点位",
+            appendRequestData = true
+    )
     public R enableDisable(@RequestBody XpPointEnableDisableDto dto) {
         XpPoint xpPoint = xpPointService.getById(dto.getId());
         xpPoint.setOperationStatus(dto.getOperationStatus());
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java
index 4585f49..5428f66 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java
@@ -12,6 +12,9 @@
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.utils.bean.BeanUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.map.constant.I18nKeyConstant;
 import com.xiaopeng.map.service.*;
 import com.xiaopeng.map.utils.OperationStrategyIndex;
@@ -92,6 +95,12 @@
      */
     @PostMapping("/add")
     @ApiOperation(value = "新增电子围栏")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_ELECTRONIC_FENCE,
+            operationType = AdminOperationType.ADD,
+            content = "新增测试demo电子围栏",
+            appendRequestData = true
+    )
     public R add(@Validated @RequestBody TestElectronicFenceAddDto dto) {
         validateFenceTime(dto.getStatus(), dto.getEffectType(), dto.getEffectTime(), dto.getFailureType(), dto.getFailureTime());
         return xpElectronicFenceService.addElectronic(dto);
@@ -105,6 +114,12 @@
     @PostMapping("/updateStatus")
     @ResponseBody
     @ApiOperation(value = "修改状态")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_ELECTRONIC_FENCE,
+            operationType = AdminOperationType.EDIT,
+            content = "修改测试demo电子围栏状态",
+            appendRequestData = true
+    )
     public R updateStatus(@RequestBody ElectronicFenceAreaUpdateStatusDto dto) {
         XpTestElectronicFenceArea electronicFenceArea = xpElectronicFenceAreaService.getById(dto.getId());
         if (electronicFenceArea == null) {
@@ -143,6 +158,12 @@
      */
     @PostMapping("/edit")
     @ApiOperation(value = "编辑电子围栏")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_ELECTRONIC_FENCE,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑测试demo电子围栏",
+            appendRequestData = true
+    )
     @Transactional
     @ShardingSphereTransactionType(TransactionType.BASE)
     public R edit(@Validated @RequestBody TestElectronicFenceUpdateDto dto) {
@@ -218,6 +239,12 @@
      */
     @PostMapping("/copy")
     @ApiOperation(value = "复制电子围栏")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_ELECTRONIC_FENCE,
+            operationType = AdminOperationType.ADD,
+            content = "复制测试demo电子围栏",
+            appendRequestData = true
+    )
     @Transactional
     @ShardingSphereTransactionType(TransactionType.BASE)
     public R<Long> copy(@RequestParam("id") Integer id) {
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestPointManagementController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestPointManagementController.java
index 32d8604..502818b 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestPointManagementController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestPointManagementController.java
@@ -17,6 +17,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.map.dto.XpPointSpecialDto;
 import com.xiaopeng.map.service.*;
 import com.xiaopeng.map.vo.SpecialPointListVo;
@@ -83,6 +86,12 @@
     @PostMapping("/api/v1/testPoint/addPoint")
     @ResponseBody
     @ApiOperation(value = "新增点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_POINT_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增测试demo点位",
+            appendRequestData = true
+    )
     public R add(@Validated @RequestBody PointAddDto pointAddDto) {
         XpTestPoint xpPoint = new XpTestPoint();
         BeanUtils.copyProperties(pointAddDto, xpPoint);
@@ -97,6 +106,12 @@
     @GetMapping("/api/v1/testPoint/deletePoint")
     @ResponseBody
     @ApiOperation(value = "删除点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_POINT_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除测试demo点位,ids=' + #p0",
+            appendRequestData = false
+    )
     public R deletePoint(@RequestParam("ids") String ids) {
         xpTestPointService.removeBatchByIds(Arrays.stream(ids.split(","))
                 .map(Long::parseLong).collect(Collectors.toList()));
@@ -108,6 +123,12 @@
      */
     @PostMapping("/api/v1/testPoint/editPoint")
     @ApiOperation(value = "编辑点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_POINT_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑测试demo点位",
+            appendRequestData = true
+    )
     public R edit(@Validated @RequestBody PointUpdateDto pointAddDto) {
         XpTestPoint xpPoint = new XpTestPoint();
         BeanUtils.copyProperties(pointAddDto, xpPoint);
@@ -130,6 +151,12 @@
      */
     @PostMapping("/api/v1/testPoint/enableDisablePoint")
     @ApiOperation(value = "启用/禁用")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_POINT_MANAGEMENT,
+            operationType = AdminOperationType.SWITCH_STATUS,
+            content = "启用/禁用测试demo点位",
+            appendRequestData = true
+    )
     public R enableDisable(@RequestBody XpPointEnableDisableDto dto) {
         XpTestPoint xpPoint = xpTestPointService.getById(dto.getId());
         xpPoint.setOperationStatus(dto.getOperationStatus());
@@ -144,6 +171,12 @@
      */
     @PostMapping("/api/v1/testPoint/setSpecialPoint")
     @ApiOperation(value = "设置特殊点位", tags = "后台管理-特殊点位")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_POINT_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "设置测试demo特殊点位",
+            appendRequestData = true
+    )
     public R setSpecialPoint(@RequestBody XpPointSpecialDto dto) {
         xpTestPointService.update(new LambdaUpdateWrapper<XpTestPoint>().set(XpTestPoint::getChargePoint, 0)
                 .set(XpTestPoint::getParkingPoint, 0));
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java
index 6b32447..b7b2cbc 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java
@@ -14,6 +14,9 @@
 import com.xiaopeng.common.core.constant.CacheConstants;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.service.*;
 import com.xiaopeng.operation.service.IXpActicityCouponService;
 import com.xiaopeng.operation.service.IXpActicityService;
@@ -172,6 +175,12 @@
 
     @PostMapping("/v1/api/appUserCoupon/add")
     @ApiOperation(value = "添加活动", tags = {"管理后台-活动管理"}, response = XpCoupon.class)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACTIVITY_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "添加活动",
+            appendRequestData = true
+    )
     public R<?> add(@RequestBody XpActivityDto dto) {
         service.save(dto);
         return R.ok();
@@ -180,6 +189,12 @@
 
     @PostMapping("/v1/api/appUserCoupon/{op}")
     @ApiOperation(value = "修改活动状态,release,pause,resume,stop,del", tags = {"管理后台-活动管理"}, response = XpCoupon.class)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ACTIVITY_MANAGEMENT,
+            operationTypeExpression = "#p0 == 'release' ? T(com.xiaopeng.common.log.enums.AdminOperationType).RELEASE : (#p0 == 'del' ? T(com.xiaopeng.common.log.enums.AdminOperationType).DELETE : T(com.xiaopeng.common.log.enums.AdminOperationType).EDIT)",
+            contentExpression = "'修改活动状态:' + #p0 + ',id=' + #p1",
+            appendRequestData = true
+    )
     public R<XpActivity> updateById(@PathVariable String op, @RequestParam Long id) {
 
         XpActivity activity = service.getById(id);
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAdminOperationLogController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAdminOperationLogController.java
new file mode 100644
index 0000000..1c16a4c
--- /dev/null
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAdminOperationLogController.java
@@ -0,0 +1,74 @@
+package com.xiaopeng.operation.controller;
+
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
+import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.web.domain.AjaxResult;
+import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.security.annotation.InnerAuth;
+import com.xiaopeng.common.security.annotation.Logical;
+import com.xiaopeng.common.security.annotation.RequiresPermissions;
+import com.xiaopeng.operation.query.AdminOperationLogPageQuery;
+import com.xiaopeng.operation.service.IXpAdminOperationLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 管理后台操作记录
+ */
+@RestController
+@RequestMapping({"/api/v1/adminOperationLog"})
+@Api(tags = "管理后台-操作记录")
+public class XpAdminOperationLogController {
+
+    @Resource
+    private IXpAdminOperationLogService adminOperationLogService;
+
+    @RequiresPermissions(value = {"/adminOperationLog/list", "/operationLog/list"}, logical = Logical.OR)
+    @GetMapping("/list")
+    @ApiOperation(value = "管理后台操作记录分页列表", tags = {"管理后台-操作记录"})
+    public AjaxResult<PageInfo<XpAdminOperationLog>> list(AdminOperationLogPageQuery query) {
+        return AjaxResult.success(adminOperationLogService.pageList(query));
+    }
+
+    @RequiresPermissions(value = {"/adminOperationLog/list", "/operationLog/list"}, logical = Logical.OR)
+    @GetMapping("/businessTypeList")
+    @ApiOperation(value = "管理后台操作记录业务类型列表", tags = {"管理后台-操作记录"})
+    public AjaxResult<List<Map<String, Object>>> businessTypeList() {
+        List<Map<String, Object>> list = Arrays.stream(AdminBusinessType.values())
+                .sorted(Comparator.comparingInt(AdminBusinessType::getCode))
+                .map(type -> {
+                    Map<String, Object> item = new LinkedHashMap<>();
+                    item.put("code", type.getCode());
+                    item.put("desc", type.getDesc());
+                    item.put("name", type.name());
+                    return item;
+                })
+                .collect(Collectors.toList());
+        return AjaxResult.success(list);
+    }
+
+    @InnerAuth
+    @PostMapping("/saveLog")
+    public R<Boolean> saveLog(@RequestBody XpAdminOperationLog adminOperationLog) {
+        if (adminOperationLog.getOperationTime() == null) {
+            adminOperationLog.setOperationTime(LocalDateTime.now());
+        }
+        adminOperationLog.setCreateTime(LocalDateTime.now());
+        return R.ok(adminOperationLogService.save(adminOperationLog));
+    }
+}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAppVersionController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAppVersionController.java
index e474977..95585d5 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAppVersionController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAppVersionController.java
@@ -4,6 +4,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.BasePage;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.service.IXpAppVersionService;
 import com.xiaopeng.operation.vo.XpAppVersionVO;
 import io.swagger.annotations.ApiOperation;
@@ -44,6 +47,12 @@
 
     @ApiOperation(value = "发布APP版本", tags = "管理后台-APP版本")
     @PostMapping("/api/v1/appVersion/release")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.APP_VERSION,
+            operationType = AdminOperationType.RELEASE,
+            content = "发布APP版本",
+            appendRequestData = true
+    )
     public R<?> release(@RequestBody XpAppVersion appVersion) {
         appVersionService.release(appVersion);
         return R.ok();
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpBannerManagementController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpBannerManagementController.java
index 2331c3e..cb64dab 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpBannerManagementController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpBannerManagementController.java
@@ -7,6 +7,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.evi.oss.service.AliOssService;
 import com.xiaopeng.operation.query.BannerPageListQuery;
 import com.xiaopeng.operation.query.WhitelistPageListQuery;
@@ -44,12 +47,24 @@
     }
     @ApiOperation(value = "新增banner")
     @PostMapping("/saveBanner")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.BANNER_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增banner",
+            appendRequestData = true
+    )
     public R saveBanner(@RequestBody XpBanner dto) {
         xpBannerService.save(dto);
         return R.ok();
     }
     @ApiOperation(value = "修改banner")
     @PostMapping("/updateBanner")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.BANNER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "修改banner",
+            appendRequestData = true
+    )
     public R updateBanner(@RequestBody XpBanner dto) {
         xpBannerService.updateById(dto);
         return R.ok();
@@ -75,6 +90,12 @@
     }
     @ApiOperation(value = "删除banner")
     @DeleteMapping("/deleteBanner")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.BANNER_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除banner,id=' + #p0",
+            appendRequestData = false
+    )
     public R deleteBanner(Long id) {
         xpBannerService.removeById(id);
         return R.ok();
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java
index 29a0460..4214f74 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java
@@ -5,6 +5,9 @@
 import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
 import com.xiaopeng.api.model.operation.XpCoupon;
 import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.query.XpCouponListQuery;
 import com.xiaopeng.operation.service.IXpCouponService;
 import io.swagger.annotations.ApiOperation;
@@ -57,6 +60,12 @@
      */
     @PostMapping("/v1/api/xp-coupon/add")
     @ApiOperation(value = "添加优惠券",tags = {"管理后台-优惠券"},response = XpCoupon.class)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.COUPON_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "添加优惠券",
+            appendRequestData = true
+    )
     public R<?> add(@RequestBody XpCoupon xpCoupon){
         xpCouponService.save(xpCoupon);
         return R.ok();
@@ -81,6 +90,12 @@
      */
     @DeleteMapping("/v1/api/xp-coupon/deleteById")
     @ApiOperation(value = "删除优惠券",tags = {"管理后台-优惠券"},response = XpCoupon.class)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.COUPON_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除优惠券,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@RequestParam Long id){
 
         if (!xpAppUserCouponClient.isHolding(id)){
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java
index eb88bf1..fe7ce88 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java
@@ -14,6 +14,9 @@
 import com.xiaopeng.api.model.order.XpCruiseOrder;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.dto.XpCruisePlanAddDTO;
 import com.xiaopeng.operation.dto.XpCruisePlanEditDTO;
 import com.xiaopeng.operation.query.CruisePlanQuery;
@@ -75,6 +78,12 @@
 
     @ApiOperation(value = "新增巡游计划", tags = {"管理后台-巡游计划"})
     @PostMapping(value = {"/api/v1/xp-cruise-plan/add"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CRUISE_PLAN,
+            operationType = AdminOperationType.ADD,
+            content = "新增巡游计划",
+            appendRequestData = true
+    )
     public R<?> add(@Valid @RequestBody XpCruisePlanAddDTO dto) {
         xpCruisePlanService.add(dto);
         return R.ok();
@@ -82,6 +91,12 @@
 
     @ApiOperation(value = "编辑巡游计划", tags = {"管理后台-巡游计划"})
     @PostMapping(value = {"/api/v1/xp-cruise-plan/edit"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CRUISE_PLAN,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑巡游计划",
+            appendRequestData = true
+    )
     public R<?> edit(@Valid @RequestBody XpCruisePlanEditDTO dto) {
         xpCruisePlanService.edit(dto);
         return R.ok();
@@ -89,6 +104,12 @@
 
     @ApiOperation(value = "删除巡游计划", tags = {"管理后台-巡游计划"})
     @DeleteMapping(value = {"/api/v1/xp-cruise-plan/deleteById/{id}"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.CRUISE_PLAN,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除巡游计划,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@ApiParam(name = "id", value = "巡游计划ID") @PathVariable Long id) {
         xpCruisePlanService.deleteById(id);
         return R.ok();
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeManagementController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeManagementController.java
index c5fbb55..017cc46 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeManagementController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeManagementController.java
@@ -5,6 +5,9 @@
 import com.xiaopeng.api.model.operation.XpFeedbackType;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.constant.I18nKeyConstant;
 import com.xiaopeng.operation.service.IXpFeedbackTypeService;
 import io.swagger.annotations.Api;
@@ -48,16 +51,34 @@
     }
     @ApiOperation(value = "新增意见反馈类型")
     @PostMapping(value = "/saveFeedbackType")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FEEDBACK_TYPE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增意见反馈类型",
+            appendRequestData = true
+    )
     public R<Boolean> add(@RequestBody XpFeedbackType xpFeedbackType) {
         return R.ok(xpFeedbackTypeService.save(xpFeedbackType));
     }
     @ApiOperation(value = "编辑意见反馈类型")
     @PostMapping(value = "/updateFeedbackType")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FEEDBACK_TYPE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑意见反馈类型",
+            appendRequestData = true
+    )
     public R<Boolean> updateFeedbackType(@RequestBody XpFeedbackType xpFeedbackType) {
         return R.ok(xpFeedbackTypeService.updateById(xpFeedbackType));
     }
     @ApiOperation(value = "删除意见反馈类型")
     @DeleteMapping(value = "/deleteFeedbackType")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FEEDBACK_TYPE_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除意见反馈类型,id=' + #p0",
+            appendRequestData = false
+    )
     public R<Boolean> deleteFeedbackType(Long id) {
         // 判断工单是否包含这个类型
         R<Boolean> include = xpWorkOrderClient.include(id);
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java
index 25f85e8..e4a068c 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java
@@ -20,6 +20,9 @@
 import com.xiaopeng.common.core.utils.DateUtils;
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.operation.constant.I18nKeyConstant;
 import com.xiaopeng.operation.dto.InvitationAddDto;
@@ -97,6 +100,12 @@
     @PostMapping("/api/v1/invitation/add")
     @ResponseBody
     @ApiOperation(value = "生成邀请码")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.INVITATION_CODE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "生成邀请码",
+            appendRequestData = true
+    )
     public R add(@RequestBody InvitationAddDto dto) {
         long existing = xpInvitationCodeService.count();
         long incoming = Arrays.stream(Optional.ofNullable(dto.getPhones()).orElse("").split(","))
@@ -119,6 +128,12 @@
     @PutMapping("/api/v1/invitation/unbind")
     @ResponseBody
     @ApiOperation(value = "解绑")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.INVITATION_CODE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'解绑邀请码,id=' + #p0",
+            appendRequestData = false
+    )
     @ApiImplicitParams({
             @ApiImplicitParam(value = "id", name = "id", dataType = "Long", required = true)
     })
@@ -165,6 +180,12 @@
 
     @ApiOperation(value = "邀请码导入")
     @PostMapping("/base/v1/invitation/importExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.INVITATION_CODE_MANAGEMENT,
+            operationType = AdminOperationType.IMPORT,
+            content = "导入邀请码",
+            appendRequestData = false
+    )
     public R<String> importExcel(@RequestParam("file") MultipartFile file) {
         ImportParams params = new ImportParams();
         params.setHeadRows(1); //表头行数
@@ -313,6 +334,12 @@
 
     @ApiOperation(value = "邀请码导出")
     @PostMapping(value = "/api/v1/invitation/exportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.INVITATION_CODE_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出邀请码",
+            appendRequestData = true
+    )
     public void exportExcel(@RequestBody InvitationPageListQuery query) {
         List<XpInvitationCode> list = xpInvitationCodeService.exportList(query);
         List<XpInvitationCodeExportExcel> xpWhitelistExportExcels = new ArrayList<>();
@@ -357,6 +384,12 @@
     @GetMapping("/api/v1/invitation/deleteByIds")
     @ResponseBody
     @ApiOperation(value = "批量删除")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.INVITATION_CODE_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'批量删除邀请码,ids=' + #p0",
+            appendRequestData = false
+    )
     public R deleteByIds(String ids) {
         // 再转化为Long类型
         List<Long> longs = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList());
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java
index 4e20d87..67dd908 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpOpenCityController.java
@@ -4,6 +4,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.dto.OpenCityAddDTO;
 import com.xiaopeng.operation.dto.OpenCityEditDTO;
 import com.xiaopeng.operation.query.OpenCityPageQuery;
@@ -101,6 +104,12 @@
      */
     @ApiOperation(value = "新增开通城市", tags = {"管理后台-开通城市管理"})
     @PostMapping("/api/v1/openCity/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPEN_CITY_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增开通城市",
+            appendRequestData = true
+    )
     public R<?> add(@Valid @RequestBody OpenCityAddDTO dto) {
         xpOpenCityService.add(dto);
         return R.ok();
@@ -113,6 +122,12 @@
      */
     @ApiOperation(value = "编辑开通城市", tags = {"管理后台-开通城市管理"})
     @PostMapping("/api/v1/openCity/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPEN_CITY_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑开通城市",
+            appendRequestData = true
+    )
     public R<?> add(@Valid @RequestBody OpenCityEditDTO dto) {
         xpOpenCityService.edit(dto);
         return R.ok();
@@ -125,6 +140,12 @@
      */
     @ApiOperation(value = "删除开通城市", tags = {"管理后台-开通城市管理"})
     @DeleteMapping("/api/v1/openCity/delete/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPEN_CITY_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除开通城市,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@ApiParam(name = "id", value = "开通城市ID") @PathVariable Long id) {
         xpOpenCityService.deleteById(id);
         return R.ok();
@@ -138,6 +159,12 @@
      */
     @ApiOperation(value = "启用/禁用", tags = {"管理后台-开通城市管理"})
     @PostMapping("/api/v1/openCity/upDown")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPEN_CITY_MANAGEMENT,
+            operationTypeExpression = "#p1 == 1 ? T(com.xiaopeng.common.log.enums.AdminOperationType).ENABLE : T(com.xiaopeng.common.log.enums.AdminOperationType).DISABLE",
+            contentExpression = "(#p1 == 1 ? '启用开通城市,id=' : '禁用开通城市,id=') + #p0",
+            appendRequestData = false
+    )
     public R<?> upDown(Long id, Integer status) {
         xpOpenCityService.upDown(id, status);
         return R.ok();
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java
index b6909ba..244e80c 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java
@@ -7,6 +7,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.operation.service.XpOpenCityService;
 import com.xiaopeng.operation.service.XpPasswordFreePolicyService;
@@ -60,6 +63,12 @@
      * 新增路线规划配置
      */
     @ApiOperation(value = "新增免密支付策略", tags = {"管理后台-交易定价-免密支付策略"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PASSWORD_FREE_POLICY,
+            operationType = AdminOperationType.ADD,
+            content = "新增免密支付策略",
+            appendRequestData = true
+    )
     @PostMapping("/api/v1/passwordFreePolicy/add")
     public R<?> add(@Valid @RequestBody XpPasswordFreePolicy dto) {
 
@@ -87,6 +96,12 @@
      * 编辑路线规划配置
      */
     @ApiOperation(value = "编辑免密支付策略", tags = {"管理后台-交易定价-免密支付策略"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PASSWORD_FREE_POLICY,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑免密支付策略",
+            appendRequestData = true
+    )
     @PostMapping("/api/v1/passwordFreePolicy/edit")
     public R<?> edit(@Valid @RequestBody XpPasswordFreePolicy dto) {
         // 1. 查询原记录是否存在
@@ -117,6 +132,12 @@
      * 删除路线规划配置
      */
     @ApiOperation(value = "删除免密支付策略", tags = {"管理后台-管理后台-交易定价-免密支付策略"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PASSWORD_FREE_POLICY,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除免密支付策略,id=' + #p0",
+            appendRequestData = false
+    )
     @DeleteMapping("/api/v1/passwordFreePolicy/deleteById/{id}")
     public R<?> deleteById(@PathVariable Long id) {
         xpPasswordFreePolicyService.deleteById(id);
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java
index 41174b8..d5a0b3d 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java
@@ -15,6 +15,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.operation.exportExcle.XpPointSituationReportExportExcel;
 import com.xiaopeng.operation.service.IXpPointSituationReportService;
@@ -82,6 +85,12 @@
      */
     @ApiOperation(value = "删除现场情况上报", tags = {"管理后台-运维-现场情况上报"})
     @DeleteMapping("/api/v1/pointSituationReport/deleteById/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_SITUATION_REPORT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除现场情况上报,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@PathVariable Long id) {
 
         try {
@@ -100,6 +109,12 @@
 
     @ApiOperation(value = "导出现场情况上报", tags = {"管理后台-运维-现场情况上报"})
     @PostMapping(value = "/api/v1/pointSituationReport/exportExcels")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POINT_SITUATION_REPORT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出现场情况上报",
+            appendRequestData = true
+    )
     public void exportExcels(@RequestBody XpPointSituationReportQuery query) {
         if(query.getIds().isEmpty()){
             return;
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
index 4b97879..44dcdf3 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -14,8 +14,12 @@
 import com.xiaopeng.api.vo.operation.RouteAndFareVo;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.operation.constant.I18nKeyConstant;
 import com.xiaopeng.operation.dto.*;
@@ -32,6 +36,7 @@
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -162,7 +167,12 @@
         if (baseUserByUid != null) {
             try {
                 String phone = baseUserByUid.getMobile();
-                long count = xpWhitelistService.count(new LambdaQueryWrapper<XpWhitelist>().eq(XpWhitelist::getAccount, phone).eq(XpWhitelist::getStatus, 1));
+                if (StringUtils.isBlank(phone)) {
+                    return R.ok(false);
+                }
+                long count = xpWhitelistService.count(new LambdaQueryWrapper<XpWhitelist>()
+                        .in(XpWhitelist::getAccount, SensitiveDataCryptoUtil.queryValues(phone))
+                        .eq(XpWhitelist::getStatus, 1));
                 return R.ok(count > 0);
             } catch (Exception e) {
                 log.error("获取用户信息失败: {}", e.getMessage());
@@ -239,18 +249,36 @@
 
     @PostMapping("/api/v1/pricing/add")
     @ApiOperation(value = "管理后台-新增定价", tags = {"管理后台-定价管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PRICING_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增定价",
+            appendRequestData = true
+    )
     public R<Long> add(@Valid @RequestBody PricingAddDTO dto) {
         return R.ok(xpPricingService.add(dto));
     }
 
     @PostMapping("/api/v1/pricing/edit")
     @ApiOperation(value = "管理后台-编辑定价", tags = {"管理后台-定价管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PRICING_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑定价",
+            appendRequestData = true
+    )
     public R<?> edit(@Valid @RequestBody PricingEditDTO dto) {
         return R.ok(xpPricingService.edit(dto));
     }
 
     @PostMapping("/api/v1/pricing/setPrice")
     @ApiOperation(value = "管理后台-定价管理-设置价格", tags = {"管理后台-定价管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PRICING_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "设置价格",
+            appendRequestData = true
+    )
     public R<?> setPrice(@Valid @RequestBody PricingSetPriceDTO dto) {
         xpPricingService.setPrice(dto);
         return R.ok();
@@ -258,6 +286,12 @@
 
     @PostMapping("/api/v1/pricing/setRule")
     @ApiOperation(value = "管理后台-计费规则富文本配置", tags = {"管理后台-定价管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PRICING_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "配置计费规则",
+            appendRequestData = true
+    )
     public R<?> setRule(@Valid @RequestBody PricingSetRuleDTO dto) {
         xpPricingService.setRule(dto);
         return R.ok();
@@ -265,6 +299,12 @@
 
     @DeleteMapping("/api/v1/pricing/deleteById")
     @ApiOperation(value = "管理后台-定价管理-删除", tags = {"管理后台-定价管理"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.PRICING_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除定价,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@RequestParam Long id) {
         XpPricing pricing = xpPricingService.getById(id);
         if (pricing == null) {
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRoutePlanController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRoutePlanController.java
index 902e054..bb04e29 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRoutePlanController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRoutePlanController.java
@@ -4,6 +4,9 @@
 import com.xiaopeng.api.model.operation.XpRoutePlan;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.dto.RoutePlanAddDTO;
 import com.xiaopeng.operation.dto.RoutePlanEditDTO;
 import com.xiaopeng.operation.query.RoutePlanPageListQuery;
@@ -48,6 +51,12 @@
      * 新增路线规划配置
      */
     @ApiOperation(value = "新增路线规划配置", tags = {"管理后台-交易管理-导航及路线规划"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ROUTE_PLAN_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增路线规划配置",
+            appendRequestData = true
+    )
     @PostMapping("/api/v1/routePlan/add")
     public R<?> add(@Validated @RequestBody RoutePlanAddDTO dto) {
         routePlanService.add(dto);
@@ -58,6 +67,12 @@
      * 编辑路线规划配置
      */
     @ApiOperation(value = "编辑路线规划配置", tags = {"管理后台-交易管理-导航及路线规划"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ROUTE_PLAN_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑路线规划配置",
+            appendRequestData = true
+    )
     @PostMapping("/api/v1/routePlan/edit")
     public R<?> edit(@Validated @RequestBody RoutePlanEditDTO dto) {
         routePlanService.edit(dto);
@@ -68,6 +83,11 @@
      * 删除路线规划配置
      */
     @ApiOperation(value = "删除路线规划配置", tags = {"管理后台-交易管理-导航及路线规划"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ROUTE_PLAN_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除路线规划配置,id=' + #p0"
+    )
     @DeleteMapping("/api/v1/routePlan/deleteById/{id}")
     public R<?> deleteById(@ApiParam(name = "id", value = "线路ID") @PathVariable Long id) {
         routePlanService.deleteById(id);
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java
index 05dfdf1..7452299 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTargetedServiceController.java
@@ -13,6 +13,9 @@
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.utils.bean.BeanUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.operation.dto.WhitelistAddDto;
 import com.xiaopeng.operation.dto.WhitelistEditDto;
@@ -76,6 +79,12 @@
      */
     @PostMapping("/api/v1/targetedService/add")
     @ApiOperation(value = "定向服务-添加", tags = {"管理后台-定向服务添加"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TARGETED_SERVICE,
+            operationType = AdminOperationType.ADD,
+            content = "新增定向服务",
+            appendRequestData = true
+    )
     public R add(@Validated @RequestBody XpTargetedServiceVo dto) {
         SysUser sysUser = tokenService.getLoginUser().getSysUser();
         xpTargetedServiceService.add(dto, sysUser);
@@ -88,6 +97,12 @@
      */
     @PostMapping("/api/v1/targetedService/edit")
     @ApiOperation(value = "定向服务-修改", tags = {"管理后台-定向服务修改"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TARGETED_SERVICE,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑定向服务",
+            appendRequestData = true
+    )
     public R edit(@Validated @RequestBody XpTargetedServiceVo dto) {
         if(dto.getId() == null){
             return R.fail("ID不能为空");
@@ -107,6 +122,12 @@
      */
     @PostMapping("/api/v1/targetedService/updateStatus")
     @ApiOperation(value = "定向服务-修改状态", tags = {"管理后台-定向服务修改状态"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TARGETED_SERVICE,
+            operationTypeExpression = "#p1 == 1 ? T(com.xiaopeng.common.log.enums.AdminOperationType).ENABLE : T(com.xiaopeng.common.log.enums.AdminOperationType).DISABLE",
+            contentExpression = "(#p1 == 1 ? '启用定向服务,id=' : '禁用定向服务,id=') + #p0",
+            appendRequestData = false
+    )
     public R updateStatus(@RequestParam Long id, @RequestParam Integer status) {
         if (id == null) {
             return R.fail("ID不能为空");
@@ -130,6 +151,12 @@
      */
     @PostMapping("/api/v1/targetedService/deleteByIds")
     @ApiOperation(value = "定向服务-批量删除", tags = {"管理后台-定向服务批量删除"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TARGETED_SERVICE,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'批量删除定向服务,ids=' + #p0.ids",
+            appendRequestData = false
+    )
     public R deleteByIds(@RequestBody XpTargetedServiceQuery query ) {
         if(CollUtil.isEmpty(query.getIds())){
             return R.fail("ID列表不能为空");
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTestPlanController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTestPlanController.java
index 68ef6e3..2804492 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTestPlanController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTestPlanController.java
@@ -9,7 +9,9 @@
 import com.xiaopeng.api.model.operation.XpTestPlanVehicle;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
-import com.xiaopeng.operation.dto.XpTestPlanAddDTO;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.operation.dto.XpTestPlanEditDTO;
 import com.xiaopeng.operation.query.TestPlanQuery;
 import com.xiaopeng.operation.service.IXpTestPlanPointService;
@@ -54,6 +56,12 @@
 
     @ApiOperation(value = "新增测试计划", tags = {"管理后台-测试计划"})
     @PostMapping(value = {"/api/v1/xp-test-plan/add"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_PLAN,
+            operationType = AdminOperationType.ADD,
+            content = "新增测试计划",
+            appendRequestData = true
+    )
     public R<Long> add() {
         XpTestPlan plan = new XpTestPlan();
         xpTestPlanService.save(plan);
@@ -62,6 +70,12 @@
 
     @ApiOperation(value = "编辑测试计划", tags = {"管理后台-测试计划"})
     @PostMapping(value = {"/api/v1/xp-test-plan/edit"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_PLAN,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑测试计划",
+            appendRequestData = true
+    )
     public R<?> edit(@Valid @RequestBody XpTestPlanEditDTO dto) {
         xpTestPlanService.edit(dto);
         return R.ok();
@@ -69,6 +83,12 @@
 
     @ApiOperation(value = "删除测试计划", tags = {"管理后台-测试计划"})
     @DeleteMapping(value = {"/api/v1/xp-test-plan/deleteById/{id}"})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.TEST_PLAN,
+            operationType = AdminOperationType.DELETE,
+            content = "删除测试计划",
+            appendRequestData = true
+    )
     public R<?> deleteById(@ApiParam(name = "id", value = "测试计划ID") @PathVariable Long id) {
         xpTestPlanService.deleteById(id);
         return R.ok();
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java
index 1e962b0..0ed3867 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java
@@ -15,6 +15,7 @@
 import com.xiaopeng.api.vo.account.LoginUser;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.utils.bean.BeanUtils;
 import com.xiaopeng.common.core.utils.ip.IpUtils;
@@ -94,6 +95,7 @@
     public R<XpWhitelist> detail(@PathVariable("id") Long id) {
         LoginUser loginUser = tokenService.getLoginUser();
         XpWhitelist xpWhitelist = xpWhitelistService.getById(id);
+        xpWhitelist.setAccount(SensitiveDataCryptoUtil.decryptIfPossible(xpWhitelist.getAccount()));
         if(!loginUser.getPhoneDesensitizationExempt()){
             xpWhitelist.setAccount(DesensitizedUtil.mobilePhone(xpWhitelist.getAccount()));
         }
@@ -284,10 +286,11 @@
             if (!CollectionUtils.isEmpty(candidateAccounts)) {
                 existsAccounts = xpWhitelistService.lambdaQuery()
                         .select(XpWhitelist::getAccount)
-                        .in(XpWhitelist::getAccount, candidateAccounts)
+                        .in(XpWhitelist::getAccount, buildAccountQueryValues(candidateAccounts))
                         .list()
                         .stream()
                         .map(XpWhitelist::getAccount)
+                        .map(SensitiveDataCryptoUtil::decryptIfPossible)
                         .filter(StringUtils::hasLength)
                         .collect(Collectors.toSet());
             }
@@ -302,7 +305,7 @@
             }
             XpWhitelist xpWhitelist = new XpWhitelist();
             xpWhitelist.setNickName(whitelistImportExcel.getNickName());
-            xpWhitelist.setAccount(whitelistImportExcel.getAccount());
+            xpWhitelist.setAccount(SensitiveDataCryptoUtil.encrypt(whitelistImportExcel.getAccount()));
             xpWhitelist.setStatus(true);
             xpWhitelist.setIsPriorityDispatch(true);
             xpWhitelist.setWhitelistSource(1);
@@ -422,6 +425,19 @@
         return value.substring(0, maxLength);
     }
 
+    private static List<String> buildAccountQueryValues(Collection<String> accounts) {
+        Set<String> values = new LinkedHashSet<>();
+        if (accounts == null) {
+            return new ArrayList<>();
+        }
+        for (String account : accounts) {
+            if (StringUtils.hasLength(account)) {
+                values.addAll(SensitiveDataCryptoUtil.queryValues(account));
+            }
+        }
+        return new ArrayList<>(values);
+    }
+
     @ApiOperation(value = "白名单导出")
     @PostMapping(value = "/api/v1/whitelist/exportExcels")
     public void exportExcels(@RequestBody WhitelistPageListQuery query) {
@@ -500,8 +516,12 @@
      */
     @PostMapping("/logan/api/v1/whitelist/inner/getXpWhitelistByPhone")
     public R<List<XpWhitelist>> getXpWhitelistByPhone(@RequestParam String phone){
-        List<XpWhitelist> list = xpWhitelistService.list(new QueryWrapper<XpWhitelist>().eq("account", phone)
+        if (!StringUtils.hasLength(phone)) {
+            return R.ok(Collections.emptyList());
+        }
+        List<XpWhitelist> list = xpWhitelistService.list(new QueryWrapper<XpWhitelist>().in("account", SensitiveDataCryptoUtil.queryValues(phone))
                 .eq("status", 1).eq("is_deleted", 0));
+        list.forEach(item -> item.setAccount(SensitiveDataCryptoUtil.decryptIfPossible(item.getAccount())));
         return R.ok(list);
     }
 
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpAdminOperationLogMapper.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpAdminOperationLogMapper.java
new file mode 100644
index 0000000..2747f9f
--- /dev/null
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpAdminOperationLogMapper.java
@@ -0,0 +1,10 @@
+package com.xiaopeng.operation.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
+
+/**
+ * 管理后台操作记录 Mapper
+ */
+public interface XpAdminOperationLogMapper extends BaseMapper<XpAdminOperationLog> {
+}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/AdminOperationLogPageQuery.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/AdminOperationLogPageQuery.java
new file mode 100644
index 0000000..814189a
--- /dev/null
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/AdminOperationLogPageQuery.java
@@ -0,0 +1,37 @@
+package com.xiaopeng.operation.query;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.xiaopeng.common.core.web.page.BasePage;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+@Data
+@ApiModel(value = "管理后台操作记录分页查询")
+public class AdminOperationLogPageQuery extends BasePage {
+
+    @ApiModelProperty(value = "业务类型:1订单 2车辆 3车队 4账号 5运维 6交易定价 7内容中心 8系统 9白名单 10服务中心 11测试demo电子围栏管理 12测试计划 13账号管理 14权限组管理 15角色管理 16APP版本管理 17用户优惠券管理 18活动管理 19优惠券管理 20Banner管理 21开通城市管理 22电子围栏管理 23现场情况上报 24巡游计划 25在库车辆管理 26运营车辆管理 27车队管理 28车型管理 29定价管理 30路线规划配置管理 31定向服务 32免密支付策略 33运维人员管理 34打卡点管理 35班次管理 36排班计划管理 37任务工单管理 38巡检打卡规则管理 39资质审核 40政策申请 41意见反馈类型管理 42工单管理 43订单管理 44测试demo点位管理 45正式点位管理 46邀请码管理 99其他")
+    private Integer businessType;
+
+    @ApiModelProperty(value = "操作人")
+    private String operatorName;
+
+    @ApiModelProperty(value = "操作账号")
+    private String operatorAccount;
+
+    @ApiModelProperty(value = "操作类型:1新增 2编辑 3删除 4导入 5导出 6冻结 7解冻 8启用 9禁用 10批量冻结 11重置密码 12审核 13启用/禁用 14发布 15发放 99其他")
+    private Integer operationType;
+
+    @ApiModelProperty(value = "开始时间", notes = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty(value = "结束时间", notes = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime endTime;
+}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java
index 4d7e599..e6db519 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java
@@ -20,6 +20,8 @@
     private Integer whitelistSource;
     @ApiModelProperty(value = "选中的记录id集合")
     private List<Long> ids;
+    @ApiModelProperty(value = "白名单账号查询值,包含明文兼容值和密文值")
+    private List<String> accountQueryValues;
 
 
 
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpAdminOperationLogService.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpAdminOperationLogService.java
new file mode 100644
index 0000000..c46f831
--- /dev/null
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpAdminOperationLogService.java
@@ -0,0 +1,14 @@
+package com.xiaopeng.operation.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
+import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.operation.query.AdminOperationLogPageQuery;
+
+/**
+ * 管理后台操作记录服务
+ */
+public interface IXpAdminOperationLogService extends IService<XpAdminOperationLog> {
+
+    PageInfo<XpAdminOperationLog> pageList(AdminOperationLogPageQuery query);
+}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAdminOperationLogServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAdminOperationLogServiceImpl.java
new file mode 100644
index 0000000..f01c0d9
--- /dev/null
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAdminOperationLogServiceImpl.java
@@ -0,0 +1,41 @@
+package com.xiaopeng.operation.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xiaopeng.api.model.operation.XpAdminOperationLog;
+import com.xiaopeng.common.core.utils.StringUtils;
+import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.operation.mapper.XpAdminOperationLogMapper;
+import com.xiaopeng.operation.query.AdminOperationLogPageQuery;
+import com.xiaopeng.operation.service.IXpAdminOperationLogService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 管理后台操作记录服务实现
+ */
+@Service
+public class XpAdminOperationLogServiceImpl extends ServiceImpl<XpAdminOperationLogMapper, XpAdminOperationLog>
+        implements IXpAdminOperationLogService {
+
+    @Override
+    public PageInfo<XpAdminOperationLog> pageList(AdminOperationLogPageQuery query) {
+        PageInfo<XpAdminOperationLog> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
+        LambdaQueryWrapper<XpAdminOperationLog> wrapper = new LambdaQueryWrapper<>();
+        if (query.getBusinessType() != null) {
+            wrapper.eq(XpAdminOperationLog::getBusinessType, query.getBusinessType());
+        }
+        if (StringUtils.isNotEmpty(query.getOperatorName())) {
+            wrapper.like(XpAdminOperationLog::getOperatorName, query.getOperatorName());
+        }
+        if (StringUtils.isNotEmpty(query.getOperatorAccount())) {
+            wrapper.like(XpAdminOperationLog::getOperatorAccount, query.getOperatorAccount());
+        }
+        if (query.getOperationType() != null) {
+            wrapper.eq(XpAdminOperationLog::getOperationType, query.getOperationType());
+        }
+        if (query.getStartTime() != null && query.getEndTime() != null) {
+            wrapper.between(XpAdminOperationLog::getOperationTime, query.getStartTime(), query.getEndTime());
+        }
+        return page(pageInfo, wrapper.orderByDesc(XpAdminOperationLog::getOperationTime));
+    }
+}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java
index 00c88c5..76b796e 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.PhoneUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xiaopeng.api.dto.account.UcUserInfo;
 import com.xiaopeng.api.feignClient.account.UserResourcesClient;
@@ -10,6 +11,7 @@
 import com.xiaopeng.api.model.operation.XpWhitelistOperlog;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.ip.IpUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
 import com.xiaopeng.operation.constant.I18nKeyConstant;
@@ -25,6 +27,7 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
+import java.io.Serializable;
 import java.time.LocalDate;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -48,15 +51,19 @@
 
     @Override
     public PageInfo<XpWhitelist> pageList(WhitelistPageListQuery query) {
+        query.setAccountQueryValues(SensitiveDataCryptoUtil.queryValues(query.getAccount()));
         PageInfo<XpWhitelist> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize());
         List<XpWhitelist> list = this.baseMapper.pageList(pageInfo,query);
+        decryptWhitelistAccounts(list);
         pageInfo.setRecords(list);
         return pageInfo;
     }
 
     @Override
     public List<XpWhitelist> exportList(WhitelistPageListQuery query) {
+        query.setAccountQueryValues(SensitiveDataCryptoUtil.queryValues(query.getAccount()));
         List<XpWhitelist> list = this.baseMapper.exportList(query);
+        decryptWhitelistAccounts(list);
         return list;
     }
 
@@ -115,13 +122,16 @@
 
         Set<String> existsAccounts = new HashSet<>();
         if (CollUtil.isNotEmpty(candidates)) {
-            existsAccounts = this.lambdaQuery()
+            Set<String> existsStoredAccounts = this.lambdaQuery()
                     .select(XpWhitelist::getAccount)
-                    .in(XpWhitelist::getAccount, candidates)
+                    .in(XpWhitelist::getAccount, buildQueryValues(candidates))
                     .list()
                     .stream()
                     .map(XpWhitelist::getAccount)
                     .filter(StringUtils::hasLength)
+                    .collect(Collectors.toSet());
+            existsAccounts = existsStoredAccounts.stream()
+                    .map(SensitiveDataCryptoUtil::decryptIfPossible)
                     .collect(Collectors.toSet());
         }
 
@@ -132,7 +142,7 @@
                 continue;
             }
             XpWhitelist xpWhitelist = new XpWhitelist();
-            xpWhitelist.setAccount(account);
+            xpWhitelist.setAccount(SensitiveDataCryptoUtil.encrypt(account));
             xpWhitelist.setNickName(userMap.get(account).getNickName());
             xpWhitelist.setAppUserId(userMap.get(account).getUid());
             xpWhitelist.setStatus(true);
@@ -165,7 +175,7 @@
         StringBuilder operationContent = new StringBuilder("新增账号:");
         StringBuilder accountBuilder = new StringBuilder();
         for (XpWhitelist item : addList) {
-            accountBuilder.append("\"").append(item.getAccount()).append("\"").append(",");
+            accountBuilder.append("\"").append(SensitiveDataCryptoUtil.decryptIfPossible(item.getAccount())).append("\"").append(",");
         }
         if (accountBuilder.length() > 0) {
             operationContent.append(accountBuilder.substring(0, accountBuilder.length() - 1));
@@ -257,13 +267,14 @@
         }
         UcUserInfo userByAccount = this.getUserByAccount(dto.getAccount());
         XpWhitelist old = this.lambdaQuery()
-                .eq(XpWhitelist::getAccount, dto.getAccount())
+                .in(XpWhitelist::getAccount, SensitiveDataCryptoUtil.queryValues(dto.getAccount()))
                 .ne(XpWhitelist::getId, dto.getId())
                 .last("limit 1").one();
         if (old != null) {
             return R.fail("该账号已存在");
         }
         XpWhitelist whitelist = this.getById(dto.getId());
+        whitelist.setAccount(SensitiveDataCryptoUtil.decryptIfPossible(whitelist.getAccount()));
 
         whitelist.setAppUserId(userByAccount.getUid());
 
@@ -310,7 +321,7 @@
         xpWhitelistOperlogMapper.insert(xpWhitelistOperlog);
         whitelist.setNickName(dto.getNickName());
         whitelist.setIsPriorityDispatch(dto.getIsPriorityDispatch());
-        whitelist.setAccount(dto.getAccount());
+        whitelist.setAccount(SensitiveDataCryptoUtil.encrypt(dto.getAccount()));
         whitelist.setStatus(dto.getStatus());
         this.updateById(whitelist);
         return R.ok();
@@ -319,6 +330,7 @@
     @Override
     public R freezeUnfreeze(Long id, SysUser sysUser) {
         XpWhitelist whitelist = this.getById(id);
+        whitelist.setAccount(SensitiveDataCryptoUtil.decryptIfPossible(whitelist.getAccount()));
         StringBuilder operationContent = new StringBuilder("编辑账号:"+"\""+whitelist.getAccount()+"\"");
         StringBuilder accountBuilder = new StringBuilder();
         accountBuilder.append("状态" + "\"" + (whitelist.getIsPriorityDispatch() ? "正常" : "冻结") + "\"" + "为" + "\"" + (!whitelist.getIsPriorityDispatch() ? "正常" : "冻结") + "\"");
@@ -339,7 +351,9 @@
     @Override
     public R deleteByIds(List<Long> ids, SysUser sysUser) {
         List<String> accounts = this.lambdaQuery().in(XpWhitelist::getId, ids).list()
-                .stream().map(XpWhitelist::getAccount).collect(Collectors.toList());
+                .stream().map(XpWhitelist::getAccount)
+                .map(SensitiveDataCryptoUtil::decryptIfPossible)
+                .collect(Collectors.toList());
         this.removeBatchByIds(ids);
         StringBuilder operationContent = new StringBuilder("删除账号:");
         StringBuilder accountBuilder = new StringBuilder();
@@ -384,6 +398,116 @@
     @Override
     public List<String> getAllWhiteList() {
         return lambdaQuery().select(XpWhitelist::getAccount).list()
-                .stream().map(XpWhitelist::getAccount).collect(Collectors.toList());
+                .stream().map(XpWhitelist::getAccount)
+                .map(SensitiveDataCryptoUtil::decryptIfPossible)
+                .collect(Collectors.toList());
+    }
+
+    private static List<String> buildQueryValues(Collection<String> plainValues) {
+        Set<String> values = new LinkedHashSet<>();
+        if (plainValues == null) {
+            return new ArrayList<>();
+        }
+        for (String plainValue : plainValues) {
+            if (StringUtils.hasLength(plainValue)) {
+                values.addAll(SensitiveDataCryptoUtil.queryValues(plainValue));
+            }
+        }
+        return new ArrayList<>(values);
+    }
+
+    private static void decryptWhitelistAccounts(List<XpWhitelist> list) {
+        if (CollUtil.isEmpty(list)) {
+            return;
+        }
+        for (XpWhitelist item : list) {
+            item.setAccount(SensitiveDataCryptoUtil.decryptIfPossible(item.getAccount()));
+        }
+    }
+
+    @Override
+    public XpWhitelist getById(Serializable id) {
+        XpWhitelist whitelist = super.getById(id);
+        decryptWhitelistAccount(whitelist);
+        return whitelist;
+    }
+
+    @Override
+    public boolean save(XpWhitelist entity) {
+        encryptWhitelistAccount(entity);
+        try {
+            return super.save(entity);
+        } finally {
+            decryptWhitelistAccount(entity);
+        }
+    }
+
+    @Override
+    public boolean saveBatch(Collection<XpWhitelist> entityList) {
+        if (entityList != null) {
+            entityList.forEach(this::encryptWhitelistAccount);
+        }
+        try {
+            return super.saveBatch(entityList);
+        } finally {
+            decryptWhitelistAccounts(entityList);
+        }
+    }
+
+    @Override
+    public boolean updateById(XpWhitelist entity) {
+        encryptWhitelistAccount(entity);
+        try {
+            return super.updateById(entity);
+        } finally {
+            decryptWhitelistAccount(entity);
+        }
+    }
+
+    @Override
+    public boolean updateBatchById(Collection<XpWhitelist> entityList) {
+        if (entityList != null) {
+            entityList.forEach(this::encryptWhitelistAccount);
+        }
+        try {
+            return super.updateBatchById(entityList);
+        } finally {
+            decryptWhitelistAccounts(entityList);
+        }
+    }
+
+    @Override
+    public List<XpWhitelist> list(Wrapper<XpWhitelist> queryWrapper) {
+        List<XpWhitelist> list = super.list(queryWrapper);
+        decryptWhitelistAccounts(list);
+        return list;
+    }
+
+    @Override
+    public List<XpWhitelist> list() {
+        List<XpWhitelist> list = super.list();
+        decryptWhitelistAccounts(list);
+        return list;
+    }
+
+    private void encryptWhitelistAccount(XpWhitelist whitelist) {
+        if (whitelist != null) {
+            whitelist.setAccount(SensitiveDataCryptoUtil.encrypt(whitelist.getAccount()));
+        }
+    }
+
+    private static void decryptWhitelistAccount(XpWhitelist whitelist) {
+        if (whitelist != null) {
+            whitelist.setAccount(SensitiveDataCryptoUtil.decryptIfPossible(whitelist.getAccount()));
+        }
+    }
+
+    private void decryptWhitelistAccounts(Collection<XpWhitelist> list) {
+        if (CollUtil.isEmpty(list)) {
+            return;
+        }
+        for (XpWhitelist item : list) {
+            decryptWhitelistAccount(item);
+        }
     }
 }
diff --git a/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpAdminOperationLogMapper.xml b/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpAdminOperationLogMapper.xml
new file mode 100644
index 0000000..71da303
--- /dev/null
+++ b/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpAdminOperationLogMapper.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.xiaopeng.operation.mapper.XpAdminOperationLogMapper">
+
+    <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.operation.XpAdminOperationLog">
+        <id column="id" property="id"/>
+        <result column="business_type" property="businessType"/>
+        <result column="business_type_name" property="businessTypeName"/>
+        <result column="operator_name" property="operatorName"/>
+        <result column="operator_account" property="operatorAccount"/>
+        <result column="operator_account_id" property="operatorAccountId"/>
+        <result column="operation_type" property="operationType"/>
+        <result column="operation_type_name" property="operationTypeName"/>
+        <result column="operation_content" property="operationContent"/>
+        <result column="operation_ip" property="operationIp"/>
+        <result column="request_uri" property="requestUri"/>
+        <result column="request_method" property="requestMethod"/>
+        <result column="method" property="method"/>
+        <result column="status" property="status"/>
+        <result column="error_msg" property="errorMsg"/>
+        <result column="operation_time" property="operationTime"/>
+        <result column="create_time" property="createTime"/>
+    </resultMap>
+</mapper>
diff --git a/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml b/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml
index 9b1ed27..4c65411 100644
--- a/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml
+++ b/xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml
@@ -13,8 +13,11 @@
         ,create_time as createTime,update_time as updateTime,create_by as createBy,update_by as updateBy
         from xp_whitelist
         where is_deleted = 0
-        <if test="query.account != null and query.account != ''">
-            and account like concat('%',#{query.account},'%')
+        <if test="query.accountQueryValues != null and query.accountQueryValues.size()>0">
+            and account in
+            <foreach item="item" collection="query.accountQueryValues" separator="," open="(" close=")">
+                #{item}
+            </foreach>
         </if>
         <if test="query.nickName != null and query.nickName != ''">
             and nick_name like concat('%',#{query.nickName},'%')
@@ -34,8 +37,11 @@
         ,create_time as createTime,update_time as updateTime,create_by as createBy,update_by as updateBy
         from xp_whitelist
         where is_deleted = 0
-        <if test="query.account != null and query.account != ''">
-            and account like concat('%',#{query.account},'%')
+        <if test="query.accountQueryValues != null and query.accountQueryValues.size()>0">
+            and account in
+            <foreach item="item" collection="query.accountQueryValues" separator="," open="(" close=")">
+                #{item}
+            </foreach>
         </if>
         <if test="query.status != null">
             and status = #{query.status}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/BluetoothDebugConfig.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/BluetoothDebugConfig.java
new file mode 100644
index 0000000..b0039a2
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/BluetoothDebugConfig.java
@@ -0,0 +1,50 @@
+package com.xiaopeng.order.config;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * 蓝牙开锁联调配置(临时)
+ * <p>
+ * 通过 Nacos 配置固定的蓝牙 token、macAddress、slaveMacList,用于联调测试。
+ * <p>
+ * 配置格式示例:
+ * <pre>
+ * bluetooth-debug:
+ *   enabled: false
+ *   token: "your-fixed-token"
+ *   mac-address: "AA:BB:CC:DD:EE:FF"
+ *   slave-mac-list:
+ *     - "AA:BB:CC:DD:EE:01"
+ *     - "AA:BB:CC:DD:EE:02"
+ * </pre>
+ */
+@Slf4j
+@Data
+@ConfigurationProperties(prefix = "bluetooth-debug")
+public class BluetoothDebugConfig {
+
+    /**
+     * 联调开关,默认 false(关闭)
+     */
+    private boolean enabled = false;
+
+    /**
+     * 固定的蓝牙 token
+     */
+    private String token;
+
+    /**
+     * 固定的 MAC 地址
+     */
+    private String macAddress;
+
+    /**
+     * 固定的从设备 MAC 地址列表
+     */
+    private List<String> slaveMacList;
+}
+
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/PropertiesAutoConfiguration.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/PropertiesAutoConfiguration.java
new file mode 100644
index 0000000..c62b9e8
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/config/PropertiesAutoConfiguration.java
@@ -0,0 +1,10 @@
+package com.xiaopeng.order.config;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties({BluetoothDebugConfig.class})
+public class PropertiesAutoConfiguration {
+}
+
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
index b056e11..8c9a76e 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -34,8 +34,12 @@
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.common.security.service.TokenService;
+import com.xiaopeng.order.config.BluetoothDebugConfig;
 import com.xiaopeng.order.dto.OrderNavigationDto;
 import com.xiaopeng.api.model.order.OrderTrajectory;
 import com.xiaopeng.order.model.dto.XpOrderCommentDto;
@@ -112,6 +116,10 @@
 
     @Resource
     private TokenService tokenService;
+
+    @Autowired
+    private BluetoothDebugConfig bluetoothDebugConfig;
+
 
 
     /**
@@ -273,6 +281,12 @@
      */
     @ApiOperation(value = "删除订单", tags = {"管理后台-交易管理-订单管理"})
     @DeleteMapping("/api/v1/order/deleteById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ORDER_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除订单,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@ApiParam(value = "订单id", required = true) @RequestParam Long id) {
         xpOrderService.deleteOrder(id);
         return R.ok();
@@ -285,6 +299,12 @@
      */
     @ApiOperation(value = "订单导出", tags = {"管理后台-交易管理-订单管理"})
     @PostMapping("/api/v1/order/exportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "订单导出",
+            appendRequestData = true
+    )
     public void exportExcel(@RequestBody XpOrderExcelQuery query) {
         // 1. 查询导出数据
         List<XpOrderPageVO> dataList = xpOrderService.exportList(query);
@@ -326,6 +346,12 @@
      */
     @ApiOperation(value = "取消/关闭订单", tags = {"管理后台-交易管理-订单管理"})
     @PostMapping("/api/v1/order/cancelAndCloseById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "取消/关闭订单",
+            appendRequestData = true
+    )
     public R<?> cancelAndCloseById(@Validated @RequestBody XpOrderOperateDTO dto) {
         xpOrderService.cancelOrCloseOrder(dto.getOrderId(), dto.getType(),dto.getIsFree());
         return R.ok();
@@ -339,6 +365,12 @@
      */
     @ApiOperation(value = "改派订单", tags = {"管理后台-交易管理-订单管理"}, notes = "车辆列表在 vehicleConvoy.availableList 服务")
     @PostMapping("/api/v1/order/reassignById")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "改派订单",
+            appendRequestData = true
+    )
     public R<?> reassignById(@Validated @RequestBody XpOrderReassignDTO dto) {
         xpOrderService.reassignOrder(
                 dto.getOrderId(),
@@ -355,6 +387,12 @@
             @ApiImplicitParam(name = "id", value = "订单ID", required = true, dataType = "Long"),
             @ApiImplicitParam(name = "amount", value = "新的订单金额", required = true, dataType = "BigDecimal")
     })
+    @AdminOperationLog(
+            businessType = AdminBusinessType.ORDER_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'订单改价,id=' + #p0 + ',amount=' + #p1",
+            appendRequestData = false
+    )
     public R<?> changeAmount(@RequestParam("id") Long id, @RequestParam("amount") BigDecimal amount) {
         xpOrderService.changeAmount(id, amount);
         return R.ok();
@@ -707,6 +745,18 @@
     @GetMapping("/api/v1/mini-program/bluetooth/getUnlocktToken/{orderId}")
     @XpClientCheck(checkToken = false, checkOtpToken = true)
     public R<BluetoothTokenVo> getBluetoothToken(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
+
+        // ========== 联调临时逻辑:通过 Nacos 配置返回固定蓝牙信息(bluetooth-debug.enabled=true 时生效) ==========
+        if (bluetoothDebugConfig.isEnabled()) {
+            BluetoothTokenVo vo = new BluetoothTokenVo();
+            vo.setToken(bluetoothDebugConfig.getToken());
+            vo.setMacAddress(bluetoothDebugConfig.getMacAddress());
+            vo.setSlaveMacList(bluetoothDebugConfig.getSlaveMacList());
+            return R.ok(vo);
+        }
+        // ========== 联调临时逻辑结束 ==========
+
+        // 原逻辑
         String uid = request.getHeader("XP-Uid");
         XpOrder xpOrder = xpOrderService.getById(orderId);
         if (!Objects.equals(xpOrder.getAppUserId(), Long.valueOf(uid))) {
@@ -876,4 +926,4 @@
         XpOrderInfoVo xpOrderInfoVo = BeanUtil.copyProperties(xpOrder, XpOrderInfoVo.class);
         return R.ok(xpOrderInfoVo);
     }
-}
\ No newline at end of file
+}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
index 7ca3950..b587e5d 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -706,7 +706,8 @@
                     redisService.deleteObject("rt:bluetooth:unlock:order:" + order.getId());
                     XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
                     BluetoothDeliverVo vo = new BluetoothDeliverVo();
-                    vo.setVim(xpVehicle.getVehicleVin());
+                    vo.setCredential(token);
+                    vo.setVin(xpVehicle.getVehicleVin());
                     vo.setPassengerUid(order.getAppUserId());
                     BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
                     if (null == delete || delete.getCode() != 0) {
@@ -1885,8 +1886,7 @@
 
                 BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo);
                 if (baseVehicleUserDto == null) {
-                    // TODO 本地无法调通
-//            throw new RuntimeException("取消订单失败");
+                    throw new RuntimeException("取消订单失败");
                 }
 
                 //还原车辆状态
@@ -1897,23 +1897,24 @@
                     xpVehicleClient.updateVehicleById(vehicle1);
                     log.info("用户取消订单,车辆状态修改0 {}", xpVehicle.getPlateNumber());
                 }
+
+                //删除蓝牙秘钥
+                String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + order.getId());
+                if (StringUtils.isNotBlank(token)) {
+                    redisService.deleteObject("rt:bluetooth:unlock:" + token);
+                    redisService.deleteObject("rt:bluetooth:unlock:order:" + order.getId());
+                    BluetoothDeliverVo vo = new BluetoothDeliverVo();
+                    vo.setCredential(token);
+                    vo.setVin(xpVehicle.getVehicleVin());
+                    vo.setPassengerUid(order.getAppUserId());
+                    BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
+                    if (null == delete || delete.getCode() != 0) {
+                        log.error("删除蓝牙解锁失败:{} {}", delete.getMsg(), order.getOrderNumber());
+                    }
+                }
+
                 //车辆继续巡游
                 addCruiseMission(order, status);
-            }
-
-            //删除蓝牙秘钥
-            String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + order.getId());
-            if (StringUtils.isNotBlank(token)) {
-                redisService.deleteObject("rt:bluetooth:unlock:" + token);
-                redisService.deleteObject("rt:bluetooth:unlock:order:" + order.getId());
-                XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
-                BluetoothDeliverVo vo = new BluetoothDeliverVo();
-                vo.setVim(xpVehicle.getVehicleVin());
-                vo.setPassengerUid(order.getAppUserId());
-                BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
-                if (null == delete || delete.getCode() != 0) {
-                    log.error("删除蓝牙解锁失败:{} {}", delete.getMsg(), order.getOrderNumber());
-                }
             }
         }else{
             //流量接入-订单推送 推送取消订单
@@ -1943,7 +1944,8 @@
                 redisService.deleteObject("rt:bluetooth:unlock:order:" + order.getId());
                 XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
                 BluetoothDeliverVo vo = new BluetoothDeliverVo();
-                vo.setVim(xpVehicle.getVehicleVin());
+                vo.setCredential(token);
+                vo.setVin(xpVehicle.getVehicleVin());
                 vo.setPassengerUid(order.getAppUserId());
                 BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
                 if (null == delete || delete.getCode() != 0) {
@@ -2351,19 +2353,20 @@
         order.setAppUserId(appUserId);
         bootCommonService.setCache_orderStatus(order.getId(), order, null);
         //删除蓝牙秘钥
-//        String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + orderId);
-//        if(StringUtils.isNotBlank(token)){
-//            redisService.deleteObject("rt:bluetooth:unlock:" + token);
-//            redisService.deleteObject("rt:bluetooth:unlock:order:" + orderId);
-//            XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
-//            BluetoothDeliverVo vo = new BluetoothDeliverVo();
-//            vo.setVim(xpVehicle.getVehicleVin());
-//            vo.setPassengerUid(order.getAppUserId());
-//            BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
-//            if(null == delete || delete.getCode() != 0){
-//                log.error("删除蓝牙解锁失败:{} {}", delete.getMsg(), order.getOrderNumber());
-//            }
-//        }
+        String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + orderId);
+        if(StringUtils.isNotBlank(token)){
+            redisService.deleteObject("rt:bluetooth:unlock:" + token);
+            redisService.deleteObject("rt:bluetooth:unlock:order:" + orderId);
+            XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
+            BluetoothDeliverVo vo = new BluetoothDeliverVo();
+            vo.setCredential(token);
+            vo.setVin(xpVehicle.getVehicleVin());
+            vo.setPassengerUid(order.getAppUserId());
+            BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
+            if(null == delete || delete.getCode() != 0){
+                log.error("删除蓝牙解锁失败:{} {}", delete.getMsg(), order.getOrderNumber());
+            }
+        }
 
         // 根据订单所属开通城市id 查询定价
         XpPricing pricing = bootCommonService.getXpPricing(order.getCityId(), order.getVehicleId());
@@ -3826,17 +3829,17 @@
                 //开始下发蓝牙token
                 BluetoothDeliverVo vo = new BluetoothDeliverVo();
                 vo.setCredential(token);
-                vo.setVim(vehicle.getVehicleVin());
+                vo.setVin(vehicle.getVehicleVin());
                 vo.setPassengerUid(order.getAppUserId());
-//                BaseVehicleUserDto deliver = bluetoothUnlockClient.deliver(vo);
-//                if(null == deliver){
-//                    throw new ServiceException("下发蓝牙token失败");
-//                }
-//                if(deliver.getCode() != 0){
-//                    log.error("下发蓝牙token失败:{} {}", deliver.getMsg(), order.getOrderNumber());
-//                    throw new ServiceException(deliver.getMsg());
-//                }
-//                log.info("下发蓝牙token成功:{} {}", deliver.getData(), order.getOrderNumber());
+                BaseVehicleUserDto deliver = bluetoothUnlockClient.deliver(vo);
+                if(null == deliver){
+                    throw new ServiceException("下发蓝牙token失败");
+                }
+                if(deliver.getCode() != 0){
+                    log.error("下发蓝牙token失败:{} {}", deliver.getMsg(), order.getOrderNumber());
+                    throw new ServiceException(deliver.getMsg());
+                }
+                log.info("下发蓝牙token成功:{} {}", deliver.getData(), order.getOrderNumber());
             }
 
             if (order.getStatus() == 2) {
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaskOrderCancelUtil.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaskOrderCancelUtil.java
index f5bc2c6..04498b5 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaskOrderCancelUtil.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaskOrderCancelUtil.java
@@ -84,7 +84,8 @@
             redisService.deleteObject("rt:bluetooth:unlock:order:" + order.getId());
             XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
             BluetoothDeliverVo vo = new BluetoothDeliverVo();
-            vo.setVim(xpVehicle.getVehicleVin());
+            vo.setCredential(token);
+            vo.setVin(xpVehicle.getVehicleVin());
             vo.setPassengerUid(order.getAppUserId());
             BaseVehicleUserDto delete = bluetoothUnlockClient.delete(vo);
             if(null == delete || delete.getCode() != 0){
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
index 18f5b7f..3cb5a77 100644
--- a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
@@ -26,14 +26,44 @@
 
 import java.util.*;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 @Slf4j
 @Api(tags = "订单推送轨迹接口")
 @RestController
 @RequestMapping("")
 public class PushOrderRouteController {
+
+    /**
+     * 推送轨迹重试线程池(类级别单例复用)
+     * 修复:原代码在每次 sendRoute 失败时都 new ThreadPoolExecutor 且不 shutdown,
+     * 导致核心线程在 LinkedBlockingQueue.take() 上永久 WAITING,造成线程泄漏。
+     *
+     * 参数推导(基于业务并发量估算):
+     * - 车端上报频率 ~1次/秒/车,接口限频1.5秒,实际处理 ~0.67次/秒/车
+     * - 常态(50车 + 5%失败率):~1.65 任务/秒,任务耗时~5秒,同时~8个任务
+     * - 突发(100车 + 20%失败率):~13 任务/秒,同时~66个任务
+     * - corePoolSize=4 覆盖常态,maxPoolSize=16 + 队列512 覆盖突发
+     */
+    private static final ThreadPoolExecutor RETRY_EXECUTOR = new ThreadPoolExecutor(
+            4,
+            16,
+            60L, TimeUnit.SECONDS,
+            new LinkedBlockingQueue<>(512),
+            new ThreadFactory() {
+                private final AtomicInteger counter = new AtomicInteger(0);
+                @Override
+                public Thread newThread(Runnable r) {
+                    Thread t = new Thread(r, "route-push-retry-" + counter.incrementAndGet());
+                    t.setDaemon(true);
+                    return t;
+                }
+            },
+            new ThreadPoolExecutor.CallerRunsPolicy()
+    );
 
     @Autowired
     private RedisService redisService;
@@ -141,8 +171,7 @@
                 R<String> stringR = xpPushMessageClient.sendRoute(sendMessageDTO);
                 //推送失败,重试3次
                 if(stringR.getCode() != Constants.SUCCESS){
-                    ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
-                    executor.execute(() -> {
+                    RETRY_EXECUTOR.execute(() -> {
                         for (int i = 0; i < 3; i++) {
                             R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO);
                             if(stringR1.getCode() == Constants.SUCCESS){
@@ -151,7 +180,8 @@
                             try {
                                 Thread.sleep(1000);
                             } catch (InterruptedException e) {
-                                throw new RuntimeException(e);
+                                Thread.currentThread().interrupt();
+                                return;
                             }
                             log.info("推送乘客端剩余导航数据消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), xpOrder.getOrderNumber());
                         }
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
index 86b7c74..1721ceb 100644
--- a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
@@ -11,62 +11,95 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class TrajectoryDensifier {
 
     private static final int THREAD_NUM = 5;
 
+    /**
+     * 轨迹补全计算线程池(类级别单例复用)
+     * 修复:原代码每次调用 densify() 都 new ThreadPoolExecutor 并在方法结束时 shutdown,
+     * 频繁创建/销毁线程开销大,且异常路径(latch.await 被中断)会跳过 shutdown 导致线程泄漏。
+     * 改为单例线程池复用,避免上述问题。
+     */
+    private static final ThreadPoolExecutor DENSIFY_EXECUTOR = new ThreadPoolExecutor(
+            5, 5, 60L, TimeUnit.SECONDS,
+            new LinkedBlockingQueue<>(256),
+            new ThreadFactory() {
+                private final AtomicInteger counter = new AtomicInteger(0);
+                @Override
+                public Thread newThread(Runnable r) {
+                    Thread t = new Thread(r, "trajectory-densify-" + counter.incrementAndGet());
+                    t.setDaemon(true);
+                    return t;
+                }
+            },
+            new ThreadPoolExecutor.CallerRunsPolicy()
+    );
+
+    static {
+        // 允许核心线程超时回收,空闲时不占用资源
+        DENSIFY_EXECUTOR.allowCoreThreadTimeOut(true);
+    }
+
 
     public static List<LonLatDto> densify(List<LonLatDto> originalPoints, int distance) {
+        if (originalPoints == null || originalPoints.size() <= 1) {
+            return new ArrayList<>(originalPoints);
+        }
         int num = originalPoints.size() / THREAD_NUM;
         if(num == 0){
             num = 1;
         }
-        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(num, num, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
         CountDownLatch latch = new CountDownLatch(num);
-        Map<Integer, List<LonLatDto>> map = new HashMap<>();
+        Map<Integer, List<LonLatDto>> map = new ConcurrentHashMap<>();
         for (int i = 0; i < num; i++) {
             List<LonLatDto> trackPoints = originalPoints.subList(i * THREAD_NUM, i == num - 1 ? originalPoints.size() : (i + 1) * THREAD_NUM);
             int finalI = i;
-            poolExecutor.execute(()->{
-                List<LonLatDto> new_polyline = new ArrayList<>();
-                for (int j = 0; j < trackPoints.size(); j++) {
-                    LonLatDto trackPoint = trackPoints.get(j);
-                    if(j == trackPoints.size() - 1){
-                        new_polyline.add(new LonLatDto(trackPoint.getLongitude(), trackPoint.getLatitude()));
-                        break;
-                    }
-                    LonLatDto trackPoint1 = trackPoints.get(j+1);
+            DENSIFY_EXECUTOR.execute(()->{
+                try {
+                    List<LonLatDto> new_polyline = new ArrayList<>();
+                    for (int j = 0; j < trackPoints.size(); j++) {
+                        LonLatDto trackPoint = trackPoints.get(j);
+                        if(j == trackPoints.size() - 1){
+                            new_polyline.add(new LonLatDto(trackPoint.getLongitude(), trackPoint.getLatitude()));
+                            break;
+                        }
+                        LonLatDto trackPoint1 = trackPoints.get(j+1);
 
-                    //对两个点位进行坐标补全
-                    List<TrackPoint> track = new ArrayList<>();
-                    track.add(new TrackPoint(trackPoint.getLatitude(), trackPoint.getLongitude(), null));
-                    track.add(new TrackPoint(trackPoint1.getLatitude(), trackPoint1.getLongitude(), null));
-                    //10米补全一个点位
-                    List<TrackPoint> densified = densifyByDistance(track, distance);
-                    for (TrackPoint point : densified) {
-                        new_polyline.add(new LonLatDto(point.getLongitude(), point.getLatitude()));
+                        //对两个点位进行坐标补全
+                        List<TrackPoint> track = new ArrayList<>();
+                        track.add(new TrackPoint(trackPoint.getLatitude(), trackPoint.getLongitude(), null));
+                        track.add(new TrackPoint(trackPoint1.getLatitude(), trackPoint1.getLongitude(), null));
+                        //10米补全一个点位
+                        List<TrackPoint> densified = densifyByDistance(track, distance);
+                        for (TrackPoint point : densified) {
+                            new_polyline.add(new LonLatDto(point.getLongitude(), point.getLatitude()));
+                        }
                     }
+                    if (!new_polyline.isEmpty()) {
+                        new_polyline.remove(new_polyline.size() - 1);
+                    }
+                    map.put(finalI, new_polyline);
+                } finally {
+                    latch.countDown();
                 }
-                new_polyline.remove(new_polyline.size() - 1);
-                map.put(finalI, new_polyline);
-                latch.countDown();
             });
         }
         try {
             latch.await();
-            poolExecutor.shutdown();
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            Thread.currentThread().interrupt();
             throw new RuntimeException(e);
         }
         List<LonLatDto> result = new ArrayList<>();
         for (int i = 0; i < num; i++) {
-            result.addAll(map.get(i));
+            List<LonLatDto> chunk = map.get(i);
+            if (null != chunk) {
+                result.addAll(chunk);
+            }
         }
         //添加最后一个点
         result.add(originalPoints.get(originalPoints.size() - 1));
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/service/WebSocketUserChannelConnectionManager.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/service/WebSocketUserChannelConnectionManager.java
new file mode 100644
index 0000000..46ad62d
--- /dev/null
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/service/WebSocketUserChannelConnectionManager.java
@@ -0,0 +1,282 @@
+package com.xiaopeng.pushMessage.webSocket.service;
+
+import io.netty.channel.Channel;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 基于 AppUser 的 WebSocket 连接管理器
+ * 使用 Spring WebSocketSession(共用 Spring Boot HTTP 端口)
+ * 支持按用户 ID 管理连接,一个用户可以有多个设备连接
+ */
+@Component
+@Slf4j
+public class WebSocketUserChannelConnectionManager {
+
+    /**
+     * 存储用户的所有连接
+     * Key: 用户ID (appUserId)
+     * Value: 该用户的所有连接Channel列表
+     */
+    private static final ConcurrentHashMap<String, Set<Channel>> userConnections = new ConcurrentHashMap<>();
+
+    /**
+     * 存储连接与用户的映射关系
+     * Key: ChannelId.asLongText()
+     * Value: 用户ID (appUserId)
+     */
+    private static final ConcurrentHashMap<String, String> channelToUser = new ConcurrentHashMap<>();
+
+    /**
+     * 存储所有连接
+     * Key: ChannelId.asLongText()
+     * Value: Channel
+     */
+    private static final ConcurrentHashMap<String, Channel> allConnections = new ConcurrentHashMap<>();
+
+    /**
+     * 添加用户连接
+     * @param appUserId 用户ID
+     * @param channel WebSocket连接通道
+     */
+    public void addUserConnection(String appUserId, Channel channel) {
+        String channelId = channel.id().asLongText();
+
+        // 添加到用户连接映射
+        userConnections.computeIfAbsent(appUserId, k -> ConcurrentHashMap.newKeySet())
+                .add(channel);
+
+        // 添加到连接用户映射
+        channelToUser.put(channelId, appUserId);
+
+        // 添加到所有连接
+        allConnections.put(channelId, channel);
+
+        log.info("用户连接已添加,用户ID: {}, ChannelId: {}, 该用户连接数: {}",
+                appUserId, channelId, userConnections.get(appUserId).size());
+    }
+
+    /**
+     * 移除用户连接
+     * @param channel WebSocket连接通道
+     */
+    public void removeUserConnection(Channel channel) {
+        String channelId = channel.id().asLongText();
+        String appUserId = channelToUser.get(channelId);
+
+        if (appUserId != null) {
+            // 从用户连接中移除
+            Set<Channel> userChannels = userConnections.get(appUserId);
+            if (userChannels != null) {
+                userChannels.remove(channel);
+                // 如果用户没有连接了,删除用户映射
+                if (userChannels.isEmpty()) {
+                    userConnections.remove(appUserId);
+                }
+            }
+
+            // 从连接用户映射中移除
+            channelToUser.remove(channelId);
+
+            log.info("用户连接已移除,用户ID: {}, ChannelId: {}, 该用户剩余连接数: {}",
+                    appUserId, channelId, userChannels != null ? userChannels.size() : 0);
+        }
+
+        // 从所有连接中移除
+        allConnections.remove(channelId);
+    }
+
+    /**
+     * 向指定用户的所有设备发送消息
+     * @param appUserId 用户ID
+     * @param message 消息内容
+     * @return 成功发送的设备数
+     */
+    public int sendMessageToUser(String appUserId, String message) {
+        Set<Channel> userChannels = userConnections.get(appUserId);
+        if (userChannels == null || userChannels.isEmpty()) {
+            log.warn("用户 {} 没有活跃连接", appUserId);
+            return 0;
+        }
+
+        int successCount = 0;
+        for (Channel channel : userChannels) {
+            if (channel != null && channel.isActive()) {
+                try {
+                    channel.writeAndFlush(new TextWebSocketFrame(message));
+                    successCount++;
+                } catch (Exception e) {
+                    log.error("向用户 {} 发送消息失败,连接ID: {}, 错误: {}",
+                            appUserId, channel.id().asLongText(), e.getMessage());
+                }
+            }
+        }
+
+        log.info("向用户 {} 发送消息完成,成功发送到 {} 个设备,消息内容: {}",
+                appUserId, successCount, message);
+        return successCount;
+    }
+
+    /**
+     * 向指定连接发送消息
+     * @param channelId 连接ID
+     * @param message 消息内容
+     * @return 是否发送成功
+     */
+    public boolean sendMessageToChannel(String channelId, String message) {
+        Channel channel = allConnections.get(channelId);
+        if (channel != null && channel.isActive()) {
+            try {
+                channel.writeAndFlush(new TextWebSocketFrame(message));
+                log.info("消息已发送到连接: {}, 内容: {}", channelId, message);
+                return true;
+            } catch (Exception e) {
+                log.error("发送消息失败,连接ID: {}, 错误: {}", channelId, e.getMessage());
+                return false;
+            }
+        } else {
+            log.warn("连接不存在或已关闭,ChannelId: {}", channelId);
+            return false;
+        }
+    }
+
+    /**
+     * 向所有连接广播消息
+     * @param message 消息内容
+     * @return 成功发送的连接数
+     */
+    public int broadcastMessage(String message) {
+        int successCount = 0;
+        for (Channel channel : allConnections.values()) {
+            if (channel != null && channel.isActive()) {
+                try {
+                    channel.writeAndFlush(new TextWebSocketFrame(message));
+                    successCount++;
+                } catch (Exception e) {
+                    log.error("广播消息失败,连接ID: {}, 错误: {}",
+                            channel.id().asLongText(), e.getMessage());
+                }
+            }
+        }
+        log.info("广播消息完成,成功发送到 {} 个连接,消息内容: {}", successCount, message);
+        return successCount;
+    }
+
+    /**
+     * 向多个用户发送消息
+     * @param appUserIds 用户ID列表
+     * @param message 消息内容
+     * @return 成功发送的用户数
+     */
+    public int sendMessageToUsers(List<String> appUserIds, String message) {
+        int successUserCount = 0;
+        for (String appUserId : appUserIds) {
+            int deviceCount = sendMessageToUser(appUserId, message);
+            if (deviceCount > 0) {
+                successUserCount++;
+            }
+        }
+        log.info("向 {} 个用户发送消息完成,成功发送到 {} 个用户", appUserIds.size(), successUserCount);
+        return successUserCount;
+    }
+
+    /**
+     * 获取用户的所有连接
+     * @param appUserId 用户ID
+     * @return 连接列表
+     */
+    public Set<Channel> getUserConnections(String appUserId) {
+        return userConnections.getOrDefault(appUserId, Collections.emptySet());
+    }
+
+    /**
+     * 获取用户连接数
+     * @param appUserId 用户ID
+     * @return 连接数
+     */
+    public int getUserConnectionCount(String appUserId) {
+        Set<Channel> userChannels = userConnections.get(appUserId);
+        return userChannels != null ? userChannels.size() : 0;
+    }
+
+    /**
+     * 获取总连接数
+     * @return 总连接数
+     */
+    public int getTotalConnectionCount() {
+        return allConnections.size();
+    }
+
+    /**
+     * 获取在线用户数
+     * @return 在线用户数
+     */
+    public int getOnlineUserCount() {
+        return userConnections.size();
+    }
+
+    /**
+     * 获取所有在线用户ID
+     * @return 用户ID集合
+     */
+    public Set<String> getOnlineUserIds() {
+        return userConnections.keySet();
+    }
+
+    /**
+     * 检查用户是否在线
+     * @param appUserId 用户ID
+     * @return 是否在线
+     */
+    public boolean isUserOnline(String appUserId) {
+        Set<Channel> userChannels = userConnections.get(appUserId);
+        if (userChannels == null || userChannels.isEmpty()) {
+            return false;
+        }
+        // 检查是否有活跃连接
+        return userChannels.stream().anyMatch(Channel::isActive);
+    }
+
+    /**
+     * 检查连接是否存在
+     * @param channelId 连接ID
+     * @return 是否存在
+     */
+    public boolean isConnectionExists(String channelId) {
+        Channel channel = allConnections.get(channelId);
+        return channel != null && channel.isActive();
+    }
+
+    /**
+     * 根据连接ID获取用户ID
+     * @param channelId 连接ID
+     * @return 用户ID
+     */
+    public String getUserIdByChannelId(String channelId) {
+        return channelToUser.get(channelId);
+    }
+
+    /**
+     * 获取连接统计信息
+     * @return 统计信息
+     */
+    public Map<String, Object> getConnectionStats() {
+        Map<String, Object> stats = new HashMap<>();
+        stats.put("totalConnections", getTotalConnectionCount());
+        stats.put("onlineUsers", getOnlineUserCount());
+        stats.put("onlineUserIds", getOnlineUserIds());
+
+        // 统计每个用户的连接数
+        Map<String, Integer> userConnectionCounts = new HashMap<>();
+        for (Map.Entry<String, Set<Channel>> entry : userConnections.entrySet()) {
+            userConnectionCounts.put(entry.getKey(), entry.getValue().size());
+        }
+        stats.put("userConnectionCounts", userConnectionCounts);
+
+        return stats;
+    }
+}
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
index d8e8ebc..c08a543 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
@@ -11,6 +11,9 @@
 import com.xiaopeng.api.vo.account.LoginUser;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.vehicleConvoy.model.dto.FleetAddDTO;
 import com.xiaopeng.vehicleConvoy.model.dto.FleetEditDTO;
@@ -129,6 +132,12 @@
      */
     @ApiOperation(value = "添加车队", tags = {"管理后台-车队管理"}, notes = "打卡地列表接口在xp-robotaxi-maintenance-boot,人员列表在xp-robotaxi-account-boot")
     @PostMapping("/api/v1/fleet/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "添加车队",
+            appendRequestData = true
+    )
     public R<Void> add(@Valid @RequestBody FleetAddDTO dto) {
         return xpFleetService.add(dto);
     }
@@ -141,6 +150,12 @@
      */
     @ApiOperation(value = "编辑车队", tags = {"管理后台-车队管理"}, notes = "打卡地列表接口在xp-robotaxi-maintenance-boot,人员列表在xp-robotaxi-account-boot")
     @PostMapping("/api/v1/fleet/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑车队",
+            appendRequestData = true
+    )
     public R<Void> edit(@Valid @RequestBody FleetEditDTO dto) {
         return xpFleetService.edit(dto);
     }
@@ -207,6 +222,12 @@
 
     @ApiOperation(value = "删除车队", tags = {"管理后台-车队管理"})
     @DeleteMapping("/api/v1/fleet/delete/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除车队,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@ApiParam(name = "id", value = "车队ID") @PathVariable Long id) {
         xpFleetService.deleteById(id);
         return R.ok();
@@ -217,6 +238,12 @@
     @ApiImplicitParams({
             @ApiImplicitParam(name = "fleetId", value = "车队ID", dataTypeClass = Long.class),
             @ApiImplicitParam(name = "vehicleId", value = "车辆ID", dataTypeClass = Long.class)})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            contentExpression = "'车队添加车辆成员,fleetId=' + #p0 + ',vehicleId=' + #p1",
+            appendRequestData = false
+    )
     public R<?> addVehicle(Long fleetId, Long vehicleId) {
         xpFleetService.addVehicle(fleetId, vehicleId);
         return R.ok();
@@ -227,6 +254,12 @@
     @ApiImplicitParams({
             @ApiImplicitParam(name = "fleetId", value = "车队ID", dataTypeClass = Long.class),
             @ApiImplicitParam(name = "operationUserId", value = "车辆ID", dataTypeClass = Long.class)})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            contentExpression = "'车队添加人员成员,fleetId=' + #p0 + ',operationUserId=' + #p1",
+            appendRequestData = false
+    )
     public R<?> addOperationUserId(Long fleetId, Long operationUserId) {
         xpFleetService.addOperationUserId(fleetId, operationUserId);
         return R.ok();
@@ -237,6 +270,12 @@
     @ApiImplicitParams({
             @ApiImplicitParam(name = "fleetId", value = "车队ID", dataTypeClass = Long.class, required = true),
             @ApiImplicitParam(name = "vehicleId", value = "车辆ID", dataTypeClass = Long.class, required = true)})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'车队删除车辆成员,fleetId=' + #p0 + ',vehicleId=' + #p1",
+            appendRequestData = false
+    )
     public R<?> removeVehicle(Long fleetId, Long vehicleId) {
         xpFleetService.removeVehicle(fleetId, vehicleId);
         return R.ok();
@@ -247,6 +286,12 @@
     @ApiImplicitParams({
             @ApiImplicitParam(name = "fleetId", value = "车队ID", dataTypeClass = Long.class, required = true),
             @ApiImplicitParam(name = "operationUserId", value = "人员ID", dataTypeClass = Long.class, required = true)})
+    @AdminOperationLog(
+            businessType = AdminBusinessType.FLEET_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'车队删除人员成员,fleetId=' + #p0 + ',operationUserId=' + #p1",
+            appendRequestData = false
+    )
     public R<?> removeOperationUser(Long fleetId, Long operationUserId) {
         xpFleetService.removeOperationUser(fleetId, operationUserId);
         return R.ok();
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpPolicyApplicationController.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpPolicyApplicationController.java
index 6c622c9..01c91e8 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpPolicyApplicationController.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpPolicyApplicationController.java
@@ -2,6 +2,9 @@
 
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.vehicleConvoy.model.dto.XpPolicyApplicationAuditDTO;
 import com.xiaopeng.vehicleConvoy.model.query.XpPolicyApplicationQuery;
@@ -39,12 +42,24 @@
 
     @ApiOperation("批量审核")
     @PostMapping("/api/v1/policyApplication/batchAudit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POLICY_APPLICATION,
+            operationType = AdminOperationType.AUDIT,
+            contentExpression = "'批量审核保单申请,ids=' + #p0.ids + ',auditStatus=' + #p0.auditStatus",
+            appendRequestData = false
+    )
     public R<?> batchAudit(@Valid @RequestBody XpPolicyApplicationAuditDTO dto) {
         xpPolicyApplicationService.batchAudit(dto);
         return R.ok();
     }
     @ApiOperation("删除保单申请")
     @DeleteMapping("/api/v1/policyApplication/deleteById/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.POLICY_APPLICATION,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除保单申请,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> deleteById(@PathVariable Long id) {
         xpPolicyApplicationService.removeById(id);
         return R.ok();
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
index 791d304..f7e8169 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -32,8 +32,12 @@
 import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandCallbackVo;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.utils.WebUtils;
 import com.xiaopeng.common.core.web.page.PageInfo;
+import com.xiaopeng.common.log.annotation.AdminOperationLog;
+import com.xiaopeng.common.log.enums.AdminBusinessType;
+import com.xiaopeng.common.log.enums.AdminOperationType;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.evi.oss.service.AliOssService;
 import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
@@ -190,6 +194,12 @@
      */
     @ApiOperation(value = "新增车辆", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/add")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.ADD,
+            content = "新增车辆",
+            appendRequestData = true
+    )
     public R<?> addVehicle(@Valid @RequestBody VehicleAddDTO dto) {
         xpVehicleService.addVehicle(dto, null);
         return R.ok();
@@ -203,6 +213,12 @@
      */
     @ApiOperation(value = "编辑车辆", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/edit")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "编辑车辆",
+            appendRequestData = true
+    )
     public R<?> editVehicle(@Valid @RequestBody VehicleEditDTO dto) {
         xpVehicleService.editVehicle(dto, null);
         return R.ok();
@@ -216,6 +232,12 @@
      */
     @ApiOperation(value = "完善/更新车辆信息", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/improveInfo")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "完善/更新车辆信息",
+            appendRequestData = true
+    )
     public R<?> improveInfo(@RequestBody VehicleImproveInfoDTO dto) {
         xpVehicleService.improveInfo(dto);
         return R.ok();
@@ -230,6 +252,12 @@
     @ApiOperation(value = "批量运营", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/batchOperation")
     @ApiImplicitParam(name = "idStr", value = "车辆ID字符串列表,逗号分隔", required = true, dataTypeClass = String.class)
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'批量运营车辆,ids=' + #p0",
+            appendRequestData = false
+    )
     public R<?> batchOperation(@RequestParam String idStr) {
         xpVehicleService.batchOperation(idStr);
         return R.ok();
@@ -243,6 +271,12 @@
      */
     @ApiOperation(value = "批量设置运营区域", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/batchSetElectronic")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            content = "批量设置运营区域",
+            appendRequestData = true
+    )
     public R<?> batchSetElectronic(@Valid @RequestBody VehicleBatchSetElectronicDTO dto) {
         xpVehicleService.batchSetElectronic(dto.getIds(), dto.getElectronicId());
         return R.ok();
@@ -266,6 +300,12 @@
      */
     @ApiOperation(value = "下载导入模板", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/importTemplate")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "下载车辆导入模板",
+            appendRequestData = false
+    )
     public void importTemplate() {
         // 1. 查询导出数据
         Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpVehicleImportExcel.class, new ArrayList<>());
@@ -301,6 +341,12 @@
      */
     @ApiOperation(value = "导入", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/importExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.IMPORT,
+            content = "导入车辆",
+            appendRequestData = false
+    )
     public R<?> importExcel(@RequestParam("file") MultipartFile file) {
         ImportParams params = new ImportParams();
         params.setHeadRows(1);
@@ -467,12 +513,16 @@
         }
         Set<String> existsVins = Collections.emptySet();
         if (!vinSet.isEmpty()) {
+            Set<String> vinQueryValues = vinSet.stream()
+                    .flatMap(vin -> SensitiveDataCryptoUtil.queryValues(vin).stream())
+                    .collect(java.util.stream.Collectors.toSet());
             existsVins = xpVehicleService.lambdaQuery()
                     .select(XpVehicle::getVehicleVin)
-                    .in(XpVehicle::getVehicleVin, vinSet)
+                    .in(XpVehicle::getVehicleVin, vinQueryValues)
                     .list()
                     .stream()
                     .map(XpVehicle::getVehicleVin)
+                    .map(SensitiveDataCryptoUtil::decryptIfPossible)
                     .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
                     .collect(java.util.stream.Collectors.toSet());
         }
@@ -574,6 +624,12 @@
      */
     @ApiOperation(value = "导出", tags = {"管理后台-车辆管理-在库车辆管理"})
     @PostMapping("/api/v1/vehicle/exportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出在库车辆",
+            appendRequestData = true
+    )
     public void exportExcel(@RequestBody VehicleExportQuery query) {
         // 1. 查询导出数据
         List<XpVehicle> dataList = xpVehicleService.vehicleExportList(query);
@@ -621,6 +677,12 @@
     @ApiOperation(value = "批量在库", tags = {"管理后台-车辆管理-运营车辆管理"})
     @ApiImplicitParam(name = "idStr", value = "车辆ID字符串列表,逗号分隔", required = true, dataTypeClass = String.class)
     @PostMapping("/api/v1/vehicle/batchStock")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATION_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EDIT,
+            contentExpression = "'批量在库车辆,ids=' + #p0",
+            appendRequestData = false
+    )
     public R<?> batchStock(@RequestParam String idStr) {
         xpVehicleService.batchStock(idStr);
         return R.ok();
@@ -654,6 +716,12 @@
      */
     @ApiOperation(value = "删除在库车辆", tags = {"管理后台-车辆管理-在库车辆管理"})
     @DeleteMapping("/api/v1/vehicle/delete/{id}")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.STOCK_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.DELETE,
+            contentExpression = "'删除在库车辆,id=' + #p0",
+            appendRequestData = false
+    )
     public R<?> delete(@ApiParam(name = "id", value = "车辆ID") @PathVariable Long id) {
         XpFleetVehicle binding = vehicleService.lambdaQuery()
                 .eq(XpFleetVehicle::getVehicleId, id)
@@ -695,6 +763,12 @@
      */
     @ApiOperation(value = "运营车辆管理列表导出", tags = {"管理后台-车辆管理-运营车辆管理"})
     @PostMapping("/api/v1/vehicle/operationExportExcel")
+    @AdminOperationLog(
+            businessType = AdminBusinessType.OPERATION_VEHICLE_MANAGEMENT,
+            operationType = AdminOperationType.EXPORT,
+            content = "导出运营车辆",
+            appendRequestData = true
+    )
     public void exportExcel(@RequestBody OperationVehicleExportQuery query) {
         // 1. 查询导出数据
         List<XpVehicle> dataList = xpVehicleService.operationVehicleExportList(query);
@@ -772,9 +846,15 @@
      */
     @PostMapping("/logan/inner/vehicle/queryVehiclePositionByVin")
     public R<List<String>> queryVehiclePositionByVin(@RequestBody VehiclePositionByVinDto dto){
+        if (dto == null) {
+            return R.ok(new ArrayList<>());
+        }
+        List<String> vinQueryValues = buildVinQueryValues(dto.getVinList());
+        if (vinQueryValues.isEmpty()) {
+            return R.ok(new ArrayList<>());
+        }
         List<XpVehicle> list = xpVehicleService.list(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getState, Optional.ofNullable(dto.getStatus()).orElse(0))
-                .eq(XpVehicle::getOperatingStatus, 1).eq(XpVehicle::getElectronicId, dto.getFenceId()).in(XpVehicle::getVehicleVin,
-                dto.getVinList()));
+                .eq(XpVehicle::getOperatingStatus, 1).eq(XpVehicle::getElectronicId, dto.getFenceId()).in(XpVehicle::getVehicleVin, vinQueryValues));
         if (list.isEmpty()) {
             return R.ok(new ArrayList<>());
         } else {
@@ -796,7 +876,13 @@
      */
     @GetMapping("/logan/inner/vehicle/findByVehicleVin")
     public R<XpVehicle> findByVehicleVin(@RequestParam("vehicleVin") String vehicleVin) {
-        XpVehicle xpVehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getVehicleVin, vehicleVin));
+        if (StringUtils.isBlank(vehicleVin)) {
+            return R.ok();
+        }
+        XpVehicle xpVehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().in(XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(vehicleVin)));
+        if (xpVehicle == null) {
+            return R.ok();
+        }
 
         // 获取车队
         XpFleetVehicle xpFleetVehicle = vehicleService.getOne(new LambdaQueryWrapper<XpFleetVehicle>().eq(XpFleetVehicle::getVehicleId, xpVehicle.getId()));
@@ -828,7 +914,10 @@
      */
     @PostMapping("/logan/inner/vehicle/updateVehicleStatus")
     public R<?> updateVehicleStatus(@RequestBody UpdateVehicleStateDto updateVehicleStateDto) {
-        xpVehicleService.update(new LambdaUpdateWrapper<XpVehicle>().eq(XpVehicle::getVehicleVin, updateVehicleStateDto.getVin()).set(XpVehicle::getState, updateVehicleStateDto.getState()));
+        if (StringUtils.isBlank(updateVehicleStateDto.getVin())) {
+            return R.ok();
+        }
+        xpVehicleService.update(new LambdaUpdateWrapper<XpVehicle>().in(XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(updateVehicleStateDto.getVin())).set(XpVehicle::getState, updateVehicleStateDto.getState()));
         return R.ok();
     }
 
@@ -1058,7 +1147,10 @@
      */
     @PostMapping("/base/vi/vehicle/updateVehicleStatus")
     public R<?> testUpdateVehicleStatus(@RequestBody UpdateVehicleStateDto updateVehicleStateDto) {
-        xpVehicleService.update(new LambdaUpdateWrapper<XpVehicle>().eq(XpVehicle::getVehicleVin, updateVehicleStateDto.getVin()).set(XpVehicle::getState, updateVehicleStateDto.getState()));
+        if (StringUtils.isBlank(updateVehicleStateDto.getVin())) {
+            return R.ok();
+        }
+        xpVehicleService.update(new LambdaUpdateWrapper<XpVehicle>().in(XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(updateVehicleStateDto.getVin())).set(XpVehicle::getState, updateVehicleStateDto.getState()));
         return R.ok();
     }
 
@@ -1172,7 +1264,7 @@
         List<XpVehicleVO> xpVehicleList = vehiclePositions.stream()
                 .sorted(Comparator.comparingDouble(VehiclePositionVo::getDistance))
                 .map(vp -> {
-                    XpVehicle xpVehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getVehicleVin, vp.getVin()));
+                    XpVehicle xpVehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().in(XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(vp.getVin())));
                     if (xpVehicle == null) {
                         return null;
                     }
@@ -1245,4 +1337,14 @@
         XpVehicle vehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getPlateNumber, plateNumber).eq(XpVehicle::getOfficialPartnerId, officialPartnerId));
         return R.ok(vehicle);
     }
+
+    private List<String> buildVinQueryValues(List<String> vinList) {
+        if (vinList == null || vinList.isEmpty()) {
+            return java.util.Collections.emptyList();
+        }
+        return vinList.stream()
+                .flatMap(vin -> SensitiveDataCryptoUtil.queryValues(vin).stream())
+                .distinct()
+                .collect(Collectors.toList());
+    }
 }
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleExportQuery.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleExportQuery.java
index e42799c..d39e18c 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleExportQuery.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleExportQuery.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 
 import java.time.LocalDate;
+import java.util.List;
 
 /**
  * 在库车辆导出查询参数
@@ -22,6 +23,8 @@
     @ApiModelProperty(value = "车辆vin码")
     private String vehicleVin;
 
+    private List<String> vehicleVinQueryValues;
+
     @ApiModelProperty(value = "车牌号")
     private String plateNumber;
 
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehiclePageQuery.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehiclePageQuery.java
index cf50caa..bfa8a6d 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehiclePageQuery.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehiclePageQuery.java
@@ -9,6 +9,7 @@
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * 在库车辆管理分页查询参数
@@ -26,6 +27,8 @@
     @ApiModelProperty(value = "车辆vin码")
     private String vehicleVin;
 
+    private List<String> vehicleVinQueryValues;
+
     @ApiModelProperty(value = "车牌号")
     private String plateNumber;
 
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
index aa9ba81..a9f5ae1 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -6,6 +6,7 @@
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -47,9 +48,11 @@
 import com.xiaopeng.api.vo.vehicleConvoy.*;
 import com.xiaopeng.common.core.constant.CacheConstants;
 import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
 import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.exception.base.BaseException;
 import com.xiaopeng.common.core.utils.GeodesyUtil;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
 import com.xiaopeng.common.core.web.page.PageInfo;
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.evi.oss.service.AliOssService;
@@ -86,6 +89,7 @@
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
@@ -174,7 +178,9 @@
             return new ArrayList<>();
         }
         //查询车型和 车队信息
-        return super.listByIds(ids);
+        List<XpVehicle> list = super.listByIds(ids);
+        decryptVehicles(list);
+        return list;
     }
 
     /**
@@ -236,6 +242,7 @@
         query.setPlateNumber(plateNumber);
 
         List<XpVehicleVO> list = baseMapper.findList(query);
+        decryptVehicleVos(list);
         //获取车的位置 和订单的位置 并计算 距离 和 时间
         if(!list.isEmpty()){
             for (XpVehicle xpVehicle : list) {
@@ -329,6 +336,7 @@
             query.setElectronicIdList(Arrays.asList(query.getElectronicId().split(",")));
         }
         List<XpVehicleVO> list = this.baseMapper.pageList(pageInfo, query);
+        decryptVehicleVos(list);
         if (CollectionUtils.isEmpty(list)) {
             return pageInfo;
         }
@@ -376,7 +384,9 @@
             return Collections.emptyList();
         }
 
-        return lambdaQuery().like(XpVehicle::getPlateNumber, plateNumber).list();
+        List<XpVehicle> list = lambdaQuery().like(XpVehicle::getPlateNumber, plateNumber).list();
+        decryptVehicles(list);
+        return list;
     }
 
     @Override
@@ -384,7 +394,9 @@
         if (fenceId == null) {
             return Collections.emptyList();
         }
-        return lambdaQuery().eq(XpVehicle::getElectronicId, fenceId).eq(XpVehicle::getOperatingStatus, 1).eq(XpVehicle::getState, 0).list();
+        List<XpVehicle> list = lambdaQuery().eq(XpVehicle::getElectronicId, fenceId).eq(XpVehicle::getOperatingStatus, 1).eq(XpVehicle::getState, 0).list();
+        decryptVehicles(list);
+        return list;
     }
 
     @Override
@@ -392,7 +404,9 @@
         if (fenceId == null) {
             return Collections.emptyList();
         }
-        return lambdaQuery().eq(XpVehicle::getElectronicId, fenceId).list();
+        List<XpVehicle> list = lambdaQuery().eq(XpVehicle::getElectronicId, fenceId).list();
+        decryptVehicles(list);
+        return list;
     }
 
     @Override
@@ -681,7 +695,7 @@
                 .ne(excludeId != null, XpVehicle::getId, excludeId)
                 .and(w -> w.eq(XpVehicle::getVehicleCode, vehicleCode)
                         .or()
-                        .eq(XpVehicle::getVehicleVin, vehicleVin)
+                        .in(XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(vehicleVin))
                         .or()
                         .eq(XpVehicle::getPlateNumber, plateNumber))
                 .last("limit 3")
@@ -695,7 +709,7 @@
             throw new ServiceException("车辆编码已存在", I18nKeyConstant.VEHICLE_CODE_EXISTS, new Object[]{vehicleCode});
         }
 
-        boolean vehicleVinExists = duplicates.stream().anyMatch(v -> vehicleVin.equals(v.getVehicleVin()));
+        boolean vehicleVinExists = duplicates.stream().anyMatch(v -> vehicleVin.equals(SensitiveDataCryptoUtil.decryptIfPossible(v.getVehicleVin())));
         if (vehicleVinExists) {
             throw new ServiceException("车辆VIN码已存在", I18nKeyConstant.VEHICLE_VIN_EXISTS, new Object[]{vehicleVin});
         }
@@ -1035,8 +1049,10 @@
 
     @Override
     public PageInfo<XpVehicle> vehiclePageList(VehiclePageQuery query) {
+        query.setVehicleVinQueryValues(SensitiveDataCryptoUtil.queryValues(query.getVehicleVin()));
         PageInfo<XpVehicle> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
         List<XpVehicle> list = this.baseMapper.vehiclePageList(pageInfo, query);
+        decryptVehicles(list);
         //查询运营区域名称
         List<Long> electronicIds = list.stream()
                 .map(XpVehicle::getElectronicId)
@@ -1088,7 +1104,10 @@
 
     @Override
     public List<XpVehicle> vehicleExportList(VehicleExportQuery query) {
-        return this.baseMapper.vehicleExportList(query);
+        query.setVehicleVinQueryValues(SensitiveDataCryptoUtil.queryValues(query.getVehicleVin()));
+        List<XpVehicle> list = this.baseMapper.vehicleExportList(query);
+        decryptVehicles(list);
+        return list;
     }
 
     @Override
@@ -1137,7 +1156,7 @@
         LambdaQueryWrapper<XpVehicle> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(XpVehicle::getVehicleType, 2)
                 .like(StringUtils.isNotBlank(query.getVehicleCode()), XpVehicle::getVehicleCode, query.getVehicleCode())
-                .like(StringUtils.isNotBlank(query.getVehicleVin()), XpVehicle::getVehicleVin, query.getVehicleVin())
+                .in(StringUtils.isNotBlank(query.getVehicleVin()), XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(query.getVehicleVin()))
                 .like(StringUtils.isNotBlank(query.getPlateNumber()), XpVehicle::getPlateNumber, query.getPlateNumber())
                 .eq(Objects.nonNull(query.getOperatingStatus()), XpVehicle::getOperatingStatus, query.getOperatingStatus())
                 .eq(Objects.nonNull(query.getElectronicId()), XpVehicle::getElectronicId, query.getElectronicId());
@@ -1150,6 +1169,7 @@
         wrapper.orderByDesc(XpVehicle::getCreateTime);
         //3.执行分页查询
         PageInfo<XpVehicle> page = this.page(pageInfo, wrapper);
+        decryptVehicles(page.getRecords());
 
         //4.批量查询围栏名称并填充
         Set<Long> electronicIdSet = page.getRecords().stream().map(XpVehicle::getElectronicId).collect(Collectors.toSet());
@@ -1173,7 +1193,7 @@
         LambdaQueryWrapper<XpVehicle> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(XpVehicle::getVehicleType, 2)
                 .like(StringUtils.isNotBlank(query.getVehicleCode()), XpVehicle::getVehicleCode, query.getVehicleCode())
-                .like(StringUtils.isNotBlank(query.getVehicleVin()), XpVehicle::getVehicleVin, query.getVehicleVin())
+                .in(StringUtils.isNotBlank(query.getVehicleVin()), XpVehicle::getVehicleVin, SensitiveDataCryptoUtil.queryValues(query.getVehicleVin()))
                 .like(StringUtils.isNotBlank(query.getPlateNumber()), XpVehicle::getPlateNumber, query.getPlateNumber())
                 .eq(Objects.nonNull(query.getOperatingStatus()), XpVehicle::getOperatingStatus, query.getOperatingStatus())
                 .eq(Objects.nonNull(query.getElectronicId()), XpVehicle::getElectronicId, query.getOperatingStatus())
@@ -1187,6 +1207,7 @@
         wrapper.orderByDesc(XpVehicle::getCreateTime);
         //2.执行查询
         List<XpVehicle> list = this.list(wrapper);
+        decryptVehicles(list);
 
         //3.批量查询围栏名称并填充
         Set<Long> electronicIdSet = list.stream().map(XpVehicle::getElectronicId).collect(Collectors.toSet());
@@ -1284,8 +1305,9 @@
         PageInfo<XpVehicle> page = this.page(pageInfo, new QueryWrapper<XpVehicle>().eq("vehicle_type", 2)
                 .eq("status", 2).eq("operating_status", 1)
                 .eq("is_deleted", 0).like(StringUtils.isNotBlank(dto.getPlateNumber()), "plate_number", dto.getPlateNumber())
-                .like(StringUtils.isNotBlank(dto.getVin()), "vehicle_vin", dto.getVin())
+                .in(StringUtils.isNotBlank(dto.getVin()), "vehicle_vin", SensitiveDataCryptoUtil.queryValues(dto.getVin()))
                 .last(" order by create_time desc"));
+        decryptVehicles(page.getRecords());
         return page.getRecords();
     }
 
@@ -1419,7 +1441,7 @@
             }
             log.info("同步查询车辆空调状态成功,开始等到查询回调结果");
             try {
-                Thread.sleep(2000);
+                Thread.sleep(5000);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
@@ -1489,7 +1511,7 @@
         }
         log.info("同步查询车辆空调状态成功,开始等到查询回调结果");
         try {
-            Thread.sleep(2000);
+            Thread.sleep(5000);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
@@ -1579,7 +1601,7 @@
         if(null == dto.getLatitude() || null == dto.getLongitude()){
             throw new ServiceException("无效数据");
         }
-        XpVehicle vehicle = this.getOne(new QueryWrapper<XpVehicle>().eq("vehicle_vin", dto.getVin()).eq("is_deleted", 0));
+        XpVehicle vehicle = this.getOne(new QueryWrapper<XpVehicle>().in("vehicle_vin", SensitiveDataCryptoUtil.queryValues(dto.getVin())).eq("is_deleted", 0));
         if(null == vehicle){
             throw new ServiceException("无效数据");
         }
@@ -1611,6 +1633,7 @@
         //调用推送服务接口,给乘客推送剩余轨迹和里程时长
         if (null != orderId) {
             PushOrderRouteDTO dto1 = new PushOrderRouteDTO();
+            dto1.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc());
             dto1.setOrderId(orderId);
             dto1.setRouteType(1);
             dto1.setLongitude(longitude);
@@ -1642,4 +1665,88 @@
         }
 
     }
+
+    @Override
+    public XpVehicle getById(Serializable id) {
+        XpVehicle vehicle = super.getById(id);
+        decryptVehicle(vehicle);
+        return vehicle;
+    }
+
+    @Override
+    public boolean save(XpVehicle entity) {
+        encryptVehicle(entity);
+        try {
+            return super.save(entity);
+        } finally {
+            decryptVehicle(entity);
+        }
+    }
+
+    @Override
+    public boolean saveBatch(Collection<XpVehicle> entityList) {
+        if (entityList != null) {
+            entityList.forEach(this::encryptVehicle);
+        }
+        try {
+            return super.saveBatch(entityList);
+        } finally {
+            decryptVehicles(entityList);
+        }
+    }
+
+    @Override
+    public boolean updateById(XpVehicle entity) {
+        encryptVehicle(entity);
+        try {
+            return super.updateById(entity);
+        } finally {
+            decryptVehicle(entity);
+        }
+    }
+
+    @Override
+    public List<XpVehicle> list() {
+        List<XpVehicle> list = super.list();
+        decryptVehicles(list);
+        return list;
+    }
+
+    @Override
+    public List<XpVehicle> list(Wrapper<XpVehicle> queryWrapper) {
+        List<XpVehicle> list = super.list(queryWrapper);
+        decryptVehicles(list);
+        return list;
+    }
+
+    @Override
+    public XpVehicle getOne(Wrapper<XpVehicle> queryWrapper) {
+        XpVehicle vehicle = super.getOne(queryWrapper);
+        decryptVehicle(vehicle);
+        return vehicle;
+    }
+
+    private void encryptVehicle(XpVehicle vehicle) {
+        if (vehicle != null) {
+            vehicle.setVehicleVin(SensitiveDataCryptoUtil.encrypt(vehicle.getVehicleVin()));
+        }
+    }
+
+    private void decryptVehicle(XpVehicle vehicle) {
+        if (vehicle != null) {
+            vehicle.setVehicleVin(SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin()));
+        }
+    }
+
+    private void decryptVehicles(Collection<? extends XpVehicle> vehicles) {
+        if (vehicles != null) {
+            vehicles.forEach(this::decryptVehicle);
+        }
+    }
+
+    private void decryptVehicleVos(Collection<XpVehicleVO> vehicles) {
+        if (vehicles != null) {
+            vehicles.forEach(this::decryptVehicle);
+        }
+    }
 }
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
index f4cb934..d0218f2 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
@@ -154,8 +154,11 @@
         <if test="query.vehicleCode != null and query.vehicleCode != ''">
             AND vehicle_code LIKE CONCAT('%', #{query.vehicleCode}, '%')
         </if>
-        <if test="query.vehicleVin != null and query.vehicleVin != ''">
-            AND vehicle_vin LIKE CONCAT('%', #{query.vehicleVin}, '%')
+        <if test="query.vehicleVinQueryValues != null and query.vehicleVinQueryValues.size() > 0">
+            AND vehicle_vin IN
+            <foreach item="item" collection="query.vehicleVinQueryValues" separator="," open="(" close=")">
+                #{item}
+            </foreach>
         </if>
         <if test="query.plateNumber != null and query.plateNumber != ''">
             AND plate_number LIKE CONCAT('%', #{query.plateNumber}, '%')

--
Gitblit v1.7.1