You need to sign in or sign up before continuing.
Commit 3b0a4c85 authored by 张宇迪's avatar 张宇迪

init

parents
clone:
git:
image: registry.cn-qingdao.aliyuncs.com/wod/devops-git-arm64:1.0
pipeline:
read-cache:
image: registry.cn-qingdao.aliyuncs.com/wod/devops-cache-arm64:1.0
restore: true
mount:
- ./node_modules
volumes:
- /cache:/cache
build:
image: registry.cn-qingdao.aliyuncs.com/wod/devops-node-arm64:12.18.2-buster
volumes:
- /data/cache/yarn:/usr/local/share/.cache/yarn/v1
commands:
- yarn install
- yarn run build
store-cache:
image: registry.cn-qingdao.aliyuncs.com/wod/devops-cache-arm64:1.0
rebuild: true
mount:
- ./node_modules
volumes:
- /cache:/cache
docker-branch:
image: registry.cn-qingdao.aliyuncs.com/wod/devops-docker-arm64:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry.cn-qingdao.aliyuncs.com/wod/apaas-login-base-arm64:v3.0.0-apaasv3
repo: wod/apaas-login-arm64
registry: registry.cn-qingdao.aliyuncs.com
version: "v3.0.1"
channel: branch
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
when:
branch:
exclude: [master,dev]
latest:
image: registry.cn-qingdao.aliyuncs.com/wod/devops-docker-arm64:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry.cn-qingdao.aliyuncs.com/wod/apaas-login-base-arm64:v3.0.0-apaasv3
repo: wod/apaas-login-arm64
registry: registry.cn-qingdao.aliyuncs.com
version: "v3.0"
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
\ No newline at end of file
platform: 10.11.92.33
clone:
git:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/git:1.4.0
pull: true
dns: 223.5.5.5
pipeline:
read-cache:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/cache:latest
restore: true
mount:
- ./node_modules
volumes:
- /cache:/cache
build:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/node:8.15.0-onbuild
dns: 223.5.5.5
volumes:
- /data/cache/yarn:/usr/local/share/.cache/yarn/v1
commands:
- yarn install
- yarn run build
store-cache:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/cache:latest
rebuild: true
mount:
- ./node_modules
volumes:
- /cache:/cache
docker:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/docker:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry.cn-qingdao.aliyuncs.com/wod/apaas-login-base:v3.0.2-apaasv3
repo: wod/apaas-login
version: "v3.0.0"
channel: alpha
registry: registry.cn-qingdao.aliyuncs.com
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
when:
branch: dev
docker-master:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/docker:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry.cn-qingdao.aliyuncs.com/wod/apaas-login-base:v3.0.2-apaasv3
repo: wod/apaas-login
version: "v3.0.0"
registry: registry.cn-qingdao.aliyuncs.com
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
when:
branch: master
docker-branch:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/docker:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry.cn-qingdao.aliyuncs.com/wod/apaas-login-base:v3.0.2-apaasv3
repo: wod/apaas-login
registry: registry.cn-qingdao.aliyuncs.com
version: "v3.0.0"
channel: branch
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
when:
branch:
exclude: [master,dev]
latest:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/docker:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry.cn-qingdao.aliyuncs.com/wod/apaas-login-base:v3.0.2-apaasv3
repo: wod/apaas-login
registry: registry.cn-qingdao.aliyuncs.com
version: "v3.0"
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
when:
branch:
exclude: [master,dev]
deploy:
image: registry.cn-qingdao.aliyuncs.com/wod-devops/kubernetes:1.0
namespace: apaas-v3
deployment: apaas-login
container: apaas-login
registry: registry.cn-qingdao.aliyuncs.com
\ No newline at end of file
node_modules/
\ No newline at end of file
.DS_Store
node_modules/
dist
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
\ No newline at end of file
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}
module.exports = {
presets: [
["@babel/preset-env", {
"modules": false
}]
],
plugins: ["transform-vue-jsx", "@babel/plugin-transform-runtime"]
}
FROM {{ BASEIMAGE }}
MAINTAINER {{ AUTHOR }}
LABEL Author={{ AUTHOR }} Name={{ PROJECT }} Version={{ VERSION }}
ADD ./dist /www
\ No newline at end of file
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec(cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('yarn')) {
versionRequirements.push({
name: 'yarn',
currentVersion: exec('yarn --version'),
versionRequirement: packageConfig.engines.yarn
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
index: /awecloud/ui/
login: /awecloud/dex/login
logout: /awecloud/dex/logout
\ No newline at end of file
FROM {{ BASEIMAGE }}
MAINTAINER {{ AUTHOR }}
LABEL Author={{ AUTHOR }} Name={{ PROJECT }} Version={{ VERSION }}
ADD ./dist /www
\ No newline at end of file
'use strict'
const path = require('path')
const config = require('../config')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = []
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
loaders.push(MiniCssExtractPlugin.loader)
}
else {
loaders.push('vue-style-loader')
}
loaders.push(cssLoader)
if (options.usePostCSS) {
loaders.push(postcssLoader)
}
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
return loaders
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const config = require('../config')
module.exports = {
cacheBusting: config.dev.cacheBusting,
transformAssetUrls: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const { VueLoaderPlugin } = require('vue-loader')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
plugins: [
new VueLoaderPlugin(),
],
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
mode: 'development',
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
favicon: './static/favicon.ico'
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
],
optimization: {
noEmitOnErrors: true,
},
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin');
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
mode: 'production',
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
// extract css into its own file
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[chunkhash].css'),
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.NamedChunksPlugin(),
new webpack.HashedModuleIdsPlugin(),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
],
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/]/,
enforce: true,
},
},
},
runtimeChunk: 'single',
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: 6,
compress: true,
output: {
comments: false,
beautify: false
}
}
}),
],
},
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist', 'iam','login', 'index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist', 'iam','login'),
assetsSubDirectory: 'static',
assetsPublicPath: '/iam/login/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
'use strict'
module.exports = {
NODE_ENV: '"production"'
}
<?xml version="1.0" encoding="utf-8"?>
<AutoResponder LastSave="2018-04-21T17:18:19.4349974+08:00" FiddlerVersion="5.0.20173.50948">
<State Enabled="true" Fallthrough="true" UseLatency="false">
<ResponseRule Match="EXACT:http://localhost:8080/rest/harbor/api/projects" Action="C:\Git\cloud\awecloud-ui\docs\harbor_api_projects.json" Enabled="true" />
<ResponseRule Match="EXACT:http://localhost:8080/rest/harbor/api/projects/3" Action="C:\Git\cloud\awecloud-ui\docs\harbor_api_projects_3.json" Enabled="true" />
<ResponseRule Match="regex:http://localhost:8080/rest/harbor/api/repositories/(.*?)/tags" Action="C:\Git\cloud\awecloud-ui\docs\harbor_api_repositories_cig_rest_tags.json" Enabled="true" />
<ResponseRule Match="regex:http://localhost:8080/rest/harbor/api/repositories(.*?)" Action="C:\Git\cloud\awecloud-ui\docs\harbor_api_repositories.json" Enabled="true" />
<ResponseRule Match="regex:http://localhost:8080/rest/kubernetes/api/v1/node(.*?)" Action="C:\Git\cloud\awecloud-ui\docs\k8s_api_v1_node.json" Enabled="true" />
<ResponseRule Match="EXACT:http://localhost:8080/rest/kubernetes/api/v1/node" Action="C:\Git\cloud\awecloud-ui\docs\k8s_api_v1_node.json" Enabled="true" />
<ResponseRule Match="EXACT:http://localhost:8080/rest/kubernetes/api/v1/node/172.16.11.241" Action="C:\Git\cloud\awecloud-ui\docs\k8s_api_v1_node_192.168.74.101.json" Enabled="true" />
<ResponseRule Match="EXACT:http://localhost:8080/api/v4/user" Action="C:\Git\cloud\awecloud-ui\docs\gitlab_api_v4_user.json" Enabled="true" />
</State>
</AutoResponder>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<AutoResponder LastSave="2018-04-20T23:41:40.6792103+08:00" FiddlerVersion="5.0.20173.49666">
<State Enabled="true" Fallthrough="true" UseLatency="false">
<ResponseRule Match="regex:https://gitlab.ispacesys.cn/awecloud/ui(.*?)" Action="http://localhost:8080$1" Enabled="true" />
<ResponseRule Match="regex:https://gitlab.ispacesys.cn/static(.*?)" Action="http://localhost:8080/static$1" Enabled="true" />
<ResponseRule Match="EXACT:https://gitlab.ispacesys.cn/app.js" Action="http://localhost:8080/app.js" Enabled="true" />
</State>
</AutoResponder>
\ No newline at end of file
This diff is collapsed.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>单点登录</title>
<link rel="shortcut icon" type="image/x-icon" href="static/favicon.ico" />
</head>
<body>
<style>
html {
overflow-y: auto;
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 0;
}
</style>
<div id="app"></div>
</body>
</html>
{
"name": "apaas-login",
"version": "1.0.0",
"description": "A Vuetify.js Project Manage Kubernetes",
"author": "shucheng <shucheng@bd-apaas.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.8.0",
"axios": "^0.19.2",
"babel-polyfill": "^6.26.0",
"codemirror": "^5.45.0",
"element-ui": "^2.11.1",
"material-design-icons-iconfont": "^4.0.5",
"qs": "^6.9.4",
"string-format": "^2.0.0",
"vue": "^2.6.10",
"vue-router": "^3.0.2",
"vuex": "^3.1.0"
},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/plugin-syntax-jsx": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"@babel/runtime": "^7.4.2",
"autoprefixer": "^9.5.0",
"babel-loader": "^8.0.5",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.5.0",
"node-notifier": "^5.4.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"ora": "^3.2.0",
"portfinder": "^1.0.20",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"postcss-url": "^8.0.0",
"rimraf": "^2.6.3",
"semver": "^5.6.0",
"shelljs": "^0.8.3",
"terser-webpack-plugin": "^1.2.3",
"url-loader": "^1.1.2",
"vue-loader": "^15.7.0",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.29.6",
"webpack-bundle-analyzer": "^3.1.0",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.2.1",
"webpack-merge": "^4.2.1"
},
"engines": {
"node": ">= 8.12.0",
"npm": ">= 6.4.1",
"yarn": ">= 1.12.3"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
# awecloud
> A Vue.js project
## Build Setup
``` bash
# install dependencies
yarn install
# serve with hot reload at localhost:8080
yarn run dev
# build for production with minification
yarn run build
```
# 使用
## 修改config/index.js
```javascript
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist', 'awecloud', 'ui', 'index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist', 'awecloud', 'ui'),
assetsSubDirectory: 'static',
assetsPublicPath: '/awecloud/ui/',
}
```
## 修改build/dockerfile
```
ADD ./dist /www
ADD ./build/conf.yaml /etc/awecloud/conf.yaml
```
## 修改.drone.yml
```
```
## googlefonts本地化
```bash
# index.html
- <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">
# src/assets/css
add googlefonts.css googlefonts
# src/main.js
+ import "@src/assets/css/googlefonts.css";
```
## add IE11 support
```bash
# src/main.js
+ import "babel-polyfill";
# package.json
yarn add babel-polyfill
```
## remove overflow-y
```bash
# index.html
+ <style>
+ html {
+ overflow-y: auto
+ }
+ </style>
```
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/vuetifyjs/templates-common.git
branch = subrepo/webpack-src
commit = 090741fa8ba4da0c6f85db64eff64550704123e1
parent = e05204fc0583a8c99f1963ce873eba1266838215
method = merge
cmdver = 0.4.0
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
data: () => ({}),
methods: {},
created() {},
};
</script>
<style scoped>
#app {
background-color: #f6f7fb;
font-size: 14px;
}
</style>
\ No newline at end of file
<template>
<div class="s-canvas">
<canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
</div>
</template>
<script>
export default {
name: "SIdentify",
props: {
identifyCode: {
type: String,
default: "1234"
},
fontSizeMin: {
type: Number,
default: 25
},
fontSizeMax: {
type: Number,
default: 30
},
backgroundColorMin: {
type: Number,
default: 255
},
backgroundColorMax: {
type: Number,
default: 255
},
colorMin: {
type: Number,
default: 0
},
colorMax: {
type: Number,
default: 160
},
lineColorMin: {
type: Number,
default: 100
},
lineColorMax: {
type: Number,
default: 255
},
dotColorMin: {
type: Number,
default: 0
},
dotColorMax: {
type: Number,
default: 255
},
contentWidth: {
type: Number,
default: 150
},
contentHeight: {
type: Number,
default: 38
}
},
methods: {
// 生成一个随机数
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min);
},
// 生成一个随机的颜色
randomColor(min, max) {
let r = this.randomNum(min, max);
let g = this.randomNum(min, max);
let b = this.randomNum(min, max);
return "rgb(" + r + "," + g + "," + b + ")";
},
drawPic() {
let canvas = document.getElementById("s-canvas");
let ctx = canvas.getContext("2d");
ctx.textBaseline = "bottom";
// 绘制背景
ctx.fillStyle = this.randomColor(
this.backgroundColorMin,
this.backgroundColorMax
);
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight);
// 绘制文字
for (let i = 0; i < this.identifyCode.length; i++) {
this.drawText(ctx, this.identifyCode[i], i);
}
this.drawLine(ctx);
this.drawDot(ctx);
},
drawText(ctx, txt, i) {
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax);
ctx.font =
this.randomNum(this.fontSizeMin, this.fontSizeMax) + "px SimHei";
let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1));
let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5);
var deg = this.randomNum(-45, 45);
// 修改坐标原点和旋转角度
ctx.translate(x, y);
ctx.rotate((deg * Math.PI) / 180);
ctx.fillText(txt, 0, 0);
// 恢复坐标原点和旋转角度
ctx.rotate((-deg * Math.PI) / 180);
ctx.translate(-x, -y);
},
drawLine(ctx) {
// 绘制干扰线
for (let i = 0; i < 5; i++) {
ctx.strokeStyle = this.randomColor(
this.lineColorMin,
this.lineColorMax
);
ctx.beginPath();
ctx.moveTo(
this.randomNum(0, this.contentWidth),
this.randomNum(0, this.contentHeight)
);
ctx.lineTo(
this.randomNum(0, this.contentWidth),
this.randomNum(0, this.contentHeight)
);
ctx.stroke();
}
},
drawDot(ctx) {
// 绘制干扰点
for (let i = 0; i < 80; i++) {
ctx.fillStyle = this.randomColor(0, 255);
ctx.beginPath();
ctx.arc(
this.randomNum(0, this.contentWidth),
this.randomNum(0, this.contentHeight),
1,
0,
2 * Math.PI
);
ctx.fill();
}
}
},
watch: {
identifyCode() {
this.drawPic();
}
},
mounted() {
this.drawPic();
}
};
</script>
<style scoped>
.s-canvas {
height: 38px;
}
</style>
\ No newline at end of file
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import '@fortawesome/fontawesome-free/css/all.css'
import 'material-design-icons-iconfont/dist/material-design-icons.css'
import "babel-polyfill";
import Vue from 'vue'
import Vuex from 'vuex';
Vue.use(Vuex);
import store from '@/store';
store.install(Vuex);
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
import api from './request/api'
Vue.prototype.$api = api;
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
This diff is collapsed.
import general from '@/request/api/general';
export default {
general
}
\ No newline at end of file
import axios from '@/request/http'; // 导入http中创建的axios实例
import qs from 'qs'; // 根据需求是否导入qs模块
const general = {
login(params) {
return axios.post(`/iam/api/login`, params);
},
validateUser(params) {
return axios.get(`/apaas/backmgt/user/checkUserId?user_id=${params.value}`);
},
register(params) {
return axios.post(`/apaas/backmgt/user/register`, params);
},
getOrganizations() {
return axios.get(`/apaas/backmgt/department/list`);
},
// user info
getNowUser() {
return axios.get(`/apaas/backmgt/user/getCurrentUser`);
},
}
export default general;
/**
* axios封装
* 请求拦截、响应拦截、错误统一处理
*/
import axios from 'axios';
import router from '../router';
import store from '../store/index';
import ElementUI from 'element-ui';
const tip = msg => {
console.log(msg);
ElementUI.Message.error(msg);
}
/**
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
*/
const toLogin = () => {
window.location.href = "/login?redirect=" + router.currentRoute.fullPath
}
/**
* 请求失败后的错误统一处理
* @param {Number} status 请求失败的状态码
*/
const errorHandle = (status, other) => {
// 状态码判断
switch (status) {
case 400: tip('请求错误(400)'); break;
// 401: 未登录状态,跳转登录页
case 401:
toLogin();
break;
// 403 token过期
// 清除token并跳转登录页
case 403:
tip('登录过期,请重新登录');
localStorage.removeItem('token');
store.commit('loginSuccess', null);
setTimeout(() => {
toLogin();
}, 1000);
break;
case 404: tip('请求的资源不存在'); break;
case 408: tip('请求超时(408)'); break;
case 500: tip('服务器错误(500)'); break;
case 501: tip('服务未实现(501)'); break;
case 502: tip('网络错误(502)'); break;
case 503: tip('服务不可用(503)'); break;
case 504: tip('网络超时(504)'); break;
case 505: tip('HTTP版本不受支持(505)'); break;
default: tip(`连接出错,${other}`);
}
}
// 创建axios实例
var instance = axios.create({ timeout: 1000 * 12 });
// 设置post请求头
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
instance.interceptors.request.use(
config => {
// const token = store.state.token;
// token && (config.headers.Authorization = token);
return config;
},
error => Promise.error(error))
// 响应拦截器
instance.interceptors.response.use(
// 请求成功
res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),
// 请求失败
error => {
const { response } = error;
if (response) {
// 请求已发出,但是不在2xx的范围
errorHandle(response.status, response.data.errmessage);
return Promise.reject(response);
}
});
export default instance;
import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/pages/login'
Vue.use(Router)
export default new Router({
routes: [
{
path: "/",
redirect: "/login",
},
{
path: '/login',
name: 'Login',
component: Login
},
]
})
// 取得cookie
function getCookie(name) {
var nameEQ = name + '='
var ca = document.cookie.split(';') // 把cookie分割成组
for (var i = 0; i < ca.length; i++) {
var c = ca[i] // 取得字符串
while (c.charAt(0) == ' ') { // 判断一下字符串有没有前导空格
c = c.substring(1, c.length) // 有的话,从第二位开始取
}
if (c.indexOf(nameEQ) == 0) { // 如果含有我们要的name
return unescape(c.substring(nameEQ.length, c.length)) // 解码并截取我们要值
}
}
return false
}
// 清除cookie
function clearCookie(name) {
setCookie(name, "", -1);
}
// 设置cookie
function setCookie(name, value, seconds) {
seconds = seconds || 0; //seconds有值就直接赋值,没有为0,这个根php不一样。
var expires = "";
if (seconds != 0 ) { //设置cookie生存时间
var date = new Date();
date.setTime(date.getTime()+(seconds*1000));
expires = "; expires="+date.toGMTString();
}
document.cookie = name+"="+escape(value)+expires+"; path=/"; //转码并赋值
}
export {
getCookie,
clearCookie,
setCookie,
}
module.exports = {
"harbor": "/awecloud/rest/harbor/api",
};
\ No newline at end of file
var store = {
install: function (Vuex) {
store.namespace = new Vuex.Store({
state: {
name: "",
},
mutations: {
change(state, name) {
state.name = name;
sessionStorage.setItem("name", name);
}
}
})
}
}
module.exports = store;
(function (window, document) {
var eventUrl = "/awecloud/api/events/token/subscribe";
var pingUrl = "/awecloud/api/events/token/publish?state=ping";
var evtSource = new EventSource(eventUrl);
evtSource.addEventListener("message", function (e) {
console.log("message:", e);
if (e.data == "timeout") {
location.href = "/awecloud/dex/logout?ReturnUrl=" + encodeURIComponent(location.href);
} else if (e.data == "new_login") {
location.href = "/awecloud/dex/logout?ReturnUrl=" + encodeURIComponent(location.href);
}
});
var pingFn = function () {
var req = new XMLHttpRequest();
req.open("GET", pingUrl);
req.send();
};
var nowFn = function () {
return new Date().getTime();
};
var lastActTime = nowFn();
var interval = 10000;
var pingTimerFn = function () {
if (nowFn() - lastActTime < interval) {
pingFn();
}
setTimeout(pingTimerFn, interval);
};
pingTimerFn();
var listenMouseover = function () {
document.body.addEventListener("mouseover", function (e) {
lastActTime = nowFn();
});
};
if (document.body) {
listenMouseover();
} else {
window.addEventListener("load", listenMouseover);
}
})(window, document);
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment