Skip to content

Commit b521177

Browse files
committed
refactor: 调整View Page
1 parent 3466029 commit b521177

38 files changed

+688
-1095
lines changed

src/component/base/page-panel.vue

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
<header
44
v-if="title || hasTitleSlot || hasActionsSlot"
55
class="page-panel__header"
6-
:class="{ 'page-panel__header--with-actions': hasActionsSlot }"
6+
:class="{
7+
'page-panel__header--with-actions': hasActionsSlot,
8+
'page-panel__header--sticky': stickyHeader,
9+
}"
710
:style="headerStyle"
811
>
912
<div class="page-panel__title">
@@ -27,53 +30,56 @@ defineOptions({
2730
name: 'PagePanel',
2831
})
2932
30-
const { title, headerPadding, bodyPadding, bodyClass } = defineProps({
33+
const { title, headerPadding, bodyPadding, bodyClass, stickyHeader, stickyTop } = defineProps({
3134
title: {
3235
type: String,
3336
default: '',
3437
},
3538
headerPadding: {
3639
type: String,
37-
default: '0 40px',
40+
default: '0 30px',
3841
},
3942
bodyPadding: {
4043
type: String,
41-
default: '20px',
44+
default: '',
4245
},
4346
bodyClass: {
4447
type: [String, Array, Object],
4548
default: '',
4649
},
50+
stickyHeader: {
51+
type: Boolean,
52+
default: true,
53+
},
54+
stickyTop: {
55+
type: String,
56+
default: '0px',
57+
},
4758
})
4859
4960
const slots = useSlots()
5061
const hasTitleSlot = computed(() => Boolean(slots.title))
5162
const hasActionsSlot = computed(() => Boolean(slots.actions))
5263
const headerStyle = computed(() => ({
5364
'--page-panel-header-padding': headerPadding,
65+
'--page-panel-sticky-top': stickyTop,
5466
}))
5567
const bodyStyle = computed(() => ({
56-
'--page-panel-body-padding': bodyPadding,
68+
'--page-panel-body-padding': resolveBodyPadding(),
5769
}))
70+
71+
function resolveBodyPadding() {
72+
if (bodyPadding) {
73+
return bodyPadding
74+
}
75+
76+
return '20px 30px 30px'
77+
}
5878
</script>
5979

6080
<style lang="scss" scoped>
6181
.page-panel {
6282
position: relative;
63-
overflow: hidden;
64-
background: var(--theme-panel-gradient);
65-
border: 1px solid var(--theme-border);
66-
border-radius: 18px;
67-
box-shadow: var(--theme-panel-shadow);
68-
69-
&:before {
70-
content: '';
71-
position: absolute;
72-
inset: 0 0 auto;
73-
height: 68px;
74-
background: linear-gradient(180deg, var(--theme-panel-highlight), transparent);
75-
pointer-events: none;
76-
}
7783
}
7884
7985
.page-panel__header {
@@ -83,14 +89,27 @@ const bodyStyle = computed(() => ({
8389
min-height: 59px;
8490
padding: var(--page-panel-header-padding);
8591
border-bottom: 1px solid var(--theme-border);
86-
background: linear-gradient(180deg, rgba(255, 255, 255, 0.14), transparent);
8792
}
8893
8994
.page-panel__header--with-actions {
9095
justify-content: space-between;
9196
gap: 16px;
9297
}
9398
99+
.page-panel__header--sticky {
100+
position: sticky;
101+
top: var(--page-panel-sticky-top);
102+
z-index: 9;
103+
}
104+
105+
.page-panel__header--sticky:before {
106+
content: '';
107+
position: absolute;
108+
inset: 0;
109+
z-index: -1;
110+
background: var(--theme-main-bg);
111+
}
112+
94113
.page-panel__title {
95114
min-width: 0;
96115
color: $parent-title-color;
@@ -103,11 +122,26 @@ const bodyStyle = computed(() => ({
103122
.page-panel__actions {
104123
display: flex;
105124
align-items: center;
125+
justify-content: flex-end;
126+
flex-wrap: wrap;
106127
gap: 12px;
128+
min-width: 0;
107129
}
108130
109131
.page-panel__body {
110132
position: relative;
111133
padding: var(--page-panel-body-padding);
112134
}
135+
136+
@media screen and (width <= 680px) {
137+
.page-panel__header--with-actions {
138+
align-items: stretch;
139+
flex-direction: column;
140+
}
141+
142+
.page-panel__actions {
143+
width: 100%;
144+
justify-content: flex-start;
145+
}
146+
}
113147
</style>

src/component/layout/use-current-user-profile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ElMessage } from 'element-plus'
22

3-
import { MAX_SUCCESS_CODE } from '@/config/global'
43
import { getInformation, updateProfile as updateUserProfile } from '@/model/user'
54
import { notifyRequestError } from '@/lin/util/request-error'
5+
import { isFailedResponse } from '@/lin/util/response'
66
import { mergeUserSnapshot } from '@/store/modules/user-helpers'
77

88
const defaultUserModel = {
@@ -26,7 +26,7 @@ export function useCurrentUserProfile({ userStore, message = ElMessage, userMode
2626
try {
2727
const result = await userModel.updateProfile(profile)
2828

29-
if (result.code >= MAX_SUCCESS_CODE) {
29+
if (isFailedResponse(result)) {
3030
message.error(result.message || failureMessage)
3131
return null
3232
}

src/lin/util/form.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
export async function validateElementForm(form) {
2+
if (!form) {
3+
return false
4+
}
5+
6+
try {
7+
await form.validate()
8+
return true
9+
} catch {
10+
return false
11+
}
12+
}
13+
14+
export function getRequiredFieldError(value, message = '信息不能为空') {
15+
return value ? '' : message
16+
}
17+
18+
export function getPasswordError(
19+
value,
20+
{ emptyMessage = '请输入密码', minLength = 6, minLengthMessage = `密码长度不能少于${minLength}位数` } = {},
21+
) {
22+
if (value === '') {
23+
return emptyMessage
24+
}
25+
26+
if (value.length < minLength) {
27+
return minLengthMessage
28+
}
29+
30+
return ''
31+
}
32+
33+
export function getConfirmedValueError(
34+
value,
35+
expectedValue,
36+
{ emptyMessage = '请再次输入密码', mismatchMessage = '两次输入密码不一致!' } = {},
37+
) {
38+
if (value === '') {
39+
return emptyMessage
40+
}
41+
42+
if (value !== expectedValue) {
43+
return mismatchMessage
44+
}
45+
46+
return ''
47+
}
48+
49+
export function createErrorMessageValidator(resolveErrorMessage, { onSuccess } = {}) {
50+
return (_, value, callback) => {
51+
const errorMessage = resolveErrorMessage(value)
52+
53+
if (errorMessage) {
54+
callback(new Error(errorMessage))
55+
return
56+
}
57+
58+
onSuccess?.(value)
59+
callback()
60+
}
61+
}
62+
63+
export function createRequiredRule(message = '信息不能为空', { trigger = 'blur' } = {}) {
64+
return {
65+
required: true,
66+
trigger,
67+
validator: createErrorMessageValidator(value => getRequiredFieldError(value, message)),
68+
}
69+
}

src/lin/util/response.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { MAX_SUCCESS_CODE } from '@/config/global'
2+
3+
export function isSuccessfulResponse(response = {}, successCode = MAX_SUCCESS_CODE) {
4+
return Number.isFinite(response?.code) && response.code < successCode
5+
}
6+
7+
export function isFailedResponse(response = {}, successCode = MAX_SUCCESS_CODE) {
8+
return !isSuccessfulResponse(response, successCode)
9+
}

src/view/admin/group/group-create.vue

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<template>
2-
<div class="container">
3-
<div class="title">新建分组信息</div>
2+
<PagePanel title="新建分组信息">
43
<div class="wrap">
54
<el-row>
65
<el-col :lg="16" :md="20" :sm="24" :xs="24">
@@ -31,13 +30,15 @@
3130
</el-col>
3231
</el-row>
3332
</div>
34-
</div>
33+
</PagePanel>
3534
</template>
3635

3736
<script setup>
3837
import { useTemplateRef } from 'vue'
3938
import { useRouter } from 'vue-router'
4039
40+
import PagePanel from '@/component/base/page-panel.vue'
41+
4142
import GroupPermissions from './group-permission'
4243
import { useGroupCreation } from './use-group-form'
4344
@@ -53,22 +54,7 @@ const { groupDraft, loading, resetGroupForm, rules, selectedPermissionIds, submi
5354
</script>
5455

5556
<style lang="scss" scoped>
56-
.container {
57-
padding: 0 30px;
58-
59-
.title {
60-
height: 59px;
61-
line-height: 59px;
62-
color: $parent-title-color;
63-
font-size: 16px;
64-
font-weight: 500;
65-
border-bottom: 1px solid #dae1ec;
66-
}
67-
68-
.wrap {
69-
padding: 20px;
70-
}
71-
57+
.wrap {
7258
.submit :deep(.el-form-item__content) {
7359
justify-content: flex-start;
7460
}
Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<template>
2-
<div class="container">
3-
<div class="title">编辑分组权限</div>
2+
<PagePanel title="编辑分组权限">
43
<div class="wrap">
54
<el-row>
65
<el-col :lg="16" :md="20" :sm="24" :xs="24">
@@ -16,12 +15,14 @@
1615
</el-col>
1716
</el-row>
1817
</div>
19-
</div>
18+
</PagePanel>
2019
</template>
2120

2221
<script setup>
2322
import { useRoute, useRouter } from 'vue-router'
2423
24+
import PagePanel from '@/component/base/page-panel.vue'
25+
2526
import GroupPermissions from './group-permission'
2627
import { useGroupPermissionEditor } from './use-group-form'
2728
@@ -36,28 +37,11 @@ const { groupId, selectedPermissionIds, handlePermissionsLoaded, applyPermission
3637
</script>
3738

3839
<style lang="scss" scoped>
39-
.container {
40-
padding: 0 30px;
41-
42-
.title {
43-
height: 59px;
44-
line-height: 59px;
45-
color: $parent-title-color;
46-
font-size: 16px;
47-
font-weight: 500;
48-
border-bottom: 1px solid #dae1ec;
49-
}
50-
51-
.wrap {
52-
padding: 20px;
53-
}
54-
55-
.actions {
56-
display: flex;
57-
align-items: center;
58-
gap: 12px;
59-
padding-left: 5px;
60-
margin-top: 30px;
61-
}
40+
.actions {
41+
display: flex;
42+
align-items: center;
43+
gap: 12px;
44+
padding-left: 5px;
45+
margin-top: 30px;
6246
}
6347
</style>

src/view/admin/group/group-helpers.js

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,6 @@ export function assignGroupDraft(target, source = {}) {
2929
target.info = source.info || ''
3030
}
3131

32-
export function createGroupRules() {
33-
const checkName = (_, value, callback) => {
34-
if (!value) {
35-
callback(new Error('分组名称不能为空'))
36-
return
37-
}
38-
39-
callback()
40-
}
41-
42-
return {
43-
info: [],
44-
name: [{ validator: checkName, trigger: ['blur', 'change'], required: true }],
45-
}
46-
}
47-
4832
export function buildGroupEditRoute(groupId) {
4933
return {
5034
path: '/admin/group/edit',
@@ -74,19 +58,6 @@ export function normalizePermissionIds(permissionIds = []) {
7458
return [...normalizedIds]
7559
}
7660

77-
export async function validateGroupForm(form) {
78-
if (!form) {
79-
return false
80-
}
81-
82-
try {
83-
await form.validate()
84-
return true
85-
} catch {
86-
return false
87-
}
88-
}
89-
9061
export function hasGroupInfoChanged(group, cacheGroup) {
9162
return cacheGroup.name !== group.name || cacheGroup.info !== group.info
9263
}

0 commit comments

Comments
 (0)