feat:工作台初始化项目。
12
.babelrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
||||
}
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-vue-jsx", "transform-runtime", "syntax-dynamic-import"]
|
||||
}
|
||||
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
12
.idea/intc-workbenches.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/intc-workbenches.iml" filepath="$PROJECT_DIR$/.idea/intc-workbenches.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
7
.postcssrc.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
"plugins": {
|
||||
"postcss-import": {},
|
||||
"postcss-url": {},
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
||||
41
build/build.js
Normal file
@@ -0,0 +1,41 @@
|
||||
'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'
|
||||
))
|
||||
})
|
||||
})
|
||||
54
build/check-versions.js
Normal file
@@ -0,0 +1,54 @@
|
||||
'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('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
BIN
build/logo.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
101
build/utils.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const config = require('../config')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-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 = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(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')
|
||||
})
|
||||
}
|
||||
}
|
||||
22
build/vue-loader.conf.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const sourceMapEnabled = isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: sourceMapEnabled,
|
||||
extract: isProduction
|
||||
}),
|
||||
cssSourceMap: sourceMapEnabled,
|
||||
cacheBusting: config.dev.cacheBusting,
|
||||
transformToRequire: {
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
||||
82
build/webpack.base.conf.js
Normal file
@@ -0,0 +1,82 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const vueLoaderConfig = require('./vue-loader.conf')
|
||||
|
||||
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
|
||||
},
|
||||
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'
|
||||
}
|
||||
}
|
||||
95
build/webpack.dev.conf.js
Normal file
@@ -0,0 +1,95 @@
|
||||
'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, {
|
||||
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
|
||||
}),
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.dev.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
})
|
||||
145
build/webpack.prod.conf.js
Normal file
@@ -0,0 +1,145 @@
|
||||
'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 ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
const env = require('../config/prod.env')
|
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, {
|
||||
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'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
},
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
||||
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
|
||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
||||
allChunks: true,
|
||||
}),
|
||||
// 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 via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// keep module.id stable when vendor modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// This instance extracts shared chunks from code splitted chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
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
|
||||
7
config/dev.env.js
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict'
|
||||
const merge = require('webpack-merge')
|
||||
const prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
||||
69
config/index.js
Normal file
@@ -0,0 +1,69 @@
|
||||
'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-
|
||||
|
||||
|
||||
/**
|
||||
* 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/index.html'),
|
||||
|
||||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
||||
4
config/prod.env.js
Normal file
@@ -0,0 +1,4 @@
|
||||
'use strict'
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
||||
8
docker/buildWebsite.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
docker rm -f intcwebsite
|
||||
docker rmi intcwebsite:1.0.0
|
||||
|
||||
cd /mnt/data/intc/intcwebsite
|
||||
docker build -t intcwebsite:1.0.0 .
|
||||
docker run --restart=always -di --name intcwebsite -p 80:80 intcwebsite:1.0.0
|
||||
51
docker/intcwebsite/conf/nginx.conf
Normal file
@@ -0,0 +1,51 @@
|
||||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
client_max_body_size 20m;
|
||||
server_tokens off;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
add_header Referrer-Policy "no-referrer";
|
||||
|
||||
location /stub_status {
|
||||
stub_status on;
|
||||
access_log off;
|
||||
allow 192.168.0.177;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /home/intc/projects/intc-ui/;
|
||||
try_files $uri $uri/ /index.html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
location /fileUrl/ {
|
||||
rewrite ^/fileUrl/(.*) /$1 break;
|
||||
proxy_pass http://101.126.95.100:9000;
|
||||
}
|
||||
location /prod-api/{
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header REMOTE-HOST $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_redirect off;
|
||||
proxy_pass http://154.8.147.51:8288/;
|
||||
}
|
||||
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
docker/intcwebsite/dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
# 基础镜像
|
||||
FROM nginx:1.26.2
|
||||
# author
|
||||
MAINTAINER intc
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/intc/projects/intc-ui
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/intc/projects/intc-ui
|
||||
# 指定路径
|
||||
WORKDIR /home/intc/projects/intc-ui
|
||||
# 复制conf文件到路径
|
||||
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
|
||||
# 复制html文件到路径
|
||||
COPY ./html/dist /home/intc/projects/intc-ui
|
||||
0
docker/intcwebsite/html/dist/readme.txt
vendored
Normal file
BIN
favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
21
index.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-Hans-CN">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="Keywords" content="记账平台,健康档案,茅台预约"/>
|
||||
<meta name="Description"
|
||||
content="智聪网络科技"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
|
||||
<meta name="format-detection" content="telephone=no,email=no"/>
|
||||
<meta http-equiv="x-dns-prefetch-control" content="on"/>
|
||||
<link rel="icon" href="/static/favicon.ico" />
|
||||
<link rel="dns-prefetch" href="http://www.qdintc.com"/>
|
||||
<title>智聪网络科技</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
28686
package-lock.json
generated
Normal file
68
package.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "com_web",
|
||||
"version": "1.0.0",
|
||||
"description": "A Vue.js project",
|
||||
"author": "kaka212000@163.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": {
|
||||
"jsonp": "^0.2.1",
|
||||
"vue": "^2.7.15",
|
||||
"vue-carousel": "^0.18.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-template-compiler": "^2.7.15",
|
||||
"vuex": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.0",
|
||||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"file-loader": "^1.1.4",
|
||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||
"html-webpack-plugin": "^2.30.1",
|
||||
"less": "^3.9.0",
|
||||
"less-loader": "^5.0.0",
|
||||
"node-notifier": "^5.1.2",
|
||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
||||
"ora": "^1.2.0",
|
||||
"portfinder": "^1.0.13",
|
||||
"postcss-import": "^11.0.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"postcss-url": "^7.2.1",
|
||||
"rimraf": "^2.6.0",
|
||||
"semver": "^5.3.0",
|
||||
"shelljs": "^0.7.6",
|
||||
"uglifyjs-webpack-plugin": "^1.1.1",
|
||||
"url-loader": "^0.5.8",
|
||||
"vue-loader": "^13.3.0",
|
||||
"vue-style-loader": "^3.0.1",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-bundle-analyzer": "^2.9.0",
|
||||
"webpack-dev-server": "^2.9.1",
|
||||
"webpack-merge": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
||||
23
src/Util.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 常用函数工具类
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const userAgent = navigator.userAgent
|
||||
export default class Util {
|
||||
static os = {
|
||||
trident: userAgent.indexOf('Trident') > -1, // IE内核
|
||||
presto: userAgent.indexOf('Presto') > -1, // opera内核
|
||||
webKit: userAgent.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
|
||||
gecko: userAgent.indexOf('Gecko') > -1 && userAgent.indexOf('KHTML') === -1, // 火狐内核
|
||||
ios: !!userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
|
||||
android: userAgent.indexOf('Android') > -1 || userAgent.indexOf('Linux') > -1, // android终端或者uc浏览器
|
||||
iPhone: userAgent.indexOf('iPhone') > -1, // 是否为iPhone
|
||||
mobile: !!userAgent.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
|
||||
iPad: userAgent.indexOf('iPad') > -1, // 是否iPad
|
||||
webApp: userAgent.indexOf('Safari') === -1, // 是否web应该程序,没有头部与底部
|
||||
wechat: userAgent.indexOf('MicroMessenger') > -1, // 是否微信浏览器
|
||||
isapp: window.innerWidth < 768, // 是否微信浏览器
|
||||
harmonyOS: userAgent.indexOf('HarmonyOS') > -1,
|
||||
}
|
||||
}
|
||||
19
src/assets/css/common.css
Normal file
@@ -0,0 +1,19 @@
|
||||
/* 全局样式 */
|
||||
.m-0-auto {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.m-0 {
|
||||
margin: 0;
|
||||
}
|
||||
.m-r-5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.m-t-5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.p-0 {
|
||||
padding: 0;
|
||||
}
|
||||
.w-100pct {
|
||||
width: 100%;
|
||||
}
|
||||
1
src/assets/css/vivify.min.css
vendored
Normal file
BIN
src/assets/img/feature1.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
20
src/assets/img/feature1.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||
<defs>
|
||||
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#4CAF50;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#45a049;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle cx="48" cy="48" r="44" fill="url(#grad1)" opacity="0.1"/>
|
||||
<circle cx="48" cy="48" r="40" fill="none" stroke="url(#grad1)" stroke-width="3"/>
|
||||
|
||||
<!-- 钱包图标 -->
|
||||
<path d="M 28 35 L 68 35 C 70.2 35 72 36.8 72 39 L 72 61 C 72 63.2 70.2 65 68 65 L 28 65 C 25.8 65 24 63.2 24 61 L 24 39 C 24 36.8 25.8 35 28 35 Z" fill="url(#grad1)" opacity="0.8"/>
|
||||
|
||||
<!-- 钱币符号 ¥ -->
|
||||
<text x="48" y="56" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#ffffff" text-anchor="middle">¥</text>
|
||||
|
||||
<!-- 账本线条 -->
|
||||
<line x1="32" y1="42" x2="44" y2="42" stroke="#ffffff" stroke-width="2" opacity="0.6"/>
|
||||
<line x1="32" y1="48" x2="40" y2="48" stroke="#ffffff" stroke-width="2" opacity="0.6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/img/feature2.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
20
src/assets/img/feature2.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||
<defs>
|
||||
<linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#E91E63;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#C2185B;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle cx="48" cy="48" r="44" fill="url(#grad2)" opacity="0.1"/>
|
||||
<circle cx="48" cy="48" r="40" fill="none" stroke="url(#grad2)" stroke-width="3"/>
|
||||
|
||||
<!-- 心电图/健康图标 -->
|
||||
<path d="M 28 50 L 35 50 L 38 42 L 42 58 L 46 38 L 50 50 L 68 50" fill="none" stroke="url(#grad2)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<!-- 心形 -->
|
||||
<path d="M 48 62 C 48 62 38 54 38 46 C 38 42 40 40 43 40 C 45 40 47 41 48 43 C 49 41 51 40 53 40 C 56 40 58 42 58 46 C 58 54 48 62 48 62 Z" fill="url(#grad2)" opacity="0.8"/>
|
||||
|
||||
<!-- 十字符号 -->
|
||||
<rect x="45" y="26" width="6" height="10" rx="1" fill="url(#grad2)"/>
|
||||
<rect x="42" y="29" width="12" height="4" rx="1" fill="url(#grad2)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/img/feature3.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
27
src/assets/img/feature3.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||
<defs>
|
||||
<linearGradient id="grad3" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#FF9800;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#F57C00;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle cx="48" cy="48" r="44" fill="url(#grad3)" opacity="0.1"/>
|
||||
<circle cx="48" cy="48" r="40" fill="none" stroke="url(#grad3)" stroke-width="3"/>
|
||||
|
||||
<!-- 酒瓶轮廓 -->
|
||||
<path d="M 42 28 L 54 28 L 54 32 L 52 32 L 52 36 C 56 38 58 42 58 48 L 58 64 C 58 66 56 68 54 68 L 42 68 C 40 68 38 66 38 64 L 38 48 C 38 42 40 38 44 36 L 44 32 L 42 32 Z" fill="url(#grad3)" opacity="0.8"/>
|
||||
|
||||
<!-- 瓶盖 -->
|
||||
<rect x="44" y="24" width="8" height="4" rx="1" fill="url(#grad3)"/>
|
||||
|
||||
<!-- 酒标签 -->
|
||||
<ellipse cx="48" cy="52" rx="8" ry="10" fill="#ffffff" opacity="0.3"/>
|
||||
|
||||
<!-- 日历/预约符号 -->
|
||||
<rect x="60" y="26" width="10" height="12" rx="1" fill="url(#grad3)" opacity="0.9"/>
|
||||
<line x1="62" y1="28" x2="68" y2="28" stroke="#ffffff" stroke-width="1.5"/>
|
||||
<circle cx="63" cy="32" r="1" fill="#ffffff"/>
|
||||
<circle cx="67" cy="32" r="1" fill="#ffffff"/>
|
||||
<circle cx="63" cy="35" r="1" fill="#ffffff"/>
|
||||
<circle cx="67" cy="35" r="1" fill="#ffffff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/img/feature4.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
20
src/assets/img/feature4.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||
<defs>
|
||||
<linearGradient id="grad4" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#2196F3;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#1976D2;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle cx="48" cy="48" r="44" fill="url(#grad4)" opacity="0.1"/>
|
||||
<circle cx="48" cy="48" r="40" fill="none" stroke="url(#grad4)" stroke-width="3"/>
|
||||
|
||||
<!-- 客服耳机图标 -->
|
||||
<path d="M 48 32 C 38 32 30 40 30 50 L 30 58 C 30 60 32 62 34 62 L 38 62 C 40 62 42 60 42 58 L 42 52 C 42 50 40 48 38 48 L 34 48 L 34 50 C 34 42 40 36 48 36 C 56 36 62 42 62 50 L 62 48 L 58 48 C 56 48 54 50 54 52 L 54 58 C 54 60 56 62 58 62 L 62 62 C 64 60 66 58 66 58 L 66 50 C 66 40 58 32 48 32 Z" fill="url(#grad4)" opacity="0.8"/>
|
||||
|
||||
<!-- 麦克风 -->
|
||||
<rect x="45" y="62" width="6" height="8" rx="3" fill="url(#grad4)"/>
|
||||
<line x1="42" y1="70" x2="54" y2="70" stroke="url(#grad4)" stroke-width="2" stroke-linecap="round"/>
|
||||
|
||||
<!-- 服务星标 -->
|
||||
<path d="M 48 24 L 50 29 L 55 29 L 51 32 L 53 37 L 48 34 L 43 37 L 45 32 L 41 29 L 46 29 Z" fill="url(#grad4)" opacity="0.6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/img/health.png
Normal file
|
After Width: | Height: | Size: 315 KiB |
BIN
src/assets/img/healthQrcode.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/img/imaotai.png
Normal file
|
After Width: | Height: | Size: 317 KiB |
BIN
src/assets/img/imaotaiQrcode.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/img/invest.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
src/assets/img/investQrcode.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/img/qrcode.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
src/assets/img/qrcode.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
475
src/assets/less/normalize.less
vendored
Normal file
@@ -0,0 +1,475 @@
|
||||
// =============================================================================
|
||||
// Normalize.less based on Nicolas Gallagher and Jonathan Neal's
|
||||
// normalize.css v3.0.1 | MIT License | github.com/necolas/normalize.css
|
||||
// =============================================================================
|
||||
|
||||
//
|
||||
// Variables
|
||||
// ====================================================================
|
||||
|
||||
// Base font-family
|
||||
@base-font-family: sans-serif;
|
||||
|
||||
// The base font size
|
||||
@base-font-size: 16px;
|
||||
|
||||
// The base line height determines the basic unit of vertical rhythm.
|
||||
@base-line-height: 24px;
|
||||
|
||||
// Heading sizes
|
||||
@h1-size: 36px;
|
||||
|
||||
|
||||
//
|
||||
// Mixins
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Passing in a single value will create font-sizing in
|
||||
// pixels, rems as well as a proper line-height.
|
||||
//
|
||||
// `.font-size(24px, false);`
|
||||
//
|
||||
|
||||
.font-size(@font-size, @line-height: true) {
|
||||
@px-value: (@font-size);
|
||||
@rem-value: (@font-size / @base-font-size) * 1rem;
|
||||
@line-height-value: ceil(@font-size / @base-line-height) * (@base-line-height / @font-size);
|
||||
|
||||
font-size: ~"@{px-value}";
|
||||
font-size: @rem-value;
|
||||
|
||||
.line-height(@boolean) when (@boolean = true) {
|
||||
line-height: unit(@line-height-value);
|
||||
}
|
||||
|
||||
.line-height(@line-height);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 1. Set default font family to sans-serif.
|
||||
// 2. Prevent iOS and IE text size adjust after device orientation change,
|
||||
// without disabling user zoom.
|
||||
//
|
||||
|
||||
html {
|
||||
font-size: 100%; // 1 //
|
||||
-ms-text-size-adjust: 100%; // 2 //
|
||||
-webkit-text-size-adjust: 100%; // 2 //
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Remove default margin.
|
||||
//
|
||||
|
||||
body { margin: 0; }
|
||||
|
||||
|
||||
//
|
||||
// HTML5 display definitions
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||
// Correct `block` display not defined for `details` or `summary` in IE 10/11
|
||||
// and Firefox.
|
||||
// Correct `block` display not defined for `main` in IE 11.
|
||||
//
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
main,
|
||||
nav,
|
||||
section,
|
||||
summary { display: block; }
|
||||
|
||||
|
||||
//
|
||||
// 1. Correct `inline-block` display not defined in IE 8/9.
|
||||
// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||
//
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block; // 1 //
|
||||
vertical-align: baseline; // 2 //
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Prevent modern browsers from displaying `audio` without controls.
|
||||
// Remove excess height in iOS 5 devices.
|
||||
//
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Address `[hidden]` styling not present in IE 8/9/10.
|
||||
// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
|
||||
//
|
||||
|
||||
[hidden],
|
||||
template { display: none; }
|
||||
|
||||
|
||||
//
|
||||
// Links
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Remove the gray background color from active links in IE 10.
|
||||
//
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
|
||||
|
||||
//
|
||||
// Improve readability of focused elements when they are also in an
|
||||
// active/hover state.
|
||||
//
|
||||
|
||||
&:focus { outline: thin dotted; }
|
||||
|
||||
&:active,
|
||||
&:hover { outline: 0; }
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Text-level semantics
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||
//
|
||||
|
||||
abbr[title] { border-bottom: 1px dotted; }
|
||||
|
||||
|
||||
//
|
||||
// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
b,
|
||||
strong { font-weight: bold; }
|
||||
|
||||
|
||||
//
|
||||
// Address styling not present in Safari and Chrome.
|
||||
//
|
||||
|
||||
dfn { font-style: italic; }
|
||||
|
||||
|
||||
//
|
||||
// Address variable `h1` font-size and margin within `section` and `article`
|
||||
// contexts in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
h1 {
|
||||
.font-size(@h1-size);
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Address styling not present in IE 8/9.
|
||||
//
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Address inconsistent and variable font size in all browsers.
|
||||
//
|
||||
|
||||
small { font-size: 80%; }
|
||||
|
||||
|
||||
//
|
||||
// Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||
//
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup { top: -0.5em; }
|
||||
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
|
||||
//
|
||||
// Embedded content
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Remove border when inside `a` element in IE 8/9/10.
|
||||
//
|
||||
|
||||
img { border: 0; }
|
||||
|
||||
|
||||
//
|
||||
// Correct overflow not hidden in IE 9/10/11.
|
||||
//
|
||||
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
|
||||
|
||||
//
|
||||
// Grouping content
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Address margin not present in IE 8/9 and Safari.
|
||||
//
|
||||
|
||||
figure { margin: 1em 40px; }
|
||||
|
||||
|
||||
//
|
||||
// Address differences between Firefox and other browsers.
|
||||
//
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Contain overflow in all browsers.
|
||||
//
|
||||
|
||||
pre { overflow: auto; }
|
||||
|
||||
|
||||
//
|
||||
// Address odd `em`-unit font size rendering in all browsers.
|
||||
//
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
.font-size(@base-font-size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Forms
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||
// styling of `select`, unless a `border` property is set.
|
||||
//
|
||||
|
||||
//
|
||||
// 1. Correct color not being inherited.
|
||||
// Known issue: affects color of disabled elements.
|
||||
// 2. Correct font properties not being inherited.
|
||||
// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||
//
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
color: inherit; // 1 //
|
||||
font: inherit; // 1 //
|
||||
margin: 0; // 1 //
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||
//
|
||||
|
||||
button { overflow: visible; }
|
||||
|
||||
|
||||
//
|
||||
// Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
// All other form control elements do not inherit `text-transform` values.
|
||||
// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||
// Correct `select` style inheritance in Firefox.
|
||||
//
|
||||
|
||||
button,
|
||||
select { text-transform: none; }
|
||||
|
||||
|
||||
//
|
||||
// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
// and `video` controls.
|
||||
// 2. Correct inability to style clickable `input` types in iOS.
|
||||
// 3. Improve usability and consistency of cursor style between image-type
|
||||
// `input` and others.
|
||||
//
|
||||
|
||||
button,
|
||||
html input[type="button"], // 1 //
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; // 2 //
|
||||
cursor: pointer; // 3 //
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Re-set default cursor for disabled elements.
|
||||
//
|
||||
|
||||
button[disabled],
|
||||
html input[disabled] { cursor: default; }
|
||||
|
||||
|
||||
//
|
||||
// Remove inner padding and border in Firefox 4+.
|
||||
//
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
// the UA stylesheet.
|
||||
//
|
||||
|
||||
input {
|
||||
line-height: normal;
|
||||
|
||||
|
||||
//
|
||||
// It's recommended that you don't attempt to style these elements.
|
||||
// Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||
//
|
||||
// 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||
// 2. Remove excess padding in IE 8/9/10.
|
||||
//
|
||||
|
||||
&[type="checkbox"],
|
||||
&[type="radio"] {
|
||||
box-sizing: border-box; // 1 //
|
||||
padding: 0; // 2 //
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||
// `font-size` values of the `input`, it causes the cursor style of the
|
||||
// decrement button to change from `default` to `text`.
|
||||
//
|
||||
|
||||
&[type="number"] {
|
||||
&::-webkit-inner-spin-button,
|
||||
&::-webkit-outer-spin-button { height: auto; }
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 1. Address `appearance` set to `searchfield` in Safari and Chrome.
|
||||
// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
|
||||
//
|
||||
|
||||
&[type="search"] {
|
||||
-webkit-appearance: textfield; // 1 //
|
||||
box-sizing: content-box; // 2 //
|
||||
|
||||
|
||||
//
|
||||
// Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||
// Safari (but not Chrome) clips the cancel button when the search input has
|
||||
// padding (and `textfield` appearance).
|
||||
//
|
||||
|
||||
&::-webkit-search-cancel-button,
|
||||
&::-webkit-search-decoration { -webkit-appearance: none; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Define consistent border, margin, and padding.
|
||||
//
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||
// 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
//
|
||||
|
||||
legend {
|
||||
border: 0; // 1 //
|
||||
padding: 0; // 2 //
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Remove default vertical scrollbar in IE 8/9/10/11.
|
||||
//
|
||||
|
||||
textarea { overflow: auto; }
|
||||
|
||||
|
||||
//
|
||||
// Don't inherit the `font-weight` (applied by a rule above).
|
||||
// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
|
||||
//
|
||||
|
||||
optgroup { font-weight: bold; }
|
||||
|
||||
|
||||
//
|
||||
// Tables
|
||||
// ====================================================================
|
||||
|
||||
//
|
||||
// Remove most spacing between table cells.
|
||||
//
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
td,
|
||||
th { padding: 0; }
|
||||
525
src/assets/scss/normalize.scss
vendored
Normal file
@@ -0,0 +1,525 @@
|
||||
// =============================================================================
|
||||
// Normalize.scss based on Nicolas Gallagher and Jonathan Neal's
|
||||
// normalize.css v2.1.3 | MIT License | git.io/normalize
|
||||
// =============================================================================
|
||||
|
||||
// =============================================================================
|
||||
// Normalize.scss settings
|
||||
// =============================================================================
|
||||
|
||||
|
||||
// Set to true if you want to add support for IE6 and IE7
|
||||
// Notice: setting to true might render some elements
|
||||
// slightly differently than when set to false
|
||||
$legacy_support_for_ie: false !default; // Used also in Compass
|
||||
|
||||
|
||||
// Set the default font family here so you don't have to override it later
|
||||
$normalized_font_family: sans-serif !default;
|
||||
|
||||
$normalize_headings: true !default;
|
||||
|
||||
$h1_font_size: 2em !default;
|
||||
$h2_font_size: 1.5em !default;
|
||||
$h3_font_size: 1.17em !default;
|
||||
$h4_font_size: 1em !default;
|
||||
$h5_font_size: 0.83em !default;
|
||||
$h6_font_size: 0.75em !default;
|
||||
|
||||
$h1_margin: 0.67em 0 !default;
|
||||
$h2_margin: 0.83em 0 !default;
|
||||
$h3_margin: 1em 0 !default;
|
||||
$h4_margin: 1.33em 0 !default;
|
||||
$h5_margin: 1.67em 0 !default;
|
||||
$h6_margin: 2.33em 0 !default;
|
||||
|
||||
$background: #fff !default;
|
||||
$color: #000 !default;
|
||||
|
||||
// =============================================================================
|
||||
// HTML5 display definitions
|
||||
// =============================================================================
|
||||
|
||||
// Corrects block display not defined in IE6/7/8/9 & FF3
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Corrects inline-block display not defined in IE6/7/8/9 & FF3
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
@if $legacy_support_for_ie {
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Prevents modern browsers from displaying 'audio' without controls
|
||||
// 2. Remove excess height in iOS5 devices
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none; // 1
|
||||
height: 0; // 2
|
||||
}
|
||||
|
||||
//
|
||||
// Address `[hidden]` styling not present in IE 8/9.
|
||||
// Hide the `template` element in IE, Safari, and Firefox < 22.
|
||||
//
|
||||
|
||||
[hidden], template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Base
|
||||
// =============================================================================
|
||||
|
||||
// 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
|
||||
// http://clagnut.com/blog/348/#c790
|
||||
// 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
|
||||
// www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
|
||||
|
||||
html {
|
||||
@if $legacy_support_for_ie {
|
||||
font-size: 100%; // 1
|
||||
}
|
||||
background: $background;
|
||||
color: $color;
|
||||
-webkit-text-size-adjust: 100%; // 2
|
||||
-ms-text-size-adjust: 100%; // 2
|
||||
}
|
||||
|
||||
// Addresses font-family inconsistency between 'textarea' and other form elements.
|
||||
|
||||
html,
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: $normalized_font_family;
|
||||
}
|
||||
|
||||
// Addresses margins handled incorrectly in IE6/7
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Links
|
||||
// =============================================================================
|
||||
|
||||
// 1. Remove the gray background color from active links in IE 10.
|
||||
// 2. Addresses outline displayed oddly in Chrome
|
||||
// 3. Improves readability when focused and also mouse hovered in all browsers
|
||||
// people.opera.com/patrickl/experiments/keyboard/test
|
||||
|
||||
a {
|
||||
// 1
|
||||
|
||||
background: transparent;
|
||||
|
||||
// 2
|
||||
|
||||
&:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
// 3
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Typography
|
||||
// =============================================================================
|
||||
|
||||
// Addresses font sizes and margins set differently in IE6/7
|
||||
// Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
|
||||
|
||||
@if $normalize_headings == true {
|
||||
h1 {
|
||||
font-size: $h1_font_size;
|
||||
margin: $h1_margin;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $h2_font_size;
|
||||
margin: $h2_margin;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $h3_font_size;
|
||||
margin: $h3_margin;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: $h4_font_size;
|
||||
margin: $h4_margin;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $h5_font_size;
|
||||
margin: $h5_margin;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: $h6_font_size;
|
||||
margin: $h6_margin;
|
||||
}
|
||||
}
|
||||
|
||||
// Addresses styling not present in IE 8/9, S5, Chrome
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
// Addresses style set to 'bolder' in FF3+, S4/5, Chrome
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@if $legacy_support_for_ie {
|
||||
blockquote {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// Addresses styling not present in S5, Chrome
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
// Addresses styling not present in IE6/7/8/9
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
// Addresses margins set differently in IE6/7
|
||||
@if $legacy_support_for_ie {
|
||||
p,
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Corrects font family set oddly in IE6, S4/5, Chrome
|
||||
// en.wikipedia.org/wiki/User:Davidgothberg/Test59
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
@if $legacy_support_for_ie {
|
||||
_font-family: 'courier new', monospace;
|
||||
}
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
// Improves readability of pre-formatted text in all browsers
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
// Set consistent quote types.
|
||||
|
||||
q {
|
||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
||||
}
|
||||
|
||||
// 1. Addresses CSS quotes not supported in IE6/7
|
||||
// 2. Addresses quote property not supported in S4
|
||||
|
||||
// 1
|
||||
@if $legacy_support_for_ie {
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 2
|
||||
q {
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Address inconsistent and variable font size in all browsers.
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
// Prevents sub and sup affecting line-height in all browsers
|
||||
// gist.github.com/413930
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Lists
|
||||
// =============================================================================
|
||||
|
||||
// Addresses margins set differently in IE6/7
|
||||
@if $legacy_support_for_ie {
|
||||
dl,
|
||||
menu,
|
||||
ol,
|
||||
ul {
|
||||
margin: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
@if $legacy_support_for_ie {
|
||||
dd {
|
||||
margin: 0 0 0 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// Addresses paddings set differently in IE6/7
|
||||
@if $legacy_support_for_ie {
|
||||
menu,
|
||||
ol,
|
||||
ul {
|
||||
padding: 0 0 0 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// Corrects list images handled incorrectly in IE7
|
||||
|
||||
nav {
|
||||
ul,
|
||||
ol {
|
||||
@if $legacy_support_for_ie {
|
||||
list-style-image: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Embedded content
|
||||
// =============================================================================
|
||||
|
||||
// 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
|
||||
// 2. Improves image quality when scaled in IE7
|
||||
// code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
|
||||
|
||||
img {
|
||||
border: 0; // 1
|
||||
@if $legacy_support_for_ie {
|
||||
-ms-interpolation-mode: bicubic; // 2
|
||||
}
|
||||
}
|
||||
|
||||
// Corrects overflow displayed oddly in IE9
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Figures
|
||||
// =============================================================================
|
||||
|
||||
// Addresses margin not present in IE6/7/8/9, S5, O11
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Forms
|
||||
// =============================================================================
|
||||
|
||||
// Corrects margin displayed oddly in IE6/7
|
||||
@if $legacy_support_for_ie {
|
||||
form {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Define consistent border, margin, and padding
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
// 1. Corrects color not being inherited in IE6/7/8/9
|
||||
// 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
// 3. Corrects text not wrapping in FF3
|
||||
// 4. Corrects alignment displayed oddly in IE6/7
|
||||
|
||||
legend {
|
||||
border: 0; // 1
|
||||
padding: 0; // 2
|
||||
white-space: normal; // 3
|
||||
@if $legacy_support_for_ie {
|
||||
*margin-left: -7px; // 4
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Correct font family not being inherited in all browsers.
|
||||
// 2. Corrects font size not being inherited in all browsers
|
||||
// 3. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
|
||||
// 4. Improves appearance and consistency in all browsers
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; // 1
|
||||
font-size: 100%; // 2
|
||||
margin: 0; // 3
|
||||
vertical-align: baseline; // 4
|
||||
@if $legacy_support_for_ie {
|
||||
*vertical-align: middle; // 4
|
||||
}
|
||||
}
|
||||
|
||||
// Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
|
||||
|
||||
button, input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
// Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
// All other form control elements do not inherit `text-transform` values.
|
||||
// Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
|
||||
// Correct `select` style inheritance in Firefox 4+ and Opera.
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
// and `video` controls
|
||||
// 2. Corrects inability to style clickable 'input' types in iOS
|
||||
// 3. Improves usability and consistency of cursor style between image-type
|
||||
// 'input' and others
|
||||
// 4. Removes inner spacing in IE7 without affecting normal text inputs
|
||||
// Known issue: inner spacing remains in IE6
|
||||
|
||||
button,
|
||||
html input[type="button"], // 1
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; // 2
|
||||
cursor: pointer; // 3
|
||||
@if $legacy_support_for_ie {
|
||||
*overflow: visible; // 4
|
||||
}
|
||||
}
|
||||
|
||||
// Re-set default cursor for disabled elements
|
||||
|
||||
button[disabled],
|
||||
input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
// Removes inner padding and border in FF3+
|
||||
// www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
|
||||
|
||||
button, input {
|
||||
&::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Removes default vertical scrollbar in IE6/7/8/9
|
||||
// 2. Improves readability and alignment in all browsers
|
||||
|
||||
textarea {
|
||||
overflow: auto; // 1
|
||||
vertical-align: top; // 2
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Tables
|
||||
// =============================================================================
|
||||
|
||||
// Remove most spacing between table cells
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
// 1. Addresses appearance set to searchfield in S5, Chrome
|
||||
// 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
|
||||
&[type="search"] {
|
||||
-webkit-appearance: textfield; // 1
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; // 2
|
||||
box-sizing: content-box;
|
||||
|
||||
// Remove inner padding and search cancel button in Safari 5 and Chrome
|
||||
// on OS X.
|
||||
&::-webkit-search-cancel-button,
|
||||
&::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||
// 2. Remove excess padding in IE 8/9/10.
|
||||
// 3. Removes excess padding in IE7
|
||||
// Known issue: excess padding remains in IE6
|
||||
&[type="checkbox"],
|
||||
&[type="radio"] {
|
||||
box-sizing: border-box; // 1
|
||||
padding: 0; // 2
|
||||
@if $legacy_support_for_ie {
|
||||
*height: 13px; // 3
|
||||
*width: 13px; // 3
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/components/App.vue
Normal file
@@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
15
src/components/Button.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<button class="zui-button" @click="onClick">
|
||||
<slot></slot>
|
||||
</button>
|
||||
</template>
|
||||
<script>
|
||||
import './less/button.less'
|
||||
export default {
|
||||
methods: {
|
||||
onClick (e) {
|
||||
this.$emit('click', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
151
src/components/CaseLogo.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<!-- <img alt="zhichou" class="zui-logo" :src="src" @click="onClick"/> -->
|
||||
<img alt="zhichou" class="zui-logo" :src="src" />
|
||||
</template>
|
||||
<script>
|
||||
import './less/logo.less'
|
||||
import case1 from './img/case1.png'
|
||||
import case2 from './img/case2.png'
|
||||
import case3 from './img/case3.png'
|
||||
import case4 from './img/case4.png'
|
||||
import case5 from './img/case5.png'
|
||||
import case6 from './img/case6.png'
|
||||
import case7 from './img/case7.png'
|
||||
import case8 from './img/case8.png'
|
||||
import case9 from './img/case9.png'
|
||||
import case10 from './img/case10.png'
|
||||
import case11 from './img/case11.png'
|
||||
import case12 from './img/case12.png'
|
||||
import case13 from './img/case13.png'
|
||||
import case14 from './img/case14.png'
|
||||
import case15 from './img/case15.png'
|
||||
|
||||
import mcase1 from './img/mcase1.png'
|
||||
import mcase2 from './img/mcase2.png'
|
||||
import mcase3 from './img/mcase3.png'
|
||||
import mcase4 from './img/mcase4.png'
|
||||
import mcase5 from './img/mcase5.png'
|
||||
import mcase6 from './img/mcase6.png'
|
||||
import mcase7 from './img/mcase7.png'
|
||||
import mcase8 from './img/mcase8.png'
|
||||
import mcase9 from './img/mcase9.png'
|
||||
import mcase10 from './img/mcase10.png'
|
||||
import mcase11 from './img/mcase11.png'
|
||||
import mcase12 from './img/mcase12.png'
|
||||
import mcase13 from './img/mcase13.png'
|
||||
import mcase14 from './img/mcase14.png'
|
||||
import mcase15 from './img/mcase15.png'
|
||||
|
||||
export default {
|
||||
name: 'CaseLogo',
|
||||
props: {
|
||||
type: {
|
||||
default: 'case1'
|
||||
},
|
||||
href: {
|
||||
default: '/'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
src: function () {
|
||||
if (this.type === 'case1') {
|
||||
return case1
|
||||
}
|
||||
if (this.type === 'case2') {
|
||||
return case2
|
||||
}
|
||||
if (this.type === 'case3') {
|
||||
return case3
|
||||
}
|
||||
if (this.type === 'case4') {
|
||||
return case4
|
||||
}
|
||||
if (this.type === 'case5') {
|
||||
return case5
|
||||
}
|
||||
if (this.type === 'case6') {
|
||||
return case6
|
||||
}
|
||||
if (this.type === 'case7') {
|
||||
return case7
|
||||
}
|
||||
if (this.type === 'case8') {
|
||||
return case8
|
||||
}
|
||||
if (this.type === 'case9') {
|
||||
return case9
|
||||
}
|
||||
if (this.type === 'case10') {
|
||||
return case10
|
||||
}
|
||||
if (this.type === 'case11') {
|
||||
return case11
|
||||
}
|
||||
if (this.type === 'case12') {
|
||||
return case12
|
||||
}
|
||||
if (this.type === 'case13') {
|
||||
return case13
|
||||
}
|
||||
if (this.type === 'case14') {
|
||||
return case14
|
||||
}
|
||||
if (this.type === 'case15') {
|
||||
return case15
|
||||
}
|
||||
|
||||
|
||||
if (this.type === 'mcase1') {
|
||||
return mcase1
|
||||
}
|
||||
if (this.type === 'mcase2') {
|
||||
return mcase2
|
||||
}
|
||||
if (this.type === 'mcase3') {
|
||||
return mcase3
|
||||
}
|
||||
if (this.type === 'mcase4') {
|
||||
return mcase4
|
||||
}
|
||||
if (this.type === 'mcase5') {
|
||||
return mcase5
|
||||
}
|
||||
if (this.type === 'mcase6') {
|
||||
return mcase6
|
||||
}
|
||||
if (this.type === 'mcase7') {
|
||||
return mcase7
|
||||
}
|
||||
if (this.type === 'mcase8') {
|
||||
return mcase8
|
||||
}
|
||||
if (this.type === 'mcase9') {
|
||||
return mcase9
|
||||
}
|
||||
if (this.type === 'mcase10') {
|
||||
return mcase10
|
||||
}
|
||||
if (this.type === 'mcase11') {
|
||||
return mcase11
|
||||
}
|
||||
if (this.type === 'mcase12') {
|
||||
return mcase12
|
||||
}
|
||||
if (this.type === 'mcase13') {
|
||||
return mcase13
|
||||
}
|
||||
if (this.type === 'mcase14') {
|
||||
return mcase14
|
||||
}
|
||||
if (this.type === 'mcase15') {
|
||||
return mcase15
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick: function (e) {
|
||||
location.assign(this.href)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
10
src/components/CustomerCase.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div class="customer-case">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import './less/customer-case.less'
|
||||
export default {
|
||||
}
|
||||
</script>
|
||||
23
src/components/Footer.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<footer class="zui-footer">
|
||||
<div class="footer-content">
|
||||
<div class="footer-qrcode">
|
||||
<img src="../assets/img/qrcode.png" width="270" height="155" alt="客服二维码">
|
||||
</div>
|
||||
<div class="links">
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank">鲁ICP备2024118666号-1</a>
|
||||
<img src="./img/gongan.png" width="18" height="20" alt="公安图标"> <a href="https://beian.mps.gov.cn/#/query/webSearch?code=37021202001661" rel="noreferrer" target="_blank">鲁公网安备37021202001661</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="copy-right">
|
||||
Copyright 2025 智聪网络科技 .All rights reserved
|
||||
<br>
|
||||
|
||||
</p>
|
||||
|
||||
</footer>
|
||||
</template>
|
||||
<script>
|
||||
import './less/footer.less'
|
||||
export default {}
|
||||
</script>
|
||||
15
src/components/FormItem.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div class="zui-form-item">
|
||||
<label class="zui-form-label">{{label}}</label>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
17
src/components/Header.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<header class="zui-header">
|
||||
<slot></slot>
|
||||
</header>
|
||||
</template>
|
||||
<script>
|
||||
import './less/header.less'
|
||||
import Logo from './Logo'
|
||||
export default {
|
||||
props: {
|
||||
logoType: {
|
||||
default: 'zhichou'
|
||||
}
|
||||
},
|
||||
components: {Logo}
|
||||
}
|
||||
</script>
|
||||
10
src/components/Label.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<label class="zui-label">
|
||||
<slot></slot>
|
||||
<span class="zui-label-triangle"></span>
|
||||
</label>
|
||||
</template>
|
||||
<script>
|
||||
import './less/label.less'
|
||||
export default {}
|
||||
</script>
|
||||
15
src/components/Loading.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div class="zui-loading">
|
||||
<div class="zui-loading-content">
|
||||
<div class="zui-loading-dot white"></div>
|
||||
<div class="zui-loading-dot"></div>
|
||||
<div class="zui-loading-dot"></div>
|
||||
<div class="zui-loading-dot"></div>
|
||||
<div class="zui-loading-dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import './less/loading.less'
|
||||
export default {}
|
||||
</script>
|
||||
56
src/components/Logo.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<img alt="xiaoyanyun" class="zui-logo" :src="src" @click="onClick"/>
|
||||
</template>
|
||||
<script>
|
||||
import './less/logo.less'
|
||||
import logo from './img/logo.png'
|
||||
import zlogo from './img/zlogo.png'
|
||||
import hrLogo from './img/hr-logo.png'
|
||||
import plusLogo from './img/plus-logo.png'
|
||||
import mlogo from './img/m-logo.png'
|
||||
import mhrLogo from './img/m-hr-logo.png'
|
||||
import mplusLogo from './img/m-plus-logo.png'
|
||||
export default {
|
||||
name: 'Logo',
|
||||
props: {
|
||||
type: {
|
||||
default: 'xiaoyanyun'
|
||||
},
|
||||
href: {
|
||||
default: '/'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
src: function () {
|
||||
if (this.type === 'xiaoyanyun') {
|
||||
return logo
|
||||
}
|
||||
if (this.type === 'zhongtai') {
|
||||
return zlogo
|
||||
}
|
||||
if (this.type === 'mzhichou') {
|
||||
return mlogo
|
||||
}
|
||||
if (this.type === 'hr') {
|
||||
return hrLogo
|
||||
}
|
||||
if (this.type === 'mhr') {
|
||||
return mhrLogo
|
||||
}
|
||||
if (this.type === 'plus') {
|
||||
return plusLogo
|
||||
}
|
||||
if (this.type === 'mplus') {
|
||||
return mplusLogo
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick: function (e) {
|
||||
if(this.type==="xiaoyanyun"){
|
||||
location.assign(this.href)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
37
src/components/Page.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div :class="cls">
|
||||
<slot></slot>
|
||||
<zui-toast v-if="toastText!==''">
|
||||
{{toastText}}
|
||||
</zui-toast>
|
||||
<zui-loading v-if="loadingVisible"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import './less/page.less'
|
||||
import '../assets/css/vivify.min.css'
|
||||
import ZuiToast from './Toast'
|
||||
import ZuiLoading from './Loading'
|
||||
import Util from '../Util'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
title: '智聪'
|
||||
},
|
||||
components: {
|
||||
ZuiToast,
|
||||
ZuiLoading
|
||||
},
|
||||
computed: {
|
||||
cls () {
|
||||
return 'zui-page'
|
||||
},
|
||||
toastText () {
|
||||
return this.$store.state.toastText
|
||||
},
|
||||
loadingVisible () {
|
||||
return this.$store.state.loadingVisible
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
9
src/components/Toast.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div class="zui-toast">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import './less/toast.less'
|
||||
export default {}
|
||||
</script>
|
||||
BIN
src/components/img/gongan.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/components/img/hr-logo.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
src/components/img/logo--.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
src/components/img/logo.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
src/components/img/m-hr-logo.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
src/components/img/m-logo.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src/components/img/m-plus-logo.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src/components/img/plus-logo.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
src/components/img/zlogo.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
0
src/components/less/app.less
Normal file
24
src/components/less/button.less
Normal file
@@ -0,0 +1,24 @@
|
||||
@import "./mixin";
|
||||
|
||||
.@{prefix}-button{
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, #00b8ff, #007bff);
|
||||
border: none;
|
||||
min-width: 190px;
|
||||
box-shadow: 0 0 0 rgba(0, 212, 255, 0);
|
||||
transition: all .2s ease;
|
||||
.cursor();
|
||||
}
|
||||
|
||||
.@{prefix}-button:hover{
|
||||
background: linear-gradient(135deg, #00c2ff, #0088ff);
|
||||
box-shadow: 0 0 12px rgba(0, 212, 255, 0.5);
|
||||
}
|
||||
|
||||
.@{prefix}-button:active{
|
||||
background: linear-gradient(135deg, #00a8f0, #006fe6);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
126
src/components/less/customer-case.less
Normal file
@@ -0,0 +1,126 @@
|
||||
.customer-case {
|
||||
margin: 0 auto;
|
||||
max-width: 1120px;
|
||||
padding: 90px 0 100px 0;
|
||||
h2 {
|
||||
color: #F7931E;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
p {
|
||||
color: #808080;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.customer-case-carousel {
|
||||
margin-top: 35px;
|
||||
.customer-case-carousel-item {
|
||||
float: left;
|
||||
max-width: 540px;
|
||||
min-height: 320px;
|
||||
margin: 10px;
|
||||
padding: 20px 0;
|
||||
background: #DEF0EF;
|
||||
border: 2px dashed #6AC2B5;
|
||||
position: relative;
|
||||
&:after {
|
||||
clear: both;
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
h3 {
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
margin: 0 50px;
|
||||
padding: 0 0 10px 0;
|
||||
border-bottom: 3px solid #6AC2B5;
|
||||
}
|
||||
h5{
|
||||
color: #808080;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.labels{
|
||||
position: relative;
|
||||
.zui-label {
|
||||
top: -5px;
|
||||
left: 20px;
|
||||
display: block;
|
||||
min-width: 116px;
|
||||
position: absolute;
|
||||
&:nth-child(2){
|
||||
top: 50px;
|
||||
}
|
||||
}
|
||||
p {
|
||||
color: #000;
|
||||
font-size: 25px;
|
||||
text-align: left;
|
||||
padding: 0 30px 0 165px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.customer-case{
|
||||
max-width: 100%;
|
||||
padding: 25px 10px;
|
||||
h2{
|
||||
font-size:24px;
|
||||
}
|
||||
p{
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.customer-case-carousel{
|
||||
margin-top: 25px;
|
||||
.customer-case-carousel-item{
|
||||
margin: 10px 0;
|
||||
padding: 10px 0;
|
||||
min-width: 100%;
|
||||
min-height: auto;
|
||||
h3{
|
||||
font-size: 16px;
|
||||
margin: 0 20px;
|
||||
}
|
||||
h5{
|
||||
font-size: 12px;
|
||||
}
|
||||
.labels{
|
||||
.zui-label{
|
||||
top: -5px;
|
||||
left: 20px;
|
||||
font-size: 12px;
|
||||
min-width: 85px;
|
||||
&:nth-child(2){
|
||||
top: 30px;
|
||||
}
|
||||
}
|
||||
p{
|
||||
font-size: 14px;
|
||||
margin: 10px 0 0 0;
|
||||
padding: 0 20px 0 125px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.VueCarousel-pagination{
|
||||
.VueCarousel-dot-container{
|
||||
.VueCarousel-dot{
|
||||
margin-top: 0!important;
|
||||
padding: 5px!important;
|
||||
.VueCarousel-dot-inner{
|
||||
width: 8px!important;
|
||||
height: 8px!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/components/less/flag.less
Normal file
@@ -0,0 +1,38 @@
|
||||
.zui-flag {
|
||||
padding: 20px 20px 0 20px;
|
||||
width: 170px;
|
||||
margin-bottom: 85px;
|
||||
background: #32ADC6;
|
||||
position: relative;
|
||||
.zui-flag-border{
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
width: 130px;
|
||||
height: 117px;
|
||||
border-top: 3px solid #fff;
|
||||
border-left: 3px solid #fff;
|
||||
border-right: 3px solid #fff;
|
||||
display: inline-block;
|
||||
}
|
||||
.zui-label-triangle {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 85px solid transparent;
|
||||
border-right: 85px solid transparent;
|
||||
border-top: 80px solid #32ADC6;
|
||||
bottom: -80px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.zui-label-small-triangle {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 85px solid transparent;
|
||||
border-right: 85px solid transparent;
|
||||
border-top: 80px solid #32ADC6;
|
||||
bottom: -80px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
102
src/components/less/footer.less
Normal file
@@ -0,0 +1,102 @@
|
||||
@import './mixin';
|
||||
|
||||
.@{prefix}-footer {
|
||||
width: 100%;
|
||||
min-height: 125px;
|
||||
background: #646464;
|
||||
padding: 40px 0 0 0;
|
||||
border-top: 1px solid rgba(255,255,255,0.25);
|
||||
.links {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
a {
|
||||
color: #fff;
|
||||
&:after {
|
||||
content: '|';
|
||||
margin: 0 10px;
|
||||
}
|
||||
&:last-child:after {
|
||||
content: '';
|
||||
}
|
||||
&:hover {
|
||||
color: #35A3BA;
|
||||
&:after {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
br {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.copy-right {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
margin: 8px 0 0 0;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.footer-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.footer-qrcode img {
|
||||
display: block;
|
||||
max-width: 270px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.@{prefix}-footer {
|
||||
padding: 25px 15px 15px 15px;
|
||||
.footer-content {
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
padding: 0;
|
||||
}
|
||||
.footer-qrcode {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-qrcode img {
|
||||
width: 200px !important;
|
||||
max-width: 200px;
|
||||
height: auto !important;
|
||||
margin: 0 auto 10px;
|
||||
}
|
||||
.links {
|
||||
width: 100%;
|
||||
padding: 0 5px;
|
||||
a {
|
||||
display: inline-block;
|
||||
margin: 0 3px;
|
||||
padding: 4px 6px;
|
||||
font-size: 11px;
|
||||
line-height: 1.6;
|
||||
border-radius: 4px;
|
||||
&:after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
br {
|
||||
display: block;
|
||||
}
|
||||
img {
|
||||
width: 14px !important;
|
||||
height: 16px !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
.copy-right {
|
||||
font-size: 11px;
|
||||
padding: 10px 5px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/components/less/form.less
Normal file
@@ -0,0 +1,57 @@
|
||||
.zui-form {
|
||||
.zui-form-item {
|
||||
font-size: 0;
|
||||
margin: 15px 0;
|
||||
.zui-form-label {
|
||||
font-size: 16px;
|
||||
min-width: 95px;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
padding: 10px 30px 10px 0;
|
||||
}
|
||||
.zui-form-input{
|
||||
min-width: 610px;
|
||||
font-size: 16px;
|
||||
line-height: 50px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #B3B3B3;
|
||||
background: #F2F2F2;
|
||||
&:focus{
|
||||
border-color: #F7931E;
|
||||
}
|
||||
}
|
||||
.zui-button{
|
||||
min-width: 610px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: 420px) {
|
||||
.zui-form{
|
||||
padding: 20px;
|
||||
.zui-form-item{
|
||||
margin: 10px 0;
|
||||
position: relative;
|
||||
.zui-form-label{
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
line-height: 25px;
|
||||
top: 2px;
|
||||
left: 5px;
|
||||
position: absolute;
|
||||
}
|
||||
.zui-form-input{
|
||||
width: 100%;
|
||||
min-width: 100px;
|
||||
line-height: 25px;
|
||||
padding-left: 75px;
|
||||
text-align: right;
|
||||
}
|
||||
.zui-button{
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
min-width: 100px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
src/components/less/header.less
Normal file
@@ -0,0 +1,116 @@
|
||||
@import "./mixin.less";
|
||||
|
||||
.@{prefix}-header {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
background: rgba(255,255,255,0.75);
|
||||
backdrop-filter: saturate(180%) blur(8px);
|
||||
box-shadow: 0 4px 14px rgba(16,24,40,0.08);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
.float-clear;
|
||||
.@{prefix}-logo{
|
||||
width: 135px;
|
||||
height: 100px;
|
||||
margin: 0 0 0 20px;
|
||||
float: left;
|
||||
}
|
||||
.@{prefix}-logo-text{
|
||||
float: left;
|
||||
height: 100px;
|
||||
color: #36A4BB;
|
||||
font-size: 16px;
|
||||
// padding-top: 28px;
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
margin: 0 0 0 0px;
|
||||
}
|
||||
.@{prefix}-logo-text a{
|
||||
color: var(--color-text);
|
||||
text-decoration: none;
|
||||
margin: 0 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.@{prefix}-logo-text a:hover{
|
||||
color: var(--color-accent);
|
||||
text-decoration: underline;
|
||||
}
|
||||
.@{prefix}-button{
|
||||
float: right;
|
||||
line-height: 40px;
|
||||
margin: 30px 30px 0 0;
|
||||
min-width: 100px;
|
||||
}
|
||||
.@{prefix}-rightcol{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.@{prefix}-logo-line {
|
||||
width: 1px;
|
||||
height: 45px;
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
float: left;
|
||||
position: relative;
|
||||
background: #32adc6;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.@{prefix}-header{
|
||||
height: 60px;
|
||||
.zui-logo{
|
||||
height: 60px;
|
||||
width: 100px;
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
.@{prefix}-logo-text{
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
font-size: 10px;
|
||||
margin: 0;
|
||||
a {
|
||||
margin: 0 4px;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
.@{prefix}-button{
|
||||
display: none !important;
|
||||
}
|
||||
.@{prefix}-rightcol{
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
float: right;
|
||||
line-height: 35px;
|
||||
margin: 12px 10px 0 0;
|
||||
min-width: 60px;
|
||||
padding: 0 12px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #35A3BA, #0088ff);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 6px rgba(53, 163, 186, 0.3);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.@{prefix}-rightcol:active {
|
||||
transform: scale(0.96);
|
||||
box-shadow: 0 1px 3px rgba(53, 163, 186, 0.4);
|
||||
}
|
||||
.@{prefix}-logo-line {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.@{prefix}-header{
|
||||
.@{prefix}-rightcol{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/components/less/label.less
Normal file
@@ -0,0 +1,35 @@
|
||||
.zui-label {
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
padding: 0 20px;
|
||||
margin-right: 20px;
|
||||
background: #6AC2B5;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
.zui-label-triangle {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 20px solid transparent;
|
||||
border-left: 20px solid #6AC2B5;
|
||||
border-bottom: 20px solid transparent;
|
||||
right: -20px;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.zui-label{
|
||||
line-height: 25px;
|
||||
padding: 0 10px;
|
||||
min-width: 85px;
|
||||
.zui-label-triangle{
|
||||
border-top: 11px solid transparent;
|
||||
border-left: 12px solid #6AC2B5;
|
||||
border-bottom: 15px solid transparent;
|
||||
right: -11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
151
src/components/less/loading.less
Normal file
@@ -0,0 +1,151 @@
|
||||
@import './mixin';
|
||||
|
||||
.@{prefix}-loading {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
margin: auto;
|
||||
position: fixed;
|
||||
|
||||
-webkit-animation: rotate .8s linear infinite;
|
||||
-moz-animation: rotate .8s linear infinite;
|
||||
-o-animation: rotate .8s linear infinite;
|
||||
animation: rotate .8s linear infinite;
|
||||
.@{prefix}-loading-content{
|
||||
.@{prefix}-loading-dot{
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 100%;
|
||||
|
||||
-webkit-transition: all .8s ease;
|
||||
-moz-transition: all .8s ease;
|
||||
-o-transition: all .8s ease;
|
||||
transition: all .8s ease;
|
||||
|
||||
&.white {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
opacity: 0;
|
||||
|
||||
-webkit-animation: flash .8s linear infinite;
|
||||
-moz-animation: flash .8s linear infinite;
|
||||
-o-animation: flash .8s linear infinite;
|
||||
animation: flash .8s linear infinite;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: #FF4444;
|
||||
|
||||
-webkit-animation: dotsY .8s linear infinite;
|
||||
-moz-animation: dotsY .8s linear infinite;
|
||||
-o-animation: dotsY .8s linear infinite;
|
||||
animation: dotsY .8s linear infinite;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background: #FFBB33;
|
||||
|
||||
-webkit-animation: dotsX .8s linear infinite;
|
||||
-moz-animation: dotsX .8s linear infinite;
|
||||
-o-animation: dotsX .8s linear infinite;
|
||||
animation: dotsX .8s linear infinite;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: #99CC00;
|
||||
|
||||
-webkit-animation: dotsY .8s linear infinite;
|
||||
-moz-animation: dotsY .8s linear infinite;
|
||||
-o-animation: dotsY .8s linear infinite;
|
||||
animation: dotsY .8s linear infinite;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #33B5E5;
|
||||
|
||||
-webkit-animation: dotsX .8s linear infinite;
|
||||
-moz-animation: dotsX .8s linear infinite;
|
||||
-o-animation: dotsX .8s linear infinite;
|
||||
animation: dotsX .8s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
-webkit-transform: rotate(0);
|
||||
-moz-transform: rotate(0);
|
||||
-o-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
10% {
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
}
|
||||
66% {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
-moz-transform: rotate(360deg);
|
||||
-o-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dotsY {
|
||||
66% {
|
||||
opacity: .1;
|
||||
width: 1em;
|
||||
}
|
||||
77% {
|
||||
opacity: 1;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dotsX {
|
||||
66% {
|
||||
opacity: .1;
|
||||
height: 1em;
|
||||
}
|
||||
77% {
|
||||
opacity: 1;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flash {
|
||||
33% {
|
||||
opacity: 0;
|
||||
border-radius: 0%;
|
||||
}
|
||||
55% {
|
||||
opacity: .6;
|
||||
border-radius: 100%;
|
||||
}
|
||||
66% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/components/less/logo.less
Normal file
@@ -0,0 +1,5 @@
|
||||
.zui-logo {
|
||||
width: 150px;
|
||||
height: 52px;
|
||||
cursor: pointer;
|
||||
}
|
||||
280
src/components/less/mixin.less
Normal file
@@ -0,0 +1,280 @@
|
||||
.transform(@t) {
|
||||
-webkit-transform: @t;
|
||||
transform: @t;
|
||||
}
|
||||
|
||||
.transform-origin(@to) {
|
||||
-webkit-transform-origin: @to;
|
||||
transform-origin: @to;
|
||||
}
|
||||
|
||||
.transition(@value) {
|
||||
-webkit-transition: @value;
|
||||
}
|
||||
|
||||
.hairline-top(@color) {
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
right: auto;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border-top: 1px solid @color;
|
||||
display: block;
|
||||
z-index: 15;
|
||||
.transform-origin(50% 0%);
|
||||
html.pixel-ratio-2 & {
|
||||
.transform(scaleY(0.5));
|
||||
}
|
||||
html.pixel-ratio-3 & {
|
||||
.transform(scaleY(0.33));
|
||||
}
|
||||
html.pixel-ratio-4 & {
|
||||
.transform(scaleY(0.25));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hairline-left(@color) {
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
right: auto;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background-color: @color;
|
||||
display: block;
|
||||
z-index: 15;
|
||||
.transform-origin(0% 50%);
|
||||
html.pixel-ratio-2 & {
|
||||
.transform(scaleX(0.5));
|
||||
}
|
||||
html.pixel-ratio-3 & {
|
||||
.transform(scaleX(0.33));
|
||||
}
|
||||
html.pixel-ratio-4 & {
|
||||
.transform(scaleX(0.25));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hairline-bottom(@color, @left:0) {
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: @left;
|
||||
bottom: 0;
|
||||
right: auto;
|
||||
top: auto;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border-bottom: 1px solid @color;
|
||||
display: block;
|
||||
z-index: 15;
|
||||
.transform-origin(50% 100%);
|
||||
html.pixel-ratio-2 & {
|
||||
.transform(scaleY(0.5));
|
||||
}
|
||||
html.pixel-ratio-3 & {
|
||||
.transform(scaleY(0.33));
|
||||
}
|
||||
html.pixel-ratio-4 & {
|
||||
.transform(scaleY(0.25));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hairline-right(@color) {
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
left: auto;
|
||||
bottom: auto;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background-color: @color;
|
||||
display: block;
|
||||
z-index: 15;
|
||||
.transform-origin(100% 50%);
|
||||
html.pixel-ratio-2 & {
|
||||
.transform(scaleX(0.5));
|
||||
}
|
||||
html.pixel-ratio-3 & {
|
||||
.transform(scaleX(0.33));
|
||||
}
|
||||
html.pixel-ratio-4 & {
|
||||
.transform(scaleX(0.25));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For right and bottom
|
||||
.hairline-remove-right-bottom {
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// For left and top
|
||||
.hairline-remove-left-top {
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Encoded SVG Background
|
||||
.encoded-svg-background(@svg) {
|
||||
@url: `encodeURIComponent(@{svg})`;
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,@{url}");
|
||||
}
|
||||
|
||||
.align-self(@as) {
|
||||
-ms-flex-item-align: @as;
|
||||
-webkit-align-self: @as;
|
||||
align-self: @as;
|
||||
}
|
||||
|
||||
.ellipsis() {
|
||||
width: auto;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.backgroundSize(@width,@height) {
|
||||
-webkit-background-size: @width @height;
|
||||
}
|
||||
|
||||
.display-box() {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-direction(@direction: row) {
|
||||
flex-direction: @direction;
|
||||
}
|
||||
|
||||
.flex-wrap(@wrap: nowrap) {
|
||||
flex-wrap: @wrap;
|
||||
}
|
||||
|
||||
.flex-justify(@justify: flex-start) {
|
||||
justify-content: @justify;
|
||||
}
|
||||
|
||||
.box-align(@align: center) {
|
||||
align-items: @align;
|
||||
}
|
||||
|
||||
.box-align-content(@alignContent: stretch) {
|
||||
align-content: @alignContent;
|
||||
}
|
||||
|
||||
.box-flex(@scale: 1) {
|
||||
flex: @scale;
|
||||
}
|
||||
|
||||
.border-radius(@radius: 0) {
|
||||
border-top-left-radius: @radius;
|
||||
border-top-right-radius: @radius;
|
||||
border-bottom-left-radius: @radius;
|
||||
border-bottom-right-radius: @radius;
|
||||
-webkit-background-clip: padding-box;
|
||||
}
|
||||
|
||||
.background(@start: #ffffff, @end: #000000) {
|
||||
background: @end;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(@start), to(@end)); /* Saf4+, Chrome */
|
||||
background-image: linear-gradient(@start, @end);
|
||||
}
|
||||
|
||||
.border-1px-bottom(@color: #d2d2d2) {
|
||||
background: left bottom repeat-x;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(.5, transparent), color-stop(.5, @color), to(@color));
|
||||
background-image: linear-gradient(left top, left bottom, color-stop(.5, transparent), color-stop(.5, @color), to(@color));
|
||||
-webkit-background-size: 100% 1px;
|
||||
background-size: 100% 1px;
|
||||
}
|
||||
|
||||
.border-1px-top(@color: #d2d2d2) {
|
||||
background: left top repeat-x;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(@color), color-stop(.5, @color), color-stop(.5, transparent));
|
||||
background-image: linear-gradient(left top, left bottom, from(@color), color-stop(.5, @color), color-stop(.5, transparent));
|
||||
-webkit-background-size: 100% 1px;
|
||||
background-size: 100% 1px;
|
||||
}
|
||||
|
||||
.border-1px-both(@color: #d2d2d2) {
|
||||
background-position: left top, left bottom;
|
||||
background-repeat: repeat-x, repeat-x;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(@color), color-stop(.5, @color), color-stop(.5, transparent)), -webkit-gradient(linear, left top, left bottom, color-stop(.5, transparent), color-stop(.5, @color), to(@color));
|
||||
background-image: linear-gradient(left top, left bottom, from(@color), color-stop(.5, @color), color-stop(.5, transparent)), linear-gradient(left top, left bottom, color-stop(.5, transparent), color-stop(.5, @color), to(@color));
|
||||
-webkit-background-size: 100% 1px, 100% 1px;
|
||||
background-size: 100% 1px, 100% 1px;
|
||||
}
|
||||
|
||||
.border-1px-scale(@color: #d2d2d2) {
|
||||
position: relative;
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
border-bottom: 1px solid @color;
|
||||
-webkit-transform: scaleY(.5);
|
||||
-webkit-transform-origin: 0px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.box-sizing(@sizing: border-box) {
|
||||
-webkit-box-sizing: @sizing;
|
||||
}
|
||||
|
||||
.box-shadow(@value) {
|
||||
-webkit-box-shadow: @value;
|
||||
}
|
||||
|
||||
.box-shadow(@value1, @value2) {
|
||||
-webkit-box-shadow: @value1, @value2;
|
||||
}
|
||||
|
||||
.ellipsis(@w:auto) {
|
||||
width: @w;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.float-clear() {
|
||||
&:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0px;
|
||||
content: ' ';
|
||||
clear: both;
|
||||
height: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.cursor() {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.overflow-scroll() {
|
||||
overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
@colorMain: #6ac2b6;
|
||||
@prefix: zui;
|
||||
109
src/components/less/page.less
Normal file
@@ -0,0 +1,109 @@
|
||||
@import './reset.less';
|
||||
|
||||
:root {
|
||||
--color-bg: #edf7f7;
|
||||
--color-text: #1f2a37;
|
||||
--color-accent: #35A3BA;
|
||||
--color-accent-strong: #0ea5b7;
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--radius-1: 10px;
|
||||
--radius-2: 16px;
|
||||
--shadow-1: 0 2px 8px rgba(16,24,40,.06);
|
||||
--shadow-2: 0 8px 24px rgba(16,24,40,.08);
|
||||
--transition-fast: 180ms;
|
||||
}
|
||||
|
||||
.zui-page {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
margin: 0 auto;
|
||||
font-family: "微软雅黑", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: #35A3BA;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.zui-nav-link {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
margin-left: 12px;
|
||||
}
|
||||
.zui-nav-link:hover {
|
||||
text-decoration: underline;
|
||||
color: #35A3BA;
|
||||
}
|
||||
.zui-nav-link--mobile {
|
||||
font-size: 12px;
|
||||
}
|
||||
.clear:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
/* Drawer menu */
|
||||
.zui-drawer-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 999;
|
||||
}
|
||||
.zui-drawer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 70%;
|
||||
max-width: 300px;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.06);
|
||||
z-index: 1000;
|
||||
padding: 16px;
|
||||
}
|
||||
.zui-drawer__header {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
}
|
||||
.zui-drawer__list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.zui-drawer__list li {
|
||||
padding: 12px 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.zui-drawer__list li:hover {
|
||||
background: #f6f8fa;
|
||||
cursor: pointer;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.zui-page {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.zui-drawer,
|
||||
.zui-drawer-overlay {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.zui-page {
|
||||
min-width: 1200px;
|
||||
}
|
||||
}
|
||||
84
src/components/less/reset.less
Normal file
@@ -0,0 +1,84 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
-ms-touch-action: none;
|
||||
}
|
||||
|
||||
html, body {
|
||||
-webkit-text-size-adjust: none;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
font-size: 14px !important;
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #32ADC6;
|
||||
text-decoration: none;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
button {
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
input, button, textarea {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input:active, textarea:active, select:active {
|
||||
border: none;
|
||||
}
|
||||
|
||||
input, textarea, select {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
|
||||
/* WebKit browsers */
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input:-moz-placeholder, textarea:-moz-placeholder {
|
||||
/* Mozilla Firefox 4 to 18 */
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
/* Mozilla Firefox 19+ */
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
|
||||
/* Internet Explorer 10+ */
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
23
src/components/less/toast.less
Normal file
@@ -0,0 +1,23 @@
|
||||
@import "./mixin";
|
||||
|
||||
.@{prefix}-toast{
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 250px;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
border-radius: 10px;
|
||||
background: rgba(0,0,0,.7);
|
||||
animation: toastScaleIn .2s ease forwards;
|
||||
@keyframes toastScaleIn {
|
||||
0%{
|
||||
transform: scale(.8, .8) translate(-50%, -50%);
|
||||
}
|
||||
100%{
|
||||
transform: scale(1, 1) translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/components/less/var.css
Normal file
@@ -0,0 +1,44 @@
|
||||
$color-blue: #26a2ff;
|
||||
$color-white: #fff;
|
||||
$color-grey: #d9d9d9;
|
||||
$border-color: #c8c8cd;
|
||||
$success-color: #4caf50;
|
||||
$error-color: #f44336;
|
||||
$warning-color: #ffc107;
|
||||
|
||||
/* Cell Component */
|
||||
$cell-value-color: #888;
|
||||
|
||||
/* Header Component */
|
||||
$header-height: 40px;
|
||||
|
||||
/* Button Component */
|
||||
$button-default-color: #656b79;
|
||||
$button-default-background-color: #f6f8fa;
|
||||
$button-default-plain-color: #5a5a5a;
|
||||
$button-default-box-shadow: 0 0 1px #b8bbbf;
|
||||
$button-primary-color: #fff;
|
||||
$button-primary-background-color: #26a2ff;
|
||||
$button-danger-color: #fff;
|
||||
$button-danger-background-color: #ef4f4f;
|
||||
|
||||
/* Tab Item Component */
|
||||
$tab-item-font-size: 12px;
|
||||
|
||||
/* Tabbar Component */
|
||||
$tabbar-background-color: #fafafa;
|
||||
$tabbar-tab-item-selected-background-color: #eaeaea;
|
||||
$tabbar-tab-item-selected-color: $color-blue;
|
||||
|
||||
/* Navbar Component */
|
||||
$navbar-background-color: #fafafa;
|
||||
$tabbar-tab-item-selected-background-color: #eaeaea;
|
||||
|
||||
/* Checklist Component */
|
||||
$checklist-title-color: #888;
|
||||
|
||||
/* Radio Component */
|
||||
$radio-title-color: #888;
|
||||
|
||||
/* z-index */
|
||||
$z-index-normal: 1;
|
||||
12
src/main.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import Vue from 'vue'
|
||||
import store from './store'
|
||||
import router from './router'
|
||||
import App from './components/App'
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
template: '<App/>',
|
||||
components: { App }
|
||||
}).$mount('#app')
|
||||
|
||||
16
src/router/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
const HomePage = () => import('../views/HomePage')
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: __dirname,
|
||||
routes: [{
|
||||
path: '/',
|
||||
component: HomePage
|
||||
}]
|
||||
});
|
||||
|
||||
export default router;
|
||||
81
src/services/BaseService.js
Normal file
@@ -0,0 +1,81 @@
|
||||
'use strict'
|
||||
import jsonp from 'jsonp'
|
||||
import store from '../store'
|
||||
|
||||
const buildQuery = (data) => {
|
||||
let query = ''
|
||||
for (let i in data) {
|
||||
let queryItem = ''
|
||||
if (Object.prototype.toString.call(data[i]) === '[object Array]') {
|
||||
queryItem = data[i].map((item, key) => {
|
||||
return i + '[' + key + ']=' + item
|
||||
}).join('&')
|
||||
} else {
|
||||
queryItem = i + '=' + encodeURIComponent(data[i])
|
||||
}
|
||||
query += queryItem + '&'
|
||||
}
|
||||
return query.substr(0, query.length - 1)
|
||||
}
|
||||
|
||||
const buildUrl = (path, data) => {
|
||||
const protocol = location.href.indexOf('https') === -1 ? 'http://' : 'https://'
|
||||
const host = path.indexOf('//') === -1 ? protocol + process.env.API_HOST + '/' : ''
|
||||
const query = data ? '?' + buildQuery(data) : ''
|
||||
return host + path + query
|
||||
}
|
||||
|
||||
const beforeSend = (data) => {
|
||||
if (data && data.loading === false) {
|
||||
store.commit('loading', false)
|
||||
} else {
|
||||
store.commit('loading', true)
|
||||
window.ajaxnum = (window.ajaxnum || 0) + 1
|
||||
}
|
||||
}
|
||||
|
||||
const afterSend = (data) => {
|
||||
store.commit('loading', false)
|
||||
window.ajaxnum = (window.ajaxnum || 0) + 1
|
||||
}
|
||||
|
||||
const onStatusError = (res) => {
|
||||
if (res.status === 40001) {
|
||||
store.commit('requireLogin')
|
||||
return false
|
||||
}
|
||||
store.commit('toast', res.message || '请求错误, 请稍候重试')
|
||||
}
|
||||
|
||||
const onRequestError = (err) => {
|
||||
store.commit('requestError', err)
|
||||
}
|
||||
|
||||
export default class BaseService {
|
||||
/**
|
||||
* send jsonp request
|
||||
* @param url
|
||||
* @param data
|
||||
* @param onSuccess
|
||||
* @param onError
|
||||
*/
|
||||
static jsonp = (url, data, onSuccess, onError) => {
|
||||
beforeSend(data)
|
||||
jsonp(buildUrl(url, data), {
|
||||
timeout: 10000
|
||||
}, (err, res) => {
|
||||
afterSend(res)
|
||||
|
||||
if (err != null) {
|
||||
onRequestError(err)
|
||||
return false
|
||||
}
|
||||
if (res.status !== 0 && res.status !== 40006 && res.status !== 80001) {
|
||||
onStatusError(res)
|
||||
return false
|
||||
}
|
||||
|
||||
onSuccess && onSuccess(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
7
src/services/FeedbackService.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import BaseService from './BaseService'
|
||||
|
||||
export default class FeedbackService {
|
||||
static create = (data, success) => {
|
||||
BaseService.jsonp('feedback/create', data, success)
|
||||
}
|
||||
}
|
||||
7
src/services/UserService.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import BaseService from './BaseService'
|
||||
|
||||
export default class UserService {
|
||||
static feedback = (data, success) => {
|
||||
BaseService.jsonp('user/feedback', data, success)
|
||||
}
|
||||
}
|
||||
28
src/store/index.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
Vue.use(Vuex)
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
toastText: '',
|
||||
loadingVisible: false
|
||||
},
|
||||
mutations: {
|
||||
increment (state) {
|
||||
state.count++
|
||||
},
|
||||
toast (state, text) {
|
||||
state.toastText = text
|
||||
setTimeout(() => {
|
||||
state.toastText = ''
|
||||
}, 2000)
|
||||
},
|
||||
loading (state, loadingVisible) {
|
||||
state.loadingVisible = loadingVisible
|
||||
},
|
||||
requireLogin (state) {
|
||||
const host = process.env.NODE_ENV === 'development' ? 'wxtest.zhichou.com' : 'wx.zhichou.com'
|
||||
location.assign('http://' + host + '/#/me/login?rurl=' + encodeURIComponent(location.href))
|
||||
}
|
||||
}
|
||||
})
|
||||
610
src/views/HomePage.vue
Normal file
@@ -0,0 +1,610 @@
|
||||
<template>
|
||||
<page class="home-page workbench-page">
|
||||
<div class="workbench-header">
|
||||
<h1>Qdintc - 统一工作平台</h1>
|
||||
</div>
|
||||
|
||||
<div class="workbench-container">
|
||||
<div class="tools-container">
|
||||
<!-- 代码管理 -->
|
||||
<div class="tool-category" v-if="codeTools.length > 0">
|
||||
<h2 class="category-title">代码管理</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in codeTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 持续集成 -->
|
||||
<div class="tool-category" v-if="ciTools.length > 0">
|
||||
<h2 class="category-title">持续集成</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in ciTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 项目管理 -->
|
||||
<div class="tool-category" v-if="projectTools.length > 0">
|
||||
<h2 class="category-title">项目管理</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in projectTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据库 -->
|
||||
<div class="tool-category" v-if="databaseTools.length > 0">
|
||||
<h2 class="category-title">数据库</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in databaseTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 监控告警 -->
|
||||
<div class="tool-category" v-if="monitorTools.length > 0">
|
||||
<h2 class="category-title">监控告警</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in monitorTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文档知识 -->
|
||||
<div class="tool-category" v-if="docTools.length > 0">
|
||||
<h2 class="category-title">文档知识</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in docTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 测试工具 -->
|
||||
<div class="tool-category" v-if="testTools.length > 0">
|
||||
<h2 class="category-title">测试工具</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in testTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 安全扫描 -->
|
||||
<div class="tool-category" v-if="securityTools.length > 0">
|
||||
<h2 class="category-title">安全扫描</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in securityTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 云平台 -->
|
||||
<div class="tool-category" v-if="cloudTools.length > 0">
|
||||
<h2 class="category-title">云平台</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in cloudTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 其他工具 -->
|
||||
<div class="tool-category" v-if="otherTools.length > 0">
|
||||
<h2 class="category-title">其他工具</h2>
|
||||
<div class="category-items">
|
||||
<div class="tool-card" v-for="tool in otherTools" :key="tool.name" @click="openTool(tool.url)">
|
||||
<div class="tool-icon" :style="{background: tool.color}">
|
||||
<span class="icon-text">{{ tool.icon }}</span>
|
||||
</div>
|
||||
<div class="tool-info">
|
||||
<h4 class="tool-name">{{ tool.name }}</h4>
|
||||
<p class="tool-desc">{{ tool.desc }}</p>
|
||||
<p class="tool-url">{{ tool.displayUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</page>
|
||||
</template>
|
||||
<script>
|
||||
import './less/home-page.less'
|
||||
import Page from '../components/Page'
|
||||
export default{
|
||||
components: {Page},
|
||||
data () {
|
||||
return {
|
||||
// 代码管理工具
|
||||
codeTools: [
|
||||
{
|
||||
name: 'Gitea',
|
||||
desc: 'Git代码仓库管理',
|
||||
url: 'http://your-gitea-url.com',
|
||||
displayUrl: 'gitea.company.com',
|
||||
icon: 'Git',
|
||||
color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
|
||||
},
|
||||
{
|
||||
name: 'GitLab',
|
||||
desc: 'DevOps生命周期工具',
|
||||
url: 'http://your-gitlab-url.com',
|
||||
displayUrl: 'gitlab.company.com',
|
||||
icon: 'GL',
|
||||
color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)'
|
||||
}
|
||||
],
|
||||
// 持续集成工具
|
||||
ciTools: [
|
||||
{
|
||||
name: 'Jenkins',
|
||||
desc: '持续集成构建平台',
|
||||
url: 'http://your-jenkins-url.com',
|
||||
displayUrl: 'jenkins.company.com',
|
||||
icon: 'JK',
|
||||
color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Harbor',
|
||||
desc: 'Docker镜像仓库',
|
||||
url: 'http://your-harbor-url.com',
|
||||
displayUrl: 'harbor.company.com',
|
||||
icon: 'HB',
|
||||
color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)'
|
||||
}
|
||||
],
|
||||
// 项目管理工具
|
||||
projectTools: [
|
||||
{
|
||||
name: '禅道',
|
||||
desc: '项目管理与Bug追踪',
|
||||
url: 'http://your-zentao-url.com',
|
||||
displayUrl: 'zentao.company.com',
|
||||
icon: '禅',
|
||||
color: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Jira',
|
||||
desc: '敏捷项目管理工具',
|
||||
url: 'http://your-jira-url.com',
|
||||
displayUrl: 'jira.company.com',
|
||||
icon: 'JR',
|
||||
color: 'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)'
|
||||
}
|
||||
],
|
||||
// 数据库工具
|
||||
databaseTools: [
|
||||
{
|
||||
name: 'MySQL',
|
||||
desc: 'MySQL数据库管理',
|
||||
url: 'http://your-mysql-url.com',
|
||||
displayUrl: 'mysql.company.com',
|
||||
icon: 'SQL',
|
||||
color: 'linear-gradient(135deg, #f8b500 0%, #fceabb 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Redis',
|
||||
desc: '缓存数据库管理',
|
||||
url: 'http://your-redis-url.com',
|
||||
displayUrl: 'redis.company.com',
|
||||
icon: 'RD',
|
||||
color: 'linear-gradient(135deg, #e43a15 0%, #e65245 100%)'
|
||||
}
|
||||
],
|
||||
// 监控告警工具
|
||||
monitorTools: [
|
||||
{
|
||||
name: 'Grafana',
|
||||
desc: '监控数据可视化',
|
||||
url: 'http://your-grafana-url.com',
|
||||
displayUrl: 'grafana.company.com',
|
||||
icon: 'GF',
|
||||
color: 'linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Prometheus',
|
||||
desc: '系统监控告警平台',
|
||||
url: 'http://your-prometheus-url.com',
|
||||
displayUrl: 'prometheus.company.com',
|
||||
icon: 'PM',
|
||||
color: 'linear-gradient(135deg, #d299c2 0%, #fef9d7 100%)'
|
||||
}
|
||||
],
|
||||
// 文档知识工具
|
||||
docTools: [
|
||||
{
|
||||
name: 'Confluence',
|
||||
desc: '团队协作知识库',
|
||||
url: 'http://your-confluence-url.com',
|
||||
displayUrl: 'wiki.company.com',
|
||||
icon: 'CF',
|
||||
color: 'linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%)'
|
||||
},
|
||||
{
|
||||
name: 'GitBook',
|
||||
desc: '文档编写平台',
|
||||
url: 'http://your-gitbook-url.com',
|
||||
displayUrl: 'docs.company.com',
|
||||
icon: 'GB',
|
||||
color: 'linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%)'
|
||||
}
|
||||
],
|
||||
// 测试工具
|
||||
testTools: [
|
||||
{
|
||||
name: 'Selenium',
|
||||
desc: '自动化测试平台',
|
||||
url: 'http://your-selenium-url.com',
|
||||
displayUrl: 'test.company.com',
|
||||
icon: 'SE',
|
||||
color: 'linear-gradient(135deg, #96fbc4 0%, #f9f586 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Postman',
|
||||
desc: 'API测试工具',
|
||||
url: 'http://your-postman-url.com',
|
||||
displayUrl: 'api-test.company.com',
|
||||
icon: 'PM',
|
||||
color: 'linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)'
|
||||
}
|
||||
],
|
||||
// 安全扫描工具
|
||||
securityTools: [
|
||||
{
|
||||
name: 'SonarQube',
|
||||
desc: '代码质量检测平台',
|
||||
url: 'http://your-sonar-url.com',
|
||||
displayUrl: 'sonar.company.com',
|
||||
icon: 'SQ',
|
||||
color: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Trivy',
|
||||
desc: '容器安全扫描',
|
||||
url: 'http://your-trivy-url.com',
|
||||
displayUrl: 'security.company.com',
|
||||
icon: 'TV',
|
||||
color: 'linear-gradient(135deg, #30cfd0 0%, #330867 100%)'
|
||||
}
|
||||
],
|
||||
// 云平台工具
|
||||
cloudTools: [
|
||||
{
|
||||
name: 'Kubernetes',
|
||||
desc: '容器编排平台',
|
||||
url: 'http://your-k8s-url.com',
|
||||
displayUrl: 'k8s.company.com',
|
||||
icon: 'K8s',
|
||||
color: 'linear-gradient(135deg, #2af598 0%, #009efd 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Rancher',
|
||||
desc: 'K8s集群管理',
|
||||
url: 'http://your-rancher-url.com',
|
||||
displayUrl: 'rancher.company.com',
|
||||
icon: 'RC',
|
||||
color: 'linear-gradient(135deg, #0ba360 0%, #3cba92 100%)'
|
||||
}
|
||||
],
|
||||
// 其他工具
|
||||
otherTools: [
|
||||
{
|
||||
name: 'Nexus',
|
||||
desc: 'Maven私服仓库',
|
||||
url: 'http://your-nexus-url.com',
|
||||
displayUrl: 'nexus.company.com',
|
||||
icon: 'NX',
|
||||
color: 'linear-gradient(135deg, #fdcbf1 0%, #e6dee9 100%)'
|
||||
},
|
||||
{
|
||||
name: 'Portainer',
|
||||
desc: 'Docker容器管理',
|
||||
url: 'http://your-portainer-url.com',
|
||||
displayUrl: 'portainer.company.com',
|
||||
icon: 'PT',
|
||||
color: 'linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%)'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
openTool: function (url) {
|
||||
if(url && url !== 'http://your-gitea-url.com') {
|
||||
window.open(url, '_blank')
|
||||
} else {
|
||||
alert('请先配置该工具的访问地址')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.workbench-page {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 0;
|
||||
padding-top: 76px;
|
||||
}
|
||||
|
||||
.workbench-container {
|
||||
max-width: 1920px;
|
||||
margin: 0 auto;
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
.workbench-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
background: rgba(255,255,255,0.08);
|
||||
z-index: 1000;
|
||||
backdrop-filter: blur(15px);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.15);
|
||||
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
text-shadow: 0 2px 10px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
color: rgba(255,255,255,0.85);
|
||||
margin: 8px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tools-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 25px 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.tool-category {
|
||||
flex: 0 1 auto;
|
||||
|
||||
.category-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 15px;
|
||||
padding-left: 12px;
|
||||
border-left: 4px solid rgba(255,255,255,0.8);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.category-items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 14px 18px;
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
width: 260px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.2);
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||
|
||||
.icon-text {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.tool-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.tool-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0 0 4px 0;
|
||||
}
|
||||
|
||||
.tool-desc {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin: 0 0 4px 0;
|
||||
}
|
||||
|
||||
.tool-url {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
font-family: 'Consolas', 'Monaco', monospace;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.tools-container {
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
.tool-category {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
.category-title {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.category-items {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-card {
|
||||
width: calc(50% - 8px);
|
||||
}
|
||||
|
||||
.workbench-header h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.workbench-container {
|
||||
padding: 30px 15px;
|
||||
}
|
||||
|
||||
.workbench-header {
|
||||
margin-bottom: 30px;
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.tools-container {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.tool-category {
|
||||
.category-title {
|
||||
font-size: 16px;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-card {
|
||||
padding: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tool-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 12px;
|
||||
|
||||
.icon-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.tool-name {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.tool-desc {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
src/views/img/case-banner.jpg
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
src/views/img/feature10.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/views/img/feature11.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
src/views/img/feature12.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/views/img/feature13.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
src/views/img/feature14.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
src/views/img/feature8.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
src/views/img/feature9.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
src/views/img/link-banner.jpg
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
src/views/img/plan-banner-mobile.jpg
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
src/views/img/plan-banner.jpg
Normal file
|
After Width: | Height: | Size: 52 KiB |