Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
boyueCEnd
Project
Project
Details
Activity
Releases
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
游洁
boyueCEnd
Commits
86f65c4d
Commit
86f65c4d
authored
Dec 01, 2025
by
youjie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改基础资料
parent
8bde77b4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
745 additions
and
305 deletions
+745
-305
App.vue
src/App.vue
+3
-1
axiosUpload.ts
src/api/axiosUpload.ts
+122
-0
zh-CN.ts
src/i18n/locales/zh-CN.ts
+11
-2
UploadService.ts
src/services/UploadService.ts
+292
-0
UserService.ts
src/services/UserService.ts
+36
-0
register.vue
src/views/auth/register.vue
+2
-2
accountCenter.vue
src/views/personalCenter/accountCenter.vue
+1
-1
basicInfor.vue
...ws/personalCenter/components/accountCenter/basicInfor.vue
+278
-299
No files found.
src/App.vue
View file @
86f65c4d
...
@@ -86,6 +86,7 @@ body {
...
@@ -86,6 +86,7 @@ body {
--gray-7
:
96
,
105
,
97
;
//#606961
--gray-7
:
96
,
105
,
97
;
//#606961
--gray-6
:
163
,
164
,
160
;
//#A3A4A0
--gray-6
:
163
,
164
,
160
;
//#A3A4A0
--gray-5
:
74
,
102
,
77
;
//#4A664D
--gray-5
:
74
,
102
,
77
;
//#4A664D
--gray-4
:
142
,
173
,
142
;
//#8EAD8E
// --color-neutral-10: rgb(var(--gray-10));//#0c150d
// --color-neutral-10: rgb(var(--gray-10));//#0c150d
// --color-neutral-9: rgb(var(--gray-9));//#5a5a5a
// --color-neutral-9: rgb(var(--gray-9));//#5a5a5a
...
@@ -114,7 +115,7 @@ body {
...
@@ -114,7 +115,7 @@ body {
--customColor-text-7
:
#606961
;
--customColor-text-7
:
#606961
;
--customColor-text-6
:
#A3A4A0
;
--customColor-text-6
:
#A3A4A0
;
--customColor-text-5
:
#4A664D
;
--customColor-text-5
:
#4A664D
;
--customColor-text-4
:
#8EAD8E
;
}
}
.customPrimary-10
{
color
:
var
(
--
customPrimary-10
);}
.customPrimary-10
{
color
:
var
(
--
customPrimary-10
);}
.customPrimary-9
{
color
:
var
(
--
customPrimary-9
);}
.customPrimary-9
{
color
:
var
(
--
customPrimary-9
);}
...
@@ -144,6 +145,7 @@ body {
...
@@ -144,6 +145,7 @@ body {
.customColor-text-7
{
color
:
var
(
--
customColor-text-7
);}
.customColor-text-7
{
color
:
var
(
--
customColor-text-7
);}
.customColor-text-6
{
color
:
var
(
--
customColor-text-6
);}
.customColor-text-6
{
color
:
var
(
--
customColor-text-6
);}
.customColor-text-5
{
color
:
var
(
--
customColor-text-5
);}
.customColor-text-5
{
color
:
var
(
--
customColor-text-5
);}
.customColor-text-4
{
color
:
var
(
--
customColor-text-4
);}
@font-face
{
@font-face
{
font-family
:
'Source Han Sans CN ExtraLight'
;
font-family
:
'Source Han Sans CN ExtraLight'
;
...
...
src/api/axiosUpload.ts
0 → 100644
View file @
86f65c4d
import
Axios
,
{
type
AxiosResponse
,
type
InternalAxiosRequestConfig
,
AxiosError
,
}
from
'axios'
;
// import { domainManager } from '../utils/domainManager'
let
datas
:
AxiosResponse
export
enum
ApiResult
{
'SUCCESS'
=
1
,
'FAILED'
=
0
,
'TOKEN_INVALID'
=
10000
,
'TOKEN_ILLEGAL'
=
10001
,
}
/**
* get status code
* @param {AxiosResponse} response Axios response object
*/
const
getErrorCode2text
=
(
response
:
AxiosResponse
):
string
=>
{
const
code
=
response
.
status
let
message
=
'Request Error'
switch
(
code
)
{
case
400
:
message
=
'Request Error'
break
case
401
:
message
=
'Unauthorized, please login'
break
case
403
:
message
=
'拒绝访问'
break
case
404
:
message
=
'访问资源不存在'
break
case
408
:
message
=
'请求超时'
break
case
500
:
message
=
'位置错误'
break
case
501
:
message
=
'承载服务未实现'
break
case
502
:
message
=
'网关错误'
break
case
503
:
message
=
'服务暂不可用'
break
case
504
:
message
=
'网关超时'
break
case
505
:
message
=
'暂不支持的 HTTP 版本'
break
default
:
message
=
'位置错误'
}
return
message
}
/**
* @returns {AxiosResponse} result
* @tutorial see more:https://github.com/onlyling/some-demo/tree/master/typescript-width-axios
* @example
* service.get<{data: string; code: number}>('/test').then(({data}) => { console.log(data.code) })
*/
const
service
=
Axios
.
create
({
baseURL
:
import
.
meta
.
env
.
VITE_FILEUPLOAD_API_BASE_URL
,
timeout
:
20000
,
headers
:
{
"Content-Type"
:
"application/x-www-form-urlencoded;"
}
})
/**
* @description 请求发起前的拦截器
* @returns {AxiosRequestConfig} config
*/
service
.
interceptors
.
request
.
use
(
async
(
config
:
InternalAxiosRequestConfig
)
=>
{
return
config
;
},
error
=>
{
//TODO: 新增网络请求异常处理业务
return
Promise
.
reject
(
error
)
}
)
/**
* @description 响应收到后的拦截器
* @returns {}
*/
service
.
interceptors
.
response
.
use
(
/** 请求有响应 */
async
(
response
:
AxiosResponse
)
=>
{
if
(
response
.
status
===
200
)
{
if
(
response
.
data
.
resultCode
==
ApiResult
.
TOKEN_ILLEGAL
||
response
.
data
.
resultCode
==
ApiResult
.
TOKEN_INVALID
){
}
datas
=
response
return
Promise
.
resolve
(
datas
)
}
else
{
const
__text
=
getErrorCode2text
(
response
)
return
Promise
.
reject
(
new
Error
(
__text
))
}
},
/** 请求无响应 */
(
error
:
AxiosError
)
=>
{
if
(
error
&&
error
.
response
)
{
const
__text
=
getErrorCode2text
(
error
.
response
);
return
Promise
.
reject
(
new
Error
(
__text
));
}
else
{
return
Promise
.
reject
(
new
Error
(
'unknow error'
));
}
}
)
export
default
service
src/i18n/locales/zh-CN.ts
View file @
86f65c4d
...
@@ -50,7 +50,7 @@ export default {
...
@@ -50,7 +50,7 @@ export default {
backToHome
:
'返回首页'
,
backToHome
:
'返回首页'
,
bindingName
:
'姓名'
,
bindingName
:
'姓名'
,
bindingNameRequired
:
'请输入中文/英文名称'
,
bindingNameRequired
:
'请输入中文/英文名称'
,
bindingPhone
:
'
手机
号码'
,
bindingPhone
:
'
电话
号码'
,
bindingPhoneRequired
:
'输入电话号码'
,
bindingPhoneRequired
:
'输入电话号码'
,
bindingWechat
:
'微信账号'
,
bindingWechat
:
'微信账号'
,
bindingWechatRequired
:
'请输入可添加的账号'
,
bindingWechatRequired
:
'请输入可添加的账号'
,
...
@@ -201,7 +201,16 @@ export default {
...
@@ -201,7 +201,16 @@ export default {
accountInfor
:
'账户信息'
,
accountInfor
:
'账户信息'
,
commonPassenger
:
'常用旅客'
,
commonPassenger
:
'常用旅客'
,
firstName
:
'名'
,
firstName
:
'名'
,
lastName
:
'姓'
lastName
:
'姓'
,
gender
:
'性别'
,
placeholderLastName
:
'请输入姓'
,
placeholderFirstName
:
'请输入名'
,
placeholderGender
:
'请选择性别'
,
birthday
:
'出生日期'
,
placeholder
:
'请选择'
,
changePhoto
:
'修改头像'
,
photo
:
'头像'
,
photoTip
:
'*支持jpg,gif,png格式图片,且文件小于2M。'
,
},
},
// HTTP 错误状态码
// HTTP 错误状态码
httpError
:
{
httpError
:
{
...
...
src/services/UploadService.ts
0 → 100644
View file @
86f65c4d
import
service
from
'@/api/axiosUpload'
;
import
{
Message
}
from
'@arco-design/web-vue'
;
/**
* 上传服务器返回的数据结构
*/
interface
UploadResponse
{
FileName
:
string
;
SourceFileName
:
string
;
FilePath
:
string
;
FileType
:
number
;
StatusCode
:
number
;
Message
:
string
;
Ocr
:
any
;
Barcode
:
any
;
VideoCoverImg
:
any
;
OtherFile
:
any
;
FileSize
:
number
;
HashInfo
:
any
;
}
/**
* 上传配置接口
*/
export
interface
UploadConfig
{
/** 上传路径前缀 */
path
:
string
;
/** 是否启用 OCR 识别 */
ocr
?:
boolean
;
/** 上传成功回调 */
onSuccess
?:
(
fileUrl
:
string
,
file
:
File
,
index
:
number
)
=>
void
;
/** 上传失败回调 */
onError
?:
(
error
:
Error
,
file
:
File
,
index
:
number
)
=>
void
;
/** 上传进度回调 */
onProgress
?:
(
percent
:
number
,
file
:
File
,
index
:
number
)
=>
void
;
}
/**
* 上传服务
* 统一的文件上传服务,所有表单组件的文件上传都使用此服务
*/
class
UploadService
{
/**
* 上传单个文件
* @param file 要上传的文件
* @param config 上传配置
* @returns 成功返回完整的线上文件路径,失败返回空字符串
*
* @example
* ```typescript
* const fileUrl = await UploadService.uploadFile(file, {
* path: '/Product/',
* ocr: false,
* onProgress: (percent) => {
* console.log(`上传进度: ${percent}%`);
* }
* });
*
* if (fileUrl) {
* console.log('上传成功:', fileUrl);
* // 可以将 fileUrl 保存到表单数据中
* formData.imageUrl = fileUrl;
* } else {
* console.log('上传失败');
* }
* ```
*/
static
async
uploadFileAsync
(
file
:
File
,
config
:
UploadConfig
):
Promise
<
string
>
{
try
{
// 构建 FormData
const
formData
=
new
FormData
();
formData
.
append
(
'myfile'
,
file
);
// 构建上传 URL
const
uploadUrl
=
`/Upload/Index?filePath=
${
config
.
path
}
&ocr=
${
config
.
ocr
||
false
}
`
;
// 发起上传请求
const
response
=
await
service
.
post
<
UploadResponse
>
(
uploadUrl
,
formData
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
onUploadProgress
:
(
progressEvent
)
=>
{
if
(
config
.
onProgress
&&
progressEvent
.
total
)
{
const
percent
=
Math
.
round
((
progressEvent
.
loaded
*
100
)
/
progressEvent
.
total
);
config
.
onProgress
(
percent
,
file
,
0
);
}
},
});
// 检查返回数据
const
data
=
response
.
data
;
if
(
!
data
||
!
data
.
FilePath
)
{
throw
new
Error
(
data
?.
Message
||
'上传失败'
);
}
// 拼接完整的文件路径
const
baseUrl
=
import
.
meta
.
env
.
VITE_FILEPREVIEW_API_BASE_URL
||
''
;
const
fullUrl
=
`
${
baseUrl
}${
data
.
FilePath
}
`
;
// 调用成功回调
if
(
config
.
onSuccess
)
{
config
.
onSuccess
(
fullUrl
,
file
,
0
);
}
return
fullUrl
;
}
catch
(
error
)
{
const
err
=
error
as
Error
;
// 调用失败回调
if
(
config
.
onError
)
{
config
.
onError
(
err
,
file
,
0
);
}
else
{
Message
.
error
(
`文件
${
file
.
name
}
上传失败!`
);
}
return
''
;
}
}
/**
* 批量上传文件(串行上传)
* @param files 要上传的文件列表
* @param config 上传配置
* @returns 成功返回完整的线上文件路径数组,失败的文件路径为空字符串
*
* @example
* ```typescript
* const fileUrls = await UploadService.uploadFiles(files, {
* path: '/Product/',
* ocr: false,
* onProgress: (percent, file, index) => {
* console.log(`文件 ${index + 1} 上传进度: ${percent}%`);
* },
* onSuccess: (fileUrl, file, index) => {
* console.log(`文件 ${index + 1} 上传成功:`, fileUrl);
* }
* });
*
* // 过滤出成功上传的文件路径
* const successUrls = fileUrls.filter(url => url !== '');
* console.log('成功上传的文件:', successUrls);
* ```
*/
static
async
uploadFilesAsync
(
files
:
File
[],
config
:
UploadConfig
):
Promise
<
string
[]
>
{
if
(
!
files
||
files
.
length
===
0
)
{
return
[];
}
const
results
:
string
[]
=
[];
// 串行上传文件
for
(
let
index
=
0
;
index
<
files
.
length
;
index
++
)
{
const
file
=
files
[
index
];
try
{
// 构建 FormData
const
formData
=
new
FormData
();
formData
.
append
(
'myfile'
,
file
);
// 构建上传 URL
const
uploadUrl
=
`/Upload/Index?filePath=
${
config
.
path
}
&ocr=
${
config
.
ocr
||
false
}
`
;
// 发起上传请求
const
response
=
await
service
.
post
<
UploadResponse
>
(
uploadUrl
,
formData
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
onUploadProgress
:
(
progressEvent
)
=>
{
if
(
config
.
onProgress
&&
progressEvent
.
total
)
{
const
percent
=
Math
.
round
((
progressEvent
.
loaded
*
100
)
/
progressEvent
.
total
);
config
.
onProgress
(
percent
,
file
,
index
);
}
},
});
// 检查返回数据
const
data
=
response
.
data
;
if
(
!
data
||
!
data
.
FilePath
)
{
throw
new
Error
(
data
?.
Message
||
'上传失败'
);
}
// 拼接完整的文件路径
const
baseUrl
=
import
.
meta
.
env
.
VITE_FILEPREVIEW_API_BASE_URL
||
''
;
const
fullUrl
=
`
${
baseUrl
}${
data
.
FilePath
}
`
;
// 调用成功回调
if
(
config
.
onSuccess
)
{
config
.
onSuccess
(
fullUrl
,
file
,
index
);
}
results
.
push
(
fullUrl
);
}
catch
(
error
)
{
const
err
=
error
as
Error
;
// 调用失败回调
if
(
config
.
onError
)
{
config
.
onError
(
err
,
file
,
index
);
}
else
{
Message
.
error
(
`文件
${
file
.
name
}
上传失败!`
);
}
results
.
push
(
''
);
}
}
return
results
;
}
/**
* 并行上传多个文件(比串行上传更快,但可能给服务器带来更大压力)
* @param files 要上传的文件列表
* @param config 上传配置
* @returns 成功返回完整的线上文件路径数组,失败的文件路径为空字符串
*
* @example
* ```typescript
* const fileUrls = await UploadService.uploadFilesParallel(files, {
* path: '/Product/',
* ocr: false,
* onProgress: (percent, file, index) => {
* console.log(`文件 ${index + 1} 上传进度: ${percent}%`);
* }
* });
*
* const successUrls = fileUrls.filter(url => url !== '');
* console.log('成功上传的文件:', successUrls);
* ```
*/
static
async
uploadFilesParallelAsync
(
files
:
File
[],
config
:
UploadConfig
):
Promise
<
string
[]
>
{
if
(
!
files
||
files
.
length
===
0
)
{
return
[];
}
const
uploadPromises
=
files
.
map
((
file
,
index
)
=>
{
return
(
async
()
=>
{
try
{
// 构建 FormData
const
formData
=
new
FormData
();
formData
.
append
(
'myfile'
,
file
);
// 构建上传 URL
const
uploadUrl
=
`/Upload/Index?filePath=
${
config
.
path
}
&ocr=
${
config
.
ocr
||
false
}
`
;
// 发起上传请求
const
response
=
await
service
.
post
<
UploadResponse
>
(
uploadUrl
,
formData
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
onUploadProgress
:
(
progressEvent
)
=>
{
if
(
config
.
onProgress
&&
progressEvent
.
total
)
{
const
percent
=
Math
.
round
((
progressEvent
.
loaded
*
100
)
/
progressEvent
.
total
);
config
.
onProgress
(
percent
,
file
,
index
);
}
},
});
// 检查返回数据
const
data
=
response
.
data
;
if
(
!
data
||
!
data
.
FilePath
)
{
throw
new
Error
(
data
?.
Message
||
'上传失败'
);
}
// 拼接完整的文件路径
const
baseUrl
=
import
.
meta
.
env
.
VITE_FILEPREVIEW_API_BASE_URL
||
''
;
const
fullUrl
=
`
${
baseUrl
}${
data
.
FilePath
}
`
;
// 调用成功回调
if
(
config
.
onSuccess
)
{
config
.
onSuccess
(
fullUrl
,
file
,
index
);
}
return
fullUrl
;
}
catch
(
error
)
{
const
err
=
error
as
Error
;
// 调用失败回调
if
(
config
.
onError
)
{
config
.
onError
(
err
,
file
,
index
);
}
else
{
Message
.
error
(
`文件
${
file
.
name
}
上传失败!`
);
}
return
''
;
}
})();
});
return
Promise
.
all
(
uploadPromises
);
}
}
export
default
UploadService
;
src/services/UserService.ts
View file @
86f65c4d
...
@@ -669,6 +669,42 @@ class UserService {
...
@@ -669,6 +669,42 @@ class UserService {
)
)
return
response
as
unknown
as
HttpResponse
return
response
as
unknown
as
HttpResponse
}
}
/**
* 获取基础资料
* @param tenantId 租户ID(可选)
* @param provider 外部id
*/
static
async
memberUserDetail
(
tenantId
:
string
,
id
:
any
):
Promise
<
HttpResponse
>
{
const
response
=
await
OtaRequest
.
get
(
`/member-user/
${
id
}
/detail`
,
{},
{
headers
:
tenantId
?
{
'__tenant'
:
tenantId
}
:
{}
}
)
return
response
as
unknown
as
HttpResponse
}
/**
* 修改基础资料
* @param tenantId 租户ID(可选)
* @param provider 外部id
*/
static
async
updateMemberUser
(
tenantId
:
string
,
data
:
any
):
Promise
<
HttpResponse
>
{
const
response
=
await
OtaRequest
.
put
(
'/member-user'
,
data
,
{
headers
:
tenantId
?
{
'__tenant'
:
tenantId
}
:
{}
}
)
return
response
as
unknown
as
HttpResponse
}
}
}
export
default
UserService
export
default
UserService
src/views/auth/register.vue
View file @
86f65c4d
...
@@ -375,7 +375,7 @@ const getSimples = async () => {
...
@@ -375,7 +375,7 @@ const getSimples = async () => {
const
handleAreaCodeChange
=
(
value
:
string
)
=>
{
const
handleAreaCodeChange
=
(
value
:
string
)
=>
{
formData
.
phoneCode
=
`${value
}
`
formData
.
phoneCode
=
`${value
.indexOf('+')>-1?value:('+'+value)
}
`
}
}
const
receiveChange
=
(
type
:
number
)
=>
{
const
receiveChange
=
(
type
:
number
)
=>
{
...
@@ -681,7 +681,7 @@ onMounted(() => {
...
@@ -681,7 +681,7 @@ onMounted(() => {
}
)
}
)
}
)
}
)
<
/script
>
<
/script
>
<
style
>
<
style
scoped
lang
=
"scss"
>
.
light
-
login
-
bg
{
.
light
-
login
-
bg
{
background
:
url
(
'../../assets/images/login/login-bg.png'
)
no
-
repeat
;
background
:
url
(
'../../assets/images/login/login-bg.png'
)
no
-
repeat
;
background
-
size
:
100
%
100
%
;
background
-
size
:
100
%
100
%
;
...
...
src/views/personalCenter/accountCenter.vue
View file @
86f65c4d
...
@@ -105,7 +105,7 @@ onMounted(async () => {
...
@@ -105,7 +105,7 @@ onMounted(async () => {
text-indent
:
4px
;
text-indent
:
4px
;
}
}
:deep
(
.arco-form-item-label-required-symbol
)
{
:deep
(
.arco-form-item-label-required-symbol
)
{
display
:
none
;
//
display: none;
}
}
:deep
(
.arco-form-item-message
)
{
:deep
(
.arco-form-item-message
)
{
color
:
rgba
(
255
,
0
,
0
,
0
);
color
:
rgba
(
255
,
0
,
0
,
0
);
...
...
src/views/personalCenter/components/accountCenter/basicInfor.vue
View file @
86f65c4d
This diff is collapsed.
Click to expand it.
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