This commit is contained in:
jacky 2024-04-09 12:31:09 +08:00
parent 6e9811b0f4
commit b9973f343d
9 changed files with 174 additions and 542 deletions

View File

@ -1,27 +0,0 @@
import service from '@/utils/request'
// @Tags InitDB
// @Summary 初始化用户数据库
// @Produce application/json
// @Param data body request.InitDB true "初始化数据库参数"
// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
// @Router /init/initdb [post]
export const initDB = (data) => {
return service({
url: '/init/initdb',
method: 'post',
data,
donNotShowLoading: true
})
}
// @Tags CheckDB
// @Summary 初始化用户数据库
// @Produce application/json
// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
// @Router /init/checkdb [post]
export const checkDB = () => {
return service({
url: '/init/checkdb',
method: 'post'
})
}

View File

@ -4,11 +4,6 @@ const routes = [{
path: '/', path: '/',
redirect: '/login' redirect: '/login'
}, },
{
path: '/init',
name: 'Init',
component: () => import('@/view/init/index.vue')
},
{ {
path: '/login', path: '/login',
name: 'Login', name: 'Login',
@ -20,8 +15,7 @@ const routes = [{
closeTab: true, closeTab: true,
}, },
component: () => import('@/view/error/index.vue') component: () => import('@/view/error/index.vue')
} }]
]
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(), history: createWebHashHistory(),

View File

@ -3,7 +3,7 @@
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="24"> <el-col :span="24">
<div> <div>
email: phpcrazy@163.com 建设中...
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -3,7 +3,7 @@
<div class="gva-card-box"> <div class="gva-card-box">
<div class="gva-card gva-top-card"> <div class="gva-card gva-top-card">
<div class="gva-top-card-left"> <div class="gva-top-card-left">
<div class="gva-top-card-left-title">早安请开始一天的工作吧</div> <div class="gva-top-card-left-title">您好请开始一天的工作吧</div>
<div class="gva-top-card-left-dot">{{ weatherInfo }}</div> <div class="gva-top-card-left-dot">{{ weatherInfo }}</div>
<div> <div>
<div class="gva-top-card-left-item"> <div class="gva-top-card-left-item">
@ -16,11 +16,6 @@
</div> </div>
</div> </div>
</div> </div>
<img
src="@/assets/dashboard.png"
class="gva-top-card-right"
alt
>
</div> </div>
</div> </div>
<div class="gva-card-box"> <div class="gva-card-box">
@ -53,33 +48,10 @@
</el-row> </el-row>
</div> </div>
</div> </div>
<div class="gva-card-box">
<div class="gva-card">
<div class="gva-card-title">数据统计</div>
<div class="p-4">
<el-row :gutter="20">
<el-col
:xs="24"
:sm="18"
>
<echarts-line />
</el-col>
<el-col
:xs="24"
:sm="6"
>
<dashboard-table />
</el-col>
</el-row>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import EchartsLine from '@/view/dashboard/dashboardCharts/echartsLine.vue'
import DashboardTable from '@/view/dashboard/dashboardTable/dashboardTable.vue'
import { ref } from 'vue' import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useWeatherInfo } from '@/view/dashboard/weather.js' import { useWeatherInfo } from '@/view/dashboard/weather.js'
@ -125,13 +97,6 @@ const toolCards = ref([
name: 'formCreate', name: 'formCreate',
color: '#ff85c0', color: '#ff85c0',
bg: 'rgba(255, 133, 192,.3)' bg: 'rgba(255, 133, 192,.3)'
},
{
label: '关于我们',
icon: 'user',
name: 'about',
color: '#5cdbd3',
bg: 'rgba(92, 219, 211,.3)'
} }
]) ])
@ -159,7 +124,7 @@ const toTarget = (name) => {
} }
} }
.gva-top-card { .gva-top-card {
@apply h-72 flex items-center justify-between text-gray-500; @apply h-48 flex items-center justify-between text-gray-500;
&-left { &-left {
@apply h-full flex flex-col w-auto; @apply h-full flex flex-col w-auto;
&-title { &-title {

View File

@ -1,98 +0,0 @@
<template>
<div class="commit-table">
<div class="commit-table-title">
更新日志
</div>
<div class="log">
<div
v-for="(item,key) in dataTimeline"
:key="key"
class="log-item"
>
<div class="flex-1 flex key-box">
<span
class="key"
:class="key<3&&'top'"
>{{ key+1 }}</span>
</div>
<div class="flex-5 flex message">{{ item.message }}</div>
<div class="flex-3 flex form">{{ item.from }}</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
defineOptions({
name: 'DashboardTable',
})
const dataTimeline = ref([])
</script>
<style lang="scss" scoped>
.commit-table{
background-color: #fff;
height: 400px;
&-title{
font-weight: 600;
margin-bottom: 12px;
}
.log{
&-item{
display: flex;
justify-content: space-between;
margin-top: 14px;
.key-box{
justify-content: center;
}
.key{
&.top{
background: #314659;
color: #FFFFFF;;
}
display: inline-flex;
justify-content: center;
align-items: center;
width: 20px;
height: 20px;
border-radius: 50%;
background: #F0F2F5;
text-align: center;
color:rgba($color: #000000, $alpha: 0.65)
}
.message{
color: rgba(0, 0, 0, 0.65);
}
.form{
color: rgba(0, 0, 0, 0.65);
margin-left: 12px;
}
.flex{
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.flex-1{
flex:1;
}
.flex-2{
flex:2;
}
.flex-3{
flex:3;
}
.flex-4{
flex:4;
}
.flex-5{
flex:5;
}
}
}
}
</style>

165
src/view/dashboard/home.vue Normal file
View File

@ -0,0 +1,165 @@
<template>
<div class="page">
<div class="gva-card-box">
<div class="gva-card gva-top-card">
<div class="gva-top-card-left">
<div class="gva-top-card-left-title">您好请开始一天的工作吧</div>
<div class="gva-top-card-left-dot">{{ weatherInfo }}</div>
</div>
</div>
</div>
<div class="gva-card-box">
<div class="gva-card quick-entrance">
<div class="gva-card-title">快捷入口</div>
<el-row :gutter="20">
<el-col
v-for="(card, key) in toolCards"
:key="key"
:span="4"
:xs="8"
class="quick-entrance-items"
@click="toTarget(card.name)"
>
<div class="quick-entrance-item">
<div
class="quick-entrance-item-icon"
:style="{ backgroundColor: card.bg }"
>
<el-icon>
<component
:is="card.icon"
:style="{ color: card.color }"
/>
</el-icon>
</div>
<p>{{ card.label }}</p>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useWeatherInfo } from '@/view/dashboard/weather.js'
defineOptions({
name: 'Dashboard'
})
const weatherInfo = useWeatherInfo()
const toolCards = ref([
{
label: '用户管理',
icon: 'monitor',
name: 'user',
color: '#ff9c6e',
bg: 'rgba(255, 156, 110,.3)'
},
{
label: '角色管理',
icon: 'setting',
name: 'authority',
color: '#69c0ff',
bg: 'rgba(105, 192, 255,.3)'
},
{
label: '菜单管理',
icon: 'menu',
name: 'menu',
color: '#b37feb',
bg: 'rgba(179, 127, 235,.3)'
},
{
label: '代码生成器',
icon: 'cpu',
name: 'autoCode',
color: '#ffd666',
bg: 'rgba(255, 214, 102,.3)'
},
{
label: '表单生成器',
icon: 'document-checked',
name: 'formCreate',
color: '#ff85c0',
bg: 'rgba(255, 133, 192,.3)'
}
])
const router = useRouter()
const toTarget = (name) => {
router.push({ name })
}
</script>
<style lang="scss" scoped>
.page {
@apply p-0;
.gva-card-box{
@apply p-4;
&+.gva-card-box{
@apply pt-0;
}
}
.gva-card {
@apply box-border bg-white rounded h-auto px-6 py-8 overflow-hidden shadow-sm;
.gva-card-title{
@apply pb-5 border-t-0 border-l-0 border-r-0 border-b border-solid border-gray-100;
}
}
.gva-top-card {
@apply h-48 flex items-center justify-between text-gray-500;
&-left {
@apply h-full flex flex-col w-auto;
&-title {
@apply text-3xl text-gray-600;
}
&-dot {
@apply mt-4 text-gray-600 text-lg;
}
&-item{
+.gva-top-card-left-item{
margin-top: 24px;
}
margin-top: 14px;
}
}
&-right {
height: 600px;
width: 600px;
margin-top: 28px;
}
}
::v-deep(.el-card__header){
@apply p-0 border-gray-200;
}
.card-header{
@apply pb-5 border-b border-solid border-gray-200 border-t-0 border-l-0 border-r-0;
}
.quick-entrance-items {
@apply flex items-center justify-center text-center text-gray-800;
.quick-entrance-item {
@apply px-8 py-6 flex items-center flex-col transition-all duration-100 ease-in-out rounded-lg cursor-pointer;
&:hover{
@apply shadow-lg;
}
&-icon {
@apply flex items-center h-16 w-16 rounded-lg justify-center mx-0 my-auto text-2xl;
}
p {
@apply mt-2.5;
}
}
}
}
.dashboard-icon {
@apply flex items-center text-xl mr-2 text-blue-400;
}
</style>

View File

@ -2,8 +2,8 @@
import axios from 'axios' import axios from 'axios'
import { ref } from 'vue' import { ref } from 'vue'
const weatherInfo = ref('今日晴0℃ - 10℃天气寒冷注意添加衣物。') const weatherInfo = ref('')
const amapKey = '8e8baa8a7317586c29ec694895de6e0a' const amapKey = '1f0c8b27920dc41d204800793d629d8e'
export const useWeatherInfo = () => { export const useWeatherInfo = () => {
ip() ip()

View File

@ -1,361 +0,0 @@
<template>
<div class="rounded-lg flex items-center justify-evenly w-full h-full relative bg-white md:w-screen md:h-screen md:bg-[#194bfb] overflow-hidden">
<div class="rounded-md w-full h-full flex items-center justify-center overflow-hidden">
<div class="oblique h-[130%] w-3/5 bg-white transform -rotate-12 absolute -ml-80" />
<div
v-if="!page.showForm"
:class="[page.showReadme ?'slide-out-right' :'slide-in-fwd-top' ]"
>
<div class=" text-lg">
<div class="font-sans text-4xl font-bold text-center mb-4">WEB-ADMIN</div>
<p class="text-gray-600 mb-2">初始化须知</p>
<p class="text-gray-600 mb-2">1.您需有用一定的VUE和GOLANG基础</p>
<p class="text-gray-600 mb-2">2.请您确认是否已经阅读过官方文档初始化视频</p>
<p class="text-gray-600 mb-2">3.请您确认是否了解后续的配置流程</p>
<p class="text-gray-600 mb-2">4.如果您使用mysql数据库请确认数据库引擎为<span class="text-red-600 font-bold text-3xl ml-2 ">innoDB</span></p>
<p class="text-gray-600 mb-2">开发组不为文档中书写过的内容提供无偿服务</p>
<p class="flex items-center justify-between mt-8">
<el-button
type="primary"
size="large"
@click="showNext"
>
我已确认
</el-button>
</p>
</div>
</div>
<div
v-if="page.showForm "
:class="[ page.showForm ? 'slide-in-left' : 'slide-out-right' ]"
class="w-96"
>
<el-form
ref="formRef"
:model="form"
label-width="100px"
size="large"
>
<el-form-item label="数据库类型">
<el-select
v-model="form.dbType"
placeholder="请选择"
class="w-full"
@change="changeDB"
>
<el-option
key="mysql"
label="mysql"
value="mysql"
/>
<el-option
key="pgsql"
label="pgsql"
value="pgsql"
/>
<el-option
key="oracle"
label="oracle"
value="oracle"
/>
<el-option
key="mssql"
label="mssql"
value="mssql"
/>
<el-option
key="sqlite"
label="sqlite"
value="sqlite"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="form.dbType !== 'sqlite'"
label="host"
>
<el-input
v-model="form.host"
placeholder="请输入数据库链接"
/>
</el-form-item>
<el-form-item
v-if="form.dbType !== 'sqlite'"
label="port"
>
<el-input
v-model="form.port"
placeholder="请输入数据库端口"
/>
</el-form-item>
<el-form-item
v-if="form.dbType !== 'sqlite'"
label="userName"
>
<el-input
v-model="form.userName"
placeholder="请输入数据库用户名"
/>
</el-form-item>
<el-form-item
v-if="form.dbType !== 'sqlite'"
label="password"
>
<el-input
v-model="form.password"
placeholder="请输入数据库密码(没有则为空)"
/>
</el-form-item>
<el-form-item label="dbName">
<el-input
v-model="form.dbName"
placeholder="请输入数据库名称"
/>
</el-form-item>
<el-form-item
v-if="form.dbType === 'sqlite'"
label="dbPath"
>
<el-input
v-model="form.dbPath"
placeholder="请输入sqlite数据库文件存放路径"
/>
</el-form-item>
<el-form-item>
<div style="text-align: right">
<el-button
type="primary"
@click="onSubmit"
>立即初始化</el-button>
</div>
</el-form-item>
</el-form>
</div>
</div>
<div class="hidden md:block w-1/2 h-full float-right bg-[#194bfb]"><img
class="h-full"
src="@/assets/login_right_banner.jpg"
alt="banner"
></div>
</div>
</template>
<script setup>
// @ts-ignore
import { initDB } from '@/api/initdb'
import { reactive, ref } from 'vue'
import { ElLoading, ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
defineOptions({
name: 'Init',
})
const router = useRouter()
const page = reactive({
showReadme: false,
showForm: false
})
const showNext = () => {
page.showReadme = false
setTimeout(() => {
page.showForm = true
}, 20)
}
const goDoc = () => {
// test
}
const out = ref(false)
const form = reactive({
dbType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva',
dbPath: ''
})
const changeDB = (val) => {
switch (val) {
case 'mysql':
Object.assign(form, {
dbType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva',
dbPath: ''
})
break
case 'pgsql':
Object.assign(form, {
dbType: 'pgsql',
host: '127.0.0.1',
port: '5432',
userName: 'postgres',
password: '',
dbName: 'gva',
dbPath: ''
})
break
case 'oracle':
Object.assign(form, {
dbType: 'oracle',
host: '127.0.0.1',
port: '1521',
userName: 'oracle',
password: '',
dbName: 'gva',
dbPath: ''
})
break
case 'mssql':
Object.assign(form, {
dbType: 'mssql',
host: '127.0.0.1',
port: '1433',
userName: 'mssql',
password: '',
dbName: 'gva',
dbPath: ''
})
break
case 'sqlite':
Object.assign(form, {
dbType: 'sqlite',
host: '',
port: '',
userName: '',
password: '',
dbName: 'gva',
dbPath: ''
})
break
default:
Object.assign(form, {
dbType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva',
dbPath: ''
})
}
}
const onSubmit = async() => {
const loading = ElLoading.service({
lock: true,
text: '正在初始化数据库,请稍候',
spinner: 'loading',
background: 'rgba(0, 0, 0, 0.7)',
})
try {
const res = await initDB(form)
if (res.code === 0) {
out.value = true
ElMessage({
type: 'success',
message: res.msg,
})
router.push({ name: 'Login' })
}
loading.close()
} catch (err) {
loading.close()
}
}
</script>
<style lang="scss" scoped>
.slide-in-fwd-top {
-webkit-animation: slide-in-fwd-top 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)
both;
animation: slide-in-fwd-top 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
.slide-out-right {
-webkit-animation: slide-out-right 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53)
both;
animation: slide-out-right 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53) both;
}
.slide-in-left {
-webkit-animation: slide-in-left 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94)
both;
animation: slide-in-left 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
@-webkit-keyframes slide-in-fwd-top {
0% {
transform: translateZ(-1400px) translateY(-800px);
opacity: 0;
}
100% {
transform: translateZ(0) translateY(0);
opacity: 1;
}
}
@keyframes slide-in-fwd-top {
0% {
transform: translateZ(-1400px) translateY(-800px);
opacity: 0;
}
100% {
transform: translateZ(0) translateY(0);
opacity: 1;
}
}
@-webkit-keyframes slide-out-right {
0% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(1000px);
opacity: 0;
}
}
@keyframes slide-out-right {
0% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(1000px);
opacity: 0;
}
}
@-webkit-keyframes slide-in-left {
0% {
transform: translateX(-1000px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-in-left {
0% {
transform: translateX(-1000px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@media (max-width: 750px) {
.form {
width: 94vw !important;
padding: 0;
}
}
</style>

View File

@ -1,11 +1,5 @@
<!-- 此文件禁止修改如果您没有购买授权请联系wx:shouzi_1994购买授权未授权状态只需保留此代码 不影响任何正常使用 --> <!-- 此文件禁止修改如果您没有购买授权请联系wx:shouzi_1994购买授权未授权状态只需保留此代码 不影响任何正常使用 -->
<template> <template>
<div class="flex gap-4 items-center text-sm text-gray-500 justify-center mb-4"> <div class="flex gap-4 items-center text-sm text-gray-500 justify-center mb-4" />
<span>Powered by</span>
<span>Web-Admin</span>
<slot />
<span>Copyright</span>
<span>利农天下</span>
</div>
</template> </template>