Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
Starter Web Vue
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
product
kim3-web-vue
Starter Web Vue
Commits
d8b5fd57
Commit
d8b5fd57
authored
Jun 30, 2021
by
水落(YangLei)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 更新用户信息完成
parent
5efc64b4
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
455 additions
and
128 deletions
+455
-128
src/api/system.js
src/api/system.js
+35
-1
src/components/index.js
src/components/index.js
+3
-1
src/components/table/index.vue
src/components/table/index.vue
+4
-10
src/components/transition/PageToggleTransition.vue
src/components/transition/PageToggleTransition.vue
+68
-71
src/components/upload/index.vue
src/components/upload/index.vue
+41
-0
src/components/white_card/index.vue
src/components/white_card/index.vue
+7
-0
src/main.js
src/main.js
+2
-0
src/pages/frame/components/header/LayoutTopHeaderAvatar.vue
src/pages/frame/components/header/LayoutTopHeaderAvatar.vue
+8
-4
src/pages/frame/components/tab/LayoutTabsHeader.vue
src/pages/frame/components/tab/LayoutTabsHeader.vue
+31
-7
src/pages/frame/view/template/BlankTemplateView.vue
src/pages/frame/view/template/BlankTemplateView.vue
+6
-5
src/pages/frame/view/template/TabsTemplateView.vue
src/pages/frame/view/template/TabsTemplateView.vue
+41
-26
src/pages/user/components/ToDo.vue
src/pages/user/components/ToDo.vue
+3
-0
src/pages/user/components/info.vue
src/pages/user/components/info.vue
+73
-0
src/pages/user/components/message.vue
src/pages/user/components/message.vue
+3
-0
src/pages/user/components/modify_password.vue
src/pages/user/components/modify_password.vue
+67
-0
src/pages/user/components/todo.vue
src/pages/user/components/todo.vue
+0
-0
src/pages/user/index.vue
src/pages/user/index.vue
+38
-1
src/plugins/index.js
src/plugins/index.js
+3
-1
src/router/config.js
src/router/config.js
+1
-1
src/store/index.js
src/store/index.js
+18
-0
src/style/index.css
src/style/index.css
+3
-0
No files found.
src/api/system.js
View file @
d8b5fd57
import
{
putReq
}
from
'
@/utils
'
;
import
{
getReq
,
postReq
,
putReq
}
from
'
@/utils
'
;
/**
* 退出登录
*/
export
function
logoutApi
()
{
return
putReq
(
'
/api/v1/logout
'
);
}
/**
* 修改密码
*/
export
function
modifyPasswordApi
(
data
)
{
return
putReq
(
'
/api/v1/users/password
'
,
data
);
}
/**
* 修改用户信息
*/
export
function
updateUserInfoApi
(
data
)
{
return
putReq
(
'
/api/v1/users/profile
'
,
data
);
}
/**
* 获取当前用户信息
*/
export
function
getUserInfoApi
()
{
return
getReq
(
'
/api/v1/detail
'
);
}
/**
* 上传文件
*/
export
function
uploadFileApi
(
modelName
,
file
)
{
const
formData
=
new
FormData
();
formData
.
append
(
'
modelName
'
,
modelName
);
formData
.
append
(
'
file
'
,
file
);
return
postReq
(
'
/api/v1/upload
'
,
formData
);
}
src/components/index.js
View file @
d8b5fd57
import
Table
from
'
./table/index.vue
'
;
import
WhiteCard
from
'
./white_card/index.vue
'
;
import
Upload
from
'
./upload/index.vue
'
;
export
{
Table
};
export
{
Table
,
WhiteCard
,
Upload
};
src/components/table/index.vue
View file @
d8b5fd57
<
template
>
<div>
<
div
:class=
"$style.card"
v-if=
"$scopedSlots.search"
>
<
my-card
v-if=
"$scopedSlots.search"
>
<a-form-model
layout=
"inline"
:model=
"queryForm"
>
<slot
name=
"search"
:query=
"queryForm"
/>
</a-form-model>
...
...
@@ -11,9 +11,9 @@
<a-button
type=
"primary"
@
click=
"getData"
>
查询
</a-button>
</a-space>
</div>
</
div
>
</
my-card
>
<
div
class=
"tw-mt-3"
:class=
"$style.card
"
>
<
my-card
class=
"tw-mt-3
"
>
<a-space
class=
"tw-mb-2.5"
>
<a-button
v-if=
"addBtn"
type=
"primary"
key=
"add"
v-bind=
"addBtn.options"
@
click=
"add"
>
{{
addBtn
.
text
||
'
新建
'
}}
...
...
@@ -32,7 +32,7 @@
>
<slot
/>
</a-table>
</
div
>
</
my-card
>
<!-- 新增 -->
<a-drawer
...
...
@@ -196,9 +196,3 @@ export default {
},
};
</
script
>
<
style
module
>
.card
{
@apply
tw-bg-white
tw-rounded-md
tw-p-4;
}
</
style
>
src/components/transition/PageToggleTransition.vue
View file @
d8b5fd57
...
...
@@ -10,85 +10,82 @@
</
template
>
<
script
>
import
{
globalConfig
}
from
'
@/config
'
import
{
globalConfig
}
from
'
@/config
'
;
const
animates
=
globalConfig
.
animates
.
preset
;
const
animates
=
globalConfig
.
animates
.
preset
;
export
default
{
export
default
{
name
:
'
PageToggleTransition
'
,
props
:
{
disabled
:
{
type
:
Boolean
,
default
:
false
default
:
false
,
},
animate
:
{
type
:
String
,
validator
(
value
)
{
return
animates
.
findIndex
(
item
=>
item
.
name
==
value
)
!=
-
1
return
animates
.
findIndex
(
item
=>
item
.
name
==
value
)
!=
-
1
;
},
default
:
'
bounce
'
default
:
'
bounce
'
,
},
direction
:
{
type
:
String
,
},
reverse
:
{
type
:
Boolean
,
default
:
true
}
default
:
true
,
},
},
computed
:
{
enterAnimate
()
{
return
this
.
activeClass
(
false
)
return
this
.
activeClass
(
false
);
},
leaveAnimate
()
{
return
this
.
activeClass
(
true
)
}
return
this
.
activeClass
(
true
);
},
},
methods
:
{
activeClass
(
isLeave
)
{
let
animate
=
animates
.
find
(
item
=>
this
.
animate
==
item
.
name
)
let
animate
=
animates
.
find
(
item
=>
this
.
animate
==
item
.
name
);
if
(
animate
==
undefined
)
{
return
''
return
''
;
}
let
direction
=
''
let
direction
=
''
;
if
(
this
.
direction
==
undefined
)
{
direction
=
animate
.
directions
[
0
]
direction
=
animate
.
directions
[
0
];
}
else
{
direction
=
animate
.
directions
.
find
(
item
=>
item
==
this
.
direction
)
direction
=
animate
.
directions
.
find
(
item
=>
item
==
this
.
direction
);
}
direction
=
(
direction
==
undefined
||
direction
===
'
default
'
)
?
''
:
direction
direction
=
direction
==
undefined
||
direction
===
'
default
'
?
''
:
direction
;
if
(
direction
!=
''
)
{
direction
=
isLeave
&&
this
.
reverse
?
this
.
reversePosition
(
direction
,
animate
.
directions
)
:
direction
direction
=
direction
[
0
].
toUpperCase
()
+
direction
.
substring
(
1
)
direction
=
isLeave
&&
this
.
reverse
?
this
.
reversePosition
(
direction
,
animate
.
directions
)
:
direction
;
direction
=
direction
[
0
].
toUpperCase
()
+
direction
.
substring
(
1
);
}
let
t
=
isLeave
?
'
Out
'
:
'
In
'
return
animate
.
name
+
t
+
direction
let
t
=
isLeave
?
'
Out
'
:
'
In
'
;
return
animate
.
name
+
t
+
direction
;
},
reversePosition
(
direction
,
directions
)
{
if
(
direction
.
length
==
0
||
direction
==
'
x
'
||
direction
==
'
y
'
)
{
return
direction
}
let
index
=
directions
.
indexOf
(
direction
)
index
=
(
index
%
2
==
1
)
?
index
-
1
:
index
+
1
return
directions
[
index
]
}
}
if
(
direction
.
length
==
0
||
direction
==
'
x
'
||
direction
==
'
y
'
)
{
return
direction
;
}
let
index
=
directions
.
indexOf
(
direction
);
index
=
index
%
2
==
1
?
index
-
1
:
index
+
1
;
return
directions
[
index
];
},
},
};
</
script
>
<
style
lang=
"less"
>
.page-toggle-enter-active
{
.page-toggle-enter-active
{
position: absolute !important;
animation-duration: 0.8s !important;
width: calc(100%) !important;
}
.page-toggle-leave-active
{
}
.page-toggle-leave-active
{
position: absolute !important;
animation-duration: 0.8s !important;
width: calc(100%) !important;
}
.page-toggle-enter{
}
.page-toggle-leave-to{
}
}
</
style
>
src/components/upload/index.vue
0 → 100644
View file @
d8b5fd57
<
template
>
<a-upload
:customRequest=
"customRequest"
:showUploadList=
"showUploadList"
v-bind=
"$attrs"
>
<slot>
<a-button>
<a-icon
type=
"upload"
/>
上传
</a-button>
</slot>
</a-upload>
</
template
>
<
script
>
import
{
uploadFileApi
}
from
'
@/api
'
;
export
default
{
props
:
{
value
:
[
String
,
Array
],
modelName
:
{
type
:
String
,
default
:
'
adminSystem
'
,
},
showUploadList
:
{
type
:
[
Object
,
Boolean
],
default
:
false
,
},
},
model
:
{
prop
:
'
value
'
,
event
:
'
change
'
,
},
methods
:
{
async
customRequest
(
info
)
{
const
{
file
}
=
info
;
try
{
const
res
=
await
uploadFileApi
(
this
.
modelName
,
file
);
this
.
$message
.
success
(
'
上传成功
'
);
this
.
$emit
(
'
change
'
,
res
.
fileSrc
);
}
catch
(
error
)
{
this
.
$message
.
error
(
'
上传失败
'
);
}
},
},
};
</
script
>
src/components/white_card/index.vue
0 → 100644
View file @
d8b5fd57
<
template
>
<div
:class=
"$style.card"
>
<slot
/>
</div>
</
template
>
<
style
module
src=
"@/style/index.css"
/>
src/main.js
View file @
d8b5fd57
...
...
@@ -6,6 +6,7 @@ import Router from 'vue-router';
import
{
initRouter
}
from
'
./router
'
;
import
VueI18n
from
'
vue-i18n
'
;
import
{
accountModule
,
settingModule
}
from
'
./pages/frame/store
'
;
import
globalStore
from
'
@/store
'
;
import
App
from
'
./App.vue
'
;
import
'
tailwindcss/tailwind.css
'
;
...
...
@@ -27,6 +28,7 @@ Vue.config.productionTip = false;
Vue
.
use
(
Vuex
);
//加载 框架的module包括 命名空间accountModule,settingModule
const
store
=
new
Vuex
.
Store
({
...
globalStore
,
modules
:
{
accountModule
,
settingModule
},
});
...
...
src/pages/frame/components/header/LayoutTopHeaderAvatar.vue
View file @
d8b5fd57
<
template
>
<a-dropdown>
<div
class=
"tw-inline-flex tw-cursor-pointer tw-items-center"
>
<a-avatar
class=
"tw-mr-3"
size=
"small"
shape=
"circle"
:src=
"user
.a
vatar"
/>
<span>
{{
user
.
n
ame
}}
</span>
<a-avatar
class=
"tw-mr-3"
size=
"small"
shape=
"circle"
:src=
"user
Info.userA
vatar"
/>
<span>
{{
user
Info
.
userN
ame
}}
</span>
</div>
<a-menu
style=
"width: 150px"
slot=
"overlay"
>
<a-menu-item
@
click=
"toUserCenter"
>
...
...
@@ -19,7 +19,7 @@
</
template
>
<
script
>
import
{
map
Getters
}
from
'
vuex
'
;
import
{
map
State
}
from
'
vuex
'
;
import
{
logout
}
from
'
@/pages/frame/services/accountService
'
;
import
layoutTopHeaderI18n
from
'
./i18n
'
;
...
...
@@ -27,7 +27,8 @@ export default {
name
:
'
LayoutTopHeaderAvatar
'
,
i18n
:
layoutTopHeaderI18n
,
computed
:
{
...
mapGetters
(
'
accountModule
'
,
[
'
user
'
]),
...
mapState
([
'
userInfo
'
]),
profile
()
{
return
this
.
$t
(
'
profile
'
);
},
...
...
@@ -38,6 +39,9 @@ export default {
return
this
.
$t
(
'
loginOut
'
);
},
},
mounted
()
{
this
.
$store
.
dispatch
(
'
getUserInfo
'
);
},
methods
:
{
logout
()
{
logout
();
...
...
src/pages/frame/components/tab/LayoutTabsHeader.vue
View file @
d8b5fd57
<
template
>
<div
:class=
"['tabs-head', layout, pageWidth]"
>
<a-tabs
type=
"editable-card"
:class=
"['tabs-container', layout, pageWidth,
{'affixed' : affixed, 'fixed-header' : fixedHeader, 'collapsed' : adminLayout.collapsed}]" :active-key="active" :hide-add="true">
<a-tabs
type=
"editable-card"
:class=
"[
'tabs-container',
layout,
pageWidth,
{ affixed: affixed, 'fixed-header': fixedHeader, collapsed: adminLayout.collapsed },
]"
:active-key="active"
:hide-add="true"
>
<a-tooltip
placement=
"left"
:title=
"lockTitle"
slot=
"tabBarExtraContent"
>
<a-icon
theme=
"filled"
@
click=
"onLockClick"
class=
"header-lock"
:type=
"fixedTabs ? 'lock' : 'unlock'"
/>
<a-icon
theme=
"filled"
@
click=
"onLockClick"
class=
"header-lock"
:type=
"fixedTabs ? 'lock' : 'unlock'"
/>
</a-tooltip>
<a-tab-pane
v-for=
"page in pageList"
:key=
"page.fullPath"
>
<div
slot=
"tab"
class=
"tab"
@
contextmenu=
"e => onContextmenu(page.fullPath, e)"
>
<a-icon
@
click=
"onRefresh(page)"
:class=
"['icon-sync',
{'hide': page.fullPath !== active
&&
!page.loading}]" :type="page.loading ? 'loading' : 'sync'" />
<div
class=
"title"
@
click=
"onTabClick(page.fullPath)"
>
{{
pageName
(
page
)
}}
</div>
<a-icon
v-if=
"!page.unclose"
@
click=
"onClose(page.fullPath)"
class=
"icon-close"
type=
"close"
/>
<a-icon
@
click=
"onRefresh(page)"
:class=
"['icon-sync',
{ hide: page.fullPath !== active
&&
!page.loading }]"
:type="page.loading ? 'loading' : 'sync'"
/>
<div
class=
"title"
@
click=
"onTabClick(page.fullPath)"
>
{{
pageName
(
page
)
}}
</div>
<a-icon
v-if=
"!page.unclose"
@
click=
"onClose(page.fullPath)"
class=
"icon-close"
type=
"close"
/>
</div>
</a-tab-pane>
</a-tabs>
...
...
@@ -72,7 +96,7 @@ export default {
},
pageName
(
page
)
{
const
pagePath
=
page
.
fullPath
.
split
(
'
?
'
)[
0
];
const
custom
=
this
.
customTitles
.
find
(
(
item
)
=>
item
.
path
===
pagePath
);
const
custom
=
this
.
customTitles
.
find
(
item
=>
item
.
path
===
pagePath
);
return
(
custom
&&
custom
.
title
)
||
page
.
title
||
this
.
$t
(
getI18nKey
(
page
.
keyPath
));
},
},
...
...
src/pages/frame/view/template/BlankTemplateView.vue
View file @
d8b5fd57
<
template
>
<page-toggle-transition
:disabled=
"animate.disabled"
:animate=
"animate.name"
:direction=
"animate.direction"
>
<page-toggle-transition
:disabled=
"animate.disabled"
:animate=
"animate.name"
:direction=
"animate.direction"
>
<router-view
/>
</page-toggle-transition>
</
template
>
<
script
>
import
PageToggleTransition
from
'
@/components/transition/PageToggleTransition
'
;
import
PageToggleTransition
from
'
@/components/transition/PageToggleTransition
.vue
'
;
import
{
mapState
}
from
'
vuex
'
;
export
default
{
...
...
@@ -16,6 +20,3 @@ export default {
},
};
</
script
>
<
style
scoped
>
</
style
>
src/pages/frame/view/template/TabsTemplateView.vue
View file @
d8b5fd57
<
template
>
<admin-layout>
<contextmenu
:itemList=
"menuItemList"
:visible.sync=
"menuVisible"
@
select=
"onMenuSelect"
/>
<layout-tabs-header
v-if=
"multiPage"
:active=
"activePage"
:page-list=
"pageList"
@
change=
"changePage"
@
close=
"remove"
@
refresh=
"refresh"
@
contextmenu=
"onContextmenu"
/>
<div
:class=
"['tabs-view-content', layout, pageWidth]"
:style=
"`margin-top: $
{multiPage ? -24 : 0}px`">
<page-toggle-transition
:disabled=
"animate.disabled"
:animate=
"animate.name"
:direction=
"animate.direction"
>
<layout-tabs-header
v-if=
"multiPage"
:active=
"activePage"
:page-list=
"pageList"
@
change=
"changePage"
@
close=
"remove"
@
refresh=
"refresh"
@
contextmenu=
"onContextmenu"
/>
<div
:class=
"['tabs-view-content', layout, pageWidth]"
:style=
"`margin-top: $
{multiPage ? -20 : 0}px`"
>
<page-toggle-transition
:disabled=
"animate.disabled"
:animate=
"animate.name"
:direction=
"animate.direction"
>
<a-keep-alive
:exclude-keys=
"excludeKeys"
v-if=
"multiPage && cachePage"
v-model=
"clearCaches"
>
<router-view
v-if=
"!refreshing"
ref=
"tabContent"
:key=
"$route.fullPath"
/>
</a-keep-alive>
...
...
@@ -15,7 +30,7 @@
<
script
>
import
AdminLayout
from
'
../../layouts/AdminLayout
'
;
import
Contextmenu
from
'
@/components/menu/Contextmenu
'
;
import
Contextmenu
from
'
@/components/menu/Contextmenu
.vue
'
;
import
PageToggleTransition
from
'
@/components/transition/PageToggleTransition
'
;
import
{
mapState
,
mapMutations
}
from
'
vuex
'
;
import
{
getI18nKey
}
from
'
@/utils/routerUtil
'
;
...
...
@@ -56,7 +71,7 @@ export default {
this
.
loadCacheConfig
(
this
.
$router
?.
options
?.
routes
);
this
.
loadCachedTabs
();
const
route
=
this
.
$route
;
if
(
this
.
pageList
.
findIndex
(
(
item
)
=>
item
.
fullPath
===
route
.
fullPath
)
===
-
1
)
{
if
(
this
.
pageList
.
findIndex
(
item
=>
item
.
fullPath
===
route
.
fullPath
)
===
-
1
)
{
this
.
pageList
.
push
(
this
.
createPage
(
route
));
}
this
.
activePage
=
route
.
fullPath
;
...
...
@@ -75,11 +90,11 @@ export default {
this
.
correctPageMinHeight
(
this
.
tabsOffset
);
},
watch
:
{
'
$router.options.routes
'
:
function
(
val
)
{
'
$router.options.routes
'
:
function
(
val
)
{
this
.
excludeKeys
=
[];
this
.
loadCacheConfig
(
val
);
},
$route
:
function
(
newRoute
)
{
$route
:
function
(
newRoute
)
{
this
.
activePage
=
newRoute
.
fullPath
;
console
.
log
(
'
#################################
'
);
...
...
@@ -87,7 +102,7 @@ export default {
console
.
log
(
newRoute
);
console
.
log
(
'
#################################
'
);
if
(
this
.
pageList
.
findIndex
(
(
item
)
=>
item
.
fullPath
===
newRoute
.
fullPath
)
===
-
1
)
{
if
(
this
.
pageList
.
findIndex
(
item
=>
item
.
fullPath
===
newRoute
.
fullPath
)
===
-
1
)
{
if
(
!
this
.
multiPage
)
{
this
.
pageList
=
[
this
.
createPage
(
newRoute
)];
}
else
{
...
...
@@ -100,7 +115,7 @@ export default {
}
}
},
multiPage
:
function
(
newVal
)
{
multiPage
:
function
(
newVal
)
{
if
(
!
newVal
)
{
this
.
pageList
=
[
this
.
createPage
(
this
.
$route
)];
this
.
removeListener
();
...
...
@@ -122,8 +137,8 @@ export default {
return
this
.
$message
.
warning
(
this
.
$t
(
'
tabs.warn
'
));
}
//清除缓存
let
index
=
this
.
pageList
.
findIndex
(
(
item
)
=>
item
.
fullPath
===
key
);
this
.
clearCaches
=
this
.
pageList
.
splice
(
index
,
1
).
map
(
(
page
)
=>
page
.
cachedKey
);
let
index
=
this
.
pageList
.
findIndex
(
item
=>
item
.
fullPath
===
key
);
this
.
clearCaches
=
this
.
pageList
.
splice
(
index
,
1
).
map
(
page
=>
page
.
cachedKey
);
if
(
next
)
{
this
.
$router
.
push
(
next
);
}
else
if
(
key
===
this
.
activePage
)
{
...
...
@@ -133,7 +148,7 @@ export default {
}
},
refresh
(
key
,
page
)
{
page
=
page
||
this
.
pageList
.
find
(
(
item
)
=>
item
.
fullPath
===
key
);
page
=
page
||
this
.
pageList
.
find
(
item
=>
item
.
fullPath
===
key
);
page
.
loading
=
true
;
this
.
clearCache
(
page
);
if
(
key
===
this
.
activePage
)
{
...
...
@@ -170,9 +185,9 @@ export default {
},
closeOthers
(
pageKey
)
{
// 清除缓存
const
clearPages
=
this
.
pageList
.
filter
(
(
item
)
=>
item
.
fullPath
!==
pageKey
&&
!
item
.
unclose
);
this
.
clearCaches
=
clearPages
.
map
(
(
item
)
=>
item
.
cachedKey
);
this
.
pageList
=
this
.
pageList
.
filter
(
(
item
)
=>
!
clearPages
.
includes
(
item
));
const
clearPages
=
this
.
pageList
.
filter
(
item
=>
item
.
fullPath
!==
pageKey
&&
!
item
.
unclose
);
this
.
clearCaches
=
clearPages
.
map
(
item
=>
item
.
cachedKey
);
this
.
pageList
=
this
.
pageList
.
filter
(
item
=>
!
clearPages
.
includes
(
item
));
// 判断跳转
if
(
this
.
activePage
!=
pageKey
)
{
this
.
activePage
=
pageKey
;
...
...
@@ -180,25 +195,25 @@ export default {
}
},
closeLeft
(
pageKey
)
{
const
index
=
this
.
pageList
.
findIndex
(
(
item
)
=>
item
.
fullPath
===
pageKey
);
const
index
=
this
.
pageList
.
findIndex
(
item
=>
item
.
fullPath
===
pageKey
);
// 清除缓存
const
clearPages
=
this
.
pageList
.
filter
((
item
,
i
)
=>
i
<
index
&&
!
item
.
unclose
);
this
.
clearCaches
=
clearPages
.
map
(
(
item
)
=>
item
.
cachedKey
);
this
.
pageList
=
this
.
pageList
.
filter
(
(
item
)
=>
!
clearPages
.
includes
(
item
));
this
.
clearCaches
=
clearPages
.
map
(
item
=>
item
.
cachedKey
);
this
.
pageList
=
this
.
pageList
.
filter
(
item
=>
!
clearPages
.
includes
(
item
));
// 判断跳转
if
(
!
this
.
pageList
.
find
(
(
item
)
=>
item
.
fullPath
===
this
.
activePage
))
{
if
(
!
this
.
pageList
.
find
(
item
=>
item
.
fullPath
===
this
.
activePage
))
{
this
.
activePage
=
pageKey
;
this
.
$router
.
push
(
this
.
activePage
);
}
},
closeRight
(
pageKey
)
{
// 清除缓存
const
index
=
this
.
pageList
.
findIndex
(
(
item
)
=>
item
.
fullPath
===
pageKey
);
const
index
=
this
.
pageList
.
findIndex
(
item
=>
item
.
fullPath
===
pageKey
);
const
clearPages
=
this
.
pageList
.
filter
((
item
,
i
)
=>
i
>
index
&&
!
item
.
unclose
);
this
.
clearCaches
=
clearPages
.
map
(
(
item
)
=>
item
.
cachedKey
);
this
.
pageList
=
this
.
pageList
.
filter
(
(
item
)
=>
!
clearPages
.
includes
(
item
));
this
.
clearCaches
=
clearPages
.
map
(
item
=>
item
.
cachedKey
);
this
.
pageList
=
this
.
pageList
.
filter
(
item
=>
!
clearPages
.
includes
(
item
));
// 判断跳转
if
(
!
this
.
pageList
.
find
(
(
item
)
=>
item
.
fullPath
===
this
.
activePage
))
{
if
(
!
this
.
pageList
.
find
(
item
=>
item
.
fullPath
===
this
.
activePage
))
{
this
.
activePage
=
pageKey
;
this
.
$router
.
push
(
this
.
activePage
);
}
...
...
@@ -259,7 +274,7 @@ export default {
* 页面 unload 事件监听器,添加页签到 session 缓存,用于刷新时保留页签
*/
unloadListener
()
{
const
tabs
=
this
.
pageList
.
map
(
(
item
)
=>
({
...
item
,
_init_
:
false
}));
const
tabs
=
this
.
pageList
.
map
(
item
=>
({
...
item
,
_init_
:
false
}));
sessionStorage
.
setItem
(
process
.
env
.
VUE_APP_TBAS_KEY
,
JSON
.
stringify
(
tabs
));
},
createPage
(
route
)
{
...
...
@@ -276,7 +291,7 @@ export default {
* @param route 页面对应的路由
*/
setCachedKey
(
route
)
{
const
page
=
this
.
pageList
.
find
(
(
item
)
=>
item
.
fullPath
===
route
.
fullPath
);
const
page
=
this
.
pageList
.
find
(
item
=>
item
.
fullPath
===
route
.
fullPath
);
page
.
unclose
=
route
.
meta
&&
route
.
meta
.
page
&&
route
.
meta
.
page
.
closable
===
false
;
if
(
!
page
.
_init_
)
{
const
vnode
=
this
.
$refs
.
tabContent
.
$vnode
;
...
...
@@ -303,7 +318,7 @@ export default {
}
},
loadCacheConfig
(
routes
,
pCache
=
true
)
{
routes
.
forEach
(
(
item
)
=>
{
routes
.
forEach
(
item
=>
{
const
cacheAble
=
item
.
meta
?.
page
?.
cacheAble
??
pCache
??
true
;
if
(
!
cacheAble
)
{
this
.
excludeKeys
.
push
(
new
RegExp
(
`
${
item
.
fullPath
}
\\d+$`
));
...
...
src/pages/user/components/ToDo.vue
0 → 100644
View file @
d8b5fd57
<
template
>
<h1>
TODO
</h1>
</
template
>
src/pages/user/components/info.vue
0 → 100644
View file @
d8b5fd57
<
template
>
<div
class=
"tw-flex"
>
<a-form-model
layout=
"vertical"
style=
"flex: 0 0 400px"
>
<a-form-model-item
label=
"用户账户"
>
<a-input
disabled
:value=
"loginId"
/>
</a-form-model-item>
<a-form-model-item
label=
"姓名"
>
<a-input
v-model=
"form.userName"
/>
</a-form-model-item>
<a-form-model-item
label=
"固定电话"
>
<a-input
v-model=
"form.fixedPhone"
/>
</a-form-model-item>
<a-form-model-item
label=
"移动电话"
>
<a-input
v-model=
"form.mobilePhone"
/>
</a-form-model-item>
<a-form-model-item
label=
"电子邮箱"
>
<a-input
v-model=
"form.userEmail"
/>
</a-form-model-item>
<a-form-model-item>
<a-button
type=
"primary"
:loading=
"loading"
@
click=
"update"
>
更新信息
</a-button>
</a-form-model-item>
</a-form-model>
<div
style=
"flex: 0 0 300px"
class=
"tw-flex tw-flex-col tw-items-center "
>
<div>
头像
</div>
<img
style=
"width: 100px;height: 100px"
class=
"tw-max-w-full tw-max-h-full tw-rounded-full tw-my-4"
:src=
"`//$
{form.userAvatar}`"
/>
<my-upload
v-model=
"form.userAvatar"
/>
</div>
</div>
</
template
>
<
script
>
import
{
updateUserInfoApi
}
from
'
@/api
'
;
export
default
{
data
:
()
=>
({
form
:
{
userName
:
''
,
mobilePhone
:
''
,
fixedPhone
:
''
,
userEmail
:
''
,
userAvatar
:
''
,
},
loading
:
false
,
}),
computed
:
{
loginId
()
{
return
this
.
$store
.
state
.
userInfo
.
loginId
;
},
},
watch
:
{
'
$store.state.userInfo
'
(
userInfo
)
{
this
.
form
.
userName
=
userInfo
.
userName
;
this
.
form
.
fixedPhone
=
userInfo
.
fixedPhone
;
this
.
form
.
mobilePhone
=
userInfo
.
mobilePhone
;
this
.
form
.
userEmail
=
userInfo
.
userEmail
;
this
.
form
.
userAvatar
=
userInfo
.
userAvatar
;
},
},
methods
:
{
async
update
()
{
this
.
loading
=
true
;
await
updateUserInfoApi
(
this
.
form
);
this
.
loading
=
false
;
this
.
$store
.
commit
(
'
setUserInfo
'
,
{
...
this
.
$store
.
state
.
userInfo
,
...
this
.
form
});
this
.
$message
.
success
(
'
更新成功
'
);
},
},
};
</
script
>
src/pages/user/components/message.vue
0 → 100644
View file @
d8b5fd57
<
template
>
<h1>
消息仲系
</h1>
</
template
>
src/pages/user/components/modify_password.vue
0 → 100644
View file @
d8b5fd57
<
template
>
<a-form-model
layout=
"vertical"
style=
"width: 500px"
:model=
"form"
:rules=
"rules"
ref=
"form"
>
<a-form-model-item
label=
"原始密码"
prop=
"oldPassword"
>
<a-input-password
v-model=
"form.oldPassword"
/>
</a-form-model-item>
<a-form-model-item
label=
"新密码"
prop=
"newPassword"
>
<a-input-password
v-model=
"form.newPassword"
/>
</a-form-model-item>
<a-form-model-item
label=
"确认新密码"
prop=
"confirmPassword"
>
<a-input-password
v-model=
"form.confirmPassword"
/>
</a-form-model-item>
<a-form-model-item>
<a-button
type=
"primary"
@
click=
"modifyPassword"
:loading=
"loading"
>
修改密码
</a-button>
</a-form-model-item>
</a-form-model>
</
template
>
<
script
>
import
{
modifyPasswordApi
}
from
'
@/api
'
;
import
{
EMPTY_FUN
}
from
'
@/utils
'
;
import
md5
from
'
crypto-js/md5
'
;
export
default
{
data
:
vm
=>
({
form
:
{
newPassword
:
''
,
oldPassword
:
''
,
confirmPassword
:
''
,
},
rules
:
{
newPassword
:
[{
required
:
true
}],
oldPassword
:
[{
required
:
true
}],
confirmPassword
:
[
{
required
:
true
},
{
validator
(
rule
,
value
,
callback
)
{
if
(
value
!==
vm
.
form
.
newPassword
)
callback
(
'
两次密码不一致
'
);
callback
();
},
},
],
},
loading
:
false
,
}),
methods
:
{
modifyPassword
()
{
this
.
$refs
.
form
.
validate
()
.
then
(
async
()
=>
{
try
{
this
.
loading
=
true
;
await
modifyPasswordApi
({
newPassword
:
md5
(
this
.
form
.
newPassword
).
toString
(),
oldPassword
:
md5
(
this
.
form
.
oldPassword
).
toString
(),
});
this
.
$message
.
success
(
'
修改成功
'
);
}
catch
(
error
)
{
// todo
this
.
$message
.
error
(
'
服务器异常
'
);
}
this
.
loading
=
false
;
})
.
catch
(
EMPTY_FUN
);
},
},
};
</
script
>
src/pages/user/components/todo.vue
0 → 100644
View file @
d8b5fd57
src/pages/user/index.vue
View file @
d8b5fd57
<
template
>
<h1>
用户个人中心
</h1>
<my-card
class=
"tw-flex"
>
<a-menu
style=
"flex: 0 0 100px"
v-model=
"selectKeys"
>
<a-menu-item
key=
"UserInfo"
>
个人信息
</a-menu-item>
<a-menu-item
key=
"ModifyPassword"
>
修改密码
</a-menu-item>
<a-menu-item
key=
"MessageCenter"
>
消息中心
</a-menu-item>
<a-menu-item
key=
"ToDo"
>
代办事宜
</a-menu-item>
</a-menu>
<div
class=
"tw-flex-1 tw-ml-6"
>
<component
:is=
"currentCom"
/>
</div>
</my-card>
</
template
>
<
script
>
import
UserInfo
from
'
./components/info.vue
'
;
import
MessageCenter
from
'
./components/message.vue
'
;
import
ToDo
from
'
./components/todo.vue
'
;
import
ModifyPassword
from
'
./components/modify_password.vue
'
;
const
components
=
{
UserInfo
,
ToDo
,
MessageCenter
,
ModifyPassword
,
};
export
default
{
data
()
{
return
{
selectKeys
:
[
'
UserInfo
'
],
};
},
computed
:
{
currentCom
()
{
return
components
[
this
.
selectKeys
[
0
]];
},
},
};
</
script
>
src/plugins/index.js
View file @
d8b5fd57
import
VueI18nPlugin
from
'
./vueI18nPlugin
'
;
import
AuthorityPlugin
from
'
./authorityPlugin
'
;
import
TabsPagePlugin
from
'
./tabsPagePlugin
'
;
import
{
Table
}
from
'
@/components
'
;
import
{
Table
,
WhiteCard
,
Upload
}
from
'
@/components
'
;
const
Plugins
=
{
install
:
function
(
Vue
)
{
...
...
@@ -9,6 +9,8 @@ const Plugins = {
Vue
.
use
(
AuthorityPlugin
);
Vue
.
use
(
TabsPagePlugin
);
Vue
.
component
(
'
my-table
'
,
Table
);
Vue
.
component
(
'
my-card
'
,
WhiteCard
);
Vue
.
component
(
'
my-upload
'
,
Upload
);
},
};
export
default
Plugins
;
src/router/config.js
View file @
d8b5fd57
...
...
@@ -32,7 +32,7 @@ const options = {
children
:
[
{
path
:
'
home
'
,
name
:
'
Home
'
,
name
:
'
首页
'
,
meta
:
{
icon
:
'
home
'
},
component
:
()
=>
import
(
'
@/pages/home/index.vue
'
),
},
...
...
src/store/index.js
0 → 100644
View file @
d8b5fd57
import
{
getUserInfoApi
}
from
'
@/api
'
;
export
default
{
state
:
{
userInfo
:
{},
},
mutations
:
{
setUserInfo
(
state
,
userInfo
)
{
state
.
userInfo
=
userInfo
;
},
},
actions
:
{
async
getUserInfo
({
commit
})
{
const
userInfo
=
await
getUserInfoApi
();
commit
(
'
setUserInfo
'
,
userInfo
);
},
},
};
src/style/index.css
0 → 100644
View file @
d8b5fd57
.card
{
@apply
tw-bg-white
tw-rounded-md
tw-p-4;
}
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