mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-11-29 18:38:32 +08:00
fix
This commit is contained in:
parent
9253785610
commit
d9d57c01e9
@ -26,20 +26,126 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="favicon.ico" />
|
||||
<link rel="icon" href="<%- base_url %>favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="keywords" content="Jpom,Java项目管理,Jar管理,Java管理系统,服务器项目运维" />
|
||||
<meta name="description" content="Jpom-项目管理系统,简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
<meta name="build-time" content="2023-12-12" />
|
||||
<meta name="build-env" content="生产" />
|
||||
<meta name="jpom-version" content="2.2.30" />
|
||||
<title>Jpom项目管理系统</title>
|
||||
<meta name="build-time" content="<%- build %>" />
|
||||
<meta name="build-env" content="<%- env %>" />
|
||||
<meta name="jpom-version" content="<%- buildVersion %>" />
|
||||
<title><%- title %></title>
|
||||
<style>
|
||||
.first-loading-wrp {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
min-height: 420px;
|
||||
height: 100%;
|
||||
}
|
||||
.first-loading-wrp > h1 {
|
||||
font-size: 128px;
|
||||
}
|
||||
.first-loading-wrp .loading-wrp {
|
||||
padding: 98px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.dot {
|
||||
animation: antRotate 1.2s infinite linear;
|
||||
transform: rotate(45deg);
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-size: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.dot i {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
background-color: #1890ff;
|
||||
border-radius: 100%;
|
||||
transform: scale(0.75);
|
||||
transform-origin: 50% 50%;
|
||||
opacity: 0.3;
|
||||
animation: antSpinMove 1s infinite linear alternate;
|
||||
}
|
||||
.dot i:nth-child(1) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.dot i:nth-child(2) {
|
||||
top: 0;
|
||||
right: 0;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
.dot i:nth-child(3) {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
.dot i:nth-child(4) {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
@keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
@keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<noscript>
|
||||
<strong
|
||||
>We're sorry but <%- title %> doesn't work properly without JavaScript enabled. Please enable it to
|
||||
continue.</strong
|
||||
>
|
||||
</noscript>
|
||||
<script>
|
||||
window.routerBase = '<routerBase>'
|
||||
window.apiTimeout = '<apiTimeout>'
|
||||
window.uploadFileSliceSize = '<uploadFileSliceSize>'
|
||||
window.uploadFileConcurrent = '<uploadFileConcurrent>'
|
||||
window.oauth2Provide = '<oauth2Provide>'
|
||||
</script>
|
||||
<div id="app">
|
||||
<div class="first-loading-wrp">
|
||||
<div class="loading-wrp">
|
||||
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: center; align-items: center"><%- title %></div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<div id="jpomCommonJs"><!--Don't delete this line, place for public JS --></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "web-vue3",
|
||||
"name": "jpom-vue3",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "2.10.39",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --mode dev",
|
||||
@ -42,6 +42,7 @@
|
||||
"eslint": "^8.36.0",
|
||||
"https": "^1.0.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.1.0"
|
||||
"vite": "^4.1.0",
|
||||
"vite-plugin-html": "^3.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import { useMenuStore } from '@/stores/menu'
|
||||
const _window = window as any
|
||||
const delTimeout = 20 * 1000
|
||||
const apiTimeout = _window.apiTimeout === '<apiTimeout>' ? delTimeout : _window.apiTimeout
|
||||
// debug routerBase
|
||||
const routerBase = _window.routerBase === '<routerBase>' ? '' : _window.routerBase
|
||||
|
||||
const pro = process.env.NODE_ENV === 'production'
|
||||
|
||||
@ -30,15 +32,13 @@ instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
|
||||
const userStore = useUserStore()
|
||||
|
||||
const { headers } = config
|
||||
const accessToken = localStorage.getItem('accessToken')
|
||||
headers['Authorization'] = accessToken ? 'Bearer ' + accessToken : ''
|
||||
headers[TOKEN_HEADER_KEY] = userStore.token
|
||||
headers[CACHE_WORKSPACE_ID] = appStore.getWorkspaceId
|
||||
|
||||
// if (_window.routerBase) {
|
||||
// // 防止 url 出现 //
|
||||
// config.url = (_window.routerBase + config.url).replace(new RegExp('//', 'gm'), '/')
|
||||
// }
|
||||
if (routerBase) {
|
||||
// 防止 url 出现 //
|
||||
config.url = (routerBase + config.url).replace(new RegExp('//', 'gm'), '/')
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
|
24
web-vue3/src/interface/common.d.ts
vendored
24
web-vue3/src/interface/common.d.ts
vendored
@ -1,10 +1,18 @@
|
||||
export interface SystemType {
|
||||
disabledCaptcha: bollean
|
||||
disabledGuide: bollean
|
||||
inDocker: bollean
|
||||
loginTitle: string
|
||||
name: string
|
||||
notificationPlacement: string
|
||||
routerBase: string
|
||||
subTitle: string
|
||||
disabledCaptcha: bollean
|
||||
disabledGuide: bollean
|
||||
inDocker: bollean
|
||||
loginTitle: string
|
||||
name: string
|
||||
notificationPlacement: string
|
||||
routerBase: string
|
||||
subTitle: string
|
||||
}
|
||||
|
||||
export interface GlobalWindow {
|
||||
routerBase: string
|
||||
apiTimeout: string
|
||||
uploadFileSliceSize: string
|
||||
uploadFileConcurrent: string
|
||||
oauth2Provide: string
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div class="init-wrapper">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1440 500" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 1440 500"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g>
|
||||
<circle stroke="#13C2C2" cx="500" cy="-20" r="6"></circle>
|
||||
<circle fill-opacity="0.4" fill="#9EE6E6" cx="166" cy="76" r="8"></circle>
|
||||
@ -12,18 +20,25 @@
|
||||
<g>
|
||||
<path
|
||||
d="M1182.79367,448.230356 L1186.00213,453.787581 C1186.55442,454.744166 1186.22667,455.967347 1185.27008,456.519632 C1184.96604,456.695168 1184.62116,456.787581 1184.27008,456.787581 L1177.85315,456.787581 C1176.74858,456.787581 1175.85315,455.89215 1175.85315,454.787581 C1175.85315,454.436507 1175.94556,454.091619 1176.1211,453.787581 L1179.32957,448.230356 C1179.88185,447.273771 1181.10503,446.946021 1182.06162,447.498305 C1182.36566,447.673842 1182.61813,447.926318 1182.79367,448.230356 Z"
|
||||
stroke="#CED4D9"></path>
|
||||
stroke="#CED4D9"
|
||||
></path>
|
||||
<path
|
||||
d="M1376.79367,204.230356 L1380.00213,209.787581 C1380.55442,210.744166 1380.22667,211.967347 1379.27008,212.519632 C1378.96604,212.695168 1378.62116,212.787581 1378.27008,212.787581 L1371.85315,212.787581 C1370.74858,212.787581 1369.85315,211.89215 1369.85315,210.787581 C1369.85315,210.436507 1369.94556,210.091619 1370.1211,209.787581 L1373.32957,204.230356 C1373.88185,203.273771 1375.10503,202.946021 1376.06162,203.498305 C1376.36566,203.673842 1376.61813,203.926318 1376.79367,204.230356 Z"
|
||||
stroke="#2F54EB"></path>
|
||||
stroke="#2F54EB"
|
||||
></path>
|
||||
</g>
|
||||
<g>
|
||||
<rect stroke="#13C2C2" stroke-opacity="0.6" x="120" y="322" width="12" height="12" rx="1"></rect>
|
||||
<rect stroke="#CED4D9" x="108" y="1" width="9" height="9" rx="1"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
<a-card v-if="canInstall" class="card-box" :style="`${setpCurrent === 1 ? 'width: 60vw' : 'width: 550px'}`" hoverable
|
||||
:bodyStyle="{ padding: '24px 0', overflow: 'auto' }">
|
||||
<a-card
|
||||
v-if="canInstall"
|
||||
class="card-box"
|
||||
:style="`${setpCurrent === 1 ? 'width: 60vw' : 'width: 550px'}`"
|
||||
hoverable
|
||||
:bodyStyle="{ padding: '24px 0', overflow: 'auto' }"
|
||||
>
|
||||
<template #title>
|
||||
<a-steps :current="setpCurrent">
|
||||
<a-step title="初始化系统" status="process" description="设置一个超级管理员账号">
|
||||
@ -41,20 +56,34 @@
|
||||
|
||||
<a-row type="flex" justify="center">
|
||||
<a-col :span="16" v-if="setpCurrent === 0">
|
||||
<a-card-meta title="初始化系统账户" style="textalign: center" description="您需要创建一个账户用以后续登录管理系统,请牢记超级管理员账号密码" />
|
||||
<a-card-meta
|
||||
title="初始化系统账户"
|
||||
style="textalign: center"
|
||||
description="您需要创建一个账户用以后续登录管理系统,请牢记超级管理员账号密码"
|
||||
/>
|
||||
<br />
|
||||
<a-form :model="loginForm" name="login" :label-col="{ span: 0 }" :wrapper-col="{ span: 24 }"
|
||||
@finish="handleLogin" class="init-form">
|
||||
<a-form
|
||||
:model="loginForm"
|
||||
name="login"
|
||||
:label-col="{ span: 0 }"
|
||||
:wrapper-col="{ span: 24 }"
|
||||
@finish="handleLogin"
|
||||
class="init-form"
|
||||
>
|
||||
<a-form-item class="init-user-name" name="userName" :rules="[{ required: true, message: '请输入账户名' }]">
|
||||
<a-input v-model:value="loginForm.userName" placeholder="账户名称" />
|
||||
</a-form-item>
|
||||
<a-form-item class="init-user-password" name="userPwd" :rules="[
|
||||
{ required: true, message: '请输入密码' },
|
||||
{
|
||||
pattern: /^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,18}$/,
|
||||
message: '密码必须包含数字,字母,字符,且大于6位',
|
||||
},
|
||||
]">
|
||||
<a-form-item
|
||||
class="init-user-password"
|
||||
name="userPwd"
|
||||
:rules="[
|
||||
{ required: true, message: '请输入密码' },
|
||||
{
|
||||
pattern: /^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,18}$/,
|
||||
message: '密码必须包含数字,字母,字符,且大于6位',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-input-password v-model:value="loginForm.userPwd" placeholder="密码(6-18位数字、字母、符号组合)" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
@ -82,8 +111,13 @@
|
||||
</a-col>
|
||||
<a-divider type="vertical" />
|
||||
<a-col :span="20">
|
||||
<a-form :model="mfaForm" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }" @submit="handleMfaSure"
|
||||
class="init-form">
|
||||
<a-form
|
||||
:model="mfaForm"
|
||||
:label-col="{ span: 5 }"
|
||||
:wrapper-col="{ span: 18 }"
|
||||
@finish="handleMfaSure"
|
||||
class="init-form"
|
||||
>
|
||||
<a-form-item label="二维码" style="margin-bottom: 5px">
|
||||
<div class="qrcode">
|
||||
<qrcode-vue :value="qrCode.value" :size="qrCode.size" level="H" />
|
||||
@ -91,18 +125,21 @@
|
||||
</a-form-item>
|
||||
<a-form-item label="MFA key" name="mfa">
|
||||
<a-input-group compact>
|
||||
<a-input v-model:value="mfaForm.mfa" disabled style="width: calc(100% - 32px)">
|
||||
</a-input>
|
||||
<a-button style="padding: 4px 6px;">
|
||||
<a-input v-model:value="mfaForm.mfa" disabled style="width: calc(100% - 32px)"> </a-input>
|
||||
<a-button style="padding: 4px 6px">
|
||||
<a-typography-paragraph :copyable="{ text: mfaForm.mfa }"></a-typography-paragraph>
|
||||
</a-button>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="验证码" name="twoCode" :rules="[
|
||||
{ required: true, message: '请输入两步验证码' },
|
||||
{ pattern: /^\d{6}$/, message: '验证码 6 为纯数字' },
|
||||
]">
|
||||
<a-form-item
|
||||
label="验证码"
|
||||
name="twoCode"
|
||||
:rules="[
|
||||
{ required: true, message: '请输入两步验证码' },
|
||||
{ pattern: /^\d{6}$/, message: '验证码 6 为纯数字' },
|
||||
]"
|
||||
>
|
||||
<a-input v-model:value="mfaForm.twoCode" placeholder="两步验证码" />
|
||||
</a-form-item>
|
||||
|
||||
@ -138,7 +175,7 @@ import sha1 from 'js-sha1'
|
||||
import { checkSystem } from '@/api/install'
|
||||
import { initInstall } from '@/api/install'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { UserOutlined, SolutionOutlined, CopyOutlined } from '@ant-design/icons-vue'
|
||||
import { UserOutlined, SolutionOutlined } from '@ant-design/icons-vue'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import { Modal, notification } from 'ant-design-vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
@ -153,7 +190,7 @@ const loginForm = reactive({
|
||||
})
|
||||
const mfaForm = reactive({
|
||||
twoCode: '',
|
||||
mfa: ''
|
||||
mfa: '',
|
||||
})
|
||||
const setpCurrent = ref(0)
|
||||
|
||||
@ -183,7 +220,7 @@ const handleLogin = (values: any) => {
|
||||
setpCurrent.value = 1
|
||||
qrCode.value = res.data.url
|
||||
userStore.login({ token: tokenData.token, longTermToken: tokenData.longTermToken })
|
||||
router.push({ path: '/' })
|
||||
|
||||
const firstWorkspace = tokenData.bindWorkspaceModels[0]
|
||||
appStore.changeWorkspace(firstWorkspace.id)
|
||||
}
|
||||
@ -212,7 +249,7 @@ const handleIgnoreBindMfa = () => {
|
||||
onOk: () => {
|
||||
router.push({ path: '/' })
|
||||
},
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const goHome = () => {
|
||||
|
@ -2,9 +2,13 @@ import SparkMD5 from 'spark-md5'
|
||||
import { concurrentExecution } from '@/utils/const'
|
||||
import { generateShardingId } from '@/api/common'
|
||||
import Vue from 'vue'
|
||||
import { GlobalWindow } from '@/interface/common'
|
||||
|
||||
const uploadFileSliceSize = window.uploadFileSliceSize === '<uploadFileSliceSize>' ? 1 : window.uploadFileSliceSize
|
||||
const uploadFileConcurrent = window.uploadFileConcurrent === '<uploadFileConcurrent>' ? 1 : window.uploadFileConcurrent
|
||||
const _window = window as unknown as GlobalWindow
|
||||
|
||||
const uploadFileSliceSize = _window.uploadFileSliceSize === '<uploadFileSliceSize>' ? 1 : _window.uploadFileSliceSize
|
||||
const uploadFileConcurrent =
|
||||
_window.uploadFileConcurrent === '<uploadFileConcurrent>' ? 1 : _window.uploadFileConcurrent
|
||||
|
||||
/**
|
||||
* 文件分片上传
|
||||
|
@ -1,7 +1,8 @@
|
||||
export function getHashQuery() {
|
||||
const querys: Record<string, any> = {}
|
||||
location.hash.replace(/[?&]+([^=&]+)=([^&]*)/gi, (_m: string, key: string, value: any) => {
|
||||
const querys: Record<string, string> = {}
|
||||
location.hash.replace(/[?&]+([^=&]+)=([^&]*)/gi, (_match: string, key: string, value: string) => {
|
||||
querys[key] = value
|
||||
return ''
|
||||
})
|
||||
return querys
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import path from 'node:path'
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import { createHtmlPlugin } from 'vite-plugin-html'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ mode }) => {
|
||||
@ -84,6 +85,21 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [vue(), vueJsx()],
|
||||
plugins: [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
createHtmlPlugin({
|
||||
minify: true,
|
||||
inject: {
|
||||
data: {
|
||||
title: env.JPOM_APP_TITLE,
|
||||
base_url: env.JPOM_BASE_URL,
|
||||
build: new Date().getTime(),
|
||||
env: process.env.NODE_ENV,
|
||||
buildVersion: process.env.npm_package_version,
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user