Browse Source

第N版绿谷

master
aBin 5 years ago
parent
commit
3da7124f30
  1. 12
      .babelrc
  2. 3
      .browserslistrc
  3. 9
      .editorconfig
  4. 3
      .env
  5. 10
      .env.development
  6. 10
      .env.production
  7. 4
      .eslintignore
  8. 64
      .eslintrc.js
  9. 13
      .gitignore
  10. 10
      .postcssrc.js
  11. 13
      .prettierrc
  12. 33
      README.md
  13. 13
      babel.config.js
  14. 41
      build/build.js
  15. 54
      build/check-versions.js
  16. BIN
      build/logo.png
  17. 101
      build/utils.js
  18. 22
      build/vue-loader.conf.js
  19. 92
      build/webpack.base.conf.js
  20. 95
      build/webpack.dev.conf.js
  21. 145
      build/webpack.prod.conf.js
  22. 1
      commitlint.config.js
  23. 7
      config/dev.env.js
  24. 45
      config/index.js
  25. 4
      config/prod.env.js
  26. 13
      index.html
  27. 18979
      package-lock.json
  28. 119
      package.json
  29. BIN
      public/favicon.ico
  30. BIN
      public/img/icons/android-chrome-192x192.png
  31. BIN
      public/img/icons/android-chrome-512x512.png
  32. BIN
      public/img/icons/android-chrome-maskable-192x192.png
  33. BIN
      public/img/icons/android-chrome-maskable-512x512.png
  34. BIN
      public/img/icons/apple-touch-icon-120x120.png
  35. BIN
      public/img/icons/apple-touch-icon-152x152.png
  36. BIN
      public/img/icons/apple-touch-icon-180x180.png
  37. BIN
      public/img/icons/apple-touch-icon-60x60.png
  38. BIN
      public/img/icons/apple-touch-icon-76x76.png
  39. BIN
      public/img/icons/apple-touch-icon.png
  40. BIN
      public/img/icons/favicon-16x16.png
  41. BIN
      public/img/icons/favicon-32x32.png
  42. BIN
      public/img/icons/msapplication-icon-144x144.png
  43. BIN
      public/img/icons/mstile-150x150.png
  44. 3
      public/img/icons/safari-pinned-tab.svg
  45. 17
      public/index.html
  46. 2
      public/robots.txt
  47. 15
      rest/http-client.env.json
  48. 56
      rest/project.http
  49. 122
      src/App.vue
  50. 79
      src/api/axios.js
  51. 16
      src/api/getData.js
  52. BIN
      src/assets/erweima.png
  53. 28
      src/assets/icon/iconfont.css
  54. BIN
      src/assets/icon/iconfont.eot
  55. 8
      src/assets/icon/iconfont.svg
  56. BIN
      src/assets/icon/iconfont.ttf
  57. BIN
      src/assets/icon/iconfont.woff
  58. BIN
      src/assets/logo.png
  59. BIN
      src/assets/lvgu.png
  60. 244
      src/common/portrait.styl
  61. 20
      src/components/Community.vue
  62. 115
      src/components/Demand.vue
  63. 140
      src/components/Footer.vue
  64. 15
      src/components/FooterPage/FooterPage.vue
  65. 27
      src/components/FooterPage/FriendShip.vue
  66. 198
      src/components/HeadNav/HeadNav.vue
  67. 111
      src/components/LeftFixed.vue
  68. 499
      src/components/Navbar.vue
  69. 418
      src/components/Page.vue
  70. 70
      src/components/Rotation/Rotation.vue
  71. 106
      src/components/Sidebar.vue
  72. 189
      src/components/User/MechanismSignUp.vue
  73. 177
      src/components/User/PersonalSignUp.vue
  74. 26
      src/config/api-user.js
  75. 40
      src/config/api.js
  76. 19
      src/config/selComment.js
  77. 30
      src/config/setting.js
  78. 19
      src/config/user.js
  79. 40
      src/main.js
  80. 72
      src/plugins/ant-design-vue.js
  81. 77
      src/plugins/axios.js
  82. 34
      src/registerServiceWorker.js
  83. 139
      src/router/index.js
  84. 143
      src/store/actions.js
  85. 7
      src/store/getters.js
  86. 20
      src/store/index.js
  87. 5
      src/store/loginInfo/actions.js
  88. 5
      src/store/loginInfo/index.js
  89. 7
      src/store/loginInfo/mutations.js
  90. 5
      src/store/loginInfo/state.js
  91. 134
      src/store/mutations.js
  92. 25
      src/store/state.js
  93. 54
      src/styles/index.scss
  94. 25
      src/views/About/About.vue
  95. 74
      src/views/About/Children/Introduction.vue
  96. 19
      src/views/About/components/Introduce.vue
  97. 19
      src/views/About/components/Organ.vue
  98. 19
      src/views/About/components/Partner.vue
  99. 115
      src/views/Activity/ActDetails.vue
  100. 234
      src/views/Activity/Activity.vue

12
.babelrc

@ -1,12 +0,0 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}

3
.browserslistrc

@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

9
.editorconfig

@ -1,9 +1,8 @@
root = true [*.{js,jsx,ts,tsx,vue}]
[*]
charset = utf-8
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
end_of_line = lf end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 140
root = true

3
.env

@ -0,0 +1,3 @@
VUE_APP_MODE=production
VUE_APP_PREVIEW=false
VUE_APP_URL=http://www.sxwikionline.com/

10
.env.development

@ -0,0 +1,10 @@
VUE_APP_MODE=development
VUE_APP_NODE_ENV=development
VUE_APP_SCENE=greenvalley
VUE_APP_BASE_URL=http://www.sxwikionline.com/
VUE_APP_API_URL=http://www.sxwikionline.com/gateway
VUE_APP_PROXY_URL=/gateway
VUE_APP_PUBLIC_PATH=/greenvalley
VUE_APP_MSG_URL=wss://test.tall.wiki/websocket/message/v4.0/ws
VUE_APP_TITLE=绿谷在线
VUE_APP_DESCRIPTION=绿谷在线管理后台

10
.env.production

@ -0,0 +1,10 @@
VUE_APP_MODE=production
VUE_APP_NODE_ENV=production
VUE_APP_SCENE=greenvalley
VUE_APP_BASE_URL=http://www.sxwikionline.com/
VUE_APP_API_URL=http://www.sxwikionline.com/gateway
VUE_APP_PROXY_URL=/gateway
VUE_APP_PUBLIC_PATH=/greenvalley
VUE_APP_MSG_URL=wss://www.tall.wiki/websocket/message/v4.0/ws
VUE_APP_TITLE=绿谷在线
VUE_APP_DESCRIPTION=绿谷在线管理后台

4
.eslintignore

@ -1,4 +0,0 @@
/build/
/config/
/dist/
/*.js

64
.eslintrc.js

@ -1,29 +1,47 @@
// https://eslint.org/docs/user-guide/configuring /*
* Copyright (c) 2019.
* author: wally
* email: 18603454788@163.com
*/
module.exports = { module.exports = {
root: true, root: true,
parserOptions: { env: { browser: true, node: true },
parser: 'babel-eslint' extends: ['plugin:vue/recommended', 'plugin:vue/essential'],
rules: {
'vue/html-self-closing': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['state'] }],
'max-len': ['error', { code: 140, tabWidth: 2 }],
'object-curly-newline': ['error', { multiline: true }],
'arrow-parens': ['error', 'as-needed'],
'linebreak-style': 'off',
'vue/attributes-order': 'off',
'no-param-reassign': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/max-attributes-per-line': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/html-indent': 'off',
}, },
env: {
browser: true, parserOptions: { parser: 'babel-eslint' },
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)'],
env: { jest: true },
}, },
extends: [
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
'plugin:vue/essential',
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
'standard'
], ],
// required to lint *.vue files
plugins: [ globals: {
'vue' Vue: true,
], VueRouter: true,
// add your custom rules here Vuex: true,
rules: { axios: true,
// allow async-await _: true,
'generator-star-spacing': 'off', Vuetify: true,
// allow debugger during development vuetify: true,
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' },
} };
}

13
.gitignore

@ -1,9 +1,17 @@
.DS_Store .DS_Store
node_modules/ node_modules
/dist/ /dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log*
# Editor directories and files # Editor directories and files
.idea .idea
@ -12,3 +20,4 @@ yarn-error.log*
*.ntvs* *.ntvs*
*.njsproj *.njsproj
*.sln *.sln
*.sw?

10
.postcssrc.js

@ -1,10 +0,0 @@
// 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": {}
}
}

13
.prettierrc

@ -0,0 +1,13 @@
{
"printWidth": 140,
"singleQuote": true,
"semi": true,
"trailingComma": "all",
"arrowParens": "avoid",
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"jsxBracketSameLine": false,
"proseWrap": "always",
"endOfLine": "lf"
}

33
README.md

@ -1,21 +1,24 @@
# lvgu # green-valley
> A Vue.js project ## Project setup
```
## Build Setup yarn install
```
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080 ### Compiles and hot-reloads for development
npm run dev ```
yarn serve
```
# build for production with minification ### Compiles and minifies for production
npm run build ```
yarn build
```
# build for production and view the bundle analyzer report ### Lints and fixes files
npm run build --report ```
yarn lint
``` ```
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). ### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

13
babel.config.js

@ -0,0 +1,13 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
plugins: [
[
"import",
{
libraryName: "ant-design-vue",
libraryDirectory: "es",
style: true
}
]
]
};

41
build/build.js

@ -1,41 +0,0 @@
'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

@ -1,54 +0,0 @@
'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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

101
build/utils.js

@ -1,101 +0,0 @@
'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

@ -1,22 +0,0 @@
'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'
}
}

92
build/webpack.base.conf.js

@ -1,92 +0,0 @@
'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)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
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: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
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

@ -1,95 +0,0 @@
'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

@ -1,145 +0,0 @@
'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

1
commitlint.config.js

@ -0,0 +1 @@
module.exports = {extends: ['./node_modules/vue-cli-plugin-commitlint/lib/lint']};

7
config/dev.env.js

@ -1,7 +0,0 @@
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})

45
config/index.js

@ -1,45 +0,0 @@
'use strict'
const path = require('path')
module.exports = {
dev: {
assetsSubDirectory: 'static',
assetsPublicPath: '/',
// 配置与后台接口问题
proxyTable: {
'/api': { // 配置后台代理
target: 'https://www.sxwikionline.com/gateway', // 后台接口地址
ws: true,
secure: false,
pathRewrite: { // 路径简写
'^/api': ''
},
changeOrigin: true // 是否跨域
}
},
host: 'localhost',
port: 8080,
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false,
useEslint: true,
showEslintErrorsInOverlay: false,
devtool: 'cheap-module-eval-source-map',
cacheBusting: true,
cssSourceMap: true
},
build: {
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
productionSourceMap: true,
devtool: '#source-map',
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
bundleAnalyzerReport: process.env.npm_config_report
}
}

4
config/prod.env.js

@ -1,4 +0,0 @@
'use strict'
module.exports = {
NODE_ENV: '"production"'
}

13
index.html

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="./static/logo.ico" type="image/x-icon">
<title>山西绿谷生物科技有限公司</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

18979
package-lock.json

File diff suppressed because it is too large

119
package.json

@ -1,84 +1,51 @@
{ {
"name": "lvgu", "name": "green-valley",
"version": "1.0.0", "version": "0.1.0",
"description": "A Vue.js project",
"author": "zhangbin",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "serve": "vue-cli-service serve",
"start": "npm run dev", "build": "vue-cli-service build",
"lint": "eslint --ext .js,.vue src", "lint": "vue-cli-service lint"
"build": "node build/build.js"
}, },
"dependencies": { "dependencies": {
"axios": "^0.20.0", "ant-design-vue": "^1.2.4",
"babel-polyfill": "^6.26.0", "compression-webpack-plugin": "^6.1.1",
"element-ui": "^2.13.2", "core-js": "^3.6.5",
"style-loader": "^2.0.0", "moment": "^2.29.1",
"vue": "^2.5.2", "quill": "^1.3.7",
"vue-router": "^3.0.1", "register-service-worker": "^1.7.1",
"vuex": "^3.5.1" "stylus": "^0.54.8",
"vue": "^2.6.11",
"vue-dompurify-html": "^2.3.0",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^7.1.2", "@vue/cli-plugin-babel": "~4.5.0",
"babel-core": "^6.22.1", "@vue/cli-plugin-eslint": "~4.5.0",
"babel-eslint": "^8.2.1", "@vue/cli-plugin-pwa": "~4.5.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3", "@vue/cli-plugin-router": "~4.5.0",
"babel-loader": "^7.1.1", "@vue/cli-plugin-vuex": "~4.5.0",
"babel-plugin-syntax-jsx": "^6.18.0", "@vue/cli-service": "~4.5.0",
"babel-plugin-transform-runtime": "^6.22.0", "@vue/eslint-config-prettier": "^6.0.0",
"babel-plugin-transform-vue-jsx": "^3.5.0", "axios": "^0.18.0",
"babel-preset-env": "^1.3.2", "babel-eslint": "^10.1.0",
"babel-preset-stage-2": "^6.22.0", "babel-plugin-import": "^1.11.0",
"chalk": "^2.0.1", "css-loader": "^5.0.1",
"copy-webpack-plugin": "^4.0.1", "eslint": "^6.7.2",
"css-loader": "^0.28.0", "eslint-plugin-prettier": "^3.1.3",
"eslint": "^4.15.0", "eslint-plugin-vue": "^6.2.2",
"eslint-config-standard": "^10.2.1", "less": "^2.7.3",
"eslint-friendly-formatter": "^3.0.0", "less-loader": "^4.1.0",
"eslint-loader": "^1.7.1", "prettier": "^1.19.1",
"eslint-plugin-import": "^2.7.0", "sass": "^1.26.5",
"eslint-plugin-node": "^5.2.0", "sass-loader": "^8.0.2",
"eslint-plugin-promise": "^3.4.0", "stylus": "^0.54.5",
"eslint-plugin-standard": "^3.0.1", "stylus-loader": "^3.0.2",
"eslint-plugin-vue": "^4.0.0", "svg-sprite-loader": "^5.0.0",
"extract-text-webpack-plugin": "^3.0.0", "vue-cli-plugin-ant-design": "^1.0.1",
"file-loader": "^1.1.4", "vue-cli-plugin-axios": "^0.0.4",
"friendly-errors-webpack-plugin": "^1.6.1", "vue-template-compiler": "^2.6.11"
"html-webpack-plugin": "^2.30.1", }
"less": "^3.12.2",
"less-loader": "^7.0.2",
"node-notifier": "^5.1.2",
"node-sass": "^4.14.1",
"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",
"sass-loader": "^7.3.1",
"scss": "^0.2.4",
"scss-loader": "^0.0.1",
"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",
"vue-template-compiler": "^2.5.2",
"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"
]
} }

BIN
public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/img/icons/android-chrome-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
public/img/icons/android-chrome-512x512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
public/img/icons/android-chrome-maskable-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
public/img/icons/android-chrome-maskable-512x512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/img/icons/apple-touch-icon-120x120.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/img/icons/apple-touch-icon-152x152.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
public/img/icons/apple-touch-icon-180x180.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/img/icons/apple-touch-icon-60x60.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
public/img/icons/apple-touch-icon-76x76.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/img/icons/apple-touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/img/icons/favicon-16x16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

BIN
public/img/icons/favicon-32x32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/img/icons/msapplication-icon-144x144.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/img/icons/mstile-150x150.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

3
public/img/icons/safari-pinned-tab.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 215 B

17
public/index.html

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

2
public/robots.txt

@ -0,0 +1,2 @@
User-agent: *
Disallow:

15
rest/http-client.env.json

@ -0,0 +1,15 @@
{
"$shared": {
"version": "v1",
"identifier": "wally",
"credential": "111111"
},
"dev": {
"name": "dev",
"url": "http://192.168.0.99/gateway"
},
"local": {
"version": "v2",
"url": "http://192.168.0.99/gateway"
}
}

56
rest/project.http

@ -0,0 +1,56 @@
# @tall = {{url}}/tall/v1.0
@tall = http://www.sxwikionline.com/gateway/tall/v1.0
@greenvalley = http://www.sxwikionline.com/gateway/greenvalley
@type = content-type: application/json;charset=utf-8
### login
# @name login
POST {{tall}}/users/signin
{{type}}
{
"client": 1,
"type": 3,
"data": {
"identifier": "song",
"credential": "999999"
}
}
### send code
GET {{tall}}/users/smscode?phone=16603418748
### phone login
# @name phonelogin
POST {{tall}}/users/signin
{{type}}
{
"client": 1,
"type": 1,
"data": {
"identifier": "16603418748",
"credential": "1111"
}
}
### 根据团队id查看研发团队相关信息
POST {{greenvalley}}/researchTeam/selectTeam
{{type}}
Authorization: Bearer {{login.response.body.$.data.token}}
{
"param": {
"company": "",
"researchDirection": "",
"teamId": 0,
"teamIntroduce": "",
"teamLeaderName": "",
"teamName": ""
}
}

122
src/App.vue

@ -1,56 +1,104 @@
<template> <template>
<a-config-provider :locale="zh_CN">
<div id="app"> <div id="app">
<Navbar /> <head-nav class="head-nav" />
<router-view /> <router-view></router-view>
<Footer /> <friend-ship class="friend" />
<footer-page class="footer" />
<div id="components-back-top-demo-custom">
<a-back-top>
<div class="ant-back-top-inner">
回到顶部
<a-icon type="vertical-align-top" />
</div> </div>
</a-back-top>
</div>
</div>
</a-config-provider>
</template> </template>
<script> <script>
import Navbar from '@/components/Navbar' import { mapState, mapActions, mapMutations } from 'vuex';
import Footer from '@/components/Footer' import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN';
import { debug } from '@/api/getData.js' import HeadNav from './components/HeadNav/HeadNav.vue';
import FooterPage from './components/FooterPage/FooterPage.vue';
import FriendShip from './components/FooterPage/FriendShip.vue';
export default { export default {
components: { Navbar, Footer }, name: 'App',
data () { components: { HeadNav, FooterPage, FriendShip },
return { data() {
screenWidth: 0 return { zh_CN };
}
}, },
watch: { computed: mapState(['anyringToken']),
screenWidth (val) { updated() {
// font-size window.scroll(0, 0);
var html = document.getElementsByTagName('html')[0] },
// var oWidth = document.body.clientWidth || document.documentElement.clientWidth created() {
// 750, console.log('process.env ', process.env);
html.style.fontSize = val / 100 + 'px' const userId = '1218763410024566784';
console.log('rem:', html.style.fontSize) const params = { userId };
debug().then(res => { this.getUserId(params);
console.log(res) if (sessionStorage.getItem('store')) {
}).catch(err => { this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))));
console.log(err)
})
} }
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('store', JSON.stringify(this.$store.state));
});
}, },
mounted: function () { methods: { ...mapActions(['getUserId']) },
window.onresize = () => { };
return (() => {
this.screenWidth = document.body.clientWidth
})()
}
}
}
</script> </script>
<style> <style>
* { html,
margin: 0; body,
padding: 0; #app {
min-height: 100%;
}
#app {
background: transparent;
} }
body { body {
min-height: 100%; background: #f5f5f5 !important;
padding-top: 14vh; padding-top: 80px;
}
body::-webkit-scrollbar {
width: 0;
}
.head-nav {
height: 80px;
width: 100%;
top: 0;
background: white;
box-shadow: 0 0 10px #ccc;
position: fixed !important;
z-index: 100;
}
.friend {
height: 64px;
}
.footer {
height: 397px;
width: 100%;
background: #0d1f32;
bottom: 0;
}
#components-back-top-demo-custom .ant-back-top {
bottom: 100px;
right: 180px;
}
#components-back-top-demo-custom .ant-back-top-inner {
height: 40px;
width: 120px;
line-height: 40px;
border-radius: 4px;
background-color: #13acc4;
color: #fff;
text-align: center;
font-size: 14px;
} }
</style> </style>

79
src/api/axios.js

@ -1,79 +0,0 @@
import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'
let router = import('@/router')
// axios.defaults.baseURL = '/'
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
// axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
// axios.defaults.headers['Cache-Control'] = 'no-cache'
// axios.defaults.headers['pragma'] = 'no-cache'
let source = axios.CancelToken.source()
// 请求添加token
axios.interceptors.request.use(request => {
request.headers['Authorization'] = store.state.loginInfo ? 'Bearer ' + store.state.loginInfo.token : '' // 已将userId保存在store中
return request
})
// 切换页面取消请求
axios.interceptors.request.use(request => {
request.cancelToken = source.token
return request
})
router.then(lib => {
lib.default.beforeEach((to, from, next) => {
source.cancel()
source = axios.CancelToken.source()
next()
})
})
// 登录过期跳转
axios.interceptors.response.use(response => {
let data = response.data
if (
[10002].includes(data.ret)
) {
router.then(lib => lib.default.push({ name: 'login' })) // 跳转到登录页面
Message.warning(data.msg)
}
return response
})
// 返回值解构
axios.interceptors.response.use(response => {
let data = response.data
let isJson = (response.headers['content-type'] || '').includes('json')
if (isJson) {
if (data.code === 200) {
return Promise.resolve({
data: data.data,
msg: data.msg,
code: data.code
})
}
return Promise.reject(
data.msg || '网络错误'
)
} else {
return data
}
}, err => {
let isCancel = axios.isCancel(err)
if (isCancel) {
return new Promise(() => { })
}
return Promise.reject(
(err.response.data && err.response.data.msg) || '网络错误'
)
})
export function post (url, data, otherConfig) {
return axios.post(url, data, otherConfig)
}
export function get (url, data, otherConfig) {
return axios.get(url, { params: data, ...otherConfig })
}

16
src/api/getData.js

@ -1,16 +0,0 @@
import { get, post } from '@/api/axios'
export function getConfig () {
return get('static/config.json', null, { baseURL: './' })
}
// get接口例子
export function debug (params) {
return get('api/tall/v1.0/debug', params)
}
// post接口例子
export function switchLabel (params) {
return post('/goods/switchLabel', params)
}

BIN
src/assets/erweima.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

28
src/assets/icon/iconfont.css

@ -1,29 +1,21 @@
@font-face {font-family: "iconfont"; @font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1602646174342'); /* IE9 */ src: url('iconfont.eot?t=1606814380789'); /* IE9 */
src: url('iconfont.eot?t=1602646174342#iefix') format('embedded-opentype'), /* IE6-IE8 */ src: url('iconfont.eot?t=1606814380789#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAANMAAsAAAAAB0QAAAL/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDFAqBcIF6ATYCJAMQCwoABCAFhG0HXht6BsiemjzZ0FgesPBYUCxGQETxwP/9qPvix1RSRGoUzxlKyl1Ksl1b8ARdXpCmCoF/79zXdLMMNkuOCF1x0uZT/kvT5SNWxBZQWGK7p1iSvFNndvtnC6vu5LimSUVFjurcEiDA+OBY6qdFgeQBvUtWUiTgCz5gF+ZGtoHMfcvwWpdWB32bgFYjqmhHI1NLkCrDRQHhAXdNSM35ZVlO1YKyZmdGeEbVcccPwNPw98N/2CgVoiIBV57cH3ag7xd/ZaXVHDR8BMF8Vsj7SFgCMuGqNn6JCDKVaF2RaAUoZUH8xWJZTcOcvFDPPhM14qh/XiiBxe1gCxKJX5oLIr9k6hRZILz5hgxqb1OwDTyBuCGfCqJY9cxMmz0u60XYOn2e2vu9lYil/5fvp0W/ePu6VSBnrloj3EjcJjm+FjldPZH2oRJPq/rQ21sNXUr+8K/h2Hjiva/f7xLm+fGdvAik39JTps+0qJfvJK78V1fI23fkebriS69Q8rt3hAMV0BwY03Rd8zJHdWMMxsA6bVQb0/WxFeOn29LyPeBE4iPcFV/HJ6B5nt6RYwDSacLez/8bb4rXHuk5XX9TMwTw5cHZW6G/eZ71T9QisuBXC3r2ZUuEhpwNscu3ndn46GhEKwvRALp7fZlDPfAmyaA2kEJUGYakNoXM2CUotNmCUm0XWi0a3d+mj0SEbGDBMQJBt8cQdXoLSbePyIz9DIVBf6DUHYFWp6HgxDYz8fRBiaZCh1pblNsixrhJpUelC+gGEVNmRSFtBaXPQ7S+pq6YGsUYyjnW+Otug1KMMimidITch5GIoHEpQmirGk+peEdtLav7phpbRCHdIQmZFOSgLFsozibEMH+0kl76+QXIFYgwyZamJvsKJPn4+FS9GnU9kKPyWK+me3nEt87VQFEYipGEKGqEWFGExQUqXj8tBNmUGt6IaFyHWjqM9ZXXrK+MfkCe3AZ+cQ6FlUJFx62H61LEqiV3PVWoAoubYtvj24GICsuMVdc1Zj3NJD3wUcbMKAIAAA==') format('woff2'), url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALAAAsAAAAABnAAAAJ0AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAp8gRABNgIkAwgLBgAEIAWEbQcvG7UFyJ6aPClS2/jAQpBlKUHgLEQQraGzf/cfBIUoGRWCjoqLMLFRrXRVrTH1bMRfztXeEwobfUDy1DOlP3OusGk5nTSH6gmFJ0tKIY+nBgQ4ZZ5fe/U+cbjXxvJA5jvvchlj0FiTJnUBxoEU0N4YbeEC+QD+h7ELXMJlAs2GJMUOR6aWoE1mzQrEm22q0JbzyzJLNQpVzcYsvio1Fp/FAXwJfx//IR9tFMrEqrh4HTag75dmZ6SPmhefIEBA20skLACZuKmNn2kUjNmoOd5kDOyrNPil1bVvE3v954mKVdwKBqDknqSu7Fb5C5DpzRiwMuoDpJaW1veXVeV5b+lxhVLteX355ZA+rS0ZjT+ex05fRr8/jR493lS0+Eefi/THEQbKv8zAm9u5cn11ob622gISIuUCqogn3i5OR1tKlzE/z2iuVkMfQC0tEYA/mX852tS7eVtLBj//5s/CKbVc+kDjvh3BP5L2bMm63LIWWZXWpgtjGs9d1awZddjd7Xusoe+G0qFR3205GwymSBpNEDN1AaUWi6g02kGzeaPbW/QQGkVuwpxNgNDpEoV235B0uiJm6hdK/f5R6YxGNLuLngNbTIXdcSBQlWgQrUZsnQfMscuOqHQBzZKniqw8ZCkoIjtEculsMTWKAYo5lkRlMy8lI0xwn4yA69DzOAkFd1CXaUvKsJDJsLo7pXXuQ4cDAlJJyEBoagibjgswv7PUUfr+AmQq8ahES1NNUIGEiN0/kZOW7UEc1QS9mu7llkiZKU+SGIIROB8xAsYhj4cjwvpxDqST0qwR0VBBxm7H+mrS6+v8r9sFzSxjEfaIpHzjuuoBAAA=') format('woff2'),
url('iconfont.woff?t=1602646174342') format('woff'), url('iconfont.woff?t=1606814380789') format('woff'),
url('iconfont.ttf?t=1602646174342') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('iconfont.ttf?t=1606814380789') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1602646174342#iconfont') format('svg'); /* iOS 4.1- */ url('iconfont.svg?t=1606814380789#iconfont') format('svg'); /* iOS 4.1- */
} }
.iconfont { .iconfont {
font-family: "iconfont" !important; font-family: "iconfont" !important;
font-size: 16px; font-size: 14px;
font-style: normal; font-style: normal;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-chevron-right:before { .icon-local:before {
content: "\e60d"; content: "\e662";
font-size: 20px;
} }
.icon-tubiaozhizuomoban-03:before {
content: "\e601";
}
.icon-icon_username:before {
content: "\e602";
}

BIN
src/assets/icon/iconfont.eot

Binary file not shown.

8
src/assets/icon/iconfont.svg

@ -20,13 +20,7 @@ Created by iconfont
/> />
<missing-glyph /> <missing-glyph />
<glyph glyph-name="chevron-right" unicode="&#58893;" d="M364.8 19.2L320 64l294.4 294.4L320 659.2l44.8 44.8 320-320v-44.8l-320-320z" horiz-adv-x="1024" /> <glyph glyph-name="local" unicode="&#58978;" d="M720.0256 262.9504c115.168 115.5392 115.168 303.0336 0 418.5664-114.9376 115.3088-301.12 115.3088-416.0512 0-115.168-115.5328-115.168-303.0272 0-418.56L512 54.2464l208.0256 208.704z m-506.7072-90.3616c-164.96 165.4912-164.96 433.8048 0 599.296 164.96 165.4848 432.4032 165.4848 597.3632 0 164.96-165.4912 164.96-433.8048 0-599.296L512-127.0592l-298.6816 299.648zM512 345.6c-70.6944 0-128 57.3056-128 128s57.3056 128 128 128 128-57.3056 128-128-57.3056-128-128-128z" horiz-adv-x="1024" />
<glyph glyph-name="tubiaozhizuomoban-03" unicode="&#58881;" d="M960.05-23.17L761.42 181.78a399.14 399.14 0 0 1 98.29 262.66c0 221-179.82 400.85-400.85 400.85S58 665.47 58 444.44 237.84 43.6 458.86 43.6a399.35 399.35 0 0 1 273.6 108.18l197.66-204a20.84 20.84 0 1 1 29.93 29zM458.86 85.28c-198 0-359.17 161.12-359.17 359.16S260.82 803.61 458.86 803.61 818 642.49 818 444.44 656.91 85.28 458.86 85.28z" horiz-adv-x="1024" />
<glyph glyph-name="icon_username" unicode="&#58882;" d="M512 384c94.293333 0 170.666667 76.373333 170.666667 170.666667s-76.373333 170.666667-170.666667 170.666666-170.666667-76.373333-170.666667-170.666666 76.373333-170.666667 170.666667-170.666667z m0-85.333333c-113.92 0-341.333333-57.173333-341.333333-170.666667v-85.333333h682.666666v85.333333c0 113.493333-227.413333 170.666667-341.333333 170.666667z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1018 B

BIN
src/assets/icon/iconfont.ttf

Binary file not shown.

BIN
src/assets/icon/iconfont.woff

Binary file not shown.

BIN
src/assets/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
src/assets/lvgu.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

244
src/common/portrait.styl

@ -0,0 +1,244 @@
// padding
.pa-3 {
padding: 12px;
}
.pb-3 {
padding-bottom: 12px;
}
.pb-4 {
padding-bottom: 16px;
}
.pb-5 {
padding-bottom: 20px;
}
.pb-10 {
padding-bottom: 40px;
}
// margin
.ma-3 {
margin: 12px;
}
.mx-2{
margin-left: 8px;
margin-right: 8px;
}
.my-2{
margin-top: 8px;
margin-bottom: 8px;
}
.my-3{
margin-top: 12px;
margin-bottom: 12px;
}
.my-4{
margin-top: 16px;
margin-bottom: 16px;
}
.mt-1{
margin-top: 4px;
}
.mt-2{
margin-top: 8px;
}
.mt-3{
margin-top: 12px;
}
.mt-4{
margin-top: 16px;
}
.mb-1{
margin-bottom: 4px;
}
.mb-2{
margin-bottom: 8px;
}
.mb-3{
margin-bottom: 12px;
}
.mb-4{
margin-bottom: 16px;
}
.ml-2{
margin-left: 8px;
}
.ml-3{
margin-left: 12px;
}
.ml-4{
margin-left: 16px;
}
.ml-5{
margin-left: 20px;
}
.ml-6{
margin-left: 24px;
}
.ml-7{
margin-left: 28px;
}
.ml-8{
margin-left: 32px;
}
.mr-1{
margin-right: 4px;
}
.mr-2{
margin-right: 8px;
}
.mr-3{
margin-right: 12px;
}
.mr-4{
margin-right: 16px;
}
.mr-5{
margin-right: 20px;
}
.mr-6{
margin-right: 24px;
}
// background
.white {
background: white;
}
// flex
.d-flex{
display: flex;
}
.flex-wrap{
flex-wrap: wrap;
}
.flex-nowrap{
flex-wrap: nowrap;
}
.flex-column{
flex-direction: column;
}
.flex-column-reverse{
flex-direction: column-reverse;
}
.flex-row{
flex-direction: row;
}
.flex-row-reverse{
flex-direction: row-reverse;
}
.justify-center{
justify-content: center;
}
.justify-space-between{
justify-content: space-between;
}
.flex-1{
display: flex;
flex: 1;
}
// other
.pointer{
cursor:pointer;
}
.fill-height{
height:100%;
}
// font
.font-bold-24{
font-size: 24px;
font-weight: bold;
}
.font-24{
font-size: 24px;
}
.font-bold-16{
font-size: 16px;
font-weight: bold;
}
.font-16{
font-size: 16px;
}
.font-bold-14{
font-size: 14px;
font-weight: bold;
}
.font-14{
font-size: 14px;
}
.icon-size{
font-size: 20px;
}
h2{
font-size: 24px;
font-weight: bold;
color: rgba(0,0,0,.85)
}
.textColor{
color: rgba(0,0,0,.65)
}
.baseColor{
color: #13ACC4
}
.bg{
background: #F5F5F5
}
.ant-btn-primary{
background-color: #13ACC4
border-color: #13ACC4;
}
.ant-btn-link:hover, .ant-btn-link:focus{
color: #13ACC4;
}

20
src/components/Community.vue

@ -1,20 +0,0 @@
<template>
<div>
交流社区组件
</div>
</template>
<script>
export default {
name: 'Community',
data () {
return {
}
}
}
</script>
<style lang="">
</style>

115
src/components/Demand.vue

@ -1,115 +0,0 @@
<template>
<div>
<div class="box" @click="dialogFormVisible=true">
提交<br/>需求
<div class="remind">1</div>
</div>
<el-dialog title="需求列表" :visible.sync="dialogFormVisible" style="font-weight: bold;">
<div v-for="(item,index) in datalist" :key="index" class="data-box">
<p class="data-title">{{ item.title }}</p>
<div v-for="(a,b) in item.content" :key="b" class="data-content">{{ a }}</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogFormVisible=false">
取消
</el-button>
<el-button type="success" @click="jumpDemand">
提交需求
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'Demandbox',
data () {
return {
dialogFormVisible: false,
listLoading: false,
datalist: [{
title: '服务需求',
content: ['一个服务', '两个服务', '三个服务']
}, {
title: '团队需求',
content: ['一个团队', '两个团队', '三个团队']
}, {
title: '设备需求',
content: ['一个设备', '两个设备', '三个设备']
}]
}
},
methods: {
jumpDemand () {
this.$router.push('/Demand')
}
}
}
</script>
<style scoped>
.box {
position: fixed;
height: 5.5rem;
width: 5.5rem;
background: #82DCE5;
font-size: 1.4rem;
color: #fff;
font-weight: bold;
bottom: 20vh;
right: 18vw;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
cursor: pointer;
box-shadow: 4px 4px 5px #707070;
}
.box:hover {
animation: boxhover 5s;
-moz-animation: boxhover 5s; /* Firefox */
-webkit-animation: boxhover 5s; /* Safari 和 Chrome */
-o-animation: boxhover 5s;
}
@keyframes boxhover {
from {background: #82DCE5;}
to {background: yellow;}
}
.remind {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
font-size: 0.8rem;
background: #FBBC73;
height: 30%;
width: 30%;
top: 0;
right: 0;
border-radius: 50%;
}
.data-title {
color: #707070;
font-size: 0.9rem;
font-weight: bold;
border-bottom: 2px solid #00B7CB;
}
.data-box {
margin-bottom: 20px;
overflow: hidden;
}
.data-content {
height: 3rem;
width: 29%;
text-align: center;
line-height: 3rem;
border-radius: 5px;
box-shadow: 2px 2px 2px #707070;
border: 2px solid #909090;
margin: 5px 2% 2px 2%;
float: left;
box-sizing: border-box;
}
</style>

140
src/components/Footer.vue

@ -1,140 +0,0 @@
<template>
<div class="footer">
<div class="footer-top">
<div class="footer-content" v-for="(item,index) in bottomContent" :key="index">
<p class="content-title">{{ item.title }}</p>
<ul>
<li class="content-li" v-for="(x,y) in item.children" :key="y">{{ x.content }}</li>
</ul>
</div>
</div>
<div class="footer-center">
<p class="content-title">友情链接</p>
<ul>
<li>科技部</li>
<li>发改部</li>
<li>工信部</li>
<li>山西省综改区</li>
<li>山西省科技厅</li>
<li>山西省工信厅</li>
<li>山西省发改委</li>
</ul>
</div>
<div class="footer-img">
<img :src="erweimaImg" alt="">
</div>
<div class="footer-bottom">
<span v-for="(item,index) in bottomList" :key="index">{{ item }}</span>
</div>
</div>
</template>
<script>
export default {
name: 'Footer',
data () {
return {
bottomList: ['联系绿谷', '隐私跳跃', '使用条款', '信息无障碍选项', 'Cookie 首选项'],
bottomContent: [
{
title: '发现',
children: [{content: '资讯'}, {content: '研发'}, {content: '服务'}, {content: '行业'}, {content: '成功案例'}, {content: '融资'}]
}, {
title: '关于绿谷',
children: [{content: '公告'}, {content: '活动'}, {content: '投资者'}, {content: '社会责任'}, {content: '政策支持'}, {content: '工作机会'}]
}, {
title: '联系我们',
children: [{content: '在线资讯'}, {content: '众创空间'}, {content: '孵化器'}, {content: '实体空间'}, {content: '虚拟空间'}, {content: '支持'}]
}
],
erweimaImg: require('@/assets/erweima.png')
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.footer {
height: 25.5rem;
width: 100%;
position: relative;
background: #E2E6EB;
}
.footer-top {
width: 60%;
margin: 0 auto;
height: 70%;
display: flex;
padding-top: 3.5rem;
box-sizing: border-box;
}
.footer-bottom {
width: 60%;
margin: 0 auto;
height: 12%;
box-sizing: border-box;
display: flex;
align-items: center;
}
.footer-bottom > span {
color: #707070;
font-size: 0.85rem;
font-weight: 400;
margin-right: 1rem;
cursor: pointer;
}
.footer-content {
flex: 1;
height: 70%;
}
.content-title {
font-size: 1.4rem;
color: #707070;
font-weight: bold;
margin-bottom: 0.5rem;
}
.content-li {
font-size: 1.2rem;
color: #909090;
list-style: none;
font-weight: 600;
float: none !important;
height: 1.8rem;
line-height: 1.8rem;
text-align: left;
margin: 0.15rem 0 !important;
}
.footer-content ul {
height: auto;
}
.footer-img {
position: absolute;
top: 8.7rem;
right: 4.5rem;
}
.footer-img img {
height: 10.5rem;
width: 10.5rem;
}
.footer-center {
width: 100%;
height: 18%;
padding: 0 20%;
border-bottom: 1px solid #707070;
box-sizing: border-box;
}
.footer-center li {
font-size: 1rem;
color: #909090;
list-style: none;
font-weight: 600;
float: left;
height: 1.5rem;
line-height: 1.5rem;
text-align: left;
margin: 0.1rem 1rem 0 0 !important;
}
</style>

15
src/components/FooterPage/FooterPage.vue

@ -0,0 +1,15 @@
<template>
<div class="footer">
{{ str }}
</div>
</template>
<script>
export default {
data() {
return { str: '头部导航栏' };
},
};
</script>
<style lang="stylus" scoped></style>

27
src/components/FooterPage/FriendShip.vue

@ -0,0 +1,27 @@
<template>
<div class="friend">
<div class="friend-content">
{{ str }}
</div>
</div>
</template>
<script>
export default {
data() {
return { str: '友情链接' };
},
};
</script>
<style lang="stylus" scoped>
.friend {
line-height: 64px;
background: #ffffff;
}
.friend-content {
width: 1260px;
margin: auto;
}
</style>

198
src/components/HeadNav/HeadNav.vue

@ -0,0 +1,198 @@
<template>
<div class="head">
<img @click="jumUrl('/')" alt class="logo-img" src="@/assets/logo.png" style="cursor: pointer" />
<div class="li-box">
<a-dropdown :disabled="item.children.length > 0 ? false : true" :key="a" class="list-down" v-for="(item, a) in list">
<a @click="jumUrl(item.url)" class="ant-dropdown-link">
{{ item.name }}&nbsp;&nbsp;
<a-icon type="down" v-show="item.children.length > 0" />
</a>
<a-menu slot="overlay">
<a-menu-item :key="b" style="text-align: center" v-for="(con, b) in item.children">
<a>{{ con.title }}</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</div>
<a-icon class="icon-head" style="right: 150px" type="search" />
<a-icon class="icon-head baseColor" style="right: 100px" type="shopping-cart" />
<router-link tag="span" to="/login">
<a-icon class="icon-head" style="right: 50px" type="user" />
</router-link>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
data() {
return {
str: '这是头部导航',
list: [
{
name: '关于我们',
children: [
{
title: '公司介绍',
url: '',
},
{
title: '组织机构',
url: '',
},
{
title: '合作伙伴',
url: '',
},
{
title: '衍生企业',
url: '',
},
],
},
{
name: '创新政策',
children: [],
url: '/Policy',
},
{
name: '创新平台',
children: [
{
title: '协同创新中心',
url: '',
},
{
title: '创新服务平台',
url: '',
},
{
title: '科技创新服务',
url: '',
},
],
},
{
name: '孵化平台',
children: [
{
title: '众创空间',
url: '',
},
{
title: '公共实验室',
url: '',
},
{
title: '合作伙伴',
url: '',
},
{
title: '创业服务',
url: '',
},
{
title: '产品展示',
url: '',
},
],
},
{
name: '产业平台',
children: [
{
title: '产业创新联盟',
url: '',
},
{
title: '产业服务',
url: '',
},
{
title: '衍生企业',
url: '',
},
],
},
{
name: '知识平台',
children: [],
},
{
name: '活动公告',
children: [],
url: '/Activity',
},
{
name: '创新挑战',
children: [
{
title: '需求征集',
url: '',
},
{
title: '项目发布',
url: '',
},
{
title: '结果公告',
url: '',
},
],
},
{
name: '交流社区',
children: [],
url: '/Community',
},
{
name: '联系我们',
children: [],
},
],
};
},
methods: {
jumUrl(url) {
if (this.$route.path !== url) {
this.$router.push(url);
}
},
},
};
</script>
<style lang="stylus" scoped>
.head {
height: 80px;
width: 100%;
background: white;
position: relative;
}
.icon-head {
font-size: 24px;
position: absolute;
top: 28px;
cursor: pointer;
}
.li-box {
line-height: 80px;
position: absolute;
height: 80px;
top: 0;
left: 250px;
}
.list-down {
margin-right: 20px;
color: rgba(0, 0, 0, 0.65);
}
.logo-img {
height: 50px;
margin-top: 15px;
margin-left: 48px;
}
</style>

111
src/components/LeftFixed.vue

@ -1,111 +0,0 @@
<template>
<div class="left-fixed">
<ul class="fixed-li-box">
<li
v-for="(item, index) in list[`${type}`]"
:key="index"
class="fixed-li"
:class="isactive === index ? 'active' : ''"
@click="changeAcitve(index)"
>
<p :class="isactive === index ? 'pactive' : ''">{{ item }}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'LeftFixed',
data () {
return {
list: [
[],
['绿谷简介', '组织架构', '合作伙伴', '衍生企业'],
['国家政策', '省级政策', '行业政策'],
['协同中心', '科技创新服务', '科技资源共享服务平台', '交流社区'],
['孵化平台介绍', '实体众创空间', '线上众创空间', '创新创业服务', '交流社区'],
['产业技术创新联盟', '衍生企业', '交流社区'],
['创新挑战介绍', '创新挑战项目征集', '创新挑战项目公告', '创新挑战结果公示'],
['联系我们', '我要入驻', '人员招聘'],
['企业需求信息列表']
],
isactive: 0
}
},
props: {
type: {
type: Number,
default: 0
}
},
methods: {
changeAcitve (num) {
const that = this
that.isactive = num
}
}
}
</script>
<style lang="scss" scoped>
.left-fixed {
z-index: 1;
position: fixed;
top: 14vh;
height: 86vh;
overflow: auto;
overflow: -moz-scrollbars-none;
overflow: -moz-scrollbars-none;
box-sizing: border-box;
width: 13.5vw;
background: #e2e6eb;
}
.left-fixed::-webkit-scrollbar {
display: none;
}
.fixed-li-box {
padding-top: 1rem;
}
.fixed-li {
height: 2.5rem;
line-height: 2.5rem;
padding-left: 2.2rem;
color: #707070;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
overflow: hidden;
}
p {
word-break: keep-all; /* 不换行 */
white-space: nowrap; /* 不换行 */
}
.pactive {
animation: 7s wordsLoop linear infinite normal;
}
@keyframes wordsLoop {
0% {
transform: translateX(0px);
-webkit-transform: translateX(0px);
}
100% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
}
@-webkit-keyframes wordsLoop {
0% {
transform: translateX(0px);
-webkit-transform: translateX(0px);
}
100% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
}
.active {
background: #4accda;
color: #ffffff;
}
</style>

499
src/components/Navbar.vue

@ -1,499 +0,0 @@
<template>
<div class="head-box">
<div class="nav-head">
<div class="head-left">
<img src="@/assets/lvgu.png" alt="" />
</div>
<div class="head-right">
<router-link
tag="i"
to="/Login"
class="iconfont icon-icon_username user"
></router-link>
</div>
<div class="head-right head-ipt-box">
<input class="head-ipt" type="text" placeholder="全站搜索" />
<i class="iconfont icon-tubiaozhizuomoban-03 search"></i>
</div>
</div>
<div class="nav-con">
<ul class="nav-con-ul">
<li v-for="(item, index) in list" :key="index">
<div
class="li-con"
:class="isshow === index ? 'lishow' : ''"
@mouseenter="ShowLi(index, item.type, item.statrtype)"
@click="Showli1(index, item.type)"
>
{{ item.title }}
</div>
</li>
</ul>
</div>
<div style="width: 100%; position: absolute; z-index: 10">
<el-collapse-transition>
<div @click="noShow" v-show="show3" @mouseleave="leave">
<div class="transition-box">
<div class="transition-left">
<ul class="left-ul" v-show="isshow !== 0">
<!-- 适配代码 -->
<!-- <router-link tag="li" :to="{path:`${jumpUrl}`}" v-for="(item,index) in list[`${isshow}`].children" :key="index" :class="active === index ? 'li-active' : ''" @mouseenter.native="changeAcitve(index,item.showtype)"> -->
<router-link
tag="li"
:to="{ path: `${jumpUrl}` }"
v-for="(item, index) in list[`${isshow}`].children"
:key="index"
:class="active === index ? 'li-active' : ''"
@mouseenter.native="changeAcitve(index)"
>
{{ item.title }}
<i
v-if="active === index"
class="iconfont icon-chevron-right position-right"
></i>
</router-link>
</ul>
</div>
<div class="transition-right">
<!-- 适配代码 -->
<!-- <div class="type1" v-show="showtype === 1">
<h1></h1>
</div>
<div class="type1" v-show="showtype === 2">
类型222
</div>
<div class="type1" v-show="showtype === 3">
类型33333
</div> -->
<div class="type1" v-show="showtype === 1">
<p class="title-big">绿谷简介</p>
<p class="title-two">功能食品与生物医药专业化众创空间</p>
<div class="show-con">
本众创空间立足功能食品生物医药和大健康产业面向科技型中小微企业创新创业团队和创客集协同创新中心公共实验室中试基地和创新创业大讲堂为一体致力于打造线上线下相结合实体虚拟相融合的全要素开放式专业化众创空间促进技术转移转化和科技型中小微企业集聚发展
本众创空间办公场所位于太原市晋阳街202号英语周报大厦8层公共实验室位于太原市师范街50号山西省生物研究院有限公司中试基地位于太原市小店区正阳街43号山西力德福科技有限公司
</div>
<p class="title-three">聚焦创新 聚力孵化 聚合产业</p>
<img class="show-img" src="./../../static/showye1.png" alt="" />
</div>
<div class="type1" v-show="showtype === 2">
<p class="title-big">国家政策</p>
<ul class="show-con1">
<li v-for="(item, index) in showlist" :key="index">
{{ item.title }} &nbsp;&nbsp;&nbsp;<span
class="show-con1-time"
>{{ item.time }}</span
>
</li>
</ul>
</div>
<div class="type1" v-show="showtype === 3">
<p class="title-big">协同创新中心</p>
<div class="show-con-box">
<div
class="box-content"
v-for="(item, index) in showlist1"
:key="index"
>
<p class="con-box-title">{{ item.title }}</p>
<p class="con-box-content">{{ item.content }}</p>
</div>
</div>
</div>
<div class="type1" v-show="showtype === 4">
<p class="title-big">平台介绍</p>
<p class="title-two">标题111</p>
<div class="show-con">
本众创空间立足功能食品生物医药和大健康产业面向科技型中小微企业创新创业团队和创客集协同创新中心公共实验室中试基地和创新创业大讲堂为一体致力于打造线上线下相结合实体虚拟相融合的全要素开放式专业化众创空间促进技术转移转化和科技型中小微企业集聚发展
本众创空间办公场所位于太原市晋阳街202号英语周报大厦8层公共实验室位于太原市师范街50号山西省生物研究院有限公司中试基地位于太原市小店区正阳街43号山西力德福科技有限公司
</div>
<p class="title-three">标题222</p>
<img class="show-img" src="./../../static/showye1.png" alt="" />
</div>
<div class="type1" v-show="showtype === 5">
<p class="title-big">产业技术联盟</p>
<p class="title-two">标题111</p>
<div class="show-con">
本众创空间立足功能食品生物医药和大健康产业面向科技型中小微企业创新创业团队和创客集协同创新中心公共实验室中试基地和创新创业大讲堂为一体致力于打造线上线下相结合实体虚拟相融合的全要素开放式专业化众创空间促进技术转移转化和科技型中小微企业集聚发展
本众创空间办公场所位于太原市晋阳街202号英语周报大厦8层公共实验室位于太原市师范街50号山西省生物研究院有限公司中试基地位于太原市小店区正阳街43号山西力德福科技有限公司
</div>
<p class="title-three">标题222</p>
<img class="show-img" src="./../../static/showye1.png" alt="" />
</div>
<div class="type1" v-show="showtype === 6">
<p class="title-big">创新挑战介绍</p>
<p class="title-two">标题111</p>
<div class="show-con">
本众创空间立足功能食品生物医药和大健康产业面向科技型中小微企业创新创业团队和创客集协同创新中心公共实验室中试基地和创新创业大讲堂为一体致力于打造线上线下相结合实体虚拟相融合的全要素开放式专业化众创空间促进技术转移转化和科技型中小微企业集聚发展
本众创空间办公场所位于太原市晋阳街202号英语周报大厦8层公共实验室位于太原市师范街50号山西省生物研究院有限公司中试基地位于太原市小店区正阳街43号山西力德福科技有限公司
</div>
<p class="title-three">标题222</p>
<img class="show-img" src="./../../static/showye1.png" alt="" />
</div>
<div class="type1" v-show="showtype === 7">
<p class="title-big">联系我们</p>
<div class="we-left">
<p><span> </span>高璨 19935658782</p>
<p><span>服务热线</span>0351 5223175 5223179</p>
<p><span>电子邮箱</span>lgzc2020@163.com</p>
<p><span>物业管理</span>山西恒洁物业管理有限公司</p>
<p>
<span>公司地址</span
>山西省太原市晋阳街202号英语周报大厦八层
</p>
</div>
<img class="img1" src="@/assets/erweima.png" alt="" />
<img class="img2" src="./../../static/ditu.jpg" alt="" />
</div>
</div>
</div>
</div>
</el-collapse-transition>
</div>
</div>
</template>
<script>
export default {
name: 'Navbar',
data () {
return {
list: [{
title: '首页',
type: 1,
children: []
}, {
title: '关于我们',
type: 2,
statrtype: 1,
children: [{title: '绿谷简介', showtype: 1}, {title: '组织架构', showtype: 1}, {title: '合作伙伴', showtype: 1}, {title: '衍生企业', showtype: 1}]
}, {
title: '创新政策',
type: 2,
statrtype: 2,
children: [{title: '国家政策', showtype: 2}, {title: '省级政策', showtype: 1}, {title: '行业政策', showtype: 1}]
}, {
title: '创新平台',
type: 2,
statrtype: 3,
children: [{title: '协同中心', showtype: 3}, {title: '科技创新服务', showtype: 1}, {title: '科技资源共享服务平台', showtype: 1}, {title: '交流社区', showtype: 1}]
}, {
title: '孵化平台',
type: 2,
statrtype: 4,
children: [{title: '孵化平台介绍', showtype: 1}, {title: '实体众创空间', showtype: 1}, {title: '线上众创空间', showtype: 1}, {title: '创新创业服务', showtype: 1}, {title: '交流社区', showtype: 1}]
}, {
title: '产业平台',
type: 2,
statrtype: 5,
children: [{title: '产业技术创新联盟', showtype: 1}, {title: '衍生企业', showtype: 1}, {title: '交流社区', showtype: 1}]
}, {
title: '创新挑战',
type: 2,
statrtype: 6,
children: [{title: '创新挑战介绍', showtype: 1}, {title: '创新挑战项目征集', showtype: 1}, {title: '创新挑战项目公告', showtype: 1}, {title: '创新挑战结果公示', showtype: 1}]
}, {
title: '联系我们',
type: 2,
statrtype: 7,
children: [{title: '联系我们', showtype: 1}, {title: '我要入驻', showtype: 1}, {title: '人员招聘', showtype: 1}]
}],
isshow: 0,
active: 0,
show3: false,
urlList: ['/About', '/Policy', '/Innovate', '/Hatch', '/Industry', '/Challenge', '/Contact'],
jumpUrl: '',
showtype: 1,
showlist: [{
title: '国务院办公厅关于加快推进政务服务“跨省通办”的指导意见',
time: '2020-09-29'
}, {
title: '国务院办公厅关于同意成立2023年亚足联亚洲杯中国组委会的函',
time: '2020-09-28'
}, {
title: '国务院办公厅关于促进畜牧业高质量发展的意见',
time: '2020-09-27'
}, {
title: '中共中央办公厅国务院办公厅印发《关于加快推进媒体深度融合发展的意见》',
time: '2020-09-26'
}, {
title: '国务院办公厅转发国家发展改革委关于促进特色小镇规范健康发展意见的通知',
time: '2020-09-25'
}],
showlist1: [{
title: '中心介绍',
content: '中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍中心介绍'
}, {
title: '研发方向',
content: '研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向研发方向'
}]
}
},
methods: {
ShowLi (num, type, shownum) {
if (type === 2) {
const that = this
this.Func(num, type)
that.showtype = shownum
}
},
Showli1 (num, type) {
if (type === 1) {
this.Func(num, type)
}
},
Func (num, type) {
const that = this
if (num === 0) {
if (that.isshow !== 0) {
location.href = '/'
}
that.show3 = false
that.isshow = 0
that.active = 0
} else if (num === that.isshow && that.show3 === true) {
that.isshow = 0
that.show3 = false
that.active = 0
} else {
that.show3 = true
that.isshow = num
that.active = 0
}
let jumpNum = num - 1
that.jumpUrl = that.urlList[`${jumpNum}`]
},
changeAcitve (num, shownum) {
const that = this
that.active = num
// that.showtype = shownum
},
noShow () {
const that = this
that.show3 = false
},
leave () {
const that = this
that.show3 = false
}
}
}
</script>
<style lang="scss" scoped>
.head-box {
position: fixed;
width: 100vw;
top: 0;
z-index: 10;
background: white;
}
.transition-box {
width: 100%;
height: 35vh;
border-radius: 4px;
background-color: #fff;
text-align: center;
color: #fff;
// padding: 0 20px;
box-sizing: border-box;
margin-right: 20px;
}
.transition-left {
float: left;
height: 100%;
position: relative;
width: 40%;
box-sizing: border-box;
background: #e2e6eb;
}
.transition-right {
float: right;
height: 100%;
width: 60%;
color: #707070;
text-align: left;
box-sizing: border-box;
overflow: hidden;
}
.left-ul {
position: absolute;
width: 70%;
right: 20px;
padding-top: 20px;
box-sizing: border-box;
height: 35vh;
overflow: hidden;
}
.left-ul li {
height: 2.2rem;
margin: 0 0 2px 0 !important;
line-height: 2.2rem;
// color: #707070;
font-size: 1rem;
width: 100%;
text-align: left;
box-sizing: border-box;
padding-left: 20px;
color: #707070;
cursor: pointer;
}
.li-active {
color: white !important;
background: #4accda !important;
}
li {
list-style: none;
// height: 46px;
// line-height: 50px;
font-weight: 600;
color: white;
float: left;
text-align: center;
flex: 1;
margin: 0 20px;
}
.user {
font-size: 2rem;
color: #b8b8b8;
cursor: pointer;
}
.head-ipt-box {
position: relative;
margin-right: 30px;
}
.head-ipt {
height: 2rem;
line-height: 2rem;
width: 15rem;
outline: none;
padding-left: 20px;
font-size: 1rem;
color: #707070;
border-radius: 2.5rem;
border: 1px solid #707070;
}
.search {
font-size: 1rem;
position: absolute;
color: #b7b7b7;
font-weight: 600;
right: 10px;
top: 0.1rem;
cursor: pointer;
}
.position-right {
position: absolute;
right: 0;
font-size: 1.25rem;
}
.type1 {
height: 100%;
width: 100%;
padding-top: 1.5rem;
box-sizing: border-box;
padding-left: 2.25rem;
cursor: pointer;
position: relative;
}
.title-big {
font-size: 2rem;
height: 2rem;
line-height: 2rem;
color: #707070;
font-weight: bold;
}
.title-two {
position: absolute;
font-size: 1rem;
height: 26px;
line-height: 26px;
color: #707070;
font-weight: bold;
margin-top: 10px;
}
.show-con {
margin-top: 46px;
width: 64%;
height: auto;
color: #969696;
font-size: 0.9rem;
font-weight: bold;
overflow: hidden;
}
.show-img {
position: absolute;
width: 25%;
left: 72%;
top: 6rem;
}
.title-three {
position: absolute;
font-size: 1.1rem;
height: 26px;
line-height: 26px;
left: 72%;
top: 80px;
color: #707070;
font-weight: bold;
}
.show-con1 {
width: 100%;
height: auto;
margin-top: 20px;
}
.show-con1 li {
color: #707070;
font-size: 0.9rem;
float: none;
text-align: left;
font-weight: bold;
margin: 10px 0;
}
.show-con1-time {
color: #ccc;
}
.show-con-box {
display: flex;
margin-top: 10px;
}
.box-content {
flex: 1;
box-sizing: border-box;
margin-right: 40px;
}
.con-box-title {
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 10px;
}
.con-box-content {
color: #969696;
font-size: 0.9rem;
font-weight: bold;
}
.we-left {
margin-top: 20px;
}
.we-left p {
margin-bottom: 10px;
font-size: 0.9rem;
color: #969696;
font-weight: bold;
}
.img1 {
height: 150px;
width: 150px;
position: absolute;
top: 80px;
left: 60%;
}
.img2 {
height: 150px;
width: 150px;
position: absolute;
top: 80px;
left: 80%;
}
</style>

418
src/components/Page.vue

@ -1,418 +0,0 @@
<template>
<div class="page-box">
<div v-show="pageType === 1">
<div v-for="(item, index) in list1" :key="index" class="hauto">
<div v-if="item.colNums === 1">
<div
v-if="item.detail.style === 0"
class="oneTitle"
:style="{ width: item.detail.width + '%' }"
>
{{ item.detail.content }}
</div>
<div
v-else-if="item.detail.style === 1"
class="twoTitle"
:style="{ width: item.detail.width + '%' }"
>
{{ item.detail.content }}
</div>
<div
v-else-if="item.detail.style === 2"
class="contentText"
:style="{ width: item.detail.width + '%' }"
>
{{ item.detail.content }}
</div>
<div
v-else-if="item.detail.style === 3"
class="bigtitle"
:style="{ width: item.detail.width + '%' }"
>
<!-- 列表 -->
</div>
<div
v-else-if="item.detail.style === 4"
:style="{ width: item.detail.width + '%' }"
>
<!-- 图片样式 -->
<img :src="item.detail.content.url" class="imgStyle" alt="" />
</div>
<div
v-else-if="item.detail.style === 5"
:style="{ width: item.detail.width + '%' }"
>
<!-- 图片滚动 -->
</div>
<div
v-else-if="item.detail.style === 6"
:style="{ width: item.detail.width + '%' }"
>
<!-- 多列排序 -->
</div>
<div
v-else-if="item.detail.style === null"
:style="{ width: item.detail.width + '%' }"
>
<!-- 特殊模块 -->
特殊模块
</div>
</div>
<div v-else>
<div
v-for="(a, b) in item.colNums"
:key="b"
class="fl"
:style="{ width: item.details[a - 1].width + '%' }"
>
<div v-if="item.details[a - 1].style === 0" class="oneTitle">
{{ item.details[a - 1].content }}
</div>
<div v-if="item.details[a - 1].style === 1" class="twoTitle">
{{ item.details[a - 1].content }}
</div>
<div v-if="item.details[a - 1].style === 2" class="contentText">
{{ item.details[a - 1].content }}
</div>
<div v-if="item.details[a - 1].style === 3">
<!-- 列表 -->
</div>
<div v-if="item.details[a - 1].style === 4" class="contentImg">
<img
:src="item.details[a - 1].content.url"
class="imgStyle1"
alt=""
/>
</div>
<div v-if="item.details[a - 1].style === 5">
<div v-if="item.details[a - 1].content.style === 0">
<!-- 多列图片 -->
<img
:src="item.details[a - 1].content.url"
alt=""
class="teamimg"
/>
</div>
<div v-if="item.details[a - 1].content.style === 1">
<!-- 多列图片图片底部有文字 -->
</div>
<div v-if="item.details[a - 1].content.style === 2">
<!-- 多列图片图片下方有文字 -->
</div>
</div>
<div v-if="item.details[a - 1].style === 6">
<!-- 多列排序 -->
</div>
<div v-if="item.details[a - 1].style === null">
<!-- 特殊模块 -->
</div>
</div>
<!-- 当不只一列时此时有{{ item.colNums }} -->
</div>
</div>
</div>
<div v-show="pageType === 2">创新政策界面</div>
<div v-show="pageType === 3">创新平台界面</div>
<div v-show="pageType === 4">孵化平台界面</div>
<div v-show="pageType === 5">产业平台界面</div>
<div v-show="pageType === 6">创新挑战界面</div>
<div v-show="pageType === 7">联系我们界面</div>
</div>
</template>
<script>
export default {
name: 'Page',
props: {
pageType: {
type: Number,
default: 0
}
},
mounted: function () {
for (var i = 0; i < this.list1.length; i++) {
if (this.list1[i] && this.list1[i].detail) {
if (this.list1[i].detail.style === 4 || this.list1[i].detail.style === 5 || this.list1[i].detail.style === 6) {
if (this.list1[i].detail.content !== null) {
this.list1[i].detail.content = JSON.parse(this.list1[i].detail.content)
// console.log(this.list1[i].detail.content)
}
}
}
if (this.list1[i] && this.list1[i].details) {
for (var j = 0; j < this.list1[i].details.length; j++) {
if (this.list1[i].details[j].style === 4 || this.list1[i].details[j].style === 5 || this.list1[i].details[j].style === 6) {
this.list1[i].details[j].content = JSON.parse(this.list1[i].details[j].content)
// console.log(JSON.parse(this.list1[i].details[j].content))
}
}
}
}
console.log(this.list1)
},
data () {
return {
list: [{
bigTitle: '绿谷简介',
children: [{
twotile: '众创空间',
content: ['本众创空间立足功能食品、生物医药和大健康产业,面向科技型中小微企业、创新创业团队和创客,集协同创新中心、公共实验室、中试基地和创新创业大讲堂为一体,致力于打造线上线下相结合、实体虚拟相融合的全要素开放式专业化众创空间,促进技术转移转化和科技型中小微企业集聚发展。', '本众创空间办公场所位于太原市晋阳街202号英语周报大厦8层;公共实验室位于太原市师范街50号山西省生物研究院有限公司;中试基地位于太原市小店区正阳街43号山西力德福科技有限公司。', '英语周报大厦西临滨河东路,南靠龙城大街,城市快速路、主干道横贯,距火车南站5公里,距武宿机场11公里,交通十分便利;大厦北侧是山西省实验中学高新校区,西侧是汾河湿地公园,自然环境十分优美。'],
img: ''
}, {
twotile: '运营主体',
content: [''],
img: ''
}, {
twotile: '研究方向',
content: [''],
img: ''
}, {
twotile: '研究单位',
content: [''],
img: ''
}]
}, {
bigTitle: '组织架构',
children: [{
twotile: '',
content: [''],
img: ''
}, {}, {}, {}]
}, {
bigTitle: '合作伙伴',
children: [{
twotile: '',
content: [''],
img: ''
}, {}, {}, {}]
}, {
bigTitle: '衍生企业',
children: [{
twotile: '',
content: [''],
img: ''
}, {}, {}, {}]
}],
list1: [{
//
colNums: 1,
detail: {
id: 1,
titleId: 1,
content: '绿谷简介',
style: 0,
width: 100,
col: 1,
queryMethod: 0,
queryModule: null,
sort: 1
},
details: null
},
{
//
colNums: 1,
detail: {
id: 1,
titleId: 1,
content: '{"url":"./../../static/item001.jpg", "word":null, "style":0}',
style: 4,
width: 100,
col: 1,
queryMethod: 0,
queryModule: null,
sort: 2
},
details: null
},
{
//
colNums: 4,
detail: null,
details: [{
id: 1,
titleId: 1,
content: '{"url":"./../../static/item001.jpg", "word":null, "style":0}',
style: 5,
width: 25,
col: 1,
queryMethod: 0,
queryModule: null,
sort: 3
}, {
id: 1,
titleId: 1,
content: '{"url":"./../../static/item002.jpg", "word":null, "style":0}',
style: 5,
width: 25,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
}, {
id: 1,
titleId: 1,
content: '{"url":"./../../static/item003.jpg", "word":null, "style":0}',
style: 5,
width: 25,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
}, {
id: 1,
titleId: 1,
content: '{"url":"./../../static/item001.jpg", "word":null, "style":0}',
style: 5,
width: 25,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
}]
},
{
//
colNums: 4,
detail: null,
details: [{
id: 1,
titleId: 1,
content: 'xxxxxx',
style: 2,
width: 25,
col: 1,
queryMethod: 0,
queryModule: null,
sort: 3
},
{
id: 1,
titleId: 1,
content: 'xxxxxx',
style: 2,
width: 25,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
},
{
id: 1,
titleId: 1,
content: 'xxxxxx',
style: 2,
width: 25,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
},
{
id: 1,
titleId: 1,
content: 'xxxxxx',
style: 2,
width: 25,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
}]
},
{
// 11
colNums: 2,
detail: null,
details: [
//
{
id: 1,
titleId: 1,
content: 'xxxxxx',
style: 2,
width: 55,
col: 1,
queryMethod: 0,
queryModule: null,
sort: 3
},
//
{
id: 1,
titleId: 1,
content: '{"url":"./../../static/item002.jpg", "word":null, "style":0}',
style: 4,
width: 45,
col: 2,
queryMethod: 0,
queryModule: null,
sort: 3
}]
},
//
{
//
colNums: 1,
detail: {
id: 1,
titleId: null,
content: null,
style: null,
width: 100,
col: 1,
queryMethod: 1,
queryModule: 0, //
sort: 1
},
details: null
}]
}
}
}
</script>
<style lang="scss" scoped>
.page-box {
width: 62vw;
margin: auto;
}
.fl {
float: left;
}
.hauto {
overflow: hidden;
}
.oneTitle {
margin-top: 2rem;
font-size: 2rem;
font-weight: bold;
color: #707070;
}
.twoTitle {
margin-top: 3rem;
font-size: 1.2rem;
font-weight: bold;
color: #707070;
}
.contentText {
margin-top: 1.2rem;
font-size: 1rem;
font-weight: 400;
color: #707070;
}
.imgStyle {
width: 50%;
margin-left: 25%;
}
.imgStyle1 {
width: 100%;
}
.contentImg {
margin-top: 1.2rem;
}
.teamimg {
width: 50%;
margin-left: 25%;
}
</style>

70
src/components/Rotation/Rotation.vue

@ -0,0 +1,70 @@
<template>
<div class="head">
<a-carousel autoplay :autoplay-speed="time">
<div class="img-box" v-for="item in lists" :key="item.id">
<img :src="item.url" alt="" />
</div>
</a-carousel>
</div>
</template>
<script>
import { queryRotation } from 'config/api';
export default {
data() {
return {
time: 3000,
lists: [],
};
},
created() {
this.getData();
},
methods: {
async getData() {
try {
const params = { param: { showPage: 0 } };
const res = await queryRotation(params);
const { code, data, msg } = res.data;
if (code === 200) {
this.lists = data;
} else {
this.$message.error(error);
}
} catch (error) {
this.$message.error(error);
}
},
},
};
</script>
<style lang="stylus">
.head {
background: white;
max-height: 460px;
overflow: hidden;
}
.img-box {
height: 460px;
width: 100%;
img {
height: 100%;
width: 100%;
}
}
.ant-carousel >>> .slick-slide {
text-align: center;
height: 160px;
line-height: 160px;
background: #364d79;
overflow: hidden;
}
.ant-carousel >>> .slick-slide h3 {
color: #fff;
}
</style>

106
src/components/Sidebar.vue

@ -1,106 +0,0 @@
<template>
<div class="box" :class="trueFixed ? 'fixedT' : ''">
<router-link to="/Innovate" tag="div" class="box-content-box">
<div class="box-content" v-for="(item,index) in list" :key="index">
<p>{{ item }}</p>
</div>
</router-link>
<div class="back-top" @click="toTop()">
<p>Top</p>
</div>
</div>
</template>
<script>
export default {
name: 'Sidebar',
data () {
return {
list: ['科研设施与仪器开放共享服务平台', '技术转移转化服务平台', '功能食品与生物医药资源开发利用平台'],
trueFixed: false
}
},
props: {
num: {
type: Number,
default: 1
}
},
mounted () {
window.addEventListener('scroll', this.handleScroll)
},
methods: {
toTop () {
let top = document.documentElement.scrollTop || document.body.scrollTop
const timeTop = setInterval(() => {
document.body.scrollTop = document.documentElement.scrollTop = top -= 50
if (top <= 0) {
clearInterval(timeTop)
}
}, 10)
},
handleScroll () {
const that = this
let Box = document.getElementsByClassName('box')[0].getBoundingClientRect().top
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
let height = document.documentElement.clientHeight
if (Box <= height * 0.14) {
that.trueFixed = true
}
if (that.num === 0) {
if (scrollTop < height * 0.35) {
that.trueFixed = false
}
}
}
}
}
</script>
<style lang="scss" scoped>
p {
width: 100%;
}
.box {
z-index: 1;
height: 46vh;
margin-top: 2vh;
right: 50px;
width: 13vw;
background: #00B7CB;
border-radius: 16px;
position: absolute;
box-shadow: 4px 4px 5px #707070;
}
.fixedT {
top: 14vh !important;
right: 50px !important;
position: fixed !important;
}
.box-content-box {
height: 90%;
display: flex;
flex-direction: column;
}
.box-content {
flex: 1;
cursor: pointer;
display: flex;
text-align: center;
margin: 0 20px;
color: #FFFFFF;
font-size: 1.2rem;
font-weight: bold;
align-items: center;
border-bottom: 1px solid #FFFFFF;
}
.back-top {
height: 10%;
display: flex;
color: #FFFFFF;
align-items: center;
font-weight: bold;
text-align: center;
cursor: pointer;
}
</style>

189
src/components/User/MechanismSignUp.vue

@ -0,0 +1,189 @@
<template>
<div>
<!-- 机构注册 -->
<a-row class="d-flex flex-nowrap mt-4 pb-10" type="flex">
<a-col :span="8" class="explain" flex="auto">
<a-form :form="form" @submit="handleSignUp">
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
help="支持中文、字母、数字、“_”的组合且不能为纯数字,4-20位字符"
label="登录用户名"
required
>
<a-input v-decorator="['account']" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="单位性质" required>
<a-select placeholder="请选择单位性质" v-decorator="['nature']">
<a-select-option value="1">高校</a-select-option>
<a-select-option value="2">初中</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
help="不能超过100个字符"
label="机构全称"
required
>
<a-input v-decorator="['fullName']" />
</a-form-item>
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
help="统一社会信用代码、组织机构代码由字母和数字组成,分别为18/9位字符"
label="统一社会信用代码或组织机构代码"
required
>
<a-input v-decorator="['code']" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="登录密码" required>
<a-input-password placeholder="密码由字母和数字混合组成,6-16位字符" v-decorator="['password', { rules: passwordRules }]" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="确认密码">
<a-input-password placeholder="请再次输入您设置的密码" v-decorator="['againCredential', { rules: againPassword }]" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="手机">
<a-input
@change="changePhone"
placeholder="该手机号用于账号激活、登录及找回密码"
type="number"
v-decorator="['phone', { rules: phoneRules }]"
/>
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="图片验证码" required>
<div class="d-flex flex-nowrap">
<a-input placeholder="请输入图片验证码" type="number" v-model="codeNum" />
<img :src="picCode.imageBase64" @click="changePicCode" class="code_img ml-2" v-if="picCode && picCode.imageBase64" />
<a-button @click="changePicCode" class="code_img ml-2" size="small" type="primary" v-else>重新获取</a-button>
</div>
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="短信验证码" required>
<div class="d-flex flex-nowrap">
<a-input placeholder="请输入验证码" type="number" v-decorator="['smsCode', { rules: codeRules }]" />
<a-button class="ml-2" disabled type="primary" v-if="showInterval">重新发送 {{ interval }}</a-button>
<a-button :disabled="phone && phone.length !== 11" @click="getCode" class="ml-2" type="primary" v-else>获取验证码</a-button>
</div>
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="来源">
<a-select placeholder="请选择来源" v-decorator="['source']">
<a-select-option value="1">绿谷</a-select-option>
</a-select>
</a-form-item>
<div class="d-flex flex-row-reverse">
<a-button block class="my-5" html-type="submit" style="width: 75%" type="primary">立即注册</a-button>
</div>
</a-form>
<div class="d-flex flex-row-reverse mt-1">
<div class="d-flex flex-wrap" style="width: 75%">
<div class="flex-1"></div>
<router-link tag="span" to="/login">
<span class="baseColor">已有账号去登录</span>
</router-link>
</div>
</div>
</a-col>
<a-col :span="4" flex="150px">
<div class="d-flex flex-column">
<div>说明</div>
<div>1. 注册后即可登录部分功能需平台人员审核后才能使用</div>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex';
import mixin from 'views/User/mixin';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};
const formTailLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18, offset: 6 },
};
export default {
name: 'MechanismSignUp',
mixins: [mixin],
data() {
return {
formItemLayout,
formTailLayout,
form: this.$form.createForm(this, { name: 'mechanismSignUp' }),
phone: '',
codeNum: '',
};
},
computed: mapState(['picCode']),
created() {
this.sendPicCode();
},
methods: {
...mapActions(['signUp', 'sendCode', 'sendPicCode']),
changePhone(e) {
this.phone = e.target.value;
},
//
changePicCode() {
this.sendPicCode();
},
//
async getCode() {
try {
const params = {
phone: this.form.getFieldValue('phone'),
verificationCodeId: this.picCode.verificationCodeId,
verificationCodeValue: this.codeNum,
};
await this.sendCode(params);
this.getCodeInterval();
} catch (error) {
throw new Error(`mechanismSignUp.vue method getCode: ${error}`);
}
},
//
async handleSignUp(e) {
e.preventDefault();
this.form.validateFields(async (err, values) => {
if (!err) {
console.log('Received values of form: ', values);
try {
const { account, password, phone, smsCode, source } = values;
const params = { account, password, phone, smsCode, source };
console.log('params: ', params);
await this.signUp(params);
// TODO:
} catch (error) {
console.log(`mechanismSignUp.vue methods handleSignUp: ${error}`);
}
}
});
return;
},
},
};
</script>
<style lang="stylus" scoped>
.explain {
padding-right: 28px;
margin-right: 28px;
border-right: 1px solid #EEEEEE;
}
.code_img {
width: 102px !important;
height: 32px !important;
}
</style>

177
src/components/User/PersonalSignUp.vue

@ -0,0 +1,177 @@
<template>
<div>
<!-- 个人注册 -->
<a-row class="d-flex flex-nowrap mt-4 pb-10" type="flex">
<a-col :span="8" class="explain" flex="auto">
<a-form :form="form" @submit="handleSignUp">
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
help="支持中文、字母、数字、“_”的组合且不能为纯数字,4-20位字符"
label="登录用户名"
required
>
<a-input v-decorator="['account']" />
</a-form-item>
<a-form-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
help="不能超过20个字符"
label="昵称"
required
>
<a-input maxlength="20" v-decorator="['nickname']" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="登录密码">
<a-input-password placeholder="密码由字母和数字混合组成,6-16位字符" v-decorator="['password', { rules: passwordRules }]" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="确认密码">
<a-input-password placeholder="请再次输入您设置的密码" v-decorator="['againCredential', { rules: againPassword }]" />
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="手机">
<a-input
@change="changePhone"
placeholder="该手机号用于账号激活、登录及找回密码"
type="number"
v-decorator="['phone', { rules: phoneRules }]"
/>
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="图片验证码" required>
<div class="d-flex flex-nowrap">
<a-input placeholder="请输入图片验证码" type="number" v-model="codeNum" />
<img :src="picCode.imageBase64" @click="changePicCode" class="code_img ml-2" v-if="picCode && picCode.imageBase64" />
<a-button @click="changePicCode" class="code_img ml-2" size="small" type="primary" v-else>重新获取</a-button>
</div>
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="短信验证码" required>
<div class="d-flex flex-nowrap">
<a-input placeholder="请输入验证码" type="number" v-decorator="['smsCode', { rules: codeRules }]" />
<a-button class="ml-2" disabled type="primary" v-if="showInterval">重新发送 {{ interval }}</a-button>
<a-button :disabled="phone && phone.length !== 11" @click="getCode" class="ml-2" type="primary" v-else>获取验证码</a-button>
</div>
</a-form-item>
<a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="来源">
<a-select placeholder="请选择来源" v-decorator="['source']">
<a-select-option value="1">绿谷</a-select-option>
</a-select>
</a-form-item>
<div class="d-flex flex-row-reverse">
<a-button block class="my-5" html-type="submit" style="width: 75%" type="primary">立即注册</a-button>
</div>
</a-form>
<div class="d-flex flex-row-reverse mt-1">
<div class="d-flex flex-wrap" style="width: 75%">
<div class="flex-1"></div>
<router-link tag="span" to="/login">
<span class="baseColor">已有账号去登录</span>
</router-link>
</div>
</div>
</a-col>
<a-col :span="4" flex="150px">
<div class="d-flex flex-column">
<div>说明</div>
<div>1. 个人用户无法享受完整服务尽可能使用公司 注册</div>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex';
import mixin from 'views/User/mixin';
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};
const formTailLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18, offset: 6 },
};
export default {
name: 'PersonalSignUp',
mixins: [mixin],
data() {
return {
formItemLayout,
formTailLayout,
form: this.$form.createForm(this, { name: 'personalSignUp' }),
phone: '',
codeNum: '',
};
},
computed: mapState(['picCode']),
created() {
this.sendPicCode();
},
methods: {
...mapActions(['signUp', 'sendCode', 'sendPicCode']),
changePhone(e) {
this.phone = e.target.value;
},
//
changePicCode() {
this.sendPicCode();
},
//
async getCode() {
try {
const params = {
phone: this.form.getFieldValue('phone'),
verificationCodeId: this.picCode.verificationCodeId,
verificationCodeValue: this.codeNum,
};
await this.sendCode(params);
this.getCodeInterval();
} catch (error) {
throw new Error(`personalSignUp.vue method getCode: ${error}`);
}
},
//
async handleSignUp(e) {
e.preventDefault();
this.form.validateFields(async (err, values) => {
if (!err) {
console.log('Received values of form: ', values);
try {
const { account, password, phone, smsCode, source } = values;
const params = { account, password, phone, smsCode, source };
console.log('params: ', params);
await this.signUp(params);
//
const { query } = this.$route;
this.$router.replace({ path: '/', query });
} catch (error) {
console.log(`personalSignUp.vue methods handleSignUp: ${error}`);
}
}
});
return;
},
},
};
</script>
<style lang="stylus" scoped>
.explain {
padding-right: 28px;
margin-right: 28px;
border-right: 1px solid #EEEEEE;
}
.code_img {
width: 102px !important;
height: 32px !important;
}
</style>

26
src/config/api-user.js

@ -0,0 +1,26 @@
/*
* Copyright (c) 2020.
* author: wally
* email: 18603454788@163.com
*/
import axios from 'axios';
let { proxyUrl, msgUrl } = require('@/config/setting');
const tall = `${proxyUrl}/tall/v1.0`;
// console.log('tall: ', tall);
const users = `${tall}/users`;
// 用户登录
export const signIn = params => axios.post(`${users}/signin`, params);
// 注册
export const signUp = params => axios.post(`${users}/signup`, params);
// 图片验证码
export const getPicCode = () => axios.get(`${users}/code`);
// 发送验证码
export const getSmscode = params => axios.get(`${users}/smscode`, params);
// 通过手机号修改密码
export const changePassword = params => axios.post(`${users}/password`, params);

40
src/config/api.js

@ -0,0 +1,40 @@
/*
* Copyright (c) 2019.
* author: wally
* email: 18603454788@163.com
*/
import axios from 'axios';
let { proxyUrl, msgUrl } = require('@/config/setting');
const greenvalley = `${proxyUrl}/greenvalley`;
// const page = `${greenvalley}/page`; // 创新平台相关操作
const policy = `${proxyUrl}/policy/policy`; // 创新政策相关接口
const activity = `${greenvalley}/activity`; // 创新政策相关接口
const Business = `${greenvalley}//Business`; // 衍生企业和合作伙伴查询
const carousel = `${greenvalley}//carousel`; // 轮播图相关接口
// websocket基础地址
export const WS_BASE_URL = msgUrl;
// 查询政策列表
export const selLikePolicy = params => axios.post(`${policy}/selLikePolicy`, params);
// 查询政策详情
export const selPolicy = params => axios.post(`${policy}/selPolicy`, params);
// 申请加入三大平台
export const JoinPlatform = params => axios.post(`${greenvalley}/platform/JoinPlatform`, params);
// 上传附件
export const upload = `${greenvalley}/file/upload`;
// 加入我们
export const joinUs = params => axios.post(`${greenvalley}/PersonApply/joinUs`, params);
// 查询轮播图
export const queryRotation = params => axios.post(`${greenvalley}/carousel/query`, params);
// 查询行业政策列表
export const industryInfo = params => axios.post(`${greenvalley}/industryInfo/beforeSearch`, params);
// 查询活动公告列表
export const front = params => axios.post(`${activity}/query/front`, params);
// 申请加入活动
export const apply = params => axios.post(`${activity}/apply`, params);
// 查询衍生企业
export const FrontSearchFriend = params => axios.post(`${Business}/FrontSearchFriend`, params);
// 查询合作伙伴
export const FrontSearchCompany = params => axios.post(`${Business}/FrontSearchCompany`, params);

19
src/config/selComment.js

@ -0,0 +1,19 @@
/*
* Copyright (c) 2019.
* author: wally
* email: 18603454788@163.com
*/
import axios from 'axios';
let { proxyUrl, msgUrl } = require('@/config/setting');
const greenvalley = `${proxyUrl}/greenvalley`;
const comment = `${greenvalley}/comment`; // 交流社区
// 发帖
export const addComment = params => axios.post(`${comment}/addComment`, params);
// 发帖查询
export const selComment = params => axios.post(`${comment}/selComment`, params);
// 跟帖发表(评论发表)
export const insComment = params => axios.post(`${comment}/insComment`, params);
// 跟帖查询(评论查询)
export const selCommunity = params => axios.post(`${comment}/selCommunity`, params);

30
src/config/setting.js

@ -0,0 +1,30 @@
const title = process.env.VUE_APP_TITLE;
const description = process.env.VUE_APP_DESCRIPTION;
const baseUrl = process.env.VUE_APP_BASE_URL;
const apiUrl = process.env.VUE_APP_API_URL;
const proxyUrl = process.env.VUE_APP_PROXY_URL;
const publicPath = process.env.VUE_APP_PUBLIC_PATH;
const msgUrl = process.env.VUE_APP_MSG_URL;
module.exports = {
// 首页标题
title,
// 首页描述信息
description,
// 基础地址
baseUrl,
// api基础地址
apiUrl,
// 消息系统地址
msgUrl,
// api代理地址
proxyUrl,
// 生成文件目录 publicPath
publicPath,
};

19
src/config/user.js

@ -0,0 +1,19 @@
/*
* Copyright (c) 2019.
* author: wally
* email: 18603454788@163.com
*/
// 用户登录client
export const SIGN_IN_CLIENTS = { mp: 0, h5: 1, android: 2, ios: 3 };
// 用户登录类型
export const SIGN_IN_TYPES = {
mp: 0,
phone: 1,
email: 2,
username: 3,
wx: 4,
wx_web: 5,
wb: 6,
};

40
src/main.js

@ -1,27 +1,23 @@
import Vue from 'vue' // @ts-ignore
import Vue from 'vue';
import './plugins/axios';
import App from './App.vue';
import './registerServiceWorker';
import router from './router';
import store from './store';
import './plugins/ant-design-vue.js';
import 'common/portrait.styl';
import './assets/icon/iconfont.css';
import VueDOMPurifyHTML from 'vue-dompurify-html';
import moment from 'moment'; //导入文件
Vue.prototype.$moment = moment; //赋值使用
import ElementUI from 'element-ui' Vue.config.productionTip = false;
import 'element-ui/lib/theme-chalk/index.css'
import '@/styles/index.scss' Vue.use(VueDOMPurifyHTML);
import 'babel-polyfill' window.vm = new Vue({
import App from './App'
import store from './store'
import router from './router'
import './assets/icon/iconfont.css'
Vue.use(ElementUI)
Vue.config.productionTip = false
router.afterEach((to, from, next) => {
window.scrollTo(0, 0)
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router, router,
store, store,
components: { App }, render: h => h(App),
template: '<App/>' }).$mount('#app');
})

72
src/plugins/ant-design-vue.js

@ -0,0 +1,72 @@
import Vue from 'vue';
import {
Pagination,
Button,
Input,
message,
notification,
Modal,
Tag,
Table,
Tabs,
Icon,
Empty,
Form,
Select,
Upload,
Badge,
Popconfirm,
DatePicker,
Switch,
Radio,
Dropdown,
Menu,
Row,
Col,
Timeline,
Checkbox,
BackTop,
Carousel,
Avatar,
} from 'ant-design-vue';
import { ConfigProvider } from 'ant-design-vue';
Vue.component(ConfigProvider.name, ConfigProvider);
Vue.use(Pagination);
Vue.use(Button);
Vue.use(Input);
Vue.use(Modal);
Vue.use(Tag);
Vue.use(Table);
Vue.use(Tabs);
Vue.use(Icon);
Vue.use(Empty);
Vue.use(Form);
Vue.use(Select);
Vue.use(Upload);
Vue.use(Badge);
Vue.use(Popconfirm);
Vue.use(DatePicker);
Vue.use(Switch);
Vue.use(Radio);
Vue.use(Dropdown);
Vue.use(Menu);
Vue.use(Row);
Vue.use(Col);
Vue.use(Timeline);
Vue.use(Checkbox);
Vue.use(BackTop);
Vue.use(Carousel);
Vue.use(Avatar);
Vue.prototype.$message = message;
Vue.prototype.$notification = notification;
Vue.prototype.$info = Modal.info;
Vue.prototype.$success = Modal.success;
Vue.prototype.$error = Modal.error;
Vue.prototype.$warning = Modal.warning;
Vue.prototype.$confirm = Modal.confirm;
message.config({
duration: 3,
maxCount: 3,
});

77
src/plugins/axios.js

@ -0,0 +1,77 @@
'use strict';
import Vue from 'vue';
import axios from 'axios';
import router from '../router/index';
import store from '../store/index';
// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
let config = {
// baseURL: process.env.baseURL || process.env.apiUrl || ""
timeout: 60 * 1000, // Timeout
// withCredentials: true, // Check cross-site Access-Control
};
const _axios = axios.create(config);
axios.interceptors.request.use(
function(config) {
let token = store.state.anyringToken || sessionStorage.getItem('anyringToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
},
);
// Add a response interceptor
axios.interceptors.response.use(
function(response) {
if (response.data && response.data.code >= 400 && response.data.code < 500) {
store.commit('user/sign', '');
router.replace({
path: '/user/login',
query: { redirect: router.currentRoute.fullPath },
});
}
// Do something with response data
return response;
},
function(error) {
// Do something with response error
return Promise.reject(error);
},
);
Plugin.install = function(Vue) {
Vue.axios = _axios;
window.axios = _axios;
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios;
},
},
$axios: {
get() {
return _axios;
},
},
$http: {
get() {
return _axios;
},
},
});
};
Vue.use(Plugin);
export default Plugin;

34
src/registerServiceWorker.js

@ -0,0 +1,34 @@
/* eslint-disable no-console */
import { register } from "register-service-worker";
if (process.env.NODE_ENV === "production") {
register(`${process.env.BASE_URL}service-worker.js`, {
ready() {
console.log(
"App is being served from cache by a service worker.\n" +
"For more details, visit https://goo.gl/AFskqB"
);
},
registered() {
console.log("Service worker has been registered.");
},
cached() {
console.log("Content has been cached for offline use.");
},
updatefound() {
console.log("New content is downloading.");
},
updated() {
console.log("New content is available; please refresh.");
},
offline() {
console.log(
"No internet connection found. App is running in offline mode."
);
},
error(error) {
console.error("Error during service worker registration:", error);
}
});
}

139
src/router/index.js

@ -1,56 +1,95 @@
import Vue from 'vue' import Vue from 'vue';
import Router from 'vue-router' import VueRouter from 'vue-router';
// import Navbar from '@/components/Navbar' import Home from 'views/FirstPage/FirstPage.vue';
Vue.use(Router) Vue.use(VueRouter);
export default new Router({ const routes = [
routes: [ // 首页
{ {
path: '/', path: '/',
name: 'FristPage', name: 'Home',
component: () => import('@/views/FirstPage/FirstPage') component: Home,
}, { },
path: '/About', // 登录界面
name: 'About', {
component: () => import('@/views/About/About.vue'), path: '/login',
children: [{ name: 'Login',
path: 'Introduction', component: () => import(/* webpackChunkName: "Login" */ 'views/User/Login.vue'),
name: 'Introduction', },
component: () => import('@/views/About/Children/Introduction.vue') // 注册界面
}] {
}, { path: '/register',
name: 'Register',
component: () => import(/* webpackChunkName: "register" */ 'views/User/Register.vue'),
},
// 修改密码
{
path: '/forget-password',
name: 'ForgetPassword',
component: () => import(/* webpackChunkName: "forget-password" */ 'views/User/ForgetPassword.vue'),
},
// 政策界面
{
path: '/Policy', path: '/Policy',
name: 'Policy', name: 'Policy',
component: () => import('@/views/Policy/Policy.vue') component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Policy/Policy.vue'),
}, { },
path: '/Innovate', // 政策详情界面
name: 'Innovate', {
component: () => import('@/views/Innovate/Innovate.vue') path: '/Policy/PolicyDetails',
}, { name: 'PolicyDetails',
path: '/Hatch', component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Policy/PolicyDetails.vue'),
name: 'Hatch', },
component: () => import('@/views/Hatch/Hatch.vue') // 交流社区界面
}, { {
path: '/Industry', path: '/Community',
name: 'Industry', name: 'Community',
component: () => import('@/views/Industry/Industry.vue') component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Community/Community.vue'),
}, { },
path: '/Challenge', // 交流社区发帖界面
name: 'Challenge', {
component: () => import('@/views/Challenge/Challenge.vue') path: '/Posting',
}, { name: 'Posting',
path: '/Contact', component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Community/Posting.vue'),
name: 'Contact', },
component: () => import('@/views/Contact/Contact.vue') // 交流帖子详情页
}, { {
path: '/Login', path: '/ComDetails',
name: 'Login', name: 'ComDetails',
component: () => import('@/views/Login/Login.vue') component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Community/ComDetails.vue'),
}, { },
path: '/Demand', // 行业资讯界面
name: 'Demand', {
component: () => import('@/views/Demand/Demand.vue') path: '/ItInformation',
} name: 'ItInformation',
] component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/ItInformation/ItInformation.vue'),
}) },
// 活动公告界面
{
path: '/Activity',
name: 'Activity',
component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Activity/Activity.vue'),
},
// 活动公告详情界面
{
path: '/ActDetails',
name: 'ActDetails',
component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/Activity/ActDetails.vue'),
},
// 关于我们界面
{
path: '/About',
name: 'About',
component: () => import(/* webpackChunkName: "cooperative-enterprise" */ 'views/About/About.vue'),
},
,
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
export default router;

143
src/store/actions.js

@ -0,0 +1,143 @@
import axios from 'axios';
import { message } from 'ant-design-vue';
import { getSmscode, getPicCode, signIn, changePassword, signUp, getUserId } from 'config/api-user';
const actions = {
/**
* sendCode 发送验证码
* @param {any} commit
* @param {object} params 提交的数据
* @param {string} params.phone 手机号
*/
async sendCode({ commit }, params) {
try {
const res = await getSmscode({ params });
const { code, msg, data } = res.data;
if (code === 200) {
return data;
} else {
message.error(msg || '发送失败');
throw msg;
}
} catch (error) {
throw error || '发送失败';
}
},
/**
* sendPicCode 获取图片验证码
* @param {any} commit
* @param {object} params 提交的数据
*/
async sendPicCode({ commit }) {
try {
const res = await getPicCode();
const { code, msg, data } = res.data;
if (code === 200) {
commit('setPicCode', data);
return data;
} else {
throw msg;
}
} catch (error) {
throw error || '获取失败';
}
},
/**
* signIn 登录
* @param {any} commit
* @param {string} identifier 身份标识 手机号 用户名
* @param {string} credential 身份凭证 验证码 密码
* @return {Promise} result 服务器返回信息
*/
async signIn({ commit }, params) {
const hideLoading = message.loading('登录中', 0);
try {
const res = await signIn(params);
const { code, msg, data } = res.data;
if (code === 200) {
commit('sign', data.token);
commit('setUser', data);
hideLoading();
message.success('登录成功');
return data;
} else {
hideLoading();
throw msg || '登录失败';
}
} catch (error) {
hideLoading();
throw error || '登录失败';
}
},
/**
* 修改密码 忘记密码
* @param {any} commit
* @param {object} params 要提交的参数
*/
async changePassword({ commit }, params) {
try {
const res = await changePassword(params);
const { code, msg, data } = res.data;
if (code === 200) {
message.success('修改密码成功');
return data;
} else {
throw msg || '修改密码失败';
}
} catch (error) {
throw error || '修改密码失败';
}
},
/**
* singUp 注册新用户
* @param {any} commit
* @param {object} params 提交的数据
* @param {string} params.account 用户名
* @param {string} params.password 密码
* @param {string} params.phone 手机号
* @param {string} params.smsCode 验证码
*/
async signUp({ commit }, params) {
try {
const res = await signUp(params);
const { code, msg, data } = res.data;
if (code === 200) {
commit('sign', data.token);
commit('setUser', data);
message.success('注册成功');
return data;
} else {
throw msg || '注册失败';
}
} catch (error) {
throw error || '注册失败';
}
},
/**
* 通过userId获取token
* @param {any} commit
* @param {object} params 提交的参数
*/
// async getUserId({ commit }, params) {
// try {
// const res = await getUserId({ params });
// const { code, msg, data } = res.data;
// if (code === 200) {
// commit('sign', data.token);
// commit('setUser', data);
// return data;
// } else {
// throw msg;
// }
// } catch (error) {
// throw error || '获取个人信息失败';
// }
// },
};
export default actions;

7
src/store/getters.js

@ -0,0 +1,7 @@
const getters = {};
// 域定制导航展示形式
// 0 -> 无特殊导航文字
// 1 -> 横向定制导航
// 2 -> 纵向定制导航
export default getters;

20
src/store/index.js

@ -1,10 +1,16 @@
import Vue from 'vue' import Vue from "vue";
import Vuex from 'vuex' import Vuex from "vuex";
import userInfo from './loginInfo/index' import mutations from './mutations';
import actions from './actions';
import state from './state';
import getters from './getters';
Vue.use(Vuex);
Vue.use(Vuex)
const store = new Vuex.Store({ const store = new Vuex.Store({
modules: { userInfo } state,
}) mutations,
actions,
});
export default store export default store;

5
src/store/loginInfo/actions.js

@ -1,5 +0,0 @@
const actions = {
}
export default actions

5
src/store/loginInfo/index.js

@ -1,5 +0,0 @@
import state from './state'
import mutations from './mutations'
import actions from './actions.js'
export default { namespaced: true, state, actions, mutations }

7
src/store/loginInfo/mutations.js

@ -1,7 +0,0 @@
const mutations = {
setInfo (state, loginInfo) {
if (!loginInfo) return
state.loginInfo = loginInfo
}
}
export default mutations

5
src/store/loginInfo/state.js

@ -1,5 +0,0 @@
const state = {
loginInfo: {}
}
export default state

134
src/store/mutations.js

@ -0,0 +1,134 @@
import { List } from 'ant-design-vue';
const mutations = {
/**
* 设置token
* @param { object } state
* @param { string } token
*/
sign(state, token) {
state.anyringToken = token;
sessionStorage.setItem('anyringToken', token);
},
/**
* 设置user用户信息
* @param {object} state
* @param {object} user {id, account, phone}
*/
setUser(state, user) {
if (!user) return;
state.user = { ...user };
sessionStorage.setItem('user', JSON.stringify(user));
},
/**
* 图片验证码
* @param {object} state
* @param {object} picCode
*/
setPicCode(state, picCode) {
state.picCode = { ...picCode };
},
/**
* 获取显示政策的ID
* @param {object} state
* @param {Number} num
*/
setPolicyId(state, num) {
state.policyId = num;
},
/**
* 改变当前政策页数
* @param {object} state
* @param {Number} num
*/
setCurrent(state, num) {
state.current = num;
},
/**
* 改变当前政策列表
* @param {object} state
* @param {object} data
*/
setPolicyStatus(state, data) {
state.policyStatus = { ...data };
},
/**
* 改变当前政策页数
* @param {object} state
* @param {Number} num
*/
setComCurrent(state, num) {
state.comCurrent = num;
},
/**
* 查看帖子详情
* @param {object} state
* @param {object} data
*/
setPostDetail(state, data) {
state.postDetail = { ...data };
},
/**
* 改变当前帖子所选类型
* @param {object} state
* @param {Number} num
*/
setPostVal(state, num) {
state.postVal = num;
},
/**
* 改变当前帖子搜索框内容
* @param {object} state
* @param {object} obj
*/
setPostIpCon(state, data) {
state.postIpCon = data;
},
/**
* 改变当前活动公告搜索类型
* @param {object} state
* @param {List} list
*/
setActList(state, list) {
state.actList = list;
},
/**
* 改变当前活动公告搜索框内容
* @param {object} state
* @param {string} str
*/
setActIpCon(state, str) {
state.actIpCon = str;
},
/**
* 改变当前活动公告处于第几页
* @param {object} state
* @param {Number} num
*/
setActCurrent(state, num) {
state.actCurrent = num;
},
/**
* 存储当前活动公告详情
* @param {object} state
* @param {object} data
*/
setActDetail(state, data) {
state.actDetail = { ...data };
},
};
export default mutations;

25
src/store/state.js

@ -0,0 +1,25 @@
const state = {
anyringToken: '',
user: { id: '', phone: '', account: '' },
policyId: 0,
current: 1, // 政策当前处于第几页,默认1
comCurrent: 1, // 帖子列表当前处于第几页,默认1
policyStatus: {
bw: 0,
sx: 0,
zg: 0,
value: 1, // 搜索框当前选项value
code: 'title', // 搜索框当前选项code
policyText: ['标题', '地区', '发布部门'], // 搜索框选项列表
iptCon: '', // 搜索框input内容
},
postDetail: {}, // 当前帖子详情
postVal: 0, // 当前帖子所选类型
postIpCon: '', // 帖子搜索框内容
actList: [], // 活动公告当前所选类型
actIpCon: '', // 活动公告搜索框内容
actCurrent: 1, // 活动公告当前处于第几页
actDetail: {}, // 当前活动公告详情
};
export default state;

54
src/styles/index.scss

@ -1,54 +0,0 @@
.nav-head{
width: 100%;
padding: 0 1rem;
line-height: 5rem;
height: 9vh;
box-sizing: border-box;
}
.head-left{
float: left;
box-sizing: border-box;
height: 9vh;
position: relative;
img{
position: absolute;
top: 1.5vh;
height: 6vh;
}
}
.head-right{
height: 9vh;
line-height: 9vh;
float: right;
margin-right: 1vw;
}
.nav-con{
width: 100%;
padding: 0 1rem;
box-sizing: border-box;
height: 5vh;
background: #00B7CB;
}
.li-con{
height: 5vh;
line-height: 5vh;
cursor: pointer;
box-sizing: border-box;
margin: auto;
width: 5rem;
}
.lishow{
border-bottom: 4px solid white;
}
.nav-con-ul{
display: flex;
width: 100%;
height: 5vh;
align-items: flex-start;
justify-content: space-between;
}
// .footer{
// width: 100%;
// height: 485px;
// background: #E2E6EB;
// }

25
src/views/About/About.vue

@ -1,30 +1,19 @@
<template> <template>
<div> <div>
<left-fixed :type="type" /> {{ str }}
<!-- 关于我们界面 -->
<sidebar :num="typeNum" />
<page :pageType="pageType" />
<router-view></router-view>
</div> </div>
</template> </template>
<script> <script>
import LeftFixed from '@/components/LeftFixed'
import Sidebar from '@/components/Sidebar'
import Page from '@/components/Page'
export default { export default {
name: 'About', name: 'About',
components: { LeftFixed, Sidebar, Page }, data() {
data () {
return { return {
typeNum: 1, str: '这是关于我们界面',
type: 1, list: [],
pageType: 1 };
}
}, },
methods: {} };
}
</script> </script>
<style lang="scss" scoped> <style lang="stylus" scoped></style>
</style>

74
src/views/About/Children/Introduction.vue

@ -1,74 +0,0 @@
<template>
<div class="box">
</div>
</template>
<script>
export default {
name: 'Introduction',
data () {
return {
list: [{
bigTitle: '绿谷简介',
children: [{
twotile: '众创空间',
content: '',
img: ''
}, {
twotile: '运营主体',
content: '',
img: ''
}, {
twotile: '研究方向',
content: '',
img: ''
}, {
twotile: '研究单位',
content: '',
img: ''
}]
}, {
bigTitle: '组织架构',
children: [{
twotile: '',
content: '',
img: ''
}, {}, {}, {}]
}, {
bigTitle: '合作伙伴',
children: [{
twotile: '',
content: '',
img: ''
}, {}, {}, {}]
}, {
bigTitle: '衍生企业',
children: [{
twotile: '',
content: '',
img: ''
}, {}, {}, {}]
}]
}
}
}
</script>
<style lang="scss" scoped>
.box{
width: 62.5vw;
height: 50px;
margin-top: 40px !important;
margin: auto;
}
.page-title {
margin-bottom: 40px;
}
.small-title {
margin-bottom: 10px;
}
.small-content {
margin-bottom: 10px;
}
</style>

19
src/views/About/components/Introduce.vue

@ -0,0 +1,19 @@
<template>
<div>
{{ str }}
</div>
</template>
<script>
export default {
name: 'Introduce',
data() {
return {
str: '这是公司介绍界面',
list: [],
};
},
};
</script>
<style lang="stylus" scoped></style>

19
src/views/About/components/Organ.vue

@ -0,0 +1,19 @@
<template>
<div>
{{ str }}
</div>
</template>
<script>
export default {
name: 'Organ',
data() {
return {
str: '这是组织机构界面',
list: [],
};
},
};
</script>
<style lang="stylus" scoped></style>

19
src/views/About/components/Partner.vue

@ -0,0 +1,19 @@
<template>
<div>
{{ str }}
</div>
</template>
<script>
export default {
name: 'Partner',
data() {
return {
str: '这是合作伙伴界面',
list: [],
};
},
};
</script>
<style lang="stylus" scoped></style>

115
src/views/Activity/ActDetails.vue

@ -0,0 +1,115 @@
<template>
<div class="box">
<div>
<div class="policy-title">
<span>{{ actDetail.title }}</span>
</div>
<div class="policy-info">
<span>
<a-icon type="clock-circle" class="baseColor" style="font-size: 14px; margin-right: 10px" />
<span>{{ actDetail.releaseTime }}-{{ actDetail.closeTime }}</span>
</span>
<span style="margin-left: 60px">
<a-icon type="environment" style="margin-right: 10px" class="baseColor" />
<span>{{ actDetail.address }}</span>
</span>
</div>
<div class="policy-content" v-dompurify-html="actDetail.content"></div>
<enroll style="margin: 50px 25px" :fnval="actDetail.activityId" />
</div>
</div>
</template>
<script>
import { mapState } from 'vuex';
import Enroll from './components/Enroll.vue';
export default {
name: 'ActDetails',
components: { Enroll },
data() {
return {};
},
computed: mapState(['actDetail']),
created() {},
methods: {},
};
</script>
<style lang="stylus" scoped>
.box {
width: 1260px;
position: relative;
margin: 80px auto;
background: #fff;
min-height: 1037px;
overflow: hidden;
opacity: 1;
padding-bottom: 480px;
}
.back-btn {
width: 80px;
position: absolute;
right: 0;
}
.policy-title {
height: 120px;
font-size: 24px;
font-family: Microsoft YaHei;
font-weight: 400;
color: rgba(0, 0, 0, 0.85);
opacity: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
padding: 0 150px;
border-bottom: 1px solid #707070;
}
.policy-info {
height: 76px;
line-height: 76px;
text-align: center;
}
.policy-content {
padding: 0 25px;
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
font-weight: 400;
font-family: Microsoft YaHei;
}
.coms-style {
height: 480px;
padding: 25px 0;
border-top: 2px solid #ccc;
position: absolute;
bottom: 0;
width: 100%;
}
.coms-top {
height: 280px;
padding: 0 25px;
overflow: auto;
box-shadow: 0 0 5px #ccc;
}
.coms-btm {
margin-top: 20px;
padding: 0 10px;
}
.coms-content {
background: rgba(19, 172, 196, 0.1);
}
.sub {
position: absolute;
right: 20px;
bottom: 20px;
}
</style>

234
src/views/Activity/Activity.vue

@ -0,0 +1,234 @@
<!--
Copyright (c) 2020.
author: song
email: 15235360226@163.com
-->
<template>
<div class="wrap">
<div class="search-list">
<span>
<a-checkbox :checked="sta.ly === 1" @click="cSta('ly')"> 路演 </a-checkbox>
<a-checkbox :checked="sta.jz === 1" @click="cSta('jz')"> 讲座 </a-checkbox>
<a-checkbox :checked="sta.sl === 1" @click="cSta('sl')"> 沙龙 </a-checkbox>
</span>
<a-input-search class="search" v-model="iptCon" style="width: 381px" placeholder="请输入..." enter-button="搜索" @search="getData" />
</div>
<div class="policy-box">
<div v-for="(item, index) in lists" :key="index" class="div-box">
<div @click="jumpDetails(item)" style="cursor: pointer">
<p class="item-title">{{ item.title }}</p>
<p class="item-content">{{ item.content }}</p>
<p class="source-time">
<span class="source">时间{{ item.releaseTime }}-{{ item.closeTime }}</span>
<span class="time">地点{{ item.address }}</span>
</p>
</div>
<p class="original">
<enroll :fnval="item.activityId" />
<!-- <a-button type="primary">立即报名</a-button> -->
</p>
</div>
</div>
<a-pagination show-quick-jumper class="pagination" :current="actCurrent" :total="total" show-less-items @change="onShowSizeChange" />
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex';
import { front } from 'config/api';
import Enroll from './components/Enroll.vue';
export default {
name: 'Activity',
components: { Enroll },
data() {
return {
str: '这是活动公告界面',
total: 0,
iptCon: '',
sta: {
ly: 0,
jz: 0,
sl: 0,
},
aList: [],
lists: [],
};
},
computed: mapState(['actList', 'actIpCon', 'actCurrent']),
created() {
this.iptCon = this.actIpCon;
this.aList = this.actList;
for (var i = 0; i < this.aList.length; i++) {
if (this.aList[i] === 0) {
this.sta.ly = 1;
}
if (this.aList[i] === 1) {
this.sta.jz = 1;
}
if (this.aList[i] === 2) {
this.sta.sl = 1;
}
}
this.getData();
},
methods: {
...mapMutations(['setActList', 'setActIpCon', 'setActCurrent', 'setActDetail']),
//
async getData() {
try {
this.setActIpCon(this.iptCon);
const params = {
param: {
activityType: this.actList,
pageNum: this.actCurrent,
pageSize: 5,
title: this.iptCon,
},
};
const res = await front(params);
const { data, msg, code } = res.data;
if (code === 200) {
this.lists = data.list;
this.total = parseInt(data.total);
}
} catch (error) {
console.log(error);
}
},
//
cSta(index) {
this.aList = [];
if (this.sta[index] === 0) {
this.sta[index] = 1;
console.log(this.sta);
} else {
this.sta[index] = 0;
console.log(this.sta);
}
if (this.sta.ly === 1) {
this.aList = this.aList.concat(0);
}
if (this.sta.jz === 1) {
this.aList = this.aList.concat(1);
}
if (this.sta.sl === 1) {
this.aList = this.aList.concat(2);
}
this.setActList(this.aList);
this.getData();
},
//
onShowSizeChange(current, size) {
this.setActCurrent(current);
this.getData();
},
//
jumpDetails(item) {
this.setActDetail(item);
this.$router.push('/ActDetails');
},
},
};
</script>
<style scoped lang="stylus">
.wrap {
width: 1260px;
min-height: 1037px;
margin: 80px auto 28px auto;
overflow: hidden;
opacity: 1;
}
.search-list {
height: 72px;
line-height: 72px;
position: relative;
padding-left: 24px;
background: #fff;
}
.policy-box {
.div-box {
position: relative;
height: 238px;
background: #fff;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
margin-top: 24px;
padding: 25px;
}
}
.item-title {
overflow: hidden;
display: -webkit-box;
font-size: 20px;
color: rgba(0, 0, 0, 0.65);
font-family: Microsoft YaHei;
font-weight: bold;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.item-content {
text-indent: 2em;
overflow: hidden;
display: -webkit-box;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
font-family: Microsoft YaHei;
font-weight: bold;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.source {
font-family: Microsoft YaHei;
font-weight: 400;
opacity: 1;
margin-right: 24px;
}
.time {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
opacity: 1;
}
.original {
position: absolute;
right: 25px;
bottom: 25px;
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
line-height: 22px;
color: rgba(0, 0, 0, 0.65);
opacity: 1;
margin-bottom: 0;
span {
cursor: pointer;
}
}
.source-time {
position: absolute;
bottom: 60px;
color: rgba(0, 0, 0, 0.45);
margin-bottom: 0;
}
.pagination {
margin-top: 68px;
text-align: right;
}
.search {
position: absolute;
right: 24px;
top: 20px;
}
</style>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save