style(web): 统一后台图标与全局视觉
This commit is contained in:
1 parent
5c087f4db9
commit
97fbeda508
67 files changed
+737
-744
No files matched your search
+67
-22
@@ -29,11 +29,11 @@ const themeChange = () => {
|
||||
<div class="login-shell">
|
||||
<section class="login-hero">
|
||||
<div class="hero-brand">
|
||||
<img src="@/assets/imgs/logo.png" alt="" />
|
||||
<img src="@/assets/imgs/brand-mark.png" alt="" />
|
||||
<span>{{ underlineToHump(appStore.getTitle) }}</span>
|
||||
</div>
|
||||
<div class="hero-copy">
|
||||
<p class="hero-kicker">FruitShorts Studio</p>
|
||||
<p class="hero-kicker">{{ t('login.consoleLabel') }}</p>
|
||||
<h1>{{ t('login.welcome') }}</h1>
|
||||
<p>{{ t('login.message') }}</p>
|
||||
<ul>
|
||||
@@ -63,7 +63,7 @@ const themeChange = () => {
|
||||
.login-page {
|
||||
height: 100%;
|
||||
color: var(--el-text-color-primary);
|
||||
background: #eef3f9;
|
||||
background: var(--el-bg-color-page);
|
||||
}
|
||||
|
||||
.login-scroll {
|
||||
@@ -82,9 +82,9 @@ const themeChange = () => {
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background:
|
||||
radial-gradient(circle at 18% 18%, rgb(255 255 255 / 16%), transparent 28%),
|
||||
radial-gradient(circle at 82% 78%, rgb(64 158 255 / 45%), transparent 32%),
|
||||
linear-gradient(155deg, #0d2344 0%, #1a4f96 52%, #409eff 100%);
|
||||
radial-gradient(circle at 18% 18%, rgb(255 255 255 / 10%), transparent 28%),
|
||||
radial-gradient(circle at 82% 78%, rgb(196 50 42 / 34%), transparent 34%),
|
||||
linear-gradient(155deg, #17100f 0%, #241714 55%, #3b1d19 100%);
|
||||
flex: 1.05;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
@@ -111,8 +111,10 @@ const themeChange = () => {
|
||||
font-weight: 700;
|
||||
|
||||
img {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
width: var(--brand-mark-size);
|
||||
height: var(--brand-mark-size);
|
||||
border-radius: var(--brand-mark-radius);
|
||||
box-shadow: 0 10px 24px rgb(196 50 42 / 28%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +171,7 @@ const themeChange = () => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 88px 32px 48px;
|
||||
background: #f4f7fb;
|
||||
background: var(--el-bg-color-page);
|
||||
}
|
||||
|
||||
.login-tools {
|
||||
@@ -184,28 +186,28 @@ const themeChange = () => {
|
||||
.login-card {
|
||||
width: min(420px, 100%);
|
||||
padding: 36px 32px 28px;
|
||||
background: #fff;
|
||||
border: 1px solid #e6edf5;
|
||||
background: var(--el-bg-color);
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 18px 50px rgb(15 39 68 / 8%);
|
||||
box-shadow: 0 18px 50px rgb(42 24 16 / 10%);
|
||||
}
|
||||
|
||||
.is-dark {
|
||||
background: #0e1116;
|
||||
background: var(--el-bg-color-page);
|
||||
|
||||
.login-hero {
|
||||
background:
|
||||
radial-gradient(circle at 18% 18%, rgb(64 158 255 / 18%), transparent 30%),
|
||||
linear-gradient(155deg, #07111f 0%, #0e2744 58%, #163e73 100%);
|
||||
radial-gradient(circle at 18% 18%, rgb(255 255 255 / 8%), transparent 30%),
|
||||
linear-gradient(155deg, #0e0a09 0%, #1a1110 58%, #2c1513 100%);
|
||||
}
|
||||
|
||||
.login-panel {
|
||||
background: #0e1116;
|
||||
background: var(--el-bg-color-page);
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: #161b22;
|
||||
border-color: #2a313c;
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-color: var(--el-border-color);
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
@@ -217,16 +219,46 @@ const themeChange = () => {
|
||||
|
||||
.login-hero {
|
||||
flex: none;
|
||||
min-height: 280px;
|
||||
padding: 28px 24px 32px;
|
||||
min-height: 132px;
|
||||
padding: 16px 24px 20px;
|
||||
}
|
||||
|
||||
.hero-copy h1 {
|
||||
font-size: 30px;
|
||||
margin: 6px 0 8px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.hero-copy ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.login-panel {
|
||||
padding: 72px 16px 32px;
|
||||
padding: 44px 16px 12px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding-top: 28px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.login-tools {
|
||||
top: 8px;
|
||||
right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 600px) {
|
||||
.login-hero {
|
||||
min-height: 118px;
|
||||
padding: 16px 18px 18px;
|
||||
}
|
||||
|
||||
.hero-copy p {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: 28px 20px 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -269,6 +301,19 @@ const themeChange = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.login-card :deep(.el-button--primary) {
|
||||
--el-button-bg-color: var(--app-brand);
|
||||
--el-button-border-color: var(--app-brand);
|
||||
--el-button-hover-bg-color: var(--app-brand-pressed);
|
||||
--el-button-hover-border-color: var(--app-brand-pressed);
|
||||
--el-button-active-bg-color: var(--app-brand-pressed);
|
||||
--el-button-active-border-color: var(--app-brand-pressed);
|
||||
}
|
||||
|
||||
.login-card :deep(.el-input__wrapper.is-focus) {
|
||||
box-shadow: 0 0 0 1px var(--app-brand) inset;
|
||||
}
|
||||
|
||||
body:has(.login-page) {
|
||||
min-width: 0;
|
||||
background: transparent;
|
||||
|
||||
@@ -64,7 +64,7 @@ const schema = reactive<FormSchema[]>([
|
||||
span: 24
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: 'admin'
|
||||
placeholder: t('login.usernamePlaceholder')
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -79,7 +79,7 @@ const schema = reactive<FormSchema[]>([
|
||||
style: {
|
||||
width: '100%'
|
||||
},
|
||||
placeholder: 'admin123'
|
||||
placeholder: t('login.passwordPlaceholder')
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -143,8 +143,7 @@ const remember = ref(userStore.getRememberMe)
|
||||
const initLoginInfo = () => {
|
||||
const loginInfo = userStore.getLoginInfo
|
||||
if (loginInfo) {
|
||||
const { username, password } = loginInfo
|
||||
setValues({ username, password })
|
||||
setValues({ username: loginInfo.username })
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
@@ -170,6 +169,7 @@ watch(
|
||||
|
||||
// 登录
|
||||
const signIn = async () => {
|
||||
if (loading.value) return
|
||||
const formRef = await getElFormExpose()
|
||||
await formRef?.validate(async (isValid) => {
|
||||
if (isValid) {
|
||||
@@ -183,8 +183,7 @@ const signIn = async () => {
|
||||
// 是否记住我
|
||||
if (unref(remember)) {
|
||||
userStore.setLoginInfo({
|
||||
username: formData.username,
|
||||
password: formData.password
|
||||
username: formData.username
|
||||
})
|
||||
} else {
|
||||
userStore.setLoginInfo(undefined)
|
||||
@@ -196,7 +195,7 @@ const signIn = async () => {
|
||||
}
|
||||
// 是否使用动态路由
|
||||
if (appStore.getDynamicRouter) {
|
||||
getRole()
|
||||
await getRole()
|
||||
} else {
|
||||
await permissionStore.generateRoutes('static').catch(() => {})
|
||||
permissionStore.getAddRouters.forEach((route) => {
|
||||
@@ -254,6 +253,7 @@ const toRegister = () => {
|
||||
hide-required-asterisk
|
||||
size="large"
|
||||
class="login-form"
|
||||
@keyup.enter="signIn"
|
||||
@register="formRegister"
|
||||
/>
|
||||
</template>
|
||||
@@ -3,7 +3,7 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
createProductApi,
|
||||
deleteProductApi,
|
||||
@@ -245,7 +245,7 @@ onMounted(load)
|
||||
class="primary-button"
|
||||
@click="openCreate"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新建商品
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { VideoCamera, CaretRight, Clock, CircleCheck, Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { pageDramasApi } from '@/api/admin/drama'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import { formatCount } from '@/utils/format'
|
||||
@@ -52,36 +52,32 @@ onMounted(async () => {
|
||||
type="primary"
|
||||
class="primary-button"
|
||||
@click="router.push({ name: 'dramas' })"
|
||||
><el-icon><Plus /></el-icon>上传新短剧</el-button
|
||||
><AppIcon :icon="AppIcons.add" />上传新短剧</el-button
|
||||
></div
|
||||
>
|
||||
<div v-loading="loading" class="stats-grid">
|
||||
<div class="stat-card"
|
||||
><div class="stat-top"
|
||||
><span>短剧总数</span
|
||||
><span class="stat-icon"
|
||||
><el-icon><VideoCamera /></el-icon></span></div
|
||||
><span class="stat-icon"><AppIcon :icon="AppIcons.content" /></span></div
|
||||
><div class="stat-value">{{ total }} <small>部</small></div></div
|
||||
>
|
||||
<div class="stat-card"
|
||||
><div class="stat-top"
|
||||
><span>累计播放量</span
|
||||
><span class="stat-icon"
|
||||
><el-icon><CaretRight /></el-icon></span></div
|
||||
><span class="stat-icon"><AppIcon :icon="AppIcons.videoPlay" /></span></div
|
||||
><div class="stat-value">{{ formatCount(totalViews) }}</div></div
|
||||
>
|
||||
<div class="stat-card"
|
||||
><div class="stat-top"
|
||||
><span>待审核内容</span
|
||||
><span class="stat-icon"
|
||||
><el-icon><Clock /></el-icon></span></div
|
||||
><span class="stat-icon"><AppIcon :icon="AppIcons.clock" /></span></div
|
||||
><div class="stat-value">{{ reviewingCount }} <small>项</small></div></div
|
||||
>
|
||||
<div class="stat-card"
|
||||
><div class="stat-top"
|
||||
><span>已上线</span
|
||||
><span class="stat-icon"
|
||||
><el-icon><CircleCheck /></el-icon></span></div
|
||||
><span class="stat-icon"><AppIcon :icon="AppIcons.checkCircle" /></span></div
|
||||
><div class="stat-value">{{ publishedCount }} <small>部</small></div></div
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
createBannerApi,
|
||||
deleteBannerApi,
|
||||
@@ -219,7 +219,7 @@ onMounted(async () => {
|
||||
class="primary-button"
|
||||
@click="openCreate"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新建轮播图
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
createDramaCategoryApi,
|
||||
deleteDramaCategoryApi,
|
||||
@@ -100,7 +100,7 @@ onMounted(load)
|
||||
description="维护短剧类型,供新建短剧选择,也作为客户端分类筛选的依据。"
|
||||
>
|
||||
<el-button v-if="can('drama:create')" type="primary" class="primary-button" @click="openCreate">
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新建类型
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus, Search } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
changeDramaStatusApi,
|
||||
createDramaApi,
|
||||
@@ -242,7 +242,7 @@ onMounted(async () => {
|
||||
><div class="eyebrow">内容管理</div><h1>短剧管理</h1
|
||||
><p>管理短剧信息、封面、剧集和发布状态。</p></div
|
||||
><el-button v-if="can('drama:create')" type="primary" class="primary-button" @click="openCreate"
|
||||
><el-icon><Plus /></el-icon>新建短剧</el-button
|
||||
><AppIcon :icon="AppIcons.add" />新建短剧</el-button
|
||||
></div
|
||||
>
|
||||
<section class="panel library-panel">
|
||||
@@ -251,11 +251,12 @@ onMounted(async () => {
|
||||
><el-input
|
||||
v-model="keyword"
|
||||
placeholder="搜索短剧名称"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
@keyup.enter="search"
|
||||
@clear="search"
|
||||
/><el-select v-model="statusFilter" clearable placeholder="全部状态" @change="search"
|
||||
>
|
||||
<template #prefix><AppIcon :icon="AppIcons.search" /></template> </el-input
|
||||
><el-select v-model="statusFilter" clearable placeholder="全部状态" @change="search"
|
||||
><el-option
|
||||
v-for="item in statusOptions"
|
||||
:key="item.code"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { pageDramasApi } from '@/api/admin/drama'
|
||||
import {
|
||||
createEpisodeApi,
|
||||
@@ -232,7 +232,7 @@ onMounted(async () => {
|
||||
class="primary-button"
|
||||
:disabled="!selectedDramaId"
|
||||
@click="openCreate"
|
||||
><el-icon><Plus /></el-icon>新增剧集</el-button
|
||||
><AppIcon :icon="AppIcons.add" />新增剧集</el-button
|
||||
></div
|
||||
>
|
||||
<section class="panel episode-panel">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup>
|
||||
import { ArrowLeft, Upload } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
import CreatorCenterPage from './components/CreatorCenterPage.vue'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
@@ -72,7 +72,7 @@ function requestDramaCover(options) {
|
||||
title="作品编辑"
|
||||
:description="drama ? `${drama.title}(${drama.code})` : ''"
|
||||
>
|
||||
<el-button :icon="ArrowLeft" @click="back">返回</el-button>
|
||||
<el-button @click="back"><AppIcon :icon="AppIcons.arrowBack" />返回</el-button>
|
||||
</PageHeading>
|
||||
|
||||
<section v-loading="loading" class="panel">
|
||||
@@ -145,7 +145,7 @@ function requestDramaCover(options) {
|
||||
:http-request="requestDramaCover"
|
||||
:disabled="uploadingId !== null"
|
||||
>
|
||||
<el-button size="small" :icon="Upload">上传封面</el-button>
|
||||
<el-button size="small"> <AppIcon :icon="AppIcons.upload" />上传封面 </el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@@ -341,7 +341,7 @@ function requestDramaCover(options) {
|
||||
accept="image/*"
|
||||
:http-request="(options) => requestEpisodeCover({ id: episodeEditingId }, options)"
|
||||
>
|
||||
<el-button size="small" :icon="Upload">上传封面</el-button>
|
||||
<el-button size="small"> <AppIcon :icon="AppIcons.upload" />上传封面 </el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
import CreatorCenterPage from './components/CreatorCenterPage.vue'
|
||||
import { useCreatorAccess } from './composables/useCreatorAccess'
|
||||
@@ -112,12 +112,13 @@ function openEdit(row) {
|
||||
<el-input
|
||||
v-model="dramas.keyword"
|
||||
class="console-keyword"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="搜索作品名称"
|
||||
@keyup.enter="queryDramas"
|
||||
@clear="queryDramas"
|
||||
/>
|
||||
>
|
||||
<template #prefix><AppIcon :icon="AppIcons.search" /></template>
|
||||
</el-input>
|
||||
<el-select
|
||||
v-model="dramas.status"
|
||||
class="console-select"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup>
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import { dateCell } from '@/utils/format'
|
||||
@@ -72,12 +72,13 @@ const {
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
class="console-keyword"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="搜索名称 / 编号 / 联系人 / 联系方式"
|
||||
@keyup.enter="query"
|
||||
@clear="query"
|
||||
/>
|
||||
>
|
||||
<template #prefix><AppIcon :icon="AppIcons.search" /></template>
|
||||
</el-input>
|
||||
<el-select
|
||||
v-model="statusFilter"
|
||||
class="console-select"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
createNoticeApi,
|
||||
deleteNoticeApi,
|
||||
@@ -184,7 +184,7 @@ onMounted(load)
|
||||
class="primary-button"
|
||||
@click="openCreate"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新建公告
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup>
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { menuIconNames, useMenuManagement } from '@/views/permission/composables/useMenuManagement'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
|
||||
@@ -12,7 +12,7 @@ const { treeData, loading, form, parentOptions, resetForm, selectNode, saveMenu,
|
||||
<template>
|
||||
<PageHeading eyebrow="后台管理" title="菜单管理" description="维护系统菜单结构、路由与按钮权限。">
|
||||
<el-button type="primary" @click="resetForm(0)">
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新增菜单
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup>
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { useRoleCategories } from '@/views/permission/composables/useRoleCategories'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
|
||||
@@ -25,7 +25,7 @@ const {
|
||||
description="维护角色分类,方便按职责整理权限角色。"
|
||||
>
|
||||
<el-button type="primary" class="primary-button" @click="openCreateDialog">
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新增分类
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup>
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { useRolePermissionEditor } from '@/views/permission/composables/useRolePermissionEditor'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
|
||||
@@ -36,7 +36,7 @@ function removeRoleRow(row) {
|
||||
description="角色等级数字越小权限越高,低等级角色不能修改高等级角色。"
|
||||
>
|
||||
<el-button type="primary" class="primary-button" @click="dialogVisible = true">
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
新增角色
|
||||
</el-button>
|
||||
</PageHeading>
|
||||
|
||||
@@ -3,17 +3,9 @@
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { createMenuApi, deleteMenuApi, getMenuTreeApi, updateMenuApi } from '@/api/admin/role'
|
||||
import { MenuIconOptions, normalizeAppIcon } from '@/constants/icons'
|
||||
|
||||
export const menuIconNames = [
|
||||
'Document',
|
||||
'DataAnalysis',
|
||||
'Picture',
|
||||
'User',
|
||||
'Setting',
|
||||
'VideoCamera',
|
||||
'Menu',
|
||||
'Grid'
|
||||
]
|
||||
export const menuIconNames = MenuIconOptions
|
||||
|
||||
/** 菜单管理:直接读写后端 sys_menu,变更后重新登录生效。 */
|
||||
export function useMenuManagement() {
|
||||
@@ -101,7 +93,7 @@ export function useMenuManagement() {
|
||||
routePath: raw.path || '',
|
||||
routeName: raw.name || '',
|
||||
component: raw.component === '#' ? '' : raw.component || '',
|
||||
icon: raw.icon || '',
|
||||
icon: normalizeAppIcon(raw.icon),
|
||||
permissionCode: raw.permissionCode || '',
|
||||
type: raw.type || 'MENU',
|
||||
sort: raw.sort ?? 1,
|
||||
@@ -121,7 +113,7 @@ export function useMenuManagement() {
|
||||
routePath: form.routePath.trim(),
|
||||
routeName: form.routeName.trim(),
|
||||
component: form.type === 'CATALOG' ? '#' : form.component.trim(),
|
||||
icon: form.icon,
|
||||
icon: form.type === 'BUTTON' ? '' : normalizeAppIcon(form.icon),
|
||||
permissionCode: form.permissionCode.trim(),
|
||||
type: form.type,
|
||||
sort: Number(form.sort) || 1,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { getOperationLogApi, pageOperationLogsApi } from '@/api/admin/log'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
|
||||
@@ -103,12 +103,13 @@ onMounted(load)
|
||||
<div class="drama-filters">
|
||||
<el-input
|
||||
v-model="filters.username"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="操作人"
|
||||
@keyup.enter="search"
|
||||
@clear="search"
|
||||
/>
|
||||
>
|
||||
<template #prefix><AppIcon :icon="AppIcons.search" /></template>
|
||||
</el-input>
|
||||
<el-select v-model="filters.module" clearable placeholder="全部模块" @change="search">
|
||||
<el-option
|
||||
v-for="item in moduleOptions"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Author: fruit.com.cn -->
|
||||
|
||||
<script setup>
|
||||
import { Plus, Search } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import { useAdminUsers } from '@/views/userManagement/composables/useAdminUsers'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
@@ -44,18 +44,19 @@ const {
|
||||
<div class="admin-user-toolbar">
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="搜索登录账号"
|
||||
@keyup.enter="queryUsers"
|
||||
@clear="queryUsers"
|
||||
/>
|
||||
>
|
||||
<template #prefix><AppIcon :icon="AppIcons.search" /></template>
|
||||
</el-input>
|
||||
<el-select v-model="roleFilter" clearable placeholder="全部角色" @change="queryUsers">
|
||||
<el-option v-for="role in roles" :key="role.id" :label="role.name" :value="role.id" />
|
||||
</el-select>
|
||||
<el-button type="primary" @click="queryUsers">查询</el-button>
|
||||
<el-button v-if="can('system:admin-user')" type="primary" @click="openCreate">
|
||||
<el-icon><Plus /></el-icon>
|
||||
<AppIcon :icon="AppIcons.add" />
|
||||
添加用户
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import {
|
||||
@@ -87,12 +87,13 @@ function canBeBanned(row) {
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
class="app-user-keyword"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="搜索 uid / 昵称 / 手机号 / 邮箱"
|
||||
@keyup.enter="queryUsers"
|
||||
@clear="queryUsers"
|
||||
/>
|
||||
>
|
||||
<template #prefix><AppIcon :icon="AppIcons.search" /></template>
|
||||
</el-input>
|
||||
<el-select
|
||||
v-model="statusFilter"
|
||||
class="app-user-status"
|
||||
|
||||
Reference in new issue
Block a user