Commit 2aa9245c by 严立

更换专家注册下载文件 | 邮箱校验规则 | 备案跳转地址

parent b8ba49a5
Showing with 2442 additions and 2417 deletions
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}
# merchant2.1.x
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
# merchant2.1.x
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('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)
}
}
'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)
}
}
'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').concat({
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/common/css/global.less')
}
}),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const 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').concat({
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/common/css/global.less')
}
}),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const 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'
}
}
'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'
}
}
'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: ['babel-polyfill', './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',
options:{
presets: ['es2015']
},
include: [
resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client'),
resolve('src'), resolve('test'), resolve('node_modules/element-ui/src'),
resolve('src'), resolve('test'), resolve('node_modules/element-ui/packages'),
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
'use strict'
const 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: ['babel-polyfill', './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',
options:{
presets: ['es2015']
},
include: [
resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client'),
resolve('src'), resolve('test'), resolve('node_modules/element-ui/src'),
resolve('src'), resolve('test'), resolve('node_modules/element-ui/packages'),
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
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)
}
})
})
'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)
}
})
})
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://192.168.31.231:8084',//设置你调用的接口域名和端口号 别忘了加http
changeOrigin: true,
pathRewrite: {
// '^/api': '' //这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'https://api.douban.com/user/add',直接写‘/api/user/add’即可,此处的‘api’可以设置为自己想要设置的任何词语,符合规范即可
}
}
},
// Various Dev Server settings
host: '127.0.0.1', // 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,
disableHostCheck: true,
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
}
}
'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: {
'/api': {
target: 'http://192.168.31.231:8084',//设置你调用的接口域名和端口号 别忘了加http
changeOrigin: true,
pathRewrite: {
// '^/api': '' //这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'https://api.douban.com/user/add',直接写‘/api/user/add’即可,此处的‘api’可以设置为自己想要设置的任何词语,符合规范即可
}
}
},
// Various Dev Server settings
host: '127.0.0.1', // 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,
disableHostCheck: true,
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
}
}
'use strict'
module.exports = {
NODE_ENV: '"production"'
}
'use strict'
module.exports = {
NODE_ENV: '"production"'
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title>建信招标采购平台</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title>建信招标采购平台</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
data: function () {
return {
}
}
}
</script>
<style lang="less">
#app {
display: flex;
min-width: 1200px;
flex-direction: column;
align-items: center;
background: #F8F8F8;
}
.about-code {
li {
width: 130px;
height: 130px;
margin: 0;
padding: 0;
}
}
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
data: function () {
return {
}
}
}
</script>
<style lang="less">
#app {
display: flex;
min-width: 1200px;
flex-direction: column;
align-items: center;
background: #F8F8F8;
}
.about-code {
li {
width: 130px;
height: 130px;
margin: 0;
padding: 0;
}
}
</style>
\ No newline at end of file
/* SAMCSS-layout */
.row {
display: flex;
flex-direction: row;
}
.col {
display: flex;
flex-direction: column;
}
.con-s {
justify-content: flex-start;
}
.con-c {
justify-content: center;
}
.con-e {
justify-content: flex-end;
}
.con-b {
justify-content: space-between;
}
.con-a {
justify-content: space-around;
}
.align-s {
align-items: flex-start;
}
.align-c {
align-items: center;
}
.align-e {
align-items: flex-end;
/* SAMCSS-layout */
.row {
display: flex;
flex-direction: row;
}
.col {
display: flex;
flex-direction: column;
}
.con-s {
justify-content: flex-start;
}
.con-c {
justify-content: center;
}
.con-e {
justify-content: flex-end;
}
.con-b {
justify-content: space-between;
}
.con-a {
justify-content: space-around;
}
.align-s {
align-items: flex-start;
}
.align-c {
align-items: center;
}
.align-e {
align-items: flex-end;
}
\ No newline at end of file
/*声明 WebFont*/
@font-face {
font-family: 'siyuanyahei';
src: url('../../assets/NotoSansHans-Light.ttf');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'siyuanyahei';
src: url('../../assets/NotoSansHans-Light.otf');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'siyuanyahei';
src: url('../../assets/NotoSansHans-Light.woff');
font-weight: normal;
font-style: normal;
}
html,body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
font-family: 'siyuanyahei', arial;
box-sizing: border-box !important;
margin: 0;
padding: 0;
}
input,
input:focus,
input:hover {
outline: none !important;
border-color: #dcdfe6 !important;
}
li {
list-style-type: none;
}
button {
outline: none !important;
/*声明 WebFont*/
@font-face {
font-family: 'siyuanyahei';
src: url('../../assets/NotoSansHans-Light.ttf');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'siyuanyahei';
src: url('../../assets/NotoSansHans-Light.otf');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'siyuanyahei';
src: url('../../assets/NotoSansHans-Light.woff');
font-weight: normal;
font-style: normal;
}
html,body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
font-family: 'siyuanyahei', arial;
box-sizing: border-box !important;
margin: 0;
padding: 0;
}
input,
input:focus,
input:hover {
outline: none !important;
border-color: #dcdfe6 !important;
}
li {
list-style-type: none;
}
button {
outline: none !important;
}
\ No newline at end of file
This diff could not be displayed because it is too large.
let output = {
/**
* 重新渲染表格
* 修复 element-ui table 不会跟随屏幕宽度自适应的问题
* @function
* @returns
*/
tableRender: function (funcVue, funcContainerWidth, funcTableItemWidth, funcTableItemWidthProportion) {
let funcWidth = 0
if (document.body.clientHeight > document.documentElement.clientHeight) {
funcWidth = funcContainerWidth / 100
} else {
funcWidth = (funcContainerWidth - 17) / 100
}
for (let i = 0, len = funcTableItemWidth.length; i < len; i++) {
funcTableItemWidth[i] = Math.floor(funcTableItemWidthProportion[i] * funcWidth)
}
funcVue.tableShow = true
},
}
let output = {
/**
* 重新渲染表格
* 修复 element-ui table 不会跟随屏幕宽度自适应的问题
* @function
* @returns
*/
tableRender: function (funcVue, funcContainerWidth, funcTableItemWidth, funcTableItemWidthProportion) {
let funcWidth = 0
if (document.body.clientHeight > document.documentElement.clientHeight) {
funcWidth = funcContainerWidth / 100
} else {
funcWidth = (funcContainerWidth - 17) / 100
}
for (let i = 0, len = funcTableItemWidth.length; i < len; i++) {
funcTableItemWidth[i] = Math.floor(funcTableItemWidthProportion[i] * funcWidth)
}
funcVue.tableShow = true
},
}
export default output
\ No newline at end of file
let output = {
sendType: 'json', // 数据发送方式
sendTypeEnumeration: [ 'params', 'json','form', 'formdata'],
method: 'post', // 请求方式
methodEnumeration: [ 'get', 'post' ],
timeout: 10000, // 超时设置
isToken: true, // 是否携带
isLog: true, // 是否打印请求相关信息
errorCode: [ 101 ],
}
let output = {
sendType: 'json', // 数据发送方式
sendTypeEnumeration: [ 'params', 'json','form', 'formdata'],
method: 'post', // 请求方式
methodEnumeration: [ 'get', 'post' ],
timeout: 10000, // 超时设置
isToken: true, // 是否携带
isLog: true, // 是否打印请求相关信息
errorCode: [ 101 ],
}
export default output
\ No newline at end of file
let output = function (funcParams, funcType) {
funcType = funcType.toLowerCase()
switch (funcType) {
case 'url':
if (JSON.stringify(funcParams) !== '{}') {
let funcQuery = '?'
Object.keys(funcParams).forEach((funcKey) => {
funcQuery = funcQuery + funcKey + '=' + funcParams[funcKey] + '&'
})
return funcQuery.substring(0, funcQuery.length - 1)
} else {
return ''
}
break
case 'json':
return JSON.stringify(funcParams)
break
case 'formdata':
let funcFormData = new FormData()
Object.keys(funcParams).forEach((funcKey) => {
funcFormData.append(funcKey, funcParams[funcKey])
})
return funcFormData
break
}
}
let output = function (funcParams, funcType) {
funcType = funcType.toLowerCase()
switch (funcType) {
case 'url':
if (JSON.stringify(funcParams) !== '{}') {
let funcQuery = '?'
Object.keys(funcParams).forEach((funcKey) => {
funcQuery = funcQuery + funcKey + '=' + funcParams[funcKey] + '&'
})
return funcQuery.substring(0, funcQuery.length - 1)
} else {
return ''
}
break
case 'json':
return JSON.stringify(funcParams)
break
case 'formdata':
let funcFormData = new FormData()
Object.keys(funcParams).forEach((funcKey) => {
funcFormData.append(funcKey, funcParams[funcKey])
})
return funcFormData
break
}
}
export default output
\ No newline at end of file
let output = function (funcXMLHttpRequest, funcConfigure) {
funcXMLHttpRequest.setRequestHeader('expires', '-10')
funcXMLHttpRequest.setRequestHeader('pragma', 'no-cache')
funcXMLHttpRequest.setRequestHeader('Cache-Control', 'no-cache')
switch (funcConfigure.sendType) {
case 'json':
funcXMLHttpRequest.setRequestHeader('Content-Type', 'application/json;')
break
case 'file':
funcXMLHttpRequest.setRequestHeader('Content-Type', 'multipart/form-data;')
break
case 'form':
funcXMLHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;')
break
case 'formdata':
// 浏览器自行设置表头
break
case 'params':
break
}
}
let output = function (funcXMLHttpRequest, funcConfigure) {
funcXMLHttpRequest.setRequestHeader('expires', '-10')
funcXMLHttpRequest.setRequestHeader('pragma', 'no-cache')
funcXMLHttpRequest.setRequestHeader('Cache-Control', 'no-cache')
switch (funcConfigure.sendType) {
case 'json':
funcXMLHttpRequest.setRequestHeader('Content-Type', 'application/json;')
break
case 'file':
funcXMLHttpRequest.setRequestHeader('Content-Type', 'multipart/form-data;')
break
case 'form':
funcXMLHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;')
break
case 'formdata':
// 浏览器自行设置表头
break
case 'params':
break
}
}
export default output
\ No newline at end of file
// 0630
let output = {
isInt: function (value, isZero) {
let regExp
if (isZero) {
regExp = new RegExp('^(0|[1-9][0-9]*)$')
} else {
regExp = new RegExp('^([1-9][0-9]*)$')
}
return regExp.test(value)
},
isMoney: function (value) {
let regExp = new RegExp('^[0-9]+(.[0-9]{1,2})?$')
return regExp.test(value)
},
isChinese: function (value) {
let regExp = new RegExp('[\u4e00-\u9fa5]+', 'ig')
return regExp.test(value)
},
isPhone: function (value) {
let regExp = new RegExp(/^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9]|19[0-9])[0-9]{8}$/, 'ig')
return regExp.test(value)
},
isFixedPhone: function (value) {
let regExp = new RegExp(/^\d{3}-\d{7,8}|\d{4}-\d{7,8}$/, 'ig')
return regExp.test(value)
}
}
// 0630
let output = {
isInt: function (value, isZero) {
let regExp
if (isZero) {
regExp = new RegExp('^(0|[1-9][0-9]*)$')
} else {
regExp = new RegExp('^([1-9][0-9]*)$')
}
return regExp.test(value)
},
isMoney: function (value) {
let regExp = new RegExp('^[0-9]+(.[0-9]{1,2})?$')
return regExp.test(value)
},
isChinese: function (value) {
let regExp = new RegExp('[\u4e00-\u9fa5]+', 'ig')
return regExp.test(value)
},
isPhone: function (value) {
let regExp = new RegExp(/^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9]|19[0-9])[0-9]{8}$/, 'ig')
return regExp.test(value)
},
isFixedPhone: function (value) {
let regExp = new RegExp(/^\d{3}-\d{7,8}|\d{4}-\d{7,8}$/, 'ig')
return regExp.test(value)
}
}
export default output
\ No newline at end of file
import iAtom from './atom.js'
let output = {
// 文本,除emoji符号
predefineRoutineText: function (rule, value, callback) {
let funcRegExp = new RegExp(/[\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]|\uD83D[\uDE80-\uDEFF]|[\u2700-\u27BF]\uFE0F]/, 'ig')
if (funcRegExp.test(value)) {
callback(new Error('不允许使用表情符号'))
return
}
callback()
},
// 文本,仅数字、英文字母(区分大小写)
predefineNumeralText: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[0-9a-z]+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
// 文本,仅数字
predefineNumeral: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[0-9]+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
email: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[.A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
idCard: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[1-9][0-9]{5}(18|19|20)[0-9]{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)[0-9]{3}[0-9Xx]$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
phone: function (rule, value, callback) {
let funcRegExp = new RegExp(/^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9]|19[0-9])[0-9]{8}$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
fixedPhone: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[0-9*#-]+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
phoneAndFixedPhone: function (rule, value, callback) {
if (!iAtom.isPhone(value) && !iAtom.isFixedPhone(value)) {
callback(new Error(rule.message))
return
}
callback()
},
password: function (rule, value, callback) {
let funcRegulation
let funcComplexity = 0
funcRegulation = /[0-9]+/ig
if (funcRegulation.test(value)) {
funcComplexity = funcComplexity + 1
}
funcRegulation = /[a-z]+/ig
if (funcRegulation.test(value)) {
funcComplexity = funcComplexity + 1
}
funcRegulation = /((?=[\x21-\x7e]+)[^A-Za-z0-9])/ig
if (funcRegulation.test(value)) {
funcComplexity = funcComplexity + 1
}
if (funcComplexity < 2) {
callback(new Error(rule.message))
return
}
callback()
},
passwordRepeat: function (rule, value, callback, password) {
if (value !== password) {
callback(new Error(rule.message))
return
}
callback()
},
unEmoji: function (rule, value, callback) {
let funcRegExp = new RegExp(/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/, 'ig')
if (funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
unSpace: function (rule, value, callback) {
let funcRegExp = new RegExp(/ /, 'ig')
if (funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
unChinese: function (rule, value, callback) {
let regExp = new RegExp('[\u4e00-\u9fa5]+', 'ig')
regExp.test(value) ? callback(new Error(rule.message)) : callback()
},
// 无符号正整数
signlessInteger: function (rule, value, callback) {
if (!iAtom.isInt(value, true)) {
callback(new Error(rule.message))
return
}
callback()
},
// 无符号非零正整数
signlessIntegerNonZero: function (rule, value, callback) {
if (!iAtom.isInt(value, false)) {
callback(new Error(rule.message))
return
}
callback()
}
}
import iAtom from './atom.js'
let output = {
// 文本,除emoji符号
predefineRoutineText: function (rule, value, callback) {
let funcRegExp = new RegExp(/[\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]|\uD83D[\uDE80-\uDEFF]|[\u2700-\u27BF]\uFE0F]/, 'ig')
if (funcRegExp.test(value)) {
callback(new Error('不允许使用表情符号'))
return
}
callback()
},
// 文本,仅数字、英文字母(区分大小写)
predefineNumeralText: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[0-9a-z]+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
// 文本,仅数字
predefineNumeral: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[0-9]+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
email: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[.A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
idCard: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[1-9][0-9]{5}(18|19|20)[0-9]{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)[0-9]{3}[0-9Xx]$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
phone: function (rule, value, callback) {
let funcRegExp = new RegExp(/^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9]|19[0-9])[0-9]{8}$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
fixedPhone: function (rule, value, callback) {
let funcRegExp = new RegExp(/^[0-9*#-]+$/, 'ig')
if (!funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
phoneAndFixedPhone: function (rule, value, callback) {
if (!iAtom.isPhone(value) && !iAtom.isFixedPhone(value)) {
callback(new Error(rule.message))
return
}
callback()
},
password: function (rule, value, callback) {
let funcRegulation
let funcComplexity = 0
funcRegulation = /[0-9]+/ig
if (funcRegulation.test(value)) {
funcComplexity = funcComplexity + 1
}
funcRegulation = /[a-z]+/ig
if (funcRegulation.test(value)) {
funcComplexity = funcComplexity + 1
}
funcRegulation = /((?=[\x21-\x7e]+)[^A-Za-z0-9])/ig
if (funcRegulation.test(value)) {
funcComplexity = funcComplexity + 1
}
if (funcComplexity < 2) {
callback(new Error(rule.message))
return
}
callback()
},
passwordRepeat: function (rule, value, callback, password) {
if (value !== password) {
callback(new Error(rule.message))
return
}
callback()
},
unEmoji: function (rule, value, callback) {
let funcRegExp = new RegExp(/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/, 'ig')
if (funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
unSpace: function (rule, value, callback) {
let funcRegExp = new RegExp(/ /, 'ig')
if (funcRegExp.test(value)) {
callback(new Error(rule.message))
return
}
callback()
},
unChinese: function (rule, value, callback) {
let regExp = new RegExp('[\u4e00-\u9fa5]+', 'ig')
regExp.test(value) ? callback(new Error(rule.message)) : callback()
},
// 无符号正整数
signlessInteger: function (rule, value, callback) {
if (!iAtom.isInt(value, true)) {
callback(new Error(rule.message))
return
}
callback()
},
// 无符号非零正整数
signlessIntegerNonZero: function (rule, value, callback) {
if (!iAtom.isInt(value, false)) {
callback(new Error(rule.message))
return
}
callback()
}
}
export default output
\ No newline at end of file
let output = function () {
return new Date()
// return 1590564000000
// return 1590654903000 // 2020-05-28 16:35:03
// return 1591778103000 // 2020-06-10 16:35:03
// return 1592469303000 // 2020-06-18 16:35:03
// return 1592728503000 // 2020-06-21 16:35:03
}
let output = function () {
return new Date()
// return 1590564000000
// return 1590654903000 // 2020-05-28 16:35:03
// return 1591778103000 // 2020-06-10 16:35:03
// return 1592469303000 // 2020-06-18 16:35:03
// return 1592728503000 // 2020-06-21 16:35:03
}
export default output
\ No newline at end of file
import iBase64 from 'js-base64';
let output = {
/**
* 提取令牌有效期限
* @function
* @param {event}
* @returns
*/
term: function (funcToken) {
let funcIndex = funcToken.indexOf('.') + 1
let funcDateBase = funcToken.substring(funcIndex)
funcIndex = funcDateBase.indexOf('.')
funcDateBase = funcDateBase.substring(0, funcIndex)
let funcDateInfo = iBase64.Base64.decode(funcDateBase)
let funcDateKey = '"exp":'
let funcDateString = funcDateInfo.substring(funcDateInfo.indexOf(funcDateKey) + funcDateKey.length, funcDateInfo.length)
funcDateString = funcDateString.substring(0, funcDateString.indexOf(','))
return Number(funcDateString)
},
/**
* 根据时间判断当前令牌状态
* @function
* @param {string} - funcToken
* @returns
*/
state: function (funcToken) {
let funcDate = output.term(funcToken)
let funcNowDate = Math.round(new Date() / 1000)
// 令牌有效
if (funcNowDate < funcDate) {
// 判断当前时间是否小于令牌期限
if (funcNowDate + 1200 < funcDate) {
// 令牌有效时间大于安全时间
console.log('[token] valid')
return 'valid'
} else {
console.log('[token] refresh')
return 'refresh'
}
}
// 令牌无效继续判断刷新令牌是否有效
funcDate = output.term(localStorage.getItem('refresh'))
// 令牌过期,刷新令牌有效需要重新登录
if (funcNowDate < funcDate) {
console.log('[token] relist')
return 'relist'
}
// 令牌过期,刷新令牌过期默认游客身份
if (funcNowDate > funcDate) {
console.log('[token] invalid')
return 'invalid'
}
},
}
import iBase64 from 'js-base64';
let output = {
/**
* 提取令牌有效期限
* @function
* @param {event}
* @returns
*/
term: function (funcToken) {
let funcIndex = funcToken.indexOf('.') + 1
let funcDateBase = funcToken.substring(funcIndex)
funcIndex = funcDateBase.indexOf('.')
funcDateBase = funcDateBase.substring(0, funcIndex)
let funcDateInfo = iBase64.Base64.decode(funcDateBase)
let funcDateKey = '"exp":'
let funcDateString = funcDateInfo.substring(funcDateInfo.indexOf(funcDateKey) + funcDateKey.length, funcDateInfo.length)
funcDateString = funcDateString.substring(0, funcDateString.indexOf(','))
return Number(funcDateString)
},
/**
* 根据时间判断当前令牌状态
* @function
* @param {string} - funcToken
* @returns
*/
state: function (funcToken) {
let funcDate = output.term(funcToken)
let funcNowDate = Math.round(new Date() / 1000)
// 令牌有效
if (funcNowDate < funcDate) {
// 判断当前时间是否小于令牌期限
if (funcNowDate + 1200 < funcDate) {
// 令牌有效时间大于安全时间
console.log('[token] valid')
return 'valid'
} else {
console.log('[token] refresh')
return 'refresh'
}
}
// 令牌无效继续判断刷新令牌是否有效
funcDate = output.term(localStorage.getItem('refresh'))
// 令牌过期,刷新令牌有效需要重新登录
if (funcNowDate < funcDate) {
console.log('[token] relist')
return 'relist'
}
// 令牌过期,刷新令牌过期默认游客身份
if (funcNowDate > funcDate) {
console.log('[token] invalid')
return 'invalid'
}
},
}
export default output
\ No newline at end of file
......@@ -46,7 +46,7 @@
<div class="record-info global-maxwidth row con-c align-c">
<span>©2020</span>
<span>建信发展(厦门)采购招标有限公司</span>
<span><a href="http://www.beian.miit.gov.cn/" target="view_window">备案号:闽ICP备18026805号-4</a></span>
<span><a href="https://beian.miit.gov.cn/" target="view_window">备案号:闽ICP备18026805号-4</a></span>
</div>
</div>
</template>
......
<template>
<!-- 通用组件 - 侧边菜单 -->
<div class="components-navigation-top">
</div>
</template>
<script>
export default {
name: 'componentsNavigationTop',
data () {
return {
formSignIn: {
account: '', // 账号
password: '', // 密码
code: '' // 动态密令
},
rule: {
account: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
],
password: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
code: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
]
}
}
}
}
</script>
<style lang="less">
</style>
<template>
<!-- 通用组件 - 侧边菜单 -->
<div class="components-navigation-top">
</div>
</template>
<script>
export default {
name: 'componentsNavigationTop',
data () {
return {
formSignIn: {
account: '', // 账号
password: '', // 密码
code: '' // 动态密令
},
rule: {
account: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
],
password: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
code: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
]
}
}
}
}
</script>
<style lang="less">
</style>
<template>
<!-- 信息模板 - 相关公告 -->
<div class="components-relation col con-b">
<div class="list">
<div class="item global-overflow-ellipsis" v-for="(item, index) in noticeBuffer" :key="index">
<span class="global-cursor" @click="onBidDetails(item)">{{item.title}}</span>
</div>
</div>
<div class="pagination row con-c align-c">
<div class="current row con-c align-c" v-for="(item, index) in noticeTotal" :key="index" @click="onPagination(index, 'current', searchOtherNotice)">
<div :class="index === searchOtherNotice.current ? 'active' : 'unactive'"></div>
</div>
</div>
</div>
</template>
<script>
import iFramePagination from '@/common/frame/pagination/pagination.js'
export default {
data () {
return {
noticeTotal: 1,
noticeBuffer: [],
searchOtherNotice: {
size: 8,
total: 0,
current: 0,
}
}
},
computed: {
componentNotice: function () {
return this.$store.state.componentNotice
},
},
watch: {
componentNotice: {
handler: function (funcNewValue, funcOldValue) {
this.setNotice()
},
deep: true,
immediate: true,
}
},
created: function () {
this.setNotice()
},
methods: {
setNotice: function () {
let funcSize = this.searchOtherNotice.size
let funcIndex = this.searchOtherNotice.current
this.noticeBuffer = []
this.noticeTotal = Math.ceil(this.componentNotice.length / this.searchOtherNotice.size)
for (let i = funcSize * funcIndex, len = funcSize * (funcIndex + 1); i < len; i++) {
if (this.componentNotice[i]) {
this.noticeBuffer.push(this.componentNotice[i])
}
}
},
onBidDetails: function (funcItem) {
this.$router.replace('/bid/notice?type=' + funcItem.type + '&id=' + funcItem.id)
},
onPagination: function (funcValue, funcType, funcUpdateObject) {
iFramePagination(funcValue, funcType, funcUpdateObject)
this.setNotice()
},
}
}
</script>
<style lang="less">
.components-relation {
width: 100%;
height: 200px;
.list {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 50%;
margin-bottom: 20px;
padding-right: 30px;
font-size: @fontSize01;
::before {
content: '·';
display: inline-block;
width: 4px;
height: 4px;
margin-right: 8px;
}
}
}
.pagination {
.current {
width: 20px;
height: 20px;
> div {
width: 8px;
height: 8px;
border-radius: 50%;
}
}
.active {
background: #CF2F1E;
}
.unactive {
background: #00468C;
}
}
}
</style>
<template>
<!-- 信息模板 - 相关公告 -->
<div class="components-relation col con-b">
<div class="list">
<div class="item global-overflow-ellipsis" v-for="(item, index) in noticeBuffer" :key="index">
<span class="global-cursor" @click="onBidDetails(item)">{{item.title}}</span>
</div>
</div>
<div class="pagination row con-c align-c">
<div class="current row con-c align-c" v-for="(item, index) in noticeTotal" :key="index" @click="onPagination(index, 'current', searchOtherNotice)">
<div :class="index === searchOtherNotice.current ? 'active' : 'unactive'"></div>
</div>
</div>
</div>
</template>
<script>
import iFramePagination from '@/common/frame/pagination/pagination.js'
export default {
data () {
return {
noticeTotal: 1,
noticeBuffer: [],
searchOtherNotice: {
size: 8,
total: 0,
current: 0,
}
}
},
computed: {
componentNotice: function () {
return this.$store.state.componentNotice
},
},
watch: {
componentNotice: {
handler: function (funcNewValue, funcOldValue) {
this.setNotice()
},
deep: true,
immediate: true,
}
},
created: function () {
this.setNotice()
},
methods: {
setNotice: function () {
let funcSize = this.searchOtherNotice.size
let funcIndex = this.searchOtherNotice.current
this.noticeBuffer = []
this.noticeTotal = Math.ceil(this.componentNotice.length / this.searchOtherNotice.size)
for (let i = funcSize * funcIndex, len = funcSize * (funcIndex + 1); i < len; i++) {
if (this.componentNotice[i]) {
this.noticeBuffer.push(this.componentNotice[i])
}
}
},
onBidDetails: function (funcItem) {
this.$router.replace('/bid/notice?type=' + funcItem.type + '&id=' + funcItem.id)
},
onPagination: function (funcValue, funcType, funcUpdateObject) {
iFramePagination(funcValue, funcType, funcUpdateObject)
this.setNotice()
},
}
}
</script>
<style lang="less">
.components-relation {
width: 100%;
height: 200px;
.list {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
.item {
width: 50%;
margin-bottom: 20px;
padding-right: 30px;
font-size: @fontSize01;
::before {
content: '·';
display: inline-block;
width: 4px;
height: 4px;
margin-right: 8px;
}
}
}
.pagination {
.current {
width: 20px;
height: 20px;
> div {
width: 8px;
height: 8px;
border-radius: 50%;
}
}
.active {
background: #CF2F1E;
}
.unactive {
background: #00468C;
}
}
}
</style>
const output = {
urlFormat: function (value) {
if (!value) return value
let funcRegExp = new RegExp('^(https://)|(http://)', 'i')
if (!funcRegExp.test(value)) {
value = 'http://' + value
}
console.log('[filter]', value)
return value
}
}
const output = {
urlFormat: function (value) {
if (!value) return value
let funcRegExp = new RegExp('^(https://)|(http://)', 'i')
if (!funcRegExp.test(value)) {
value = 'http://' + value
}
console.log('[filter]', value)
return value
}
}
export default output
\ No newline at end of file
import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
import store from './store/store.js'
import filter from './filter/filter.js'
import router from './router/router.js'
Object.keys(filter).forEach(key => {
Vue.filter(key, filter[key])
})
import ElementUi from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './common/css/reset.css'
import './common/css/flex.css'
Vue.use(ElementUi)
Vue.config.productionTip = false
/* eslint-disable no-new */
let output = new Vue({
'el': '#app',
'store': store,
'router': router,
'components': { App },
'template': '<App/>'
})
import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
import store from './store/store.js'
import filter from './filter/filter.js'
import router from './router/router.js'
Object.keys(filter).forEach(key => {
Vue.filter(key, filter[key])
})
import ElementUi from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './common/css/reset.css'
import './common/css/flex.css'
Vue.use(ElementUi)
Vue.config.productionTip = false
/* eslint-disable no-new */
let output = new Vue({
'el': '#app',
'store': store,
'router': router,
'components': { App },
'template': '<App/>'
})
export default output
\ No newline at end of file
localStorage
请求令牌 - {string} token: ''
刷新令牌 - {string} refresh: ''
专家登录信息 - {object} signInInfo: {} | { phone: '', password: '' }
供应登录信息 - {object} signInInfo: {} | { phone: '', password: '' }
登录身份 - {string} identity: '' - 1 - 专家, 2 - 供应商
注册状态 - {string} register: '' - 0 - 审核中, 1 - 通过, 2 - 不通过
localStorage
请求令牌 - {string} token: ''
刷新令牌 - {string} refresh: ''
专家登录信息 - {object} signInInfo: {} | { phone: '', password: '' }
供应登录信息 - {object} signInInfo: {} | { phone: '', password: '' }
登录身份 - {string} identity: '' - 1 - 专家, 2 - 供应商
注册状态 - {string} register: '' - 0 - 审核中, 1 - 通过, 2 - 不通过
sessionStorage
\ No newline at end of file
<template>
<div class="not-found">
<span>404</span>
</div>
</template>
<script>
import iRule from '@/common/js/request/request.js'
import iRequest from '@/common/js/request/request.js'
export default {
components: {},
data: function () {
return {
}
},
created: function () {
this.$router.push('/')
},
watch: {},
methods: {},
}
</script>
<style lang="less">
</style>
<template>
<div class="not-found">
<span>404</span>
</div>
</template>
<script>
import iRule from '@/common/js/request/request.js'
import iRequest from '@/common/js/request/request.js'
export default {
components: {},
data: function () {
return {
}
},
created: function () {
this.$router.push('/')
},
watch: {},
methods: {},
}
</script>
<style lang="less">
</style>
<template>
<div class="about col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<div class="about-banner row con-c align-c">
<img src="../assets/about.png" alt="">
</div>
<div class="global-maxwidth about-us row con-c">
<div class="about-us-info">
<p><span>厦门建发集团有限公司</span>系厦门市属国有企业,创立于1980年12月,经过三十多年的创新与变革,公司已发展成为注册资本65.5亿元、年营业收入超过2800亿元、资产总额超过2500亿元的大型实业投资企业集团,业务涵盖供应链运营、房地产开发、旅游酒店、会展业、医疗、投资等,排名2019年度《财富》"世界500强"第277位、2019中国企业500强第71位、中国服务业500强第39位。</p>
<p>今后集团将通过扩大现有核心产业的投资、适度增强现有新兴产业投资、积极对现有其他投资企业进行资本运作,并尝试一些新领域投资,将采取传统产业项目与高科技项目相结合、产业投资与战略投资、风险投资相结合、独立投资经营与合资合作相结合的策略,促进重点领域核心竞争力的形成与升级,实现投资收益的较大增长和核心产业品牌增值,促使集团稳步发展。</p>
<p><span>地址:厦门市思明区创想中心A座1801单元</span></p>
<p><span>电话:0592-5859311</span></p>
</div>
<div class="about-us-amp">
<img src="../assets/about-map.png" alt="">
</div>
</div>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter,
},
data: function () {
return {
}
}
}
</script>
<style lang="less">
.about {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
.about-banner {
align-items: center;
flex-direction: column;
max-width: 100%;
width: 100%;
overflow: hidden;
img {
height: 400px;
}
}
.about-us {
width: 1200px;
height: 508px;
margin: 50px 0;
padding: 54px 44px 54px 32px;
background: @colorWhite;
box-shadow: 0px 0px 20px 0px rgba(41, 41, 41, 0.05);
.about-us-info {
margin-right: 26px;
> p {
margin-bottom: 8px;
line-height: 2.0;
font-size: @fontSize02;
color: @colorGrey60;
text-indent: 2em;
span {
color: @colorGrey00;
}
}
}
}
.bm-view {
width: 100%;
height: 300px;
}
}
<template>
<div class="about col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<div class="about-banner row con-c align-c">
<img src="../assets/about.png" alt="">
</div>
<div class="global-maxwidth about-us row con-c">
<div class="about-us-info">
<p><span>厦门建发集团有限公司</span>系厦门市属国有企业,创立于1980年12月,经过三十多年的创新与变革,公司已发展成为注册资本65.5亿元、年营业收入超过2800亿元、资产总额超过2500亿元的大型实业投资企业集团,业务涵盖供应链运营、房地产开发、旅游酒店、会展业、医疗、投资等,排名2019年度《财富》"世界500强"第277位、2019中国企业500强第71位、中国服务业500强第39位。</p>
<p>今后集团将通过扩大现有核心产业的投资、适度增强现有新兴产业投资、积极对现有其他投资企业进行资本运作,并尝试一些新领域投资,将采取传统产业项目与高科技项目相结合、产业投资与战略投资、风险投资相结合、独立投资经营与合资合作相结合的策略,促进重点领域核心竞争力的形成与升级,实现投资收益的较大增长和核心产业品牌增值,促使集团稳步发展。</p>
<p><span>地址:厦门市思明区创想中心A座1801单元</span></p>
<p><span>电话:0592-5859311</span></p>
</div>
<div class="about-us-amp">
<img src="../assets/about-map.png" alt="">
</div>
</div>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter,
},
data: function () {
return {
}
}
}
</script>
<style lang="less">
.about {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
.about-banner {
align-items: center;
flex-direction: column;
max-width: 100%;
width: 100%;
overflow: hidden;
img {
height: 400px;
}
}
.about-us {
width: 1200px;
height: 508px;
margin: 50px 0;
padding: 54px 44px 54px 32px;
background: @colorWhite;
box-shadow: 0px 0px 20px 0px rgba(41, 41, 41, 0.05);
.about-us-info {
margin-right: 26px;
> p {
margin-bottom: 8px;
line-height: 2.0;
font-size: @fontSize02;
color: @colorGrey60;
text-indent: 2em;
span {
color: @colorGrey00;
}
}
}
}
.bm-view {
width: 100%;
height: 300px;
}
}
</style>
\ No newline at end of file
<template>
<div class="public-information">
<span>public-information</span>
</div>
</template>
<script>
export default {
name: 'publicInformation'
}
</script>
<style lang="less">
<template>
<div class="public-information">
<span>public-information</span>
</div>
</template>
<script>
export default {
name: 'publicInformation'
}
</script>
<style lang="less">
</style>
\ No newline at end of file
<template>
<!-- 用户中心组件 - 侧边菜单 -->
<div class="components-personal-sidebar row con-b align-c">
<el-menu class="sidebar" @select="onSelectItem">
<el-menu-item v-if="info ? info.register === 1 : true" index="1">
<span slot="title">工作台首页</span>
</el-menu-item>
<el-submenu v-if="info ? info.register === 1 : true" index="2">
<template slot="title">
<span>投标管理</span>
</template>
<el-menu-item index="2-1">我投标的项目</el-menu-item>
<el-menu-item index="2-2">我竞价的项目</el-menu-item>
</el-submenu>
<el-menu-item v-if="info ? info.register === 1 : true" index="3">
<span slot="title">我的订单</span>
</el-menu-item>
<el-submenu index="4">
<template slot="title">
<span>账号管理</span>
</template>
<el-menu-item index="4-1">企业信息</el-menu-item>
<el-menu-item index="4-2">更换手机号码</el-menu-item>
<el-menu-item index="4-3">修改登录密码</el-menu-item>
</el-submenu>
</el-menu>
</div>
</template>
<script>
export default {
data: function () {
return {
}
},
computed: {
info: function () {
return this.$store.state.info
},
},
watch: {
info: {
handler: function (funcNewValue, funcOldValue) {
},
deep: true,
immediate: true,
},
},
methods: {
onSelectItem: function (funcIndex) {
switch (funcIndex) {
case '1':
this.$router.push('/supplier')
break
case '2-1':
this.$router.push('/supplier/bidding')
break
case '2-2':
this.$router.push('/supplier/auction')
break
case '3':
this.$router.push('/supplier/orders')
break
case '4-1':
this.$router.push('/supplier/info')
break
case '4-2':
this.$router.push('/supplier/infophone')
break
case '4-3':
this.$router.push('/supplier/infopassword')
break
}
},
}
}
</script>
<style lang="less">
.components-personal-sidebar {
.sidebar {
width: 220px;
height: 100%;
min-height: 908px;
background: #FBFBFB;
border: 1px solid #EFEFEF;
.el-menu-item {
height: 50px;
}
div,
ul,
li {
background: #FBFBFB;
}
}
}
</style>
<template>
<!-- 用户中心组件 - 侧边菜单 -->
<div class="components-personal-sidebar row con-b align-c">
<el-menu class="sidebar" @select="onSelectItem">
<el-menu-item v-if="info ? info.register === 1 : true" index="1">
<span slot="title">工作台首页</span>
</el-menu-item>
<el-submenu v-if="info ? info.register === 1 : true" index="2">
<template slot="title">
<span>投标管理</span>
</template>
<el-menu-item index="2-1">我投标的项目</el-menu-item>
<el-menu-item index="2-2">我竞价的项目</el-menu-item>
</el-submenu>
<el-menu-item v-if="info ? info.register === 1 : true" index="3">
<span slot="title">我的订单</span>
</el-menu-item>
<el-submenu index="4">
<template slot="title">
<span>账号管理</span>
</template>
<el-menu-item index="4-1">企业信息</el-menu-item>
<el-menu-item index="4-2">更换手机号码</el-menu-item>
<el-menu-item index="4-3">修改登录密码</el-menu-item>
</el-submenu>
</el-menu>
</div>
</template>
<script>
export default {
data: function () {
return {
}
},
computed: {
info: function () {
return this.$store.state.info
},
},
watch: {
info: {
handler: function (funcNewValue, funcOldValue) {
},
deep: true,
immediate: true,
},
},
methods: {
onSelectItem: function (funcIndex) {
switch (funcIndex) {
case '1':
this.$router.push('/supplier')
break
case '2-1':
this.$router.push('/supplier/bidding')
break
case '2-2':
this.$router.push('/supplier/auction')
break
case '3':
this.$router.push('/supplier/orders')
break
case '4-1':
this.$router.push('/supplier/info')
break
case '4-2':
this.$router.push('/supplier/infophone')
break
case '4-3':
this.$router.push('/supplier/infopassword')
break
}
},
}
}
</script>
<style lang="less">
.components-personal-sidebar {
.sidebar {
width: 220px;
height: 100%;
min-height: 908px;
background: #FBFBFB;
border: 1px solid #EFEFEF;
.el-menu-item {
height: 50px;
}
div,
ul,
li {
background: #FBFBFB;
}
}
}
</style>
<template>
<!-- 用户中心 -->
<div class="supplier">
<componentHeader></componentHeader>
<div class="row">
<componentSidebar></componentSidebar>
<div class="main">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import iRule from '@/common/js/request/request.js'
import iRequest from '@/common/js/request/request.js'
import iHeader from './component/personal-header.vue'
import iSidebar from './component/personal-sidebar.vue'
export default {
components: {
componentHeader: iHeader,
componentSidebar: iSidebar,
},
data: function () {
return {
// 仅能访问的受限页面
authorityLimit: [
'/supplier/info',
'/supplier/infochange',
'/supplier/inforecord',
'/supplier/infophone',
'/supplier/infopassword',
'/supplier/notify',
]
}
},
computed: {
info: function () {
return this.$store.state.info
},
},
watch: {
info: {
handler: function (funcNewValue, funcOldValue) {
},
deep: true,
immediate: true,
},
$route: {
handler: function (funcNewValue, funcOldValue) {
this.authority(funcNewValue.fullPath)
},
deep: true,
immediate: true,
},
},
methods: {
authority: function (funcPath) {
if (!this.info) return
switch(this.info.register) {
// 注册账号未通过初审
case 0:
if (this.authorityLimit.indexOf(funcPath) === -1) {
this.$router.push('/supplier/info')
}
break
}
},
},
}
</script>
<style lang="less">
.supplier {
width: 100%;
background: #FFFFFF;
.main {
position: relative;
width: 100%;
padding: 0 32px;
}
}
</style>
<template>
<!-- 用户中心 -->
<div class="supplier">
<componentHeader></componentHeader>
<div class="row">
<componentSidebar></componentSidebar>
<div class="main">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import iRule from '@/common/js/request/request.js'
import iRequest from '@/common/js/request/request.js'
import iHeader from './component/personal-header.vue'
import iSidebar from './component/personal-sidebar.vue'
export default {
components: {
componentHeader: iHeader,
componentSidebar: iSidebar,
},
data: function () {
return {
// 仅能访问的受限页面
authorityLimit: [
'/supplier/info',
'/supplier/infochange',
'/supplier/inforecord',
'/supplier/infophone',
'/supplier/infopassword',
'/supplier/notify',
]
}
},
computed: {
info: function () {
return this.$store.state.info
},
},
watch: {
info: {
handler: function (funcNewValue, funcOldValue) {
},
deep: true,
immediate: true,
},
$route: {
handler: function (funcNewValue, funcOldValue) {
this.authority(funcNewValue.fullPath)
},
deep: true,
immediate: true,
},
},
methods: {
authority: function (funcPath) {
if (!this.info) return
switch(this.info.register) {
// 注册账号未通过初审
case 0:
if (this.authorityLimit.indexOf(funcPath) === -1) {
this.$router.push('/supplier/info')
}
break
}
},
},
}
</script>
<style lang="less">
.supplier {
width: 100%;
background: #FFFFFF;
.main {
position: relative;
width: 100%;
padding: 0 32px;
}
}
</style>
<template>
<div class="public-bid col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-bid {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
<template>
<div class="public-bid col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-bid {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
</style>
\ No newline at end of file
<template>
<div class="public-help col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-help {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
<template>
<div class="public-help col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-help {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
</style>
\ No newline at end of file
<template>
<div class="public-policy-details col align-c">
<div class="title row con-c align-c">
<div class="global-maxwidth">
<span>政策法规</span>
</div>
</div>
<div class="main global-maxwidth">
<!-- 页面地图 -->
<div>
<currencyMap></currencyMap>
</div>
<div class="info-title col align-c">
<span>{{title}}</span>
<span>{{'发布时间:' + releaseTime}}</span>
</div>
<!-- 政策法规 -->
<div class="info-item content">
<div v-html="content"></div>
</div>
</div>
</div>
</template>
<script>
import iMiment from 'miment'
import iHost from '@/common/js/host.js'
import iRequest from '@/common/js/request/request.js'
import iCurrencyMap from '@/components/currency-map.vue'
export default {
components: {
currencyMap: iCurrencyMap
},
data: function () {
return {
title: '',
releaseTime: '',
content: ''
}
},
created: function () {
this.initInfoDetails()
this.$store.commit('redirectPath', this.$route.fullPath)
},
methods: {
initInfoDetails: function () {
let funcParam = {
'id': this.$route.query.id
}
iRequest.request(iHost.base + 'bid/zPolicy/detail', funcParam, 'json', 'post')
.then((funcResponse) => {
this.title = this.content = funcResponse.zPolicy.title
this.releaseTime = iMiment(funcResponse.zPolicy.releaseTime).format('YYYY-MM-DD hh:mm')
this.content = funcResponse.zPolicy.content
})
.catch((funcError) => {
this.$message.error(funcError.message)
})
}
}
}
</script>
<style lang="less">
.public-policy-details {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
.title {
width: 100%;
height: 90px;
background-image: url(../../assets/bg-title.png);
background-repeat: no-repeat;
span {
font-size: @fontSize06;
color: @colorWhite;
}
}
.main {
min-height: 400px;
margin: 36px 0;
padding: 32px 32px 0 32px;
background: @colorWhite;
box-shadow:0px 0px 20px 0px rgba(41,41,41,0.05);
.info-title {
margin: 30px 0;
padding-bottom: 38px;
border-bottom: 1px @colorGrey90 solid;
> span:nth-child(1) {
font-size: @fontSize06;
}
> span:nth-child(2) {
margin-top: 14px;
color: @colorGrey40;
font-size: @fontSize01;
}
}
.info-item {
margin-bottom: 54px;
}
.content {
overflow: hidden;
line-height: 1.5;
// 对应后台富文本编辑边框样式
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
text-align: center;
}
td {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
}
}
}
}
<template>
<div class="public-policy-details col align-c">
<div class="title row con-c align-c">
<div class="global-maxwidth">
<span>政策法规</span>
</div>
</div>
<div class="main global-maxwidth">
<!-- 页面地图 -->
<div>
<currencyMap></currencyMap>
</div>
<div class="info-title col align-c">
<span>{{title}}</span>
<span>{{'发布时间:' + releaseTime}}</span>
</div>
<!-- 政策法规 -->
<div class="info-item content">
<div v-html="content"></div>
</div>
</div>
</div>
</template>
<script>
import iMiment from 'miment'
import iHost from '@/common/js/host.js'
import iRequest from '@/common/js/request/request.js'
import iCurrencyMap from '@/components/currency-map.vue'
export default {
components: {
currencyMap: iCurrencyMap
},
data: function () {
return {
title: '',
releaseTime: '',
content: ''
}
},
created: function () {
this.initInfoDetails()
this.$store.commit('redirectPath', this.$route.fullPath)
},
methods: {
initInfoDetails: function () {
let funcParam = {
'id': this.$route.query.id
}
iRequest.request(iHost.base + 'bid/zPolicy/detail', funcParam, 'json', 'post')
.then((funcResponse) => {
this.title = this.content = funcResponse.zPolicy.title
this.releaseTime = iMiment(funcResponse.zPolicy.releaseTime).format('YYYY-MM-DD hh:mm')
this.content = funcResponse.zPolicy.content
})
.catch((funcError) => {
this.$message.error(funcError.message)
})
}
}
}
</script>
<style lang="less">
.public-policy-details {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
.title {
width: 100%;
height: 90px;
background-image: url(../../assets/bg-title.png);
background-repeat: no-repeat;
span {
font-size: @fontSize06;
color: @colorWhite;
}
}
.main {
min-height: 400px;
margin: 36px 0;
padding: 32px 32px 0 32px;
background: @colorWhite;
box-shadow:0px 0px 20px 0px rgba(41,41,41,0.05);
.info-title {
margin: 30px 0;
padding-bottom: 38px;
border-bottom: 1px @colorGrey90 solid;
> span:nth-child(1) {
font-size: @fontSize06;
}
> span:nth-child(2) {
margin-top: 14px;
color: @colorGrey40;
font-size: @fontSize01;
}
}
.info-item {
margin-bottom: 54px;
}
.content {
overflow: hidden;
line-height: 1.5;
// 对应后台富文本编辑边框样式
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
text-align: center;
}
td {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="public-bid col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-bid {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
<template>
<div class="public-bid col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-bid {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
</style>
\ No newline at end of file
<template>
<div class="public-question col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-question {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
<template>
<div class="public-question col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-question {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
</style>
\ No newline at end of file
<template>
<div class="public-trends-details col align-c">
<div class="title row con-c align-c">
<div class="global-maxwidth">
<span>招标动态</span>
</div>
</div>
<div class="main global-maxwidth">
<!-- 页面地图 -->
<div>
<currencyMap></currencyMap>
</div>
<div class="info-title col align-c">
<span>{{title}}</span>
<span>{{'发布时间:' + releaseTime}}</span>
</div>
<!-- 政策法规 -->
<div class="info-item content">
<div v-html="content"></div>
</div>
</div>
</div>
</template>
<script>
import iMiment from 'miment'
import iHost from '@/common/js/host.js'
import iRequest from '@/common/js/request/request.js'
import iCurrencyMap from '@/components/currency-map.vue'
export default {
components: {
currencyMap: iCurrencyMap
},
data: function () {
return {
title: '',
releaseTime: '',
content: ''
}
},
created: function () {
this.initInfoDetails()
this.$store.commit('redirectPath', this.$route.fullPath)
},
methods: {
initInfoDetails: function () {
let funcParam = {
'id': this.$route.query.id
}
iRequest.request(iHost.base + 'bid/zTenderDynamic/detail', funcParam, 'json', 'post')
.then((funcResponse) => {
this.title = this.content = funcResponse.zTenderDynamic.title
this.releaseTime = iMiment(funcResponse.zTenderDynamic.releaseTime).format('YYYY-MM-DD hh:mm')
this.content = funcResponse.zTenderDynamic.content
})
.catch((funcError) => {
this.$message.error(funcError.message)
})
}
}
}
</script>
<style lang="less">
.public-trends-details {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
.title {
width: 100%;
height: 90px;
background-image: url(../../assets/bg-title.png);
background-repeat: no-repeat;
span {
font-size: @fontSize06;
color: @colorWhite;
}
}
.main {
min-height: 400px;
margin: 36px 0;
padding: 32px 32px 0 32px;
background: @colorWhite;
box-shadow: 0px 0px 20px 0px rgba(41, 41, 41, 0.05);
.info-title {
margin: 30px 0;
padding-bottom: 38px;
border-bottom: 1px @colorGrey90 solid;
> span:nth-child(1) {
font-size: @fontSize06;
}
> span:nth-child(2) {
margin-top: 14px;
color: @colorGrey40;
font-size: @fontSize01;
}
}
.info-item {
margin-bottom: 54px;
}
.content {
overflow: hidden;
// 对应后台富文本编辑边框样式
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
text-align: center;
}
td {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
}
}
}
}
<template>
<div class="public-trends-details col align-c">
<div class="title row con-c align-c">
<div class="global-maxwidth">
<span>招标动态</span>
</div>
</div>
<div class="main global-maxwidth">
<!-- 页面地图 -->
<div>
<currencyMap></currencyMap>
</div>
<div class="info-title col align-c">
<span>{{title}}</span>
<span>{{'发布时间:' + releaseTime}}</span>
</div>
<!-- 政策法规 -->
<div class="info-item content">
<div v-html="content"></div>
</div>
</div>
</div>
</template>
<script>
import iMiment from 'miment'
import iHost from '@/common/js/host.js'
import iRequest from '@/common/js/request/request.js'
import iCurrencyMap from '@/components/currency-map.vue'
export default {
components: {
currencyMap: iCurrencyMap
},
data: function () {
return {
title: '',
releaseTime: '',
content: ''
}
},
created: function () {
this.initInfoDetails()
this.$store.commit('redirectPath', this.$route.fullPath)
},
methods: {
initInfoDetails: function () {
let funcParam = {
'id': this.$route.query.id
}
iRequest.request(iHost.base + 'bid/zTenderDynamic/detail', funcParam, 'json', 'post')
.then((funcResponse) => {
this.title = this.content = funcResponse.zTenderDynamic.title
this.releaseTime = iMiment(funcResponse.zTenderDynamic.releaseTime).format('YYYY-MM-DD hh:mm')
this.content = funcResponse.zTenderDynamic.content
})
.catch((funcError) => {
this.$message.error(funcError.message)
})
}
}
}
</script>
<style lang="less">
.public-trends-details {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
.title {
width: 100%;
height: 90px;
background-image: url(../../assets/bg-title.png);
background-repeat: no-repeat;
span {
font-size: @fontSize06;
color: @colorWhite;
}
}
.main {
min-height: 400px;
margin: 36px 0;
padding: 32px 32px 0 32px;
background: @colorWhite;
box-shadow: 0px 0px 20px 0px rgba(41, 41, 41, 0.05);
.info-title {
margin: 30px 0;
padding-bottom: 38px;
border-bottom: 1px @colorGrey90 solid;
> span:nth-child(1) {
font-size: @fontSize06;
}
> span:nth-child(2) {
margin-top: 14px;
color: @colorGrey40;
font-size: @fontSize01;
}
}
.info-item {
margin-bottom: 54px;
}
.content {
overflow: hidden;
// 对应后台富文本编辑边框样式
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
text-align: center;
}
td {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="public-trends col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-trends {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
<template>
<div class="public-trends col align-c">
<componentHeader></componentHeader>
<componentNavigation></componentNavigation>
<router-view></router-view>
<componentFooter></componentFooter>
</div>
</template>
<script>
import iHeader from '@/components/currency-header.vue'
import iNavigation from '@/components/currency-navigation.vue'
import iFooter from '@/components/currency-footer.vue'
export default {
components: {
componentHeader: iHeader,
componentNavigation: iNavigation,
componentFooter: iFooter
},
data: function () {
return {
}
},
methods: {
}
}
</script>
<style lang="less">
.public-trends {
width: 100%;
background-image: url(@backgroundImageUrl);
background-repeat: no-repeat;
}
</style>
\ No newline at end of file
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment