Commit 97ff58ad by DaiJiezhang

feat: 完善企微新增号码信息

parent ea21e468
package com.xyw.console.asset.controller;
import com.xyw.console.asset.exception.PhoneAssetNotFoundException;
import com.xyw.console.asset.exception.PhoneAssetValidationException;
import com.xyw.console.common.ApiResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/** 文件用途(白话):把手机号码管理的业务异常转换成前端可读的统一 JSON 错误。 */
@RestControllerAdvice(assignableTypes = PhoneAssetController.class)
public class PhoneAssetExceptionHandler {
/** 代码作用(白话):把手机号格式、ICCID 和实名人必填等校验失败转为 400。关联文件:PhoneAssetService.java。关联逻辑(调用链/数据流):Service 校验异常 -> Advice -> ApiResponse -> 弹窗提示。 */
@ExceptionHandler(PhoneAssetValidationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> validation(PhoneAssetValidationException exception) { return ApiResponse.error(400, exception.getMessage()); }
/** 代码作用(白话):把不存在的手机号码管理转为 404。关联文件:PhoneAssetService.java。关联逻辑(调用链/数据流):Service 查无记录 -> Advice -> ApiResponse -> 前端提示。 */
@ExceptionHandler(PhoneAssetNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND)
public ApiResponse<Void> notFound(PhoneAssetNotFoundException exception) { return ApiResponse.error(404, exception.getMessage()); }
}
...@@ -57,6 +57,10 @@ public class WecomAccountController { ...@@ -57,6 +57,10 @@ public class WecomAccountController {
@GetMapping("/lookups/phone-assets") @GetMapping("/lookups/phone-assets")
public ApiResponse<List<PhoneAssetLookupResponse>> phoneAssets(@RequestParam(defaultValue = "") String keyword) { permissions.require(PagePermissionService.WECOM, "READ"); return ApiResponse.success(service.searchPhoneAssets(keyword)); } public ApiResponse<List<PhoneAssetLookupResponse>> phoneAssets(@RequestParam(defaultValue = "") String keyword) { permissions.require(PagePermissionService.WECOM, "READ"); return ApiResponse.success(service.searchPhoneAssets(keyword)); }
/** 代码作用(白话):查询注册手机号在手机号码管理中是否已存在,供企微表单决定是否展开新增手机号区块。关联文件:WecomAccountService.java、WecomAccountView.js。关联逻辑(调用链/数据流):手机号输入 -> GET phone-exists -> 精确查询 -> 布尔结果。 */
@GetMapping("/lookups/phone-exists")
public ApiResponse<Boolean> phoneExists(@RequestParam(defaultValue = "") String phoneNumber) { permissions.require(PagePermissionService.WECOM, "READ"); return ApiResponse.success(service.phoneExists(phoneNumber)); }
/** 代码作用(白话):按名称搜索可关联的有效设备,供表单下拉远程查询。关联文件:DeviceAssetLookupResponse.java、WecomAccountService.java。关联逻辑(调用链/数据流):下拉输入 -> GET lookup -> 设备选项。 */ /** 代码作用(白话):按名称搜索可关联的有效设备,供表单下拉远程查询。关联文件:DeviceAssetLookupResponse.java、WecomAccountService.java。关联逻辑(调用链/数据流):下拉输入 -> GET lookup -> 设备选项。 */
@GetMapping("/lookups/devices") @GetMapping("/lookups/devices")
public ApiResponse<List<DeviceAssetLookupResponse>> devices(@RequestParam(defaultValue = "") String keyword) { permissions.require(PagePermissionService.WECOM, "READ"); return ApiResponse.success(service.searchDevices(keyword)); } public ApiResponse<List<DeviceAssetLookupResponse>> devices(@RequestParam(defaultValue = "") String keyword) { permissions.require(PagePermissionService.WECOM, "READ"); return ApiResponse.success(service.searchDevices(keyword)); }
......
...@@ -2,7 +2,7 @@ package com.xyw.console.asset.dto; ...@@ -2,7 +2,7 @@ package com.xyw.console.asset.dto;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
/** ???????????????????????? Controller ??????????? */ /** 代码作用(白话):限定新增和编辑时浏览器可以提交的企业微信资产字段,并携带注册手机号为新增号码时所需的手机号信息。关联文件:WecomAccountController.java、WecomAccountService.java。关联逻辑(调用链/数据流):弹窗表单 -> DTO -> Service 写入允许修改的实体字段。 */
public record WecomAccountSaveRequest( public record WecomAccountSaveRequest(
@NotBlank String wecomName, @NotBlank String wecomName,
String wecomAlias, String wecomAlias,
...@@ -13,5 +13,8 @@ public record WecomAccountSaveRequest( ...@@ -13,5 +13,8 @@ public record WecomAccountSaveRequest(
String realNameOwnerStatus, String realNameOwnerStatus,
String gender, String gender,
Long deviceId, Long deviceId,
Long operatorPersonId) { Long operatorPersonId,
String cardType,
String iccid,
String phoneRealNameOwner) {
} }
...@@ -69,7 +69,9 @@ public class PhoneAssetService { ...@@ -69,7 +69,9 @@ public class PhoneAssetService {
/** 代码作用(白话):读取一条仍有效的资产,供编辑和删除共用。关联文件:PhoneAssetMapper.java、PhoneAssetExceptionHandler.java。关联逻辑(调用链/数据流):Service 查询 -> 无记录 -> 404 异常。 */ /** 代码作用(白话):读取一条仍有效的资产,供编辑和删除共用。关联文件:PhoneAssetMapper.java、PhoneAssetExceptionHandler.java。关联逻辑(调用链/数据流):Service 查询 -> 无记录 -> 404 异常。 */
private PhoneAssetEntity requireActiveEntity(Long id){ PhoneAssetEntity entity=mapper.selectOne(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime,0L).eq(PhoneAssetEntity::getId,id)); if(entity==null) throw new PhoneAssetNotFoundException("手机号码管理不存在或已删除"); return entity; } private PhoneAssetEntity requireActiveEntity(Long id){ PhoneAssetEntity entity=mapper.selectOne(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime,0L).eq(PhoneAssetEntity::getId,id)); if(entity==null) throw new PhoneAssetNotFoundException("手机号码管理不存在或已删除"); return entity; }
/** 代码作用(白话):把表单允许提交的字段写入实体,并统一处理手机号和默认使用状态。关联文件:PhoneAssetSaveRequest.java、PhoneAssetEntity.java。关联逻辑(调用链/数据流):弹窗表单 -> DTO -> Entity -> Mapper 保存。 */ /** 代码作用(白话):把表单允许提交的字段写入实体,并统一处理手机号和默认使用状态。关联文件:PhoneAssetSaveRequest.java、PhoneAssetEntity.java。关联逻辑(调用链/数据流):弹窗表单 -> DTO -> Entity -> Mapper 保存。 */
private void applyEditableFields(PhoneAssetEntity entity, PhoneAssetSaveRequest request){ entity.setPhoneNumber(normalizePhoneNumber(request.phoneNumber())); entity.setCardType(request.cardType()); entity.setIccid(request.iccid()); entity.setRealNameOwner(request.realNameOwner()); entity.setManagementType(request.managementType()); entity.setDisposalStatus(request.disposalStatus()==null||request.disposalStatus().isBlank()?"正常使用":request.disposalStatus()); entity.setDeviceId(request.deviceId()); } private void applyEditableFields(PhoneAssetEntity entity, PhoneAssetSaveRequest request){ validateRequiredIdentityFields(request); entity.setPhoneNumber(normalizePhoneNumber(request.phoneNumber())); entity.setCardType(request.cardType()); entity.setIccid(request.iccid()); entity.setRealNameOwner(request.realNameOwner()); entity.setManagementType(request.managementType()); entity.setDisposalStatus(request.disposalStatus()==null||request.disposalStatus().isBlank()?"正常使用":request.disposalStatus()); entity.setDeviceId(request.deviceId()); }
/** 代码作用(白话):运营商为虚拟号码时实名人和 ICCID 可不填,其余运营商必须填写。关联文件:PhoneAssetSaveRequest.java、PhoneAssetValidationException.java。关联逻辑(调用链/数据流):DTO -> 校验 -> 失败抛 400 -> 前端保留弹窗并提示。 */
private void validateRequiredIdentityFields(PhoneAssetSaveRequest request){ if("虚拟号码".equals(request.cardType())) return; if(!hasText(request.iccid())) throw new PhoneAssetValidationException("ICCID 不能为空"); if(!hasText(request.realNameOwner())) throw new PhoneAssetValidationException("实名人不能为空"); }
/** 代码作用(白话):按已确认规则清理手机号并验证其最终格式。关联文件:PhoneAssetSaveRequest.java、PhoneAssetExceptionHandler.java。关联逻辑(调用链/数据流):前端输入 -> 去空格和 +86 -> 格式失败返回 400。 */ /** 代码作用(白话):按已确认规则清理手机号并验证其最终格式。关联文件:PhoneAssetSaveRequest.java、PhoneAssetExceptionHandler.java。关联逻辑(调用链/数据流):前端输入 -> 去空格和 +86 -> 格式失败返回 400。 */
private String normalizePhoneNumber(String value){ String normalized=value==null?"":value.trim(); if(normalized.startsWith("+86")) normalized=normalized.substring(3); if(!normalized.matches("\\d{11}")) throw new PhoneAssetValidationException("手机号必须是 11 位数字"); return normalized; } private String normalizePhoneNumber(String value){ String normalized=value==null?"":value.trim(); if(normalized.startsWith("+86")) normalized=normalized.substring(3); if(!normalized.matches("\\d{11}")) throw new PhoneAssetValidationException("手机号必须是 11 位数字"); return normalized; }
/** 代码作用(白话):只挑选列表需要展示的字段,并按传入的设备名映射补上关联设备名称。关联文件:PhoneAssetResponse.java、PhoneAssetEntity.java。关联逻辑(调用链/数据流):实体 + 设备名映射 -> DTO -> ApiResponse -> 表格。 */ /** 代码作用(白话):只挑选列表需要展示的字段,并按传入的设备名映射补上关联设备名称。关联文件:PhoneAssetResponse.java、PhoneAssetEntity.java。关联逻辑(调用链/数据流):实体 + 设备名映射 -> DTO -> ApiResponse -> 表格。 */
......
...@@ -84,7 +84,7 @@ public class WecomAccountService { ...@@ -84,7 +84,7 @@ public class WecomAccountService {
PhoneAssetEntity phone = phoneAssetMapper.selectOne(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime, 0L).eq(PhoneAssetEntity::getPhoneNumber, phoneNumber)); PhoneAssetEntity phone = phoneAssetMapper.selectOne(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime, 0L).eq(PhoneAssetEntity::getPhoneNumber, phoneNumber));
boolean created = phone == null; boolean created = phone == null;
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
if (created) { phone = new PhoneAssetEntity(); phone.setPhoneNumber(phoneNumber); phone.setNumberType("EXTERNAL"); phone.setSourceAssetType("WECOM"); phone.setDisposalStatus("正常使用"); phone.setCreateTime(now); phone.setUpdateTime(now); phone.setDeleteTime(0L); phone.setLinkedWecomAccounts("[]"); phone.setLinkedWechatAccounts("[]"); phone.setLinkedDouyinAccounts("[]"); phone.setLinkedDomainAccounts("[]"); phone.setLinkedMerchants("[]"); if (phoneAssetMapper.insert(phone) != 1) throw new IllegalStateException("手机号码管理新增失败"); } if (created) { phone = new PhoneAssetEntity(); phone.setPhoneNumber(phoneNumber); phone.setNumberType("EXTERNAL"); phone.setSourceAssetType("WECOM"); applyPhoneIdentity(phone, request); phone.setDisposalStatus("正常使用"); phone.setCreateTime(now); phone.setUpdateTime(now); phone.setDeleteTime(0L); phone.setLinkedWecomAccounts("[]"); phone.setLinkedWechatAccounts("[]"); phone.setLinkedDouyinAccounts("[]"); phone.setLinkedDomainAccounts("[]"); phone.setLinkedMerchants("[]"); if (phoneAssetMapper.insert(phone) != 1) throw new IllegalStateException("手机号码管理新增失败"); }
WecomAccountEntity entity = new WecomAccountEntity(); applyEditableFields(entity, request); entity.setPhoneAssetId(phone.getId()); entity.setPhoneLinkMode(created ? "CREATED" : "EXISTING"); entity.setCreateTime(now); entity.setUpdateTime(now); entity.setDeleteTime(0L); if (wecomAccountMapper.insert(entity) != 1) throw new IllegalStateException("企业微信资产新增失败"); if (created) { phone.setSourceAssetId(entity.getId()); phoneAssetMapper.updateById(phone); } return toResponse(entity, Map.of(), Map.of(phone.getId(), phone.getPhoneNumber()), Map.of(), Map.of()); WecomAccountEntity entity = new WecomAccountEntity(); applyEditableFields(entity, request); entity.setPhoneAssetId(phone.getId()); entity.setPhoneLinkMode(created ? "CREATED" : "EXISTING"); entity.setCreateTime(now); entity.setUpdateTime(now); entity.setDeleteTime(0L); if (wecomAccountMapper.insert(entity) != 1) throw new IllegalStateException("企业微信资产新增失败"); if (created) { phone.setSourceAssetId(entity.getId()); phoneAssetMapper.updateById(phone); } return toResponse(entity, Map.of(), Map.of(phone.getId(), phone.getPhoneNumber()), Map.of(), Map.of());
} }
...@@ -104,7 +104,7 @@ public class WecomAccountService { ...@@ -104,7 +104,7 @@ public class WecomAccountService {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
// 号码没变就不动关联,避免把 EXISTING 误改成 CREATED、或把还在用的号码当成旧号清理掉。 // 号码没变就不动关联,避免把 EXISTING 误改成 CREATED、或把还在用的号码当成旧号清理掉。
if (!phoneNumber.equals(currentPhoneNumber(previousPhoneAssetId))) { if (!phoneNumber.equals(currentPhoneNumber(previousPhoneAssetId))) {
PhoneAssetEntity phone = attachPhone(phoneNumber, entity.getId(), now); PhoneAssetEntity phone = attachPhone(phoneNumber, entity.getId(), now, request);
entity.setPhoneAssetId(phone.getId()); entity.setPhoneAssetId(phone.getId());
entity.setPhoneLinkMode(isCreatedFor(phone, entity.getId()) ? "CREATED" : "EXISTING"); entity.setPhoneLinkMode(isCreatedFor(phone, entity.getId()) ? "CREATED" : "EXISTING");
releaseAutoCreatedPhone(previousPhoneAssetId, previousLinkMode, entity.getId(), now); releaseAutoCreatedPhone(previousPhoneAssetId, previousLinkMode, entity.getId(), now);
...@@ -149,11 +149,11 @@ public class WecomAccountService { ...@@ -149,11 +149,11 @@ public class WecomAccountService {
* 关联文件:PhoneAssetEntity.java、PhoneAssetMapper.java。 * 关联文件:PhoneAssetEntity.java、PhoneAssetMapper.java。
* 关联逻辑(调用链/数据流):号码 -> 查已有 -> 命中则复用,未命中则新建 EXTERNAL/WECOM 记录。 * 关联逻辑(调用链/数据流):号码 -> 查已有 -> 命中则复用,未命中则新建 EXTERNAL/WECOM 记录。
*/ */
private PhoneAssetEntity attachPhone(String phoneNumber, Long wecomAccountId, LocalDateTime now) { private PhoneAssetEntity attachPhone(String phoneNumber, Long wecomAccountId, LocalDateTime now, WecomAccountSaveRequest request) {
PhoneAssetEntity phone = phoneAssetMapper.selectOne(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime, 0L).eq(PhoneAssetEntity::getPhoneNumber, phoneNumber)); PhoneAssetEntity phone = phoneAssetMapper.selectOne(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime, 0L).eq(PhoneAssetEntity::getPhoneNumber, phoneNumber));
if (phone != null) return phone; if (phone != null) return phone;
phone = new PhoneAssetEntity(); phone = new PhoneAssetEntity();
phone.setPhoneNumber(phoneNumber); phone.setNumberType("EXTERNAL"); phone.setSourceAssetType("WECOM"); phone.setSourceAssetId(wecomAccountId); phone.setDisposalStatus("正常使用"); phone.setPhoneNumber(phoneNumber); phone.setNumberType("EXTERNAL"); phone.setSourceAssetType("WECOM"); phone.setSourceAssetId(wecomAccountId); applyPhoneIdentity(phone, request); phone.setDisposalStatus("正常使用");
phone.setCreateTime(now); phone.setUpdateTime(now); phone.setDeleteTime(0L); phone.setCreateTime(now); phone.setUpdateTime(now); phone.setDeleteTime(0L);
phone.setLinkedWecomAccounts("[]"); phone.setLinkedWechatAccounts("[]"); phone.setLinkedDouyinAccounts("[]"); phone.setLinkedDomainAccounts("[]"); phone.setLinkedMerchants("[]"); phone.setLinkedWecomAccounts("[]"); phone.setLinkedWechatAccounts("[]"); phone.setLinkedDouyinAccounts("[]"); phone.setLinkedDomainAccounts("[]"); phone.setLinkedMerchants("[]");
if (phoneAssetMapper.insert(phone) != 1) throw new IllegalStateException("手机号码管理新增失败"); if (phoneAssetMapper.insert(phone) != 1) throw new IllegalStateException("手机号码管理新增失败");
...@@ -201,6 +201,21 @@ public class WecomAccountService { ...@@ -201,6 +201,21 @@ public class WecomAccountService {
entity.setGender(request.gender()); entity.setDeviceId(request.deviceId()); entity.setOperatorPersonId(request.operatorPersonId()); entity.setGender(request.gender()); entity.setDeviceId(request.deviceId()); entity.setOperatorPersonId(request.operatorPersonId());
} }
/** 代码作用(白话):企微为新增注册手机号自动建号时,把运营商、ICCID 和手机号实名人写入号码资产,并套用与手机号码管理一致的必填规则(运营商为虚拟号码时 ICCID 和手机号实名人可不填)。关联文件:PhoneAssetEntity.java、PhoneAssetValidationException.java。关联逻辑(调用链/数据流):企微建号分支 -> 字段写入 -> 校验失败抛 400 -> 前端提示。 */
private void applyPhoneIdentity(PhoneAssetEntity phone, WecomAccountSaveRequest request) {
phone.setCardType(request.cardType());
phone.setIccid(request.iccid());
phone.setRealNameOwner(request.phoneRealNameOwner());
if ("虚拟号码".equals(request.cardType())) return;
if (!hasText(request.iccid())) throw new PhoneAssetValidationException("ICCID 不能为空");
if (!hasText(request.phoneRealNameOwner())) throw new PhoneAssetValidationException("手机号实名人不能为空");
}
/** 代码作用(白话):判断指定号码在手机号码管理中是否存在(未删除),供企微表单决定是否展开新增手机号区块。关联文件:WecomAccountController.java、PhoneAssetMapper.java。关联逻辑(调用链/数据流):手机号输入 -> GET phone-exists -> 精确查询 -> 布尔结果。 */
public boolean phoneExists(String phoneNumber) {
return phoneAssetMapper.selectCount(new LambdaQueryWrapper<PhoneAssetEntity>().eq(PhoneAssetEntity::getDeleteTime, 0L).eq(PhoneAssetEntity::getPhoneNumber, phoneNumber)) > 0;
}
/** 代码作用(白话):确认选中的关联设备仍然有效,阻止伪造或已删除的设备 ID 写入。关联文件:AssetDeviceMapper.java、WecomAccountSaveRequest.java。关联逻辑(调用链/数据流):表单 deviceId -> 有效性查询 -> 参数错误或继续保存。 */ /** 代码作用(白话):确认选中的关联设备仍然有效,阻止伪造或已删除的设备 ID 写入。关联文件:AssetDeviceMapper.java、WecomAccountSaveRequest.java。关联逻辑(调用链/数据流):表单 deviceId -> 有效性查询 -> 参数错误或继续保存。 */
private void requireActiveDevice(Long deviceId) { private void requireActiveDevice(Long deviceId) {
if (deviceId == null) return; if (deviceId == null) return;
......
...@@ -222,6 +222,15 @@ export default { ...@@ -222,6 +222,15 @@ export default {
* 关联逻辑(调用链/数据流):确认保存 -> POST/PUT -> 成功提示 -> dialogVisible=false -> loadPage。 * 关联逻辑(调用链/数据流):确认保存 -> POST/PUT -> 成功提示 -> dialogVisible=false -> loadPage。
*/ */
async function submitForm() { async function submitForm() {
// 运营商为虚拟号码时实名人/ICCID 可不填,其余运营商必须填写
if (form.cardType !== '虚拟号码' && (!form.iccid || !form.iccid.trim())) {
ElMessage.warning('请填写 ICCID');
return;
}
if (form.cardType !== '虚拟号码' && (!form.realNameOwner || !form.realNameOwner.trim())) {
ElMessage.warning('请填写实名人');
return;
}
saving.value = true; saving.value = true;
try { try {
const payload = { ...form, phoneNumber: normalizePhoneNumber(form.phoneNumber) }; const payload = { ...form, phoneNumber: normalizePhoneNumber(form.phoneNumber) };
...@@ -331,11 +340,11 @@ export default { ...@@ -331,11 +340,11 @@ export default {
<template #suffix><span class="phone-asset-modal__character-count" aria-live="polite">{{ form.phoneNumber.length }}/11</span></template> <template #suffix><span class="phone-asset-modal__character-count" aria-live="polite">{{ form.phoneNumber.length }}/11</span></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item class="phone-asset-modal__form-row" label="实名人"><el-input v-model="form.realNameOwner" maxlength="20" placeholder="请输入实名人" /></el-form-item> <el-form-item class="phone-asset-modal__form-row" label="实名人" :required="form.cardType !== '虚拟号码'"><el-input v-model="form.realNameOwner" maxlength="20" placeholder="请输入实名人" /></el-form-item>
<el-form-item class="phone-asset-modal__form-row" label="运营商"> <el-form-item class="phone-asset-modal__form-row" label="运营商">
<el-select v-model="form.cardType" clearable placeholder="请选择" popper-class="phone-asset-modal__select-popper"><el-option label="移动" value="移动" /><el-option label="电信" value="电信" /><el-option label="联通" value="联通" /><el-option label="电销卡「联通」" value="电销卡「联通」" /><el-option label="广电" value="广电" /><el-option label="虚拟号码" value="虚拟号码" /></el-select> <el-select v-model="form.cardType" clearable placeholder="请选择" popper-class="phone-asset-modal__select-popper"><el-option label="移动" value="移动" /><el-option label="电信" value="电信" /><el-option label="联通" value="联通" /><el-option label="电销卡「联通」" value="电销卡「联通」" /><el-option label="广电" value="广电" /><el-option label="虚拟号码" value="虚拟号码" /></el-select>
</el-form-item> </el-form-item>
<el-form-item class="phone-asset-modal__form-row" label="ICCID"> <el-form-item class="phone-asset-modal__form-row" label="ICCID" :required="form.cardType !== '虚拟号码'">
<el-input v-model="form.iccid" class="phone-asset-modal__count-input" maxlength="20" autocomplete="off" placeholder="请输入 ICCID" @input="limitIccid" @paste="handleIccidPaste"> <el-input v-model="form.iccid" class="phone-asset-modal__count-input" maxlength="20" autocomplete="off" placeholder="请输入 ICCID" @input="limitIccid" @paste="handleIccidPaste">
<template #suffix><span class="phone-asset-modal__character-count" aria-live="polite">{{ form.iccid.length }}/20</span></template> <template #suffix><span class="phone-asset-modal__character-count" aria-live="polite">{{ form.iccid.length }}/20</span></template>
</el-input> </el-input>
......
...@@ -32,6 +32,9 @@ export function searchCompanyProfiles(keyword) { return request(`/api/wecom-acco ...@@ -32,6 +32,9 @@ export function searchCompanyProfiles(keyword) { return request(`/api/wecom-acco
/** Code purpose (plain language): searches existing phone assets for the registration-phone input. Related files: WecomAccountView.js, WecomAccountController.java. Data flow: autocomplete -> GET lookup -> selectable numbers. */ /** Code purpose (plain language): searches existing phone assets for the registration-phone input. Related files: WecomAccountView.js, WecomAccountController.java. Data flow: autocomplete -> GET lookup -> selectable numbers. */
export function searchPhoneAssets(keyword) { return request(`/api/wecom-accounts/lookups/phone-assets?keyword=${encodeURIComponent(keyword || '')}`); } export function searchPhoneAssets(keyword) { return request(`/api/wecom-accounts/lookups/phone-assets?keyword=${encodeURIComponent(keyword || '')}`); }
/** 代码作用(白话):查询注册手机号在手机号码管理中是否已存在。关联文件:WecomAccountView.js、WecomAccountController.java。关联逻辑(调用链/数据流):手机号输入 -> GET phone-exists -> 布尔结果 -> 决定是否展开新增手机号区块。 */
export function checkPhoneExists(phoneNumber) { return request(`/api/wecom-accounts/lookups/phone-exists?phoneNumber=${encodeURIComponent(phoneNumber || '')}`); }
/** Code purpose (plain language): searches optional WeCom owners. Related files: WecomAccountView.js, WecomAccountController.java. Data flow: remote select -> GET lookup -> options. */ /** Code purpose (plain language): searches optional WeCom owners. Related files: WecomAccountView.js, WecomAccountController.java. Data flow: remote select -> GET lookup -> options. */
export function searchCompanyPersons(keyword) { return request(`/api/wecom-accounts/lookups/company-persons?keyword=${encodeURIComponent(keyword || '')}`); } export function searchCompanyPersons(keyword) { return request(`/api/wecom-accounts/lookups/company-persons?keyword=${encodeURIComponent(keyword || '')}`); }
......
...@@ -51,8 +51,10 @@ body { margin: 0; } ...@@ -51,8 +51,10 @@ body { margin: 0; }
} }
.phone-asset-modal { .phone-asset-modal {
width: min(560px, 100%) !important; width: min(560px, 100%) !important;
max-height: calc(100vh - 48px); height: min(680px, calc(100vh - 48px));
margin: 0 !important; margin: 0 !important;
display: flex;
flex-direction: column;
overflow: hidden; overflow: hidden;
border: 1px solid rgba(228, 228, 231, 0.9); border: 1px solid rgba(228, 228, 231, 0.9);
border-radius: 12px; border-radius: 12px;
...@@ -96,15 +98,44 @@ body { margin: 0; } ...@@ -96,15 +98,44 @@ body { margin: 0; }
height: 15px; height: 15px;
} }
.phone-asset-modal .el-dialog__body { .phone-asset-modal .el-dialog__body {
max-height: calc(100vh - 206px); flex: 1 1 auto;
min-height: 0; min-height: 0;
padding: 4px 24px 8px; padding: 4px 24px 8px;
overflow-y: auto; overflow-y: auto;
} }
/* 弹窗正文的滚动条缩窄并去掉轨道色,使其融入表单背景。 */
@media (min-width: 601px) {
.phone-asset-modal .el-dialog__body {
scrollbar-width: thin;
scrollbar-color: #d4d4d8 transparent;
}
.phone-asset-modal .el-dialog__body::-webkit-scrollbar {
width: 6px;
}
.phone-asset-modal .el-dialog__body::-webkit-scrollbar-track {
background: transparent;
}
.phone-asset-modal .el-dialog__body::-webkit-scrollbar-thumb {
border-radius: 999px;
background: #d4d4d8;
}
.phone-asset-modal .el-dialog__body::-webkit-scrollbar-thumb:hover {
background: #a1a1aa;
}
}
.phone-asset-modal__form { .phone-asset-modal__form {
display: grid; display: grid;
gap: 14px; gap: 14px;
} }
/* 企微新增注册手机号为系统不存在的号码时,"新增手机号"区块的分隔标题 */
.phone-asset-modal__form-divider {
margin: 4px 0 0;
padding-top: 12px;
border-top: 1px dashed #e4e4e7;
color: #52525b;
font-size: 13px;
font-weight: 600;
}
.phone-asset-modal__form-row.el-form-item { .phone-asset-modal__form-row.el-form-item {
display: grid; display: grid;
grid-template-columns: 96px minmax(0, 1fr); grid-template-columns: 96px minmax(0, 1fr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment