feat: 外观设置
|
Before Width: | Height: | Size: 8.0 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 232.4409 232.4409"><defs><style>.cls-1{fill:url(#未命名的渐变_7);}.cls-2{fill:url(#未命名的渐变_7-2);}.cls-3{fill:url(#未命名的渐变_7-3);}.cls-4{fill:url(#未命名的渐变_7-4);}.cls-5{fill:url(#未命名的渐变_7-5);}.cls-6{fill:url(#未命名的渐变_7-6);}</style><linearGradient id="未命名的渐变_7" x1="113.6159" y1="176.9998" x2="113.6159" y2="195.8629" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#3370ff"/><stop offset="1" stop-color="#7f3bf5"/></linearGradient><linearGradient id="未命名的渐变_7-2" x1="209.3027" y1="90.7042" x2="209.3027" y2="131.8553" xlink:href="#未命名的渐变_7"/><linearGradient id="未命名的渐变_7-3" x1="23.1384" y1="90.7042" x2="23.1384" y2="131.8553" xlink:href="#未命名的渐变_7"/><linearGradient id="未命名的渐变_7-4" x1="138.8087" y1="96.1512" x2="138.8087" y2="118.7847" xlink:href="#未命名的渐变_7"/><linearGradient id="未命名的渐变_7-5" x1="95.3622" y1="96.1512" x2="95.3622" y2="118.7847" xlink:href="#未命名的渐变_7"/><linearGradient id="未命名的渐变_7-6" x1="116.2206" y1="48.8968" x2="116.2206" y2="173.4002" xlink:href="#未命名的渐变_7"/></defs><title>MaxKB</title><path class="cls-1" d="M128.4532,177H98.7785L87.78,187.9985a4.6069,4.6069,0,0,0,3.2576,7.8644h45.1569a4.6069,4.6069,0,0,0,3.2575-7.8644Z"/><path class="cls-2" d="M210.0008,90.7042h-5.85v41.1511h5.85a4.4537,4.4537,0,0,0,4.4537-4.4537V95.1579A4.4537,4.4537,0,0,0,210.0008,90.7042Z"/><path class="cls-3" d="M28.29,90.7042H22.44a4.4538,4.4538,0,0,0-4.4538,4.4537v32.2437a4.4538,4.4538,0,0,0,4.4538,4.4537h5.85Z"/><path class="cls-4" d="M138.8087,96.1512a8.33,8.33,0,0,0-8.33,8.33v5.9727a8.33,8.33,0,1,0,16.6607,0v-5.9727A8.33,8.33,0,0,0,138.8087,96.1512Z"/><path class="cls-5" d="M95.3622,96.1512a8.33,8.33,0,0,0-8.33,8.33v5.9727a8.33,8.33,0,1,0,16.6607,0v-5.9727A8.33,8.33,0,0,0,95.3622,96.1512Z"/><path class="cls-6" d="M166.8344,48.8968H65.6064A33.7544,33.7544,0,0,0,31.89,82.6131v57.07A33.7548,33.7548,0,0,0,65.6064,173.4h101.228a33.7549,33.7549,0,0,0,33.7168-33.7168v-57.07A33.7545,33.7545,0,0,0,166.8344,48.8968Zm2.831,90.4457a6.0733,6.0733,0,0,1-6.0732,6.0733H114.2168a43.5922,43.5922,0,0,0-21.3313,5.5757l-16.5647,9.2946v-14.87h-7.472a6.0733,6.0733,0,0,1-6.0733-6.0733v-60.5a6.0733,6.0733,0,0,1,6.0733-6.0733h94.7434a6.0733,6.0733,0,0,1,6.0732,6.0733Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 770 KiB |
|
After Width: | Height: | Size: 647 KiB |
|
After Width: | Height: | Size: 683 KiB |
|
After Width: | Height: | Size: 602 KiB |
|
After Width: | Height: | Size: 4.7 MiB |
|
|
@ -28,12 +28,6 @@
|
|||
<div class="value" v-else>{{ item.username }}</div>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
<!-- <el-input
|
||||
:validate-event="false"
|
||||
v-model="currentval"
|
||||
:placeholder="tagsList.length == 0 ? placeholder : ''"
|
||||
@keydown.enter="addTags"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
|
|||
|
|
@ -651,3 +651,29 @@ h5 {
|
|||
border: 1px solid var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.app-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
|
||||
}
|
||||
|
||||
.app-radio-button-group {
|
||||
border: 1px solid var(--app-border-color-dark);
|
||||
border-radius: var(--el-border-radius-base);
|
||||
.el-radio-button {
|
||||
padding: 3px;
|
||||
}
|
||||
.el-radio-button__inner {
|
||||
border: none !important;
|
||||
border-radius: var(--el-border-radius-base) !important;
|
||||
padding: 5px 8px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.el-radio-button__original-radio:checked + .el-radio-button__inner {
|
||||
color: var(--el-color-primary);
|
||||
background: var(--el-color-primary-light-9);
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,27 +22,6 @@
|
|||
>
|
||||
<el-form-item label="用户名/邮箱" prop="users">
|
||||
<tags-input v-model:tags="memberForm.users" placeholder="请输入成员的用户名或邮箱" />
|
||||
<!-- <el-select
|
||||
ref="SelectRemoteRef"
|
||||
class="custom-select-multiple"
|
||||
v-model="memberForm.users"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入成员的用户名或邮箱"
|
||||
no-data-text="用户不存在"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading"
|
||||
@change="changeSelectHandle"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in userOptions"
|
||||
:key="item?.id"
|
||||
:label="item?.username"
|
||||
:value="item?.id"
|
||||
/>
|
||||
</el-select> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
|
|
|||
|
|
@ -1,294 +1,81 @@
|
|||
<template>
|
||||
<div ref="appLoginView" class="appearance-login-view" :style="customStyle">
|
||||
<div class="top-tab-container">
|
||||
<div class="flex-top-tabs">
|
||||
<div class="tab-card">
|
||||
<span>页签</span>
|
||||
<el-icon class="del-icon">
|
||||
<Icon name="icon_close_outlined" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="tab-card active">
|
||||
<div class="active-span">
|
||||
<img :src="pageWeb" alt="" />
|
||||
<span>{{ pageName || 'DataEase' }}</span>
|
||||
</div>
|
||||
<el-icon class="del-icon">
|
||||
<Icon name="icon_close_outlined" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="tab-card">
|
||||
<span>页签</span>
|
||||
<el-icon class="del-icon">
|
||||
<Icon name="icon_close_outlined" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-preview mr-16">
|
||||
<div class="header">
|
||||
<div class="tag flex-between">
|
||||
<div class="flex align-center">
|
||||
<img src="@/assets/logo.svg" height="24" class="mr-8" />
|
||||
<span class="ellipsis">MaxKB111111111111111</span>
|
||||
</div>
|
||||
<div class="login-container">
|
||||
<div class="left-img" v-if="showLoginImage">
|
||||
<el-image
|
||||
class="login-image"
|
||||
fit="cover"
|
||||
:src="pageBg || DeImage"
|
||||
/>
|
||||
</div>
|
||||
<div class="right-container">
|
||||
<div class="login-form-center">
|
||||
<div class="config-area">
|
||||
<div class="login-logo">
|
||||
<img class="login-logo-icon" v-if="pageLogin" :src='pageLogin' alt="" />
|
||||
<Icon v-else className="login-logo-icon" name="DataEase"></Icon>
|
||||
</div>
|
||||
<div class="login-welcome">
|
||||
{{ pageSlogan || '欢迎使用 DataEase 数据可视化分析平台' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-area">
|
||||
<div class="default-login-tabs">
|
||||
<el-form size="small">
|
||||
<el-form-item class="login-form-item" prop="username">
|
||||
<el-input
|
||||
readonly
|
||||
:placeholder="t('common.account') + '/' + t('commons.email')"
|
||||
autofocus
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<CustomPassword
|
||||
readonly
|
||||
:placeholder="t('common.pwd')"
|
||||
show-password
|
||||
maxlength="30"
|
||||
show-word-limit
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="login-btn">
|
||||
<el-button
|
||||
type="primary"
|
||||
class="submit"
|
||||
size="small"
|
||||
:disabled="true"
|
||||
>
|
||||
{{ t('login.btn') }}
|
||||
</el-button>
|
||||
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showFoot" class="dynamic-login-foot" v-html="pageFootContent" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<el-icon><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<login-layout style="height: 530px">
|
||||
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库" class="login-container">
|
||||
<div class="mask"></div>
|
||||
<h2 class="mb-24">{{ '普通登录' }}</h2>
|
||||
<el-form class="login-form">
|
||||
<div class="mb-24">
|
||||
<el-form-item>
|
||||
<el-input size="large" class="input-item" placeholder="请输入用户名"> </el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="mb-24">
|
||||
<el-form-item>
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-button size="large" type="primary" class="w-full">登录</el-button>
|
||||
<div class="operate-container flex-between mt-12">
|
||||
<el-button class="forgot-password" link type="primary"> 忘记密码? </el-button>
|
||||
</div>
|
||||
</LoginContainer>
|
||||
</login-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import DeImage from '@/assets/login-desc-de.png'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { computed, ref, onMounted, nextTick } from 'vue'
|
||||
import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import colorFunctions from 'less/lib/less/functions/color.js'
|
||||
import colorTree from 'less/lib/less/tree/color.js'
|
||||
const basePath = import.meta.env.VITE_API_BASEPATH
|
||||
const baseUrl = basePath + '/appearance/image/'
|
||||
const { t } = useI18n()
|
||||
const props = defineProps({
|
||||
web: propTypes.string.def(''),
|
||||
name: propTypes.string.def(''),
|
||||
slogan: propTypes.string.def(''),
|
||||
themeColor: propTypes.string.def(''),
|
||||
customColor: propTypes.string.def(''),
|
||||
login: propTypes.string.def(''),
|
||||
bg: propTypes.string.def(''),
|
||||
height: propTypes.number.def(425),
|
||||
foot: propTypes.string.def(''),
|
||||
footContent: propTypes.string.def('')
|
||||
})
|
||||
const appLoginView = ref()
|
||||
const loginContainerWidth = ref(0)
|
||||
const pageWeb = computed(() => {
|
||||
return !props.web ? '/dataease.svg' : props.web.startsWith('blob') ? props.web : baseUrl + props.web
|
||||
})
|
||||
const pageLogin = computed(() => !props.login ? null : props.login.startsWith('blob') ? props.login : baseUrl + props.login)
|
||||
const pageBg = computed(() => !props.bg ? null : props.bg.startsWith('blob') ? props.bg : baseUrl + props.bg)
|
||||
const pageName = computed(() => props.name)
|
||||
const pageSlogan = computed(() => props.slogan)
|
||||
const showFoot = computed(() => props.foot && props.foot === 'true')
|
||||
const pageFootContent = computed(() => (props.foot && props.foot === 'true') ? props.footContent : null)
|
||||
const pageThemeColor = computed(() => props.themeColor)
|
||||
const pageCustomColor = computed(() => props.customColor)
|
||||
const customStyle = computed(() => {
|
||||
const result = {'height': `${props.height + 23}px`}
|
||||
if (pageThemeColor.value === 'custom') {
|
||||
result['--ed-color-primary'] = pageCustomColor.value
|
||||
} else {
|
||||
result['--ed-color-primary'] = '#3370FF'
|
||||
}
|
||||
result['--ed-color-primary-light-5'] =
|
||||
colorFunctions
|
||||
.mix(new colorTree('ffffff'), new colorTree(result['--ed-color-primary'].substring(1)), { value: 40 })
|
||||
.toRGB()
|
||||
return result
|
||||
})
|
||||
const showLoginImage = computed<boolean>(() => {
|
||||
return !(loginContainerWidth.value < 555)
|
||||
})
|
||||
onMounted(() => {
|
||||
|
||||
const erd = elementResizeDetectorMaker()
|
||||
erd.listenTo(appLoginView.value, () => {
|
||||
nextTick(() => {
|
||||
loginContainerWidth.value = appLoginView.value?.offsetWidth
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.appearance-login-view {
|
||||
min-width: 390px;
|
||||
min-height: 314px;
|
||||
width: 100%;
|
||||
height: 464px;
|
||||
background-color: #fff;
|
||||
<style lang="scss" scoped>
|
||||
.login-preview {
|
||||
background: #ffffff;
|
||||
border-radius: 4px;
|
||||
transform-origin: center;
|
||||
.login-container {
|
||||
transform: translate(0, 0) scale(0.8);
|
||||
position: relative;
|
||||
.top-tab-container {
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
background-color: #eff0f1;;
|
||||
.flex-top-tabs {
|
||||
display: flex;
|
||||
height: 22px;
|
||||
align-items: center;
|
||||
.active {
|
||||
background-color: #fff;
|
||||
height: 18px !important;
|
||||
line-height: 18px !important;
|
||||
}
|
||||
.tab-card {
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 25%;
|
||||
min-width: 130px;
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
border-right: 1px solid #e0e0e2;
|
||||
font-size: 9px;
|
||||
align-items: center;
|
||||
.del-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
.active-span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
img {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-bottom: 2px;
|
||||
.mask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
height: calc(100% - 24px);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
.left-img {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 40%;
|
||||
min-width: 240px;
|
||||
.login-image {
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.right-container {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 290px;
|
||||
.login-form-center {
|
||||
width: 300px;
|
||||
font-size: 10px;
|
||||
.config-area {
|
||||
.login-logo {
|
||||
text-align: center;
|
||||
img {
|
||||
width: auto;
|
||||
max-height: 30px;
|
||||
@media only screen and (max-width: 1280px) {
|
||||
width: auto;
|
||||
max-height: 30px;
|
||||
}
|
||||
}
|
||||
.login-logo-icon {
|
||||
width: auto;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
.login-welcome {
|
||||
text-align: center;
|
||||
margin-top: 3px;
|
||||
color: #646a73;
|
||||
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
.form-area {
|
||||
margin-top: 24px;
|
||||
padding: 24px;
|
||||
padding-top: 12px;
|
||||
box-shadow: 0px 4px 15px rgba(31, 35, 41, 0.08);
|
||||
border: 1px solid #dee0e3;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.login-form-item {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.ed-form-item--default {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
.dynamic-login-foot {
|
||||
visibility: visible;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
z-index: 302;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
padding-top: 1px;
|
||||
zoom: 1;
|
||||
margin: 0;
|
||||
.header {
|
||||
background: #eff0f1;
|
||||
height: 38px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
position: relative;
|
||||
.tag {
|
||||
width: 180px;
|
||||
height: 30px;
|
||||
background: #ffffff;
|
||||
box-shadow: var(-app-text-color-light-1);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 8px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.login-btn {
|
||||
:deep(button) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,774 +1,177 @@
|
|||
<template>
|
||||
<p class="router-title">外观配置</p>
|
||||
<div class="appearance-table__content">
|
||||
<div class="theme-setting">
|
||||
<h4 class="p-16-24">外观设置</h4>
|
||||
<el-scrollbar>
|
||||
<div class="theme">
|
||||
<div class="platform-theme">平台显示主题</div>
|
||||
<div class="navigate-bg">顶部导航背景色</div>
|
||||
<div class="color-type">
|
||||
<div class="color-item" :class="navigateBg === 'dark' && 'active'" @click="navigateClick('dark')">
|
||||
<img :src="DarkBg" alt="" />
|
||||
<div class="color-item-label">
|
||||
<el-radio v-model="navigateBg" @change="navigateBgChange" label="dark">暗色</el-radio>
|
||||
</div>
|
||||
</div>
|
||||
<div class="color-item" :class="navigateBg === 'light' && 'active'" @click="navigateClick('light')">
|
||||
<img :src="LightBg" alt="" />
|
||||
<div class="color-item-label">
|
||||
<el-radio v-model="navigateBg" @change="navigateBgChange" label="light">浅色</el-radio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme-bg">主题色</div>
|
||||
<div class="theme-color">
|
||||
<el-radio-group v-model="themeColor" @change="themeColorChange">
|
||||
<el-radio label="default">默认 (蓝色) </el-radio>
|
||||
<el-radio label="custom">自定义</el-radio>
|
||||
<div class="p-24 pt-0">
|
||||
<div class="app-card p-24">
|
||||
<h5 class="mb-16">平台显示主题</h5>
|
||||
<el-radio-group
|
||||
v-model="themeForm.theme"
|
||||
class="app-radio-button-group"
|
||||
@change="themeColorChange"
|
||||
>
|
||||
<template v-for="(item, index) in themeList" :key="index">
|
||||
<el-radio-button :label="item.label" :value="item.value" />
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<template v-if="themeColor === 'custom'">
|
||||
<div class="custom-color">自定义色值</div>
|
||||
<el-color-picker
|
||||
:trigger-width="108"
|
||||
v-model="customColor"
|
||||
:predefine="COLOR_PANEL"
|
||||
is-custom
|
||||
effect="light"
|
||||
@change="customColorChange"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="login">
|
||||
<div class="platform-login">平台登录设置</div>
|
||||
<div class="page-preview">
|
||||
<div class="title">
|
||||
<span class="left">页面预览</span>
|
||||
<el-button text @click="resetLoginForm(true)">恢复默认</el-button>
|
||||
</div>
|
||||
<div class="page-setting">
|
||||
<div class="page-content">
|
||||
<!-- <img :src="loginPreview" alt="" /> -->
|
||||
<login-preview
|
||||
:navigate-bg="navigateBg"
|
||||
:theme-color="themeColor"
|
||||
:custom-color="customColor"
|
||||
:name="loginForm.name"
|
||||
:slogan="loginForm.slogan"
|
||||
:web="web"
|
||||
:bg="bg"
|
||||
:login="login"
|
||||
:height="navigateHeight"
|
||||
:foot="loginForm.foot"
|
||||
:foot-content="loginForm.footContent"
|
||||
/>
|
||||
<div class="tips-page">
|
||||
默认为 DataEase 登录界面,支持自定义设置
|
||||
</div>
|
||||
<div class="app-card p-24 mt-16">
|
||||
<h5 class="mb-16">平台登陆设置</h5>
|
||||
<el-card shadow="never" class="layout-bg">
|
||||
<div class="flex-between">
|
||||
<h5 class="mb-16">页面预览</h5>
|
||||
<el-button type="primary" link> 恢复默认 </el-button>
|
||||
</div>
|
||||
<div class="config-list">
|
||||
<div class="config-item" v-for="ele in configList" :key="ele.type">
|
||||
<div class="config-logo">
|
||||
<span class="logo">{{ ele.logo }}</span>
|
||||
<el-upload
|
||||
:name="ele.type"
|
||||
:show-file-list="false"
|
||||
class="upload-demo"
|
||||
accept=".jpeg,.jpg,.png,.gif,.svg"
|
||||
:before-upload="e => beforeUpload(e, ele.type)"
|
||||
:http-request="uploadImg"
|
||||
>
|
||||
<el-button secondary>替换图片</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div class="tips">{{ ele.tips }}</div>
|
||||
</div>
|
||||
<el-form
|
||||
ref="loginFormRef"
|
||||
:model="loginForm"
|
||||
label-position="top"
|
||||
:rules="rules"
|
||||
require-asterisk-position="right"
|
||||
label-width="120px"
|
||||
class="page-Form"
|
||||
>
|
||||
<el-form-item label="网站名称" prop="name">
|
||||
<el-input v-model="loginForm.name" />
|
||||
<div class="form-tips">显示在网页 Tab 的平台名称</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="Slogan" prop="slogan">
|
||||
<el-input v-model="loginForm.slogan" />
|
||||
<div class="form-tips">产品 Logo 下的 Slogan</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="页脚" prop="foot">
|
||||
<el-switch active-value="true" inactive-value="false" v-model="loginForm.foot" />
|
||||
</el-form-item>
|
||||
<el-form-item label="页脚内容" prop="footContent" v-if="loginForm.foot === 'true'">
|
||||
<tinymce-editor v-if="loginForm.foot === 'true'" v-model="loginForm.footContent"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="theme-preview">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<LoginPreview />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="theme-form">
|
||||
<el-card shadow="never" class="mb-8">
|
||||
<div class="flex-between mb-8">
|
||||
<span class="lighter">网站 Logo</span>
|
||||
<el-button size="small"> 替换图片 </el-button>
|
||||
</div>
|
||||
<el-text type="info" size="small"
|
||||
>顶部网站显示的 Logo,建议尺寸 48 x 48,支持 JPG、PNG、SVG,大小不超过
|
||||
200KB</el-text
|
||||
>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mb-8">
|
||||
<div class="flex-between mb-8">
|
||||
<span class="lighter">登录 Logo</span>
|
||||
<el-button size="small"> 替换图片 </el-button>
|
||||
</div>
|
||||
<el-text type="info" size="small"
|
||||
>登录页面右侧 Logo,建议尺寸 204*52,支持 JPG、PNG、SVG,大小不超过
|
||||
200KB</el-text
|
||||
>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mb-8">
|
||||
<div class="flex-between mb-8">
|
||||
<span class="lighter">登录背景图</span>
|
||||
<el-button size="small"> 替换图片 </el-button>
|
||||
</div>
|
||||
<el-text type="info" size="small">
|
||||
左侧背景图,矢量图建议尺寸 576*900,位图建议尺寸1152*1800;支持
|
||||
JPG、PNG、SVG,大小不超过 5M
|
||||
</el-text>
|
||||
</el-card>
|
||||
|
||||
<el-form
|
||||
ref="themeFormRef"
|
||||
:model="themeForm"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
:rules="rules"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item label="网站名称" prop="title">
|
||||
<el-input v-model="themeForm.title" placeholder="请输入网站名称">
|
||||
</el-input>
|
||||
<el-text type="info"> 显示在网页 Tab 的平台名称 </el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="欢迎语" prop="slogan">
|
||||
<el-input v-model="themeForm.slogan" placeholder="请输入欢迎语"> </el-input>
|
||||
<el-text type="info"> 产品 Logo 下的 欢迎语 </el-text>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div></el-col
|
||||
>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login">
|
||||
<div class="platform-login">平台设置</div>
|
||||
<div class="page-preview">
|
||||
<div class="title">
|
||||
<span class="left">页面预览</span>
|
||||
<el-button text @click="resetTopForm(true)">恢复默认</el-button>
|
||||
</div>
|
||||
<div class="page-setting">
|
||||
<div class="page-content">
|
||||
<!-- <div class="navigate-preview" :style="{'height': `${navigateHeight}px`}"> -->
|
||||
<div class="navigate-preview" style="height: 425px;">
|
||||
<div class="navigate-head" :class="{ 'light-head': navigateBg && navigateBg === 'light' }">
|
||||
<img class="logo" v-if="navigate" :src="navigate.startsWith('blob') ? navigate : (baseUrl + navigate)" alt="" />
|
||||
<Icon v-else className="logo" name="logo"></Icon>
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
<div class="navigate-content" />
|
||||
</div>
|
||||
<div class="tips-page">
|
||||
默认为 DataEase 平台界面,支持自定义设置
|
||||
</div>
|
||||
|
||||
<div class="mt-16">
|
||||
<el-text type="info">默认为 MaxKB 登录界面,支持自定义设置</el-text>
|
||||
</div>
|
||||
<div class="config-list">
|
||||
<div class="config-item">
|
||||
<div class="config-logo">
|
||||
<span class="logo">顶部导航 Logo</span>
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
:show-file-list="false"
|
||||
accept=".jpeg,.jpg,.png,.gif,.svg"
|
||||
:before-upload="e => beforeUpload(e, 'navigate')"
|
||||
:http-request="uploadImg"
|
||||
>
|
||||
<el-button secondary>替换图片</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div class="tips">顶部导航菜单显示的 Logo;建议尺寸 134 x 34,支持 JPG、PNG,大小不超过 200KB</div>
|
||||
</div>
|
||||
<el-form
|
||||
ref="topFormRef"
|
||||
:model="topForm"
|
||||
label-position="top"
|
||||
:rules="topRules"
|
||||
require-asterisk-position="right"
|
||||
label-width="120px"
|
||||
class="page-Form"
|
||||
>
|
||||
<el-form-item style="margin-bottom: 14px" label="帮助文档" prop="help">
|
||||
<el-input v-model="topForm.help" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="AI助手按钮" prop="showAi">
|
||||
<el-radio-group v-model="topForm.showAi" >
|
||||
<el-radio v-for="option in btnShowOptions" :key="option.label" :label="option.label">{{ option.name }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="文档按钮" prop="showDoc">
|
||||
<el-radio-group v-model="topForm.showDoc">
|
||||
<el-radio v-for="option in btnShowOptions" :key="option.label" :label="option.label">{{ option.name }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="关于按钮" prop="showAbout">
|
||||
<el-radio-group v-model="topForm.showAbout">
|
||||
<el-radio v-for="option in btnShowOptions" :key="option.label" :label="option.label">{{ option.name }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<div class="appearance-foot">
|
||||
<el-button secondary @click="giveUp">{{ t('appearance.give_up') }}</el-button>
|
||||
<el-button type="primary" v-if="showSaveButton" @click="saveHandler">{{ t('appearance.save_apply') }}</el-button>
|
||||
<div class="theme-setting__operate w-full p-16-24">
|
||||
<el-button>放弃更新</el-button>
|
||||
<el-button type="primary"> 保存并应用 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted, onUnmounted, nextTick } from "vue";
|
||||
import DarkBg from "@/assets/img/dark-theme-bg.png";
|
||||
import LightBg from "@/assets/img/light-theme-bg.png";
|
||||
import { type FormInstance, type FormRules, type UploadUserFile, ElMessage } from "element-plus-secondary";
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import request from '@/config/axios'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import LoginPreview from "./LoginPreview.vue"
|
||||
import TinymceEditor from "@/components/rich-text/TinymceEditor.vue"
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
interface LoginForm {
|
||||
name: string;
|
||||
slogan: string;
|
||||
foot: string;
|
||||
footContent?: string
|
||||
}
|
||||
interface ConfigItem {
|
||||
pkey: string
|
||||
pval: string
|
||||
type: string
|
||||
sort: number
|
||||
}
|
||||
const btnShowOptions = [
|
||||
{ label: '0', name: '显示'},
|
||||
{ label: '1', name: '隐藏'},
|
||||
{ label: '2', name: 'Iframe中隐藏'}
|
||||
import { ref, reactive } from 'vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import LoginPreview from './LoginPreview.vue'
|
||||
const themeList = [
|
||||
{
|
||||
label: '默认',
|
||||
value: '#3370FF',
|
||||
loginBackground: '@/assets/theme/default.jpg'
|
||||
},
|
||||
{
|
||||
label: '活力橙',
|
||||
value: '#FF8800',
|
||||
loginBackground: '@/assets/theme/orange.jpg'
|
||||
},
|
||||
{
|
||||
label: '松石绿',
|
||||
value: '#00B69D',
|
||||
loginBackground: '@/assets/theme/green.jpg'
|
||||
},
|
||||
{
|
||||
label: '商务蓝',
|
||||
value: '#4954E6',
|
||||
loginBackground: '@/assets/theme/default.jpg'
|
||||
},
|
||||
{
|
||||
label: '神秘紫',
|
||||
value: '#7F3BF5',
|
||||
loginBackground: '@/assets/theme/purple.jpg'
|
||||
},
|
||||
{
|
||||
label: '胭脂红',
|
||||
value: '#F01D94',
|
||||
loginBackground: '@/assets/theme/red.jpg'
|
||||
}
|
||||
]
|
||||
const COLOR_PANEL = [
|
||||
'#FF4500',
|
||||
'#FF8C00',
|
||||
'#FFD700',
|
||||
'#71AE46',
|
||||
'#00CED1',
|
||||
'#1E90FF',
|
||||
'#C71585',
|
||||
'#999999',
|
||||
'#000000',
|
||||
'#FFFFFF'
|
||||
]
|
||||
const basePath = import.meta.env.VITE_API_BASEPATH
|
||||
const baseUrl = basePath + '/appearance/image/'
|
||||
const fileList = ref<UploadUserFile[]>([])
|
||||
const navigateBg = ref("dark");
|
||||
const themeColor = ref("default");
|
||||
const customColor = ref("#307eff");
|
||||
const web = ref('')
|
||||
const bg = ref('')
|
||||
const login = ref('')
|
||||
const navigate = ref('')
|
||||
const navigateHeight = ref(400)
|
||||
|
||||
const changedItemArray = ref<ConfigItem[]>([])
|
||||
|
||||
const loginFormRef = ref<FormInstance>();
|
||||
const defaultLoginForm = reactive<LoginForm>({
|
||||
name: "DataEase",
|
||||
slogan: "欢迎使用 DataEase 数据可视化分析平台",
|
||||
foot: 'false',
|
||||
footContent: ''
|
||||
});
|
||||
const loginForm = reactive<LoginForm>({
|
||||
name: "DataEase",
|
||||
slogan: "欢迎使用 DataEase 数据可视化分析平台",
|
||||
foot: 'false',
|
||||
footContent: ''
|
||||
});
|
||||
const themeFormRef = ref<FormInstance>()
|
||||
const themeForm = ref({
|
||||
theme: '#3370FF',
|
||||
icon: '',
|
||||
loginLogo: '',
|
||||
loginImage: '',
|
||||
title: 'MaxKB',
|
||||
slogan: '欢迎使用 MaxKB 智能知识库'
|
||||
})
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
name: [{ required: true, message: "请输入网站名称", trigger: "blur" }],
|
||||
slogan: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入Slogan",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
foot: [
|
||||
{
|
||||
required: true,
|
||||
message: "",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const topForm = reactive<{ help: string, showAi: string, showDoc: string, showAbout: string }>({
|
||||
help: "https://dataease.io/docs/",
|
||||
showAi: '0',
|
||||
showDoc: '0',
|
||||
showAbout: '0'
|
||||
});
|
||||
|
||||
const defaultTopForm = reactive<{ help: string, showAi: string, showDoc: string, showAbout: string }>({
|
||||
help: "https://dataease.io/docs/",
|
||||
showAi: '0',
|
||||
showDoc: '0',
|
||||
showAbout: '0'
|
||||
});
|
||||
|
||||
const topRules = reactive<FormRules>({
|
||||
help: [{ required: true, message: "请输入帮助文档", trigger: "blur" }],
|
||||
showAi: [{ required: true, message: "请选择是否展示AI助手", trigger: "change" }],
|
||||
showDoc: [{ required: true, message: "请选择是否展示文档", trigger: "change" }],
|
||||
showAbout: [{ required: true, message: "请选择是否展示关于", trigger: "change" }],
|
||||
});
|
||||
const configList = [
|
||||
{
|
||||
logo: "网站 Logo",
|
||||
type: "web",
|
||||
tips: "顶部网站显示的 Logo,建议尺寸 48 x 48,支持 JPG、PNG、SVG,大小不超过 200KB",
|
||||
},
|
||||
{
|
||||
logo: "登录 Logo",
|
||||
type: "login",
|
||||
tips: "登录页面右侧 Logo,建议尺寸 204 x 52,支持 JPG、PNG、SVG,大小不超过 200KB",
|
||||
},
|
||||
{
|
||||
logo: "登录背景图",
|
||||
type: "bg",
|
||||
tips: "左侧背景图,矢量图建议尺寸 640 x 900,位图建议尺寸 1280 x 1800;支持 JPG、PNG、SVG,大小不超过 5M",
|
||||
},
|
||||
];
|
||||
|
||||
const giveUp = () => {
|
||||
resetLoginForm(false)
|
||||
resetTopForm(false)
|
||||
init()
|
||||
}
|
||||
const showSaveButton = ref(true)
|
||||
const saveHandler = () => {
|
||||
const param = buildParam()
|
||||
const url = '/appearance/save'
|
||||
request.post({ url, data: param, headersType: 'multipart/form-data;' }).then(res => {
|
||||
if (!res.msg) {
|
||||
ElMessage.success(t('common.save_success'))
|
||||
appearanceStore.setLoaded(false)
|
||||
appearanceStore.setAppearance()
|
||||
showSaveButton.value = false
|
||||
nextTick(() => {
|
||||
showSaveButton.value = true
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const buildParam = () => {
|
||||
for (const key in loginForm) {
|
||||
const item = loginForm[key]
|
||||
if (key === 'footContent') {
|
||||
addChangeArray(key, item, 'blob')
|
||||
} else {
|
||||
addChangeArray(key, item)
|
||||
}
|
||||
}
|
||||
for (const key in topForm) {
|
||||
const item = topForm[key]
|
||||
addChangeArray(key, item)
|
||||
}
|
||||
const formData = new FormData();
|
||||
if (fileList.value.length) {
|
||||
fileList.value.forEach((file) => {
|
||||
const name = file.name + "," + file['flag']
|
||||
const fileArray = [file]
|
||||
const newfile = new File(fileArray, name, { type: file['type'] })
|
||||
formData.append("files", newfile)
|
||||
})
|
||||
}
|
||||
formData.append(
|
||||
"request",
|
||||
new Blob([JSON.stringify(changedItemArray.value)], { type: "application/json" })
|
||||
);
|
||||
return formData
|
||||
}
|
||||
const init = () => {
|
||||
const url = '/appearance/query'
|
||||
changedItemArray.value = []
|
||||
fileList.value = []
|
||||
request.get({ url }).then(res => {
|
||||
const list = res.data
|
||||
if (!list.length) {
|
||||
return
|
||||
}
|
||||
list.forEach(item => {
|
||||
const pkey = item.pkey
|
||||
const pval = item.pval
|
||||
if (pkey === 'navigateBg') {
|
||||
navigateBg.value = pval
|
||||
} else if(pkey === 'themeColor') {
|
||||
themeColor.value = pval
|
||||
} else if(pkey === 'customColor') {
|
||||
customColor.value = pval
|
||||
} else if(pkey === 'web') {
|
||||
web.value = pval
|
||||
} else if(pkey === 'login') {
|
||||
login.value = pval
|
||||
} else if(pkey === 'bg') {
|
||||
bg.value = pval
|
||||
} else if(pkey === 'navigate') {
|
||||
navigate.value = pval
|
||||
} else if(loginForm.hasOwnProperty(pkey)) {
|
||||
loginForm[pkey] = pval
|
||||
} else if(topForm.hasOwnProperty(pkey)) {
|
||||
topForm[pkey] = pval
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
const addChangeArray = (key: string, val: string, type?: string) => {
|
||||
let len = changedItemArray.value.length
|
||||
let match = false
|
||||
while (len--) {
|
||||
const item = changedItemArray.value[len]
|
||||
if (item['pkey'] === key) {
|
||||
changedItemArray.value[len] = { pkey: key, pval: val, type: type || 'text', sort: 1 }
|
||||
match = true
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
changedItemArray.value.push({ pkey: key, pval: val, type: type || 'text', sort: 1 })
|
||||
}
|
||||
}
|
||||
const navigateBgChange = val => {
|
||||
addChangeArray('navigateBg', val)
|
||||
}
|
||||
const navigateClick = val => {
|
||||
navigateBg.value = val
|
||||
navigateBgChange(val)
|
||||
}
|
||||
const themeColorChange = val => {
|
||||
addChangeArray('themeColor', val)
|
||||
}
|
||||
const customColorChange = val => {
|
||||
addChangeArray('customColor', val)
|
||||
}
|
||||
const resetLoginForm = (reset2Default?: boolean) => {
|
||||
for (const key in loginForm) {
|
||||
loginForm[key] = defaultLoginForm[key]
|
||||
}
|
||||
clearFiles(['web', 'login', 'bg'])
|
||||
if (reset2Default) {
|
||||
addChangeArray('web', '', 'file')
|
||||
addChangeArray('login', '', 'file')
|
||||
addChangeArray('bg', '', 'file')
|
||||
web.value = ''
|
||||
login.value = ''
|
||||
bg.value = ''
|
||||
}
|
||||
}
|
||||
const resetTopForm = (reset2Default?: boolean) => {
|
||||
for (const key in topForm) {
|
||||
topForm[key] = defaultTopForm[key]
|
||||
}
|
||||
clearFiles(['navigate'])
|
||||
if (reset2Default) {
|
||||
addChangeArray('navigate', '', 'file')
|
||||
navigate.value = ''
|
||||
}
|
||||
}
|
||||
const uploadImg = options => {
|
||||
const file = options.file
|
||||
if (file['flag'] === 'web') {
|
||||
web.value = URL.createObjectURL(file)
|
||||
} else if(file['flag'] === 'bg') {
|
||||
bg.value = URL.createObjectURL(file)
|
||||
} else if(file['flag'] === 'login') {
|
||||
login.value = URL.createObjectURL(file)
|
||||
} else if(file['flag'] === 'navigate') {
|
||||
navigate.value = URL.createObjectURL(file)
|
||||
}
|
||||
}
|
||||
const beforeUpload = (file, type) => {
|
||||
addChangeArray(type, file.uid, 'file')
|
||||
let len = fileList.value?.length
|
||||
let match = false
|
||||
file.flag = type
|
||||
while (len--) {
|
||||
const tfile = fileList.value[len]
|
||||
if (type == tfile['flag']) {
|
||||
fileList.value[len] = file
|
||||
match = true
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
fileList.value?.push(file)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const clearFiles = (array?: string[]) => {
|
||||
if (!array?.length || !fileList.value?.length) {
|
||||
fileList.value = []
|
||||
return
|
||||
}
|
||||
let len = fileList.value.length
|
||||
while (len--) {
|
||||
const file = fileList.value[len]
|
||||
if (array.includes(file['flag'])) {
|
||||
fileList.value.splice(len, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getHeight = () => {
|
||||
const dom = document.getElementsByClassName('navigate-preview')
|
||||
const width = dom[0].clientWidth
|
||||
navigateHeight.value = parseInt((width * 0.625).toString())
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
nextTick(() => {
|
||||
getHeight()
|
||||
})
|
||||
window.addEventListener('resize', getHeight)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', getHeight)
|
||||
title: [{ required: true, message: '请输入网站标题', trigger: 'blur' }],
|
||||
slogan: [{ required: true, message: '请输入欢迎语', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
const themeColorChange = (val: string) => {}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.router-title {
|
||||
color: #1f2329;
|
||||
font-feature-settings: "clig" off, "liga" off;
|
||||
font-family: "阿里巴巴普惠体 3.0 55 Regular L3";
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 28px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.appearance-table__content {
|
||||
width: 100%;
|
||||
min-width: 840px;
|
||||
margin-top: 16px;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 180px);
|
||||
box-sizing: border-box;
|
||||
|
||||
:deep(.ed-form-item__error) {
|
||||
top: 88%;
|
||||
}
|
||||
|
||||
.theme,
|
||||
.login,
|
||||
.setting {
|
||||
background: var(--ContentBG, #ffffff);
|
||||
padding: 24px;
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
|
||||
& > :nth-child(1) {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.theme {
|
||||
.navigate-bg {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
margin: 16px 0 8px 0;
|
||||
}
|
||||
.theme-bg {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
margin: 16px 0 6px 0;
|
||||
}
|
||||
|
||||
.color-type {
|
||||
display: flex;
|
||||
.color-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 10px;
|
||||
width: 258px;
|
||||
height: 184px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dee0e3;
|
||||
background-color: #f5f6f7;
|
||||
margin-right: 17px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
img {
|
||||
width: 180px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.color-item-label {
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
border-top: 1px solid #dddedf;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 12px;
|
||||
background-color: #fff;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
&.active {
|
||||
border-color: var(--ed-color-primary);
|
||||
.color-item-label {
|
||||
background-color: #ebf1ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.theme-color {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.custom-color {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.login,
|
||||
.setting {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.login {
|
||||
.page-preview {
|
||||
background-color: #f5f6f7;
|
||||
margin-top: 16px;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
.title {
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.left {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-setting {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.page-content {
|
||||
width: calc(100% - 378px);
|
||||
.navigate-preview {
|
||||
height: calc(100% - 28px);
|
||||
.light-head {
|
||||
background-color: #ffffff !important;
|
||||
box-shadow: 0px 0.5px 0px 0px #1f232926 !important;
|
||||
.ed-divider {
|
||||
border-color: #1f232926 !important;
|
||||
}
|
||||
.logo {
|
||||
color: #3371ff !important;
|
||||
}
|
||||
}
|
||||
.navigate-head {
|
||||
height: 45px;
|
||||
margin-bottom: 1px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #050e21;
|
||||
padding: 0 15px;
|
||||
.logo {
|
||||
width: 120px;
|
||||
height: 28px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ed-divider {
|
||||
margin: 0 17px;
|
||||
border-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
}
|
||||
.navigate-content {
|
||||
height: calc(100% - 45px);
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.tips-page {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
color: #8f959e;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.config-list {
|
||||
width: 378px;
|
||||
margin-left: 16px;
|
||||
|
||||
.config-item {
|
||||
height: 104px;
|
||||
margin-bottom: 8px;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dee0e3;
|
||||
background: #fff;
|
||||
.config-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
.logo {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
}
|
||||
.ed-button {
|
||||
min-width: 64px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 4px 7px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
white-space: pre-wrap;
|
||||
color: #8f959e;
|
||||
}
|
||||
}
|
||||
|
||||
.page-Form {
|
||||
.form-tips {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
color: #8f959e;
|
||||
}
|
||||
|
||||
.ed-form-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.appearance-radio-item {
|
||||
:deep(.ed-form-item__content) {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
// background-color: var(--ed-input-bg-color, var(--ed-fill-color-blank));
|
||||
background-image: none;
|
||||
border-radius: var(--ed-input-border-radius, var(--ed-border-radius-base));
|
||||
transition: var(--ed-transition-box-shadow);
|
||||
box-shadow: 0 0 0 1px var(--ed-input-border-color, var(--ed-border-color)) inset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.appearance-foot {
|
||||
<style lang="scss" scoped>
|
||||
.theme-setting {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 24px;
|
||||
height: 64px;
|
||||
background: var(--ContentBG, #ffffff);
|
||||
box-shadow: 0px -2px 4px 0px #1F232914;
|
||||
margin-top: 1px;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
padding-bottom: 64px;
|
||||
|
||||
&__operate {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background: #ffffff;
|
||||
text-align: right;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0px -2px 4px 0px rgba(31, 35, 41, 0.08);
|
||||
}
|
||||
.theme-preview {
|
||||
min-width: 1000px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div @mousedown="mousedown" class="workflow-node-container p-16" style="overflow: visible">
|
||||
<div
|
||||
class="step-container p-16"
|
||||
class="step-container app-card p-16"
|
||||
:class="props.nodeModel.isSelected ? 'isSelected' : ''"
|
||||
style="overflow: visible"
|
||||
>
|
||||
|
|
@ -161,14 +161,8 @@ function showOperate(type: string) {
|
|||
<style lang="scss" scoped>
|
||||
.workflow-node-container {
|
||||
.step-container {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-radius: 9px;
|
||||
border: 2px solid #ffffff !important;
|
||||
box-shadow: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
|
||||
box-sizing: border-box;
|
||||
&:hover {
|
||||
box-shadow: 0px 6px 24px 0px rgba(31, 35, 41, 0.08);
|
||||
}
|
||||
|
|
|
|||