Commit 0c6439eb by 潘琦

Initial commit

parents
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
/build/
/config/
/dist/
/*.js
/test/unit/coverage/
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: 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: [
'vue'
],
// add your custom rules here
rules: {
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
/test/unit/coverage/
/test/e2e/reports/
selenium-debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}
# voucher-h5
> voucher h5 project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
# run unit tests
npm run unit
# run e2e tests
npm run e2e
# run all tests
npm test
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
'use strict'
const 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'
}
}
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
'use strict'
const 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 = process.env.NODE_ENV === 'testing'
? require('../config/test.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: process.env.NODE_ENV === 'testing'
? 'index.html'
: 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
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
// const url = 'http://voucher.check.icaremgt.com' // 开发
const url = 'http://voucher.icaremgt.com' // 正式
// const sjkgurl = 'https://api-wx-service.check.icaremgt.com' // 机构空间(开发)
const sjkgurl = 'https://sjkg-wx-service.icaremgt.com' // 机构空间(正式)
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/admin': {
target: url,
changeOrigin: true
},
'/auth': {
target: url,
changeOrigin: true
},
'/apply': {
target: url,
changeOrigin: true
},
'/basic': {
target: url,
changeOrigin: true
},
'/make': {
target: url,
changeOrigin: true
},
'/sjkgbasic': {
target: url,
changeOrigin: true
},
'/v1': {
target: sjkgurl,
changeOrigin: true
}
},
// Various Dev Server settings
host: '0.0.0.0', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
'use strict'
module.exports = {
NODE_ENV: '"production"'
}
'use strict'
const merge = require('webpack-merge')
const devEnv = require('./dev.env')
module.exports = merge(devEnv, {
NODE_ENV: '"testing"'
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<title>凯歌健康券</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "voucher-h5",
"version": "1.0.0",
"description": "voucher h5 project",
"author": "panqi@icaremgt.com <panqi@icaremgt.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
"build": "node build/build.js"
},
"dependencies": {
"axios": "^0.19.0",
"mint-ui": "^2.2.13",
"nprogress": "^0.2.0",
"qrcodejs2": "0.0.2",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^3.1.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-jest": "^21.0.2",
"babel-loader": "^7.1.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"chromedriver": "^2.27.2",
"copy-webpack-plugin": "^4.0.1",
"cross-spawn": "^5.0.1",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"jest": "^22.0.4",
"jest-serializer-vue": "^0.3.0",
"nightwatch": "^0.9.12",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-jest": "^1.0.2",
"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"
]
}
This diff is collapsed. Click to expand it.
import request from '@/router/request'
// 获取当前用户可使用的健康券
export function imageBase64 (params) {
return request({
url: '/admin/file/base64/' + params,
method: 'GET'
})
}
import request from '@/router/request'
// 获取当前用户可使用的健康券
export function getUserCard (size, params) {
return request({
url: '/apply/info/page',
method: 'POST',
params: { size: size },
data: params
})
}
// 根据user id获取用户待使用健康券
export function getunUsedCountById (params) {
return request({
url: '/apply/info/count',
method: 'POST',
data: params
})
}
// 根据user id获取用户信息
export function getUserInfoByUserId (params) {
return request({
url: '/basic/userrelation/list/' + params,
method: 'GET'
})
}
// 获取健康券信息
export function getVoucherInfoById (params) {
return request({
url: '/apply/info/' + params,
method: 'GET'
})
}
// 根据券voucherId获取券相关操作按钮
export function getButtonByVoucherId (params) {
return request({
url: '/apply/info/content/' + params,
method: 'GET'
})
}
// 根据券makeId获取内容流
export function getContentListByMakeId (makeId, params) {
return request({
url: '/apply/content/' + makeId,
method: 'GET',
params: params
})
}
// 根据券voucherId获取核销券二维码
export function getQrCodeByVoucherId (params) {
return request({
url: '/apply/info/generateQrCode/' + params,
method: 'GET'
})
}
// 根据券voucherId获取券小贴士
export function getTipsByVoucherId (params) {
return request({
url: '/apply/info/tips/' + params,
method: 'GET'
})
}
// 根据用户id获取用户所有健康券
export function getAllVoucherByUserId (params) {
return request({
url: '/apply/info/getAll/' + params,
method: 'GET'
})
}
// 获取知识详情信息
export function getContentInfo (params) {
return request({
url: '/apply/content/getContentInfo/' + params,
method: 'GET'
})
}
import request from '@/router/request'
// 鉴权
export function getOauth (params) {
return request({
url: '/auth/oauth/token',
headers: {
isToken: false,
'TENANT_ID': '1',
'Authorization': 'Basic dGVzdDp0ZXN0'
},
method: 'POST',
params: params
})
}
import request from '@/router/request'
// 根据id获取用户家庭成员数据
export function getUserInfoByUserId (params) {
return request({
url: '/basic/userrelation/list/' + params,
method: 'GET'
})
}
// 根据id获取用户家庭成员数据(家庭成员页调用)
export function getMemberByMainId (params) {
return request({
url: '/basic/user/relation/' + params,
method: 'GET'
})
}
// 根据id获取该用户信息
export function getUserInfoById (params) {
return request({
url: '/basic/user/' + params,
method: 'GET'
})
}
// 保存家庭成员
export function saveMember (params) {
return request({
url: '/basic/user/verified',
method: 'POST',
data: params
})
}
// 删除家庭成员
export function deleteMemberById (params) {
return request({
url: '/basic/user/family',
method: 'DELETE',
params: params
})
}
// 验证用户是否已实名认证
export function userRealStateById (params) {
return request({
url: '/basic/user/real/' + params,
method: 'GET'
})
}
import request from '@/router/request'
// 获取机构健康券
export function getVoucherByOrgId (params) {
return request({
url: '/make/info/' + params + '/vouchers',
method: 'GET'
})
}
import request from '@/router/requestSjkg'
// 获取全国省市区街
export function getAreaList (params) {
return request({
url: '/v1/addressArea/list',
method: 'POST',
params: params
})
}
// 根据街道获取居委会
export function getVillages (params) {
return request({
url: '/v1/addressArea/getAreaList',
method: 'POST',
params: params
})
}
// 获取机构与团队信息
export function getOrgInfo (params) {
return request({
url: '/v1/voucher/getByOrgAndGroup',
method: 'POST',
params: params
})
}
// 获取用户生育全程签约信息
export function getSignInfo (params) {
return request({
url: '/v1/voucher/poll',
method: 'POST',
data: params
})
}
import request from '@/router/request'
// 根据经纬度获取附近机构列表
export function getOrgListByPosition (params) {
return request({
url: '/sjkgbasic/org/list/position',
method: 'GET',
params: params
})
}
import request from '@/router/requestToken'
// 团队列表
export function WXconfirm(params) {
return request({
url: '/wxjsauth/getToken',
method: 'post',
params
})
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li>
<a
href="https://vuejs.org"
target="_blank"
>
Core Docs
</a>
</li>
<li>
<a
href="https://forum.vuejs.org"
target="_blank"
>
Forum
</a>
</li>
<li>
<a
href="https://chat.vuejs.org"
target="_blank"
>
Community Chat
</a>
</li>
<li>
<a
href="https://twitter.com/vuejs"
target="_blank"
>
Twitter
</a>
</li>
<br>
<li>
<a
href="http://vuejs-templates.github.io/webpack/"
target="_blank"
>
Docs for This Template
</a>
</li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li>
<a
href="http://router.vuejs.org/"
target="_blank"
>
vue-router
</a>
</li>
<li>
<a
href="http://vuex.vuejs.org/"
target="_blank"
>
vuex
</a>
</li>
<li>
<a
href="http://vue-loader.vuejs.org/"
target="_blank"
>
vue-loader
</a>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
>
awesome-vue
</a>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
<template>
<div class="card-item">
<img src="../assets/images/card-item-bg.png" class="bg"/>
<div class="card-item-content">
<div class="card-item-table">
<div class="card-item-cell price">
<div class="label">{{data.cost}}<span class="unit"></span></div>
<div>{{data.voucherType === '1' ? '提醒券' : data.voucherType === '2' ? '健康券' : data.voucherType === '3' ? '代金券' : ''}}</div>
</div>
<div class="card-item-cell info">
<div class="title">{{data.voucherName}}</div>
<p>类型:{{data.categoryName}}</p>
<p>机构:{{data.deptName}}</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CardItem',
data () {
return {
}
},
props: ['data'],
created () {
},
mounted: function () {
},
computed: {
},
methods: {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.card-item {
position: relative;
margin-bottom: 0.6em;
}
.card-item > .bg {
width: 100%;
}
.card-item > .card-item-content{
position: absolute;
right: 0;
left:0;
top:0;
bottom: 0;
}
.card-item > .card-item-content > .card-item-table {
display: table;
width: 100%;
height: 100%;
font-size: 1em;
}
.card-item > .card-item-content > .card-item-table > .card-item-cell {
display: table-cell;
vertical-align: middle;
}
.card-item > .card-item-content > .card-item-table > .price{
width: 30%;
color:#43d1be;
text-align:center;
}
.card-item > .card-item-content > .card-item-table > .price .label {
font-size: 2.5em;
font-weight: bold;
color:#43d1be;
padding: 0;
}
.card-item > .card-item-content > .card-item-table > .price .label > .unit {
font-size:40%;
font-weight:normal;
}
.card-item > .card-item-content > .card-item-table > .info {
width:70%;
color:#35444f;
padding-left:1em;
position:relative;
font-size: 0.9em;
}
.card-item > .card-item-content > .card-item-table > .info p {
margin-bottom: 0;
/* display: inline-block;
white-space: nowrap;
overflow: hidden;
width: 13em; */
}
.card-item > .card-item-content > .card-item-table > .info .title{
font-size: 1.3em;
font-weight:bold;
margin-bottom:0.5em;
}
</style>
<template>
<div class="content-item" v-if="data">
<div class="head">
<div class="cell picture">
<img :src="data.cover"/>
</div>
<div class="cell title">
{{data.producerName}}
</div>
</div>
<div class="body">
<div class="info">
<div class="title">{{data.mainTitle}}</div>
<div class="des">{{data.subheading}}</div>
<div class="date">{{data.releaseTime}}</div>
</div>
<div class="poster">
<div class="frame" v-if="data.producerPicUrl!==''" :style="{backgroundImage: 'url(' + data.producerPicUrl + ')' }"></div>
<div class="frame" v-if="data.producerPicUrl===''" :style="{backgroundImage: 'url(' + producerPicUrl + ')' }"></div>
<!-- <img :src="data.producerPicUrl !== '' ? data.producerPicUrl : producerPicUrl"/> -->
</div>
</div>
</div>
</template>
<script>
import _producerPicUrl from '../assets/images/org-default-picture.png'
export default {
name: 'ContentItem',
data () {
return {
producerPicUrl: _producerPicUrl
}
},
props: ['data'],
created () {
},
mounted: function () {
},
computed: {
},
methods: {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.content-item {
padding: 0.5em;
border-bottom:1px solid #eee;
min-height: 8em;
}
.content-item > .head {
display:table;
width:100%;
padding:0.6em 0;
}
.content-item > .head > .cell {
display: table-cell;
vertical-align: middle;
}
.content-item > .head > .cell.picture{
width: 2.5em;
}
.content-item > .head > .cell.picture > img{
width: 100%;
}
.content-item > .head > .cell.title {
font-size: 1em;
padding-left: 10px;
}
.content-item > .body {
display:table;
width:100%;
}
.content-item > .body > .info,
.content-item > .body > .poster {
display: table-cell;
vertical-align: middle;
color:#999999;
}
.content-item > .body > .info {
vertical-align: top;
position:relative;
padding-bottom: 1em;
/* width: 70% */
}
.content-item > .body > .info > .title {
font-size: 1.1em;
font-weight: bold;
margin-bottom: 0.2em;
color: #4B5760;
white-space:nowrap;
text-overflow:ellipsis;
max-width: 13em;
overflow:hidden;
}
.content-item > .body > .info > .date {
position:absolute;
width:100%;
bottom:0;
left:0;
}
.content-item > .body > .poster{
width: 7em;
}
.content-item > .body > .poster > .frame {
width: 7em;
height: 7em;
background-repeat: no-repeat;
background-size: 100% auto;
}
.content-item > .body > .poster > img {
width: 100%;
}
</style>
<template>
<div class="coupon-item">
<img src="../assets/images/coupon-item-bg.png" class="bg"/>
<div class="coupon-content">
<div class="coupon-table">
<div class="cell info">
<div class="title">{{data.name}}</div>
<div class="price">{{data.cost}}<span class="unit"></span></div>
<small class="des">{{data.labelId === 1 || data.labelId === 3 ? '孕产妇检券':data.labelId === 2 ? '儿童健康体检券': ''}}</small>
</div>
<div class="cell btn"></div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'couponItem',
data () {
return {
}
},
props: ['data'],
created () {
},
mounted: function () {
},
computed: {
},
methods: {
}
}
</script>
<style scoped>
.coupon-item {
position:relative;
padding: 0.5em 1em 0 1em;
}
.coupon-item > .bg {
width: 100%;
}
.coupon-item > .coupon-content {
position:absolute;
left:1em;
top:1em;
bottom:0;
right:1em;
}
.coupon-item > .coupon-content > .coupon-table{
display:table;
width:100%;
height:100%;
}
.coupon-item > .coupon-content > .coupon-table > .cell {
display:table-cell;
vertical-align:middle;
}
.coupon-item > .coupon-content > .coupon-table > .info{
padding-left: 2.5em;
width: 77%;
}
.coupon-item > .coupon-content > .coupon-table > .info .title{
font-size: 1.1em;
color:#9B7F53;
width:12em;
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;
}
.coupon-item > .coupon-content > .coupon-table > .info .price {
font-size: 2em;
color:#E9462B;
margin:0.1em 0;
font-weight:bold;
}
.coupon-item > .coupon-content > .coupon-table > .info .price > .unit {
font-size: 50%;
font-weight:normal;
}
.coupon-item > .coupon-content > .coupon-table > .info .des{
font-size: 0.8em;
color:#9B7F53;
}
</style>
<template>
<div class="list-item" @click="clickHandle">
<div class="list-item-cell picture">
<img :src="data.itemPoster" class="full-width"/>
</div>
<div class="list-item-cell info">
<div class="title text-danger">{{data.title ? data.title : ""}}<span class="text-danger">({{data.subTitle}}项可使用)</span></div>
<p v-for="(item, index) in data.des" :key="index">{{item}}</p>
</div>
<div class="list-item-cell arrow">
<i class="glyphicon glyphicon-menu-right"></i>
</div>
</div>
</template>
<script>
export default {
name: 'ListItem',
data () {
return {
}
},
props: ['data'],
created () {
},
mounted: function () {
},
computed: {
},
methods: {
clickHandle () {
this.$emit('clickHandle')
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.list-item {
background-color:#ffffff;
border-radius: 5px;
box-shadow: 1px 8px 10px #e2e3e4;
margin-bottom: 1.2em;
display: table;
width: 100%;
font-size: 1em;
}
.list-item > div {
display: table-cell;
vertical-align: middle;
}
.list-item > .picture {
width:35%;
padding:1em 0 1em 1em;
}
.list-item > .info {
padding:1em 0.8em;
color:#9aa0a4;
}
.list-item > .info .title{
font-size: 1em;
font-weight:bold;
margin-bottom:0.5em;
}
.list-item > .info p {
margin-bottom: 0;
}
.list-item > .arrow {
width: 1.6em;
font-size: 1.2em;
color: #949595;
text-align: left;
}
</style>
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import './permission' // 权限
import {
Button,
Cell,
Field,
Navbar,
TabItem,
Header,
Popup,
Picker,
Spinner,
Toast,
MessageBox,
TabContainer,
TabContainerItem,
DatetimePicker,
Indicator,
Actionsheet,
Radio,
InfiniteScroll
} from 'mint-ui'
import 'mint-ui/lib/style.css'
Vue.component(TabContainer.name, TabContainer)
Vue.component(TabContainerItem.name, TabContainerItem)
Vue.component(Button.name, Button)
Vue.component(Cell.name, Cell)
Vue.component(Field.name, Field)
Vue.component(Navbar.name, Navbar)
Vue.component(TabItem.name, TabItem)
Vue.component(Header.name, Header)
Vue.component(Popup.name, Popup)
Vue.component(Picker.name, Picker)
Vue.component(Spinner.name, Spinner)
Vue.component(DatetimePicker.name, DatetimePicker)
Vue.component(Actionsheet.name, Actionsheet)
Vue.component(Radio.name, Radio)
Vue.use(InfiniteScroll)
Vue.prototype.$toast = Toast
Vue.prototype.$MessageBox = MessageBox
Vue.prototype.$Indicator = Indicator
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
import router from './router'
import {getStore, setStore} from '@/util/store'
// import {validatenull} from '@/util/validate'
import { getOauth } from '@/api/auth/auth'
import { Toast } from 'mint-ui'
router.beforeEach((to, from, next) => {
console.log('缓冲设置')
let accessToken = getStore({ name: 'access_token' })
if (accessToken) {
next()
} else {
let spoauthParams = {
username: 'admin',
password: '0nQrmF2Zl9jz40AIUbpsbg==',
// randomStr: '13131563353180801',
// code: '4882',
grant_type: 'password',
scope: 'server'
}
getOauth(spoauthParams).then(function (res) {
if (res.access_token && res.access_token !== '' && res.user_id && res.user_id !== '') {
setStore({ name: 'access_token', content: res.access_token })
setStore({ name: 'user_id', content: res.user_id })
next()
} else {
Toast({
message: 'token不能为空!',
position: 'center',
duration: 3000
})
}
}).catch((error) => {
console.log(error)
Toast({
message: '鉴权失败',
position: 'center',
duration: 3000
})
})
}
// // 缓冲设置
// if (to.meta.keepAlive === true && store.state.tags.tagList.some(ele => {
// return ele.value === to.fullPath
// })) {
// to.meta.$keepAlive = true
// } else {
// NProgress.start()
// if (to.meta.keepAlive === true && validatenull(to.meta.$keepAlive)) {
// to.meta.$keepAlive = true
// } else {
// to.meta.$keepAlive = false
// }
// }
// const meta = to.meta || {}
// if (store.getters.access_token) {
// if (store.getters.isLock && to.path != lockPage) {
// next({path: lockPage})
// } else if (to.path === '/login') {
// next({path: '/'})
// } else {
// if (store.getters.roles.length === 0) {
// store.dispatch('GetUserInfo').then(() => {
// next({...to, replace: true})
// }).catch(() => {
// store.dispatch('FedLogOut').then(() => {
// next({path: '/login'})
// })
// })
// } else {
// const value = to.query.src || to.fullPath
// const label = to.query.name || to.name
// if (meta.isTab !== false && !validatenull(value) && !validatenull(label)) {
// store.commit('ADD_TAG', {
// label: label,
// value: value,
// params: to.params,
// query: to.query,
// group: router.$avueRouter.group || []
// })
// }
// next()
// }
// }
// } else {
// if (meta.isAuth === false) {
// next()
// } else {
// next('/h5')
// }
// }
})
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: () => import('@/views/home/index'),
meta: {keepAlive: false, title: '凯歌电子券'}
},
{
path: '/signing',
name: 'signing',
component: () => import('@/views/signing/index'),
meta: {keepAlive: false, title: '生育全程签约'}
},
{
path: '/vouchers',
name: 'vouchers',
component: () => import('@/views/vouchers/index'),
meta: {keepAlive: false, title: '我的健康券'}
},
{
path: '/voucherDetail',
name: 'detail',
component: () => import('@/views/voucherDetail/index'),
meta: {keepAlive: false, title: '服务券详情'}
},
{
path: '/user',
name: 'user',
component: (resolve) => require(['@/views/user/index'], resolve),
redirect: '/user/index',
meta: {keepAlive: false, title: '我的福利'},
children: [
{
path: 'index',
name: '我的福利',
component: (resolve) => require(['@/views/user/index'], resolve),
meta: {keepAlive: false, title: '我的福利'}
}
]
},
{
path: '/member',
name: 'member',
component: (resolve) => require(['@/views/member/index'], resolve),
redirect: '/member/list',
meta: {keepAlive: false, title: '家庭成员'},
children: [
{
path: 'list',
name: '家庭成员',
component: (resolve) => require(['@/views/member/list'], resolve),
meta: {keepAlive: false, title: '家庭成员'}
},
{
path: 'edit',
name: '编辑家庭成员',
component: (resolve) => require(['@/views/member/edit'], resolve),
meta: {keepAlive: false, title: '编辑家庭成员'}
},
{
path: 'addMain',
name: '实名认证',
component: (resolve) => require(['@/views/member/addMain'], resolve),
meta: {keepAlive: false, title: '实名认证'}
},
{
path: 'addMember',
name: '添加家庭福利',
component: (resolve) => require(['@/views/member/addMember'], resolve),
meta: {keepAlive: false, title: '添加家庭福利'}
}
]
},
{
path: '/content',
name: 'content',
component: () => import('@/views/content/index'),
meta: {keepAlive: false, title: '知识详情'}
},
{
path: '/recommend',
name: 'recommend',
component: (resolve) => require(['@/views/recommend/index'], resolve),
redirect: '/recommend/list',
meta: {keepAlive: false, title: '健康券推荐'},
children: [
{
path: 'list',
name: '健康券推荐',
component: (resolve) => require(['@/views/recommend/list'], resolve),
meta: {keepAlive: false, title: '健康券推荐'}
},
{
path: 'orglist',
name: '去医院',
component: (resolve) => require(['@/views/recommend/orglist'], resolve),
meta: {keepAlive: false, title: '去医院'}
}
]
}
]
})
import axios from 'axios'
import { getStore, setStore } from '@/util/store'
import { Toast } from 'mint-ui'
import router from '@/router/index'
axios.defaults.timeout = 30000
// 返回其他状态吗
axios.defaults.validateStatus = function (status) {
return status // 默认的
}
// 跨域请求,允许保存cookie
axios.defaults.withCredentials = true
// request拦截器
axios.interceptors.request.use(config => {
let token = getStore({name: 'access_token'})
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
}
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone拦截器
axios.interceptors.response.use(response => {
const res = response.data ? response.data : response
const status = Number(response.status) || 200
console.log('response status:' + status)
if (status !== 200) {
if (status === 401) {
Toast({
message: '您因长时间逗留,验证已过期,正在刷新!',
position: 'center',
duration: 5 * 1000
})
setStore({ name: 'access_token', content: '' })
setTimeout(function () {
window.location.reload()
}, 5 * 1000)
} else if (status === 403) {
if (res.msg === '请先进行实名认证') { // 跳转至社区推荐页
router.push({
path: '/recommend'
})
}
} else {
if (!res.msg) {
res.msg = '内部服务器错误[500]'
}
return Promise.reject(new Error(res.msg))
}
}
return res
}, error => {
console.log('错误' + error)// for debug
Toast({
message: error.message,
position: 'center',
duration: 5 * 1000
})
return Promise.reject(new Error(error))
})
export default axios
import axios from 'axios'
import { getStore, setStore } from '@/util/store'
import { Toast } from 'mint-ui'
axios.defaults.timeout = 30000
// 返回其他状态吗
axios.defaults.validateStatus = function (status) {
return status // 默认的
}
// 跨域请求,允许保存cookie
axios.defaults.withCredentials = true
// request拦截器
axios.interceptors.request.use(config => {
let token = getStore({name: 'access_token'})
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
}
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone拦截器
axios.interceptors.response.use(response => {
const res = response.data ? response.data : response
const status = Number(response.status) || 200
if (status !== 200) {
// Toast({
// message: res.msg,
// position: 'center',
// duration: 5 * 1000
// })
if (status === 401) {
Toast({
message: '您因长时间逗留,验证已过期,正在刷新!',
position: 'center',
duration: 5 * 1000
})
setStore({ name: 'access_token', content: '' })
return
} else {
return Promise.reject(new Error(res.msg))
}
}
return res
}, error => {
console.log('错误' + error)// for debug
Toast({
message: error.message,
position: 'center',
duration: 5 * 1000
})
return Promise.reject(new Error(error))
})
export default axios
import axios from 'axios'
import { Toast } from 'mint-ui'
// const defaultUrl = 'http://www.icareyou.net/' // 正式
const defaultUrl = 'http://test.icareyou.net/' // 开发
// 创建axios实例
const service = axios.create({
baseURL: defaultUrl,
timeout: 15000 // 请求超时时间
})
// respone拦截器
service.interceptors.response.use(
response => {
const res = response.data
if (res.code === 1004) {
Toast({
message: res.message,
position: 'center',
duration: 5 * 1000
})
} else {
return res
}
},
error => {
console.log('错误' + error)// for debug
Toast({
message: error.message,
position: 'center',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
const getters = {
access_token: state => state.common.access_token,
user_id: state => state.common.user_id,
userInfo: state => state.user.userInfo
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import common from './modules/common'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
common,
user
},
getters
})
export default store
import { getStore, setStore } from '@/util/store'
const common = {
state: {
access_token: getStore({ name: 'access_token' }),
user_id: getStore({ name: 'user_id' })
},
actions: {
AccessToken (context, id) {
context.commit('access_token', id)
},
UserId (context, id) {
context.commit('user_id', id)
}
},
mutations: {
SET_ACCESSTOKEN: (state, active) => {
this.state.access_token = active
setStore({
name: 'access_token',
content: state.access_token
})
},
SET_USERID: (state, active) => {
this.state.user_id = active
setStore({
name: 'user_id',
content: state.user_id
})
}
}
}
export default common
// import { getStore, setStore } from '@/util/store'
const user = {
state: {
userInfo: {}
},
actions: {
},
mutations: {
SET_USERIFNO: (state, userInfo) => {
state.userInfo = userInfo
}
}
}
export default user
/**
* 取消滚动条
* @param {*} s
*/
export function noscroll () {
document.getElementById('app').classList.add('noscroll')
}
/**
* 恢复滚动条
* @param {*} s
*/
export function renewscroll () {
document.getElementById('app').classList.remove('noscroll')
}
/**
* 根据身份证获取性别
* @param {*} s
*/
export function getSexByIdCard (idNumber) {
let sex = '3'
if (idNumber && idNumber !== '' && idNumber.length === 18) {
if (idNumber.substring(16, 17) % 2 === 0) {
sex = '2'
} else {
sex = '1'
}
}
return sex
}
/**
* 根据身份证获取生日
* @param {*} s
*/
export function getBirthByIdNumber (idNumber) {
let birth = ''
if (idNumber.length === 18) {
birth = idNumber.substring(6, 14)
} else if (idNumber.length === 15) {
birth = '19' + idNumber.substring(6, 12)
}
if (birth !== '') {
birth = birth.replace(/(.{4})(.{2})/, '$1-$2-')
}
return birth
}
/**
* 根据出生年月获取年龄
* @param {*} s
*/
export function getAgeByBirth (birth) {
console.log('getAgeByBirth')
if (!birth || birth === '') {
return ''
}
const nowDate = new Date()
let year = nowDate.getFullYear()
let month = nowDate.getMonth() + 1
let day = nowDate.getDate()
let birthYear = parseInt(birth.split('-')[0])
let birthMonth = parseInt(birth.split('-')[1])
let birthDay = parseInt(birth.split('-')[2])
let differYear = -1
let differMonth = -1
let differDay = -1
let age = ''
if (year === birthYear) {
if (month === birthMonth) {
differDay = day - birthDay
} else if (month > birthMonth) {
differYear = 0
if (day > birthDay) {
differMonth = month - birthMonth
differDay = day - birthDay
} else if (day < birthDay) {
differMonth = month - birthMonth - 1
differDay = new Date(birthYear, birthMonth, 0).getDate() - birthDay + day
} else {
differMonth = month - birthMonth
differDay = 0
}
}
} else if (year > birthYear) {
differYear = year - birthYear
if (month > birthMonth) {
differMonth = month - birthMonth
} else if (month < birthMonth) {
differYear = differYear - 1
differMonth = 12 - (birthMonth - month)
} else {
if (day > birthDay) {
differMonth = birthMonth - month
} else if (day < birthDay) {
differYear = differYear - 1
differMonth = 11
} else {
differMonth = birthMonth - month
}
}
}
if (differYear >= 0 && differMonth >= 0) {
if (differYear > 0) {
age = differYear + '岁'
}
if (differMonth > 0) {
age = age + differMonth + '月'
}
if (differDay > 0) {
age = age + differDay + '天'
}
} else {
age = differDay + '天'
}
return age
}
/**
* 计算当天之前多少天日期
* @param {*} s
*/
export function SubtractDay (day) {
let date = new Date() // 获取当前时间
date.setDate(date.getDate() - day)
return date
}
import {
validatenull
} from '@/util/validate'
const keyName = 'voucher-'
/**
* 存储localStorage
*/
export const setStore = (params = {}) => {
let {
name,
content,
type
} = params
name = keyName + name
let obj = {
dataType: typeof (content),
content: content,
type: type,
datetime: new Date().getTime()
}
if (type) window.sessionStorage.setItem(name, JSON.stringify(obj))
else window.localStorage.setItem(name, JSON.stringify(obj))
}
/**
* 获取localStorage
*/
export const getStore = (params = {}) => {
let {
name,
debug
} = params
name = keyName + name
let obj = {}
let content
obj = window.sessionStorage.getItem(name)
if (validatenull(obj)) obj = window.localStorage.getItem(name)
if (validatenull(obj)) return
try {
obj = JSON.parse(obj)
} catch (e) {
return obj
}
if (debug) {
return obj
}
if (obj.dataType === 'string') {
content = obj.content
} else if (obj.dataType === 'number') {
content = Number(obj.content)
} else if (obj.dataType === 'boolean') {
content = obj.content
} else if (obj.dataType === 'object') {
content = obj.content
}
return content
}
/**
* 删除localStorage
*/
// export const removeStore = (params = {}) => {
// let {
// name,
// type
// } = params
// name = keyName + name
// if (type) {
// window.sessionStorage.removeItem(name)
// } else {
// window.localStorage.removeItem(name)
// }
// }
// /**
// * 获取全部localStorage
// */
// export const getAllStore = (params = {}) => {
// let list = [];
// let {
// type
// } = params;
// if (type) {
// for (let i = 0; i <= window.sessionStorage.length; i++) {
// list.push({
// name: window.sessionStorage.key(i),
// content: getStore({
// name: window.sessionStorage.key(i),
// type: 'session'
// })
// })
// }
// } else {
// for (let i = 0; i <= window.localStorage.length; i++) {
// list.push({
// name: window.localStorage.key(i),
// content: getStore({
// name: window.localStorage.key(i),
// })
// })
// }
// }
// return list;
// }
// /**
// * 清空全部localStorage
// */
// export const clearStore = (params = {}) => {
// let { type } = params;
// if (type) {
// window.sessionStorage.clear();
// } else {
// window.localStorage.clear()
// }
// }
/**
* 邮箱
* @param {*} s
*/
export function isEmail (s) {
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
}
/**
* 手机号码
* @param {*} s
*/
export function isMobile (s) {
return /^1[0-9]{10}$/.test(s)
}
/**
* 电话号码
* @param {*} s
*/
export function isPhone (s) {
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
}
/**
* URL地址
* @param {*} s
*/
export function isURL (s) {
return /^http[s]?:\/\/.*/.test(s)
}
/* 合法uri */
export function validateURL (textval) {
const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return urlregex.test(textval)
}
/* 小写字母 */
export function validateLowerCase (str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/* 大写字母 */
export function validateUpperCase (str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/* 大小写字母 */
export function validatAlphabets (str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/* 验证pad还是pc */
export const vaildatePc = function () {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone',
'SymbianOS', 'Windows Phone',
'iPad', 'iPod'
]
let flag = true
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false
break
}
}
return flag
}
/**
* validate email
* @param email
* @returns {boolean}
*/
export function validateEmail (email) {
const re = /^(([^<>()\\[\]\\.,;:\s@"]+(\.[^<>()\\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return re.test(email)
}
/**
* 判断身份证号码
*/
export function cardid (code) {
let list = []
let result = true
let msg = ''
var city = {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江 ',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北 ',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏 ',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: '新疆',
71: '台湾',
81: '香港',
82: '澳门',
91: '国外 '
}
if (!validatenull(code)) {
console.log('=======')
if (code.length === 18) {
if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) {
msg = '证件号码格式错误'
} else if (!city[code.substr(0, 2)]) {
msg = '地址编码错误'
} else {
// 18位身份证需要验证最后一位校验位
code = code.split('')
// ∑(ai×Wi)(mod 11)
// 加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
// 校验位
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x']
var sum = 0
var ai = 0
var wi = 0
for (var i = 0; i < 17; i++) {
ai = code[i]
wi = factor[i]
sum += ai * wi
}
console.log(sum % 11)
if (parity[sum % 11].toString() !== code[17]) {
msg = '证件号码校验位错误'
} else {
result = false
}
}
} else {
msg = '证件号码长度不为18位'
}
} else {
msg = '证件号码不能为空'
}
list.push(result)
list.push(msg)
return list
}
/**
* 判断手机号码是否正确
*/
export function isvalidatemobile (phone) {
let list = []
let result = true
let msg = ''
var isPhone = /^0\d{2,3}-?\d{7,8}$/
// 增加134 减少|1349[0-9]{7},增加181,增加145,增加17[678]
if (!validatenull(phone)) {
if (phone.length === 11) {
if (isPhone.test(phone)) {
msg = '手机号码格式不正确'
} else {
result = false
}
} else {
msg = '手机号码长度不为11位'
}
} else {
msg = '手机号码不能为空'
}
list.push(result)
list.push(msg)
return list
}
/**
* 判断姓名是否正确
*/
export function validatename (name) {
console.log(name)
var regName = /^[a-zA-Z]+$|^[\u4e00-\u9fa5]{1,15}$/
if (!regName.test(name)) return false
return true
}
/**
* 判断是否为整数
*/
export function validatenum (num, type) {
let regName = /[^\d.]/g
if (type === 1) {
if (!regName.test(num)) return false
} else if (type === 2) {
regName = /[^\d]/g
if (!regName.test(num)) return false
}
return true
}
/**
* 判断是否为小数
*/
export function validatenumord (num, type) {
let regName = /[^\d.]/g
if (type === 1) {
if (!regName.test(num)) return false
} else if (type === 2) {
regName = /[^\d.]/g
if (!regName.test(num)) return false
}
return true
}
/**
* 判断是否为空
*/
export function validatenull (val) {
if (typeof val === 'boolean') {
return false
}
if (typeof val === 'number') {
return false
}
if (val instanceof Array) {
if (val.length === 0) return true
} else if (val instanceof Object) {
if (JSON.stringify(val) === '{}') return true
} else {
if (val === 'null' || val === null || val === 'undefined' || val === undefined || val === '') return true
return false
}
return false
}
/**
* <img> <a> src 处理
* @returns {PromiseLike<T | never> | Promise<T | never>}
*/
// export function handleImg(fileName, id) {
// return validatenull(fileName)?null: request({
// url: '/admin/file/' + fileName,
// method: 'get',
// responseType: 'blob'
// }).then((response) => { // 处理返回的文件流
// let blob = response.data;
// let img = document.getElementById(id);
// img.src = URL.createObjectURL(blob);
// window.setTimeout(function () {
// window.URL.revokeObjectURL(blob)
// }, 0)
// })
// }
<template>
<div class="full-page">
<div class="container contentPage">
<div class="head">
<div class="list-item">
<div class="list-item-cell picture">
<span class="avatar" :style="{backgroundImage:'url(' + data.producerPicUrl + ')'}"></span>
</div>
<div class="list-item-cell info">
<div class="title">{{data.producerName}}</div>
<p>{{data.producerOrgName}}</p>
</div>
<div class="list-item-cell tool">
<i class="glyphicon glyphicon-share"></i>
</div>
</div>
</div>
<div class="content" v-html="data.content"></div>
</div>
</div>
</template>
<script>
// import { getUserCard, getunUsedCountById } from '@/api/apply/apply'
import { getContentInfo } from '@/api/apply/apply'
import defaultOrgImg from '../../assets/images/org-default-picture.png'
export default {
name: 'Home',
data () {
return {
imprId: this.$route.query.imprId,
data: {
producerPicUrl: '',
producerName: '',
producerOrgName: '',
content: ''
}
}
},
created () {
this.getContentInfoFn(this.imprId)
},
mounted: function () {
},
computed: {
},
components: {
},
methods: {
getContentInfoFn (imprId) {
this.$Indicator.open()
getContentInfo(imprId).then(res => {
this.$Indicator.close()
if (res.code === 0) {
this.data = {
producerPicUrl: res.data.producerPicUrl !== '' ? res.data.producerPicUrl : defaultOrgImg,
producerName: res.data.producerName,
producerOrgName: res.data.producerOrgName,
content: res.data.content
}
}
}).catch((error) => {
this.$toast({
message: error.message,
position: 'center',
duration: 3000
})
})
}
}
}
</script>
<style scoped>
.full-page {
background-color: #ffffff;
}
.contentPage .head {
padding: 1em 0;
}
.contentPage .head > .list-item {
display: table;
width: 100%;
}
.contentPage .head > .list-item > .list-item-cell {
display: table-cell;
vertical-align: middle;
}
.contentPage .head > .list-item > .list-item-cell.picture {
width: 4.5em;
}
.contentPage .head > .list-item > .list-item-cell.picture > .avatar{
display: inline-block;
width: 4em;
height: 4em;
border-radius: 50%;
background-repeat: no-repeat;
background-size: 100% auto;
}
.contentPage .head > .list-item > .list-item-cell.info {
border-bottom:1px solid #ccc;
}
.contentPage .head > .list-item > .list-item-cell.info > .title {
font-size: 1.1em;
}
.contentPage .head > .list-item > .list-item-cell.tool {
width: 2em;
font-size: 1.8em;
color: #43d1be;
text-align: right;
border-bottom:1px solid #ccc;
}
</style>
<template>
<div class="full-page">
<div class="container">
<div class="p-title">
<span class="label">我的健康券</span>
<span class="link" @click="goToVouchers">查看全部 <i class="glyphicon glyphicon-menu-right"></i></span>
</div>
<ul>
<li v-for="(item, index) in voucherData" :key="index" @click="goToDetail(item.voucherId, item.makeId)">
<CardItem :data="item"></CardItem>
</li>
</ul>
<div class="p-title">
<span class="label">我的福利</span>
</div>
<div @click="goToUser">
<ListItem :data="userInfo"></ListItem>
</div>
</div>
</div>
</template>
<script>
import { getStore } from '@/util/store'
// import store from '@/store'
import CardItem from '@/components/cardItem'
import ListItem from '@/components/listItem'
import { getUserCard, getunUsedCountById } from '@/api/apply/apply'
import { getUserInfoByUserId } from '@/api/basic/basic'
import _itemPoster from '../../assets/images/doctor.jpg'
export default {
name: 'Home',
data () {
return {
userId: getStore({ name: 'user_id' }),
voucherData: [],
userInfo: {
name: '',
subTitle: 0,
itemPoster: _itemPoster,
des: [
'国家基本公卫服务;',
'家庭医疗健康服务;'
]
}
}
},
created () {
this.getUserCardByIdFn() // 获取当前用户待使用健康券(前3条)
this.getUserInfoByUserIdFn() // 获取当前用户基本信息
this.getunUsedCountByIdFn() // 获取当前用户待使用健康券数量
// store.commit('SET_USERIFNO', {name: '1'})
},
mounted: function () {
},
computed: {
},
components: {
CardItem,
ListItem
},
methods: {
getUserCardByIdFn () {
let parmas = {
states: [1],
userId: this.userId
}
getUserCard(3, parmas).then(res => {
if (res.code === 0) {
this.voucherData = res.data
}
}).catch((error) => {
this.$toast({
message: error.message,
position: 'center',
duration: 3000
})
})
},
getUserInfoByUserIdFn () {
getUserInfoByUserId(this.userId).then(res => {
if (res.code === 0) {
this.userInfo.title = res.data[0].name
this.$store.commit('SET_USERIFNO', res.data[0])
}
}).catch((error) => {
this.$toast({
message: error.message,
position: 'center',
duration: 3000
})
})
},
getunUsedCountByIdFn () {
let parmas = {
states: [1],
userId: this.userId
}
getunUsedCountById(parmas).then(res => {
if (res.code === 0) {
this.userInfo.subTitle = res.data
}
}).catch((error) => {
this.$toast({
message: error.message,
position: 'center',
duration: 3000
})
})
},
goToDetail (voucherId, makeId) {
this.$router.push({
path: '/voucherDetail',
query: {
voucherId: voucherId,
makeId: makeId
}
})
},
goToUser () {
console.log('go to user page')
this.$router.push({
path: '/user',
query: {
userId: this.userId
}
})
},
goToVouchers () {
this.$router.push({
path: '/vouchers'
})
}
}
}
</script>
<style scoped>
.full-page {
background-color: #f5f6f7;
}
</style>
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment