提交 19e919b1 编写于 作者: Mr.奇淼('s avatar Mr.奇淼(

Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev

# Conflicts:
#	web/package-lock.json
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.pnp.*
**/node_modules
FROM golang:alpine as builder
RUN apk add --update --no-cache yarn make g++
RUN yarn global add cross-env node-sass
ENV GOPROXY=https://goproxy.cn,https://goproxy.io,direct \
GO111MODULE=on \
CGO_ENABLED=1
WORKDIR /go/src/gin-vue-admin
RUN go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct
COPY server/ ./
RUN go env && go list && go build -v -a -ldflags "-extldflags \"-static\" " -o gvadmin .
WORKDIR /web
COPY web/ ./
RUN yarn install && yarn run build
FROM nginx:alpine
LABEL MAINTAINER="rikugun"
RUN apk add --no-cache gettext tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
date && \
apk del tzdata
COPY docker/etc/nginx/nginx.conf.tpl /etc/nginx/nginx.conf.tpl
WORKDIR /app
#copy web
COPY --from=builder /web/dist/ /var/www/
#copy go app
COPY --from=builder /go/src/gin-vue-admin/gvadmin ./
COPY --from=builder /go/src/gin-vue-admin/db.db ./
COPY --from=builder /go/src/gin-vue-admin/config.yaml ./
COPY --from=builder /go/src/gin-vue-admin/resource ./resource
COPY docker/docker-start.sh ./
ENV API_SERVER="http://localhost:8888/"
EXPOSE 80
ENTRYPOINT ["./docker-start.sh"]
...@@ -10,8 +10,8 @@ networks: ...@@ -10,8 +10,8 @@ networks:
services: services:
web: web:
build: build:
context: ./ context: ./web
dockerfile: ./dockerfile_web dockerfile: ./Dockerfile
container_name: gva-web container_name: gva-web
restart: always restart: always
ports: ports:
...@@ -25,8 +25,8 @@ services: ...@@ -25,8 +25,8 @@ services:
server: server:
build: build:
context: ./ context: ./server
dockerfile: ./dockerfile_server dockerfile: ./Dockerfile
container_name: gva-server container_name: gva-server
restart: always restart: always
ports: ports:
......
#!/bin/sh
envsubst '$API_SERVER' < /etc/nginx/nginx.conf.tpl > /etc/nginx/nginx.conf
env nginx
./gvadmin
daemon on;
worker_processes 50;
#error_log /dev/stdout warn;
error_log /var/log/nginx/error.log error;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# See http://licson.net/post/optimizing-nginx-for-large-file-delivery/ for more detail
# This optimizes the server for HLS fragment delivery
sendfile off;
#tcp_nopush on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log /dev/stdout combined;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;
server {
listen 80;
# Uncomment these lines to enable SSL.
# Update the ssl paths with your own certificate and private key.
# listen 443 ssl;
# ssl_certificate /opt/certs/example.com.crt;
# ssl_certificate_key /opt/certs/example.com.key;
location / {
root /var/www;
try_files $uri $uri/ /index.html;
index index.html;
}
location /v1/ {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_pass ${API_SERVER} ;
}
}
}
FROM golang:alpine
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct
WORKDIR /go/src/gin-vue-admin
COPY server/ ./
RUN go env && go mod tidy && go build -o server .
FROM alpine:latest
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
WORKDIR /go/src/gin-vue-admin
COPY --from=0 /go/src/gin-vue-admin/server ./
COPY --from=0 /go/src/gin-vue-admin/config.docker.yaml ./
COPY --from=0 /go/src/gin-vue-admin/resource ./resource
EXPOSE 8888
ENTRYPOINT ./server -c config.docker.yaml
{ {
"lockfileVersion": 1 "name": "gin-vue-admin",
"lockfileVersion": 2,
"requires": true,
"packages": {}
} }
...@@ -2,19 +2,18 @@ FROM golang:alpine ...@@ -2,19 +2,18 @@ FROM golang:alpine
ENV GO111MODULE=on ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct ENV GOPROXY=https://goproxy.io,direct
WORKDIR /go/src/gin-vue-admin WORKDIR /go/src/gin-vue-admin
COPY . . COPY . .
RUN go env && go build -o server . RUN go env && go build -o server .
FROM alpine:latest FROM alpine:latest
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com" LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
WORKDIR /go/src/gin-vue-admin WORKDIR /go/src/gin-vue-admin
COPY --from=0 /go/src/gin-vue-admin/server ./
COPY --from=0 /go/src/gin-vue-admin/config.yaml ./ COPY --from=0 /go/src/gin-vue-admin ./
COPY --from=0 /go/src/gin-vue-admin/resource ./resource
EXPOSE 8888 EXPOSE 8888
ENTRYPOINT ./server ENTRYPOINT ./server -c config.docker.yaml
...@@ -43,7 +43,7 @@ system: ...@@ -43,7 +43,7 @@ system:
env: 'public' # Change to "develop" to skip authentication for development mode env: 'public' # Change to "develop" to skip authentication for development mode
addr: 8888 addr: 8888
db-type: 'mysql' db-type: 'mysql'
oss-type: 'local' # 控制oss选择走本还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置 oss-type: 'local' # 控制oss选择走本还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
use-multipoint: false use-multipoint: false
# captcha configuration # captcha configuration
...@@ -85,7 +85,7 @@ autocode: ...@@ -85,7 +85,7 @@ autocode:
web-form: /view web-form: /view
web-table: /view web-table: /view
# qiniu configuration (请自行申请七牛对应的 公钥 私钥 bucket 和 域名地址) # qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu: qiniu:
zone: 'ZoneHuaDong' zone: 'ZoneHuaDong'
bucket: '' bucket: ''
......
node_modules/
\ No newline at end of file
FROM node:12.16.1 FROM node:12.16.1
WORKDIR /gva_web/ WORKDIR /gva_web/
COPY web/ . COPY . .
RUN npm install -g cnpm --registry=https://registry.npm.taobao.org RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
RUN cnpm install || npm install RUN cnpm install || npm install
...@@ -15,4 +15,3 @@ COPY --from=0 /gva_web/dist /usr/share/nginx/html ...@@ -15,4 +15,3 @@ COPY --from=0 /gva_web/dist /usr/share/nginx/html
RUN cat /etc/nginx/nginx.conf RUN cat /etc/nginx/nginx.conf
RUN cat /etc/nginx/conf.d/my.conf RUN cat /etc/nginx/conf.d/my.conf
RUN ls -al /usr/share/nginx/html RUN ls -al /usr/share/nginx/html
CMD ls -al /usr/share/nginx/html
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" width="100%" height="100%" viewBox="0 0 1400 800">
<rect x="1300" y="400" rx="40" ry="40" width="150" height="150" stroke="rgb(129, 201, 149)" fill="rgb(129, 201, 149)">
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="0 1450 550" to="360 1450 550" repeatCount="indefinite"/>
</rect>
<path d="M 100 350 A 150 150 0 1 1 400 350 Q400 370 380 370 L 250 370 L 120 370 Q100 370 100 350" fill="#a2b3ff">
<animateMotion path="M 800 -200 L 800 -300 L 800 -200" dur="20s" begin="0s" repeatCount="indefinite"/>
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="30s" type="rotate" values="0 210 530 ; -30 210 530 ; 0 210 530" keyTimes="0 ; 0.5 ; 1" repeatCount="indefinite"/>
</path>
<circle cx="150" cy="150" r="180" stroke="#85FFBD" fill="#85FFBD">
<animateMotion path="M 0 0 L 40 20 Z" dur="5s" repeatCount="indefinite"/>
</circle>
<!-- 三角形 -->
<path d="M 165 580 L 270 580 Q275 578 270 570 L 223 483 Q220 480 217 483 L 165 570 Q160 578 165 580" fill="#a2b3ff">
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="0 210 530" to="360 210 530" repeatCount="indefinite"/>
</path>
<!-- <circle cx="1200" cy="600" r="30" stroke="rgb(241, 243, 244)" fill="rgb(241, 243, 244)">-->
<!-- <animateMotion path="M 0 0 L -20 40 Z" dur="9s" repeatCount="indefinite"/>-->
<!-- </circle>-->
<path d="M 100 350 A 40 40 0 1 1 180 350 L 180 430 A 40 40 0 1 1 100 430 Z" fill="#3054EB">
<animateMotion path="M 140 390 L 180 360 L 140 390" dur="20s" begin="0s" repeatCount="indefinite"/>
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="30s" type="rotate" values="0 140 390; -60 140 390; 0 140 390" keyTimes="0 ; 0.5 ; 1" repeatCount="indefinite"/>
</path>
<rect x="400" y="600" rx="40" ry="40" width="100" height="100" stroke="rgb(129, 201, 149)" fill="#3054EB">
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="-30 550 750" to="330 550 750" repeatCount="indefinite"/>
</rect>
</svg>
\ No newline at end of file
此差异已折叠。
/*
*
* 按需加载element
*
*
* */
import Vue from 'vue'
// 按需引入element
import {
Button,
Select,
Dialog,
Form,
Input,
FormItem,
Option,
Loading,
Message,
Container,
Card,
Dropdown,
DropdownMenu,
DropdownItem,
Row,
Col,
Menu,
Submenu,
MenuItem,
Aside,
Main,
Badge,
Header,
Tabs,
Breadcrumb,
BreadcrumbItem,
Scrollbar,
Avatar,
TabPane,
Divider,
Table,
TableColumn,
Cascader,
Checkbox,
CheckboxGroup,
Pagination,
Tag,
Drawer,
Tree,
Popover,
Switch,
Collapse,
CollapseItem,
Tooltip,
DatePicker,
InputNumber,
Steps,
Upload,
Progress,
MessageBox,
Image
} from 'element-ui'
Vue.use(Button)
Vue.use(Select)
Vue.use(Dialog)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Option)
Vue.use(Container)
Vue.use(Card)
Vue.use(Dropdown)
Vue.use(DropdownMenu)
Vue.use(DropdownItem)
Vue.use(Row)
Vue.use(Col)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Badge)
Vue.use(Header)
Vue.use(Tabs)
Vue.use(Breadcrumb)
Vue.use(BreadcrumbItem)
Vue.use(Avatar)
Vue.use(TabPane)
Vue.use(Divider)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(Checkbox)
Vue.use(Cascader)
Vue.use(Tag)
Vue.use(Pagination)
Vue.use(Drawer)
Vue.use(Tree)
Vue.use(CheckboxGroup)
Vue.use(Popover)
Vue.use(InputNumber)
Vue.use(Switch)
Vue.use(Collapse)
Vue.use(CollapseItem)
Vue.use(Tooltip)
Vue.use(DatePicker)
Vue.use(Steps)
Vue.use(Upload)
Vue.use(Progress)
Vue.use(Scrollbar)
Vue.use(Loading.directive)
Vue.use(Image)
Vue.prototype.$loading = Loading.service
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
Dialog.props.closeOnClickModal.default = false
console.warn('[GIN-VUE-ADMIN]--按需加载elementUI成功,如出现element-ui组件无法使用问题,请至/src/core/element_lazy 下引入对应组件即可')
/*
* gin-vue-admin web框架组
*
* */
import Vue from 'vue'
import './element_lazy' // 按需加载element
import uploader from 'vue-simple-uploader'
import APlayer from '@moefe/vue-aplayer'
// time line css
import '../../node_modules/timeline-vuejs/dist/timeline-vuejs.css'
// 路由守卫
import Bus from '@/utils/bus'
Vue.use(Bus)
Vue.use(APlayer, {
defaultCover: 'https://github.com/u3u.png',
productionTip: true
})
Vue.use(uploader)
console.log(`
欢迎使用 Gin-Vue-Admin
当前版本:V2.4.2
加群方式:微信:shouzi_1994 QQ群:622360840
默认自动化文档地址:http://127.0.0.1:${process.env.VUE_APP_SERVER_PORT}/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:${process.env.VUE_APP_CLI_PORT}
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee
`)
import Vue from 'vue' import Vue from 'vue'
import App from './App.vue' import App from './App.vue'
// 引入gin-vue-admin前端初始化相关内容
// 按需引入element import './core/gin-vue-admin'
import {
Button,
Select,
Dialog,
Form,
Input,
FormItem,
Option,
Loading,
Message,
Container,
Card,
Dropdown,
DropdownMenu,
DropdownItem,
Row,
Col,
Menu,
Submenu,
MenuItem,
Aside,
Main,
Badge,
Header,
Tabs,
Breadcrumb,
BreadcrumbItem,
Scrollbar,
Avatar,
TabPane,
Divider,
Table,
TableColumn,
Cascader,
Checkbox,
CheckboxGroup,
Pagination,
Tag,
Drawer,
Tree,
Popover,
Switch,
Collapse,
CollapseItem,
Tooltip,
DatePicker,
InputNumber,
Steps,
Upload,
Progress,
MessageBox,
Image
} from 'element-ui'
Vue.use(Button)
Vue.use(Select)
Vue.use(Dialog)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Option)
Vue.use(Container)
Vue.use(Card)
Vue.use(Dropdown)
Vue.use(DropdownMenu)
Vue.use(DropdownItem)
Vue.use(Row)
Vue.use(Col)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Badge)
Vue.use(Header)
Vue.use(Tabs)
Vue.use(Breadcrumb)
Vue.use(BreadcrumbItem)
Vue.use(Avatar)
Vue.use(TabPane)
Vue.use(Divider)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(Checkbox)
Vue.use(Cascader)
Vue.use(Tag)
Vue.use(Pagination)
Vue.use(Drawer)
Vue.use(Tree)
Vue.use(CheckboxGroup)
Vue.use(Popover)
Vue.use(InputNumber)
Vue.use(Switch)
Vue.use(Collapse)
Vue.use(CollapseItem)
Vue.use(Tooltip)
Vue.use(DatePicker)
Vue.use(Steps)
Vue.use(Upload)
Vue.use(Progress)
Vue.use(Scrollbar)
Vue.use(Loading.directive)
Vue.use(Image)
Vue.prototype.$loading = Loading.service
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
Dialog.props.closeOnClickModal.default = false
// 引入封装的router // 引入封装的router
import router from '@/router/index' import router from '@/router/index'
// time line css
import '../node_modules/timeline-vuejs/dist/timeline-vuejs.css'
import '@/permission' import '@/permission'
import { store } from '@/store' import { store } from '@/store'
Vue.config.productionTip = false Vue.config.productionTip = false
// 路由守卫
import Bus from '@/utils/bus'
Vue.use(Bus)
import APlayer from '@moefe/vue-aplayer'
Vue.use(APlayer, {
defaultCover: 'https://github.com/u3u.png',
productionTip: true
})
import { auth } from '@/directive/auth' import { auth } from '@/directive/auth'
// 按钮权限指令 // 按钮权限指令
auth(Vue) auth(Vue)
import uploader from 'vue-simple-uploader'
Vue.use(uploader)
export default new Vue({ export default new Vue({
render: h => h(App), render: h => h(App),
router, router,
store store
}).$mount('#app') }).$mount('#app')
console.log(`
欢迎使用 Gin-Vue-Admin
当前版本:V2.4.2
加群方式:微信:shouzi_1994 QQ群:622360840
默认自动化文档地址:http://127.0.0.1:${process.env.VUE_APP_SERVER_PORT}/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:${process.env.VUE_APP_CLI_PORT}
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee
`)
...@@ -18,12 +18,12 @@ const baseRouters = [ ...@@ -18,12 +18,12 @@ const baseRouters = [
{ {
path: '/init', path: '/init',
name: 'Init', name: 'Init',
component: () => import('@/view/init/init') component: () => import('@/view/init/index')
}, },
{ {
path: '/login', path: '/login',
name: 'Login', name: 'Login',
component: () => import('@/view/login/login') component: () => import('@/view/login/index')
} }
] ]
......
#userLayout{
margin: 0;
padding: 0;
background-image: url("~@/assets/login_background.svg");
background-size: cover;
width: 100%;
height: 100%;
position: relative;
.login_panle{
position: absolute;
top: 3vh;
left: 2vw;
width: 96vw;
height: 94vh;
background-color: rgba(255,255,255,.8);
backdrop-filter: blur(5px);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: space-evenly;
.login_panle_right{
background-image: url("~@/assets/login_left.svg");
background-size: cover;
width: 40%;
height: 60%;
float: right !important;
}
.login_panle_form{
width: 420px;
background-color: #fff;
padding: 40px 40px 40px 40px;
border-radius: 10px;
box-shadow: 2px 3px 7px rgba(0,0,0,.2);
.login_panle_form_title{
display: flex;
align-items: center;
margin: 30px 0;
.login_panle_form_title_logo{
width: 90px;
height: 72px;
}
.login_panle_form_title_p{
font-size: 40px;
padding-left: 20px ;
}
}
.vPic {
width: 33%;
height: 38px;
float: right !important;
background: #ccc;
img {
cursor: pointer;
vertical-align: middle;
}
}
}
.login_panle_foot{
position: absolute;
bottom: 20px;
.links{
display: flex;
align-items: center;
justify-content: space-between;
.link-icon{
width: 30px;
height: 30px;
}
}
.copyright{
color: #777777;
margin-top: 5px;
}
}
}
}
//小屏幕不显示右侧,将登陆框居中
@media (max-width: 750px) {
.login_panle_right{
display: none;
}
.login_panle{
width: 100vw;
height: 100vh;
top: 0;
left: 0;
}
.login_panle_form{
width: 100%;
}
}
/*
powerBy : bypanghu@163.com
*/
\ No newline at end of file
<template>
<div class="init_page">
<div class="init_page_panle">
<div v-if="hello < 2" id="hello" :class="[hello < 1 ? 'slide-in-fwd-top' : 'slide-out-right']" class="hello " @click="showNext">
<div>
<div class="hello_title">GIN-VUE-ADMIN</div>
<p class="in-two a-fadeinT">您需要初始化您的数据库并且填充初始数据</p>
<p class="init_p">点击进入初始化</p>
</div>
</div>
<div v-if="hello > 0 " :class="[(hello > 0 && !out)? 'slide-in-left' : '' , out ? 'slide-out-right' : '']" class=" form">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="数据库类型">
<el-select v-model="form.sqlType" disabled placeholder="请选择">
<el-option key="mysql" label="mysql(目前只支持mysql)" value="mysql" />
</el-select>
</el-form-item>
<el-form-item label="host">
<el-input v-model="form.host" placeholder="请输入数据库链接" />
</el-form-item>
<el-form-item label="port">
<el-input v-model="form.port" placeholder="请输入数据库端口" />
</el-form-item>
<el-form-item label="userName">
<el-input v-model="form.userName" placeholder="请输入数据库用户名" />
</el-form-item>
<el-form-item 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>
<div style="text-align: right">
<el-button type="primary" @click="onSubmit">立即初始化</el-button>
</div>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
import { initDB } from '@/api/initdb'
export default {
name: 'Init',
data() {
return {
hello: 0,
out: false,
form: {
sqlType: 'mysql',
host: '127.0.0.1',
port: '3306',
userName: 'root',
password: '',
dbName: 'gva'
}
}
},
created() {
// setInterval(() => {
// if (this.hello < 3) {
// this.hello = this.hello + 1
// }
// }, 2000)
},
methods: {
showNext() {
this.hello = this.hello + 1
console.log(this.hello)
},
async onSubmit() {
this.out = true
const loading = this.$loading({
lock: true,
text: '正在初始化数据库,请稍候',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
try {
const res = await initDB(this.form)
if (res.code === 0) {
this.$message({
type: 'success',
message: res.msg
})
this.$router.push({ name: 'Login' })
}
loading.close()
} catch (err) {
loading.close()
}
}
}
}
</script>
<style lang="scss" scoped>
.init_page{
margin: 0;
padding: 0;
background-image: url("~@/assets/login_background.svg");
background-size: cover;
width: 100%;
height: 100%;
position: relative;
.init_page_panle{
position: absolute;
top: 3vh;
left: 2vw;
width: 96vw;
height: 94vh;
background-color: rgba(255,255,255,.8);
backdrop-filter: blur(5px);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: space-evenly;
.hello{
position: absolute;
z-index: 2;
text-align: center;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
.hello_title{
font-size: 32px;
line-height: 98px;
}
.in-two{
font-size: 22px;
}
.init_p{
margin-top: 20px;
color: #777777;
}
}
.form{
position: absolute;
z-index: 3;
margin-top: 60px;
width: 600px;
height: auto;
padding: 20px;
border-radius: 6px;
}
}
}
.slide-in-fwd-top {
-webkit-animation: slide-in-fwd-top 0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-fwd-top 0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
.slide-out-right {
-webkit-animation: slide-out-right 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
animation: slide-out-right 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
}
.slide-in-left {
-webkit-animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@-webkit-keyframes slide-in-fwd-top {
0% {
-webkit-transform: translateZ(-1400px) translateY(-800px);
transform: translateZ(-1400px) translateY(-800px);
opacity: 0;
}
100% {
-webkit-transform: translateZ(0) translateY(0);
transform: translateZ(0) translateY(0);
opacity: 1;
}
}
@keyframes slide-in-fwd-top {
0% {
-webkit-transform: translateZ(-1400px) translateY(-800px);
transform: translateZ(-1400px) translateY(-800px);
opacity: 0;
}
100% {
-webkit-transform: translateZ(0) translateY(0);
transform: translateZ(0) translateY(0);
opacity: 1;
}
}
@-webkit-keyframes slide-out-right {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
100% {
-webkit-transform: translateX(1000px);
transform: translateX(1000px);
opacity: 0;
}
}
@keyframes slide-out-right {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
100% {
-webkit-transform: translateX(1000px);
transform: translateX(1000px);
opacity: 0;
}
}
@-webkit-keyframes slide-in-left {
0% {
-webkit-transform: translateX(-1000px);
transform: translateX(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-in-left {
0% {
-webkit-transform: translateX(-1000px);
transform: translateX(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
opacity: 1;
}
}
@media (max-width: 750px) {
.form{
width: 94vw !important;
padding: 0;
}
}
</style>
<template>
<div id="userLayout">
<div class="login_panle">
<div class="login_panle_form">
<div class="login_panle_form_title">
<img class="login_panle_form_title_logo" src="@/assets/logo_login.png" alt=""><p class="login_panle_form_title_p">GIN-VUE-ADMIN</p>
</div>
<el-form
ref="loginForm"
:model="loginForm"
:rules="rules"
@keyup.enter.native="submitForm"
>
<el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="请输入用户名">
<i slot="suffix" class="el-input__icon el-icon-user" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
:type="lock === 'lock' ? 'password' : 'text'"
placeholder="请输入密码"
>
<i
slot="suffix"
:class="'el-input__icon el-icon-' + lock"
@click="changeLock"
/>
</el-input>
</el-form-item>
<el-form-item style="position: relative">
<el-input
v-model="loginForm.captcha"
name="logVerify"
placeholder="请输入验证码"
style="width: 60%"
/>
<div class="vPic">
<img
v-if="picPath"
:src="picPath"
width="100%"
height="100%"
alt="请输入验证码"
@click="loginVerify()"
>
</div>
</el-form-item>
<el-form-item>
<el-button
type="primary"
style="width: 100%"
@click="submitForm"
>登 录</el-button>
</el-form-item>
</el-form>
</div>
<div class="login_panle_right" />
<div class="login_panle_foot">
<div class="links">
<a href="http://doc.henrongyi.top/"><img src="@/assets/docs.png" class="link-icon"></a>
<a href="https://www.yuque.com/flipped-aurora/"><img src="@/assets/yuque.png" class="link-icon"></a>
<a href="https://github.com/flipped-aurora/gin-vue-admin"><img src="@/assets/github.png" class="link-icon"></a>
<a href="https://space.bilibili.com/322210472"><img src="@/assets/video.png" class="link-icon"></a>
</div>
<div class="copyright">Copyright &copy; {{ curYear }} 💖 flipped-aurora</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import { captcha } from '@/api/user'
export default {
name: 'Login',
data() {
const checkUsername = (rule, value, callback) => {
if (value.length < 5) {
return callback(new Error('请输入正确的用户名'))
} else {
callback()
}
}
const checkPassword = (rule, value, callback) => {
if (value.length < 6) {
return callback(new Error('请输入正确的密码'))
} else {
callback()
}
}
return {
curYear: 0,
lock: 'lock',
loginForm: {
username: 'admin',
password: '123456',
captcha: '',
captchaId: ''
},
rules: {
username: [{ validator: checkUsername, trigger: 'blur' }],
password: [{ validator: checkPassword, trigger: 'blur' }]
},
logVerify: '',
picPath: ''
}
},
created() {
this.loginVerify()
this.curYear = new Date().getFullYear()
},
methods: {
...mapActions('user', ['LoginIn']),
async login() {
return await this.LoginIn(this.loginForm)
},
async submitForm() {
this.$refs.loginForm.validate(async(v) => {
if (v) {
const flag = await this.login()
if (!flag) {
this.loginVerify()
}
} else {
this.$message({
type: 'error',
message: '请正确填写登录信息',
showClose: true
})
this.loginVerify()
return false
}
})
},
changeLock() {
this.lock = this.lock === 'lock' ? 'unlock' : 'lock'
},
loginVerify() {
captcha({}).then((ele) => {
this.picPath = ele.data.picPath
this.loginForm.captchaId = ele.data.captchaId
})
}
}
}
</script>
<style lang="scss" scoped>
@import "@/style/newLogin.scss";
</style>
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册