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
a3e29145
Commit
a3e29145
authored
Jul 01, 2026
by
DaiJiezhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refine wechat list layout and image actions
parent
f7030db4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
242 additions
and
37 deletions
+242
-37
app-v2.js
app-v2.js
+36
-6
record-adapters.js
src/modules/shared/record-adapters.js
+27
-15
wechat-api-client.js
src/modules/shared/wechat-api-client.js
+2
-0
wechat-list-runtime.js
src/modules/wechat/wechat-list-runtime.js
+0
-0
styles-v2.css
styles-v2.css
+142
-7
styles.css
styles.css
+35
-9
No files found.
app-v2.js
View file @
a3e29145
...
...
@@ -347,6 +347,23 @@ async function saveWechatRecord(payload) {
}
/**
* 代码作用(白话):在列表里删除企微手机图片时,先取最新记录再清空图片字段并复用统一保存接口;关联文件:F:/Project/xyw_console/src/modules/wechat/wechat-list-runtime.js、F:/Project/xyw_console/src/modules/shared/wechat-api-client.js;关联逻辑(调用链/消息链/数据流):列表删除图片按钮 -> removeWechatRecordImage() -> getWechatRecordById() -> saveWechatRecord() -> refreshWechatList()。
*/
async
function
removeWechatRecordImage
(
recordId
)
{
const
record
=
await
getWechatRecordById
(
recordId
);
if
(
!
record
)
{
throw
new
Error
(
'未找到对应企微记录'
);
}
const
payload
=
{
...
record
,
phone_image
:
''
,
phoneImage
:
''
,
'手机图片'
:
''
};
return
saveWechatRecord
(
payload
);
}
/**
* 代码作用(白话):在企微保存成功后刷新当前页面,保证列表、详情和弹窗看到的是同一份最新数据;关联文件:F:/Project/xyw_console/src/modules/wechat/wechat-add-dialog.js;关联逻辑(调用链/消息链/数据流):WechatAddDialogActions.afterSave() -> refreshWechatList() -> renderModule() -> 重新挂载 wechat 列表。
*/
async
function
refreshWechatList
()
{
...
...
@@ -477,24 +494,32 @@ function renderExternalRuntime(moduleKey) {
add
:
'新增资料'
,
reset
:
'重置'
,
realName
:
'姓名'
,
account
:
'账号'
,
alias
:
'别名'
,
department
:
'部门'
,
gender
:
'性别'
,
phone
:
'手机号'
,
wxId
:
'微信 ID
'
,
status
:
'状态
'
,
owner
:
'负责人
'
,
updatedAt
:
'更新时间
'
,
owner
:
'实名人
'
,
accountLocation
:
'账号位置
'
,
owner
Status
:
'实名状态
'
,
phoneImage
:
'手机图片
'
,
action
:
'操作'
,
view
:
'查看'
,
edit
:
'编辑'
,
replaceImage
:
'更换图片'
,
removeImage
:
'删除图片'
,
imageMissing
:
'暂无图片'
,
selected
:
'已选'
,
items
:
'项'
,
batchAction
:
'批量操作'
,
total
:
'共'
,
records
:
'条'
,
pageSuffix
:
' 条/页'
,
searchPlaceholder
:
'搜索姓名、
微信 ID、手机号或部门
'
,
searchPlaceholder
:
'搜索姓名、
账号、手机号、部门或实名人
'
,
loadFailed
:
'加载企微列表失败,请确认本地后端已启动'
,
openFailed
:
'打开企微详情失败,请稍后重试'
openFailed
:
'打开企微详情失败,请稍后重试'
,
imageRemoved
:
'已删除手机图片'
,
imageRemoveFailed
:
'删除手机图片失败,请稍后重试'
},
wechatTablePageSizes
:
[
10
,
20
,
50
,
100
],
mountState
:
moduleMountState
.
wechat
,
...
...
@@ -502,6 +527,7 @@ function renderExternalRuntime(moduleKey) {
loadWechatRows
,
openAddDialog
:
openWechatAddDialog
,
openDrawer
:
openWechatDrawer
,
removeRecordImage
:
removeWechatRecordImage
,
getVisiblePageNumbers
,
getWechatStatusDotClass
,
notifyError
:
showError
,
...
...
@@ -696,3 +722,7 @@ document.addEventListener('DOMContentLoaded', initPage);
src/modules/shared/record-adapters.js
View file @
a3e29145
...
...
@@ -12,33 +12,45 @@
const
ownerStatusRaw
=
source
.
ownerStatus
??
source
.
real_name_owner_status
??
source
.
realNameOwnerStatus
;
const
status
=
ownerStatusRaw
===
'abnormal'
||
ownerStatusRaw
===
'异常'
||
ownerStatusRaw
===
0
?
'异常'
:
'正常'
;
const
remark
=
source
.
remark
||
source
.
project
||
'暂无备注'
;
const
accountLocation
=
source
.
account_location
||
source
.
accountLocation
||
source
[
'账号位置'
]
||
''
;
const
phoneImage
=
source
.
phone_image
||
source
.
phoneImage
||
source
[
'手机图片'
]
||
''
;
const
departmentName
=
departmentMap
[
source
.
department
]
||
source
.
department
||
source
.
department_name
||
source
.
departmentName
||
''
;
const
realName
=
source
.
realName
||
source
.
real_name
||
''
;
const
aliasName
=
source
.
alias_name
||
source
.
alias
||
source
.
aliasName
||
''
;
const
account
=
source
.
account
||
source
.
wxId
||
''
;
const
phoneNumber
=
source
.
phone_number
||
source
.
phone
||
source
.
phoneNumber
||
''
;
const
ownerName
=
source
.
real_name_owner
||
source
.
owner
||
source
.
realNameOwner
||
''
;
return
{
...
source
,
realName
:
source
.
realName
||
source
.
real_name
||
''
,
real_name
:
source
.
real_name
||
source
.
realName
||
''
,
alias
:
source
.
alias
||
source
.
alias_name
||
source
.
aliasName
||
''
,
alias_name
:
source
.
alias_name
||
source
.
alias
||
source
.
aliasName
||
''
,
account
:
source
.
account
||
source
.
wxId
||
''
,
department
:
department
Map
[
source
.
department
]
||
source
.
department
||
source
.
department_name
||
source
.
department
Name
||
'未分配'
,
department_name
:
source
.
department_name
||
source
.
department
||
source
.
departmentName
||
''
,
phone
:
source
.
phone
||
source
.
phone_number
||
source
.
phoneNumber
||
''
,
phone_number
:
source
.
phone_number
||
source
.
phone
||
source
.
phoneNumber
||
''
,
owner
:
source
.
owner
||
source
.
real_name_owner
||
source
.
realNameOwner
||
''
,
real_name_owner
:
source
.
real_name_owner
||
source
.
owner
||
source
.
realNameOwner
||
''
,
realName
,
real_name
:
realName
,
alias
:
aliasName
,
alias_name
:
aliasName
,
account
,
department
:
departmentName
||
'未分配'
,
department_name
:
departmentName
,
phone
:
phoneNumber
,
phone_number
:
phoneNumber
,
owner
:
ownerName
,
real_name_owner
:
ownerName
,
ownerStatus
:
status
,
real_name_owner_status
:
status
===
'正常'
?
1
:
0
,
status
,
wxId
:
source
.
wxId
||
source
.
account
||
''
,
wxId
:
source
.
wxId
||
account
,
createdAt
:
source
.
createdAt
||
source
.
created_at
||
''
,
created_at
:
source
.
created_at
||
source
.
createdAt
||
''
,
updatedAt
:
source
.
updatedAt
||
source
.
updated_at
||
''
,
updated_at
:
source
.
updated_at
||
source
.
updatedAt
||
''
,
remark
,
project
:
source
.
project
||
remark
,
gender
:
source
.
gender
||
'男'
,
account_location
:
source
.
account_location
||
source
.
accountLocation
||
source
[
'账号位置'
]
||
''
,
phone_image
:
source
.
phone_image
||
source
.
phoneImage
||
source
[
'手机图片'
]
||
''
gender
:
source
.
gender
||
''
,
account_location
:
accountLocation
,
accountLocation
,
'账号位置'
:
accountLocation
,
phone_image
:
phoneImage
,
phoneImage
,
'手机图片'
:
phoneImage
};
}
...
...
src/modules/shared/wechat-api-client.js
View file @
a3e29145
(
function
attachWechatApiClient
()
{
// 当前企微资料接口对应测试数据库;后续切换到生产数据库(正式业务库)时,需要同步改成生产环境对应的后端配置。
const
BASE_URL
=
'http://localhost:8080/api/wechat-records'
;
/**
...
...
@@ -55,3 +56,4 @@
saveWechatRecord
};
})();
src/modules/wechat/wechat-list-runtime.js
View file @
a3e29145
This diff is collapsed.
Click to expand it.
styles-v2.css
View file @
a3e29145
/* Import original styles first */
/* Import original styles first */
@import
url('styles.css')
;
/* Overrides for right side replication */
...
...
@@ -306,16 +306,16 @@
}
.fselect
:after
{
content
:
"
▾"
;
content
:
"
鈻?
;
color: #9ca3af;
}
/* Custom icon for el-select to match batch action button icon
▾
*/
/* Custom icon for el-select to match batch action button icon
鈻?
*/
.custom-fselect .el-input__suffix-inner > .el-icon > svg {
display: none !important;
}
.custom-fselect .el-input__suffix-inner > .el-icon::before {
content
:
"
▾"
;
content: "
鈻?
;
color
:
#9ca3af
;
font-size
:
14px
;
display
:
flex
;
...
...
@@ -1003,7 +1003,143 @@
fill
:
currentColor
!important
;
}
/*
消除原来的旧外边距干扰
*/
/*
娑堥櫎鍘熸潵鐨勬棫澶栬竟璺濆共鎵?
*/
.domain-mode
.action-dots
{
margin
:
0
;
}
\ No newline at end of file
}
.wechat-list-table
{
table-layout
:
fixed
;
}
.table-wrap-refined
{
overflow-x
:
auto
;
overflow-y
:
hidden
;
}
.wechat-location-cell
{
white-space
:
normal
;
word-break
:
break-word
;
}
.wechat-image-cell
{
display
:
flex
;
align-items
:
center
;
}
.wechat-image-thumb
{
width
:
84px
;
height
:
84px
;
border-radius
:
10px
;
overflow
:
hidden
;
border
:
1px
solid
#dbe4f0
;
background
:
#f8fafc
;
}
.wechat-image-thumb
.el-image__inner
{
width
:
100%
;
height
:
100%
;
object-fit
:
cover
;
}
.wechat-image-empty
{
color
:
#94a3b8
;
font-size
:
12px
;
}
.wechat-action-cluster
{
flex-wrap
:
wrap
;
justify-content
:
flex-start
;
gap
:
6px
;
}
.action-pill-danger
{
color
:
#dc2626
;
}
.action-pill-danger
:hover:not
(
:disabled
)
{
background
:
#fef2f2
;
color
:
#b91c1c
;
}
.action-pill
:disabled
{
opacity
:
0.45
;
cursor
:
not-allowed
;
}
.table-area-refined
{
flex
:
1
1
auto
;
min-height
:
0
;
height
:
100%
;
}
.table-toolbar-refined
{
flex
:
0
0
auto
;
}
.table-wrap-refined
{
flex
:
1
1
auto
;
min-height
:
0
;
height
:
0
;
overflow-x
:
auto
;
overflow-y
:
auto
;
}
#wechatListRoot
,
#phoneListRoot
{
min-height
:
0
;
}
#vue-router-app
,
.legacy-wrapper
{
display
:
flex
;
flex
:
1
1
auto
;
flex-direction
:
column
;
min-height
:
0
;
height
:
100%
;
}
#pageHeader
{
flex
:
0
0
auto
;
}
#pageBody
{
display
:
flex
!important
;
flex
:
1
1
auto
;
flex-direction
:
column
;
min-height
:
0
;
overflow
:
hidden
;
}
#wechatListRoot
,
#phoneListRoot
,
#overviewListRoot
{
flex
:
1
1
auto
;
min-height
:
0
;
height
:
100%
;
}
#wechatListRoot
[
style
*=
'display: block'
],
#phoneListRoot
[
style
*=
'display: block'
],
#overviewListRoot
[
style
*=
'display: block'
]
{
display
:
flex
!important
;
flex-direction
:
column
;
}
.table-area-refined
{
flex
:
1
1
auto
!important
;
min-height
:
0
!important
;
height
:
100%
!important
;
}
.table-wrap-refined
{
flex
:
1
1
auto
!important
;
min-height
:
0
!important
;
height
:
0
!important
;
overflow-x
:
auto
!important
;
overflow-y
:
auto
!important
;
}
styles.css
View file @
a3e29145
:root
{
:root
{
--page-bg
:
#f5f7fb
;
--surface
:
#ffffff
;
--surface-soft
:
#fafcff
;
...
...
@@ -2922,14 +2922,38 @@ button {
/* Professional admin dashboard visual override */
.shell-main
{
background
:
linear-gradient
(
180deg
,
#f7f9fc
0%
,
#eff4f9
100%
);
}
.shell-header
{
padding
:
28px
28px
20px
;
border-bottom
:
1px
solid
rgba
(
15
,
23
,
42
,
0.06
);
background
:
rgba
(
255
,
255
,
255
,
0.92
);
}
.workspace-heading
{
display
:
flex
;
align-items
:
flex-start
;
justify-content
:
space-between
;
gap
:
24px
;
}
.heading-copy
{
display
:
grid
;
gap
:
12px
;
max-width
:
760px
;
}
.legacy-wrapper
{
display
:
flex
;
flex
:
1
1
auto
;
flex-direction
:
column
;
min-height
:
0
;
height
:
100%
;
}
#pageHeader
{
flex
:
0
0
auto
;
}
#pageBody
{
flex
:
1
1
auto
;
min-height
:
0
;
}
#pageBody
>
#wechatListRoot
,
#pageBody
>
#phoneListRoot
,
#pageBody
>
#overviewListRoot
{
height
:
100%
;
min-height
:
0
;
}
.shell-header
{
padding
:
20px
28px
16px
;
border-bottom
:
1px
solid
rgba
(
15
,
23
,
42
,
0.06
);
background
:
rgba
(
255
,
255
,
255
,
0.92
);
}
.workspace-heading
{
display
:
flex
;
align-items
:
flex-start
;
justify-content
:
space-between
;
gap
:
20px
;
flex-wrap
:
wrap
;
min-height
:
88px
;
}
.heading-copy
{
display
:
grid
;
gap
:
8px
;
flex
:
1
1
420px
;
min-width
:
0
;
max-width
:
760px
;
align-content
:
start
;
}
.heading-caption-row
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
flex-wrap
:
wrap
;
}
.heading-caption
{
margin
:
0
;
font-size
:
12px
;
font-weight
:
700
;
letter-spacing
:
0.08em
;
text-transform
:
uppercase
;
color
:
#6b7a90
;
}
.heading-badge
{
display
:
inline-flex
;
align-items
:
center
;
height
:
28px
;
padding
:
0
12px
;
border-radius
:
999px
;
background
:
#eef4ff
;
color
:
#2554cf
;
font-size
:
12px
;
font-weight
:
700
;
}
.page-title
{
margin
:
0
;
font-size
:
3
2px
;
line-height
:
1.1
;
font-weight
:
800
;
color
:
#0f172a
;
}
.page-summary
{
margin
:
0
;
color
:
#667085
;
font-size
:
14px
;
line-height
:
1.
7
;
}
.page-title
{
margin
:
0
;
font-size
:
3
0px
;
line-height
:
1.08
;
font-weight
:
800
;
color
:
#0f172a
;
}
.page-summary
{
margin
:
0
;
color
:
#667085
;
font-size
:
14px
;
line-height
:
1.
5
;
}
.admin-summary-pills
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
10px
;
}
.status-pill
{
display
:
inline-flex
;
align-items
:
center
;
gap
:
8px
;
height
:
34px
;
padding
:
0
12px
;
border-radius
:
999px
;
border
:
1px
solid
rgba
(
148
,
163
,
184
,
0.18
);
background
:
#fff
;
box-shadow
:
0
10px
24px
rgba
(
15
,
23
,
42
,
0.04
);
font-size
:
13px
;
color
:
#475467
;
}
.status-pill
strong
{
color
:
#0f172a
;
}
...
...
@@ -2937,7 +2961,7 @@ button {
.status-pill.green
{
background
:
#edfdf3
;
color
:
#177245
;
}
.status-pill.orange
{
background
:
#fff6ea
;
color
:
#c76a00
;
}
.status-pill.red
{
background
:
#fff1f3
;
color
:
#d92d20
;
}
.header-tools
{
display
:
flex
;
flex
:
0
0
460px
;
flex-direction
:
column
;
gap
:
14px
;
}
.header-tools
{
display
:
flex
;
flex
:
1
1
360px
;
min-width
:
280px
;
max-width
:
460px
;
margin-left
:
auto
;
flex-direction
:
column
;
gap
:
14px
;
}
.header-search
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
width
:
100%
;
min-width
:
0
;
height
:
52px
;
padding
:
0
16px
;
border
:
1px
solid
rgba
(
148
,
163
,
184
,
0.24
);
border-radius
:
16px
;
background
:
rgba
(
255
,
255
,
255
,
0.98
);
box-shadow
:
0
12px
30px
rgba
(
15
,
23
,
42
,
0.05
);
}
.header-search
::before
{
content
:
none
;
}
.header-search-icon
{
display
:
inline-flex
;
align-items
:
center
;
justify-content
:
center
;
width
:
28px
;
height
:
28px
;
border-radius
:
50%
;
background
:
#eef4ff
;
color
:
#2554cf
;
font-size
:
14px
;
}
...
...
@@ -2946,7 +2970,7 @@ button {
.header-button
,
.header-button-primary
,
.toolbar-button
,
.footer-button
,
.footer-button-primary
,
.preview-link
{
height
:
42px
;
padding
:
0
16px
;
border-radius
:
14px
;
font-weight
:
700
;
}
.header-button
,
.toolbar-button
,
.footer-button
,
.preview-link
{
border
:
1px
solid
rgba
(
148
,
163
,
184
,
0.2
);
background
:
#fff
;
box-shadow
:
0
8px
22px
rgba
(
15
,
23
,
42
,
0.05
);
}
.header-button-primary
,
.footer-button-primary
{
border
:
1px
solid
#2563eb
;
background
:
linear-gradient
(
180deg
,
#3b82f6
0%
,
#2563eb
100%
);
color
:
#fff
;
box-shadow
:
0
14px
28px
rgba
(
37
,
99
,
235
,
0.24
);
}
.shell-body
{
gap
:
20px
;
padding
:
20px
28px
28
px
;
background
:
transparent
;
}
.shell-body
{
display
:
flex
;
flex
:
1
1
auto
;
flex-direction
:
column
;
gap
:
16px
;
min-height
:
0
;
overflow
:
hidden
;
padding
:
16px
28px
20
px
;
background
:
transparent
;
}
.stats-grid
{
gap
:
16px
;
}
.metric-card-premium
{
position
:
relative
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
min-height
:
190px
;
padding
:
20px
22px
;
border-radius
:
22px
;
border
:
1px
solid
rgba
(
226
,
232
,
240
,
0.92
);
box-shadow
:
0
18px
42px
rgba
(
15
,
23
,
42
,
0.06
);
overflow
:
hidden
;
}
.metric-card-premium
[
data-tone
=
"blue"
]
{
background
:
linear-gradient
(
180deg
,
#eef5ff
0%
,
#ffffff
100%
);
}
...
...
@@ -3034,7 +3058,7 @@ button {
.timeline-time
{
color
:
#98a2b3
;
font-size
:
12px
;
}
.detail-footer
{
display
:
flex
;
gap
:
10px
;
}
.detail-footer
>
*
{
flex
:
1
;
}
@media
(
max-width
:
1360px
)
{
.workspace-heading
,
.table-head-v3
,
.filter-toolbar
,
.preview-head-v3
{
flex-direction
:
column
;
align-items
:
stretch
;
}
.header-tools
{
flex
:
1
1
auto
;
}
.table-selection-chip
{
min-width
:
0
;
}
}
@media
(
max-width
:
1360px
)
{
.workspace-heading
,
.table-head-v3
,
.filter-toolbar
,
.preview-head-v3
{
flex-direction
:
column
;
align-items
:
stretch
;
}
.header-tools
{
flex
:
1
1
auto
;
min-width
:
0
;
max-width
:
none
;
margin-left
:
0
;
}
.table-selection-chip
{
min-width
:
0
;
}
}
@media
(
max-width
:
1180px
)
{
.shell-header
,
.shell-body
{
padding-left
:
18px
;
padding-right
:
18px
;
}
.page-title
{
font-size
:
28px
;
}
.preview-row-v3
{
grid-template-columns
:
32px
minmax
(
0
,
1
fr
);
}
.preview-link
{
grid-column
:
2
;
justify-self
:
start
;
}
}
@media
(
max-width
:
840px
)
{
.shell-header
,
.shell-body
{
padding-left
:
14px
;
padding-right
:
14px
;
}
.page-title
{
font-size
:
24px
;
}
.detail-grid
{
grid-template-columns
:
1
fr
;
}
}
@media
(
min-width
:
1280px
)
{
...
...
@@ -3047,3 +3071,5 @@ button {
.workspace
:not
(
.sidebar-collapsed
)
.nav-link
,
.workspace
:not
(
.sidebar-collapsed
)
.nav-toggle-button
{
justify-content
:
flex-start
;
gap
:
12px
;
padding
:
0
14px
;
}
}
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