Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
dizhen-ui
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
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
jiangyun
dizhen-ui
Commits
ac2b9088
Commit
ac2b9088
authored
Oct 21, 2025
by
cat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
zd
parent
4e25153b
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1504 additions
and
419 deletions
+1504
-419
.env
+8
-0
.env.development
+5
-8
.env.production
+6
-6
.env.staging
+6
-10
public/index.html
+1
-1
src/assets/images/login-background.jpeg
+0
-0
src/layout/components/Sidebar/Logo.vue
+5
-4
src/views/login.vue
+181
-33
src/views/system/user/index copy.vue
+673
-0
src/views/system/user/index.vue
+7
-2
src/views/ysqqXmxx/ysgc/index.vue
+34
-2
src/views/ysqqXmxx/ysgc/index2.vue
+578
-353
No files found.
.env
0 → 100644
View file @
ac2b9088
# 环境变量配置文件
# 所有环境通用配置
# 应用标题
VUE_APP_TITLE=地震资料处理数字化验收支持平台
# API基础路径
VUE_APP_BASE_API=/dev-api
.env.development
View file @
ac2b9088
# 页面标题
VUE_APP_TITLE = 系统
# 开发环境配置
ENV = 'development'
NODE_ENV=development
#
若依管理系统/开发环境
VUE_APP_
BASE_API = '/dev-api'
#
应用标题
VUE_APP_
TITLE=地震资料处理数字化验收支持平台
#
路由懒加载
VUE_
CLI_BABEL_TRANSPILE_MODULES = true
#
API基础路径
VUE_
APP_BASE_API=/dev-api
.env.production
View file @
ac2b9088
# 页面标题
VUE_APP_TITLE = 系统
# 生产环境配置
ENV = 'production'
NODE_ENV=production
# 应用标题
VUE_APP_TITLE=地震资料处理数字化验收支持平台
#
若依管理系统/生产环境
VUE_APP_BASE_API
= '/prod-api'
#
API基础路径
VUE_APP_BASE_API
=/prod-api
.env.staging
View file @
ac2b9088
#
页面标题
VUE_APP_TITLE = 系统
#
预发布环境配置
NODE_ENV=production
BABEL_ENV = production
# 应用标题
VUE_APP_TITLE=地震资料处理数字化验收支持平台(预发布)
NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 若依管理系统/测试环境
VUE_APP_BASE_API = '/stage-api'
# API基础路径
VUE_APP_BASE_API=/stage-api
public/index.html
View file @
ac2b9088
...
...
@@ -201,7 +201,7 @@
<div
id=
"loader"
></div>
<div
class=
"loader-section section-left"
></div>
<div
class=
"loader-section section-right"
></div>
<div
class=
"load_title"
>
正在加载
系统
资源,请耐心等待
</div>
<div
class=
"load_title"
>
正在加载
地震资料处理数字化验收支持平台
资源,请耐心等待
</div>
</div>
</div>
</body>
...
...
src/assets/images/login-background.jpeg
0 → 100644
View file @
ac2b9088
795 KB
src/layout/components/Sidebar/Logo.vue
View file @
ac2b9088
...
...
@@ -6,15 +6,16 @@
<h1
v-else
class=
"sidebar-title"
:style=
"
{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
{{
title
}}
</h1>
</router-link>
<router-link
v-else
key=
"expand"
class=
"sidebar-logo-link"
to=
"/"
>
<img
v-if=
"logo"
:src=
"logo"
class=
"sidebar-logo"
/>
<h1
class=
"sidebar-title"
:style=
"
{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
{{
title
}}
</h1>
<!--
<img
v-if=
"logo"
:src=
"logo"
class=
"sidebar-logo"
/>
-->
<h1
class=
"sidebar-title"
:style=
"
{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">验收支持平台
</h1>
<!--
<h1
class=
"sidebar-title"
:style=
"
{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
{{
title
}}
</h1>
-->
</router-link>
</transition>
</div>
</
template
>
<
script
>
import
logoImg
from
'@/assets/logo/logo.png'
//
import logoImg from '@/assets/logo/logo.png'
import
variables
from
'@/assets/styles/variables.scss'
export
default
{
...
...
@@ -36,7 +37,7 @@ export default {
data
()
{
return
{
title
:
process
.
env
.
VUE_APP_TITLE
,
logo
:
logoImg
//
logo: logoImg
}
}
}
...
...
src/views/login.vue
View file @
ac2b9088
...
...
@@ -13,16 +13,18 @@
<svg-icon
slot=
"prefix"
icon-class=
"password"
class=
"el-input__icon input-icon"
/>
</el-input>
</el-form-item>
<el-form-item
prop=
"code"
v-if=
"captchaEnabled"
>
<el-input
v-model=
"loginForm.code"
auto-complete=
"off"
placeholder=
"验证码"
style=
"width: 63%"
<el-form-item
prop=
"code"
v-if=
"captchaEnabled"
class=
"captcha-item"
>
<div
class=
"captcha-container"
>
<el-input
v-model=
"loginForm.code"
auto-complete=
"off"
placeholder=
"验证码"
@
keyup
.
enter
.
native=
"handleLogin"
>
<svg-icon
slot=
"prefix"
icon-class=
"validCode"
class=
"el-input__icon input-icon"
/>
</el-input>
<div
class=
"login-code"
>
<img
:src=
"codeUrl"
@
click=
"getCode"
class=
"login-code-img"
/>
</div>
</div>
</el-form-item>
<el-checkbox
v-model=
"loginForm.rememberMe"
style=
"margin:0px 0px 25px 0px;"
>
记住密码
</el-checkbox>
<el-checkbox
v-model=
"loginForm.rememberMe"
>
记住密码
</el-checkbox>
<el-form-item
style=
"width:100%;"
>
<el-button
:loading=
"loading"
size=
"medium"
type=
"primary"
style=
"width:100%;"
@
click
.
native
.
prevent=
"handleLogin"
>
...
...
@@ -53,8 +55,8 @@ export default {
title
:
process
.
env
.
VUE_APP_TITLE
,
codeUrl
:
""
,
loginForm
:
{
username
:
"
admin
"
,
password
:
"
admin123
"
,
username
:
""
,
password
:
""
,
rememberMe
:
false
,
code
:
""
,
uuid
:
""
...
...
@@ -69,7 +71,7 @@ export default {
pattern
:
/^
(?=
.*
[
A-Za-z
])(?=
.*
\d)(?=
.*
[
@$!%*?&
])\S{6,20}
$/
,
message
:
'用户密码长度为 6 到 20 个字符,且必须包含字母、数字以及特殊符号'
,
trigger
:
'blur'
,
trigger
:
[
'blur'
,
'change'
]
,
},
],
code
:
[{
required
:
true
,
trigger
:
"change"
,
message
:
"请输入验证码"
}]
...
...
@@ -147,70 +149,216 @@ export default {
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
height
:
100
%
;
background-image
:
url("../assets/images/login-background.jpg")
;
height
:
100
vh
;
background-image
:
url("../assets/images/login-background.jp
e
g")
;
background-size
:
cover
;
background-position
:
center
;
background-attachment
:
fixed
;
position
:
relative
;
//
添加渐变遮罩层
&::before
{
content
:
''
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
background
:
linear-gradient
(
rgba
(
111
,
111
,
111
,
0.20
)
);
z-index
:
0
;
}
}
.title
{
margin
:
0px
auto
3
0px
auto
;
margin
:
0px
auto
2
0px
auto
;
text-align
:
center
;
color
:
#707070
;
color
:
#ebebeb
;
font-size
:
24px
;
font-weight
:
300
;
letter-spacing
:
2px
;
}
.login-form
{
border-radius
:
6px
;
background
:
#ffffff
;
width
:
400px
;
padding
:
25px
25px
5px
25px
;
border-radius
:
20px
;
background
:
rgba
(
255
,
255
,
255
,
0.15
);
backdrop-filter
:
blur
(
20px
);
-webkit-backdrop-filter
:
blur
(
20px
);
border
:
1px
solid
rgba
(
255
,
255
,
255
,
0.2
);
box-shadow
:
0
8px
32px
rgba
(
0
,
0
,
0
,
0.1
);
width
:
480px
;
padding
:
25px
35px
20px
35px
;
z-index
:
1
;
position
:
relative
;
margin-left
:
600px
;
.el-input
{
height
:
38px
;
height
:
50px
;
margin-bottom
:
10px
;
input
{
height
:
38px
;
height
:
50px
;
background
:
rgba
(
255
,
255
,
255
,
0.9
);
border
:
1px
solid
rgba
(
255
,
255
,
255
,
0.3
);
border-radius
:
12px
;
color
:
#2c3e50
;
font-size
:
14px
;
padding-left
:
45px
;
transition
:
all
0.3s
ease
;
&:focus
{
background
:
rgba
(
255
,
255
,
255
,
1
);
border-color
:
#409eff
;
box-shadow
:
0
0
0
2px
rgba
(
64
,
158
,
255
,
0.2
);
}
&
::placeholder
{
color
:
#a0a0a0
;
}
}
}
.input-icon
{
height
:
39px
;
width
:
14px
;
margin-left
:
2px
;
height
:
20px
;
width
:
20px
;
margin-left
:
10
;
color
:
#7f8c8d
;
z-index
:
2
;
}
.el-form-item
{
margin-bottom
:
12px
;
}
.el-checkbox
{
margin-bottom
:
15px
;
.el-checkbox__label
{
color
:
#2c3e50
;
font-size
:
14px
;
}
}
.el-button
{
height
:
50px
;
border-radius
:
12px
;
font-size
:
16px
;
font-weight
:
500
;
letter-spacing
:
1px
;
background
:
linear-gradient
(
135deg
,
#409eff
0%
,
#36a3f7
100%
);
border
:
none
;
transition
:
all
0.3s
ease
;
&:hover
{
transform
:
translateY
(
-2px
);
box-shadow
:
0
8px
25px
rgba
(
64
,
158
,
255
,
0.3
);
}
&
:active
{
transform
:
translateY
(
0
);
}
}
}
.login-tip
{
font-size
:
13px
;
text-align
:
center
;
color
:
#bfbfbf
;
.captcha-container
{
display
:
flex
;
align-items
:
stretch
;
gap
:
10px
;
height
:
50px
;
}
.captcha-item
{
.el-input
{
flex
:
1
;
margin-bottom
:
0
;
height
:
50px
;
input
{
height
:
50px
;
line-height
:
50px
;
}
}
}
.login-code
{
width
:
33%
;
height
:
38px
;
float
:
right
;
width
:
120px
;
height
:
50px
;
border-radius
:
12px
;
overflow
:
hidden
;
flex-shrink
:
0
;
background
:
rgba
(
255
,
255
,
255
,
0.9
);
border
:
1px
solid
rgba
(
255
,
255
,
255
,
0.3
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
img
{
cursor
:
pointer
;
vertical-align
:
middle
;
width
:
100%
;
height
:
100%
;
object-fit
:
cover
;
border-radius
:
12px
;
transition
:
all
0.3s
ease
;
&:hover
{
transform
:
scale
(
1.05
);
}
}
}
.el-login-footer
{
height
:
4
0px
;
line-height
:
4
0px
;
height
:
5
0px
;
line-height
:
5
0px
;
position
:
fixed
;
bottom
:
0
;
width
:
100%
;
text-align
:
center
;
color
:
#fff
;
font-family
:
Arial
;
font-size
:
1
2
px
;
color
:
rgba
(
255
,
255
,
255
,
0.8
)
;
font-family
:
'Helvetica Neue'
,
Arial
,
sans-serif
;
font-size
:
1
3
px
;
letter-spacing
:
1px
;
background
:
rgba
(
0
,
0
,
0
,
0.1
);
backdrop-filter
:
blur
(
10px
);
-webkit-backdrop-filter
:
blur
(
10px
);
z-index
:
1
;
}
.login-code-img
{
height
:
38px
;
height
:
50px
;
border-radius
:
12px
;
}
//
响应式设计
@media
(
max-width
:
768px
)
{
.login-form
{
width
:
90%
;
max-width
:
420px
;
padding
:
25px
20px
20px
20px
;
}
.title
{
font-size
:
20px
;
margin-bottom
:
20px
;
}
}
.el-input__icon
{
height
:
50px
!important
;
margin-left
:
10px
!important
;
}
//
添加一些动画效果
.login-form
{
animation
:
slideInUp
0.8s
ease-out
;
}
@keyframes
slideInUp
{
from
{
opacity
:
0
;
transform
:
translateY
(
30px
);
}
to
{
opacity
:
1
;
transform
:
translateY
(
0
);
}
}
</
style
>
src/views/system/user/index copy.vue
0 → 100644
View file @
ac2b9088
<
template
>
<div
class=
"app-container"
>
<el-row
:gutter=
"20"
>
<splitpanes
:horizontal=
"this.$store.getters.device === 'mobile'"
class=
"default-theme"
>
<!--部门数据-->
<pane
size=
"16"
>
<el-col>
<div
class=
"head-container"
>
<el-input
v-model=
"deptName"
placeholder=
"请输入部门名称"
clearable
size=
"small"
prefix-icon=
"el-icon-search"
style=
"margin-bottom: 20px"
/>
</div>
<div
class=
"head-container"
>
<el-tree
:data=
"deptOptions"
:props=
"defaultProps"
:expand-on-click-node=
"false"
:filter-node-method=
"filterNode"
ref=
"tree"
node-key=
"id"
default-expand-all
highlight-current
@
node-click=
"handleNodeClick"
/>
</div>
</el-col>
</pane>
<!--用户数据-->
<pane
size=
"84"
>
<el-col>
<el-form
:model=
"queryParams"
ref=
"queryForm"
size=
"small"
:inline=
"true"
v-show=
"showSearch"
label-width=
"68px"
>
<el-form-item
label=
"用户名称"
prop=
"userName"
>
<el-input
v-model=
"queryParams.userName"
placeholder=
"请输入用户名称"
clearable
style=
"width: 240px"
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"手机号码"
prop=
"phonenumber"
>
<el-input
v-model=
"queryParams.phonenumber"
placeholder=
"请输入手机号码"
clearable
style=
"width: 240px"
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"用户状态"
clearable
style=
"width: 240px"
>
<el-option
v-for=
"dict in dict.type.sys_normal_disable"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"创建时间"
>
<el-date-picker
v-model=
"dateRange"
style=
"width: 240px"
value-format=
"yyyy-MM-dd"
type=
"daterange"
range-separator=
"-"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"el-icon-search"
size=
"mini"
@
click=
"handleQuery"
>
搜索
</el-button>
<el-button
icon=
"el-icon-refresh"
size=
"mini"
@
click=
"resetQuery"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
plain
icon=
"el-icon-plus"
size=
"mini"
@
click=
"handleAdd"
v-hasPermi=
"['system:user:add']"
>
新增
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"success"
plain
icon=
"el-icon-edit"
size=
"mini"
:disabled=
"single"
@
click=
"handleUpdate"
v-hasPermi=
"['system:user:edit']"
>
修改
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"danger"
plain
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"multiple"
@
click=
"handleDelete"
v-hasPermi=
"['system:user:remove']"
>
删除
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"info"
plain
icon=
"el-icon-upload2"
size=
"mini"
@
click=
"handleImport"
v-hasPermi=
"['system:user:import']"
>
导入
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"warning"
plain
icon=
"el-icon-download"
size=
"mini"
@
click=
"handleExport"
v-hasPermi=
"['system:user:export']"
>
导出
</el-button>
</el-col>
<right-toolbar
:showSearch
.
sync=
"showSearch"
@
queryTable=
"getList"
:columns=
"columns"
></right-toolbar>
</el-row>
<el-table
v-loading=
"loading"
:data=
"userList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"50"
align=
"center"
/>
<el-table-column
label=
"用户编号"
align=
"center"
key=
"userId"
prop=
"userId"
v-if=
"columns[0].visible"
/>
<el-table-column
label=
"用户名称"
align=
"center"
key=
"userName"
prop=
"userName"
v-if=
"columns[1].visible"
:show-overflow-tooltip=
"true"
/>
<el-table-column
label=
"用户昵称"
align=
"center"
key=
"nickName"
prop=
"nickName"
v-if=
"columns[2].visible"
:show-overflow-tooltip=
"true"
/>
<el-table-column
label=
"部门"
align=
"center"
key=
"deptName"
prop=
"dept.deptName"
v-if=
"columns[3].visible"
:show-overflow-tooltip=
"true"
/>
<el-table-column
label=
"手机号码"
align=
"center"
key=
"phonenumber"
prop=
"phonenumber"
v-if=
"columns[4].visible"
width=
"120"
/>
<el-table-column
label=
"状态"
align=
"center"
key=
"status"
v-if=
"columns[5].visible"
>
<template
slot-scope=
"scope"
>
<el-switch
v-model=
"scope.row.status"
active-value=
"0"
inactive-value=
"1"
@
change=
"handleStatusChange(scope.row)"
></el-switch>
</
template
>
</el-table-column>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
v-if=
"columns[6].visible"
width=
"160"
>
<
template
slot-scope=
"scope"
>
<span>
{{
parseTime
(
scope
.
row
.
createTime
)
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
width=
"160"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
v-if=
"scope.row.userId !== 1"
>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-edit"
@
click=
"handleUpdate(scope.row)"
v-hasPermi=
"['system:user:edit']"
>
修改
</el-button>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-delete"
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['system:user:remove']"
>
删除
</el-button>
<el-dropdown
size=
"mini"
@
command=
"(command) => handleCommand(command, scope.row)"
v-hasPermi=
"['system:user:resetPwd', 'system:user:edit']"
>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-d-arrow-right"
>
更多
</el-button>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
command=
"handleResetPwd"
icon=
"el-icon-key"
v-hasPermi=
"['system:user:resetPwd']"
>
重置密码
</el-dropdown-item>
<el-dropdown-item
command=
"handleAuthRole"
icon=
"el-icon-circle-check"
v-hasPermi=
"['system:user:edit']"
>
分配角色
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</
template
>
</el-table-column>
</el-table>
<pagination
v-show=
"total > 0"
:total=
"total"
:page
.
sync=
"queryParams.pageNum"
:limit
.
sync=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</el-col>
</pane>
</splitpanes>
</el-row>
<!-- 添加或修改用户配置对话框 -->
<el-dialog
:title=
"title"
:visible
.
sync=
"open"
width=
"60%"
append-to-body
>
<el-form
ref=
"form"
:model=
"form"
:rules=
"rules"
label-width=
"80px"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"用户昵称"
prop=
"nickName"
>
<el-input
v-model=
"form.nickName"
placeholder=
"请输入用户昵称"
maxlength=
"30"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"归属部门"
prop=
"deptId"
>
<treeselect
v-model=
"form.deptId"
:options=
"enabledDeptOptions"
:show-count=
"true"
placeholder=
"请选择归属部门"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"手机号码"
prop=
"phonenumber"
>
<el-input
v-model=
"form.phonenumber"
placeholder=
"请输入手机号码"
maxlength=
"11"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-input
v-model=
"form.email"
placeholder=
"请输入邮箱"
maxlength=
"50"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
v-if=
"form.userId == undefined"
label=
"用户名称"
prop=
"userName"
>
<el-input
v-model=
"form.userName"
placeholder=
"请输入用户名称"
maxlength=
"30"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
v-if=
"form.userId == undefined"
label=
"用户密码"
prop=
"password"
>
<el-input
v-model=
"form.password"
placeholder=
"请输入用户密码"
type=
"password"
maxlength=
"20"
show-password
@
input=
"checkPassword"
/>
<!-- 弱口令警告提示 -->
<div
v-if=
"passwordWarning.show"
class=
"password-warning"
:class=
"{ 'warning-danger': passwordWarning.isWeak }"
>
<i
class=
"el-icon-warning"
></i>
<span>
{{ passwordWarning.message }}
</span>
</div>
<!-- 密码安全建议 -->
<div
v-if=
"passwordSuggestion"
class=
"password-suggestion"
>
<i
class=
"el-icon-info"
></i>
<span>
{{ passwordSuggestion }}
</span>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"用户性别"
>
<el-select
v-model=
"form.sex"
placeholder=
"请选择性别"
>
<el-option
v-for=
"dict in dict.type.sys_user_sex"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"状态"
>
<el-radio-group
v-model=
"form.status"
>
<el-radio
v-for=
"dict in dict.type.sys_normal_disable"
:key=
"dict.value"
:label=
"dict.value"
>
{{
dict.label
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"岗位"
>
<el-select
v-model=
"form.postIds"
multiple
placeholder=
"请选择岗位"
>
<el-option
v-for=
"item in postOptions"
:key=
"item.postId"
:label=
"item.postName"
:value=
"item.postId"
:disabled=
"item.status == 1"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"角色"
>
<el-select
v-model=
"form.roleIds"
multiple
placeholder=
"请选择角色"
>
<el-option
v-for=
"item in roleOptions"
:key=
"item.roleId"
:label=
"item.roleName"
:value=
"item.roleId"
:disabled=
"item.status == 1"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-form-item
label=
"备注"
>
<el-input
v-model=
"form.remark"
type=
"textarea"
placeholder=
"请输入内容"
></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button>
<el-button
@
click=
"cancel"
>
取 消
</el-button>
</div>
</el-dialog>
<!-- 用户导入对话框 -->
<el-dialog
:title=
"upload.title"
:visible
.
sync=
"upload.open"
width=
"400px"
append-to-body
>
<el-upload
ref=
"upload"
:limit=
"1"
accept=
".xlsx, .xls"
:headers=
"upload.headers"
:action=
"upload.url + '?updateSupport=' + upload.updateSupport"
:disabled=
"upload.isUploading"
:on-progress=
"handleFileUploadProgress"
:on-success=
"handleFileSuccess"
:auto-upload=
"false"
drag
>
<i
class=
"el-icon-upload"
></i>
<div
class=
"el-upload__text"
>
将文件拖到此处,或
<em>
点击上传
</em></div>
<div
class=
"el-upload__tip text-center"
slot=
"tip"
>
<div
class=
"el-upload__tip"
slot=
"tip"
>
<el-checkbox
v-model=
"upload.updateSupport"
/>
是否更新已经存在的用户数据
</div>
<span>
仅允许导入xls、xlsx格式文件。
</span>
<el-link
type=
"primary"
:underline=
"false"
style=
"font-size: 12px; vertical-align: baseline"
@
click=
"importTemplate"
>
下载模板
</el-link>
</div>
</el-upload>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
type=
"primary"
@
click=
"submitFileForm"
>
确 定
</el-button>
<el-button
@
click=
"upload.open = false"
>
取 消
</el-button>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
{
listUser
,
getUser
,
delUser
,
addUser
,
updateUser
,
resetUserPwd
,
changeUserStatus
,
deptTreeSelect
}
from
"@/api/system/user"
import
{
getToken
}
from
"@/utils/auth"
import
Treeselect
from
"@riophae/vue-treeselect"
import
"@riophae/vue-treeselect/dist/vue-treeselect.css"
import
{
Splitpanes
,
Pane
}
from
"splitpanes"
import
"splitpanes/dist/splitpanes.css"
export
default
{
name
:
"User"
,
dicts
:
[
'sys_normal_disable'
,
'sys_user_sex'
],
components
:
{
Treeselect
,
Splitpanes
,
Pane
},
data
()
{
return
{
// 遮罩层
loading
:
true
,
// 选中数组
ids
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 显示搜索条件
showSearch
:
true
,
// 总条数
total
:
0
,
// 用户表格数据
userList
:
null
,
// 弹出层标题
title
:
""
,
// 所有部门树选项
deptOptions
:
undefined
,
// 过滤掉已禁用部门树选项
enabledDeptOptions
:
undefined
,
// 是否显示弹出层
open
:
false
,
// 部门名称
deptName
:
undefined
,
// 默认密码
initPassword
:
undefined
,
// 日期范围
dateRange
:
[],
// 岗位选项
postOptions
:
[],
// 角色选项
roleOptions
:
[],
// 表单参数
form
:
{},
// 密码安全提示
passwordWarning
:
{
show
:
false
,
isWeak
:
false
,
message
:
''
},
passwordSuggestion
:
''
,
defaultProps
:
{
children
:
"children"
,
label
:
"label"
},
// 用户导入参数
upload
:
{
// 是否显示弹出层(用户导入)
open
:
false
,
// 弹出层标题(用户导入)
title
:
""
,
// 是否禁用上传
isUploading
:
false
,
// 是否更新已经存在的用户数据
updateSupport
:
0
,
// 设置上传的请求头部
headers
:
{
Authorization
:
"Bearer "
+
getToken
()
},
// 上传的地址
url
:
process
.
env
.
VUE_APP_BASE_API
+
"/system/user/importData"
},
// 查询参数
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
userName
:
undefined
,
phonenumber
:
undefined
,
status
:
undefined
,
deptId
:
undefined
},
// 列信息
columns
:
[
{
key
:
0
,
label
:
`用户编号`
,
visible
:
true
},
{
key
:
1
,
label
:
`用户名称`
,
visible
:
true
},
{
key
:
2
,
label
:
`用户昵称`
,
visible
:
true
},
{
key
:
3
,
label
:
`部门`
,
visible
:
true
},
{
key
:
4
,
label
:
`手机号码`
,
visible
:
true
},
{
key
:
5
,
label
:
`状态`
,
visible
:
true
},
{
key
:
6
,
label
:
`创建时间`
,
visible
:
true
}
],
// 表单校验
rules
:
{
userName
:
[
{
required
:
true
,
message
:
"用户名称不能为空"
,
trigger
:
"blur"
},
{
min
:
2
,
max
:
20
,
message
:
'用户名称长度必须介于 2 和 20 之间'
,
trigger
:
'blur'
}
],
nickName
:
[
{
required
:
true
,
message
:
"用户昵称不能为空"
,
trigger
:
"blur"
}
],
password
:
[
{
required
:
true
,
message
:
"用户密码不能为空"
,
trigger
:
"blur"
},
{
min
:
5
,
max
:
20
,
message
:
'用户密码长度必须介于 5 和 20 之间'
,
trigger
:
'blur'
},
{
pattern
:
/^
[^
<>"'|
\\]
+$/
,
message
:
"不能包含非法字符:< >
\"
'
\\\
|"
,
trigger
:
"blur"
},
{
validator
:
this
.
validatePassword
,
trigger
:
'blur'
}
],
email
:
[
{
type
:
"email"
,
message
:
"请输入正确的邮箱地址"
,
trigger
:
[
"blur"
,
"change"
]
}
],
phonenumber
:
[
{
pattern
:
/^1
[
3|4|5|6|7|8|9
][
0-9
]\d{8}
$/
,
message
:
"请输入正确的手机号码"
,
trigger
:
"blur"
}
]
}
}
},
watch
:
{
// 根据名称筛选部门树
deptName
(
val
)
{
this
.
$refs
.
tree
.
filter
(
val
)
}
},
created
()
{
this
.
getList
()
this
.
getDeptTree
()
this
.
getConfigKey
(
"sys.user.initPassword"
).
then
(
response
=>
{
this
.
initPassword
=
response
.
msg
})
},
methods
:
{
// 密码验证方法
validatePassword
(
rule
,
value
,
callback
)
{
if
(
!
value
)
{
callback
(
new
Error
(
'请输入用户密码'
))
return
}
callback
()
},
/** 查询用户列表 */
getList
()
{
this
.
loading
=
true
listUser
(
this
.
addDateRange
(
this
.
queryParams
,
this
.
dateRange
)).
then
(
response
=>
{
this
.
userList
=
response
.
rows
this
.
total
=
response
.
total
this
.
loading
=
false
}
)
},
/** 查询部门下拉树结构 */
getDeptTree
()
{
deptTreeSelect
().
then
(
response
=>
{
this
.
deptOptions
=
response
.
data
this
.
enabledDeptOptions
=
this
.
filterDisabledDept
(
JSON
.
parse
(
JSON
.
stringify
(
response
.
data
)))
})
},
// 过滤禁用的部门
filterDisabledDept
(
deptList
)
{
return
deptList
.
filter
(
dept
=>
{
if
(
dept
.
disabled
)
{
return
false
}
if
(
dept
.
children
&&
dept
.
children
.
length
)
{
dept
.
children
=
this
.
filterDisabledDept
(
dept
.
children
)
}
return
true
})
},
// 筛选节点
filterNode
(
value
,
data
)
{
if
(
!
value
)
return
true
return
data
.
label
.
indexOf
(
value
)
!==
-
1
},
// 节点单击事件
handleNodeClick
(
data
)
{
this
.
queryParams
.
deptId
=
data
.
id
this
.
handleQuery
()
},
// 用户状态修改
handleStatusChange
(
row
)
{
let
text
=
row
.
status
===
"0"
?
"启用"
:
"停用"
this
.
$modal
.
confirm
(
'确认要"'
+
text
+
'""'
+
row
.
userName
+
'"用户吗?'
).
then
(
function
()
{
return
changeUserStatus
(
row
.
userId
,
row
.
status
)
}).
then
(()
=>
{
this
.
$modal
.
msgSuccess
(
text
+
"成功"
)
}).
catch
(
function
()
{
row
.
status
=
row
.
status
===
"0"
?
"1"
:
"0"
})
},
// 取消按钮
cancel
()
{
this
.
open
=
false
this
.
reset
()
},
// 表单重置
reset
()
{
this
.
form
=
{
userId
:
undefined
,
deptId
:
undefined
,
userName
:
undefined
,
nickName
:
undefined
,
password
:
undefined
,
phonenumber
:
undefined
,
email
:
undefined
,
sex
:
undefined
,
status
:
"0"
,
remark
:
undefined
,
postIds
:
[],
roleIds
:
[]
}
this
.
resetForm
(
"form"
)
},
/** 搜索按钮操作 */
handleQuery
()
{
this
.
queryParams
.
pageNum
=
1
this
.
getList
()
},
/** 重置按钮操作 */
resetQuery
()
{
this
.
dateRange
=
[]
this
.
resetForm
(
"queryForm"
)
this
.
queryParams
.
deptId
=
undefined
this
.
$refs
.
tree
.
setCurrentKey
(
null
)
this
.
handleQuery
()
},
// 多选框选中数据
handleSelectionChange
(
selection
)
{
this
.
ids
=
selection
.
map
(
item
=>
item
.
userId
)
this
.
single
=
selection
.
length
!=
1
this
.
multiple
=
!
selection
.
length
},
// 更多操作触发
handleCommand
(
command
,
row
)
{
switch
(
command
)
{
case
"handleResetPwd"
:
this
.
handleResetPwd
(
row
)
break
case
"handleAuthRole"
:
this
.
handleAuthRole
(
row
)
break
default
:
break
}
},
/** 新增按钮操作 */
handleAdd
()
{
this
.
reset
()
getUser
().
then
(
response
=>
{
this
.
postOptions
=
response
.
posts
this
.
roleOptions
=
response
.
roles
this
.
open
=
true
this
.
title
=
"添加用户"
this
.
form
.
password
=
this
.
initPassword
})
},
/** 修改按钮操作 */
handleUpdate
(
row
)
{
this
.
reset
()
const
userId
=
row
.
userId
||
this
.
ids
getUser
(
userId
).
then
(
response
=>
{
this
.
form
=
response
.
data
this
.
postOptions
=
response
.
posts
this
.
roleOptions
=
response
.
roles
this
.
$set
(
this
.
form
,
"postIds"
,
response
.
postIds
)
this
.
$set
(
this
.
form
,
"roleIds"
,
response
.
roleIds
)
this
.
open
=
true
this
.
title
=
"修改用户"
this
.
form
.
password
=
""
})
},
/** 重置密码按钮操作 */
handleResetPwd
(
row
)
{
this
.
$prompt
(
'请输入"'
+
row
.
userName
+
'"的新密码'
,
"提示"
,
{
confirmButtonText
:
"确定"
,
cancelButtonText
:
"取消"
,
closeOnClickModal
:
false
,
inputPattern
:
/^
(?=
.*
[
A-Za-z
])(?=
.*
\d)(?=
.*
[
@$!%*?&
])\S{6,20}
$/
,
inputErrorMessage
:
"用户密码长度为 6 到 20 个字符,且必须包含字母、数字以及特殊符号"
,
inputValidator
:
(
value
)
=>
{
if
(
/<|>|"|'|
\|
|
\\
/
.
test
(
value
))
{
return
"不能包含非法字符:< >
\"
'
\\\
|"
}
return
true
},
}).
then
(({
value
})
=>
{
resetUserPwd
(
row
.
userId
,
value
).
then
(
response
=>
{
this
.
$modal
.
msgSuccess
(
"修改成功,新密码是:"
+
value
)
})
}).
catch
(()
=>
{
})
},
/** 分配角色操作 */
handleAuthRole
:
function
(
row
)
{
const
userId
=
row
.
userId
this
.
$router
.
push
(
"/system/user-auth/role/"
+
userId
)
},
/** 提交按钮 */
submitForm
:
function
()
{
this
.
$refs
[
"form"
].
validate
(
valid
=>
{
if
(
valid
)
{
if
(
this
.
form
.
userId
!=
undefined
)
{
updateUser
(
this
.
form
).
then
(
response
=>
{
this
.
$modal
.
msgSuccess
(
"修改成功"
)
this
.
open
=
false
this
.
getList
()
})
}
else
{
addUser
(
this
.
form
).
then
(
response
=>
{
this
.
$modal
.
msgSuccess
(
"新增成功"
)
this
.
open
=
false
this
.
getList
()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete
(
row
)
{
const
userIds
=
row
.
userId
||
this
.
ids
this
.
$modal
.
confirm
(
'是否确认删除用户编号为"'
+
userIds
+
'"的数据项?'
).
then
(
function
()
{
return
delUser
(
userIds
)
}).
then
(()
=>
{
this
.
getList
()
this
.
$modal
.
msgSuccess
(
"删除成功"
)
}).
catch
(()
=>
{
})
},
/** 导出按钮操作 */
handleExport
()
{
this
.
download
(
'system/user/export'
,
{
...
this
.
queryParams
},
`user_
${
new
Date
().
getTime
()}
.xlsx`
)
},
/** 导入按钮操作 */
handleImport
()
{
this
.
upload
.
title
=
"用户导入"
this
.
upload
.
open
=
true
},
/** 下载模板操作 */
importTemplate
()
{
this
.
download
(
'system/user/importTemplate'
,
{
},
`user_template_
${
new
Date
().
getTime
()}
.xlsx`
)
},
// 文件上传中处理
handleFileUploadProgress
(
event
,
file
,
fileList
)
{
this
.
upload
.
isUploading
=
true
},
// 文件上传成功处理
handleFileSuccess
(
response
,
file
,
fileList
)
{
this
.
upload
.
open
=
false
this
.
upload
.
isUploading
=
false
this
.
$refs
.
upload
.
clearFiles
()
this
.
$alert
(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>"
+
response
.
msg
+
"</div>"
,
"导入结果"
,
{
dangerouslyUseHTMLString
:
true
})
this
.
getList
()
},
// 提交上传文件
submitFileForm
()
{
this
.
$refs
.
upload
.
submit
()
}
}
}
</
script
>
<
style
scoped
>
/* 密码安全提示样式 */
.password-warning
{
margin-top
:
8px
;
padding
:
8px
12px
;
border-radius
:
6px
;
background-color
:
rgba
(
255
,
193
,
7
,
0.1
);
border
:
1px
solid
rgba
(
255
,
193
,
7
,
0.3
);
color
:
#f57c00
;
font-size
:
12px
;
display
:
flex
;
align-items
:
center
;
animation
:
slideDown
0.3s
ease-out
;
}
.password-warning
i
{
margin-right
:
6px
;
font-size
:
14px
;
}
.password-warning.warning-danger
{
background-color
:
rgba
(
244
,
67
,
54
,
0.1
);
border-color
:
rgba
(
244
,
67
,
54
,
0.3
);
color
:
#d32f2f
;
}
.password-suggestion
{
margin-top
:
6px
;
padding
:
6px
12px
;
border-radius
:
6px
;
background-color
:
rgba
(
33
,
150
,
243
,
0.1
);
border
:
1px
solid
rgba
(
33
,
150
,
243
,
0.3
);
color
:
#1976d2
;
font-size
:
12px
;
display
:
flex
;
align-items
:
center
;
animation
:
slideDown
0.3s
ease-out
;
}
.password-suggestion
i
{
margin-right
:
6px
;
font-size
:
14px
;
}
@keyframes
slideDown
{
from
{
opacity
:
0
;
transform
:
translateY
(
-10px
);
}
to
{
opacity
:
1
;
transform
:
translateY
(
0
);
}
}
</
style
>
\ No newline at end of file
src/views/system/user/index.vue
View file @
ac2b9088
...
...
@@ -330,8 +330,13 @@ export default {
],
password
:
[
{
required
:
true
,
message
:
"用户密码不能为空"
,
trigger
:
"blur"
},
{
min
:
5
,
max
:
20
,
message
:
'用户密码长度必须介于 5 和 20 之间'
,
trigger
:
'blur'
},
{
pattern
:
/^
[^
<>"'|
\\]
+$/
,
message
:
"不能包含非法字符:< >
\"
'
\\\
|"
,
trigger
:
"blur"
}
{
min
:
6
,
max
:
20
,
message
:
'用户密码长度必须介于 6 和 20 之间'
,
trigger
:
'blur'
},
{
pattern
:
/^
[^
<>"'|
\\]
+$/
,
message
:
"不能包含非法字符:< >
\"
'
\\\
|"
,
trigger
:
"blur"
},
{
pattern
:
/^
(?=
.*
[
A-Za-z
])(?=
.*
\d)(?=
.*
[
@$!%*?&
])\S{6,20}
$/
,
message
:
'用户密码长度为 6 到 20 个字符,且必须包含字母、数字以及特殊符号'
,
trigger
:
[
'blur'
,
'change'
],
}
],
email
:
[
{
...
...
src/views/ysqqXmxx/ysgc/index.vue
View file @
ac2b9088
...
...
@@ -327,8 +327,40 @@ export default {
return
{
backgroundColor
:
this
.
compact
?
'#f2f2f2'
:
'#ffffff'
,
grid
:
this
.
compact
?
{
top
:
6
,
left
:
6
,
right
:
6
,
bottom
:
6
,
containLabel
:
false
}
:
{
top
:
40
,
left
:
50
,
right
:
40
,
bottom
:
50
,
containLabel
:
true
},
xAxis
:
this
.
compact
?
{
type
:
'value'
,
min
:
this
.
xMin
,
max
:
this
.
xMax
,
scale
:
true
,
axisLine
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
axisLabel
:
{
show
:
false
},
splitLine
:
{
show
:
false
}
}
:
{
type
:
'value'
,
min
:
this
.
xMin
,
max
:
this
.
xMax
,
scale
:
false
,
axisLine
:
{
show
:
true
},
axisTick
:
{
show
:
true
},
axisLabel
:
{
color
:
'#666'
},
splitLine
:
{
show
:
true
,
lineStyle
:
{
color
:
'#9bb3e7'
,
opacity
:
0.6
}
}
},
yAxis
:
this
.
compact
?
{
type
:
'value'
,
min
:
this
.
yMin
,
max
:
this
.
yMax
,
scale
:
true
,
axisLine
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
axisLabel
:
{
show
:
false
},
splitLine
:
{
show
:
false
}
}
:
{
type
:
'value'
,
min
:
this
.
yMin
,
max
:
this
.
yMax
,
scale
:
false
,
axisLine
:
{
show
:
true
},
axisTick
:
{
show
:
true
},
axisLabel
:
{
color
:
'#666'
},
splitLine
:
{
show
:
true
,
lineStyle
:
{
color
:
'#9bb3e7'
,
opacity
:
0.6
}
}
},
xAxis
:
this
.
compact
?
{
type
:
'value'
,
min
:
this
.
xMin
,
max
:
this
.
xMax
,
scale
:
true
,
axisLine
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
axisLabel
:
{
show
:
false
},
splitLine
:
{
show
:
true
,
lineStyle
:
{
color
:
'#e0e0e0'
,
opacity
:
0.8
,
width
:
1
}
}
}
:
{
type
:
'value'
,
min
:
this
.
xMin
,
max
:
this
.
xMax
,
scale
:
false
,
axisLine
:
{
show
:
true
},
axisTick
:
{
show
:
true
},
axisLabel
:
{
color
:
'#666'
},
splitLine
:
{
show
:
true
,
lineStyle
:
{
color
:
'#9bb3e7'
,
opacity
:
0.6
}
}
},
yAxis
:
this
.
compact
?
{
type
:
'value'
,
min
:
this
.
yMin
,
max
:
this
.
yMax
,
scale
:
true
,
axisLine
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
axisLabel
:
{
show
:
false
},
splitLine
:
{
show
:
true
,
lineStyle
:
{
color
:
'#e0e0e0'
,
opacity
:
0.8
,
width
:
1
}
}
}
:
{
type
:
'value'
,
min
:
this
.
yMin
,
max
:
this
.
yMax
,
scale
:
false
,
axisLine
:
{
show
:
true
},
axisTick
:
{
show
:
true
},
axisLabel
:
{
color
:
'#666'
},
splitLine
:
{
show
:
true
,
lineStyle
:
{
color
:
'#9bb3e7'
,
opacity
:
0.6
}
}
},
series
,
tooltip
:
{
trigger
:
'item'
}
}
...
...
src/views/ysqqXmxx/ysgc/index2.vue
View file @
ac2b9088
...
...
@@ -41,16 +41,37 @@
</el-button>
</el-tooltip>
-->
</div>
<div
v-if=
"shouldShowThumb"
ref=
"thumbContainer"
@
click=
"handleThumbClick"
class=
"right-thumb"
>
<div
class=
"thumb-title"
>
缩略图
</div>
<!-- 缩略图 start-->
<div
v-if=
"shouldShowThumb"
ref=
"thumbContainer"
@
click=
"handleThumbClick"
@
mousedown=
"startDrag"
class=
"right-thumb draggable-thumb"
:style=
"thumbPosition"
>
<!--
<div
class=
"thumb-title"
>
缩略图
</div>
-->
<div
ref=
"thumbHolder"
class=
"thumb-holder"
>
<YsgcIndex
v-if=
"thumbReady"
:key=
"'thumb-' + routeId + '-' + thumbReady"
:compact=
"true"
:width=
"260"
:height=
"160"
:id-override=
"routeId"
/>
</div>
<!-- 拖动指示器 -->
<div
class=
"drag-handle"
>
<i
class=
"el-icon-rank"
></i>
</div>
</div>
<!-- 缩略图 end-->
<!-- 缩略图弹窗 start -->
<el-dialog
v-if=
"shouldShowThumb"
title=
"缩略图预览"
:visible
.
sync=
"showThumbDialog"
width=
"80%"
append-to-body
>
<el-dialog
v-if=
"shouldShowThumb"
title=
"缩略图预览"
:visible
.
sync=
"showThumbDialog"
width=
"80%"
append-to-body
:z-index=
"9999999"
:modal=
"true"
:close-on-click-modal=
"true"
:close-on-press-escape=
"true"
custom-class=
"thumbnail-dialog"
>
<div
style=
"height: 100%;"
>
<YsgcIndex
:key=
"'dialog-thumb-' + routeId"
:id-override=
"routeId"
@
segyLinePick=
"onThumbLinePick"
/>
</div>
...
...
@@ -63,11 +84,8 @@
{{
loadingError
}}
</div>
<div
class=
"toolbar"
v-if=
"isWidgetReady"
>
<!-- 左侧内容 -->
<div
class=
"toolbar-left"
>
<!-- 左侧可以留空,或者将来添加其他控件 -->
</div>
</div>
<div
class=
"split-container"
:class=
"layoutMode === 'vertical' ? 'layout-vertical' : 'layout-horizontal'"
>
<div
class=
"sync-section"
ref=
"topScroll"
@
scroll=
"onScroll('top')"
>
...
...
@@ -698,6 +716,18 @@ export default {
showThumbDialog
:
false
,
// 缩略图大图弹窗可见性
// 是否允许在未指定项目/无接口数据时加载示例数据
shouldLoadDemo
:
true
,
// 缩略图拖动相关
isDragging
:
false
,
dragStartX
:
0
,
dragStartY
:
0
,
dragDistance
:
0
,
dragThreshold
:
5
,
// 拖动阈值,超过这个距离才算拖动
thumbPosition
:
{
top
:
'150px'
,
right
:
'20px'
,
left
:
'auto'
,
bottom
:
'auto'
},
};
},
computed
:
{
...
...
@@ -726,7 +756,7 @@ export default {
watch
:
{
// 监听路由变化,当路由参数改变时重新初始化数据
'$route'
(
to
,
from
)
{
console
.
log
(
'[index2] 路由变化:'
,
to
.
query
,
from
.
query
);
//
console.log('[index2] 路由变化:', to.query, from.query);
// 如果路由参数发生变化,重新初始化组件
if
(
to
.
query
.
id
!==
from
.
query
.
id
||
to
.
query
.
zbid
!==
from
.
query
.
zbid
)
{
this
.
handleRouteChange
();
...
...
@@ -734,7 +764,7 @@ export default {
},
// 监听routeId变化
routeId
(
newId
,
oldId
)
{
console
.
log
(
'[index2] routeId变化:'
,
newId
,
oldId
);
//
console.log('[index2] routeId变化:', newId, oldId);
if
(
newId
!==
oldId
)
{
this
.
handleRouteChange
();
// 强制刷新缩略图
...
...
@@ -823,9 +853,9 @@ export default {
},
200
);
},
100
);
console
.
log
(
'测试函数已添加:'
);
console
.
log
(
'- window.testOuterScrollbarSync() - 测试外层滚动条同步'
);
console
.
log
(
'- window.testInternalScrollbarHidden() - 测试内部滚动条隐藏'
);
//
console.log('测试函数已添加:');
//
console.log('- window.testOuterScrollbarSync() - 测试外层滚动条同步');
//
console.log('- window.testInternalScrollbarHidden() - 测试内部滚动条隐藏');
},
beforeDestroy
()
{
// 移除右键菜单事件监听
...
...
@@ -833,6 +863,10 @@ export default {
this
.
$refs
.
plot
.
removeEventListener
(
'contextmenu'
,
this
.
showContextMenu
);
document
.
removeEventListener
(
'click'
,
this
.
hideContextMenu
);
}
// 清理拖动事件监听
document
.
removeEventListener
(
'mousemove'
,
this
.
onDrag
);
document
.
removeEventListener
(
'mouseup'
,
this
.
stopDrag
);
// 移除键盘事件监听
document
.
removeEventListener
(
'keydown'
,
this
.
handleKeyDown
);
// 移除窗口变化监听
...
...
@@ -841,7 +875,7 @@ export default {
methods
:
{
// 处理路由变化的方法
async
handleRouteChange
()
{
console
.
log
(
'[index2] 处理路由变化,重新初始化组件'
);
//
console.log('[index2] 处理路由变化,重新初始化组件');
// 重置组件状态
this
.
resetToInitialState
();
...
...
@@ -897,7 +931,7 @@ export default {
// 强制刷新缩略图
forceRefreshThumb
()
{
console
.
log
(
'[index2] 强制刷新缩略图'
);
//
console.log('[index2] 强制刷新缩略图');
this
.
thumbReady
=
false
;
this
.
$nextTick
(()
=>
{
this
.
thumbReady
=
true
;
...
...
@@ -994,9 +1028,9 @@ export default {
try
{
this
.
_seismicWidgetBottom
&&
this
.
_seismicWidgetBottom
.
invalidate
();
}
catch
(
e
)
{
}
},
async
handlePrevTrace
()
{
console
.
log
(
'[index2] 上一道 clicked'
);
//
console.log('[index2] 上一道 clicked');
if
(
!
Array
.
isArray
(
this
.
segyList
)
||
this
.
segyList
.
length
===
0
)
{
console
.
log
(
'[index2] segyList 为空,尝试重新加载'
);
//
console.log('[index2] segyList 为空,尝试重新加载');
try
{
await
this
.
loadThumbData
();
}
catch
(
e
)
{
console
.
warn
(
'[index2] 重新加载segy失败:'
,
e
);
}
...
...
@@ -1008,15 +1042,15 @@ export default {
// 计算上一个索引
this
.
currentSegyIndex
=
this
.
currentSegyIndex
>
0
?
this
.
currentSegyIndex
-
1
:
this
.
segyList
.
length
-
1
;
console
.
log
(
'[index2] 切换到上一道,当前索引:'
,
this
.
currentSegyIndex
);
//
console.log('[index2] 切换到上一道,当前索引:', this.currentSegyIndex);
// 加载当前segy文件
this
.
loadCurrentSegy
();
},
async
handleNextTrace
()
{
console
.
log
(
'[index2] 下一道 clicked'
);
//
console.log('[index2] 下一道 clicked');
if
(
!
Array
.
isArray
(
this
.
segyList
)
||
this
.
segyList
.
length
===
0
)
{
console
.
log
(
'[index2] segyList 为空,尝试重新加载'
);
//
console.log('[index2] segyList 为空,尝试重新加载');
try
{
await
this
.
loadThumbData
();
}
catch
(
e
)
{
console
.
warn
(
'[index2] 重新加载segy失败:'
,
e
);
}
...
...
@@ -1028,7 +1062,7 @@ export default {
// 计算下一个索引
this
.
currentSegyIndex
=
this
.
currentSegyIndex
<
this
.
segyList
.
length
-
1
?
this
.
currentSegyIndex
+
1
:
0
;
console
.
log
(
'[index2] 切换到下一道,当前索引:'
,
this
.
currentSegyIndex
);
//
console.log('[index2] 切换到下一道,当前索引:', this.currentSegyIndex);
// 加载当前segy文件
this
.
loadCurrentSegy
();
...
...
@@ -1036,18 +1070,18 @@ export default {
// 加载当前segy文件
async
loadCurrentSegy
()
{
if
(
this
.
segyList
.
length
===
0
)
{
console
.
log
(
'[index2] 没有segy数据可加载'
);
//
console.log('[index2] 没有segy数据可加载');
return
;
}
const
currentSegy
=
this
.
segyList
[
this
.
currentSegyIndex
];
if
(
!
currentSegy
)
{
console
.
log
(
'[index2] 当前segy数据不存在'
);
//
console.log('[index2] 当前segy数据不存在');
return
;
}
console
.
log
(
'[index2] 加载segy文件 Top/Bottom:'
,
(
currentSegy
.
jbsegyName
||
currentSegy
.
jbsegy
),
(
currentSegy
.
xbsegyName
||
currentSegy
.
xbsegy
));
console
.
log
(
'[index2] segy文件路径 Top/Bottom:'
,
currentSegy
.
jbsegy
,
currentSegy
.
xbsegy
);
//
console.log('[index2] 加载segy文件 Top/Bottom:', (currentSegy.jbsegyName || currentSegy.jbsegy), (currentSegy.xbsegyName || currentSegy.xbsegy));
//
console.log('[index2] segy文件路径 Top/Bottom:', currentSegy.jbsegy, currentSegy.xbsegy);
try
{
// 双图加载:jbsegy -> 顶部;xbsegy -> 底部
...
...
@@ -1059,7 +1093,7 @@ export default {
},
// 清空当前图表
clearCurrentPlots
()
{
console
.
log
(
'[index2] 清空当前图表'
);
//
console.log('[index2] 清空当前图表');
try
{
// 清空主图表
if
(
this
.
_seismicWidget
)
{
...
...
@@ -1078,7 +1112,7 @@ export default {
},
// 加载segy文件的具体实现
async
loadSegyFile
(
segyPath
)
{
console
.
log
(
'[index2] 开始加载segy文件:'
,
segyPath
);
//
console.log('[index2] 开始加载segy文件:', segyPath);
try
{
// 只显示主图表,隐藏底部图表
...
...
@@ -1092,7 +1126,7 @@ export default {
this
.
createScene
(
this
.
$refs
.
plot
);
}
console
.
log
(
'[index2] segy文件加载完成'
);
//
console.log('[index2] segy文件加载完成');
}
catch
(
error
)
{
console
.
error
(
'[index2] 加载segy文件时出错:'
,
error
);
...
...
@@ -1152,9 +1186,9 @@ export default {
const
url
=
this
.
buildSegyURL
(
segyPath
);
// 拉取二进制
console
.
log
(
'[index2] 即将拉取SEGY'
,
{
position
,
name
:
displayName
,
rawPath
:
segyPath
,
builtUrl
:
url
});
//
console.log('[index2] 即将拉取SEGY', { position, name: displayName, rawPath: segyPath, builtUrl: url });
const
blob
=
await
this
.
fetchSegyBlob
(
url
);
console
.
log
(
'[index2] 已获取SEGY二进制'
,
{
position
,
name
:
displayName
,
size
:
blob
&&
blob
.
size
,
type
:
blob
&&
blob
.
type
});
//
console.log('[index2] 已获取SEGY二进制', { position, name: displayName, size: blob && blob.size, type: blob && blob.type });
const
fileName
=
(
displayName
||
this
.
extractFileName
(
segyPath
)
||
'data.segy'
);
const
filesObj
=
new
File
([
blob
],
fileName
,
{
type
:
blob
.
type
||
'application/octet-stream'
,
lastModified
:
Date
.
now
()
});
const
file
=
new
LocalFile
(
filesObj
);
...
...
@@ -1272,7 +1306,7 @@ export default {
const
errors
=
[];
for
(
const
attempt
of
attempts
)
{
try
{
console
.
log
(
'[index2] fetchSegyBlob 尝试'
,
{
url
:
attempt
.
url
,
withAuth
:
!!
attempt
.
headers
});
//
console.log('[index2] fetchSegyBlob 尝试', { url: attempt.url, withAuth: !!attempt.headers });
const
res
=
await
fetch
(
attempt
.
url
,
attempt
.
headers
?
{
headers
:
attempt
.
headers
}
:
{});
if
(
!
res
.
ok
)
{
const
text
=
await
res
.
text
().
catch
(()
=>
''
);
...
...
@@ -1298,7 +1332,7 @@ export default {
},
// 显示单个图表(隐藏底部图表)
showSingleChart
()
{
console
.
log
(
'[index2] 切换到单图表显示模式'
);
//
console.log('[index2] 切换到单图表显示模式');
// 隐藏底部图表容器
const
bottomScroll
=
this
.
$refs
.
bottomScroll
;
...
...
@@ -1318,7 +1352,7 @@ export default {
},
// 显示双图表(恢复上下或左右布局)
showDualChart
()
{
console
.
log
(
'[index2] 切换到双图表显示模式'
);
//
console.log('[index2] 切换到双图表显示模式');
// 显示底部图表容器
const
bottomScroll
=
this
.
$refs
.
bottomScroll
;
...
...
@@ -1350,14 +1384,101 @@ export default {
this
.
plots
=
null
;
this
.
_seismicWidget
=
null
;
console
.
log
(
'[index2] 场景已清空'
);
//
console.log('[index2] 场景已清空');
}
catch
(
e
)
{
console
.
warn
(
'[index2] 清空场景时出错:'
,
e
);
}
},
handleThumbClick
()
{
// 如果正在拖动或拖动距离超过阈值,不触发点击事件
if
(
this
.
isDragging
||
this
.
dragDistance
>
this
.
dragThreshold
)
{
return
;
}
this
.
showThumbDialog
=
true
;
},
// 开始拖动
startDrag
(
event
)
{
// 只有点击拖动指示器或缩略图边缘才开始拖动
if
(
!
event
.
target
.
closest
(
'.drag-handle'
)
&&
!
event
.
target
.
closest
(
'.thumb-holder'
))
{
return
;
}
event
.
preventDefault
();
this
.
isDragging
=
false
;
// 初始状态不是拖动
this
.
dragDistance
=
0
;
this
.
dragStartX
=
event
.
clientX
;
this
.
dragStartY
=
event
.
clientY
;
// 添加全局事件监听
document
.
addEventListener
(
'mousemove'
,
this
.
onDrag
);
document
.
addEventListener
(
'mouseup'
,
this
.
stopDrag
);
},
// 拖动中
onDrag
(
event
)
{
event
.
preventDefault
();
const
deltaX
=
event
.
clientX
-
this
.
dragStartX
;
const
deltaY
=
event
.
clientY
-
this
.
dragStartY
;
this
.
dragDistance
=
Math
.
sqrt
(
deltaX
*
deltaX
+
deltaY
*
deltaY
);
// 只有拖动距离超过阈值才开始真正的拖动
if
(
this
.
dragDistance
>
this
.
dragThreshold
)
{
if
(
!
this
.
isDragging
)
{
this
.
isDragging
=
true
;
// 添加拖动样式
if
(
this
.
$refs
.
thumbContainer
)
{
this
.
$refs
.
thumbContainer
.
style
.
cursor
=
'grabbing'
;
}
}
// 获取当前缩略图的位置
const
currentTop
=
parseInt
(
this
.
thumbPosition
.
top
)
||
150
;
const
currentRight
=
parseInt
(
this
.
thumbPosition
.
right
)
||
20
;
// 计算新位置
let
newTop
=
currentTop
+
deltaY
;
let
newRight
=
currentRight
-
deltaX
;
// 边界检查
const
windowWidth
=
window
.
innerWidth
;
const
windowHeight
=
window
.
innerHeight
;
const
thumbWidth
=
260
;
const
thumbHeight
=
160
;
// 限制在窗口范围内
newTop
=
Math
.
max
(
0
,
Math
.
min
(
newTop
,
windowHeight
-
thumbHeight
));
newRight
=
Math
.
max
(
0
,
Math
.
min
(
newRight
,
windowWidth
-
thumbWidth
));
// 更新位置
this
.
thumbPosition
=
{
top
:
newTop
+
'px'
,
right
:
newRight
+
'px'
,
left
:
'auto'
,
bottom
:
'auto'
};
// 更新起始位置
this
.
dragStartX
=
event
.
clientX
;
this
.
dragStartY
=
event
.
clientY
;
}
},
// 停止拖动
stopDrag
()
{
// 移除全局事件监听
document
.
removeEventListener
(
'mousemove'
,
this
.
onDrag
);
document
.
removeEventListener
(
'mouseup'
,
this
.
stopDrag
);
// 恢复样式
if
(
this
.
$refs
.
thumbContainer
)
{
this
.
$refs
.
thumbContainer
.
style
.
cursor
=
'grab'
;
}
// 延迟重置拖动状态,避免立即触发点击事件
setTimeout
(()
=>
{
this
.
isDragging
=
false
;
this
.
dragDistance
=
0
;
},
100
);
},
// 处理缩略图(绿色线)点击/双击事件
onThumbLinePick
(
payload
)
{
try
{
...
...
@@ -1385,7 +1506,7 @@ export default {
},
// 测试缩略图方法
testThumb
()
{
console
.
log
(
'[index2] ===== testThumb START ====='
);
//
console.log('[index2] ===== testThumb START =====');
// 创建完全独立的测试容器
let
testContainer
=
document
.
getElementById
(
'thumb-test-container'
);
...
...
@@ -1414,13 +1535,13 @@ export default {
document
.
body
.
appendChild
(
testContainer
);
console
.
log
(
'[index2] testThumb: independent container created'
);
console
.
log
(
'[index2] testContainer size:'
,
testContainer
.
clientWidth
,
'x'
,
testContainer
.
clientHeight
);
console
.
log
(
'[index2] ===== testThumb END ====='
);
//
console.log('[index2] testThumb: independent container created');
//
console.log('[index2] testContainer size:', testContainer.clientWidth, 'x', testContainer.clientHeight);
//
console.log('[index2] ===== testThumb END =====');
},
// 测试ECharts方法
testECharts
()
{
console
.
log
(
'[index2] ===== testECharts START ====='
);
//
console.log('[index2] ===== testECharts START =====');
// 清理现有容器
let
chartContainer
=
document
.
getElementById
(
'thumb-chart-container'
);
...
...
@@ -1452,7 +1573,7 @@ export default {
`
);
// 验证样式是否应用
console
.
log
(
'[index2] Chart container style after setAttribute:'
,
chartContainer
.
style
.
position
);
//
console.log('[index2] Chart container style after setAttribute:', chartContainer.style.position);
// 创建ECharts实例
if
(
this
.
thumbChart
)
{
...
...
@@ -1498,19 +1619,19 @@ export default {
};
this
.
thumbChart
.
setOption
(
testOption
,
true
);
console
.
log
(
'[index2] ECharts test chart created'
);
console
.
log
(
'[index2] ===== testECharts END ====='
);
//
console.log('[index2] ECharts test chart created');
//
console.log('[index2] ===== testECharts END =====');
},
// 测试按钮点击
testButtonClick
()
{
console
.
log
(
'[index2] ===== testButtonClick START ====='
);
//
console.log('[index2] ===== testButtonClick START =====');
alert
(
'按钮点击测试成功!'
);
console
.
log
(
'[index2] ===== testButtonClick END ====='
);
//
console.log('[index2] ===== testButtonClick END =====');
},
// 创建超级明显的缩略图测试
createSuperVisibleThumb
()
{
console
.
log
(
'[index2] ===== createSuperVisibleThumb START ====='
);
//
console.log('[index2] ===== createSuperVisibleThumb START =====');
// 清理现有容器
let
container
=
document
.
getElementById
(
'super-visible-thumb'
);
...
...
@@ -1554,12 +1675,12 @@ export default {
</div>
`
;
console
.
log
(
'[index2] Super visible container created'
);
console
.
log
(
'[index2] Container position:'
,
container
.
getBoundingClientRect
());
//
console.log('[index2] Super visible container created');
//
console.log('[index2] Container position:', container.getBoundingClientRect());
// 1秒后创建ECharts
setTimeout
(()
=>
{
console
.
log
(
'[index2] Starting ECharts creation...'
);
//
console.log('[index2] Starting ECharts creation...');
// 清理文字,准备ECharts
container
.
innerHTML
=
''
;
...
...
@@ -1576,16 +1697,16 @@ export default {
box-shadow: 0 0 20px rgba(0,0,255,0.8) !important;
`
;
console
.
log
(
'[index2] Container cleared and styled for ECharts'
);
console
.
log
(
'[index2] Container position after styling:'
,
container
.
getBoundingClientRect
());
//
console.log('[index2] Container cleared and styled for ECharts');
//
console.log('[index2] Container position after styling:', container.getBoundingClientRect());
// 创建ECharts
if
(
this
.
thumbChart
)
{
try
{
this
.
thumbChart
.
dispose
();
console
.
log
(
'[index2] Previous chart disposed'
);
//
console.log('[index2] Previous chart disposed');
}
catch
(
e
)
{
console
.
log
(
'[index2] Error disposing previous chart:'
,
e
);
//
console.log('[index2] Error disposing previous chart:', e);
}
}
...
...
@@ -1594,7 +1715,7 @@ export default {
width
:
300
,
height
:
200
});
console
.
log
(
'[index2] ECharts instance created:'
,
this
.
thumbChart
);
//
console.log('[index2] ECharts instance created:', this.thumbChart);
}
catch
(
e
)
{
console
.
error
(
'[index2] Error creating ECharts instance:'
,
e
);
return
;
...
...
@@ -1635,13 +1756,13 @@ export default {
try
{
this
.
thumbChart
.
setOption
(
option
,
true
);
console
.
log
(
'[index2] ECharts option set successfully'
);
//
console.log('[index2] ECharts option set successfully');
// 强制渲染
setTimeout
(()
=>
{
if
(
this
.
thumbChart
)
{
this
.
thumbChart
.
resize
();
console
.
log
(
'[index2] ECharts resized'
);
//
console.log('[index2] ECharts resized');
}
},
100
);
...
...
@@ -1649,33 +1770,33 @@ export default {
console
.
error
(
'[index2] Error setting ECharts option:'
,
e
);
}
console
.
log
(
'[index2] ECharts creation completed'
);
//
console.log('[index2] ECharts creation completed');
},
1000
);
console
.
log
(
'[index2] ===== createSuperVisibleThumb END ====='
);
//
console.log('[index2] ===== createSuperVisibleThumb END =====');
},
// 重置缩略图方法
resetThumb
()
{
console
.
log
(
'[index2] ===== resetThumb START ====='
);
//
console.log('[index2] ===== resetThumb START =====');
// 清理独立容器
const
testContainer
=
document
.
getElementById
(
'thumb-test-container'
);
if
(
testContainer
)
{
testContainer
.
remove
();
console
.
log
(
'[index2] test container removed'
);
//
console.log('[index2] test container removed');
}
const
chartContainer
=
document
.
getElementById
(
'thumb-chart-container'
);
if
(
chartContainer
)
{
chartContainer
.
remove
();
console
.
log
(
'[index2] chart container removed'
);
//
console.log('[index2] chart container removed');
}
const
superVisibleContainer
=
document
.
getElementById
(
'super-visible-thumb'
);
if
(
superVisibleContainer
)
{
superVisibleContainer
.
remove
();
console
.
log
(
'[index2] super visible container removed'
);
//
console.log('[index2] super visible container removed');
}
// 清理ECharts实例
...
...
@@ -1683,7 +1804,7 @@ export default {
try
{
this
.
thumbChart
.
dispose
();
this
.
thumbChart
=
null
;
console
.
log
(
'[index2] ECharts instance disposed'
);
//
console.log('[index2] ECharts instance disposed');
}
catch
(
e
)
{
console
.
warn
(
'[index2] Error disposing ECharts:'
,
e
);
}
...
...
@@ -1694,15 +1815,15 @@ export default {
if
(
holder
)
{
holder
.
innerHTML
=
''
;
holder
.
className
=
'thumb-holder'
;
console
.
log
(
'[index2] original container reset'
);
//
console.log('[index2] original container reset');
}
console
.
log
(
'[index2] resetThumb: all containers cleaned up'
);
console
.
log
(
'[index2] ===== resetThumb END ====='
);
//
console.log('[index2] resetThumb: all containers cleaned up');
//
console.log('[index2] ===== resetThumb END =====');
},
// 备用缩略图初始化方法
async
initThumbFallback
()
{
console
.
log
(
'[index2] ===== initThumbFallback START ====='
);
//
console.log('[index2] ===== initThumbFallback START =====');
try
{
// 创建完全独立的ECharts容器
let
chartContainer
=
document
.
getElementById
(
'thumb-chart-container'
);
...
...
@@ -1734,7 +1855,7 @@ export default {
`
);
// 验证样式是否应用
console
.
log
(
'[index2] Test chart container style after setAttribute:'
,
chartContainer
.
style
.
position
);
//
console.log('[index2] Test chart container style after setAttribute:', chartContainer.style.position);
// 创建ECharts实例
if
(
this
.
thumbChart
)
{
...
...
@@ -1788,32 +1909,32 @@ export default {
};
this
.
thumbChart
.
setOption
(
simpleOption
,
true
);
console
.
log
(
'[index2] Simple chart displayed'
);
//
console.log('[index2] Simple chart displayed');
// 检查容器状态
console
.
log
(
'[index2] Chart container position:'
,
chartContainer
.
getBoundingClientRect
());
console
.
log
(
'[index2] Chart container style:'
,
{
position
:
chartContainer
.
style
.
position
,
top
:
chartContainer
.
style
.
top
,
right
:
chartContainer
.
style
.
right
,
width
:
chartContainer
.
style
.
width
,
height
:
chartContainer
.
style
.
height
,
zIndex
:
chartContainer
.
style
.
zIndex
,
display
:
chartContainer
.
style
.
display
,
visibility
:
chartContainer
.
style
.
visibility
});
//
console.log('[index2] Chart container position:', chartContainer.getBoundingClientRect());
//
console.log('[index2] Chart container style:', {
//
position: chartContainer.style.position,
//
top: chartContainer.style.top,
//
right: chartContainer.style.right,
//
width: chartContainer.style.width,
//
height: chartContainer.style.height,
//
zIndex: chartContainer.style.zIndex,
//
display: chartContainer.style.display,
//
visibility: chartContainer.style.visibility
//
});
// 然后加载真实数据
await
this
.
loadThumbData
();
console
.
log
(
'[index2] Data loaded, rendering real chart...'
);
//
console.log('[index2] Data loaded, rendering real chart...');
this
.
renderThumb
();
console
.
log
(
'[index2] Fallback chart initialized successfully in independent container'
);
//
console.log('[index2] Fallback chart initialized successfully in independent container');
}
catch
(
e
)
{
console
.
error
(
'[index2] initThumbFallback failed:'
,
e
);
}
console
.
log
(
'[index2] ===== initThumbFallback END ====='
);
//
console.log('[index2] ===== initThumbFallback END =====');
},
async
loadThumbData
()
{
try
{
...
...
@@ -1823,11 +1944,11 @@ export default {
const
query
=
route
.
query
||
{};
const
id
=
params
.
zbid
||
query
.
zbid
||
params
.
id
||
query
.
id
;
this
.
thumbId
=
id
||
null
;
console
.
log
(
'[index2] loadThumbData id:'
,
id
);
//
console.log('[index2] loadThumbData id:', id);
// 如果没有id,使用测试数据
if
(
!
id
)
{
console
.
log
(
'[index2] No id found, using test data for thumbnail'
);
//
console.log('[index2] No id found, using test data for thumbnail');
this
.
thumbPoints
=
[
{
name
:
'测试点1'
,
x
:
10
,
y
:
20
},
{
name
:
'测试点2'
,
x
:
30
,
y
:
40
},
...
...
@@ -1841,19 +1962,19 @@ export default {
}
const
res
=
await
toDht
(
id
);
const
data
=
(
res
&&
(
res
.
data
!==
undefined
?
res
.
data
:
res
))
||
{};
console
.
log
(
'[index2] loadThumbData res:'
,
data
);
console
.
log
(
'[index2] data keys:'
,
Object
.
keys
(
data
));
//
console.log('[index2] loadThumbData res:', data);
//
console.log('[index2] data keys:', Object.keys(data));
// 井点
const
list
=
Array
.
isArray
(
data
.
ysqqXmxxJxxList
)
?
data
.
ysqqXmxxJxxList
:
[];
console
.
log
(
'[index2] jxxList length:'
,
list
.
length
);
console
.
log
(
'[index2] jxxList sample:'
,
list
.
slice
(
0
,
2
));
//
console.log('[index2] jxxList length:', list.length);
//
console.log('[index2] jxxList sample:', list.slice(0, 2));
this
.
thumbPoints
=
list
.
filter
(
it
=>
it
&&
it
.
x
!=
null
&&
it
.
y
!=
null
)
.
map
(
it
=>
({
name
:
String
(
it
.
jh
||
''
),
x
:
Number
(
it
.
x
),
y
:
Number
(
it
.
y
)
}));
console
.
log
(
'[index2] thumbPoints:'
,
this
.
thumbPoints
.
length
);
console
.
log
(
'[index2] thumbPoints sample:'
,
this
.
thumbPoints
.
slice
(
0
,
2
));
//
console.log('[index2] thumbPoints:', this.thumbPoints.length);
//
console.log('[index2] thumbPoints sample:', this.thumbPoints.slice(0, 2));
// 线(SEGY)
// 兼容两种返回结构:
// 1) { ysqqXmxxSegy: [...] }
...
...
@@ -1862,13 +1983,13 @@ export default {
?
data
.
ysqqXmxxSegy
:
(
Array
.
isArray
(
data
)
?
data
:
[]);
if
(
!
Array
.
isArray
(
data
.
ysqqXmxxSegy
)
&&
Array
.
isArray
(
data
))
{
console
.
log
(
'[index2] ysqqXmxxSegy not found, using top-level array as segy list'
);
//
console.log('[index2] ysqqXmxxSegy not found, using top-level array as segy list');
}
// 存储完整的segy数据列表
this
.
segyList
=
segys
;
this
.
currentSegyIndex
=
0
;
// 重置为第一个
console
.
log
(
'[index2] segyList length:'
,
this
.
segyList
.
length
);
console
.
log
(
'[index2] segyList sample:'
,
this
.
segyList
.
slice
(
0
,
2
));
//
console.log('[index2] segyList length:', this.segyList.length);
//
console.log('[index2] segyList sample:', this.segyList.slice(0, 2));
this
.
thumbLines
=
segys
.
map
(
seg
=>
{
try
{
...
...
@@ -1882,7 +2003,7 @@ export default {
return
ordered
.
map
(
p
=>
[
p
.
x
,
p
.
y
]);
}
catch
(
e
)
{
return
[];
}
}).
filter
(
line
=>
line
.
length
>
0
);
console
.
log
(
'[index2] thumbLines:'
,
this
.
thumbLines
.
length
);
//
console.log('[index2] thumbLines:', this.thumbLines.length);
// 边界
const
xs
=
[];
const
ys
=
[];
...
...
@@ -1893,11 +2014,11 @@ export default {
const
yMin
=
ys
.
length
?
Math
.
min
(...
ys
)
:
null
;
const
yMax
=
ys
.
length
?
Math
.
max
(...
ys
)
:
null
;
this
.
thumbBounds
=
{
xMin
,
xMax
,
yMin
,
yMax
};
console
.
log
(
'[index2] thumbBounds:'
,
this
.
thumbBounds
);
//
console.log('[index2] thumbBounds:', this.thumbBounds);
// 如果没有数据,添加测试数据来验证图表显示
if
(
this
.
thumbPoints
.
length
===
0
&&
this
.
thumbLines
.
length
===
0
)
{
console
.
log
(
'[index2] 没有数据,添加测试数据'
);
//
console.log('[index2] 没有数据,添加测试数据');
this
.
thumbPoints
=
[
{
name
:
'测试井1'
,
x
:
100
,
y
:
200
},
{
name
:
'测试井2'
,
x
:
200
,
y
:
300
},
...
...
@@ -1907,7 +2028,7 @@ export default {
[[
100
,
200
],
[
150
,
250
],
[
200
,
300
],
[
250
,
280
],
[
300
,
150
]]
];
this
.
thumbBounds
=
{
xMin
:
100
,
xMax
:
300
,
yMin
:
150
,
yMax
:
300
};
console
.
log
(
'[index2] 测试数据添加完成:'
,
this
.
thumbPoints
.
length
,
'points,'
,
this
.
thumbLines
.
length
,
'lines'
);
//
console.log('[index2] 测试数据添加完成:', this.thumbPoints.length, 'points,', this.thumbLines.length, 'lines');
}
}
catch
(
e
)
{
console
.
warn
(
'[index2] loadThumbData failed:'
,
e
);
...
...
@@ -1944,8 +2065,8 @@ export default {
yMax
:
yMax
!==
null
&&
yMax
!==
undefined
?
yMax
:
defaultRange
.
yMax
};
console
.
log
(
'[index2] buildThumbOption range:'
,
range
);
console
.
log
(
'[index2] buildThumbOption series count:'
,
series
.
length
);
//
console.log('[index2] buildThumbOption range:', range);
//
console.log('[index2] buildThumbOption series count:', series.length);
// 将数据归一化到 0~100 区间,保证在小图中清晰
const
dx
=
Math
.
max
(
1
e
-
9
,
range
.
xMax
-
range
.
xMin
);
...
...
@@ -2021,18 +2142,18 @@ export default {
console
.
warn
(
'[index2] renderThumb: no chart instance'
);
return
;
}
console
.
log
(
'[index2] renderThumb: points'
,
this
.
thumbPoints
.
length
,
'lines'
,
this
.
thumbLines
.
length
);
//
console.log('[index2] renderThumb: points', this.thumbPoints.length, 'lines', this.thumbLines.length);
try
{
const
option
=
this
.
buildThumbOption
();
console
.
log
(
'[index2] renderThumb option:'
,
option
);
//
console.log('[index2] renderThumb option:', option);
this
.
thumbChart
.
setOption
(
option
,
true
);
// 强制重新渲染
setTimeout
(()
=>
{
if
(
this
.
thumbChart
)
{
this
.
thumbChart
.
resize
();
console
.
log
(
'[index2] renderThumb: chart resized after render'
);
//
console.log('[index2] renderThumb: chart resized after render');
}
},
100
);
}
catch
(
e
)
{
...
...
@@ -2050,10 +2171,10 @@ export default {
// 强制设置初始状态,确保不显示滚动条
if
(
this
.
_isInitialLoad
)
{
console
.
log
(
'强制设置初始尺寸,不显示滚动条:'
,
{
width
:
this
.
baseCanvasWidth
,
height
:
this
.
baseCanvasHeight
});
//
console.log('强制设置初始尺寸,不显示滚动条:', {
//
width: this.baseCanvasWidth,
//
height: this.baseCanvasHeight
//
});
}
}
}
catch
(
e
)
{
/* ignore */
}
...
...
@@ -2087,11 +2208,11 @@ export default {
if
(
isInitialState
||
this
.
_isInitialLoad
)
{
this
.
baseCanvasWidth
=
containerWidth
;
this
.
baseCanvasHeight
=
containerHeight
;
console
.
log
(
'初始状态,保持容器尺寸:'
,
{
containerSize
:
{
width
:
containerWidth
,
height
:
containerHeight
},
viewSize
:
{
width
:
viewWidth
,
height
:
viewHeight
},
isInitialLoad
:
this
.
_isInitialLoad
});
//
console.log('初始状态,保持容器尺寸:', {
//
containerSize: { width: containerWidth, height: containerHeight },
//
viewSize: { width: viewWidth, height: viewHeight },
//
isInitialLoad: this._isInitialLoad
//
});
return
;
}
...
...
@@ -2112,20 +2233,20 @@ export default {
this
.
baseCanvasWidth
=
scrollWidth
;
this
.
baseCanvasHeight
=
scrollHeight
;
console
.
log
(
'用户缩放后更新滚动区域尺寸:'
,
{
containerSize
:
{
width
:
containerWidth
,
height
:
containerHeight
},
currentLimits
:
{
width
:
viewWidth
,
height
:
viewHeight
,
left
:
currentLimits
.
getLeft
(),
right
:
currentLimits
.
getRight
(),
top
:
currentLimits
.
getTop
(),
bottom
:
currentLimits
.
getBottom
()
},
scaleX
,
scaleY
,
newScrollWidth
:
scrollWidth
,
newScrollHeight
:
scrollHeight
});
//
console.log('用户缩放后更新滚动区域尺寸:', {
//
containerSize: { width: containerWidth, height: containerHeight },
//
currentLimits: {
//
width: viewWidth,
//
height: viewHeight,
//
left: currentLimits.getLeft(),
//
right: currentLimits.getRight(),
//
top: currentLimits.getTop(),
//
bottom: currentLimits.getBottom()
//
},
//
scaleX, scaleY,
//
newScrollWidth: scrollWidth,
//
newScrollHeight: scrollHeight
//
});
}
}
}
catch
(
e
)
{
...
...
@@ -2158,29 +2279,29 @@ export default {
// 方法1: 禁用滚动交互
if
(
widget
.
setScrollEnabled
)
{
widget
.
setScrollEnabled
(
false
);
console
.
log
(
'已禁用widget滚动交互'
);
//
console.log('已禁用widget滚动交互');
}
// 方法2: 禁用所有鼠标交互
if
(
widget
.
setMouseInteractionsEnabled
)
{
widget
.
setMouseInteractionsEnabled
(
false
);
console
.
log
(
'已禁用widget鼠标交互'
);
//
console.log('已禁用widget鼠标交互');
}
// 尝试其他可能的交互禁用方法
if
(
widget
.
setInteractionsEnabled
)
{
widget
.
setInteractionsEnabled
(
false
);
console
.
log
(
'已禁用widget交互'
);
//
console.log('已禁用widget交互');
}
if
(
widget
.
setWheelEnabled
)
{
widget
.
setWheelEnabled
(
false
);
console
.
log
(
'已禁用widget滚轮交互'
);
//
console.log('已禁用widget滚轮交互');
}
if
(
widget
.
setPanEnabled
)
{
widget
.
setPanEnabled
(
false
);
console
.
log
(
'已禁用widget平移交互'
);
//
console.log('已禁用widget平移交互');
}
// 方法3: 通过setOptions禁用
...
...
@@ -2314,10 +2435,10 @@ export default {
this
.
baseCanvasHeight
=
rect
.
height
;
this
.
_isInitialLoad
=
true
;
console
.
log
(
'强制重置到初始状态:'
,
{
width
:
this
.
baseCanvasWidth
,
height
:
this
.
baseCanvasHeight
});
//
console.log('强制重置到初始状态:', {
//
width: this.baseCanvasWidth,
//
height: this.baseCanvasHeight
//
});
}
}
catch
(
e
)
{
console
.
warn
(
'重置初始状态失败:'
,
e
);
...
...
@@ -2577,7 +2698,7 @@ export default {
}
catch
(
e
)
{
}
},
100
);
console
.
log
(
'内部滚动条已强制禁用'
);
//
console.log('内部滚动条已强制禁用');
}
catch
(
error
)
{
console
.
warn
(
'禁用内部滚动条时出错:'
,
error
);
}
...
...
@@ -2620,7 +2741,7 @@ export default {
}
});
console
.
log
(
'滚动条监控已执行一次'
);
//
console.log('滚动条监控已执行一次');
}
catch
(
e
)
{
console
.
warn
(
'滚动条监控失败:'
,
e
);
}
...
...
@@ -2738,7 +2859,7 @@ export default {
].
join
(
'
\
n'
);
widget
.
setCss
(
css
);
console
.
log
(
'已通过CSS方法彻底禁用内部滚动条'
);
//
console.log('已通过CSS方法彻底禁用内部滚动条');
}
catch
(
error
)
{
console
.
warn
(
'设置滚动条CSS失败:'
,
error
);
}
...
...
@@ -2757,7 +2878,7 @@ export default {
this
.
setupOuterScrollbarSync
();
// 启动外层滚动条同步监控
this
.
startOuterScrollbarSyncMonitor
();
console
.
log
(
'已彻底禁用内部滚动条并启用外层滚动条同步'
)
//
console.log('已彻底禁用内部滚动条并启用外层滚动条同步')
}
catch
(
error
)
{
console
.
warn
(
'启用外层滚动条同步失败:'
,
error
);
}
...
...
@@ -2829,7 +2950,7 @@ export default {
bottomContainer
.
addEventListener
(
'scroll'
,
this
.
_syncFromBottomOuter
);
this
.
_outerScrollListeners
.
push
({
element
:
bottomContainer
,
event
:
'scroll'
,
handler
:
this
.
_syncFromBottomOuter
});
console
.
log
(
'外层滚动条同步已设置(GeoToolkit 3.2.80兼容模式)'
);
//
console.log('外层滚动条同步已设置(GeoToolkit 3.2.80兼容模式)');
}
catch
(
error
)
{
console
.
warn
(
'设置外层滚动条同步失败:'
,
error
);
}
...
...
@@ -2875,7 +2996,7 @@ export default {
const
bottomScrollbars
=
this
.
findScrollbarElements
(
this
.
_seismicWidgetBottom
);
if
(
topScrollbars
.
length
===
0
||
bottomScrollbars
.
length
===
0
)
{
console
.
log
(
'未找到滚动条DOM元素,跳过DOM同步'
);
//
console.log('未找到滚动条DOM元素,跳过DOM同步');
return
;
}
...
...
@@ -2929,7 +3050,7 @@ export default {
this
.
_domScrollListeners
.
push
({
element
:
scrollbar
,
event
:
'scroll'
,
handler
:
onBottomScroll
});
});
console
.
log
(
'DOM级别滚动条同步已设置'
);
//
console.log('DOM级别滚动条同步已设置');
}
catch
(
e
)
{
console
.
warn
(
'设置DOM滚动条同步失败:'
,
e
);
}
...
...
@@ -3118,7 +3239,7 @@ export default {
// 方法4: (禁用)不再启动强力隐藏监控
// this.startAggressiveScrollbarHideMonitor();
console
.
log
(
'已强制隐藏所有内部滚动条'
);
//
console.log('已强制隐藏所有内部滚动条');
}
catch
(
e
)
{
console
.
warn
(
'强制隐藏内部滚动条失败:'
,
e
);
}
...
...
@@ -3139,7 +3260,7 @@ export default {
// 禁用滚动条交互
this
.
disableScrollbarInteractions
();
console
.
log
(
'滚动条隐藏监控已执行一次'
);
//
console.log('滚动条隐藏监控已执行一次');
}
catch
(
e
)
{
console
.
warn
(
'滚动条隐藏监控失败:'
,
e
);
}
...
...
@@ -3196,18 +3317,18 @@ export default {
// 测试外层滚动条同步(GeoToolkit 3.2.80兼容)
testOuterScrollbarSync
()
{
try
{
console
.
log
(
'=== 测试外层滚动条同步 ==='
);
//
console.log('=== 测试外层滚动条同步 ===');
// 获取外层滚动容器
const
topContainer
=
this
.
getOuterScrollContainer
(
this
.
_seismicWidget
);
const
bottomContainer
=
this
.
getOuterScrollContainer
(
this
.
_seismicWidgetBottom
);
console
.
log
(
'顶部容器:'
,
topContainer
);
console
.
log
(
'底部容器:'
,
bottomContainer
);
//
console.log('顶部容器:', topContainer);
//
console.log('底部容器:', bottomContainer);
if
(
topContainer
&&
bottomContainer
)
{
console
.
log
(
'顶部容器滚动位置:'
,
{
scrollLeft
:
topContainer
.
scrollLeft
,
scrollTop
:
topContainer
.
scrollTop
});
console
.
log
(
'底部容器滚动位置:'
,
{
scrollLeft
:
bottomContainer
.
scrollLeft
,
scrollTop
:
bottomContainer
.
scrollTop
});
//
console.log('顶部容器滚动位置:', { scrollLeft: topContainer.scrollLeft, scrollTop: topContainer.scrollTop });
//
console.log('底部容器滚动位置:', { scrollLeft: bottomContainer.scrollLeft, scrollTop: bottomContainer.scrollTop });
// 测试同步
const
testScrollLeft
=
100
;
...
...
@@ -3216,23 +3337,23 @@ export default {
topContainer
.
scrollLeft
=
testScrollLeft
;
topContainer
.
scrollTop
=
testScrollTop
;
console
.
log
(
'设置顶部容器滚动位置:'
,
{
scrollLeft
:
testScrollLeft
,
scrollTop
:
testScrollTop
});
//
console.log('设置顶部容器滚动位置:', { scrollLeft: testScrollLeft, scrollTop: testScrollTop });
// 检查同步是否生效
setTimeout
(()
=>
{
console
.
log
(
'同步后底部容器滚动位置:'
,
{
scrollLeft
:
bottomContainer
.
scrollLeft
,
scrollTop
:
bottomContainer
.
scrollTop
});
//
console.log('同步后底部容器滚动位置:', {
//
scrollLeft: bottomContainer.scrollLeft,
//
scrollTop: bottomContainer.scrollTop
//
});
if
(
bottomContainer
.
scrollLeft
===
testScrollLeft
&&
bottomContainer
.
scrollTop
===
testScrollTop
)
{
console
.
log
(
'✅ 外层滚动条同步测试成功!'
);
//
console.log('✅ 外层滚动条同步测试成功!');
}
else
{
console
.
log
(
'❌ 外层滚动条同步测试失败!'
);
//
console.log('❌ 外层滚动条同步测试失败!');
}
},
100
);
}
else
{
console
.
log
(
'❌ 未找到外层滚动容器'
);
//
console.log('❌ 未找到外层滚动容器');
}
}
catch
(
e
)
{
console
.
error
(
'测试外层滚动条同步失败:'
,
e
);
...
...
@@ -3242,7 +3363,7 @@ export default {
// 测试内部滚动条是否被隐藏
testInternalScrollbarHidden
()
{
try
{
console
.
log
(
'=== 测试内部滚动条是否被隐藏 ==='
);
//
console.log('=== 测试内部滚动条是否被隐藏 ===');
// 查找所有可能的滚动条元素
const
scrollbarSelectors
=
[
...
...
@@ -3271,14 +3392,14 @@ export default {
});
if
(
foundScrollbars
.
length
===
0
)
{
console
.
log
(
'✅ 未找到任何可见的内部滚动条!'
);
//
console.log('✅ 未找到任何可见的内部滚动条!');
}
else
{
console
.
log
(
'❌ 发现以下可见的内部滚动条:'
);
//
console.log('❌ 发现以下可见的内部滚动条:');
foundScrollbars
.
forEach
((
item
,
index
)
=>
{
console
.
log
(
`
${
index
+
1
}
. 选择器:
${
item
.
selector
}
`
);
console
.
log
(
` 可见性:
${
item
.
visible
?
'可见'
:
'隐藏'
}
`
);
console
.
log
(
` 尺寸:
${
item
.
dimensions
.
width
}
x
${
item
.
dimensions
.
height
}
`
);
console
.
log
(
` 元素:`
,
item
.
element
);
//
console.log(`${index + 1}. 选择器: ${item.selector}`);
//
console.log(` 可见性: ${item.visible ? '可见' : '隐藏'}`);
//
console.log(` 尺寸: ${item.dimensions.width}x${item.dimensions.height}`);
//
console.log(` 元素:`, item.element);
});
// 尝试强制隐藏这些滚动条
...
...
@@ -3286,7 +3407,7 @@ export default {
this
.
hideScrollbarElement
(
item
.
element
);
});
console
.
log
(
'已尝试强制隐藏发现的滚动条'
);
//
console.log('已尝试强制隐藏发现的滚动条');
}
}
catch
(
e
)
{
console
.
error
(
'测试内部滚动条隐藏失败:'
,
e
);
...
...
@@ -3341,7 +3462,7 @@ export default {
// 方法3: 通过CSS强制隐藏
this
.
addForceHideScrollbarCSS
();
console
.
log
(
'已强制禁用内部滚动条'
);
//
console.log('已强制禁用内部滚动条');
}
catch
(
error
)
{
console
.
warn
(
'强制禁用内部滚动条失败:'
,
error
);
}
...
...
@@ -3487,7 +3608,7 @@ export default {
// 不再注入全局隐藏滚动条CSS,避免影响布局
// this.addGlobalScrollbarHideCSS();
console
.
log
(
'已强制禁用所有内部滚动条'
);
//
console.log('已强制禁用所有内部滚动条');
}
catch
(
e
)
{
console
.
warn
(
'强制禁用滚动条失败:'
,
e
);
}
...
...
@@ -3695,7 +3816,7 @@ export default {
setTimeout
(()
=>
{
// 只在用户主动操作后才更新滚动区域
// 初始加载时不调用 updateScrollAreaSize
console
.
log
(
'数据加载完成,保持初始尺寸'
);
//
console.log('数据加载完成,保持初始尺寸');
},
1000
);
// 强制禁用内部滚动条
this
.
forceDisableInternalScrollbars
(
this
.
_seismicWidget
);
...
...
@@ -3721,9 +3842,43 @@ export default {
}
},
handleFileSelect
(
plot
)
{
let
url
=
process
.
env
.
VUE_APP_BASE_API
+
"/ndy/dz/getSegyDataFile?fileName=density.segy"
;
let
fileName
=
'density.segy'
;
async
handleFileSelect
(
plot
)
{
let
segys
=
[];
try
{
// 使用 toDht 接口获取数据
//console.log('[handleFileSelect] 开始获取数据,routeId:', this.routeId);
const
res
=
await
toDht
(
this
.
routeId
);
console
.
log
(
'[handleFileSelect] toDht 接口返回:'
,
res
);
const
data
=
(
res
&&
(
res
.
data
!==
undefined
?
res
.
data
:
res
))
||
{};
console
.
log
(
'[handleFileSelect] 解析后的数据:'
,
data
);
// 从 ysqqXmxxSegy 数组中获取 jbsegy 字段
segys
=
Array
.
isArray
(
data
.
ysqqXmxxSegy
)
?
data
.
ysqqXmxxSegy
:
[];
console
.
log
(
'[handleFileSelect] ysqqXmxxSegy 数组:'
,
segys
);
if
(
segys
.
length
===
0
)
{
throw
new
Error
(
'未找到 SEGY 数据'
);
}
}
catch
(
error
)
{
console
.
error
(
'[handleFileSelect] 获取数据失败:'
,
error
);
this
.
loadingError
=
`获取数据失败:
${
error
.
message
}
`
;
throw
error
;
}
// 使用第一个 SEGY 数据的 jbsegy 字段
const
firstSegy
=
segys
[
0
];
console
.
log
(
'[handleFileSelect] 第一个 SEGY 数据:'
,
firstSegy
);
let
url
=
firstSegy
.
jbsegy
;
if
(
url
&&
!
url
.
startsWith
(
'http'
))
{
url
=
process
.
env
.
VUE_APP_BASE_API
+
url
;
}
let
fileName
=
firstSegy
.
jbsegyName
||
'density.segy'
;
console
.
log
(
'[handleFileSelect] 最终 URL:'
,
url
);
console
.
log
(
'[handleFileSelect] 文件名:'
,
fileName
);
return
fetch
(
url
,
{
headers
:
{
...
...
@@ -3858,7 +4013,7 @@ export default {
// 延迟调用fitToBounds,确保初始状态稳定
setTimeout
(()
=>
{
this
.
_seismicWidget
.
fitToBounds
();
console
.
log
(
'数据加载完成,调用fitToBounds'
);
//
console.log('数据加载完成,调用fitToBounds');
// 再次确保内部滚动条被禁用
this
.
setScrollbarCSS
(
this
.
_seismicWidget
);
...
...
@@ -3867,7 +4022,7 @@ export default {
// 再延迟标记初始加载结束
setTimeout
(()
=>
{
this
.
_isInitialLoad
=
false
;
console
.
log
(
'初始加载完成,启用滚动区域更新'
);
//
console.log('初始加载完成,启用滚动区域更新');
// 最终确认内部滚动条被禁用
this
.
setScrollbarCSS
(
this
.
_seismicWidget
);
...
...
@@ -3997,10 +4152,10 @@ export default {
const
node
=
command
.
getNode
();
if
(
node
)
{
this
.
annotations
.
addChild
(
node
);
console
.
log
(
'开始编辑:'
,
{
type
:
node
.
getType
?
node
.
getType
()
:
'未知类型'
,
properties
:
node
.
getProperties
()
});
//
console.log('开始编辑:', {
//
type: node.getType ? node.getType() : '未知类型',
//
properties: node.getProperties()
//
});
}
})
.
addListener
(
EditEvents
.
End
,
(
tool
,
node
)
=>
{
...
...
@@ -4009,10 +4164,10 @@ export default {
tool
.
editNode
(
node
);
this
.
selectedShape
=
node
;
this
.
saveAnnotation
(
node
);
console
.
log
(
'编辑完成:'
,
{
type
:
node
.
getType
?
node
.
getType
()
:
'未知类型'
,
properties
:
node
.
getProperties
()
});
//
console.log('编辑完成:', {
//
type: node.getType ? node.getType() : '未知类型',
//
properties: node.getProperties()
//
});
}
this
.
requestRepaint
();
});
...
...
@@ -4023,7 +4178,7 @@ export default {
// 设置就绪状态
this
.
isWidgetReady
=
true
;
console
.
log
(
'注释工具初始化完成'
);
//
console.log('注释工具初始化完成');
// 强制禁用底部widget的内部滚动条
if
(
this
.
_seismicWidgetBottom
)
{
...
...
@@ -4090,32 +4245,32 @@ export default {
}
};
console
.
log
(
'文本绘制工具配置:'
,
textProperties
);
//
console.log('文本绘制工具配置:', textProperties);
this
.
annotationTool
.
setProperties
(
textProperties
);
// 添加事件监听器来打印文本绘制数据
this
.
annotationTool
.
addListener
(
EditEvents
.
Start
,
(
tool
,
command
)
=>
{
const
node
=
command
.
getNode
();
const
textStyle
=
node
.
getTextStyle
?
node
.
getTextStyle
()
:
null
;
console
.
log
(
'开始绘制文本:'
,
{
tool
:
tool
.
getMode
(),
node
:
{
type
:
node
.
getType
?
node
.
getType
()
:
'unknown'
,
properties
:
node
.
getProperties
(),
bounds
:
node
.
getBounds
?
node
.
getBounds
()
:
null
},
textStyle
:
{
font
:
textStyle
?
textStyle
.
getFont
()
:
null
,
color
:
textStyle
?
textStyle
.
getColor
()
:
null
,
size
:
textStyle
?
textStyle
.
size
||
this
.
textStyle
.
size
:
this
.
textStyle
.
size
,
alignment
:
textStyle
?
textStyle
.
getAlignment
()
:
null
},
currentToolConfig
:
{
mode
:
tool
.
getMode
(),
editMode
:
tool
.
getEditMode
(),
isEnabled
:
tool
.
isEnabled
()
}
});
//
console.log('开始绘制文本:', {
//
tool: tool.getMode(),
//
node: {
//
type: node.getType ? node.getType() : 'unknown',
//
properties: node.getProperties(),
//
bounds: node.getBounds ? node.getBounds() : null
//
},
//
textStyle: {
//
font: textStyle ? textStyle.getFont() : null,
//
color: textStyle ? textStyle.getColor() : null,
//
size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
//
alignment: textStyle ? textStyle.getAlignment() : null
//
},
//
currentToolConfig: {
//
mode: tool.getMode(),
//
editMode: tool.getEditMode(),
//
isEnabled: tool.isEnabled()
//
}
//
});
});
this
.
annotationTool
.
addListener
(
EditEvents
.
Change
,
(
tool
,
event
)
=>
{
...
...
@@ -4123,23 +4278,23 @@ export default {
if
(
node
)
{
const
textStyle
=
node
.
getTextStyle
?
node
.
getTextStyle
()
:
null
;
const
previousState
=
node
.
_previousState
||
{};
console
.
log
(
'文本绘制更新:'
,
{
previous
:
{
properties
:
previousState
.
properties
||
{},
textStyle
:
previousState
.
textStyle
||
{}
},
current
:
{
properties
:
node
.
getProperties
(),
bounds
:
node
.
getBounds
?
node
.
getBounds
()
:
null
,
textStyle
:
{
font
:
textStyle
?
textStyle
.
getFont
()
:
null
,
color
:
textStyle
?
textStyle
.
getColor
()
:
null
,
size
:
textStyle
?
textStyle
.
size
||
this
.
textStyle
.
size
:
this
.
textStyle
.
size
,
alignment
:
textStyle
?
textStyle
.
getAlignment
()
:
null
}
},
changes
:
this
.
detectChanges
(
previousState
,
node
)
});
//
console.log('文本绘制更新:', {
//
previous: {
//
properties: previousState.properties || {},
//
textStyle: previousState.textStyle || {}
//
},
//
current: {
//
properties: node.getProperties(),
//
bounds: node.getBounds ? node.getBounds() : null,
//
textStyle: {
//
font: textStyle ? textStyle.getFont() : null,
//
color: textStyle ? textStyle.getColor() : null,
//
size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
//
alignment: textStyle ? textStyle.getAlignment() : null
//
}
//
},
//
changes: this.detectChanges(previousState, node)
//
});
// 保存当前状态用于下次比较
node
.
_previousState
=
{
properties
:
{
...
node
.
getProperties
()
},
...
...
@@ -4165,32 +4320,32 @@ export default {
}
const
textStyle
=
node
.
getTextStyle
?
node
.
getTextStyle
()
:
null
;
console
.
log
(
'文本绘制完成:'
,
{
node
:
{
type
:
node
.
getType
?
node
.
getType
()
:
'unknown'
,
text
:
text
,
properties
:
node
.
getProperties
(),
bounds
:
node
.
getBounds
?
node
.
getBounds
()
:
null
},
styles
:
{
text
:
{
font
:
textStyle
?
textStyle
.
getFont
()
:
null
,
color
:
textStyle
?
textStyle
.
getColor
()
:
null
,
size
:
textStyle
?
textStyle
.
size
||
this
.
textStyle
.
size
:
this
.
textStyle
.
size
,
alignment
:
textStyle
?
textStyle
.
getAlignment
()
:
null
},
line
:
node
.
getLineStyle
?
node
.
getLineStyle
()
:
null
,
fill
:
node
.
getFillStyle
?
node
.
getFillStyle
()
:
null
},
validation
:
{
isValid
:
Boolean
(
node
&&
node
.
getText
),
hasRequiredProperties
:
Boolean
(
node
.
getProperties
().
ax
!==
undefined
&&
node
.
getProperties
().
ay
!==
undefined
),
hasStyles
:
Boolean
(
textStyle
)
}
});
//
console.log('文本绘制完成:', {
//
node: {
//
type: node.getType ? node.getType() : 'unknown',
//
text: text,
//
properties: node.getProperties(),
//
bounds: node.getBounds ? node.getBounds() : null
//
},
//
styles: {
//
text: {
//
font: textStyle ? textStyle.getFont() : null,
//
color: textStyle ? textStyle.getColor() : null,
//
size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
//
alignment: textStyle ? textStyle.getAlignment() : null
//
},
//
line: node.getLineStyle ? node.getLineStyle() : null,
//
fill: node.getFillStyle ? node.getFillStyle() : null
//
},
//
validation: {
//
isValid: Boolean(node && node.getText),
//
hasRequiredProperties: Boolean(
//
node.getProperties().ax !== undefined &&
//
node.getProperties().ay !== undefined
//
),
//
hasStyles: Boolean(textStyle)
//
}
//
});
}
this
.
requestRepaint
();
});
...
...
@@ -4267,28 +4422,28 @@ export default {
});
// 打印更新后的样式数据
console
.
log
(
'样式更新:'
,
{
type
:
shape
.
getType
?
shape
.
getType
()
:
'未知类型'
,
text
:
shape
.
getText
?
shape
.
getText
()
:
null
,
properties
:
shape
.
getProperties
(),
textStyle
:
{
font
:
fontString
,
color
:
this
.
textStyle
.
color
,
size
:
this
.
textStyle
.
size
,
alignment
:
this
.
textStyle
.
align
,
bold
:
this
.
textStyle
.
bold
,
italic
:
this
.
textStyle
.
italic
},
lineStyle
:
{
color
:
this
.
lineStyle
.
color
,
width
:
this
.
lineStyle
.
width
,
pattern
:
this
.
lineStyle
.
pattern
},
fillStyle
:
{
color
:
this
.
fillStyle
.
color
,
pattern
:
this
.
fillStyle
.
pattern
}
});
//
console.log('样式更新:', {
//
type: shape.getType ? shape.getType() : '未知类型',
//
text: shape.getText ? shape.getText() : null,
//
properties: shape.getProperties(),
//
textStyle: {
//
font: fontString,
//
color: this.textStyle.color,
//
size: this.textStyle.size,
//
alignment: this.textStyle.align,
//
bold: this.textStyle.bold,
//
italic: this.textStyle.italic
//
},
//
lineStyle: {
//
color: this.lineStyle.color,
//
width: this.lineStyle.width,
//
pattern: this.lineStyle.pattern
//
},
//
fillStyle: {
//
color: this.fillStyle.color,
//
pattern: this.fillStyle.pattern
//
}
//
});
// 强制重绘
if
(
shape
.
invalidate
)
{
...
...
@@ -4320,16 +4475,16 @@ export default {
});
// 打印更新的文本数据
console
.
log
(
'更新已存在的文本:'
,
{
text
:
shape
.
getText
(),
properties
:
shape
.
getProperties
(),
textStyle
:
{
font
:
fontString
,
size
:
value
,
color
:
this
.
textStyle
.
color
,
alignment
:
this
.
textStyle
.
align
}
});
//
console.log('更新已存在的文本:', {
//
text: shape.getText(),
//
properties: shape.getProperties(),
//
textStyle: {
//
font: fontString,
//
size: value,
//
color: this.textStyle.color,
//
alignment: this.textStyle.align
//
}
//
});
}
});
}
...
...
@@ -4360,15 +4515,15 @@ export default {
});
// 打印更新的文本数据
console
.
log
(
'更新已存在的文本:'
,
{
text
:
shape
.
getText
(),
properties
:
shape
.
getProperties
(),
textStyle
:
{
font
:
fontString
,
color
:
this
.
textStyle
.
color
,
alignment
:
this
.
textStyle
.
align
}
});
//
console.log('更新已存在的文本:', {
//
text: shape.getText(),
//
properties: shape.getProperties(),
//
textStyle: {
//
font: fontString,
//
color: this.textStyle.color,
//
alignment: this.textStyle.align
//
}
//
});
}
});
}
...
...
@@ -4408,15 +4563,15 @@ export default {
});
// 打印更新后的线条样式数据
console
.
log
(
'线条样式更新:'
,
{
type
:
this
.
selectedShape
.
getType
?
this
.
selectedShape
.
getType
()
:
'未知类型'
,
properties
:
this
.
selectedShape
.
getProperties
(),
lineStyle
:
{
color
:
this
.
lineStyle
.
color
,
width
:
this
.
lineStyle
.
width
,
pattern
:
this
.
lineStyle
.
pattern
}
});
//
console.log('线条样式更新:', {
//
type: this.selectedShape.getType ? this.selectedShape.getType() : '未知类型',
//
properties: this.selectedShape.getProperties(),
//
lineStyle: {
//
color: this.lineStyle.color,
//
width: this.lineStyle.width,
//
pattern: this.lineStyle.pattern
//
}
//
});
this
.
requestRepaint
();
}
...
...
@@ -4433,15 +4588,15 @@ export default {
});
// 打印每个更新的线条数据
console
.
log
(
'更新已存在的线条:'
,
{
type
:
shape
.
getType
?
shape
.
getType
()
:
'未知类型'
,
properties
:
shape
.
getProperties
(),
lineStyle
:
{
color
:
this
.
lineStyle
.
color
,
width
:
this
.
lineStyle
.
width
,
pattern
:
this
.
lineStyle
.
pattern
}
});
//
console.log('更新已存在的线条:', {
//
type: shape.getType ? shape.getType() : '未知类型',
//
properties: shape.getProperties(),
//
lineStyle: {
//
color: this.lineStyle.color,
//
width: this.lineStyle.width,
//
pattern: this.lineStyle.pattern
//
}
//
});
}
});
}
...
...
@@ -4551,7 +4706,7 @@ export default {
}
// 默认返回空数组(实线)
console
.
log
(
'使用默认实线模式,无法识别模式:'
,
pattern
);
//
console.log('使用默认实线模式,无法识别模式:', pattern);
return
[];
},
...
...
@@ -4706,7 +4861,7 @@ export default {
this
.
plots
.
redraw
();
}
console
.
log
(
`成功切换到颜色映射:
${
colorMapName
}
`
);
//
console.log(`成功切换到颜色映射: ${colorMapName}`);
}
catch
(
error
)
{
console
.
error
(
`切换颜色映射失败:
${
error
.
message
}
`
);
}
...
...
@@ -4980,7 +5135,7 @@ export default {
});
console
.
log
(
'颜色映射注册成功'
);
//
console.log('颜色映射注册成功');
}
catch
(
error
)
{
console
.
error
(
'注册颜色映射失败:'
,
error
);
}
...
...
@@ -5028,34 +5183,34 @@ export default {
}
};
console
.
log
(
'线条绘制工具配置:'
,
pencilProperties
);
//
console.log('线条绘制工具配置:', pencilProperties);
this
.
pencilTool
=
new
Paint
(
pencilProperties
);
// 添加事件监听
this
.
pencilTool
.
addListener
(
EditEvents
.
Start
,
(
tool
,
command
)
=>
{
const
node
=
command
.
getNode
();
console
.
log
(
'开始绘制线条:'
,
{
tool
:
tool
.
getMode
(),
properties
:
node
.
getProperties
()
});
//
console.log('开始绘制线条:', {
//
tool: tool.getMode(),
//
properties: node.getProperties()
//
});
this
.
annotations
.
addChild
(
node
);
})
.
addListener
(
EditEvents
.
Change
,
(
tool
,
event
)
=>
{
const
node
=
tool
.
getShape
();
if
(
node
)
{
console
.
log
(
'线条绘制更新:'
,
{
properties
:
node
.
getProperties
(),
bounds
:
node
.
getBounds
?
node
.
getBounds
()
:
null
});
//
console.log('线条绘制更新:', {
//
properties: node.getProperties(),
//
bounds: node.getBounds ? node.getBounds() : null
//
});
}
})
.
addListener
(
EditEvents
.
End
,
(
tool
,
node
)
=>
{
if
(
node
)
{
console
.
log
(
'线条绘制完成:'
,
{
properties
:
node
.
getProperties
(),
bounds
:
node
.
getBounds
?
node
.
getBounds
()
:
null
});
//
console.log('线条绘制完成:', {
//
properties: node.getProperties(),
//
bounds: node.getBounds ? node.getBounds() : null
//
});
}
if
(
node
&&
this
.
annotations
.
indexOfChild
(
node
)
===
-
1
)
{
...
...
@@ -5142,14 +5297,14 @@ export default {
// 如果没有活动工具,则不显示菜单
if
(
!
activeTool
)
{
console
.
log
(
'No active tool'
);
//
console.log('No active tool');
return
;
}
// 获取当前选中的形状
const
currentShape
=
activeTool
.
getShape
();
if
(
!
currentShape
)
{
console
.
log
(
'No shape selected'
);
//
console.log('No shape selected');
return
;
}
...
...
@@ -5164,12 +5319,12 @@ export default {
// 记录当前右键菜单使用的工具
this
.
_contextMenuTool
=
activeTool
;
console
.
log
(
'Context menu shown:'
,
{
x
:
this
.
contextMenu
.
x
,
y
:
this
.
contextMenu
.
y
,
tool
:
activeTool
.
getMode
(),
shape
:
currentShape
?
currentShape
.
getType
()
:
null
});
// //
console.log('Context menu shown:', {
//
x: this.contextMenu.x,
//
y: this.contextMenu.y,
//
tool: activeTool.getMode(),
//
shape: currentShape ? currentShape.getType() : null
//
});
event
.
stopPropagation
();
},
...
...
@@ -5181,7 +5336,7 @@ export default {
if
(
this
.
contextMenu
.
visible
)
{
this
.
contextMenu
.
visible
=
false
;
this
.
_contextMenuTool
=
null
;
console
.
log
(
'Context menu hidden'
);
//
console.log('Context menu hidden');
}
},
...
...
@@ -5470,14 +5625,14 @@ export default {
hasStyles
:
Boolean
(
textStyle
&&
node
.
getLineStyle
&&
node
.
getFillStyle
)
};
console
.
log
(
'标注数据验证:'
,
validation
);
//
console.log('标注数据验证:', validation);
if
(
Object
.
values
(
validation
).
every
(
v
=>
v
))
{
this
.
savedAnnotations
.
push
(
annotationData
);
console
.
log
(
'标注数据已保存:'
,
{
data
:
annotationData
,
totalAnnotations
:
this
.
savedAnnotations
.
length
});
//
console.log('标注数据已保存:', {
//
data: annotationData,
//
totalAnnotations: this.savedAnnotations.length
//
});
}
else
{
console
.
warn
(
'标注数据验证失败:'
,
validation
);
}
...
...
@@ -5507,9 +5662,9 @@ export default {
}
try
{
console
.
log
(
'开始恢复文本标注:'
,
{
totalAnnotations
:
this
.
savedAnnotations
.
length
});
//
console.log('开始恢复文本标注:', {
//
totalAnnotations: this.savedAnnotations.length
//
});
// 恢复文本标注
this
.
savedAnnotations
.
forEach
((
data
,
index
)
=>
{
...
...
@@ -5545,10 +5700,10 @@ export default {
textNode
.
setProperties
(
fullProperties
);
this
.
annotations
.
addChild
(
textNode
);
console
.
log
(
`恢复文本标注
${
index
+
1
}
/
${
this
.
savedAnnotations
.
length
}
:`
,
{
text
:
data
.
text
||
data
.
properties
.
text
,
position
:
{
x
:
data
.
properties
.
ax
,
y
:
data
.
properties
.
ay
}
});
//
console.log(`恢复文本标注 ${index + 1}/${this.savedAnnotations.length}:`, {
//
text: data.text || data.properties.text,
//
position: { x: data.properties.ax, y: data.properties.ay }
//
});
}
catch
(
error
)
{
console
.
error
(
`恢复文本标注
${
index
+
1
}
时出错:`
,
{
error
:
error
.
message
,
...
...
@@ -5583,9 +5738,9 @@ export default {
}
try
{
console
.
log
(
'开始恢复线条标注:'
,
{
totalLines
:
this
.
savedLineAnnotations
.
length
});
//
console.log('开始恢复线条标注:', {
//
totalLines: this.savedLineAnnotations.length
//
});
this
.
savedLineAnnotations
.
forEach
((
data
,
index
)
=>
{
try
{
...
...
@@ -5620,11 +5775,11 @@ export default {
// 添加到标注层
this
.
annotations
.
addChild
(
path
);
console
.
log
(
`恢复线条标注
${
index
+
1
}
/
${
this
.
savedLineAnnotations
.
length
}
:`
,
{
points
:
data
.
properties
.
x
.
length
,
style
:
lineStyle
,
bounds
:
data
.
bounds
});
//
console.log(`恢复线条标注 ${index + 1}/${this.savedLineAnnotations.length}:`, {
//
points: data.properties.x.length,
//
style: lineStyle,
//
bounds: data.bounds
//
});
}
catch
(
error
)
{
console
.
error
(
`恢复线条标注
${
index
+
1
}
时出错:`
,
{
error
:
error
.
message
,
...
...
@@ -5692,7 +5847,7 @@ export default {
// 强制重绘
this
.
_seismicWidget
.
invalidate
();
console
.
log
(
'文本标注已创建在指定位置'
);
//
console.log('文本标注已创建在指定位置');
}
catch
(
error
)
{
console
.
error
(
'创建文本标注时出错:'
,
error
);
}
...
...
@@ -5884,7 +6039,6 @@ export default {
align-items
:
flex-start
;
justify-content
:
space-between
;
gap
:
12px
;
margin-bottom
:
110px
;
/* 顶部操作与地震图拉开距离 */
min-width
:
100%
;
/* 确保有足够宽度 */
...
...
@@ -5952,6 +6106,45 @@ export default {
/* 固定定位的缩略图,确保始终可见 */
/* 移除模板内固定块样式(改为全局 body 容器) */
/* 可拖动的缩略图样式 */
.draggable-thumb
{
cursor
:
grab
;
user-select
:
none
;
transition
:
none
;
/* 拖动时禁用过渡动画 */
}
.draggable-thumb
:active
{
cursor
:
grabbing
;
}
.drag-handle
{
position
:
absolute
;
top
:
5px
;
right
:
5px
;
width
:
20px
;
height
:
20px
;
background
:
rgba
(
0
,
0
,
0
,
0.6
);
color
:
white
;
border-radius
:
3px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
font-size
:
12px
;
cursor
:
grab
;
z-index
:
10
;
opacity
:
0.7
;
transition
:
opacity
0.2s
;
}
.drag-handle
:hover
{
opacity
:
1
;
background
:
rgba
(
0
,
0
,
0
,
0.8
);
}
.drag-handle
:active
{
cursor
:
grabbing
;
}
/* 双画布容器与滚动/缩放 */
.split-container
{
display
:
flex
;
...
...
@@ -6753,14 +6946,14 @@ export default {
top
:
-9999px
!important
;
}
/*
确保外层滚动区域可以接收鼠标事件
*/
/*
外层滚动区域样式
*/
.sync-section
{
pointer-events
:
auto
!important
;
}
.sync-section
::-webkit-scrollbar
{
width
:
12
px
;
height
:
12
px
;
width
:
4
px
;
height
:
4
px
;
}
.sync-section
::-webkit-scrollbar-track
{
...
...
@@ -6769,7 +6962,7 @@ export default {
.sync-section
::-webkit-scrollbar-thumb
{
background
:
#888
;
border-radius
:
6
px
;
border-radius
:
3
px
;
}
.sync-section
::-webkit-scrollbar-thumb:hover
{
...
...
@@ -6790,4 +6983,36 @@ export default {
max-height
:
160px
;
overflow
:
hidden
;
}
/* 缩略图弹窗样式 - 确保不被遮挡 */
.thumbnail-dialog
{
z-index
:
9999999
!important
;
}
.thumbnail-dialog
.el-dialog
{
z-index
:
9999999
!important
;
}
.thumbnail-dialog
.el-dialog__wrapper
{
z-index
:
9999999
!important
;
}
.thumbnail-dialog
.el-overlay
{
z-index
:
9999998
!important
;
}
/* 确保弹窗内容完全可见 */
.thumbnail-dialog
.el-dialog__body
{
overflow
:
visible
!important
;
max-height
:
none
!important
;
}
/* 修复可能的容器遮挡问题 */
.app-containers
{
overflow
:
visible
!important
;
}
.containerBlock
{
overflow
:
visible
!important
;
}
</
style
>
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