Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xyw_asset_console
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DaiJiezhang
xyw_asset_console
Commits
da65cb92
Commit
da65cb92
authored
Jul 03, 2026
by
DaiJiezhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refine fetch handling and phone workflow
parent
f2fe141d
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
120 additions
and
85 deletions
+120
-85
WxPhoneSaveRequest.java
...in/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java
+1
-2
WxPhoneEntity.java
...main/java/com/xyw/console/phone/entity/WxPhoneEntity.java
+2
-2
WxPhoneService.java
...in/java/com/xyw/console/phone/service/WxPhoneService.java
+11
-41
phone-add-dialog.js
src/modules/phone/phone-add-dialog.js
+6
-8
phone-list-runtime.js
src/modules/phone/phone-list-runtime.js
+44
-13
phone-api-client.js
src/modules/shared/phone-api-client.js
+28
-8
record-adapters.js
src/modules/shared/record-adapters.js
+1
-3
wechat-api-client.js
src/modules/shared/wechat-api-client.js
+27
-8
No files found.
backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java
View file @
da65cb92
...
@@ -40,6 +40,5 @@ public class WxPhoneSaveRequest {
...
@@ -40,6 +40,5 @@ public class WxPhoneSaveRequest {
private
Boolean
numberStatus
;
private
Boolean
numberStatus
;
private
String
linkedWecom
;
private
String
linkedWecom
;
private
Boolean
numberRetentionStatus
;
}
}
backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java
View file @
da65cb92
...
@@ -64,8 +64,7 @@ public class WxPhoneEntity {
...
@@ -64,8 +64,7 @@ public class WxPhoneEntity {
@TableField
(
"linked_wecom"
)
@TableField
(
"linked_wecom"
)
private
String
linkedWecom
;
private
String
linkedWecom
;
@TableField
(
"number_retention_status"
)
private
Boolean
numberRetentionStatus
;
@TableField
(
exist
=
false
)
@TableField
(
exist
=
false
)
private
String
wechatStatus
;
private
String
wechatStatus
;
...
@@ -73,3 +72,4 @@ public class WxPhoneEntity {
...
@@ -73,3 +72,4 @@ public class WxPhoneEntity {
@TableField
(
exist
=
false
)
@TableField
(
exist
=
false
)
private
String
outbound
;
private
String
outbound
;
}
}
backend/src/main/java/com/xyw/console/phone/service/WxPhoneService.java
View file @
da65cb92
...
@@ -15,10 +15,7 @@ public class WxPhoneService {
...
@@ -15,10 +15,7 @@ public class WxPhoneService {
private
final
WxPhoneMapper
wxPhoneMapper
;
private
final
WxPhoneMapper
wxPhoneMapper
;
/**
/**
* 代码作用(白话):把手机号列表按 id 倒序读出来,给前端列表页直接渲染。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭妸鎵嬫満鍙峰垪琛ㄦ寜 id 鍊掑簭璇诲嚭鏉ワ紝缁欏墠绔垪琛ㄩ〉鐩存帴娓叉煋銆? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java銆丗:/Project/xyw_console/src/modules/shared/phone-api-client.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛欸ET /api/wx-phones -> listRecords() -> Mapper.selectList() -> 鍓嶇 normalizePhoneRecord() -> 鍒楄〃灞曠ず銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java、F:/Project/xyw_console/src/modules/shared/phone-api-client.js。
* 关联逻辑(调用链/消息链/数据流):GET /api/wx-phones -> listRecords() -> Mapper.selectList() -> 前端 normalizePhoneRecord() -> 列表展示。
*/
public
List
<
WxPhoneEntity
>
listRecords
()
{
public
List
<
WxPhoneEntity
>
listRecords
()
{
return
wxPhoneMapper
.
selectList
(
new
QueryWrapper
<
WxPhoneEntity
>().
orderByDesc
(
"id"
))
return
wxPhoneMapper
.
selectList
(
new
QueryWrapper
<
WxPhoneEntity
>().
orderByDesc
(
"id"
))
.
stream
()
.
stream
()
...
@@ -27,19 +24,13 @@ public class WxPhoneService {
...
@@ -27,19 +24,13 @@ public class WxPhoneService {
}
}
/**
/**
* 代码作用(白话):按主键读一条手机号卡,给详情抽屉和编辑弹窗用。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭寜涓婚敭璇讳竴鏉℃墜鏈哄彿鍗★紝缁欒鎯呮娊灞夊拰缂栬緫寮圭獥鐢ㄣ€? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java銆丗:/Project/xyw_console/src/modules/phone/phone-detail-drawer.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛欸ET /api/wx-phones/{id} -> getRecordById() -> Mapper.selectById() -> 璇︽儏/缂栬緫鎵撳紑銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java、F:/Project/xyw_console/src/modules/phone/phone-detail-drawer.js。
* 关联逻辑(调用链/消息链/数据流):GET /api/wx-phones/{id} -> getRecordById() -> Mapper.selectById() -> 详情/编辑打开。
*/
public
WxPhoneEntity
getRecordById
(
Long
id
)
{
public
WxPhoneEntity
getRecordById
(
Long
id
)
{
return
normalizeEntity
(
wxPhoneMapper
.
selectById
(
id
));
return
normalizeEntity
(
wxPhoneMapper
.
selectById
(
id
));
}
}
/**
/**
* 代码作用(白话):把前端新增表单写入 wx_phone 表,并返回带主键的新记录。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭妸鍓嶇鏂板琛ㄥ崟鍐欏叆 wx_phone 琛紝骞惰繑鍥炲甫涓婚敭鐨勬柊璁板綍銆? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java銆丗:/Project/xyw_console/src/modules/phone/phone-add-dialog.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歅OST /api/wx-phones -> createRecord() -> copyRequestToEntity() -> Mapper.insert() -> 鍓嶇鍒锋柊鍒楄〃銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java、F:/Project/xyw_console/src/modules/phone/phone-add-dialog.js。
* 关联逻辑(调用链/消息链/数据流):POST /api/wx-phones -> createRecord() -> copyRequestToEntity() -> Mapper.insert() -> 前端刷新列表。
*/
public
WxPhoneEntity
createRecord
(
WxPhoneSaveRequest
request
)
{
public
WxPhoneEntity
createRecord
(
WxPhoneSaveRequest
request
)
{
WxPhoneEntity
entity
=
new
WxPhoneEntity
();
WxPhoneEntity
entity
=
new
WxPhoneEntity
();
copyRequestToEntity
(
request
,
entity
);
copyRequestToEntity
(
request
,
entity
);
...
@@ -48,10 +39,7 @@ public class WxPhoneService {
...
@@ -48,10 +39,7 @@ public class WxPhoneService {
}
}
/**
/**
* 代码作用(白话):更新指定手机号卡,并把数据库里的最新记录返回给前端。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭洿鏂版寚瀹氭墜鏈哄彿鍗★紝骞舵妸鏁版嵁搴撻噷鐨勬渶鏂拌褰曡繑鍥炵粰鍓嶇銆? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java銆丗:/Project/xyw_console/src/modules/phone/phone-add-dialog.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歅UT /api/wx-phones/{id} -> updateRecord() -> Mapper.updateById() -> 鍓嶇鍒锋柊鍒楄〃銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java、F:/Project/xyw_console/src/modules/phone/phone-add-dialog.js。
* 关联逻辑(调用链/消息链/数据流):PUT /api/wx-phones/{id} -> updateRecord() -> Mapper.updateById() -> 前端刷新列表。
*/
public
WxPhoneEntity
updateRecord
(
Long
id
,
WxPhoneSaveRequest
request
)
{
public
WxPhoneEntity
updateRecord
(
Long
id
,
WxPhoneSaveRequest
request
)
{
WxPhoneEntity
entity
=
wxPhoneMapper
.
selectById
(
id
);
WxPhoneEntity
entity
=
wxPhoneMapper
.
selectById
(
id
);
if
(
entity
==
null
)
{
if
(
entity
==
null
)
{
...
@@ -63,19 +51,13 @@ public class WxPhoneService {
...
@@ -63,19 +51,13 @@ public class WxPhoneService {
}
}
/**
/**
* 代码作用(白话):删除指定手机号卡,给控制器判断是否需要返回 404。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氬垹闄ゆ寚瀹氭墜鏈哄彿鍗★紝缁欐帶鍒跺櫒鍒ゆ柇鏄惁闇€瑕佽繑鍥?404銆? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java銆丗:/Project/xyw_console/src/modules/phone/phone-list-runtime.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛欴ELETE /api/wx-phones/{id} -> deleteRecord() -> Mapper.deleteById() -> 鍒楄〃閲嶆柊鍔犺浇銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/controller/WxPhoneController.java、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js。
* 关联逻辑(调用链/消息链/数据流):DELETE /api/wx-phones/{id} -> deleteRecord() -> Mapper.deleteById() -> 列表重新加载。
*/
public
boolean
deleteRecord
(
Long
id
)
{
public
boolean
deleteRecord
(
Long
id
)
{
return
wxPhoneMapper
.
deleteById
(
id
)
>
0
;
return
wxPhoneMapper
.
deleteById
(
id
)
>
0
;
}
}
/**
/**
* 代码作用(白话):把接口入参安全地拷贝到数据库实体里,顺手做空白清洗和默认值处理。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭妸鎺ュ彛鍏ュ弬瀹夊叏鍦版嫹璐濆埌鏁版嵁搴撳疄浣撻噷锛岄『鎵嬪仛绌虹櫧娓呮礂鍜岄粯璁ゅ€煎鐞嗐€? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java銆丗:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歝reateRecord()/updateRecord() -> copyRequestToEntity() -> Entity -> Mapper 鎸佷箙鍖栥€? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java、F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java。
* 关联逻辑(调用链/消息链/数据流):createRecord()/updateRecord() -> copyRequestToEntity() -> Entity -> Mapper 持久化。
*/
public
void
copyRequestToEntity
(
WxPhoneSaveRequest
request
,
WxPhoneEntity
entity
)
{
public
void
copyRequestToEntity
(
WxPhoneSaveRequest
request
,
WxPhoneEntity
entity
)
{
entity
.
setPhoneNumber
(
normalizeText
(
request
.
getPhoneNumber
()));
entity
.
setPhoneNumber
(
normalizeText
(
request
.
getPhoneNumber
()));
entity
.
setRealPerson
(
normalizeText
(
request
.
getRealPerson
()));
entity
.
setRealPerson
(
normalizeText
(
request
.
getRealPerson
()));
...
@@ -94,16 +76,12 @@ public class WxPhoneService {
...
@@ -94,16 +76,12 @@ public class WxPhoneService {
entity
.
setChannelOperator
(
normalizeText
(
request
.
getChannelOperator
()));
entity
.
setChannelOperator
(
normalizeText
(
request
.
getChannelOperator
()));
entity
.
setNumberStatus
(
normalizeBoolean
(
request
.
getNumberStatus
(),
Boolean
.
TRUE
));
entity
.
setNumberStatus
(
normalizeBoolean
(
request
.
getNumberStatus
(),
Boolean
.
TRUE
));
entity
.
setLinkedWecom
(
normalizeText
(
request
.
getLinkedWecom
()));
entity
.
setLinkedWecom
(
normalizeText
(
request
.
getLinkedWecom
()));
entity
.
setNumberRetentionStatus
(
normalizeBoolean
(
request
.
getNumberRetentionStatus
(),
Boolean
.
TRUE
));
entity
.
setWechatStatus
(
Boolean
.
TRUE
.
equals
(
entity
.
getWechat
())
?
"正常"
:
"异常"
);
entity
.
setWechatStatus
(
Boolean
.
TRUE
.
equals
(
entity
.
getWechat
())
?
"正常"
:
"异常"
);
entity
.
setOutbound
(
Boolean
.
TRUE
.
equals
(
entity
.
getOutboundCall
())
?
"可外呼"
:
"不可外呼"
);
entity
.
setOutbound
(
Boolean
.
TRUE
.
equals
(
entity
.
getOutboundCall
())
?
"可外呼"
:
"不可外呼"
);
}
}
/**
/**
* 代码作用(白话):把数据库里取回来的手机号卡统一整理成前端能直接吃的状态文本和空值格式。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭妸鏁版嵁搴撻噷鍙栧洖鏉ョ殑鎵嬫満鍙峰崱缁熶竴鏁寸悊鎴愬墠绔兘鐩存帴鍚冪殑鐘舵€佹枃鏈拰绌哄€兼牸寮忋€? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/src/modules/shared/record-adapters.js銆丗:/Project/xyw_console/src/modules/phone/phone-list-runtime.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歁apper.selectList()/selectById() -> normalizeEntity() -> controller response -> 鍓嶇 normalizePhoneRecord()銆? */
* 关联文件:F:/Project/xyw_console/src/modules/shared/record-adapters.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js。
* 关联逻辑(调用链/消息链/数据流):Mapper.selectList()/selectById() -> normalizeEntity() -> controller response -> 前端 normalizePhoneRecord()。
*/
public
WxPhoneEntity
normalizeEntity
(
WxPhoneEntity
entity
)
{
public
WxPhoneEntity
normalizeEntity
(
WxPhoneEntity
entity
)
{
if
(
entity
==
null
)
{
if
(
entity
==
null
)
{
return
null
;
return
null
;
...
@@ -125,10 +103,7 @@ public class WxPhoneService {
...
@@ -125,10 +103,7 @@ public class WxPhoneService {
}
}
/**
/**
* 代码作用(白话):把前端可能传来的 0/1、正常/异常等卡状态,统一成页面能稳定显示的文本。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭妸鍓嶇鍙兘浼犳潵鐨?0/1銆佹甯?寮傚父绛夊崱鐘舵€侊紝缁熶竴鎴愰〉闈㈣兘绋冲畾鏄剧ず鐨勬枃鏈€? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/src/modules/phone/phone-add-dialog.js銆丗:/Project/xyw_console/src/modules/phone/phone-list-runtime.js銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歳equest.cardStatus/DB.card_status -> normalizeCardStatus() -> response.cardStatus -> 鍒楄〃鍜岃鎯呮樉绀恒€? */
* 关联文件:F:/Project/xyw_console/src/modules/phone/phone-add-dialog.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js。
* 关联逻辑(调用链/消息链/数据流):request.cardStatus/DB.card_status -> normalizeCardStatus() -> response.cardStatus -> 列表和详情显示。
*/
public
String
normalizeCardStatus
(
String
value
)
{
public
String
normalizeCardStatus
(
String
value
)
{
String
normalized
=
normalizeText
(
value
);
String
normalized
=
normalizeText
(
value
);
if
(
normalized
==
null
)
{
if
(
normalized
==
null
)
{
...
@@ -142,10 +117,7 @@ public class WxPhoneService {
...
@@ -142,10 +117,7 @@ public class WxPhoneService {
}
}
/**
/**
* 代码作用(白话):把字符串里的首尾空格去掉,空白内容直接当成没填。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氭妸瀛楃涓查噷鐨勯灏剧┖鏍煎幓鎺夛紝绌虹櫧鍐呭鐩存帴褰撴垚娌″~銆? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java銆丗:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歳equest/entity 瀛楁 -> normalizeText() -> 鍏ュ簱/鍑哄簱鍓嶇殑缁熶竴娓呮礂銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java、F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java。
* 关联逻辑(调用链/消息链/数据流):request/entity 字段 -> normalizeText() -> 入库/出库前的统一清洗。
*/
public
String
normalizeText
(
String
value
)
{
public
String
normalizeText
(
String
value
)
{
if
(
value
==
null
)
{
if
(
value
==
null
)
{
return
null
;
return
null
;
...
@@ -155,11 +127,9 @@ public class WxPhoneService {
...
@@ -155,11 +127,9 @@ public class WxPhoneService {
}
}
/**
/**
* 代码作用(白话):给可空布尔字段补默认值,避免数据库和页面出现一堆 null。
* 浠g爜浣滅敤锛堢櫧璇濓級锛氱粰鍙┖甯冨皵瀛楁琛ラ粯璁ゅ€硷紝閬垮厤鏁版嵁搴撳拰椤甸潰鍑虹幇涓€鍫?null銆? * 鍏宠仈鏂囦欢锛欶:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java銆丗:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java銆? * 鍏宠仈閫昏緫锛堣皟鐢ㄩ摼/娑堟伅閾?鏁版嵁娴侊級锛歳equest.Boolean -> normalizeBoolean() -> Entity.Boolean -> MyBatis-Plus 淇濆瓨銆? */
* 关联文件:F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/dto/WxPhoneSaveRequest.java、F:/Project/xyw_console/backend/src/main/java/com/xyw/console/phone/entity/WxPhoneEntity.java。
* 关联逻辑(调用链/消息链/数据流):request.Boolean -> normalizeBoolean() -> Entity.Boolean -> MyBatis-Plus 保存。
*/
public
Boolean
normalizeBoolean
(
Boolean
value
,
Boolean
defaultValue
)
{
public
Boolean
normalizeBoolean
(
Boolean
value
,
Boolean
defaultValue
)
{
return
value
==
null
?
defaultValue
:
value
;
return
value
==
null
?
defaultValue
:
value
;
}
}
}
}
src/modules/phone/phone-add-dialog.js
View file @
da65cb92
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
channelOperator
:
''
,
channelOperator
:
''
,
numberStatus
:
true
,
numberStatus
:
true
,
linkedWecom
:
''
,
linkedWecom
:
''
,
numberRetentionStatus
:
true
,
imageAttachment1
:
''
,
imageAttachment1
:
''
,
imageAttachment2
:
''
imageAttachment2
:
''
};
};
...
@@ -124,7 +124,7 @@
...
@@ -124,7 +124,7 @@
formData
.
channelOperator
=
record
.
channelOperator
||
record
.
carrier
||
''
;
formData
.
channelOperator
=
record
.
channelOperator
||
record
.
carrier
||
''
;
formData
.
numberStatus
=
record
.
numberStatus
!==
false
;
formData
.
numberStatus
=
record
.
numberStatus
!==
false
;
formData
.
linkedWecom
=
record
.
linkedWecom
||
''
;
formData
.
linkedWecom
=
record
.
linkedWecom
||
''
;
formData
.
numberRetentionStatus
=
record
.
numberRetentionStatus
!==
false
;
imageItems
.
value
=
buildImageItemsFromRecord
(
record
);
imageItems
.
value
=
buildImageItemsFromRecord
(
record
);
syncImagesToFormData
();
syncImagesToFormData
();
}
}
...
@@ -347,12 +347,7 @@
...
@@ -347,12 +347,7 @@
</el-col>
</el-col>
</el-row>
</el-row>
<el-row :gutter="24">
<el-row :gutter="24">
<el-col :span="12">
<el-col :span="24">
<el-form-item label="是否保留号码" prop="numberRetentionStatus">
<el-switch v-model="formData.numberRetentionStatus" active-text="保留" inactive-text="注销"></el-switch>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="可变更 5 元套餐" prop="packageChange5yuan">
<el-form-item label="可变更 5 元套餐" prop="packageChange5yuan">
<el-switch v-model="formData.packageChange5yuan"></el-switch>
<el-switch v-model="formData.packageChange5yuan"></el-switch>
</el-form-item>
</el-form-item>
...
@@ -412,3 +407,6 @@
...
@@ -412,3 +407,6 @@
app
.
use
(
ElementPlus
);
app
.
use
(
ElementPlus
);
app
.
mount
(
'#phoneDialogRoot'
);
app
.
mount
(
'#phoneDialogRoot'
);
})();
})();
src/modules/phone/phone-list-runtime.js
View file @
da65cb92
...
@@ -34,6 +34,17 @@
...
@@ -34,6 +34,17 @@
return
recordTime
>=
startTime
&&
recordTime
<=
endTime
+
24
*
60
*
60
*
1000
-
1
;
return
recordTime
>=
startTime
&&
recordTime
<=
endTime
+
24
*
60
*
60
*
1000
-
1
;
}
}
/**
* 代码作用(白话):把列表里的长文本压成 20 个字符内的单行展示,鼠标悬浮时还能看到完整内容;关联文件:F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js;关联逻辑(调用链/消息链/数据流):表格单元格原始值 -> formatCellText() -> 列表展示/tooltip 提示。
*/
function
formatCellText
(
value
)
{
const
text
=
String
(
value
??
'-'
);
if
(
text
.
length
<=
20
)
{
return
text
;
}
return
`
${
text
.
slice
(
0
,
20
)}
...`
;
}
const
PhoneListTable
=
{
const
PhoneListTable
=
{
name
:
'PhoneListTable'
,
name
:
'PhoneListTable'
,
props
:
{
props
:
{
...
@@ -454,9 +465,21 @@
...
@@ -454,9 +465,21 @@
<a href="#" class="domain-link" @click.prevent="focusRow(scope.row.id)">{{ scope.row.phone || '-' }}</a>
<a href="#" class="domain-link" @click.prevent="focusRow(scope.row.id)">{{ scope.row.phone || '-' }}</a>
</template>
</template>
</el-table-column>
</el-table-column>
<el-table-column property="realPerson" label="真实联系人" min-width="130" />
<el-table-column label="真实联系人" min-width="150">
<el-table-column property="iccid" label="ICCID" min-width="190" />
<template #default="scope">
<el-table-column property="city" label="所在城市" min-width="120" />
<span :title="scope.row.realPerson || '-'" style="display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ formatCellText(scope.row.realPerson) }}</span>
</template>
</el-table-column>
<el-table-column label="ICCID" min-width="220">
<template #default="scope">
<span :title="scope.row.iccid || '-'" style="display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ formatCellText(scope.row.iccid) }}</span>
</template>
</el-table-column>
<el-table-column label="所在城市" min-width="140">
<template #default="scope">
<span :title="scope.row.city || '-'" style="display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ formatCellText(scope.row.city) }}</span>
</template>
</el-table-column>
<el-table-column label="号卡状态" min-width="120">
<el-table-column label="号卡状态" min-width="120">
<template #default="scope">
<template #default="scope">
<span class="status-chip-wrap">
<span class="status-chip-wrap">
...
@@ -464,9 +487,7 @@
...
@@ -464,9 +487,7 @@
<span>{{ scope.row.status }}</span>
<span>{{ scope.row.status }}</span>
</span>
</span>
</template>
</template>
</el-table-column>
</el-table-column> <el-table-column label="企业微信" min-width="110">
<el-table-column property="cardUsageLocation" label="卡使用地点" min-width="160" />
<el-table-column label="企业微信" min-width="110">
<template #default="scope">{{ formatBooleanText(scope.row.wecom, '已开通', '未开通') }}</template>
<template #default="scope">{{ formatBooleanText(scope.row.wecom, '已开通', '未开通') }}</template>
</el-table-column>
</el-table-column>
<el-table-column label="微信" min-width="100">
<el-table-column label="微信" min-width="100">
...
@@ -475,20 +496,28 @@
...
@@ -475,20 +496,28 @@
<el-table-column label="可外呼" min-width="100">
<el-table-column label="可外呼" min-width="100">
<template #default="scope">{{ formatBooleanText(scope.row.outboundCall, '可外呼', '不可外呼') }}</template>
<template #default="scope">{{ formatBooleanText(scope.row.outboundCall, '可外呼', '不可外呼') }}</template>
</el-table-column>
</el-table-column>
<el-table-column property="douyinAccount" label="抖音账号" min-width="160" />
<el-table-column label="抖音账号" min-width="180">
<template #default="scope">
<span :title="scope.row.douyinAccount || '-'" style="display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ formatCellText(scope.row.douyinAccount) }}</span>
</template>
</el-table-column>
<el-table-column label="小程序备案" min-width="120">
<el-table-column label="小程序备案" min-width="120">
<template #default="scope">{{ formatBooleanText(scope.row.miniProgramFiling, '已备案', '未备案') }}</template>
<template #default="scope">{{ formatBooleanText(scope.row.miniProgramFiling, '已备案', '未备案') }}</template>
</el-table-column>
</el-table-column>
<el-table-column property="channelOperator" label="渠道运营商" min-width="130" />
<el-table-column label="渠道运营商" min-width="150">
<template #default="scope">
<span :title="scope.row.channelOperator || '-'" style="display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ formatCellText(scope.row.channelOperator) }}</span>
</template>
</el-table-column>
<el-table-column label="手机号状态" min-width="120">
<el-table-column label="手机号状态" min-width="120">
<template #default="scope">{{ formatStatusText(scope.row.numberStatus) }}</template>
<template #default="scope">{{ formatStatusText(scope.row.numberStatus) }}</template>
</el-table-column>
</el-table-column>
<el-table-column
property="linkedWecom" label="绑定企业微信" min-width="160" /
>
<el-table-column
label="绑定企业微信" min-width="180"
>
<el-table-column label="号码保留状态" min-width="130
">
<template #default="scope
">
<template #default="scope">{{ formatRetentionText(scope.row.numberRetentionStatus) }}</template
>
<span :title="scope.row.linkedWecom || '-'" style="display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ formatCellText(scope.row.linkedWecom) }}</span
>
</el-table-column
>
</template
>
<el-table-column label="操作" width="100" fixed="right">
<
/el-table-column> <
el-table-column label="操作" width="100" fixed="right">
<template #default="scope">
<template #default="scope">
<div class="action-cluster" style="display: flex; flex-direction: column; align-items: flex-start; gap: 8px;">
<div class="action-cluster" style="display: flex; flex-direction: column; align-items: flex-start; gap: 8px;">
<button class="action-pill action-pill-primary" type="button" @click.stop="handleRowAction('view', scope.row.id)" style="border: none; background: transparent; color: #2563eb; cursor: pointer; padding: 0; font-weight: 600; line-height: 1;">查看</button>
<button class="action-pill action-pill-primary" type="button" @click.stop="handleRowAction('view', scope.row.id)" style="border: none; background: transparent; color: #2563eb; cursor: pointer; padding: 0; font-weight: 600; line-height: 1;">查看</button>
...
@@ -544,3 +573,5 @@
...
@@ -544,3 +573,5 @@
src/modules/shared/phone-api-client.js
View file @
da65cb92
...
@@ -13,11 +13,33 @@
...
@@ -13,11 +13,33 @@
}
}
/**
/**
* 代码作用(白话):把浏览器在本地后端没启动时抛出的网络错误翻成稳定中文,避免页面直接展示原始 Failed to fetch;关联文件:F:/Project/xyw_console/src/modules/shared/phone-api-client.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js、F:/Project/xyw_console/src/modules/phone/phone-add-dialog.js;关联逻辑(调用链/消息链/数据流):fetch() 失败 -> requestJson() -> 抛出中文错误 -> 外层 catch -> 页面提示。
*/
function
isFetchUnavailableError
(
error
)
{
const
message
=
String
(
error
?.
message
||
''
).
toLowerCase
();
return
error
instanceof
TypeError
&&
message
.
includes
(
'failed to fetch'
);
}
/**
* 代码作用(白话):先请求接口再统一解析 JSON,并在网络断开或本地后端未启动时返回稳定错误文案;关联文件:F:/Project/xyw_console/src/modules/shared/phone-api-client.js;关联逻辑(调用链/消息链/数据流):listPhones()/savePhone()/deletePhone() -> requestJson() -> parseJsonResponse() -> 外层页面提示。
*/
async
function
requestJson
(
url
,
options
,
networkMessage
)
{
try
{
const
response
=
await
fetch
(
url
,
options
);
return
await
parseJsonResponse
(
response
);
}
catch
(
error
)
{
if
(
isFetchUnavailableError
(
error
))
{
throw
new
Error
(
networkMessage
);
}
throw
error
;
}
}
/**
* 代码作用(白话):从本地手机号接口拉取完整列表,返回后端 data 数组给外层适配;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js;关联逻辑(调用链/消息链/数据流):phone 页面挂载/刷新 -> listPhones() -> app-v2.js -> normalizePhoneRecord() -> 列表渲染。
* 代码作用(白话):从本地手机号接口拉取完整列表,返回后端 data 数组给外层适配;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js;关联逻辑(调用链/消息链/数据流):phone 页面挂载/刷新 -> listPhones() -> app-v2.js -> normalizePhoneRecord() -> 列表渲染。
*/
*/
async
function
listPhones
()
{
async
function
listPhones
()
{
const
response
=
await
fetch
(
BASE_URL
);
const
json
=
await
requestJson
(
BASE_URL
,
undefined
,
'手机号服务暂时不可用,请确认本地后端已启动'
);
const
json
=
await
parseJsonResponse
(
response
);
return
Array
.
isArray
(
json
.
data
)
?
json
.
data
:
[];
return
Array
.
isArray
(
json
.
data
)
?
json
.
data
:
[];
}
}
...
@@ -28,12 +50,11 @@
...
@@ -28,12 +50,11 @@
const
payload
=
{
...
record
};
const
payload
=
{
...
record
};
const
isEdit
=
Boolean
(
payload
.
id
);
const
isEdit
=
Boolean
(
payload
.
id
);
const
targetUrl
=
isEdit
?
`
${
BASE_URL
}
/
${
payload
.
id
}
`
:
BASE_URL
;
const
targetUrl
=
isEdit
?
`
${
BASE_URL
}
/
${
payload
.
id
}
`
:
BASE_URL
;
const
response
=
await
fetch
(
targetUrl
,
{
const
json
=
await
requestJson
(
targetUrl
,
{
method
:
isEdit
?
'PUT'
:
'POST'
,
method
:
isEdit
?
'PUT'
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
},
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
payload
)
body
:
JSON
.
stringify
(
payload
)
});
},
'手机号保存失败,请确认本地后端已启动'
);
const
json
=
await
parseJsonResponse
(
response
);
return
json
.
data
||
json
;
return
json
.
data
||
json
;
}
}
...
@@ -41,10 +62,9 @@
...
@@ -41,10 +62,9 @@
* 代码作用(白话):删除指定手机号记录,并把失败信息统一抛给外层处理;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js;关联逻辑(调用链/消息链/数据流):手机号列表删除按钮 -> deletePhoneRecord() -> deletePhone() -> 刷新列表或提示失败。
* 代码作用(白话):删除指定手机号记录,并把失败信息统一抛给外层处理;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/phone/phone-list-runtime.js;关联逻辑(调用链/消息链/数据流):手机号列表删除按钮 -> deletePhoneRecord() -> deletePhone() -> 刷新列表或提示失败。
*/
*/
async
function
deletePhone
(
id
)
{
async
function
deletePhone
(
id
)
{
const
response
=
await
fetch
(
`
${
BASE_URL
}
/
${
id
}
`
,
{
const
json
=
await
requestJson
(
`
${
BASE_URL
}
/
${
id
}
`
,
{
method
:
'DELETE'
method
:
'DELETE'
});
},
'手机号删除失败,请确认本地后端已启动'
);
const
json
=
await
parseJsonResponse
(
response
);
return
json
.
data
||
json
;
return
json
.
data
||
json
;
}
}
...
...
src/modules/shared/record-adapters.js
View file @
da65cb92
...
@@ -99,7 +99,6 @@
...
@@ -99,7 +99,6 @@
const
miniProgramFiled
=
toBooleanFlag
(
source
.
miniProgramFiling
??
source
.
mini_program_filing
,
false
);
const
miniProgramFiled
=
toBooleanFlag
(
source
.
miniProgramFiling
??
source
.
mini_program_filing
,
false
);
const
packageChangeEnabled
=
toBooleanFlag
(
source
.
packageChange5yuan
??
source
.
package_change_5yuan
,
false
);
const
packageChangeEnabled
=
toBooleanFlag
(
source
.
packageChange5yuan
??
source
.
package_change_5yuan
,
false
);
const
numberStatus
=
toBooleanFlag
(
source
.
numberStatus
??
source
.
mobile_status
??
source
.
number_status
,
true
);
const
numberStatus
=
toBooleanFlag
(
source
.
numberStatus
??
source
.
mobile_status
??
source
.
number_status
,
true
);
const
numberRetentionStatus
=
toBooleanFlag
(
source
.
numberRetentionStatus
??
source
.
number_retention_status
,
true
);
const
wechatStatus
=
source
.
wechatStatus
||
(
numberStatus
?
'正常'
:
'异常停机'
);
const
wechatStatus
=
source
.
wechatStatus
||
(
numberStatus
?
'正常'
:
'异常停机'
);
const
outbound
=
source
.
outbound
||
(
outboundEnabled
?
'可外呼'
:
'不可外呼'
);
const
outbound
=
source
.
outbound
||
(
outboundEnabled
?
'可外呼'
:
'不可外呼'
);
const
linkedWecom
=
source
.
linkedWecom
||
source
.
linked_wecom
||
''
;
const
linkedWecom
=
source
.
linkedWecom
||
source
.
linked_wecom
||
''
;
...
@@ -152,8 +151,6 @@
...
@@ -152,8 +151,6 @@
mobile_status
:
numberStatus
,
mobile_status
:
numberStatus
,
linkedWecom
,
linkedWecom
,
linked_wecom
:
linkedWecom
,
linked_wecom
:
linkedWecom
,
numberRetentionStatus
,
number_retention_status
:
numberRetentionStatus
};
};
}
}
...
@@ -162,3 +159,4 @@
...
@@ -162,3 +159,4 @@
normalizePhoneRecord
normalizePhoneRecord
};
};
})();
})();
src/modules/shared/wechat-api-client.js
View file @
da65cb92
...
@@ -14,11 +14,33 @@
...
@@ -14,11 +14,33 @@
}
}
/**
/**
* 代码作用(白话):把浏览器在本地后端没启动时抛出的网络错误翻成稳定中文,避免页面直接展示原始 Failed to fetch;关联文件:F:/Project/xyw_console/src/modules/shared/wechat-api-client.js、F:/Project/xyw_console/src/modules/wechat/wechat-list-runtime.js、F:/Project/xyw_console/src/modules/wechat/wechat-add-dialog.js;关联逻辑(调用链/消息链/数据流):fetch() 失败 -> requestJson() -> 抛出中文错误 -> 外层 catch -> 页面提示。
*/
function
isFetchUnavailableError
(
error
)
{
const
message
=
String
(
error
?.
message
||
''
).
toLowerCase
();
return
error
instanceof
TypeError
&&
message
.
includes
(
'failed to fetch'
);
}
/**
* 代码作用(白话):先请求接口再统一解析 JSON,并在网络断开或本地后端未启动时返回稳定错误文案;关联文件:F:/Project/xyw_console/src/modules/shared/wechat-api-client.js;关联逻辑(调用链/消息链/数据流):listWechatRecords()/getWechatRecord()/saveWechatRecord() -> requestJson() -> parseJsonResponse() -> 外层页面提示。
*/
async
function
requestJson
(
url
,
options
,
networkMessage
)
{
try
{
const
response
=
await
fetch
(
url
,
options
);
return
await
parseJsonResponse
(
response
);
}
catch
(
error
)
{
if
(
isFetchUnavailableError
(
error
))
{
throw
new
Error
(
networkMessage
);
}
throw
error
;
}
}
/**
* 代码作用(白话):从后端拉取企微资料全量列表,交给页面继续做本地筛选和分页;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/wechat/wechat-list-runtime.js;关联逻辑(调用链/消息链/数据流):wechat 页面挂载/刷新 -> listWechatRecords() -> app-v2.js -> normalizeWechatRecord() -> 列表渲染。
* 代码作用(白话):从后端拉取企微资料全量列表,交给页面继续做本地筛选和分页;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/wechat/wechat-list-runtime.js;关联逻辑(调用链/消息链/数据流):wechat 页面挂载/刷新 -> listWechatRecords() -> app-v2.js -> normalizeWechatRecord() -> 列表渲染。
*/
*/
async
function
listWechatRecords
()
{
async
function
listWechatRecords
()
{
const
response
=
await
fetch
(
BASE_URL
);
const
json
=
await
requestJson
(
BASE_URL
,
undefined
,
'企微服务暂时不可用,请确认本地后端已启动'
);
const
json
=
await
parseJsonResponse
(
response
);
return
Array
.
isArray
(
json
.
data
)
?
json
.
data
:
[];
return
Array
.
isArray
(
json
.
data
)
?
json
.
data
:
[];
}
}
...
@@ -26,8 +48,7 @@
...
@@ -26,8 +48,7 @@
* 代码作用(白话):按主键读取单条企微资料,让详情抽屉和编辑弹窗拿到数据库最新值;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/wechat/wechat-detail-drawer.js;关联逻辑(调用链/消息链/数据流):查看/编辑按钮 -> getWechatRecord() -> app-v2.js -> 详情抽屉或编辑弹窗打开。
* 代码作用(白话):按主键读取单条企微资料,让详情抽屉和编辑弹窗拿到数据库最新值;关联文件:F:/Project/xyw_console/app-v2.js、F:/Project/xyw_console/src/modules/wechat/wechat-detail-drawer.js;关联逻辑(调用链/消息链/数据流):查看/编辑按钮 -> getWechatRecord() -> app-v2.js -> 详情抽屉或编辑弹窗打开。
*/
*/
async
function
getWechatRecord
(
id
)
{
async
function
getWechatRecord
(
id
)
{
const
response
=
await
fetch
(
`
${
BASE_URL
}
/
${
id
}
`
);
const
json
=
await
requestJson
(
`
${
BASE_URL
}
/
${
id
}
`
,
undefined
,
'企微详情读取失败,请确认本地后端已启动'
);
const
json
=
await
parseJsonResponse
(
response
);
return
json
.
data
||
null
;
return
json
.
data
||
null
;
}
}
...
@@ -41,12 +62,11 @@
...
@@ -41,12 +62,11 @@
if
(
!
isEdit
)
{
if
(
!
isEdit
)
{
delete
payload
.
id
;
delete
payload
.
id
;
}
}
const
response
=
await
fetch
(
targetUrl
,
{
const
json
=
await
requestJson
(
targetUrl
,
{
method
:
isEdit
?
'PUT'
:
'POST'
,
method
:
isEdit
?
'PUT'
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
},
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
payload
)
body
:
JSON
.
stringify
(
payload
)
});
},
'企微保存失败,请确认本地后端已启动'
);
const
json
=
await
parseJsonResponse
(
response
);
return
json
.
data
||
json
;
return
json
.
data
||
json
;
}
}
...
@@ -56,4 +76,3 @@
...
@@ -56,4 +76,3 @@
saveWechatRecord
saveWechatRecord
};
};
})();
})();
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment