初始提交
This commit is contained in:
21
README.md
Normal file
21
README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# admin
|
||||
|
||||
> A Vue.js project
|
||||
|
||||
## Build Setup
|
||||
|
||||
``` bash
|
||||
# install dependencies
|
||||
npm install
|
||||
|
||||
# serve with hot reload at localhost:8080
|
||||
npm run dev
|
||||
|
||||
# build for production with minification
|
||||
npm run build
|
||||
|
||||
# build for production and view the bundle analyzer report
|
||||
npm run build --report
|
||||
```
|
||||
|
||||
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
|
||||
21
admin.ps1
Normal file
21
admin.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
$workspace="C:\Program Files (x86)\Jenkins\workspace\hualian_admin"
|
||||
$distFolder="C:\Program Files (x86)\Jenkins\workspace\hualian_admin\dist\*"
|
||||
echo "cd "+$workspace
|
||||
cd $workspace
|
||||
echo "npm"
|
||||
npm install
|
||||
npm run build --prod
|
||||
echo "npm ok"
|
||||
C:\Windows\System32\inetsrv\appcmd.exe stop site "hualian_admin"
|
||||
#$TargetFolder = "D:\www\hanniu\admin"
|
||||
#$Files = get-childitem $TargetFolder -force
|
||||
#Foreach ($File in $Files)
|
||||
#{
|
||||
##$FilePath=$File.FullName
|
||||
#Write-Host $FilePath -NoNewline
|
||||
#Remove-Item -Path $FilePath -Recurse -Force
|
||||
#}
|
||||
echo "copy start"
|
||||
copy-item $distFolder -destination "D:\www\hualian\admin" -Recurse -Force
|
||||
echo "copy ok"
|
||||
C:\Windows\System32\inetsrv\appcmd.exe start site "hualian_admin"
|
||||
41
build/build.js
Normal file
41
build/build.js
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
const ora = require('ora')
|
||||
const rm = require('rimraf')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const webpackConfig = require('./webpack.prod.conf')
|
||||
|
||||
const spinner = ora('building for production...')
|
||||
spinner.start()
|
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
||||
if (err) throw err
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
||||
})
|
||||
54
build/check-versions.js
Normal file
54
build/check-versions.js
Normal file
@@ -0,0 +1,54 @@
|
||||
'use strict'
|
||||
const chalk = require('chalk')
|
||||
const semver = require('semver')
|
||||
const packageConfig = require('../package.json')
|
||||
const shell = require('shelljs')
|
||||
|
||||
function exec (cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim()
|
||||
}
|
||||
|
||||
const versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node
|
||||
}
|
||||
]
|
||||
|
||||
if (shell.which('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
const warnings = []
|
||||
|
||||
for (let i = 0; i < versionRequirements.length; i++) {
|
||||
const mod = versionRequirements[i]
|
||||
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(mod.name + ': ' +
|
||||
chalk.red(mod.currentVersion) + ' should be ' +
|
||||
chalk.green(mod.versionRequirement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.log('')
|
||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
||||
console.log()
|
||||
|
||||
for (let i = 0; i < warnings.length; i++) {
|
||||
const warning = warnings[i]
|
||||
console.log(' ' + warning)
|
||||
}
|
||||
|
||||
console.log()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
BIN
build/logo.png
Normal file
BIN
build/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
101
build/utils.js
Normal file
101
build/utils.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const config = require('../config')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const packageConfig = require('../package.json')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
const assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
|
||||
const cssLoader = {
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
const postcssLoader = {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
}
|
||||
}
|
||||
|
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(),
|
||||
postcss: generateLoaders(),
|
||||
less: generateLoaders('less'),
|
||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
||||
scss: generateLoaders('sass'),
|
||||
stylus: generateLoaders('stylus'),
|
||||
styl: generateLoaders('stylus')
|
||||
}
|
||||
}
|
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function (options) {
|
||||
const output = []
|
||||
const loaders = exports.cssLoaders(options)
|
||||
|
||||
for (const extension in loaders) {
|
||||
const loader = loaders[extension]
|
||||
output.push({
|
||||
test: new RegExp('\\.' + extension + '$'),
|
||||
use: loader
|
||||
})
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
exports.createNotifierCallback = () => {
|
||||
const notifier = require('node-notifier')
|
||||
|
||||
return (severity, errors) => {
|
||||
if (severity !== 'error') return
|
||||
|
||||
const error = errors[0]
|
||||
const filename = error.file && error.file.split('!').pop()
|
||||
|
||||
notifier.notify({
|
||||
title: packageConfig.name,
|
||||
message: severity + ': ' + error.name,
|
||||
subtitle: filename || '',
|
||||
icon: path.join(__dirname, 'logo.png')
|
||||
})
|
||||
}
|
||||
}
|
||||
22
build/vue-loader.conf.js
Normal file
22
build/vue-loader.conf.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const sourceMapEnabled = isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: sourceMapEnabled,
|
||||
extract: isProduction
|
||||
}),
|
||||
cssSourceMap: sourceMapEnabled,
|
||||
cacheBusting: config.dev.cacheBusting,
|
||||
transformToRequire: {
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
||||
101
build/webpack.base.conf.js
Normal file
101
build/webpack.base.conf.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const vueLoaderConfig = require('./vue-loader.conf')
|
||||
const webpack = require('webpack')
|
||||
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'),
|
||||
}
|
||||
},
|
||||
// 添加代码
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({
|
||||
$: "jquery",
|
||||
jQuery: "jquery",
|
||||
jquery: "jquery",
|
||||
"window.jQuery": "jquery"
|
||||
})
|
||||
],
|
||||
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
Normal file
95
build/webpack.dev.conf.js
Normal file
@@ -0,0 +1,95 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const path = require('path')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
const portfinder = require('portfinder')
|
||||
|
||||
const HOST = process.env.HOST
|
||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
||||
|
||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
||||
},
|
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: config.dev.devtool,
|
||||
|
||||
// these devServer options should be customized in /config/index.js
|
||||
devServer: {
|
||||
clientLogLevel: 'warning',
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
|
||||
],
|
||||
},
|
||||
hot: true,
|
||||
contentBase: false, // since we use CopyWebpackPlugin.
|
||||
compress: true,
|
||||
host: HOST || config.dev.host,
|
||||
port: PORT || config.dev.port,
|
||||
open: config.dev.autoOpenBrowser,
|
||||
overlay: config.dev.errorOverlay
|
||||
? { warnings: false, errors: true }
|
||||
: false,
|
||||
publicPath: config.dev.assetsPublicPath,
|
||||
proxy: config.dev.proxyTable,
|
||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
||||
watchOptions: {
|
||||
poll: config.dev.poll,
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': require('../config/dev.env')
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true
|
||||
}),
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.dev.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
module.exports = new Promise((resolve, reject) => {
|
||||
portfinder.basePort = process.env.PORT || config.dev.port
|
||||
portfinder.getPort((err, port) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
// publish the new Port, necessary for e2e tests
|
||||
process.env.PORT = port
|
||||
// add port to devServer config
|
||||
devWebpackConfig.devServer.port = port
|
||||
|
||||
// Add FriendlyErrorsPlugin
|
||||
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
|
||||
},
|
||||
onErrors: config.dev.notifyOnErrors
|
||||
? utils.createNotifierCallback()
|
||||
: undefined
|
||||
}))
|
||||
|
||||
resolve(devWebpackConfig)
|
||||
}
|
||||
})
|
||||
})
|
||||
145
build/webpack.prod.conf.js
Normal file
145
build/webpack.prod.conf.js
Normal file
@@ -0,0 +1,145 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
const env = require('../config/prod.env')
|
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true,
|
||||
usePostCSS: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? config.build.devtool : false,
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
},
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
||||
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
|
||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
||||
allChunks: true,
|
||||
}),
|
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: config.build.productionSourceMap
|
||||
? { safe: true, map: { inline: false } }
|
||||
: { safe: true }
|
||||
}),
|
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: config.build.index,
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true
|
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
},
|
||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// keep module.id stable when vendor modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// This instance extracts shared chunks from code splitted chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.productionGzip) {
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
webpackConfig.plugins.push(
|
||||
new CompressionWebpackPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp(
|
||||
'\\.(' +
|
||||
config.build.productionGzipExtensions.join('|') +
|
||||
')$'
|
||||
),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
||||
7
config/dev.env.js
Normal file
7
config/dev.env.js
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict'
|
||||
const merge = require('webpack-merge')
|
||||
const prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
||||
77
config/index.js
Normal file
77
config/index.js
Normal file
@@ -0,0 +1,77 @@
|
||||
'use strict'
|
||||
// Template version: 1.3.1
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
dev: {
|
||||
|
||||
// Paths
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
|
||||
// Various Dev Server settings
|
||||
host: 'localhost', // can be overwritten by process.env.HOST
|
||||
port: 8081, // 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',
|
||||
devtool: '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: false,//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',
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
}
|
||||
}
|
||||
4
config/prod.env.js
Normal file
4
config/prod.env.js
Normal file
@@ -0,0 +1,4 @@
|
||||
'use strict'
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
||||
14
index.html
Normal file
14
index.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>华连云后台管理系统</title>
|
||||
<!-- <link rel="stylesheet" href="https://at.alicdn.com/t/font_488037_mniwf800wz.css"> -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
13305
package-lock.json
generated
Normal file
13305
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
85
package.json
Normal file
85
package.json
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"name": "admin",
|
||||
"version": "1.0.0",
|
||||
"description": "A Vue.js project",
|
||||
"author": "",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||
"prod": "webpack-dev-server --inline --progress --config build/webpack.prod.conf.js",
|
||||
"start": "npm run dev",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"build": "node build/build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"element-ui": "^2.12.0",
|
||||
"jquery": "^3.4.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"qrcodejs2": "0.0.2",
|
||||
"vue": "^2.5.2",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-ueditor-wrap": "^2.4.1",
|
||||
"vuex": "^3.1.2"
|
||||
},
|
||||
"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-loader": "^7.1.1",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.11",
|
||||
"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",
|
||||
"less": "^3.10.3",
|
||||
"less-loader": "^5.0.0",
|
||||
"node-notifier": "^5.1.2",
|
||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
||||
"ora": "^1.2.0",
|
||||
"portfinder": "^1.0.13",
|
||||
"postcss-import": "^11.0.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"postcss-url": "^7.2.1",
|
||||
"rimraf": "^2.6.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"semver": "^5.3.0",
|
||||
"shelljs": "^0.7.6",
|
||||
"style-loader": "^1.0.0",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
14
src/App.vue
Normal file
14
src/App.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<router-view ></router-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
}
|
||||
</style>
|
||||
125
src/components/article/add.vue
Normal file
125
src/components/article/add.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="main_box screen1" v-loading="loading">
|
||||
<el-form :model="articleModel" :rules="rules" ref="editor" label-width="100px">
|
||||
<el-form-item prop="CatalogId" label="分类" size="small">
|
||||
<el-select v-model="articleModel.CatalogId" placeholder="请选择">
|
||||
<el-option label="华连头条" :value="1"></el-option>
|
||||
<el-option label="优惠活动" :value="2"></el-option>
|
||||
<el-option label="常见问题" :value="3"></el-option>
|
||||
<el-option label="新手教程" :value="4"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Title" label="标题">
|
||||
<el-input placeholder="请填标题" v-model="articleModel.Title" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="SubTitle" label="副标题">
|
||||
<el-input placeholder="请填副标题" v-model="articleModel.SubTitle" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Keyword" label="关键字">
|
||||
<el-input v-model="articleModel.Keyword" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="AccessCount" label="访问人数">
|
||||
<el-input
|
||||
placeholder="请填访问人数:"
|
||||
v-model="articleModel.AccessCount"
|
||||
type="number"
|
||||
size="small"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="OnLine" label="发布状态">
|
||||
<el-switch
|
||||
v-model="articleModel.Publish"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
size="small"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="editor-container">
|
||||
<UE v-model="articleModel.Content" :config="config" ref="ue"></UE>
|
||||
</div>
|
||||
<div class="handel_box clr">
|
||||
<el-button @click="$router.go(-1)" size="small">取 消</el-button>
|
||||
<el-button type="primary" @click="save('editor')" size="small">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
let that;
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
articleModel: {
|
||||
Publish: 0,
|
||||
id: 0,
|
||||
Thumb: "",
|
||||
CatalogId:1,
|
||||
},
|
||||
loading: false,
|
||||
rules: {
|
||||
Title: [this.$vaild.required("标题")],
|
||||
SubTitle: [this.$vaild.required("副标题")]
|
||||
// Banner: [this.$vaild.required("课程主图")],
|
||||
// Cover: [this.$vaild.required("课程封面")],
|
||||
},
|
||||
config: {
|
||||
serverUrl: this.$api.baseURL + "ueditor",
|
||||
UEDITOR_HOME_URL: "/static/ueditor/",
|
||||
autoHeightEnabled: false,
|
||||
initialFrameHeight: 500
|
||||
},
|
||||
options: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "资讯管理>>添加资讯");
|
||||
var query = this.$route.query;
|
||||
if (query.optype == 2) {
|
||||
this.getInfo(query.id);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getInfo(id) {
|
||||
this.$api.get("course/v1/article/Get", { id: id }).then(res => {
|
||||
this.articleModel = res.Data;
|
||||
});
|
||||
},
|
||||
save(formName) {
|
||||
var that = this;
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
if (that.$route.query.optype == "1") {
|
||||
that.add();
|
||||
} else if (that.$route.query.optype == "2") {
|
||||
that.edit();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.$api.post("course/v1/article/post", this.articleModel).then(res => {
|
||||
this.$router.push({ name: "articlelist" });
|
||||
});
|
||||
},
|
||||
edit() {
|
||||
this.$api.post("course/v1/article/put", this.articleModel).then(res => {
|
||||
this.$router.push({ name: "articlelist" });
|
||||
});
|
||||
},
|
||||
upload(callback) {
|
||||
this.$api.upload("oss/v1/ImageCloud/upload").then(res => {
|
||||
callback && callback(res.Data);
|
||||
});
|
||||
},
|
||||
setCover(ret) {
|
||||
this.articleModel.Thumb = ret.Url;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-form {
|
||||
width: 600px;
|
||||
}
|
||||
</style>
|
||||
104
src/components/article/index.vue
Normal file
104
src/components/article/index.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" v-href="'add?optype=1'">添加文章</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入名称/标题" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" size="medium" :height="$getHeight(100)" row-key="Id" border>
|
||||
<!-- <el-table-column label="图片" width="80">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.Thumb" style="width:50px;height:20px" />
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column prop="CatalogId" label="分类" width="180" :formatter="catalogFormat"></el-table-column>
|
||||
<el-table-column prop="Title" label="标题" width="180"></el-table-column>
|
||||
<el-table-column prop="SubTitle" label="子标题" width="180"></el-table-column>
|
||||
<el-table-column prop="AccessCount" label="访问人数"></el-table-column>
|
||||
<el-table-column prop="CreateTime" label="发布时间" aformatter="formatterTime"></el-table-column>
|
||||
<el-table-column label="发布状态">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.Publish"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#dcdfe6"
|
||||
@change="audit(scope.row)"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" v-href="'add?optype=2&id='+scope.row.Id">编辑</span>
|
||||
<span class="handel cursor del" @click="del(scope.row)">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="20"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
catalogFormat(data) {
|
||||
console.log(data)
|
||||
return data.CatalogId==1?"华连头条":"使用技巧";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api.get("course/v1/article/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api.post("course/v1/article/Delete?id=" + item.Id).then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
audit(item) {
|
||||
this.$api.post("course/v1/article/Audit?id=" + item.Id).then(res => {
|
||||
item.Publish = res.Data;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
751
src/components/common/cutTip.vue
Normal file
751
src/components/common/cutTip.vue
Normal file
@@ -0,0 +1,751 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-popover
|
||||
v-if="showTip"
|
||||
placement="top-start"
|
||||
width="350"
|
||||
trigger="click"
|
||||
>
|
||||
<div style="padding:20px;">
|
||||
{{text}}
|
||||
</div>
|
||||
<span slot="reference">{{showText}}<i class="el-icon-arrow-down" style="padding-left:20px"></i></span>
|
||||
</el-popover>
|
||||
<span v-else>{{showText}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
text: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
default: function() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showTip: false,
|
||||
showText: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
text: function(newQuestion, oldQuestion) {
|
||||
console.log(newQuestion);
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted(){
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
if (this.text.length > this.length) {
|
||||
this.showText = this.text.substring(0, this.length);
|
||||
this.showTip = true;
|
||||
} else {
|
||||
this.showText = this.text;
|
||||
this.showTip = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#qrcode {
|
||||
position: absolute;
|
||||
right: 70px;
|
||||
top: 16px;
|
||||
}
|
||||
|
||||
.el-message-box__message p {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.cur {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main_right {
|
||||
width: calc(100% - 300px);
|
||||
height: 100%;
|
||||
float: left;
|
||||
border-left: 1px solid #dae1f2;
|
||||
padding: 20px 20px 56px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
margin-top: 16.5px;
|
||||
margin-right: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.popover_box span {
|
||||
font-size: 14px;
|
||||
color: #1a263c;
|
||||
text-align: left;
|
||||
width: calc(100% - 30px);
|
||||
margin-left: 15px;
|
||||
border-bottom: 1px solid #f0f3fa;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.popover_box span:hover {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.dialog_box {
|
||||
width: 440px;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.dialog_content {
|
||||
height: auto;
|
||||
padding-bottom: 20px;
|
||||
min-height: 95px;
|
||||
}
|
||||
|
||||
.right_top {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.right_top span {
|
||||
border-left: 2px solid #4c82ff;
|
||||
color: #17181a;
|
||||
font-size: 16px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.right_top .right {
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.right_top .right i {
|
||||
color: #4c82ff;
|
||||
}
|
||||
|
||||
.right_title {
|
||||
width: 100%;
|
||||
float: left;
|
||||
margin-top: 25px;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.right_title .left span {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 32px;
|
||||
}
|
||||
|
||||
.right_title .left i {
|
||||
font-size: 22px;
|
||||
color: rgb(184, 200, 240);
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.search_box {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.search_box input {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.handel_box {
|
||||
width: calc(100% - 10px);
|
||||
height: 50px;
|
||||
background: #f7f8fc;
|
||||
float: left;
|
||||
margin: 0px;
|
||||
max-width: 100%;
|
||||
padding-left: 10px;
|
||||
position: relative;
|
||||
transform: translateX(0px);
|
||||
}
|
||||
|
||||
.handel_box span {
|
||||
width: 105px;
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #dae1f2;
|
||||
float: left;
|
||||
background: white;
|
||||
margin-top: 6px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.handel_box span {
|
||||
color: white;
|
||||
border: 1px solid #4c82ff;
|
||||
background: #4c82ff;
|
||||
}
|
||||
|
||||
/* .handel_box span:last-child {
|
||||
border: 1px solid #ff728d;
|
||||
} */
|
||||
.tbody td:last-child {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tbody td:last-child span {
|
||||
width: auto;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
border-radius: 7px;
|
||||
cursor: pointer;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
.theader {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.theader td:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
table td {
|
||||
border-right: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid #8c96ad;
|
||||
display: block;
|
||||
border-radius: 0px;
|
||||
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tbody .checkbox {
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.checkbox i {
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: #4c82ff;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.checkbox_cur i {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ban {
|
||||
padding-left: 10px;
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
border-left: 1px solid #dae1f2;
|
||||
}
|
||||
|
||||
.span_box {
|
||||
width: calc(100% - 40px);
|
||||
margin: 5px 0 0 20px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.span_box span {
|
||||
width: calc(50% - 15px);
|
||||
height: 35px;
|
||||
text-align: center;
|
||||
line-height: 35px;
|
||||
color: #1a1a1a;
|
||||
font-size: 14px;
|
||||
margin-left: 15px;
|
||||
background: #fafbfc;
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.span_box span:first-child {
|
||||
margin-left: 0px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.right_box {
|
||||
width: 315px;
|
||||
height: calc(100vh - 75px);
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
top: 70px;
|
||||
background: #fafbfc;
|
||||
box-shadow: 0px 5px 10px #cccccc;
|
||||
margin-right: 0px;
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
overflow: hidden;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: calc(100% - 20px);
|
||||
line-height: 42px;
|
||||
color: #363c4c;
|
||||
font-size: 16px;
|
||||
background: white;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.box_title {
|
||||
width: calc(100% - 150px);
|
||||
line-height: 49px;
|
||||
text-align: left;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid #979899;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.checkbox i {
|
||||
margin: 0px;
|
||||
line-height: 16px;
|
||||
font-size: 12px;
|
||||
color: #4c82ff;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.checkbox_cur i {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.openstate {
|
||||
font-size: 14px;
|
||||
color: #4c82ff;
|
||||
font-weight: bold;
|
||||
line-height: 49px;
|
||||
}
|
||||
|
||||
.menubox {
|
||||
height: 710px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.menuhandel {
|
||||
width: calc(100% - 60px);
|
||||
height: 60px;
|
||||
background: white;
|
||||
padding: 0px 30px;
|
||||
}
|
||||
|
||||
.menuhandel span {
|
||||
width: 102px;
|
||||
height: 34px;
|
||||
border: 5px;
|
||||
text-align: center;
|
||||
line-height: 34px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #4c82ff;
|
||||
color: #4c82ff;
|
||||
float: left;
|
||||
border-radius: 5px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.menuhandel span:last-child {
|
||||
color: white;
|
||||
background: #4c82ff;
|
||||
margin-left: 45px;
|
||||
}
|
||||
|
||||
.route .icon-arrow-down {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.noroute .icon-arrow-down {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
table tr:first-child td {
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
table tr td {
|
||||
min-width: 55px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
table tr td:first-child {
|
||||
width: 15px;
|
||||
min-width: 0px;
|
||||
padding-right: 10px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.ishead {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: #edf1fa;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* table .checkbox {
|
||||
border: 2px solid #8c96ad;
|
||||
box-sizing: border-box;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
} */
|
||||
|
||||
.tbody {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.theader {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.third .icon-arrow-down {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
td .checkbox {
|
||||
box-sizing: border-box;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
td .checkbox i {
|
||||
font-size: 6px;
|
||||
display: block;
|
||||
line-height: 13px;
|
||||
text-align: center;
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
td .checkbox_cur i {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.tbody .short {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 128px;
|
||||
}
|
||||
.tbody td:last-child span {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.mt25 {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
z-index: 2000;
|
||||
}
|
||||
.search_input {
|
||||
float: right;
|
||||
}
|
||||
.el-input {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
height: 35px;
|
||||
}
|
||||
.search_btn {
|
||||
background: #4c82ff;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 3px;
|
||||
margin: 1px 0;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
.information {
|
||||
text-align: center;
|
||||
color: #919399;
|
||||
margin-top: 96px;
|
||||
}
|
||||
.nd {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.liang {
|
||||
width: 640px;
|
||||
height: 160px;
|
||||
background: url("/static/img/QRkuang.png");
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
}
|
||||
.num1,
|
||||
.num2 {
|
||||
font-size: 24px;
|
||||
color: #409eff;
|
||||
}
|
||||
.num1 {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
}
|
||||
.num2 {
|
||||
position: absolute;
|
||||
left: 340px;
|
||||
top: 10px;
|
||||
}
|
||||
.fontSize {
|
||||
font-size: 15px;
|
||||
}
|
||||
.stepText1 {
|
||||
position: absolute;
|
||||
top: 43px;
|
||||
left: 10px;
|
||||
}
|
||||
.stepText2 {
|
||||
position: absolute;
|
||||
top: 43px;
|
||||
left: 340px;
|
||||
}
|
||||
.guanzhu1 {
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
left: 10px;
|
||||
}
|
||||
.guanzhu2 {
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
left: 340px;
|
||||
}
|
||||
.weiyuQR {
|
||||
width: 130px;
|
||||
height: 130px;
|
||||
position: absolute;
|
||||
left: 110px;
|
||||
top: 16px;
|
||||
background: url("/static/img/weiyuQR.jpg");
|
||||
background-size: 100%;
|
||||
}
|
||||
/* 人脸 */
|
||||
.hang {
|
||||
height: 50px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
.hang1 {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.selectVIP {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.hangTip {
|
||||
height: 35px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.img {
|
||||
min-height: 50px;
|
||||
padding-left: 60px;
|
||||
padding-bottom: 46px;
|
||||
padding-top: 5px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 85px;
|
||||
float: left;
|
||||
height: 50px;
|
||||
line-height: 55px;
|
||||
}
|
||||
|
||||
.name {
|
||||
float: left;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-top: 10px;
|
||||
margin-left: 5px;
|
||||
width: 250px;
|
||||
border: 1px #ddd solid;
|
||||
font-size: 12px;
|
||||
text-indent: 5px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tel {
|
||||
width: 330px;
|
||||
}
|
||||
|
||||
.xing {
|
||||
margin-top: 2px;
|
||||
color: red;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.xuanze {
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
float: left;
|
||||
border: 1px #4d82ff solid;
|
||||
border-left: 0;
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
background: #4d82ff;
|
||||
}
|
||||
|
||||
.el-radio {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.imgBox {
|
||||
width: 520px;
|
||||
height: 100px;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.imgBox::after {
|
||||
content: "请采集三张人脸图片";
|
||||
position: absolute;
|
||||
bottom: -35px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.pic {
|
||||
width: 100px;
|
||||
height: 75px;
|
||||
margin-right: 30px;
|
||||
float: left;
|
||||
border: 1px #ccc solid;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
background: #409eff;
|
||||
}
|
||||
|
||||
.face {
|
||||
border: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.posi {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.addBox {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
float: left;
|
||||
border: 1px #ccc solid;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.jia {
|
||||
font-weight: 900;
|
||||
font-size: 35px;
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cameraTip {
|
||||
line-height: 150px;
|
||||
margin-left: 28%;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.cameraBox,
|
||||
.faceFail {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
.cameraBox .cameraBg {
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 300px;
|
||||
margin: 0 auto;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.faceFail {
|
||||
padding: 100px 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.textFail {
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.threepPic,
|
||||
.toPic {
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.canvasBox {
|
||||
width: 450px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.threepPic {
|
||||
width: 120px;
|
||||
}
|
||||
.el-radio {
|
||||
margin-right: 0px;
|
||||
}
|
||||
.dialog_bind_wxbox {
|
||||
width: 670px !important;
|
||||
height: 330px !important;
|
||||
}
|
||||
</style>
|
||||
21
src/components/common/layout/footer.vue
Normal file
21
src/components/common/layout/footer.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
<template>
|
||||
<div class="div_footer">
|
||||
</div>
|
||||
</template>
|
||||
<script></script>
|
||||
<style lang="less" scoped>
|
||||
.div_footer {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 30px 0;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
|
||||
&.pageAll {
|
||||
box-sizing: border-box;
|
||||
padding-left: 220px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
130
src/components/common/layout/header.vue
Normal file
130
src/components/common/layout/header.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="base_topBarbox">
|
||||
<div class="base_topBar editbase_topBar">
|
||||
<div class="base_explain">
|
||||
<span id="toolbar_title" class="edittopTittles">{{$store.state.currentNav}}</span>
|
||||
<div class="base-top-bar">
|
||||
<div class="base-top-bar__right">
|
||||
<!-- <div class="base-top-bar__right">
|
||||
<a href="/user_manage#/user_feedback" class="top-bar__text border-r">用户反馈</a>
|
||||
</div> -->
|
||||
<div><el-link type="danger" @click="logout">退出系统</el-link></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import QRCode from "qrcodejs2";
|
||||
var that = null;
|
||||
export default {
|
||||
name: "headerBar",
|
||||
data() {
|
||||
return {
|
||||
qrVisible: false,
|
||||
qrCode: null
|
||||
};
|
||||
},
|
||||
props: {},
|
||||
created() {},
|
||||
methods: {
|
||||
open() {
|
||||
console.log(open);
|
||||
var url = "http://yk.hncore.net/store";
|
||||
this.makeqrcode(url);
|
||||
},
|
||||
logout(){
|
||||
localStorage.clear();
|
||||
this.$router.replace('/login');
|
||||
},
|
||||
showQr() {
|
||||
this.qrVisible = true;
|
||||
},
|
||||
makeqrcode(url) {
|
||||
var that = this;
|
||||
this.qrCode&&this.qrCode.clear();
|
||||
var qr = document.getElementById("qrcode");
|
||||
qr.innerHTML = "";
|
||||
this.qrCode = new QRCode(qr, {
|
||||
text: url,
|
||||
width: 150,
|
||||
height: 150,
|
||||
colorDark: "#000000",
|
||||
colorLight: "#ffffff",
|
||||
correctLevel: QRCode.CorrectLevel.H
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {}
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.base_topBarbox {
|
||||
position: absolute;
|
||||
margin-left: 180px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: calc(100% - 180px);
|
||||
z-index: 1000;
|
||||
background-color: #fff;
|
||||
}
|
||||
.edittopTittles {
|
||||
-ms-flex: 0 0 auto;
|
||||
flex: 0 0 auto;
|
||||
line-height: 56px;
|
||||
}
|
||||
.base_topBar {
|
||||
min-width: 1100px;
|
||||
background-color: #fff;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.base_explain {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
#toolbar_title,
|
||||
.base_topBar.try_time .warn_info_box {
|
||||
display: block;
|
||||
}
|
||||
.base-top-bar {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.base-top-bar__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.base-top-bar__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.top-bar__text {
|
||||
width: 56px;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
line-height: 20px;
|
||||
margin: 0 16px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
.top-bar__shop-view {
|
||||
width: 81px;
|
||||
height: 28px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
border-radius: 14px;
|
||||
border: 1px solid #b2b2b2;
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
margin-right: 17px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
60
src/components/common/layout/index.vue
Normal file
60
src/components/common/layout/index.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<page>
|
||||
<Header></Header>
|
||||
<Left></Left>
|
||||
<div class="base_right">
|
||||
<router-view class="page_main"></router-view>
|
||||
</div>
|
||||
</page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let that;
|
||||
export default {
|
||||
name: "home",
|
||||
components: {
|
||||
Left: () => import("./left.vue"),
|
||||
Header: () => import("./header.vue")
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(val, oldVal) {
|
||||
this.$nextTick(() => {
|
||||
//页面加载完成后执行
|
||||
//todo
|
||||
// this.resetHandelBox();
|
||||
});
|
||||
},
|
||||
deep: true // 深度观察监听
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
updated() {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.base_right {
|
||||
margin-left: 180px;
|
||||
padding-left: 10px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background: #f5f7fa;
|
||||
transition: padding ease 0.3s;
|
||||
padding-right: 10px;
|
||||
padding-top: 56px;
|
||||
}
|
||||
.page_main {
|
||||
margin-top: 10px;
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
padding-bottom: 15px !important;
|
||||
}
|
||||
</style>
|
||||
210
src/components/common/layout/left.vue
Normal file
210
src/components/common/layout/left.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div class="base_slide editbase_slide" id="base_slide">
|
||||
<div class="base_logo_wrap">
|
||||
<a href="/index">
|
||||
<img src="../../../../static/logo.png" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="sidebarWrap">
|
||||
<div class="leftsidebarWrap">
|
||||
<div class="sideMenu_item" v-for="(item,index) in menus" :key="index">
|
||||
<div class="firstindexMenuWrap MenuCursorpointer newsideMenu">
|
||||
<i :class="'font_family theicon '+ item.Icon"></i>
|
||||
<span
|
||||
v-if="item.Permissionurl==''"
|
||||
class="firstpri_name MenuText"
|
||||
>{{item.Permissionlabel}}</span>
|
||||
<router-link v-else :to="item.Permissionurl" :target="item.target">
|
||||
<span class="firstpri_name MenuText">{{item.Permissionlabel}}</span>
|
||||
</router-link>
|
||||
<span class="font_family right_arrow icon-icon_pagination_left1" style="display: none;"></span>
|
||||
</div>
|
||||
<div class="ScedindexMenuWrap" v-if="item.Children&&item.Children.length>0">
|
||||
<ul>
|
||||
<li class="newsideMenu" v-for="(child,cindex) in item.Children" :key="cindex">
|
||||
<router-link :to="item.Permissionurl+child.Permissionurl" :target="child.target">
|
||||
<span class="sedMenuText MenuText">{{child.Permissionlabel}}</span>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
var that = null;
|
||||
//import { menus } from "@/extend/js/newMenus.js";
|
||||
export default {
|
||||
name: "leftBar",
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
menus: [],
|
||||
routerActive:"",
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
//this.getMenus();
|
||||
this.menus=this.$store.state.menus;
|
||||
if(!this.menus||this.menus.length==0){
|
||||
this.menus=this.$local.getMenus(this.menus);
|
||||
}
|
||||
|
||||
this.routerActive = this.$router.currentRoute.path
|
||||
},
|
||||
watch: {
|
||||
$route: function (to, from) {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goDefault() {
|
||||
this.$router.push({
|
||||
path: "/course/list"
|
||||
});
|
||||
},
|
||||
getMenus() {
|
||||
//this.loading=true;
|
||||
// let loadingInstance1 =this.$loading({ fullscreen: true })
|
||||
this.$api
|
||||
.get("manage/v1/ManagerToPermission/GetPermissions")
|
||||
.then(res => {
|
||||
console.log(res);
|
||||
// this.loading=false;
|
||||
// loadingInstance1.close()
|
||||
this.menus = res.Data;
|
||||
});
|
||||
},
|
||||
active(item,child){
|
||||
var res=window.location.pathname;
|
||||
var url=item.Permissionurl;
|
||||
if(child)url+=child.Permissionurl;
|
||||
return res==url;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@import url("../../../../static/css/font.css");
|
||||
.base_slide {
|
||||
top: 0;
|
||||
float: left;
|
||||
width: 180px;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
overflow-x: hidden;
|
||||
// overflow-y: auto;
|
||||
color: #fff;
|
||||
padding-top: 70px;
|
||||
}
|
||||
.base_logo_wrap {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
height: 70px;
|
||||
background-color: #273043;
|
||||
width: 180px;
|
||||
}
|
||||
.base_logo_wrap img {
|
||||
height: 27px;
|
||||
margin-left: 32px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.sidebarWrap {
|
||||
min-height: 100%;
|
||||
background-color: #273043;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0px 4px 0px 0px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.sidebarWrap .leftsidebarWrap {
|
||||
// padding-top: 20px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.sidebarWrap .leftsidebarWrap .sideMenu_item {
|
||||
width: 100%;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
.firstindexMenuWrap {
|
||||
padding: 0 24px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
}
|
||||
.MenuCursorpointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
.firstindexMenuWrap .theicon {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
float: left;
|
||||
font-size: 16px;
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.sideMenu_item .firstpri_name {
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
.sideMenu_item span {
|
||||
display: inline-block;
|
||||
}
|
||||
.sideMenu_item .ScedindexMenuWrap {
|
||||
width: 100%;
|
||||
}
|
||||
.ScedindexMenuWrap ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
padding-right: 2px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.ScedindexMenuWrap ul li {
|
||||
width: 50%;
|
||||
margin-bottom: 2px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.sidebarWrap li {
|
||||
list-style: none;
|
||||
}
|
||||
.sidebarWrap li a {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
.sedMenuText {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
padding: 0 4px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
cursor: pointer;
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.icon-icon_pagination_left1:before {
|
||||
content: "\e6b2";
|
||||
}
|
||||
.active {
|
||||
background: #4b82ff;
|
||||
}
|
||||
.router-link-active{
|
||||
background: #4b82ff;
|
||||
}
|
||||
</style>
|
||||
5
src/components/common/layout/page.vue
Normal file
5
src/components/common/layout/page.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
<template> <router-view></router-view></template>
|
||||
<script></script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
75
src/components/common/managerDrawer.vue
Normal file
75
src/components/common/managerDrawer.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-drawer title="选择员工" size="240" :visible.sync="drawer" direction="rtl">
|
||||
<div class="search-box">
|
||||
<el-input placeholder="输入关键字进行过滤" size="small" v-model="searchModel.keyWord">
|
||||
<el-button slot="append" icon="el-icon-search" @click="getManager"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" @row-click="select">
|
||||
<el-table-column prop="LoginCode" label="账号" width="120"></el-table-column>
|
||||
<el-table-column prop="RealName" label="名称" width="120"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="getManager"
|
||||
:page-size="20"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: [],
|
||||
data() {
|
||||
return {
|
||||
loading:false,
|
||||
drawer: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
keyWord(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getManager();
|
||||
},
|
||||
methods: {
|
||||
getManager() {
|
||||
this.$api.get("manage/v1/Manager/Get",this.searchModel).then(res => {
|
||||
this.retData=res;
|
||||
})
|
||||
},
|
||||
select(item,node,_this) {
|
||||
console.log(item)
|
||||
this.drawer = false;
|
||||
var item=JSON.parse( JSON.stringify(item))
|
||||
this.$emit("select", item);
|
||||
},
|
||||
close() {
|
||||
this.drawer = false;
|
||||
this.$emit("close");
|
||||
},
|
||||
show() {
|
||||
this.drawer = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search-box{
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
123
src/components/common/permisson.vue
Normal file
123
src/components/common/permisson.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<section :class="['grade'+grade,'grade']">
|
||||
<section class="clr" :class="[{'bn':permissionObj.Children&&permissionObj.Children.length>0},{'show':permissionObj.show}]">
|
||||
<div class="big" @click="showChild(permissionObj)" v-once>
|
||||
<i v-if="permissionObj.Children&&permissionObj.Children.length>0"></i>
|
||||
{{getName(permissionObj.Permissionlabel)}}
|
||||
</div>
|
||||
<div v-for="(a,i) in permissionObj.permission" :key="i">
|
||||
<span :class="[{'choose':a.value==true},{'disabled':a.value== 'disabled' }]" @click="choose(permissionObj,i)"></span>
|
||||
</div>
|
||||
</section>
|
||||
<section v-if="permissionObj.show" >
|
||||
<permission :permissionObj="item" v-for="(item,index) in permissionObj.Children" :key="index" :parentStr="parentStr+'-'+permissionObj.Permissionlabel"
|
||||
:grade="grade+1"></permission>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
var that = null;
|
||||
export default {
|
||||
name: "permission",
|
||||
props: {
|
||||
permissionObj: {
|
||||
type: Object,
|
||||
require: true
|
||||
},
|
||||
grade: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
parentStr: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
created() {
|
||||
that = this;
|
||||
},
|
||||
methods: {
|
||||
getName(str) {
|
||||
return (that.parentStr + "-" + str).replace("-", "");
|
||||
},
|
||||
choose(obj, i) {
|
||||
//更改当前选中目标状态
|
||||
// console.log(obj, i);
|
||||
if (typeof obj.permission[i].value == "boolean") {
|
||||
obj.permission[i].value = !obj.permission[i].value;
|
||||
that.chooseAll(obj, i, obj.permission[i].value);
|
||||
that.chooseAll(obj.parent, i);
|
||||
that.checkedisAll(obj, i, obj.permission[i].value);
|
||||
}
|
||||
},
|
||||
chooseAll(obj, i, bol) {
|
||||
//匹配当前菜单下子菜单选中状态
|
||||
//
|
||||
if (obj && obj.Children) {
|
||||
if (bol != undefined) {
|
||||
//匹配子集
|
||||
obj.Children.forEach(el => {
|
||||
if (el.permission[i].value != bol) {
|
||||
if (el.permission[i].value != "disabled") el.permission[i].value = bol;
|
||||
that.checkedisAll(el, i, bol);
|
||||
}
|
||||
that.chooseAll(el, i, bol);
|
||||
});
|
||||
} else {
|
||||
//追溯父级
|
||||
var bool = true;
|
||||
obj.Children.forEach(el => {
|
||||
if (el.permission[i].value == false) bool = true;
|
||||
});
|
||||
if (obj.permission[i].value != bool) {
|
||||
if (obj.permission[i].value != "disabled") obj.permission[i].value = bool;
|
||||
that.checkedisAll(obj, i, bool);
|
||||
}
|
||||
that.chooseAll(obj.parent, i);
|
||||
}
|
||||
}
|
||||
},
|
||||
showChild(permissionObj) {
|
||||
permissionObj.show = !permissionObj.show;
|
||||
},
|
||||
checkedisAll(obj, i, bol) {
|
||||
if (i == 4) {
|
||||
for (var j = 0; j < 4; j++) {
|
||||
if (obj.permission[j].value != "disabled") obj.permission[j].value = bol;
|
||||
}
|
||||
if (obj.permission[i].value) obj.chooseNum = 4;
|
||||
else obj.chooseNum = 0;
|
||||
} else {
|
||||
if (obj.permission[i].value) {
|
||||
obj.chooseNum++;
|
||||
} else {
|
||||
obj.chooseNum--;
|
||||
}
|
||||
}
|
||||
if (obj.permission[4].value != "disabled") {
|
||||
if (obj.chooseNum == 4) obj.permission[4].value = true;
|
||||
else obj.permission[4].value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {}
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.grade .big{
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.grade .grade1 .big{
|
||||
padding-left: 10px;
|
||||
}
|
||||
.grade .grade1 .big i{
|
||||
left: 30px;
|
||||
}
|
||||
.grade .grade2 .big{
|
||||
padding-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
68
src/components/common/phonehide.vue
Normal file
68
src/components/common/phonehide.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div>
|
||||
<span v-if="!showTip" @click="showTip=!showTip" class="cursor">{{showText}}</span>
|
||||
<span v-else @click="showTip=show" class="cursor">{{text}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
text: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
default: function() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showTip: false,
|
||||
showText: "",
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
text: function(newQuestion, oldQuestion) {
|
||||
console.log(newQuestion);
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted(){
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
if (this.isMobile(this.text)) {
|
||||
this.showText = this.text.substring(0, 3)+"****"+this.text.substring(7, 4);
|
||||
|
||||
}else{
|
||||
this.showText=this.text
|
||||
}
|
||||
},
|
||||
isMobile(phone){
|
||||
let reg = /^1[345789]\d{9}$/;
|
||||
return reg.test(phone)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cursor{
|
||||
cursor:hand
|
||||
}
|
||||
</style>
|
||||
11
src/components/common/router.vue
Normal file
11
src/components/common/router.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
<template>
|
||||
<router-view class="clr"></router-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
15
src/components/common/setting.vue
Normal file
15
src/components/common/setting.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<router-view class="clr"></router-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "setting",
|
||||
props: {
|
||||
menusList: {
|
||||
type: Array
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
150
src/components/common/sliderBar.vue
Normal file
150
src/components/common/sliderBar.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<section class="barContain">
|
||||
<div class="slideBar" :style="getBarWidth"></div>
|
||||
<div class="slideBlock" :style="getBlockPosition"></div>
|
||||
<template v-if="showStops">
|
||||
<span class="stops" :style="getStopsPosition(n)" v-for="n in stops" @click="changeValue(n)"></span>
|
||||
<span class="stopsValue" :style="getStopsPosition(n)" v-for="n in stops" @click="changeValue(n)">
|
||||
{{stopsValue(n)}}
|
||||
</span>
|
||||
</template>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
var that = null;
|
||||
export default {
|
||||
name: "sliderBar",
|
||||
props: {
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
showStops: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
unit: {
|
||||
type: String
|
||||
},
|
||||
value: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
that = this;
|
||||
},
|
||||
methods: {
|
||||
stopsValue(n) {
|
||||
return (this.min + this.step * (n - 1)) + this.unit
|
||||
},
|
||||
changeValue(n) {
|
||||
var currentValue = this.min + this.step * (n - 1)
|
||||
this.$emit('input', currentValue)
|
||||
},
|
||||
getStopsPosition(n) {
|
||||
let left = (this.step * n - this.min) / (this.max - this.min) * 100 + "%";
|
||||
let background, color, fontWeight;
|
||||
if (this.value >= this.step * (n + 1) - this.min) background = "#4c82ff";
|
||||
if (this.value == this.step * (n + 1) - this.min) {
|
||||
color = "#4c82ff"
|
||||
fontWeight = "bolder"
|
||||
};
|
||||
return {
|
||||
left,
|
||||
background,
|
||||
color,
|
||||
fontWeight
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stops() {
|
||||
return parseInt((this.max - this.min) / this.step) + 1
|
||||
},
|
||||
getBarWidth() {
|
||||
var currentValue = this.value || this.min;
|
||||
return {
|
||||
width: (currentValue - this.min) / (this.max - this.min) * 100 + "%"
|
||||
}
|
||||
},
|
||||
getBlockPosition() {
|
||||
var currentValue = this.value || this.min;
|
||||
return {
|
||||
left: (currentValue - this.min) / (this.max - this.min) * 100 + "%"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.barContain {
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
background: #d0d6d8;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
margin: 12px 0 29px;
|
||||
.slideBar {
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
background: #4c82ff;
|
||||
width: 0;
|
||||
transition: width ease 0.2s;
|
||||
}
|
||||
.slideBlock {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 2px solid #fafcfc;
|
||||
background: #4c82ff;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: all ease 0.2s;
|
||||
transform-origin: center center;
|
||||
z-index: 12;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
transform: translate(-50%, -50%) scale(1.2, 1.2);
|
||||
}
|
||||
}
|
||||
.stops {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fafcfc;
|
||||
background: #d0d6d8;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: background ease 0.2s;
|
||||
z-index: 11;
|
||||
cursor: pointer;
|
||||
}
|
||||
.stopsValue {
|
||||
position: absolute;
|
||||
background: transparent !important;
|
||||
top: 4px;
|
||||
height: 29px;
|
||||
line-height: 29px;
|
||||
color: #3d424d;
|
||||
font-size: 12px;
|
||||
transform: translateX(-50%);
|
||||
cursor: pointer;
|
||||
&:first-of-type {
|
||||
transform: translateX(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
80
src/components/common/userDrawer.vue
Normal file
80
src/components/common/userDrawer.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-drawer title="选择会员" size="240" :visible.sync="drawer" direction="rtl">
|
||||
<div class="search-box">
|
||||
<el-input placeholder="输入关键字进行过滤" size="small" v-model="searchModel.keyWord">
|
||||
<el-button slot="append" icon="el-icon-search" @click="getUser"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" @row-click="select" height="1000">
|
||||
<el-table-column prop="LoginCode" label="账号" width="120"></el-table-column>
|
||||
<el-table-column prop="Phone" label="手机" width="120">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.Phone" show="false"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Name" label="名称" width="120"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="getUser"
|
||||
:page-size="20"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: [],
|
||||
data() {
|
||||
return {
|
||||
loading:false,
|
||||
drawer: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
keyWord(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getUser();
|
||||
},
|
||||
methods: {
|
||||
getUser() {
|
||||
this.$api.get("baseinfo/v1/user/Search",this.searchModel).then(res => {
|
||||
this.retData=res;
|
||||
})
|
||||
},
|
||||
select(item,node,_this) {
|
||||
console.log(item)
|
||||
this.drawer = false;
|
||||
var item=JSON.parse( JSON.stringify(item))
|
||||
this.$emit("select", item);
|
||||
},
|
||||
close() {
|
||||
this.drawer = false;
|
||||
this.$emit("close");
|
||||
},
|
||||
show() {
|
||||
this.drawer = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search-box{
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
48
src/components/home/blank.vue
Normal file
48
src/components/home/blank.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let that;
|
||||
export default {
|
||||
name: "home",
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// handelshow: false,
|
||||
activeName: "",
|
||||
selsecondindex: "",
|
||||
menudata: [],
|
||||
Navigation: {
|
||||
secList: [],
|
||||
show: false,
|
||||
firsturl: "/",
|
||||
loadMain: false
|
||||
},
|
||||
showGuide: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
version: function() {
|
||||
return this.$store.state.version;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 1400px;
|
||||
}
|
||||
</style>
|
||||
48
src/components/home/index.vue
Normal file
48
src/components/home/index.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let that;
|
||||
export default {
|
||||
name: "home",
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// handelshow: false,
|
||||
activeName: "",
|
||||
selsecondindex: "",
|
||||
menudata: [],
|
||||
Navigation: {
|
||||
secList: [],
|
||||
show: false,
|
||||
firsturl: "/",
|
||||
loadMain: false
|
||||
},
|
||||
showGuide: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
version: function() {
|
||||
return this.$store.state.version;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$router.push("/order/statistics")
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 1400px;
|
||||
}
|
||||
</style>
|
||||
46
src/components/login/components/carousel.vue
Normal file
46
src/components/login/components/carousel.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<el-carousel :interval="5000" arrow="always" height="700px">
|
||||
<el-carousel-item v-for="item in 3" :key="item"></el-carousel-item>
|
||||
</el-carousel>
|
||||
</template>
|
||||
<style scoped>
|
||||
.el-carousel__item {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.el-carousel__item h3 {
|
||||
color: #475669;
|
||||
font-size: 18px;
|
||||
opacity: 0.75;
|
||||
line-height: 650px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-image: url("/static/img/login/banner1.png");
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-image: url("/static/img/login/banner1.png");
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(3n) {
|
||||
background-image: url("/static/img/login/banner1.png");
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1280px) and (max-width:1812px) {
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-image: url("/static/img/login/banner1.png");
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-image: url("/static/img/login/banner1.png");
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(3n) {
|
||||
background-image: url("/static/img/login/banner1.png");
|
||||
}
|
||||
}
|
||||
</style>
|
||||
6
src/components/login/components/footer.vue
Normal file
6
src/components/login/components/footer.vue
Normal file
@@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<footer style="padding:50px;color:#8A9199;text-align:center;font-size:12px;">
|
||||
<h2 style="font-size:18px;margin-bottom:.4em;font-weight:400;">让物业更智慧 让生活更便利</h2>
|
||||
<p style=""> Copyright©2017-2019 楼小羽 All Rights Reserved 豫ICP备17018593号 | 客服电话:400 871 6696</p>
|
||||
</footer>
|
||||
</template>
|
||||
29
src/components/login/components/header.vue
Normal file
29
src/components/login/components/header.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="title_nav">
|
||||
<div class="logo_pic">
|
||||
<a style="display:inline-block;" href="#">
|
||||
<img src="/static/logo.png">
|
||||
<!-- src="/static/img/login/denglulogo1.png"> -->
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.title_nav {
|
||||
height: 74px;
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.logo_pic {
|
||||
width: 140px;
|
||||
height: 70px;
|
||||
margin: -10px 0 0 56px;
|
||||
}
|
||||
|
||||
.logo_pic img {
|
||||
margin-top: 16px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
162
src/components/login/components/login-by-account.vue
Normal file
162
src/components/login/components/login-by-account.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<section class="login_box">
|
||||
<h1 style="margin-bottom:30px;font-size:33px;font-weight:normal">登录</h1>
|
||||
<el-form v-show="loginByNormal" ref="form" :model="data" :rules="rules" @submit.native="submit">
|
||||
<el-form-item prop="Logincode">
|
||||
<el-input style="width:310px;" type="text" v-model="data.Logincode" name="Logincode" placeholder="请输入账号"
|
||||
:maxlength="11">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<!--密码-->
|
||||
<el-form-item prop="Password">
|
||||
<el-input style="width:310px;" type="password" v-model="data.Password" name="Password" placeholder="请输入密码">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<!--图片验证码-->
|
||||
<el-form-item prop="Code">
|
||||
<el-input style="width:310px;" type="text" v-model="data.Code" placeholder="请输入验证码">
|
||||
<img slot="append" :src="vaildimg" @click="getvaild" style="height:34px;">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button native-type="submit" style="display:block;width:100%;padding:12px 0;background:#409eff" :loading="disabled"
|
||||
type="primary">登录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
loginByNormal: true,
|
||||
disabled: false,
|
||||
vaildimg: '',
|
||||
data: {
|
||||
Logincode: "",
|
||||
Password: "",
|
||||
Code: "",
|
||||
CodeKey: "",
|
||||
Appcpde: ""
|
||||
},
|
||||
rules: {
|
||||
Logincode: [this.$vaild.required("账号")],
|
||||
Password: [this.$vaild.required("密码")],
|
||||
Code: [this.$vaild.required("验证码")]
|
||||
},
|
||||
menus:[]
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
this.getvaild();
|
||||
|
||||
},
|
||||
beforeDestroy: function() {
|
||||
clearTimeout(this.timerId);
|
||||
},
|
||||
methods: {
|
||||
getMenus() {
|
||||
this.$api
|
||||
.get("manage/v1/ManagerToPermission/GetPermissions")
|
||||
.then(res => {
|
||||
var menus = res.Data;
|
||||
this.$local.setMenus(menus);
|
||||
this.$store.commit('setMnus', menus);
|
||||
var defulat=this.getDefaultMenu(menus);
|
||||
this.$router.replace(defulat);
|
||||
});
|
||||
},
|
||||
getDefaultMenu(menus){
|
||||
if(menus.length==0)return "/login"
|
||||
var sumMenus;
|
||||
for(var i=0;i<menus.length;i++){
|
||||
sumMenus=menus[i].Children;
|
||||
if(sumMenus) break;
|
||||
}
|
||||
if(sumMenus.length==0) return "/login";
|
||||
return sumMenus[0].Permissionurl;
|
||||
},
|
||||
getvaild() {
|
||||
this.$api.get('baseinfo/v1/manager/GetValidateCode').then(res=>{
|
||||
var img = "data:image/jpg;base64," + res.Data.img;
|
||||
this.vaildimg = img;
|
||||
this.data.CodeKey = res.Data.key;
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = setTimeout(() => {
|
||||
this.getvaild();
|
||||
}, 10 * 60 * 1000)
|
||||
})
|
||||
|
||||
},
|
||||
submit: function(e) {
|
||||
e.preventDefault();
|
||||
this.$refs.form.validate(pass => {
|
||||
if (!pass) return;
|
||||
this.login();
|
||||
})
|
||||
},
|
||||
loginSuccess: function(data) {
|
||||
this.userInfo = data;
|
||||
window.localStorage.clear(); //防止有未清理的缓存
|
||||
this.$local.setUserCache(data)
|
||||
this.$store.commit('updateUserInfo', data);
|
||||
window.localStorage.setItem("loginType", "property");
|
||||
this.getMenus();
|
||||
// this.$router.replace('/user/index');
|
||||
|
||||
},
|
||||
isNewUser(id) {
|
||||
this.$api.get({
|
||||
url: 'Manager/Account',
|
||||
params: {
|
||||
params: {
|
||||
ID: id
|
||||
}
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.Data.LoginCount <= 1) return this.$router.push({
|
||||
name: "initlogin"
|
||||
});
|
||||
this.$router.push('/home');
|
||||
},
|
||||
failTip: '登录失败'
|
||||
})
|
||||
},
|
||||
login() {
|
||||
this.$api.post('baseinfo/v1/manager/Login',this.data).then(
|
||||
res=>{
|
||||
if (res.Data){
|
||||
this.loginSuccess(res.Data);
|
||||
return;
|
||||
}
|
||||
return this.$message({
|
||||
type: "error",
|
||||
message: "无此用户信息"
|
||||
})
|
||||
},err=>{
|
||||
this.getvaild();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login_box {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
height: 450px;
|
||||
width: 410px;
|
||||
padding: 50px 50px 30px 50px;
|
||||
z-index: 999999;
|
||||
top: 50%;
|
||||
right: 10%;
|
||||
transform: translateY(-50%);
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
83
src/components/login/components/qr-code.vue
Normal file
83
src/components/login/components/qr-code.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<model-loading v-bind="loading" @relaoding="getwximg" style="text-align:center">
|
||||
<div ref="container" class="layout-tr-center"></div>
|
||||
<model-note>请使用微信扫描二维码登录</model-note>
|
||||
</model-loading>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
visible:Boolean
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
id:'',
|
||||
loading: {
|
||||
code: -1,
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
visible:function(value){
|
||||
if(value&&this.id) return this.time();
|
||||
clearTimeout(this.timerId);
|
||||
},
|
||||
id:function(value){
|
||||
if(value&&this.visible) return this.time();
|
||||
clearTimeout(this.timerId);
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.getwximg();
|
||||
},
|
||||
methods: {
|
||||
getwximg() {
|
||||
this.$api.get({
|
||||
url: 'baseinfo/v1/Manager/GetWxLoginQrc',
|
||||
success: (res) => {
|
||||
let data = res.Data;
|
||||
let qrcode = new QRCode(this.$refs.container, {
|
||||
text: data.image,
|
||||
width: 225,
|
||||
height: 225,
|
||||
correctLevel: QRCode.CorrectLevel.L
|
||||
});
|
||||
this.$refs.container.setAttribute('title','二维码');
|
||||
this.id=data.uuid;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
time(){
|
||||
var that = this;
|
||||
clearTimeout(this.timerId)
|
||||
this.$api.get({
|
||||
url: `baseinfo/v1/Manager/CheckScanLoginState`,
|
||||
params:{
|
||||
params:{
|
||||
uuid:this.id
|
||||
}
|
||||
},
|
||||
success: (res) => {
|
||||
let data = res.Data;
|
||||
if (data && data.State == 0) {
|
||||
this.$emit('success',data)
|
||||
} else {
|
||||
this.timerId=setTimeout(() => {
|
||||
this.time()
|
||||
}, 3000)
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
this.timerId=setTimeout(() => {
|
||||
this.time()
|
||||
}, 3000)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeDestroy:function(){
|
||||
clearTimeout(this.timerId)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
26
src/components/login/index.vue
Normal file
26
src/components/login/index.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div>
|
||||
<model-header></model-header>
|
||||
<div style="position:relative;">
|
||||
<model-carousel></model-carousel>
|
||||
<login-by-account></login-by-account>
|
||||
</div>
|
||||
<!-- <model-footer></model-footer> -->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
//components
|
||||
import modelHeader from './components/header'
|
||||
import modelCarousel from './components/carousel'
|
||||
import modelFooter from './components/footer'
|
||||
import loginByAccount from './components/login-by-account'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
modelHeader: modelHeader,
|
||||
modelCarousel:modelCarousel,
|
||||
modelFooter:modelFooter,
|
||||
loginByAccount:loginByAccount
|
||||
}
|
||||
}
|
||||
</script>
|
||||
51
src/components/logs/logList.vue
Normal file
51
src/components/logs/logList.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<el-table :data="tableData" style="width: 100%">
|
||||
<el-table-column prop="date" label="用户" width="180"> </el-table-column>
|
||||
<el-table-column prop="name" label="操作" width="180"> </el-table-column>
|
||||
<el-table-column prop="address" label="操作内容"> </el-table-column>
|
||||
<el-table-column prop="address" label="相关信息"> </el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData: [
|
||||
{
|
||||
date: "2016-05-02",
|
||||
name: "王小虎",
|
||||
address: "上海市普陀区金沙江路 1518 弄",
|
||||
},
|
||||
{
|
||||
date: "2016-05-04",
|
||||
name: "王小虎",
|
||||
address: "上海市普陀区金沙江路 1517 弄",
|
||||
},
|
||||
{
|
||||
date: "2016-05-01",
|
||||
name: "王小虎",
|
||||
address: "上海市普陀区金沙江路 1519 弄",
|
||||
},
|
||||
{
|
||||
date: "2016-05-03",
|
||||
name: "王小虎",
|
||||
address: "上海市普陀区金沙江路 1516 弄",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "日志记录");
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
getData(){
|
||||
this.$api.get("baseinfo/v1/user/page", this.searchModel).then(res => {
|
||||
console.log(res);
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
70
src/components/order/course.vue
Normal file
70
src/components/order/course.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入课程/订单号/订单名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(150)">
|
||||
<el-table-column prop="OrderNo" label="订单号" width="180"></el-table-column>
|
||||
<el-table-column prop="CourseName" label="课程" width="180"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户" width="180"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="金额"></el-table-column>
|
||||
<el-table-column prop="PayType" label="支付类型">
|
||||
<template slot-scope="scope">
|
||||
<el-rate disabled v-model="scope.row.Star"></el-rate>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OrderState" label="订单状态"></el-table-column>
|
||||
<el-table-column prop="OrderState" label="过期日期"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="10"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
formatterTime(data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.$api.get("courseOrder/v1/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
240
src/components/order/index.vue
Normal file
240
src/components/order/index.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-sold-out"
|
||||
@click="dataExport"
|
||||
v-if="$local.isRoot()"
|
||||
>导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-cascader
|
||||
placeholder="选择产品/套餐"
|
||||
size="small"
|
||||
v-model="searchModel.pModel"
|
||||
:options="options"
|
||||
:props="{ checkStrictly: true}"
|
||||
clearable
|
||||
></el-cascader>
|
||||
<!-- <el-select v-model="searchModel.ProductId" placeholder="选择产品" clearable size="small">
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select> -->
|
||||
<el-select
|
||||
v-model="searchModel.OrderTypes"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="选择类型"
|
||||
>
|
||||
<el-option v-for="item in types" :key="item.text" :label="item.text" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-input
|
||||
v-model="searchModel.keyWord"
|
||||
placeholder="请输入订单号、订单名称、用户名"
|
||||
clearable
|
||||
size="small"
|
||||
>
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="CreateTime" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="UpdateTime" label="支付日期" width="180"></el-table-column>
|
||||
<el-table-column prop="OrderNo" label="订单号" width="215"></el-table-column>
|
||||
<el-table-column prop="OrderType" label="类型" :formatter="typeFormat"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户" width="120">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserName"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="DayPrice" label="单价"></el-table-column>
|
||||
<el-table-column prop="ConnectCount" label="连接数">
|
||||
<template slot-scope="scope">{{scope.row.ConnectCount*scope.row.AccountCount}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Accounts" label="账号">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.Accounts"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OrderAmount" label="订单金额"></el-table-column>
|
||||
<el-table-column prop="CouponAmount" label="优惠金额"></el-table-column>
|
||||
<el-table-column prop="AccountPayAmount" label="余额支付"></el-table-column>
|
||||
<el-table-column prop="OtherPayAmount" label="在线支付"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="实付"></el-table-column>
|
||||
<!-- <el-table-column prop="RefundAmount" label="退款"></el-table-column> -->
|
||||
<el-table-column prop="PayType" label="付款方式" :formatter="payTypeFormat"></el-table-column>
|
||||
<el-table-column prop="TradeNo" label="支付流水号" width="140">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.TradeNo"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Remark" label="备注" width="140">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.Remark"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
cutTip: () => import("@/components/common/cutTip"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
options: [],
|
||||
types: [
|
||||
{ text: "新开", value: "1" },
|
||||
{ text: "批量新开", value: "2" },
|
||||
{ text: "续费", value: "3" },
|
||||
{ text: "批量续费", value: "4" }
|
||||
],
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
dateRange: [],
|
||||
products: [],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
ProductId: null,
|
||||
PackageId:null,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
OrderTypes: [],
|
||||
Btime: "",
|
||||
Etime: "",
|
||||
pModel:[],
|
||||
},
|
||||
types: [
|
||||
{ text: "新开", value: 1 },
|
||||
{ text: "批量新开", value: 2 },
|
||||
{ text: "续费", value: 3 },
|
||||
{ text: "批量续费", value: 4 },
|
||||
{ text: "老账号认证", value: 100 },
|
||||
{ text: "测试", value: 200 }
|
||||
],
|
||||
typeFormat(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "新开";
|
||||
case 2:
|
||||
return "批量新开";
|
||||
case 3:
|
||||
return "续费";
|
||||
case 4:
|
||||
return "批量续费";
|
||||
}
|
||||
return "";
|
||||
},
|
||||
payTypeFormat(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 10:
|
||||
return "余额";
|
||||
case 70:
|
||||
return "微信";
|
||||
case 100:
|
||||
return "支付宝";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "订单管理>>订单明细");
|
||||
this.get();
|
||||
//this.getProduct();
|
||||
this.getProductWithPackage();
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.searchModel.PageIndex = 1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
if(this.searchModel.pModel.length>0)
|
||||
this.searchModel.ProductId=this.searchModel.pModel[0];
|
||||
if(this.searchModel.pModel.length>0)
|
||||
this.searchModel.PackageId=this.searchModel.pModel[1];
|
||||
this.$api.get("course/v1/order/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
getProduct() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.products = res.Data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
getProductWithPackage() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/ProductWithPackage").then(res => {
|
||||
this.options = res.Data;
|
||||
var options = [];
|
||||
res.Data.forEach(m => {
|
||||
var product = {
|
||||
label: m.Product.Name,
|
||||
value: m.Product.Id,
|
||||
children: []
|
||||
};
|
||||
|
||||
m.Packages.forEach(p => {
|
||||
var pkg = {
|
||||
label: p.Name,
|
||||
value: p.Id
|
||||
}
|
||||
product.children.push(pkg)
|
||||
})
|
||||
options.push(product);
|
||||
});
|
||||
this.options=options;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
filterHandler(filters) {
|
||||
console.log(filters);
|
||||
var values = Object.values(filters);
|
||||
console.log(...values);
|
||||
values.forEach(m => {
|
||||
this.searchModel.OrderTypes.push(...m);
|
||||
});
|
||||
this.get();
|
||||
},
|
||||
dataExport() {
|
||||
this.$api.getDownloadFile("/course/v1/order/Export", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
73
src/components/order/managerstatistics.vue
Normal file
73
src/components/order/managerstatistics.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<span>
|
||||
总营业额: <el-tag type="danger" effect="plain">{{retData.OrderAmount }} </el-tag>
|
||||
总客户数:<el-tag type="danger" effect="plain">{{retData.UserTotal }} </el-tag>
|
||||
</span>
|
||||
<div class="search-box">
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-button slot="append" icon="el-icon-search" @click="search" size="small">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.List" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="Name" label="客户经理" width="180"></el-table-column>
|
||||
<el-table-column prop="Amount" label="营业额" width="180"></el-table-column>
|
||||
<el-table-column prop="UserCount" label="客户总数" ></el-table-column>
|
||||
<el-table-column prop="NewUserCount" label="新增客户"></el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
options: [],
|
||||
retData: { OrderAmount: 0,UserTotal:0, List: [] },
|
||||
dateRange: [],
|
||||
searchModel: {
|
||||
Btime: "",
|
||||
Etime: "",
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "订单管理>>销售统计");
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}else{
|
||||
this.searchModel.Btime =null;
|
||||
this.searchModel.Etime =null;
|
||||
}
|
||||
this.$api.get("course/v1/order/UserCountStatistics", this.searchModel).then(res => {
|
||||
this.retData = res.Data;
|
||||
});
|
||||
},
|
||||
dataExport() {
|
||||
this.$api.getDownloadFile("/baseinfo/v1/chargeorder/ExportOrder", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
96
src/components/order/openrefunds.vue
Normal file
96
src/components/order/openrefunds.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport">导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
@change=search
|
||||
></el-date-picker>
|
||||
<el-select v-model="searchModel.ProductIds" placeholder="选择产品" collapse-tags multiple clearable size="small" @change=search>
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="CreateTime" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="ConnectCount" label="连接数"></el-table-column>
|
||||
<el-table-column prop="Accounts" label="账号"></el-table-column>
|
||||
<el-table-column prop="RefundRestTime" label="剩余时间"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
dateRange:[],
|
||||
products:[],
|
||||
searchModel: {
|
||||
OrderTypes:[],
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
ProductIds:null,
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav","订单管理>>退款订单")
|
||||
this.get();
|
||||
this.getProduct();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
this.$api.get("course/v1/order/OpenRefundOrders", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
getProduct() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/OpenPage", this.searchModel).then(res => {
|
||||
this.products = res.Data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/course/v1/order/OpenExportRefundOrders", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.red{
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
73
src/components/order/package.vue
Normal file
73
src/components/order/package.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入订单号/订单名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" size="medium" :height="$getHeight(150)" row-key="Id" border>
|
||||
<el-table-column prop="OrderNo" label="订单号" width="180"></el-table-column>
|
||||
<el-table-column prop="CourseName" label="课程" width="180"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户" width="180"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="金额"></el-table-column>
|
||||
<el-table-column prop="PayType" label="支付类型">
|
||||
<template slot-scope="scope">
|
||||
<el-rate disabled v-model="scope.row.Star"></el-rate>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OrderState" label="订单状态"></el-table-column>
|
||||
<el-table-column prop="OrderState" label="过期日期"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="10"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
formatterTime(data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api.get("courseOrder/v1/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
201
src/components/order/refunds.vue
Normal file
201
src/components/order/refunds.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-select v-model="searchModel.ProductId" placeholder="选择产品" clearable size="small">
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="searchModel.OrderTypes"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="选择类型"
|
||||
>
|
||||
<el-option v-for="item in types" :key="item.text" :label="item.text" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入订单号、订单名称、用户名" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" @filter-change="filterHandler" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="CreateTime" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="OrderNo" label="订单号" width="220"></el-table-column>
|
||||
<!-- <el-table-column prop="OrderType" label="类型" :formatter="typeFormat"></el-table-column> -->
|
||||
<el-table-column prop="UserName" label="用户" >
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserName"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<!-- <el-table-column prop="DayPrice" label="单价"></el-table-column> -->
|
||||
<el-table-column prop="ConnectCount" label="连接数"></el-table-column>
|
||||
<el-table-column prop="Accounts" label="账号"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="实付金额"></el-table-column>
|
||||
<el-table-column prop="RefundAmount" label="退款金额"></el-table-column>
|
||||
<el-table-column prop="RefundRestTime" label="剩余时间"></el-table-column>
|
||||
<el-table-column prop="IsAutoRefund" label="自动退款" :formatter="autoFormat"></el-table-column>
|
||||
<el-table-column prop="BackAmount" label="返点"></el-table-column>
|
||||
<el-table-column prop="OrderState" label="退款状态">
|
||||
<template slot-scope="scope">
|
||||
<span :class="{red:scope.row.OrderState==30}"> {{refundTypeFormat(scope.row.OrderState)}}</span>
|
||||
<span v-if="scope.row.OrderState==30" class="handel cursor edit" @click="showRefund(scope.row)">处理</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog title="退款处理" :visible.sync="refundModel.Show" width="300px">
|
||||
<el-form :model="refundModel" ref="inputForm" label-width="80px">
|
||||
<el-form-item prop="Remark" label="备注说明">
|
||||
<el-input v-model="refundModel.Remark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="BackAmount" label="返点">
|
||||
<el-input v-model="refundModel.BackAmount" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="doRefund('inputForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
dateRange:[],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
OrderTypes:[],
|
||||
ProductId:null,
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
refundModel:{
|
||||
Id:0,
|
||||
BackAmount:0,
|
||||
Remark:'',
|
||||
Show:false,
|
||||
},
|
||||
types: [
|
||||
{ text: "新开", value: 1 },
|
||||
{ text: "批量新开", value: 2 },
|
||||
{ text: "续费", value: 3 },
|
||||
{ text: "批量续费", value: 4 },
|
||||
{ text: "老账号认证", value: 100 },
|
||||
{ text: "测试", value: 200 }
|
||||
],
|
||||
typeFormat(row, column, cellValue, index){
|
||||
return "退款"
|
||||
},
|
||||
autoFormat(row, column, cellValue, index){
|
||||
return cellValue&&cellValue==1?"是":"否";
|
||||
},
|
||||
refundTypeFormat(orderStatus){
|
||||
switch (orderStatus) {
|
||||
case 30:
|
||||
return "未自动退款";
|
||||
case 40:
|
||||
return "已人工处理";
|
||||
case 50:
|
||||
return "已自动退款";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav","订单管理>>退款订单")
|
||||
this.get();
|
||||
this.getProduct();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
this.$api.get("course/v1/order/RefundOrders", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
getProduct() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.products = res.Data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
filterHandler(filters) {
|
||||
console.log(filters)
|
||||
var values=Object.values(filters);
|
||||
console.log(...values)
|
||||
values.forEach(m=>{
|
||||
this.searchModel.OrderTypes.push(...m)
|
||||
});
|
||||
this.get();
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/course/v1/order/ExportRefundOrders", this.searchModel);
|
||||
},
|
||||
showRefund(item){
|
||||
this.refundModel.Show = true;
|
||||
this.refundModel.Id=item.Id;
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.refundModel.Show = false;
|
||||
},
|
||||
doRefund(formName){
|
||||
this.$api.post("course/v1/order/RefundProcess", this.refundModel).then(res => {
|
||||
this.get();
|
||||
this.resetForm(formName)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.red{
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
216
src/components/order/sellerorder.vue
Normal file
216
src/components/order/sellerorder.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="showDialog=true">认领</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-select v-model="searchModel.ProductId" placeholder="选择产品" clearable size="small">
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="searchModel.OrderTypes"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="选择类型"
|
||||
>
|
||||
<el-option v-for="item in types" :key="item.text" :label="item.text" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入订单号、订单名称、用户名" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="CreateTime" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="Channel" label="销售人" width="120"></el-table-column>
|
||||
<el-table-column prop="OrderNo" label="订单号" width="215"></el-table-column>
|
||||
<el-table-column prop="OrderType" label="类型" :formatter="typeFormat"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户" width="120">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserName"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="DayPrice" label="单价"></el-table-column>
|
||||
<el-table-column prop="ConnectCount" label="连接数">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.ConnectCount*scope.row.AccountCount}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Accounts" label="账号">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.Accounts"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OrderAmount" label="订单金额"></el-table-column>
|
||||
<el-table-column prop="CouponAmount" label="优惠金额"></el-table-column>
|
||||
<el-table-column prop="AccountPayAmount" label="余额支付"></el-table-column>
|
||||
<el-table-column prop="OtherPayAmount" label="在线支付"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="实付"></el-table-column>
|
||||
<!-- <el-table-column prop="RefundAmount" label="退款"></el-table-column> -->
|
||||
<el-table-column prop="PayType" label="付款方式" :formatter="payTypeFormat"></el-table-column>
|
||||
<el-table-column prop="TradeNo" label="支付流水号" width="140">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.TradeNo"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog title="认领订单" :visible.sync="showDialog" width="300px">
|
||||
<el-form :model="takeModel" ref="inputForm" label-width="80px">
|
||||
<el-form-item prop="phone" label="手机号">
|
||||
<el-input v-model="takeModel.phone" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="amount" label="订单金额">
|
||||
<el-input v-model="takeModel.amount" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="take()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
cutTip:()=>import("@/components/common/cutTip"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
types:[
|
||||
{text: '新开', value: '1'},
|
||||
{text: '批量新开', value: '2'},
|
||||
{text: '续费', value: '3'},
|
||||
{text: '批量续费', value: '4'}],
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
dateRange:[],
|
||||
products:[],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
ProductId:null,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
OrderTypes:[],
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
takeModel:{
|
||||
phone:'',
|
||||
amount:''
|
||||
},
|
||||
types: [
|
||||
{ text: "新开", value: 1 },
|
||||
{ text: "批量新开", value: 2 },
|
||||
{ text: "续费", value: 3 },
|
||||
{ text: "批量续费", value: 4 },
|
||||
{ text: "老账号认证", value: 100 },
|
||||
{ text: "测试", value: 200 }
|
||||
],
|
||||
typeFormat(row, column, cellValue, index){
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "新开";
|
||||
case 2:
|
||||
return "批量新开";
|
||||
case 3:
|
||||
return "续费";
|
||||
case 4:
|
||||
return "批量续费";
|
||||
}
|
||||
return "";
|
||||
},
|
||||
payTypeFormat(row, column, cellValue, index){
|
||||
switch (cellValue) {
|
||||
case 10:
|
||||
return "余额";
|
||||
case 70:
|
||||
return "微信";
|
||||
case 100:
|
||||
return "支付宝";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav","订单管理>>销售订单")
|
||||
this.get();
|
||||
this.getProduct();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
this.$api.get("course/v1/order/SellerOrders", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
getProduct() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.products = res.Data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
filterHandler(filters) {
|
||||
console.log(filters)
|
||||
var values=Object.values(filters);
|
||||
console.log(...values)
|
||||
values.forEach(m=>{
|
||||
this.searchModel.OrderTypes.push(...m)
|
||||
});
|
||||
this.get();
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.showDialog = false;
|
||||
},
|
||||
take(){
|
||||
this.$api.get("course/v1/order/TakeOrder", this.takeModel).then(res => {
|
||||
this.resetForm('inputForm')
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
dataExport() {
|
||||
this.$api.getDownloadFile("/course/v1/order/ExportSellerOrders", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
103
src/components/order/sellerstatistics.vue
Normal file
103
src/components/order/sellerstatistics.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入产品名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
:data="retData"
|
||||
border
|
||||
size="medium"
|
||||
:height="$getHeight(100)"
|
||||
:span-method="mergeSpan"
|
||||
show-summary
|
||||
>
|
||||
<el-table-column prop="Channel" label="销售员"></el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="NewBuyCount" label="新开个数"></el-table-column>
|
||||
<el-table-column prop="NewBuyAmount" label="新开金额"></el-table-column>
|
||||
<el-table-column prop="AgainBuyCount" label="续费个数"></el-table-column>
|
||||
<el-table-column prop="AgainBuyAmount" label="续费金额"></el-table-column>
|
||||
<el-table-column prop="SellAmount" label="销售金额"></el-table-column>
|
||||
<!-- <el-table-column prop="RefundCount" label="退货个数"></el-table-column>
|
||||
<el-table-column prop="RefundAmount" label="退货金额"></el-table-column> -->
|
||||
<!-- <el-table-column prop="PaymentAmount" label="换货个数"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="换货金额"></el-table-column>-->
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData:[],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
dateRange:[],
|
||||
flagMap:{}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav","销售管理>>销售员统计分析")
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.flagMap={};
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
this.$api.get("course/v1/order/SellerStatistics", this.searchModel).then(res => {
|
||||
this.retData = res.Data;
|
||||
this.retData.forEach(item=>{
|
||||
var flag=this.flagMap[item.Channel];
|
||||
if(!flag){
|
||||
this.flagMap[item.Channel]=true;
|
||||
var count=this.retData.filter(m=>m.Channel== item.Channel).length;
|
||||
item.rSpan=count;
|
||||
item.cSpan=1;
|
||||
}else{
|
||||
item.rSpan=0;
|
||||
item.cSpan=0;
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
mergeSpan({row, column, rowIndex, columnIndex}){
|
||||
if (columnIndex === 0) {
|
||||
console.log(`${row.rSpan}-${row.cSpan}`)
|
||||
return {
|
||||
rowspan: row.rSpan,
|
||||
colspan: row.cSpan
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-table{
|
||||
overflow:visible !important;
|
||||
}
|
||||
</style>
|
||||
102
src/components/order/statistics.vue
Normal file
102
src/components/order/statistics.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入产品名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
:data="retData"
|
||||
border
|
||||
size="medium"
|
||||
:height="$getHeight(150)"
|
||||
:span-method="mergeSpan"
|
||||
show-summary
|
||||
>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="NewBuyCount" label="新开个数"></el-table-column>
|
||||
<el-table-column prop="NewBuyAmount" label="新开金额"></el-table-column>
|
||||
<el-table-column prop="AgainBuyCount" label="续费个数"></el-table-column>
|
||||
<el-table-column prop="AgainBuyAmount" label="续费金额"></el-table-column>
|
||||
<el-table-column prop="RefundCount" label="退货个数"></el-table-column>
|
||||
<el-table-column prop="RefundAmount" label="退货金额"></el-table-column>
|
||||
<!-- <el-table-column prop="PaymentAmount" label="换货个数"></el-table-column>
|
||||
<el-table-column prop="PaymentAmount" label="换货金额"></el-table-column>-->
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData:[],
|
||||
dateRange:[],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Status: 0,
|
||||
PayType: 0,
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
flagMap:{}
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
this.$store.commit("setCurrentNav","销售管理>>统计分析")
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.flagMap={};
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
this.$api.get("course/v1/order/Statistics", this.searchModel).then(res => {
|
||||
this.retData = res.Data;
|
||||
this.retData.forEach(item=>{
|
||||
var flag=this.flagMap[item.ProductName];
|
||||
if(!flag){
|
||||
this.flagMap[item.ProductName]=true;
|
||||
var count=this.retData.filter(m=>m.ProductName== item.ProductName).length;
|
||||
item.rSpan=count;
|
||||
item.cSpan=1;
|
||||
}else{
|
||||
item.rSpan=0;
|
||||
item.cSpan=0;
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
mergeSpan({row, column, rowIndex, columnIndex}){
|
||||
if (columnIndex === 0) {
|
||||
console.log(`${row.rSpan}-${row.cSpan}`)
|
||||
return {
|
||||
rowspan: row.rSpan,
|
||||
colspan: row.cSpan
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-table{
|
||||
overflow:visible !important;
|
||||
}
|
||||
</style>
|
||||
77
src/components/order/taobao.vue
Normal file
77
src/components/order/taobao.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入订单号、用户名" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="Created" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="Tid" label="订单号" width="180"></el-table-column>
|
||||
<el-table-column prop="SellerNick" label="销售人" width="180"></el-table-column>
|
||||
<el-table-column prop="BuyerNick" label="购买人" width="180"></el-table-column>
|
||||
<el-table-column prop="Phone" label="购买人手机号">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.Phone"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Price" label="单价"></el-table-column>
|
||||
<el-table-column prop="Num" label="数量"></el-table-column>
|
||||
<el-table-column prop="TotalFee" label="订单金额"></el-table-column>
|
||||
<el-table-column prop="Payment" label="实付金额"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Btime: "",
|
||||
Etime: ""
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav","订单管理>>淘宝订单")
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api.get("sells/v1/taobao/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/sells/v1/taobao/Export", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
361
src/components/product/account.vue
Normal file
361
src/components/product/account.vue
Normal file
@@ -0,0 +1,361 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-edit" @click="batchSelectUser">批量修改归属</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-edit" @click="dels">批量删除</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button>
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-edit">检测</el-button> -->
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-edit">老账号认证</el-button> -->
|
||||
|
||||
<div class="search-box">
|
||||
<el-cascader
|
||||
placeholder="选择产品/套餐"
|
||||
size="small"
|
||||
v-model="searchModel.pModel"
|
||||
:options="options"
|
||||
:props="{ checkStrictly: true}"
|
||||
clearable
|
||||
></el-cascader>
|
||||
<!-- <el-select v-model="searchModel.ProductId" placeholder="选择产品" clearable size="small">
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select> -->
|
||||
<el-select
|
||||
v-model="searchModel.accountTypes"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="选择类型"
|
||||
>
|
||||
<el-option v-for="item in types" :key="item.text" :label="item.text" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-select v-model="searchModel.ExpirdDay" placeholder="选择过期时间" clearable size="small">
|
||||
<el-option
|
||||
v-for="item in expirdtypes"
|
||||
:key="item.text"
|
||||
:label="item.text"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入产品/套餐/会员/账号" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:data="retData.Data"
|
||||
:height="$getHeight(100)"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="UserCode" label="会员">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserCode"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="AccountType" label="类型" :formatter="typeFormat"></el-table-column>
|
||||
<el-table-column prop="Account" label="账号"></el-table-column>
|
||||
<el-table-column prop="Pwd" label="密码"></el-table-column>
|
||||
<el-table-column prop="ConnectCount" label="连接数"></el-table-column>
|
||||
<el-table-column prop="StartTime" label="开通时间" width="160px"></el-table-column>
|
||||
<el-table-column prop="EndTime" label="到期时间" width="160px"></el-table-column>
|
||||
<el-table-column prop="RestTime" label="剩余时间" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
v-if="scope.row.Status==1"
|
||||
:class="{red:scope.row.RestTime=='已过期'}"
|
||||
>{{scope.row.RestTime}}</span>
|
||||
<span v-else class="red">已退款</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="selectUser(scope.row)">归属</span>
|
||||
<span class="handel cursor edit" @click="del(scope.row)">删除</span>
|
||||
<span class="handel cursor edit" @click="online(scope.row)">查看在线</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<userDrawer ref="userDrawer" @select="onSelect"></userDrawer>
|
||||
<el-dialog title="查看在线" :visible.sync="showOnlineDialog" width="900px" v-loading="loadingOnline">
|
||||
<el-table
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:data="onlineClient"
|
||||
:height="$getHeight(300)"
|
||||
>
|
||||
<el-table-column prop="Account" label="账号"></el-table-column>
|
||||
<el-table-column prop="LoginTime" label="登录时间"></el-table-column>
|
||||
<el-table-column prop="OnlineTime" label="在线时间"></el-table-column>
|
||||
<el-table-column prop="ServerIP" label="服务器Ip"></el-table-column>
|
||||
<el-table-column prop="LoginIP" label="登录ip"></el-table-column>
|
||||
<el-table-column prop="UpStream" label="上行" ></el-table-column>
|
||||
<el-table-column prop="DownStream" label="下行"></el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="killout(scope.row)">强制离线</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
userDrawer: () => import("@/components/common/userDrawer"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: [],
|
||||
showOnlineDialog:false,
|
||||
loading: false,
|
||||
loadingOnline:false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
products: [],
|
||||
dateRange: [],
|
||||
searchModel: {
|
||||
ExpirdDay: -1,
|
||||
UserId: 0,
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
ProductId: null,
|
||||
PackageId:null,
|
||||
accountTypes: null,
|
||||
pModel:[],
|
||||
Btime: "",
|
||||
Etime: "",
|
||||
},
|
||||
onlineClient:[],
|
||||
currentAccount: {},
|
||||
account: [],
|
||||
types: [
|
||||
{ text: "新开", value: 1 },
|
||||
{ text: "批量新开", value: 2 },
|
||||
{ text: "续费", value: 3 },
|
||||
{ text: "批量续费", value: 4 },
|
||||
{ text: "老账号认证", value: 100 },
|
||||
{ text: "测试", value: 200 }
|
||||
],
|
||||
expirdtypes: [
|
||||
{ text: "全部", value: -1 },
|
||||
{ text: "已过期", value: 0 },
|
||||
{ text: "1天过期", value: 1 },
|
||||
{ text: "3天过期", value: 3 },
|
||||
{ text: "1周过期", value: 7 }
|
||||
],
|
||||
typeFormat(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "新开";
|
||||
case 2:
|
||||
return "批量新开";
|
||||
case 3:
|
||||
return "续费";
|
||||
case 4:
|
||||
return "批量续费";
|
||||
case 100:
|
||||
return "老账号认证";
|
||||
case 200:
|
||||
return "测试";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "会员管理>>账号管理");
|
||||
var userId = this.$route.query.userId;
|
||||
if (userId) this.searchModel.UserId = userId;
|
||||
this.get();
|
||||
this.getProductWithPackage();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
if(this.searchModel.pModel.length>0)
|
||||
this.searchModel.ProductId=this.searchModel.pModel[0];
|
||||
if(this.searchModel.pModel.length>0)
|
||||
this.searchModel.PackageId=this.searchModel.pModel[1];
|
||||
this.$api
|
||||
.get("course/v1/productaccount/page", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
getProduct() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.products = res.Data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
getProductWithPackage() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/ProductWithPackage").then(res => {
|
||||
this.options = res.Data;
|
||||
var options = [];
|
||||
res.Data.forEach(m => {
|
||||
var product = {
|
||||
label: m.Product.Name,
|
||||
value: m.Product.Id,
|
||||
children: []
|
||||
};
|
||||
|
||||
m.Packages.forEach(p => {
|
||||
var pkg = {
|
||||
label: p.Name,
|
||||
value: p.Id
|
||||
}
|
||||
product.children.push(pkg)
|
||||
})
|
||||
options.push(product);
|
||||
});
|
||||
this.options=options;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api
|
||||
.post("course/v1/productaccount/Delete?id=" + item.Id)
|
||||
.then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
dels() {
|
||||
var that = this;
|
||||
if( this.account.length==0){
|
||||
$this.$warn('请选账号')
|
||||
return
|
||||
}
|
||||
var ids= this.account.map(m => m.Id)
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api
|
||||
.post("course/v1/productaccount/Deletes",ids)
|
||||
.then(res => {
|
||||
that.searchModel.PageIndex=1;
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
goAdd() {
|
||||
this.$router.push({ name: "addPackage", query: { optype: 1 } });
|
||||
},
|
||||
goEdit(item) {
|
||||
this.$router.push({
|
||||
name: "addPackage",
|
||||
query: { id: item.Id, optype: 2 }
|
||||
});
|
||||
},
|
||||
batchSelectUser() {
|
||||
if (this.account.length == 0) {
|
||||
this.$warn("请选择账号");
|
||||
return;
|
||||
}
|
||||
this.$refs["userDrawer"].show();
|
||||
},
|
||||
selectUser(row) {
|
||||
this.$refs.multipleTable.clearSelection();
|
||||
this.$refs.multipleTable.toggleRowSelection(row);
|
||||
this.$refs["userDrawer"].show();
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.account = val;
|
||||
},
|
||||
onSelect(item) {
|
||||
var data = {
|
||||
AccountIds: this.account.map(m => m.Id),
|
||||
UserId: item.Id
|
||||
};
|
||||
this.$confirm("确定要迁移吗?").then(_ => {
|
||||
this.$api.post("course/v1/productaccount/BindUser", data).then(res => {
|
||||
this.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
online(item){
|
||||
this.showOnlineDialog=true;
|
||||
this.loadingOnline=true;
|
||||
var params={
|
||||
productId:item.ProductId,
|
||||
account:item.Account,
|
||||
}
|
||||
this.onlineClient=[];
|
||||
this.$api
|
||||
.get("course/v1/productaccount/OnLine", params)
|
||||
.then(res => {
|
||||
this.loadingOnline=false,
|
||||
this.onlineClient = res.Data;
|
||||
this.onlineClient.forEach(m=>m.info=item)
|
||||
})
|
||||
},
|
||||
killout(item){
|
||||
var params={
|
||||
productId:item.info.ProductId,
|
||||
id:item.Id,
|
||||
}
|
||||
this.$api
|
||||
.get("course/v1/productaccount/KillOut",params)
|
||||
.then(res => {
|
||||
if(res.Data){
|
||||
this.$info("离线成功");
|
||||
}
|
||||
this.online(item.info)
|
||||
})
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/course/v1/productaccount/Export");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
274
src/components/product/accountSearch.vue
Normal file
274
src/components/product/accountSearch.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-edit" @click="batchSelectUser">批量修改归属</el-button>
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-edit">检测</el-button> -->
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-edit">老账号认证</el-button> -->
|
||||
|
||||
<div class="search-box">
|
||||
<!-- <el-select v-model="searchModel.ProductId" placeholder="选择产品" clearable size="small">
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="searchModel.accountTypes"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="选择类型"
|
||||
>
|
||||
<el-option v-for="item in types" :key="item.text" :label="item.text" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-select v-model="searchModel.ExpirdDay" placeholder="选择过期时间" clearable size="small">
|
||||
<el-option
|
||||
v-for="item in expirdtypes"
|
||||
:key="item.text"
|
||||
:label="item.text"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select> -->
|
||||
<el-input v-model="searchModel.keyWord" placeholder="会员/账号" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:data="retData.Data"
|
||||
:height="$getHeight(100)"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="UserCode" label="会员">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserCode"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="AccountType" label="类型" :filters="types" :formatter="typeFormat"></el-table-column>
|
||||
<el-table-column prop="Account" label="账号"></el-table-column>
|
||||
<el-table-column prop="Pwd" label="密码"></el-table-column>
|
||||
<el-table-column prop="ConnectCount" label="连接数"></el-table-column>
|
||||
<el-table-column prop="StartTime" label="开通时间" width="160px"></el-table-column>
|
||||
<el-table-column prop="EndTime" label="到期时间" width="160px"></el-table-column>
|
||||
<el-table-column prop="RestTime" label="剩余时间" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
v-if="scope.row.Status==1"
|
||||
:class="{red:scope.row.RestTime=='已过期'}"
|
||||
>{{scope.row.RestTime}}</span>
|
||||
<span v-else class="red">已退款</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="selectUser(scope.row)">归属</span>
|
||||
<span class="handel cursor edit" @click="del(scope.row)">删除</span>
|
||||
<span class="handel cursor edit" @click="online(scope.row)">查看在线</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<userDrawer ref="userDrawer" @select="onSelect"></userDrawer>
|
||||
<el-dialog title="查看在线" :visible.sync="showOnlineDialog" width="900px" v-loading="loadingOnline">
|
||||
<el-table
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:data="onlineClient"
|
||||
:height="$getHeight(300)"
|
||||
>
|
||||
<el-table-column prop="Account" label="账号"></el-table-column>
|
||||
<el-table-column prop="LoginTime" label="登录时间"></el-table-column>
|
||||
<el-table-column prop="OnlineTime" label="在线时间"></el-table-column>
|
||||
<el-table-column prop="ServerIP" label="服务器Ip"></el-table-column>
|
||||
<el-table-column prop="LoginIP" label="登录ip"></el-table-column>
|
||||
<el-table-column prop="UpStream" label="上行" ></el-table-column>
|
||||
<el-table-column prop="DownStream" label="下行"></el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="killout(scope.row)">强制离线</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
userDrawer: () => import("@/components/common/userDrawer"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showOnlineDialog:false,
|
||||
loading: false,
|
||||
loadingOnline:false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
products: [],
|
||||
searchModel: {
|
||||
ExpirdDay: -1,
|
||||
UserId: 0,
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
ProductId: null,
|
||||
accountTypes: null
|
||||
},
|
||||
onlineClient:[],
|
||||
currentAccount: {},
|
||||
account: [],
|
||||
types: [
|
||||
{ text: "新开", value: 1 },
|
||||
{ text: "批量新开", value: 2 },
|
||||
{ text: "续费", value: 3 },
|
||||
{ text: "批量续费", value: 4 },
|
||||
{ text: "老账号认证", value: 100 },
|
||||
{ text: "测试", value: 200 }
|
||||
],
|
||||
expirdtypes: [
|
||||
{ text: "全部", value: -1 },
|
||||
{ text: "已过期", value: 0 },
|
||||
{ text: "1天过期", value: 1 },
|
||||
{ text: "3天过期", value: 3 },
|
||||
{ text: "1周过期", value: 7 }
|
||||
],
|
||||
typeFormat(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "新开";
|
||||
case 2:
|
||||
return "批量新开";
|
||||
case 3:
|
||||
return "续费";
|
||||
case 4:
|
||||
return "批量续费";
|
||||
case 100:
|
||||
return "老账号认证";
|
||||
case 200:
|
||||
return "测试";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "会员管理>>账号查询");
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api
|
||||
.get("course/v1/productaccount/Search", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
getProduct() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.products = res.Data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api
|
||||
.post("course/v1/productaccount/Delete?id=" + item.Id)
|
||||
.then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
goAdd() {
|
||||
this.$router.push({ name: "addPackage", query: { optype: 1 } });
|
||||
},
|
||||
goEdit(item) {
|
||||
this.$router.push({
|
||||
name: "addPackage",
|
||||
query: { id: item.Id, optype: 2 }
|
||||
});
|
||||
},
|
||||
batchSelectUser() {
|
||||
if (this.account.length == 0) {
|
||||
this.$warn("请选择账号");
|
||||
return;
|
||||
}
|
||||
this.$refs["userDrawer"].show();
|
||||
},
|
||||
selectUser(row) {
|
||||
this.$refs.multipleTable.clearSelection();
|
||||
this.$refs.multipleTable.toggleRowSelection(row);
|
||||
this.$refs["userDrawer"].show();
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.account = val;
|
||||
},
|
||||
onSelect(item) {
|
||||
var data = {
|
||||
AccountIds: this.account.map(m => m.Id),
|
||||
UserId: item.Id
|
||||
};
|
||||
this.$confirm("确定要迁移吗?").then(_ => {
|
||||
this.$api.post("course/v1/productaccount/BindUser", data).then(res => {
|
||||
this.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
online(item){
|
||||
this.showOnlineDialog=true;
|
||||
this.loadingOnline=true;
|
||||
var params={
|
||||
productId:item.ProductId,
|
||||
account:item.Account,
|
||||
}
|
||||
this.onlineClient=[];
|
||||
this.$api
|
||||
.get("course/v1/productaccount/OnLine", params)
|
||||
.then(res => {
|
||||
this.loadingOnline=false,
|
||||
this.onlineClient = res.Data;
|
||||
this.onlineClient.forEach(m=>m.info=item)
|
||||
})
|
||||
},
|
||||
killout(item){
|
||||
var params={
|
||||
productId:item.info.ProductId,
|
||||
id:item.Id,
|
||||
}
|
||||
this.$api
|
||||
.get("course/v1/productaccount/KillOut",params)
|
||||
.then(res => {
|
||||
this.online(item.info)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
187
src/components/product/config.vue
Normal file
187
src/components/product/config.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入产品名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)" :row-style="rowStyle">
|
||||
<el-table-column prop="Name" label="产品名称" width="180"></el-table-column>
|
||||
<el-table-column prop="Account" label="账号"></el-table-column>
|
||||
<el-table-column label="密码">
|
||||
<template>
|
||||
<span>*********</span>
|
||||
<!-- <span @click="goLook(scope.row)">
|
||||
<i class="el-icon-view"></i>
|
||||
</span> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="BaseUrl" label="接口地址"></el-table-column>
|
||||
<el-table-column prop="Status" label="状态">
|
||||
<template slot-scope="scope">
|
||||
<span :class="{statusRed:scope.row.Status==0}">{{statusFormat(scope.row.Status)}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="goLogin(scope.row)">检测</span>
|
||||
<span class="handel cursor edit" @click="goEdit(scope.row)">编辑</span>
|
||||
<!-- <span class="handel cursor del" @click="del(scope.row)">删除</span> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-dialog title="产品配置" :visible.sync="showDialog" width="400px">
|
||||
<el-form :model="currentProduct" :rules="rules" ref="inputProductForm" label-width="80px">
|
||||
<el-form-item prop="Account" label="账户">
|
||||
<el-input v-model="currentProduct.Account" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Pwd" label="密码">
|
||||
<el-input v-model="currentProduct.Pwd" show-password size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="LoginUrl" label="登录地址">
|
||||
<el-input v-model="currentProduct.BaseUrl" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputProductForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog title="登录" :visible.sync="showLoginDialog" width="400px">
|
||||
<el-form :model="loginModel" :rules="loginRules" ref="inputLoginForm" label-width="80px">
|
||||
<el-form-item prop="Code" label="验证码" v-if="loginModel.LoginCodeUrl!=''">
|
||||
<el-input v-model="loginModel.Code" size="small">
|
||||
<img :src="loginModel.LoginCodeUrl" alt="" @click="getCode" slot="append"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputLoginForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="Login">检测</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
showLoginDialog:false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
loginModel:{
|
||||
ProductId:0,
|
||||
Code:"",
|
||||
LoginCodeUrl:'',
|
||||
Key:""
|
||||
},
|
||||
currentProduct: {
|
||||
Id: 0,
|
||||
Name: "",
|
||||
Profile: "",
|
||||
Image: ""
|
||||
},
|
||||
rules: {
|
||||
Account: [this.$vaild.required("账户")],
|
||||
Pwd: [this.$vaild.required("密码")],
|
||||
LoginUrl: [this.$vaild.required("登录地址")]
|
||||
},
|
||||
loginRules:{
|
||||
Code: [this.$vaild.required("验证码")],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>产品配置");
|
||||
this.get();
|
||||
setInterval(this.get, 30*1000);
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
goEdit(item) {
|
||||
this.currentProduct = item;
|
||||
this.showDialog = true;
|
||||
},
|
||||
goLogin(item) {
|
||||
this.currentProduct=item;
|
||||
// this.loginModel.LoginCodeUrl=item.LoginCodeUrl+"&="+(new Date()).getTime();
|
||||
this.loginModel.ProductId= item.Id;
|
||||
this.getCode()
|
||||
this.showLoginDialog = true;
|
||||
},
|
||||
getCode(){
|
||||
this.$api
|
||||
.get("course/v1/agent/GetCode?productId="+this.currentProduct.Id, )
|
||||
.then(res => {
|
||||
if(res.Code==10000){
|
||||
this.loginModel.LoginCodeUrl=res.Data.CodeImage;
|
||||
this.loginModel.Key=res.Data.Key;
|
||||
}else{
|
||||
this.$error('验证码获取失败')
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
save() {
|
||||
this.$api
|
||||
.post("course/v1/product/putConfig", this.currentProduct)
|
||||
.then(res => {
|
||||
this.resetForm('inputProductForm');
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
Login() {
|
||||
this.$api
|
||||
.post("course/v1/agent/Login",this.loginModel)
|
||||
.then(res => {
|
||||
this.resetForm('inputLoginForm');
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
statusFormat(value) {
|
||||
console.log(value)
|
||||
if(value==1)return "在线";
|
||||
return "离线"
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.showDialog = false;
|
||||
this.showLoginDialog = false;
|
||||
},
|
||||
rowStyle({ row, rowIndex}) {
|
||||
if (row.Status === 0) {
|
||||
return 'color:red'
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.statusRed{
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
163
src/components/product/list.vue
Normal file
163
src/components/product/list.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入产品名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="Image" label="产品图片" width="80px">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.Image" style="width:32px;height:32px" alt />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Name" label="产品名称" width="180"></el-table-column>
|
||||
<el-table-column prop="RefundDayPrice" label="退款单价" width="180"></el-table-column>
|
||||
<el-table-column prop="DayLimitPrice" label="最低价格" width="180"></el-table-column>
|
||||
<el-table-column prop="Status" label="上下架" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.OnLine"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#dcdfe6"
|
||||
@change="changeLineStatus(scope.row)"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="Profile" label="产品说明"></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="goEdit(scope.row)">编辑</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog title="产品维护" :visible.sync="showDialog" width="400px">
|
||||
<el-form :model="currentProduct" :rules="rules" ref="inputProductForm" label-width="80px">
|
||||
<el-form-item prop="Name" label="产品名称">
|
||||
<el-input v-model="currentProduct.Name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="RefundDayPrice" label="退款单价">
|
||||
<el-input v-model="currentProduct.RefundDayPrice" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="DayLimitPrice" label="最低价格">
|
||||
<el-input v-model="currentProduct.DayLimitPrice" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Profile" label="产品说明">
|
||||
<el-input type="textarea" :rows="3" v-model="currentProduct.Profile" size="small" ></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item prop="Image" label="产品图标">
|
||||
<span class="uploadimg_box">
|
||||
<img
|
||||
:src="currentProduct.Image"
|
||||
v-if="currentProduct.Image!=''"
|
||||
class="uploadimg"
|
||||
@click="upload"
|
||||
/>
|
||||
<span class="ubloadbtn" v-else>
|
||||
<img src="/static/img/common/imgadd.png" @click="upload" />
|
||||
</span>
|
||||
<p class="imgTip" @click="upload">点击更换</p>
|
||||
</span>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
currentProduct: {
|
||||
Id:0,
|
||||
Name:"",
|
||||
Profile:"",
|
||||
Image:""
|
||||
},
|
||||
rules:{
|
||||
Name:[this.$vaild.required("产品名称")]
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>产品列表");
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.loading=true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
this.loading=false;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api.post("course/v1/product/Delete?id=" + item.Id).then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
goEdit(item) {
|
||||
this.currentProduct=item;
|
||||
this.showDialog=true;
|
||||
},
|
||||
save() {
|
||||
this.$api.post("course/v1/product/put", this.currentProduct).then(res => {
|
||||
this.resetForm()
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
changeLineStatus(item) {
|
||||
this.$api
|
||||
.post("course/v1/product/SetProductLine?id=" + item.Id)
|
||||
.then(res => {
|
||||
item.Status = res.Data;
|
||||
});
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs["inputProductForm"].resetFields();
|
||||
this.showDialog = false;
|
||||
},
|
||||
upload(callback) {
|
||||
this.$api.upload("oss/v1/ImageCloud/upload").then(res => {
|
||||
this.courseModel.Cover = ret.Url;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
153
src/components/product/package.vue
Normal file
153
src/components/product/package.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-plus" @click="goAdd">新建套餐</el-button> -->
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入套餐名称/标题" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<el-tabs tab-position="left" :style="$getStyleHeight(100)">
|
||||
<el-tab-pane :label="item.Product.Name" v-for="(item,index) in product" :key="index">
|
||||
<el-table
|
||||
:data="item.Packages"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:height="$getHeight(100)"
|
||||
>
|
||||
<el-table-column prop="Name" label="套餐名称"></el-table-column>
|
||||
<el-table-column prop="Title" label="套餐标题"></el-table-column>
|
||||
<el-table-column prop="Price" label="价格"></el-table-column>
|
||||
<el-table-column prop="LinePrice" label="划线价"></el-table-column>
|
||||
<el-table-column prop="DayPrice" label="价格/天"></el-table-column>
|
||||
<el-table-column prop="MinPrice" label="最低价"></el-table-column>
|
||||
<el-table-column prop="Profile" label="期限说明"></el-table-column>
|
||||
<el-table-column prop="Status" label="上架状态" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.Status"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#dcdfe6"
|
||||
@change="changeLineStatus(scope.row)"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="包含基本套餐">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="bindCourse(scope.row)">套餐</span>
|
||||
</template>
|
||||
</el-table-column>-->
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="goEdit(scope.row)">编辑</span>
|
||||
<!-- <span class="handel cursor del" @click="del(scope.row)">删除</span> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<el-dialog title="套餐维护" :visible.sync="showDialog" width="400px">
|
||||
<el-form
|
||||
:model="currentPackage"
|
||||
:rules="rules"
|
||||
ref="inputPackageForm"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item prop="Name" label="套餐名称">
|
||||
<el-input v-model="currentPackage.Name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Price" label="套餐价格">
|
||||
<el-input v-model="currentPackage.Price" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="LinePrice" label="划线价格">
|
||||
<el-input v-model="currentPackage.LinePrice" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="MinPrice" label="最低价格">
|
||||
<el-input v-model="currentPackage.MinPrice" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Profile" label="说明">
|
||||
<el-input v-model="currentPackage.Profile" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
product:[],
|
||||
currentPackage: {},
|
||||
rules:{}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>套餐管理");
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.$api.get("course/v1/product/ProductWithPackage").then(res => {
|
||||
this.product = res.Data;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api.post("course/v1/package/Delete?id=" + item.Id).then(res => {
|
||||
this.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
goEdit(item) {
|
||||
this.currentPackage =clone(item);
|
||||
this.showDialog = true;
|
||||
},
|
||||
save() {
|
||||
this.$api
|
||||
.post("course/v1/product/PutPackage", this.currentPackage)
|
||||
.then(res => {
|
||||
this.resetForm();
|
||||
this.get();
|
||||
// this.currentPackage = res.Data;
|
||||
});
|
||||
},
|
||||
changeLineStatus(item) {
|
||||
this.$api
|
||||
.post("course/v1/product/SetPackageLine?id=" + item.Id)
|
||||
.then(res => {
|
||||
item.Status = res.Data;
|
||||
});
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs["inputPackageForm"].resetFields();
|
||||
this.showDialog = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
139
src/components/product/pricediscount.vue
Normal file
139
src/components/product/pricediscount.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-plus" @click="goAdd">新建套餐</el-button> -->
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入套餐名称/标题" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<el-tabs tab-position="left" :style="$getStyleHeight(100)">
|
||||
<el-tab-pane
|
||||
:label="item.Product.Name"
|
||||
v-for="(item,index) in productDiscount"
|
||||
:key="index"
|
||||
>
|
||||
<el-table
|
||||
:data="item.PackageDiscounts"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:height="$getHeight(100)"
|
||||
>
|
||||
<el-table-column prop="Package.Name" label="套餐名称"></el-table-column>
|
||||
<el-table-column prop="Package.Price" label="原价格"></el-table-column>
|
||||
<el-table-column prop="PriceDiscount.BuyPriceDiscount" label="购买折扣">
|
||||
<template slot-scope="scope">{{scope.row.PriceDiscount.BuyPriceDiscount||'--'}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="PriceDiscount.RefundDayPriceDiscount" label="退款折扣">
|
||||
<template slot-scope="scope">{{scope.row.PriceDiscount.RefundDayPriceDiscount||'--'}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="PriceDiscount.Remark" label="说明"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="goEdit(scope.row)">编辑</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<el-dialog title="折扣维护" :visible.sync="showDialog" width="400px">
|
||||
<el-form :model="current" :rules="rules" ref="inputPackageForm" label-width="80px">
|
||||
<el-form-item prop="Name" label="套餐名称">
|
||||
<el-input v-model="current.Name" size="small" disabled></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item prop="Price" label="原价格">
|
||||
<el-input v-model="current.Price" type="number" size="small" disabled></el-input>
|
||||
</el-form-item> -->
|
||||
<el-form-item prop="MinPrice" label="购买折扣">
|
||||
<el-input v-model="current.BuyPriceDiscount" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="RefundDayPriceDiscount" label="退款折扣">
|
||||
<el-input v-model="current.RefundDayPriceDiscount" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Remark" label="说明">
|
||||
<el-input v-model="current.Remark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
productDiscount: [],
|
||||
current: {
|
||||
Remark: "",
|
||||
BuyPriceDiscount: 0,
|
||||
SchemeId: 0,
|
||||
PackageId: 0,
|
||||
ProductId: 0,
|
||||
RefundDayPriceDiscount: 0
|
||||
},
|
||||
rules: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>产品折扣");
|
||||
this.current.SchemeId = this.$route.query.id;
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.$api
|
||||
.get("course/v1/scheme/GetProductDiscount?id=" + this.current.SchemeId)
|
||||
.then(res => {
|
||||
this.productDiscount = res.Data;
|
||||
});
|
||||
},
|
||||
goEdit(item) {
|
||||
console.log(item);
|
||||
this.showDialog = true;
|
||||
this.current.Name = item.Package.Name;
|
||||
this.current.ProductId = item.Package.ProductId;
|
||||
this.current.PackageId = item.Package.Id;
|
||||
this.current.BuyPriceDiscount = item.PriceDiscount.BuyPriceDiscount;
|
||||
this.current.RefundDayPriceDiscount =
|
||||
item.PriceDiscount.RefundDayPriceDiscount;
|
||||
},
|
||||
save() {
|
||||
this.$api
|
||||
.post("course/v1/scheme/PutProductDiscount", this.current)
|
||||
.then(res => {
|
||||
this.resetForm();
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
changeStatus(item) {
|
||||
this.$api
|
||||
.post("course/v1/scheme/SetUserPriceStatus?id=" + item.UserPrice.Id)
|
||||
.then(res => {
|
||||
item.Status = res.Data;
|
||||
});
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs["inputPackageForm"].resetFields();
|
||||
this.showDialog = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
149
src/components/product/pricescheme.vue
Normal file
149
src/components/product/pricescheme.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-edit" @click="add">添加</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入方案名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:data="retData.Data"
|
||||
:height="$getHeight(100)"
|
||||
>
|
||||
<el-table-column prop="Name" label="方案名称"></el-table-column>
|
||||
<el-table-column prop="Remark" label="方案说明"></el-table-column>
|
||||
<el-table-column prop="CreateTime" label="创建时间"></el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="edit(scope.row)">编辑</span>
|
||||
<router-link :to="{name:'pricediscount',query:{id:scope.row.Id}}">
|
||||
<span class="handel cursor edit">折扣</span>
|
||||
</router-link>
|
||||
<span class="handel cursor edit" @click="del(scope.row)">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-dialog title="方案维护" :visible.sync="showDialog" width="500px">
|
||||
<el-form :model="schemeModel" :rules="rules" ref="inputForm" label-width="80px">
|
||||
<el-form-item prop="Name" label="方案名称">
|
||||
<el-input v-model="schemeModel.Name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Remark" label="方案说明">
|
||||
<el-input v-model="schemeModel.Remark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="save('inputForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
optype:1,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
},
|
||||
schemeModel: {
|
||||
Name:'',
|
||||
Remark:'',
|
||||
},
|
||||
types: [
|
||||
],
|
||||
rules: {
|
||||
Name: [this.$vaild.required("方案名称")]
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>价格方案");
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api
|
||||
.get("course/v1/scheme/page", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api
|
||||
.post("course/v1/scheme/Delete?id=" + item.Id)
|
||||
.then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.showDialog = true;
|
||||
this.optype = 1;
|
||||
},
|
||||
edit(item) {
|
||||
this.showDialog = true;
|
||||
this.optype = 2;
|
||||
this.schemeModel = clone(item);
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.showDialog = false;
|
||||
},
|
||||
save(formName) {
|
||||
var that=this;
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (!valid) return;
|
||||
if (that.optype == 1) {
|
||||
that.$api.post("course/v1/scheme/post", that.schemeModel).then(res => {
|
||||
that.resetForm('inputForm');
|
||||
that.get();
|
||||
});
|
||||
} else {
|
||||
that.$api.post("course/v1/scheme/put", that.schemeModel).then(res => {
|
||||
that.resetForm('inputForm');
|
||||
that.get();
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
217
src/components/product/route.vue
Normal file
217
src/components/product/route.vue
Normal file
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-edit" @click="add">添加</el-button>
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-upload" @click="importExcel">导入</el-button>
|
||||
<a href="http://www.ipkd.com/tpl.xlsx"><el-button size="small" type="primary" icon="el-icon-download" @click="importExcel">下载模板</el-button></a> -->
|
||||
<div class="search-box">
|
||||
<el-select v-model="searchModel.productId" placeholder="选择产品" clearable size="small">
|
||||
<el-option v-for="item in products" :key="item.Name" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入城市或者运营商" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:data="retData.Data"
|
||||
:height="$getHeight(100)"
|
||||
@filter-change="filterHandler"
|
||||
>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="Province" label="省份"></el-table-column>
|
||||
<el-table-column prop="City" label="城市"></el-table-column>
|
||||
<el-table-column prop="Name" label="运营商"></el-table-column>
|
||||
<el-table-column prop="ServerUrl" label="服务器域名"></el-table-column>
|
||||
<el-table-column prop="Status" label="运行状态"></el-table-column>
|
||||
<el-table-column prop="LineType" label="支持方式"></el-table-column>
|
||||
<el-table-column prop="BandWidth" label="实时带宽"></el-table-column>
|
||||
<el-table-column prop="IpRemark" label="Ip量"></el-table-column>
|
||||
<el-table-column prop="Sort" label="排序"></el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="edit(scope.row)">编辑</span>
|
||||
<span class="handel cursor edit" @click="del(scope.row)">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-dialog title="线路维护" :visible.sync="showDialog" width="500px">
|
||||
<el-form :model="routeModel" :rules="rules" ref="inputForm" label-width="80px">
|
||||
<el-form-item prop="ProductId" label="产品">
|
||||
<el-select size="small" v-model="routeModel.ProductId">
|
||||
<el-option v-for="(item,index) in products" :key="index" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Province" label="省份">
|
||||
<el-input v-model="routeModel.Province" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="City" label="城市">
|
||||
<el-input v-model="routeModel.City" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Name" label="运营商">
|
||||
<el-input v-model="routeModel.Name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="ServerUrl" label="服务器域名">
|
||||
<el-input v-model="routeModel.ServerUrl" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Status" label="运行状态">
|
||||
<el-radio-group v-model="routeModel.Status" size="small">
|
||||
<el-radio label="正常">正常</el-radio>
|
||||
<el-radio label="离线">离线</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Sort" label="排序">
|
||||
<el-input v-model="routeModel.Sort" size="small" number ></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="LineType" label="支持方式">
|
||||
<el-input v-model="routeModel.LineType" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="BandWidth" label="带宽">
|
||||
<el-input v-model="routeModel.BandWidth" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="IpRemark" label="Ip">
|
||||
<el-input v-model="routeModel.IpRemark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="save('inputForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
optype:1,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
productId:"",
|
||||
},
|
||||
products:[],
|
||||
routeModel: {
|
||||
LineType:'L.P.T',
|
||||
Status:'正常',
|
||||
},
|
||||
types: [
|
||||
],
|
||||
rules: {
|
||||
ProductId: [this.$vaild.required("产品")],
|
||||
Province: [this.$vaild.required("省份")],
|
||||
City: [this.$vaild.required("城市")],
|
||||
ServerUrl: [this.$vaild.required("服务器域名")],
|
||||
Name: [this.$vaild.required("运营商")]
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>线路管理");
|
||||
this.getProducts()
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
getProducts(){
|
||||
this.$api
|
||||
.get("course/v1/product/page", this.searchModel)
|
||||
.then(res => {
|
||||
this.products= res.Data;
|
||||
//this.types=this.products.map(m=>{ return {text:m.Name,value:m.Id} })
|
||||
});
|
||||
},
|
||||
get() {
|
||||
this.$api
|
||||
.get("course/v1/productroute/page", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api
|
||||
.post("course/v1/productroute/Delete?id=" + item.Id)
|
||||
.then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.showDialog = true;
|
||||
this.optype = 1;
|
||||
},
|
||||
edit(item) {
|
||||
this.showDialog = true;
|
||||
this.optype = 2;
|
||||
this.routeModel = clone(item);
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.showDialog = false;
|
||||
},
|
||||
filterHandler(filters) {
|
||||
console.log(filters)
|
||||
var values=Object.values(filters);
|
||||
this.searchModel.productIds=values.join(',')
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
save(formName) {
|
||||
var that=this;
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (!valid) return;
|
||||
var [name]=that.products.filter(m=>m.Id==that.routeModel.ProductId).map(m=>m.Name);
|
||||
that.routeModel.ProductName=name
|
||||
if (that.optype == 1) {
|
||||
that.$api.post("course/v1/productroute/post", that.routeModel).then(res => {
|
||||
that.resetForm('inputForm');
|
||||
that.get();
|
||||
});
|
||||
} else {
|
||||
that.$api.post("course/v1/productroute/put", that.routeModel).then(res => {
|
||||
that.resetForm('inputForm');
|
||||
that.get();
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
importExcel(callback) {
|
||||
this.$api.upload("course/v1/productroute/Import",{accept:"*/*"}).then(res => {
|
||||
this.get()
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
127
src/components/product/soft.vue
Normal file
127
src/components/product/soft.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入产品名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="Name" label="产品名称" width="180"></el-table-column>
|
||||
<el-table-column prop="PcClientDownloadUrl" label="电脑客户端">
|
||||
<template slot-scope="scope">
|
||||
<!-- <span><i class="el-icon-copy-document"></i>复制</span> -->
|
||||
<cutTip :text="scope.row.PcClientDownloadUrl"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="SimulatorDownloadUrl" label="模拟器">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.SimulatorDownloadUrl"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="DroidDownloadUrl" label="安卓客户端">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.SimulatorDownloadUrl"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="IosDownloadUrl" label="Ios客户端">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.SimulatorDownloadUrl"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="goEdit(scope.row)">编辑</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-dialog title="软件下载配置" :visible.sync="showDialog" width="400px">
|
||||
<el-form :model="currentProduct" :rules="rules" ref="inputProductForm" label-width="100px">
|
||||
<el-form-item prop="PcClientDownloadUrl" label="电脑客户端">
|
||||
<el-input v-model="currentProduct.PcClientDownloadUrl" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="DroidDownloadUrl" label="安卓客户端">
|
||||
<el-input v-model="currentProduct.DroidDownloadUrl" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="IosDownloadUrl" label="Ios客户端">
|
||||
<el-input v-model="currentProduct.IosDownloadUrl" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="SimulatorDownloadUrl" label="模拟器">
|
||||
<el-input v-model="currentProduct.SimulatorDownloadUrl" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
cutTip: () => import("@/components/common/cutTip")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
currentProduct: {
|
||||
Id: 0,
|
||||
Name: "",
|
||||
Profile: "",
|
||||
Image: ""
|
||||
},
|
||||
rules: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "产品管理>>下载配置");
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.loading = true;
|
||||
this.$api.get("course/v1/product/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
goEdit(item) {
|
||||
this.currentProduct = item;
|
||||
this.showDialog = true;
|
||||
},
|
||||
save() {
|
||||
this.$api
|
||||
.post("course/v1/product/putSoft", this.currentProduct)
|
||||
.then(res => {
|
||||
this.resetForm();
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs["inputProductForm"].resetFields();
|
||||
this.showDialog = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
250
src/components/sell/coupon.vue
Normal file
250
src/components/sell/coupon.vue
Normal file
@@ -0,0 +1,250 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="add">新建优惠券</el-button>
|
||||
<div class="search-box">
|
||||
<!-- <el-select v-model="value" placeholder="请选择" size="small">
|
||||
<el-option label="全部状态" value="0"></el-option>
|
||||
<el-option label="未开始" value="1"></el-option>
|
||||
<el-option label="进行中" value="2"></el-option>
|
||||
<el-option label="已结束" value="3"></el-option>
|
||||
<el-option label="已失效" value="4"></el-option>
|
||||
</el-select>-->
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入套餐名称/标题" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(110)">
|
||||
<el-table-column prop="Name" label="优惠券名称"></el-table-column>
|
||||
<el-table-column prop="CouponType" label="类型">
|
||||
<template slot-scope="scope">{{scope.row.CouponType==1?"满减券":"折扣券"}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CouponValue" label="优惠内容">
|
||||
<template
|
||||
slot-scope="scope"
|
||||
>{{scope.row.CouponType==1?"减"+scope.row.CouponValue+"元":scope.row.CouponValue+"折"}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已领取">
|
||||
<template slot-scope="scope">{{scope.row.GrantCount}}</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="UseCount" label="已使用" width="80"></el-table-column> -->
|
||||
<el-table-column label="使用日期" width="240">
|
||||
<template slot-scope="scope">
|
||||
<div
|
||||
v-if="scope.row.DateRule==1&&scope.row.StartDate&&scope.row.EndDate"
|
||||
>{{scope.row.StartDate.DateFormat('yyyy-MM-dd')}}至{{scope.row.EndDate.DateFormat('yyyy-MM-dd')}}</div>
|
||||
<div v-else-if="scope.row.DateRule==2">领取当天起{{scope.row.ValidDay}}天内有效</div>
|
||||
<div v-else>领取次日起{{scope.row.ValidDay}}天内有效</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="give(scope.row)">发放</span>
|
||||
<span class="handel cursor edit" @click="edit(scope.row)">编辑</span>
|
||||
<router-link :to="{name:'couponused',query:{couponId:scope.row.Id,couponName:scope.row.Name}}">
|
||||
<span class="handel cursor edit">明细</span>
|
||||
</router-link>
|
||||
<!-- <span class="handel cursor edit" v-if="scope.row.Disabled==0" @click="disabled(scope.row)">使失效</span> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-dialog title="优惠券维护" :visible.sync="showDialog" width="680px">
|
||||
<el-form :model="currentModel" :rules="rules" ref="inputForm" label-width="100px">
|
||||
<el-form-item prop="CouponType" label="优惠券类型">
|
||||
<el-radio-group v-model="currentModel.CouponType">
|
||||
<el-radio :label="1">满减券</el-radio>
|
||||
<el-radio :label="2">折扣券</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Name" label="优惠券名称">
|
||||
<el-input v-model="currentModel.Name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="CouponValue" label="优惠内容">
|
||||
<div v-if="currentModel.CouponType==1">
|
||||
<el-input v-model="currentModel.CouponValue" placeholder="请输入优惠券金额" size="small">
|
||||
<el-button slot="append">元</el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="discount-box" v-else>
|
||||
<el-input v-model="currentModel.CouponValue" placeholder="请输入优惠券折扣(1-10)" size="small">
|
||||
<el-button slot="append">折</el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item prop="isLimitAmount" label="使用门槛">
|
||||
<el-radio-group v-model="isLimitAmount">
|
||||
<el-radio :label="0">无门槛</el-radio>
|
||||
<el-radio :label="1">
|
||||
<el-input
|
||||
v-model="currentModel.AllowMinAmount"
|
||||
size="small"
|
||||
placeholder="请输入满xx元后方可使用"
|
||||
></el-input>
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="DateRule" label="使用时间">
|
||||
<el-radio-group v-model="currentModel.DateRule">
|
||||
<el-radio :label="1">
|
||||
特定时间段
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-radio>
|
||||
<el-radio :label="2">
|
||||
领取当日起
|
||||
<el-input v-model="currentModel.ValidDay" size="small" />天内可用
|
||||
</el-radio>
|
||||
<el-radio :label="3">
|
||||
领取次日起
|
||||
<el-input v-model="currentModel.ValidDay" size="small" />天内可用
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm">取 消</el-button>
|
||||
<el-button type="primary" @click="save()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<userDrawer ref="userDrawer" @select="onSelect"></userDrawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
var that = null;
|
||||
export default {
|
||||
components: {
|
||||
userDrawer: () => import("@/components/common/userDrawer")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
optype: 1, //1:新建 2:编辑
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
currentModel: {
|
||||
CouponType: 1,
|
||||
DateRule: 1,
|
||||
ValidDay: 0,
|
||||
CouponValue: 0,
|
||||
AllowMinAmount: 0,
|
||||
StartDate: null,
|
||||
EndDate: null
|
||||
},
|
||||
giveModel:{
|
||||
CouponId:0,
|
||||
UserId:0
|
||||
},
|
||||
isLimitAmount: 0,
|
||||
dateRange: [],
|
||||
rules: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "优惠券管理");
|
||||
this.get(1);
|
||||
},
|
||||
methods: {
|
||||
get(page) {
|
||||
if (Number.isInteger(page)) {
|
||||
this.searchModel.PageIndex = page;
|
||||
}
|
||||
this.$api.get("sells/v1/coupon/Page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.optype = 1;
|
||||
this.showDialog = true;
|
||||
},
|
||||
edit(item) {
|
||||
this.optype = 2;
|
||||
this.showDialog = true;
|
||||
this.currentModel = clone(item);
|
||||
if (item.AllowMinAmount > 0) this.isLimitAmount = 1;
|
||||
else this.isLimitAmount = 0;
|
||||
},
|
||||
save() {
|
||||
this.currentModel.StartDate = this.dateRange[0];
|
||||
this.currentModel.EndDate = this.dateRange[1];
|
||||
if (this.isLimitAmount == 0) this.currentModel.AllowMinAmount = 0;
|
||||
if (this.optype == 1) {
|
||||
this.$api.post("sells/v1/coupon/Post", this.currentModel).then(res => {
|
||||
this.resetForm();
|
||||
this.get();
|
||||
});
|
||||
} else {
|
||||
this.$api.post("sells/v1/coupon/put", this.currentModel).then(res => {
|
||||
this.resetForm();
|
||||
this.get();
|
||||
});
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs["inputForm"].resetFields();
|
||||
this.showDialog = false;
|
||||
},
|
||||
disabled(item) {
|
||||
this.$api.post("sells/v1/coupon/Disabled?id=" + item.Id).then(res => {
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
give(row) {
|
||||
this.giveModel.CouponId=row.Id;
|
||||
this.$refs["userDrawer"].show();
|
||||
},
|
||||
onSelect(item) {
|
||||
this.giveModel.UserId=item.Id;
|
||||
this.$confirm("确定要赠送吗?").then(_ => {
|
||||
this.$api.post("sells/v1/coupon/give", this.giveModel).then(res => {
|
||||
this.get();
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.xeBtnDefault {
|
||||
outline: medium;
|
||||
color: #666;
|
||||
background: #fafbfc;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.btnMid {
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
.el-radio {
|
||||
padding: 5px 0;
|
||||
}
|
||||
</style>
|
||||
290
src/components/sell/coupon_add.vue
Normal file
290
src/components/sell/coupon_add.vue
Normal file
@@ -0,0 +1,290 @@
|
||||
|
||||
<template>
|
||||
<div class="couponbox">
|
||||
<el-alert
|
||||
title="优惠券说明"
|
||||
type="info"
|
||||
description=" 优惠券总量为用户领取、定向发放、兑换码兑换、支付有礼发放、运营计划发放所产生的优惠券数量,具体数量可在效果数据中查看。"
|
||||
show-icon
|
||||
></el-alert>
|
||||
|
||||
<div class="baseInfo">
|
||||
<h2 class="title">基本信息</h2>
|
||||
<section class="creat_item">
|
||||
<label for="title" class="lable">
|
||||
优惠券名称
|
||||
<span class="star">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="couponModel.Name"
|
||||
placeholder="优惠券名称,不超过10个字"
|
||||
maxlength="10"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</section>
|
||||
<section class="creat_item flex">
|
||||
<div class="lable">
|
||||
优惠券类型
|
||||
<span class="star">*</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<el-radio v-model="couponModel.CouponType" :label="1">满减优惠券</el-radio>
|
||||
<el-radio v-model="couponModel.CouponType" :label="2">折扣优惠券</el-radio>
|
||||
</div>
|
||||
</section>
|
||||
<section class="creat_item flex">
|
||||
<div class="lable">
|
||||
使用门槛
|
||||
<span class="star">*</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-radio v-model="limitAmount" :label="0">无门槛使用</el-radio>
|
||||
<el-radio v-model="limitAmount" :label="1">
|
||||
<span>满</span>
|
||||
<input type="text" placeholder="输入金额" v-model="couponModel.AllowMinAmount" class="input_price" />
|
||||
<span>元使用</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
</section>
|
||||
<section class="creat_item flex">
|
||||
<div class="lable">
|
||||
优惠内容
|
||||
<span class="star">*</span>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="couponModel.CouponType==1">
|
||||
减
|
||||
<input type="text" v-model="couponModel.CouponValue" placeholder="请输入优惠券金额" />元
|
||||
</div>
|
||||
<div class="discount-box" v-else >
|
||||
打
|
||||
<input type="text" v-model="couponModel.CouponValue" />折
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="creat_item flex">
|
||||
<label for="count" class="lable">
|
||||
发行量
|
||||
<span class="star">*</span>
|
||||
</label>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
v-model="couponModel.TotalCount"
|
||||
autocomplete="off"
|
||||
placeholder="最多多少张张"
|
||||
/>张
|
||||
<br />
|
||||
<div class="grayTip">优惠券创建后,发行量只能增加不能减少,请谨慎设置</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="creat_item flex">
|
||||
<label for="range" class="lable">
|
||||
适用商品
|
||||
<span class="star">*</span>
|
||||
</label>
|
||||
<div>
|
||||
<el-radio v-model="couponModel.UseRange" :label="1">全部商品可用</el-radio>
|
||||
<el-radio v-model="couponModel.UseRange" :label="2">指定商品可用</el-radio>
|
||||
<div v-if="couponModel.UseRange==2">
|
||||
<el-button type="primary" @click="$refs['productSelector'].show()">选择课程</el-button>
|
||||
<el-table
|
||||
:data="products"
|
||||
style="width: 100%;margin-bottom: 20px;"
|
||||
row-key="ResourceId"
|
||||
border
|
||||
>
|
||||
<el-table-column label="课程图片" width="180">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.ResourceImage" style="width:50px;height:25px;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ResourceName" label="课程名称" width="180"></el-table-column>
|
||||
<el-table-column prop="Price" label="价格"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-link type="primary" @click="remove(scope.row)">移除</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="choose_time creat_item">
|
||||
<div class="lable">
|
||||
使用时间
|
||||
<span class="star">*</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex">
|
||||
<el-radio v-model="couponModel.DateRule" :label="1">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="up-down-margin">
|
||||
<el-radio v-model="couponModel.DateRule" :label="2">
|
||||
<label for="time_way_two">领取当日起</label>
|
||||
<input type="text" v-model="couponModel.ValidDay" class="input_price" />
|
||||
<span>天内可用</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div>
|
||||
<el-radio v-model="couponModel.DateRule" :label="3">
|
||||
<label for="time_way_three">领取次日起</label>
|
||||
<input type="text" v-model="couponModel.ValidDay " class="input_price" />
|
||||
<span>天内可用</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="popuInfo use-way-box">
|
||||
<h2 class="title">领用规则</h2>
|
||||
<section class="creat_item flex">
|
||||
<div class="lable">
|
||||
领取次数限制
|
||||
<span class="star">*</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-radio v-model="isLimit" :label="0">不限次数</el-radio>
|
||||
<el-radio v-model="isLimit" :label="1">每人限领</el-radio>
|
||||
<el-input v-if="isLimit==1" v-model="couponModel.GetLimitCount"></el-input>
|
||||
</div>
|
||||
</section>
|
||||
<!-- <section class="creat_item">
|
||||
<label for="can_share" class="lable lable-top">分享设置</label>
|
||||
<el-checkbox v-model="checked">优惠券允许分享给好友领取</el-checkbox>
|
||||
</section>-->
|
||||
<section class="creat_item">
|
||||
<label for="can_use_activity" class="lable lable-top">活动叠加限制</label>
|
||||
<el-checkbox v-model="couponModel.IsOverlay" :true-label="1" :false-label="0">优惠券仅原价购买商品时可用,不可与其他营销活动叠加使用</el-checkbox>
|
||||
</section>
|
||||
<section class="creat_item activity-overlay">
|
||||
<label for="can_use_activity" class="lable lable-top">公开设置</label>
|
||||
<el-checkbox v-model="couponModel.IsOpen" :true-label="1" :false-label="0">用户可在商品详情页领取</el-checkbox>
|
||||
</section>
|
||||
</div>
|
||||
<el-button @click="add">保存</el-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
var that = null;
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLimit: 0,
|
||||
limitAmount:0,
|
||||
dateRange: [],
|
||||
couponModel: {
|
||||
CouponType: 1,
|
||||
DateRule: 1,
|
||||
UseRange:1
|
||||
},
|
||||
products: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
saoma: function() {}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
get() {
|
||||
this.$api.get("sells/v1/coupon/get").then(res => {
|
||||
if (res.Data) this.couponModel = res.Data;
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.couponModel.StartDate = this.dateRange[0];
|
||||
this.couponModel.EndDate = this.dateRange[1];
|
||||
this.couponModel.Resource = this.products;
|
||||
if (this.isLimit == 0) this.couponModel.LimitCount = -1;
|
||||
this.$api.post("sells/v1/coupon/Post", this.couponModel).then(res => {
|
||||
this.$router.push({ name: "coupon" });
|
||||
});
|
||||
},
|
||||
selectCourse(data) {
|
||||
var model = data.map(m => {
|
||||
return {
|
||||
ResourceId: m.Id,
|
||||
ResourceImage: m.Cover,
|
||||
ResourceName: m.Name,
|
||||
ResourceType: 1,
|
||||
Price: m.Price
|
||||
};
|
||||
});
|
||||
this.products.push(...model);
|
||||
},
|
||||
selectLive(data) {
|
||||
var model = data.map(m => {
|
||||
return {
|
||||
ResourceId: m.Id,
|
||||
ResourceImage: m.Cover,
|
||||
ResourceName: m.Name,
|
||||
ResourceType: 2,
|
||||
Price: m.Price
|
||||
};
|
||||
});
|
||||
this.products.push(...model);
|
||||
},
|
||||
selectPackage(data) {
|
||||
var model = data.map(m => {
|
||||
return {
|
||||
ResourceId: m.Id,
|
||||
ResourceImage: m.Cover,
|
||||
ResourceName: m.Name,
|
||||
ResourceType: 3,
|
||||
Price: m.Price
|
||||
};
|
||||
});
|
||||
this.products.push(...model);
|
||||
},
|
||||
remove(item) {
|
||||
var index = this.products.indexOf(item);
|
||||
this.products.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.couponbox {
|
||||
padding: 20px;
|
||||
}
|
||||
.creat_item {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
.lable {
|
||||
width: 200px;
|
||||
float: left;
|
||||
}
|
||||
.star {
|
||||
color: red;
|
||||
font-size: 20px;
|
||||
}
|
||||
input {
|
||||
padding-left: 5px;
|
||||
width: 240px;
|
||||
height: 36px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #eee;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.grayTip {
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
text-align: left;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
97
src/components/sell/couponused.vue
Normal file
97
src/components/sell/couponused.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="heior_box">
|
||||
{{couponName}}
|
||||
<div class="search-box"></div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="CreateTime" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="OrderNo" label="订单号" width="215"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户" width="120"></el-table-column>
|
||||
<el-table-column prop="ProductName" label="产品"></el-table-column>
|
||||
<el-table-column prop="PackageName" label="套餐"></el-table-column>
|
||||
<el-table-column prop="Accounts" label="账号">
|
||||
<template slot-scope="scope">
|
||||
<cutTip :text="scope.row.Accounts"></cutTip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OrderAmount" label="订单金额"></el-table-column>
|
||||
<el-table-column prop="CouponAmount" label="优惠金额"></el-table-column>
|
||||
<!-- <el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="Free(scope.row)">冻结</span>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
var that = null;
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
couponName:'',
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
CouponId: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "优惠券明细");
|
||||
var couponId=this.$route.query.couponId;
|
||||
this.couponName=this.$route.query.couponName;
|
||||
this.get(couponId);
|
||||
},
|
||||
methods: {
|
||||
get(couponId) {
|
||||
if (Number.isInteger(couponId)) {
|
||||
this.searchModel.CouponId = couponId;
|
||||
}
|
||||
this.$api
|
||||
.get("course/v1/order/CouponOrders", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.xeBtnDefault {
|
||||
outline: medium;
|
||||
color: #666;
|
||||
background: #fafbfc;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.btnMid {
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
.el-radio {
|
||||
padding: 5px 0;
|
||||
}
|
||||
</style>
|
||||
13
src/components/setting/editrole.vue
Normal file
13
src/components/setting/editrole.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>role</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "managers",
|
||||
props: {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
1042
src/components/setting/managerDetail.vue
Normal file
1042
src/components/setting/managerDetail.vue
Normal file
File diff suppressed because it is too large
Load Diff
413
src/components/setting/managerlist.vue
Normal file
413
src/components/setting/managerlist.vue
Normal file
@@ -0,0 +1,413 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="heior_box">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
v-href="'/user/addmanager'"
|
||||
>添加子管理员</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="manageData.KeyWord" placeholder="用户名/姓名/联系方式" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="getmanagerlist(1)"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<el-table :data="manegeList" size="medium" :height="$getHeight(100)" row-key="Id" border>
|
||||
<el-table-column prop="LoginCode" label="账号"></el-table-column>
|
||||
<el-table-column prop="RealName" label="姓名"></el-table-column>
|
||||
<el-table-column prop="Phone" label="联系方式"></el-table-column>
|
||||
<el-table-column prop="CreateTime" label="添加时间"></el-table-column>
|
||||
<el-table-column prop="CreateTime" label="是否客户经理">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.roleid==100?"是":"否"}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="setUser(scope.row)">分配用户</span>
|
||||
<span class="handel cursor edit" @click="routerGo(scope.row)">编辑</span>
|
||||
<span class="handel cursor del" @click="delmanagerData.ID=scope.row.Id;delmanager()">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="manegeList.length>0"
|
||||
@current-change="getmanagerlist"
|
||||
:page-size="50"
|
||||
:current-page.sync="manageData.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="manegeTotal"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-dialog title="选中用户" :visible.sync="showUserDialog" width="770px" v-loading="userLoading">
|
||||
<div class="search-box">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="doSetUser()">分配用户</el-button>
|
||||
<el-switch
|
||||
active-value="1"
|
||||
inactive-value="0"
|
||||
v-model="searchUserModel.all"
|
||||
active-text="全部用户">
|
||||
</el-switch>
|
||||
<el-input placeholder="输入关键字进行过滤" size="small" v-model="searchUserModel.keyWord">
|
||||
<el-button slot="append" icon="el-icon-search" @click="getUser"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-table :data="userRet.Data" row-key="Id" border size="medium" height="650px"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="55">
|
||||
</el-table-column>
|
||||
<el-table-column prop="LoginCode" label="账号" ></el-table-column>
|
||||
<el-table-column prop="CreateTime" label="注册时间"> </el-table-column>
|
||||
<el-table-column prop="Name" label="名称"></el-table-column>
|
||||
<el-table-column prop="ManagerName" label="客户经理"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="userRet.Data.length>0"
|
||||
@current-change="getUser"
|
||||
:page-size="500"
|
||||
:current-page.sync="searchUserModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="userRet.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userLoading:false,
|
||||
showUserDialog:false,
|
||||
allowAdd: true,
|
||||
loading: false,
|
||||
userdata: {}, //当前登录人信息
|
||||
manegeList: [],
|
||||
manageData: {
|
||||
PageIndex: 1,
|
||||
PageSize: 50,
|
||||
TenantId: 0,
|
||||
KeyWord: "",
|
||||
RoleId: 0,
|
||||
CurrentRoleId: 0,
|
||||
IsRoot: 0
|
||||
},
|
||||
manegeTotal: 0,
|
||||
checkEstate: false, //当前是否查看项目
|
||||
delroleData: {
|
||||
//删除角色
|
||||
ID: "",
|
||||
OwnerID: 1001,
|
||||
OperaterID: 1,
|
||||
ProjectCode: ""
|
||||
},
|
||||
delmanagerData: {
|
||||
//删除管理员
|
||||
ID: "",
|
||||
OwnerID: 1001,
|
||||
OperaterID: 1,
|
||||
ProjectCode: ""
|
||||
},
|
||||
stateData: {
|
||||
//更新关联项目
|
||||
Managerid: 1,
|
||||
Projectcodes: []
|
||||
},
|
||||
bindwx: false,
|
||||
estateSelected: {
|
||||
SelectedCodes: [],
|
||||
SelectedNames: []
|
||||
},
|
||||
searchUserModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
PageSize:500,
|
||||
all:0
|
||||
},
|
||||
userRet:{
|
||||
TotalCount:0,
|
||||
Data:[]
|
||||
},
|
||||
currentManager:null,
|
||||
multipleSelection:null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
bindwx: function() {
|
||||
if (!this.bindwx) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav","会员管理>>管理员")
|
||||
this.userdata = JSON.parse(
|
||||
window.localStorage.getItem("etorcurrentuser")
|
||||
).Manager;
|
||||
this.getmanagerlist();
|
||||
this.getUser();
|
||||
},
|
||||
methods: {
|
||||
handleSelectionChange(val){
|
||||
this.multipleSelection = val;
|
||||
console.log(val)
|
||||
},
|
||||
setUser(manage){
|
||||
this.showUserDialog=true;
|
||||
this.currentManager=manage;
|
||||
},
|
||||
getUser() {
|
||||
this.$api.get("baseinfo/v1/user/Search",this.searchUserModel).then(res => {
|
||||
this.userRet=res;
|
||||
})
|
||||
},
|
||||
doSetUser() {
|
||||
var data={
|
||||
ManagerId:this.currentManager.Id,
|
||||
ManagerName:this.currentManager.RealName,
|
||||
UserIds:this.multipleSelection.map(m=>m.Id)
|
||||
};
|
||||
this.$api.post("baseinfo/v1/user/SetManager",data).then(res => {
|
||||
this.getUser();
|
||||
this.showUserDialog=false;
|
||||
})
|
||||
},
|
||||
geturl(data) {
|
||||
var that = this;
|
||||
var id = data.Id;
|
||||
var uuid = that.getguid();
|
||||
var url =
|
||||
this.$api.baseURL +
|
||||
"Manager/ManageBindWx?data.Id=" +
|
||||
id +
|
||||
"&data.uuid=" +
|
||||
uuid;
|
||||
this.bindwx = true;
|
||||
this.makeqrcode(url);
|
||||
that.timer = setInterval(function() {
|
||||
that.time(uuid, that.timer);
|
||||
}, 1000);
|
||||
},
|
||||
// 获取uuid
|
||||
getguid() {
|
||||
return "xxxx-xxxx-4xxx-yxxx-xxxx".replace(/[xy]/g, function(c) {
|
||||
var r = (Math.random() * 16) | 0,
|
||||
v = c == "x" ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
},
|
||||
time(data, time) {
|
||||
this.$api
|
||||
.getscanbindwxstate(data)
|
||||
.then(res => {
|
||||
console.log(res);
|
||||
if (res.Data.State == 0) {
|
||||
clearInterval(time);
|
||||
this.getmanagerlist(this.manageData.PageIndex);
|
||||
this.bindwx = false;
|
||||
}
|
||||
})
|
||||
.catch(res => {
|
||||
clearInterval(time);
|
||||
});
|
||||
},
|
||||
makeqrcode(url) {
|
||||
document.getElementById("qrcode").innerHTML = "";
|
||||
new QRCode(document.getElementById("qrcode"), {
|
||||
text: url,
|
||||
width: 127,
|
||||
height: 127,
|
||||
colorDark: "#000000",
|
||||
colorLight: "#ffffff",
|
||||
correctLevel: QRCode.CorrectLevel.H
|
||||
});
|
||||
},
|
||||
getmanagerlist(val) {
|
||||
//获取管理员列表
|
||||
var that = this;
|
||||
this.loading = true;
|
||||
typeof val === "number" && (this.manageData.PageIndex = val);
|
||||
var roleid = this.userdata.Roleid;
|
||||
this.manageData.CurrentRoleId = roleid;
|
||||
this.manageData.IsRoot = 1;
|
||||
this.$api
|
||||
.get("manage/v1/Manager/Get", this.manageData)
|
||||
.then(res => {
|
||||
if (res.Code == 10000) {
|
||||
this.manegeTotal = res.TotalCount;
|
||||
this.manegeList = res.Data;
|
||||
console.log(this.manegeList);
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.Message
|
||||
});
|
||||
}
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(res => {
|
||||
//console.log(res);
|
||||
});
|
||||
},
|
||||
putManagerdatadomain(e) {
|
||||
//更改某管理员关联项目列表
|
||||
this.stateData.Projectcodes = e.SelectedCodes;
|
||||
//console.log(e);
|
||||
this.$api
|
||||
.putManagerdatadomain(this.stateData)
|
||||
.then(res => {
|
||||
if (res.Code == 10000) {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "修改关联项目成功!"
|
||||
});
|
||||
this.getmanagerlist();
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.Message
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(res => {
|
||||
//console.log(res);
|
||||
});
|
||||
},
|
||||
getManagerdatadomain(id) {
|
||||
//获取管理员管理的楼宇编码
|
||||
if (this.checkEstate) {
|
||||
this.checkEstate = !this.checkEstate;
|
||||
}
|
||||
this.$api
|
||||
.getManagerdatadomain({ ID: id })
|
||||
.then(res => {
|
||||
if (res.Code == 10000) {
|
||||
this.stateData.Managerid = res.Data.Managerid;
|
||||
this.estateSelected.SelectedCodes = res.Data.Projectcodes;
|
||||
this.checkEstate = true;
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.Message
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(res => {
|
||||
//console.log(res);
|
||||
});
|
||||
},
|
||||
|
||||
delmanager() {
|
||||
//删除管理员
|
||||
this.$confirm("确认删除该管理员吗?", "删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$api
|
||||
.delmanager(this.delmanagerData)
|
||||
.then(res => {
|
||||
if (res.Code == 10000) {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "删除成功"
|
||||
});
|
||||
this.getmanagerlist(1);
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: res.Message
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(res => {
|
||||
//console.log(res);
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: "info",
|
||||
message: "已取消删除"
|
||||
});
|
||||
});
|
||||
},
|
||||
routerGo(item) {
|
||||
this.$router.push({
|
||||
name: "addmanager",
|
||||
query: {
|
||||
ID: item.Id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.basicsetting {
|
||||
height: 100%;
|
||||
.el-dialog {
|
||||
.manager {
|
||||
height: 210px;
|
||||
p {
|
||||
width: 165px;
|
||||
}
|
||||
.do img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
float: none;
|
||||
margin-left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
/deep/ .el-dialog__footer {
|
||||
height: 57px;
|
||||
line-height: 57px;
|
||||
p {
|
||||
color: #2e2f33;
|
||||
line-height: 57px;
|
||||
text-align: left;
|
||||
text-indent: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.blackList {
|
||||
color: red;
|
||||
border: 1px solid red;
|
||||
}
|
||||
}
|
||||
#qrcode {
|
||||
margin-left: calc(~"50% - 63.5px");
|
||||
}
|
||||
|
||||
.dialog_box {
|
||||
width: 440px;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.dialog_content {
|
||||
height: auto;
|
||||
padding-bottom: 20px;
|
||||
min-height: 95px;
|
||||
}
|
||||
|
||||
.look {
|
||||
color: #4c82ff;
|
||||
}
|
||||
|
||||
.textm {
|
||||
padding-left: 26px;
|
||||
font-size: 14px;
|
||||
color: #8f8f8f;
|
||||
}
|
||||
</style>
|
||||
|
||||
13
src/components/setting/managers.vue
Normal file
13
src/components/setting/managers.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>manager</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "managers",
|
||||
props: {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
13
src/components/setting/roles.vue
Normal file
13
src/components/setting/roles.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>roles</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "managers",
|
||||
props: {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
52
src/components/test.vue
Normal file
52
src/components/test.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
<template>
|
||||
<page>
|
||||
<hheader></hheader>
|
||||
<left></left>
|
||||
<div class="base_right editbase_right">
|
||||
<router-view class="page_main"></router-view>
|
||||
</div>
|
||||
</page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
left: () => import('./common/layout/left.vue'),
|
||||
hheader: () => import('./common/layout/header.vue'),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
mydata:{
|
||||
name:'ff',
|
||||
list:[1],
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
saoma: function() {}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
pp(){
|
||||
this.mydata.list.push(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.base_right {
|
||||
margin-left: 180px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background: #f5f7fa;
|
||||
transition: padding ease .3s;
|
||||
} body.help_doc_unfolding .base_right {
|
||||
padding-right: 224px;
|
||||
}.editbase_right {
|
||||
padding-top: 56px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
132
src/components/user/add.vue
Normal file
132
src/components/user/add.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<div class="main_box screen1" v-loading="loading">
|
||||
<el-breadcrumb separator-class="el-icon-arrow-right" class="ml40 xw995">
|
||||
<el-breadcrumb-item>资讯管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{name:'course'}">资讯列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>新建课程</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<el-form :model="articleModel" :rules="rules" ref="editor" class="from_box clr">
|
||||
<el-form-item prop="Title" class="from_item">
|
||||
<label>标题</label>
|
||||
<img src="/static/img/common/main.png">
|
||||
<el-input placeholder="请填标题" v-model="articleModel.Title"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="SubTitle" class="from_item">
|
||||
<label>副标题</label>
|
||||
<img src="/static/img/common/main.png">
|
||||
<el-input placeholder="请填副标题" v-model="articleModel.SubTitle"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Keyword" class="from_item">
|
||||
<label class="noimh">关键字</label>
|
||||
<el-input v-model="articleModel.Keyword" type="number"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="AccessCount" class="from_item">
|
||||
<label>访问人数:</label>
|
||||
<img src="/static/img/common/main.png">
|
||||
<el-input placeholder="请填访问人数::" v-model="articleModel.AccessCount" type="number"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="OnLine" class="from_item">
|
||||
<label>发布状态:</label>
|
||||
<img src="/static/img/common/main.png">
|
||||
<div>
|
||||
<el-switch v-model="articleModel.Publish" :active-value="1" :inactive-value="0"> </el-switch>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form :inline="true">
|
||||
<el-form-item prop="Thumb" class="from_item">
|
||||
<label>课程封面:</label>
|
||||
<div class="uploadimg_box ">
|
||||
<img :src="articleModel.Thumb" v-if="articleModel.Thumb!=''" class="uploadimg" @click="upload(setCover)" />
|
||||
<span class="ubloadbtn" v-else>
|
||||
<img src="/static/img/common/imgadd.png" @click="upload(setCover)" >
|
||||
</span>
|
||||
<p class="imgTip" @click="upload(setCover)" >点击更换</p>
|
||||
<p class="zhu">注:图片大小不可超过2M
|
||||
</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
<div class="editor-container">
|
||||
<UE v-model="articleModel.Content" :config='config' ref="ue"></UE>
|
||||
</div>
|
||||
<div class="handel_box clr">
|
||||
<router-link :to="{name:'course'}" tag="input" type="button" value="返回" class="cursor"></router-link>
|
||||
|
||||
<input type="button" value="保存" @click="save('editor')" class="small cursor">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
let that;
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
articleModel:{
|
||||
Publish:0,
|
||||
id:0,
|
||||
Thumb:'',
|
||||
},
|
||||
loading: false,
|
||||
rules: {
|
||||
Title: [this.$vaild.required("标题")],
|
||||
SubTitle: [this.$vaild.required("副标题")],
|
||||
// Banner: [this.$vaild.required("课程主图")],
|
||||
// Cover: [this.$vaild.required("课程封面")],
|
||||
},
|
||||
config:{
|
||||
serverUrl:this.$api.baseURL+"ueditor",
|
||||
UEDITOR_HOME_URL: "/static/ueditor/",
|
||||
autoHeightEnabled: false,
|
||||
initialFrameHeight: 500,
|
||||
},
|
||||
options:[]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
var query=this.$route.query;
|
||||
if(query.optype==2){
|
||||
this.getInfo(query.id);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getInfo(id){
|
||||
this.$api.get("course/v1/article/Get",{id:id}).then(res=>{this.articleModel=res.Data});
|
||||
},
|
||||
save(formName) {
|
||||
var that = this;
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
if (that.$route.query.optype=="1") {
|
||||
that.add();
|
||||
} else if(that.$route.query.optype=="2") {
|
||||
that.edit();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
add(){
|
||||
this.$api.post("course/v1/article/post",this.articleModel).then(res=>{
|
||||
this.$router.push({name:"course"})
|
||||
})
|
||||
},
|
||||
edit(){
|
||||
this.$api.post("course/v1/article/put",this.articleModel).then(res=>{
|
||||
this.$router.push({name:"article"})
|
||||
})
|
||||
},
|
||||
upload(callback) {
|
||||
this.$api.upload('oss/v1/ImageCloud/upload').then(res=>{
|
||||
callback&&callback(res.Data);
|
||||
});
|
||||
},
|
||||
setCover(ret) {
|
||||
this.articleModel.Thumb=ret.Url;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
90
src/components/user/amountdetails.vue
Normal file
90
src/components/user/amountdetails.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入会员号/名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" size="medium" :height="$getHeight(300)" row-key="Id" border>
|
||||
<el-table-column prop="CreateTime" label="日期"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserName"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OperateUserName" label="操作人员"></el-table-column>
|
||||
<el-table-column prop="ScoreTypeName" label="资金项目"></el-table-column>
|
||||
<el-table-column prop="RestAmount1" label="操做前余额"></el-table-column>
|
||||
<el-table-column prop="ScoreValue" label="金额"></el-table-column>
|
||||
<el-table-column prop="RestAmount2" label="操做后余额"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="getAmountDetail"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "userIndex",
|
||||
components: {
|
||||
cutTip: () => import("@/components/common/cutTip"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
detailAmountData: [],
|
||||
formatterCreateType(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "管理员添加";
|
||||
case 2:
|
||||
return "用户注册";
|
||||
case 3:
|
||||
return "淘宝注册";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "订单管理>>资金明细");
|
||||
this.getAmountDetail();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.getAmountDetail();
|
||||
},
|
||||
getAmountDetail() {
|
||||
this.loading = true;
|
||||
this.$api
|
||||
.get("baseinfo/v1/user/AmountDetails", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/baseinfo/v1/user/ExportAmount", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
99
src/components/user/chargeorder.vue
Normal file
99
src/components/user/chargeorder.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-sold-out"
|
||||
@click="dataExport"
|
||||
v-if="$local.isRoot()"
|
||||
>导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
<el-input
|
||||
v-model="searchModel.keyWord"
|
||||
placeholder="请输入订单号、用户名"
|
||||
clearable
|
||||
size="small"
|
||||
>
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" row-key="Id" border size="medium" :height="$getHeight(100)">
|
||||
<el-table-column prop="CreateTime" label="创建日期" width="180"></el-table-column>
|
||||
<el-table-column prop="OrderNo" label="订单号" ></el-table-column>
|
||||
<el-table-column prop="TradeNo" label="支付流水号"></el-table-column>
|
||||
<el-table-column prop="UserName" label="用户" width="120">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserName"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OrderAmount" label="充值金额" width="180"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
:page-size="50"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {
|
||||
cutTip: () => import("@/components/common/cutTip"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
options: [],
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
dateRange: [],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
Btime: "",
|
||||
Etime: "",
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "订单管理>>充值订单");
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.searchModel.PageIndex = 1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
if (this.dateRange && this.dateRange.length == 2) {
|
||||
this.searchModel.Btime = this.dateRange[0];
|
||||
this.searchModel.Etime = this.dateRange[1];
|
||||
}
|
||||
this.$api.get("baseinfo/v1/chargeorder/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
dataExport() {
|
||||
this.$api.getDownloadFile("/baseinfo/v1/chargeorder/ExportOrder", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
314
src/components/user/index.vue
Normal file
314
src/components/user/index.vue
Normal file
@@ -0,0 +1,314 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="add">添加会员</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入会员号/名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" size="medium" :height="$getHeight(100)" row-key="Id" border>
|
||||
<!-- <el-table-column prop="LoginCode" label="会员号" width="120px"></el-table-column> -->
|
||||
<!-- <el-table-column prop="Name" label="名称"></el-table-column> -->
|
||||
<el-table-column prop="LoginCode" label="会员号" width="120px">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.LoginCode"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CreateTime" label="注册时间" width="160px"></el-table-column>
|
||||
<el-table-column prop="CreateType" label="注册方式" :formatter="formatterCreateType"></el-table-column>
|
||||
<!-- <el-table-column prop="ProductAccountCount" label="账号总数"></el-table-column>
|
||||
<el-table-column prop="ExpiredProductAccountCount" label="过期数"></el-table-column>
|
||||
<el-table-column prop="ExpiredProductAccountCount" label="未过期数"></el-table-column>-->
|
||||
<!-- <el-table-column prop="ConsumeAmount" label="消费总额"></el-table-column> -->
|
||||
<el-table-column prop="RestAmount" label="余额"></el-table-column>
|
||||
<el-table-column prop="RestAmount" label="测试限额/领用数">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.TestCountLimit==0?'3':scope.row.TestCountLimit}}/{{scope.row.UseTestCount==0?'--':scope.row.UseTestCount}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ManagerName" label="客户经理"></el-table-column>
|
||||
<el-table-column label="操作" width="400px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="showUpdateTest(scope.row)">设置测试</span>
|
||||
<span class="handel cursor edit" @click="showAmount(scope.row,1)" v-if="IsRoot">充值</span>
|
||||
<span class="handel cursor edit" @click="showAmount(scope.row,2)">扣款</span>
|
||||
<router-link :to="{name:'account',query:{userId:scope.row.Id}}">
|
||||
<span class="handel cursor edit">账号</span>
|
||||
</router-link>
|
||||
<router-link :to="{name:'userprice',query:{id:scope.row.Id}}">
|
||||
<span class="handel cursor edit">会员价</span>
|
||||
</router-link>
|
||||
<span class="handel cursor edit" @click="edit(scope.row)">编辑</span>
|
||||
<span class="handel cursor edit" @click="showAmountDetail(scope.row)">明细</span>
|
||||
<el-popover placement="bottom" trigger="hover" width="180">
|
||||
<div class="popover_box">
|
||||
<span>QQ号:{{scope.row.QQ||'--'}}</span>
|
||||
<span>微信:{{scope.row.Wx||'--'}}</span>
|
||||
<span>淘宝:{{scope.row.TaoBao||'--'}}</span>
|
||||
<span>邮箱:{{scope.row.Email||'--'}}</span>
|
||||
</div>
|
||||
<span class="handel cursor more" slot="reference">更多</span>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog title="会员维护" :visible.sync="showDialog" width="400px">
|
||||
<el-form :model="userModel" :rules="rules" ref="inputUserForm" label-width="80px">
|
||||
<el-form-item prop="LoginCode" label="登录名称">
|
||||
<el-input v-model="userModel.LoginCode" :disabled="optype==2" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Password" label="密码">
|
||||
<el-input v-model="userModel.Password" show-password size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Phone" label="手机号">
|
||||
<el-input v-model="userModel.Phone" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="QQ" label="QQ号">
|
||||
<el-input v-model="userModel.QQ" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Wx" label="微信">
|
||||
<el-input v-model="userModel.Wx" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="TaoBao" label="淘宝">
|
||||
<el-input v-model="userModel.TaoBao" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Email" label="邮箱">
|
||||
<el-input v-model="userModel.Email" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Remark" label="备注">
|
||||
<el-input v-model="userModel.Remark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputUserForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="save('inputUserForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:title="amountModel.opAmountType==1?'充值':'扣费'"
|
||||
:visible.sync="amountModel.showAmountDialog"
|
||||
width="300px"
|
||||
>
|
||||
<el-form :model="amountModel" :rules="amountRules" ref="inputAmountForm" label-width="80px">
|
||||
<el-form-item prop="rest" label="当前余额">
|
||||
<el-input v-model="amountModel.rest" size="small" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="amount" :label="amountModel.opAmountType==1?'充值金额':'扣费金额'">
|
||||
<el-input v-model="amountModel.amount" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="attchInfo" label="备注">
|
||||
<el-input v-model="amountModel.attchInfo" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputAmountForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="updateAmount('inputAmountForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="测试限额设置" :visible.sync="showTestDialog" width="300px">
|
||||
<el-form :model="testLimitModel" ref="inputTestForm" label-width="80px">
|
||||
<el-form-item prop="limit" label="限制次数">
|
||||
<el-input v-model="testLimitModel.limit" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputTestForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="updateTestLimit()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="资金明细" :visible.sync="showDetailDialog" width="500px">
|
||||
<el-table
|
||||
:data="detailAmountData"
|
||||
size="medium"
|
||||
:height="$getHeight(300)"
|
||||
row-key="Id"
|
||||
border
|
||||
>
|
||||
<el-table-column prop="ScoreTypeName" label="资金项目"></el-table-column>
|
||||
<el-table-column prop="ScoreValue" label="金额"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "userIndex",
|
||||
components: {
|
||||
cutTip: () => import("@/components/common/cutTip"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isRoot:false,
|
||||
loading: false,
|
||||
showDialog: false,
|
||||
showTestDialog: false,
|
||||
showDetailDialog: false,
|
||||
optype: 1, //1:添加 2:编辑
|
||||
userModel: {
|
||||
LoginCode: "",
|
||||
Phone: "",
|
||||
Password: "",
|
||||
Remark: ""
|
||||
},
|
||||
amountModel: {
|
||||
rest: 0,
|
||||
amount: 0,
|
||||
opAmountType: 1, ////1:充值 2:扣款
|
||||
showAmountDialog: false,
|
||||
attchInfo:''
|
||||
},
|
||||
testLimitModel: {
|
||||
userId: 0,
|
||||
limit: 3
|
||||
},
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
rules: {
|
||||
LoginCode: [this.$vaild.required("登录名称")],
|
||||
Phone: [this.$vaild.required("手机号")],
|
||||
// Password: [this.$vaild.required("密码")]
|
||||
},
|
||||
amountRules: {
|
||||
// amount: [{ type: 'number', message: '金额必须为数字值'}],
|
||||
},
|
||||
detailAmountData: [],
|
||||
formatterCreateType(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "管理员添加";
|
||||
case 2:
|
||||
return "用户注册";
|
||||
case 3:
|
||||
return "淘宝注册";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "用户管理>>会员管理");
|
||||
var currentUser=this.$local.getUserByCache();
|
||||
this.IsRoot=currentUser.Manager.IsRootUser;
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api.get("baseinfo/v1/user/page", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api.post("baseinfo/v1/user/Delete?id=" + item.Id).then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.showDialog = true;
|
||||
this.optype = 1;
|
||||
},
|
||||
edit(item) {
|
||||
this.showDialog = true;
|
||||
this.optype = 2;
|
||||
this.userModel = clone(item);
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.showDialog = false;
|
||||
this.amountModel.showAmountDialog = false;
|
||||
this.showTestDialog = false;
|
||||
},
|
||||
save(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (!valid) return;
|
||||
if (this.optype == 1) {
|
||||
this.$api.post("baseinfo/v1/user/post", this.userModel).then(res => {
|
||||
this.resetForm("inputUserForm");
|
||||
this.get();
|
||||
});
|
||||
} else {
|
||||
this.$api.post("baseinfo/v1/user/put", this.userModel).then(res => {
|
||||
this.resetForm("inputUserForm");
|
||||
this.get();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
showAmount(item, type) {
|
||||
this.amountModel.rest = item.RestAmount;
|
||||
this.amountModel.opAmountType = type;
|
||||
this.amountModel.showAmountDialog = true;
|
||||
this.amountModel.UserId = item.Id;
|
||||
},
|
||||
updateAmount(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (!valid) return;
|
||||
this.$api
|
||||
.post("baseinfo/v1/user/UpdateAmount", this.amountModel)
|
||||
.then(res => {
|
||||
this.resetForm("inputAmountForm");
|
||||
this.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
showUpdateTest(item) {
|
||||
this.showTestDialog = true;
|
||||
this.testLimitModel.UserId = item.Id;
|
||||
this.testLimitModel.limit = item.TestCountLimit;
|
||||
},
|
||||
updateTestLimit() {
|
||||
this.$api
|
||||
.post("baseinfo/v1/user/UpdateTestCount", this.testLimitModel)
|
||||
.then(res => {
|
||||
this.resetForm("inputTestForm");
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
showAmountDetail(item) {
|
||||
this.showDetailDialog = true;
|
||||
this.$api
|
||||
.get("baseinfo/v1/user/AmountDetail?userId=" + item.Id)
|
||||
.then(res => {
|
||||
this.detailAmountData = res.Data;
|
||||
});
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/baseinfo/v1/user/Export");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
302
src/components/user/search.vue
Normal file
302
src/components/user/search.vue
Normal file
@@ -0,0 +1,302 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="add">添加会员</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入会员号/名称" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" size="medium" :height="$getHeight(100)" row-key="Id" border>
|
||||
<el-table-column prop="LoginCode" label="会员号" width="120px">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.LoginCode"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CreateTime" label="注册时间" width="160px"></el-table-column>
|
||||
<el-table-column prop="CreateType" label="注册方式" :formatter="formatterCreateType"></el-table-column>
|
||||
<el-table-column prop="RestAmount" label="余额"></el-table-column>
|
||||
<el-table-column prop="RestAmount" label="测试限额/领用数">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.TestCountLimit==0?'3':scope.row.TestCountLimit}}/{{scope.row.UseTestCount==0?'--':scope.row.UseTestCount}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="400px">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="showUpdateTest(scope.row)">设置测试</span>
|
||||
<router-link :to="{name:'account',query:{userId:scope.row.Id}}">
|
||||
<span class="handel cursor edit">账号</span>
|
||||
</router-link>
|
||||
<router-link :to="{name:'userprice',query:{id:scope.row.Id}}">
|
||||
<span class="handel cursor edit">会员价</span>
|
||||
</router-link>
|
||||
<span class="handel cursor edit" @click="edit(scope.row)">编辑</span>
|
||||
<span class="handel cursor edit" @click="showAmountDetail(scope.row)">明细</span>
|
||||
<el-popover placement="bottom" trigger="hover" width="180">
|
||||
<div class="popover_box">
|
||||
<span>QQ号:{{scope.row.QQ||'--'}}</span>
|
||||
<span>微信:{{scope.row.Wx||'--'}}</span>
|
||||
<span>淘宝:{{scope.row.TaoBao||'--'}}</span>
|
||||
<span>邮箱:{{scope.row.Email||'--'}}</span>
|
||||
</div>
|
||||
<span class="handel cursor more" slot="reference">更多</span>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog title="会员维护" :visible.sync="showDialog" width="400px">
|
||||
<el-form :model="userModel" :rules="rules" ref="inputUserForm" label-width="80px">
|
||||
<el-form-item prop="LoginCode" label="登录名称">
|
||||
<el-input v-model="userModel.LoginCode" :disabled="optype==2" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Password" label="密码">
|
||||
<el-input v-model="userModel.Password" show-password size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Phone" label="手机号">
|
||||
<el-input v-model="userModel.Phone" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="QQ" label="QQ号">
|
||||
<el-input v-model="userModel.QQ" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Wx" label="微信">
|
||||
<el-input v-model="userModel.Wx" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="TaoBao" label="淘宝">
|
||||
<el-input v-model="userModel.TaoBao" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Email" label="邮箱">
|
||||
<el-input v-model="userModel.Email" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Remark" label="备注">
|
||||
<el-input v-model="userModel.Remark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputUserForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="save('inputUserForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:title="amountModel.opAmountType==1?'充值':'扣费'"
|
||||
:visible.sync="amountModel.showAmountDialog"
|
||||
width="300px"
|
||||
>
|
||||
<el-form :model="amountModel" :rules="amountRules" ref="inputAmountForm" label-width="80px">
|
||||
<el-form-item prop="rest" label="当前余额">
|
||||
<el-input v-model="amountModel.rest" size="small" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="amount" :label="amountModel.opAmountType==1?'充值金额':'扣费金额'">
|
||||
<el-input v-model="amountModel.amount" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputAmountForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="updateAmount('inputAmountForm')">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="测试限额设置" :visible.sync="showTestDialog" width="300px">
|
||||
<el-form :model="testLimitModel" ref="inputTestForm" label-width="80px">
|
||||
<el-form-item prop="limit" label="限制次数">
|
||||
<el-input v-model="testLimitModel.limit" size="small" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm('inputTestForm')">取 消</el-button>
|
||||
<el-button type="primary" @click="updateTestLimit()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="资金明细" :visible.sync="showDetailDialog" width="500px">
|
||||
<el-table
|
||||
:data="detailAmountData"
|
||||
size="medium"
|
||||
:height="$getHeight(300)"
|
||||
row-key="Id"
|
||||
border
|
||||
>
|
||||
<el-table-column prop="ScoreTypeName" label="资金项目"></el-table-column>
|
||||
<el-table-column prop="ScoreValue" label="金额"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "userIndex",
|
||||
components: {
|
||||
cutTip: () => import("@/components/common/cutTip"),
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isRoot:false,
|
||||
loading: false,
|
||||
showDialog: false,
|
||||
showTestDialog: false,
|
||||
showDetailDialog: false,
|
||||
optype: 1, //1:添加 2:编辑
|
||||
userModel: {
|
||||
LoginCode: "",
|
||||
Phone: "",
|
||||
Password: "",
|
||||
Remark: ""
|
||||
},
|
||||
amountModel: {
|
||||
rest: 0,
|
||||
amount: 0,
|
||||
opAmountType: 1, ////1:充值 2:扣款
|
||||
showAmountDialog: false
|
||||
},
|
||||
testLimitModel: {
|
||||
userId: 0,
|
||||
limit: 3
|
||||
},
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
rules: {
|
||||
LoginCode: [this.$vaild.required("登录名称")],
|
||||
Phone: [this.$vaild.required("手机号")],
|
||||
Password: [this.$vaild.required("密码")]
|
||||
},
|
||||
amountRules: {
|
||||
// amount: [{ type: 'number', message: '金额必须为数字值'}],
|
||||
},
|
||||
detailAmountData: [],
|
||||
formatterCreateType(row, column, cellValue, index) {
|
||||
switch (cellValue) {
|
||||
case 1:
|
||||
return "管理员添加";
|
||||
case 2:
|
||||
return "用户注册";
|
||||
case 3:
|
||||
return "淘宝注册";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "用户管理>>用户查询");
|
||||
var currentUser=this.$local.getUserByCache();
|
||||
this.IsRoot=currentUser.Manager.IsRootUser;
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
if(this.searchModel.keyWord==''){
|
||||
this.$warn("请输入查询关键字");
|
||||
return;
|
||||
}
|
||||
this.searchModel.PageIndex=1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.$api.get("baseinfo/v1/user/SearchInfo", this.searchModel).then(res => {
|
||||
this.retData = res;
|
||||
});
|
||||
},
|
||||
del(item) {
|
||||
var that = this;
|
||||
this.$confirm("确定删除?", "", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(_ => {
|
||||
this.$api.post("baseinfo/v1/user/Delete?id=" + item.Id).then(res => {
|
||||
that.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.showDialog = true;
|
||||
this.optype = 1;
|
||||
},
|
||||
edit(item) {
|
||||
this.showDialog = true;
|
||||
this.optype = 2;
|
||||
this.userModel = clone(item);
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.showDialog = false;
|
||||
this.amountModel.showAmountDialog = false;
|
||||
this.showTestDialog = false;
|
||||
},
|
||||
save(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (!valid) return;
|
||||
if (this.optype == 1) {
|
||||
this.$api.post("baseinfo/v1/user/post", this.userModel).then(res => {
|
||||
this.resetForm("inputUserForm");
|
||||
// this.get();
|
||||
});
|
||||
} else {
|
||||
this.$api.post("baseinfo/v1/user/put", this.userModel).then(res => {
|
||||
this.resetForm("inputUserForm");
|
||||
// this.get();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
showAmount(item, type) {
|
||||
this.amountModel.rest = item.RestAmount;
|
||||
this.amountModel.opAmountType = type;
|
||||
this.amountModel.showAmountDialog = true;
|
||||
this.amountModel.UserId = item.Id;
|
||||
},
|
||||
updateAmount(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (!valid) return;
|
||||
this.$api
|
||||
.post("baseinfo/v1/user/UpdateAmount", this.amountModel)
|
||||
.then(res => {
|
||||
this.resetForm("inputAmountForm");
|
||||
this.get();
|
||||
});
|
||||
});
|
||||
},
|
||||
showUpdateTest(item) {
|
||||
this.showTestDialog = true;
|
||||
this.testLimitModel.UserId = item.Id;
|
||||
this.testLimitModel.limit = item.TestCountLimit;
|
||||
},
|
||||
updateTestLimit() {
|
||||
this.$api
|
||||
.post("baseinfo/v1/user/UpdateTestCount", this.testLimitModel)
|
||||
.then(res => {
|
||||
this.resetForm("inputTestForm");
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
showAmountDetail(item) {
|
||||
this.showDetailDialog = true;
|
||||
this.$api
|
||||
.get("baseinfo/v1/user/AmountDetail?userId=" + item.Id)
|
||||
.then(res => {
|
||||
this.detailAmountData = res.Data;
|
||||
});
|
||||
},
|
||||
dataExport(){
|
||||
this.$api.getDownloadFile("/baseinfo/v1/user/Export");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
188
src/components/user/statistics.vue
Normal file
188
src/components/user/statistics.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-sold-out"
|
||||
v-if="$local.isRoot()"
|
||||
@click="dataExport"
|
||||
>导出</el-button>
|
||||
<!-- <el-button size="small" type="primary" icon="el-icon-sold-out" @click="dataExport" v-if="$local.isRoot()">导出</el-button> -->
|
||||
<div class="search-box">
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange1"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="A开始日期"
|
||||
end-placeholder="A结束日期"
|
||||
></el-date-picker>
|
||||
<el-date-picker
|
||||
size="small"
|
||||
v-model="dateRange2"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="B开始日期"
|
||||
end-placeholder="B结束日期"
|
||||
></el-date-picker>
|
||||
<el-select
|
||||
v-model="searchModel.profile"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="状态"
|
||||
>
|
||||
<el-option v-for="item in types" :key="item.label" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入会员号" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="search"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="retData.Data" size="medium" :height="$getHeight(300)"
|
||||
@sort-change="sort"
|
||||
row-key="Id" border>
|
||||
<el-table-column prop="Profile" label="状态" width="240">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown size="small" split-button type="primary">
|
||||
{{scope.row.UserInfo.Profile}}
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'已完成')">已完成</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'高意向客户')">高意向客户</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'待跟进-消费减少')">待跟进-消费减少</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'待跟进-未购买')">待跟进-未购买</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'跟进超时-消费减少')">跟进超时-消费减少</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'跟进超时-未购买')">跟进超时-未购买</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'流失-需求减少')">流失-需求减少</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'流失-暂时不用')">流失-暂时不用</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'流失-价格问题')">流失-价格问题</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'流失-产品问题')">流失-产品问题</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="changeProfile(scope.row,'跟进超时')">跟进超时</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="UserName" label="用户">
|
||||
<template slot-scope="scope">
|
||||
<phoneHide :text="scope.row.UserName"></phoneHide>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="UserName" label="联系信息">
|
||||
<template slot-scope="scope">
|
||||
<p v-if="scope.row.UserInfo.Wx">微信:{{scope.row.UserInfo.Wx}}</p>
|
||||
<p v-if="scope.row.UserInfo.QQ">QQ:{{scope.row.UserInfo.QQ}}</p>
|
||||
<p v-if="scope.row.UserInfo.TaoBao">淘宝:{{scope.row.UserInfo.TaoBao}}</p>
|
||||
<p v-if="scope.row.UserInfo.WangWang">旺旺:{{scope.row.UserInfo.WangWang}}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CreateTime" label="注册时间"></el-table-column>
|
||||
<el-table-column prop="PrevMonthAmount" label="消费金额A" sortable="custom"></el-table-column>
|
||||
<el-table-column prop="MonthAmount" label="消费金额B" sortable="custom"></el-table-column>
|
||||
<el-table-column prop="AddAmount" label="对比增长金额" sortable="custom">
|
||||
<!-- <template slot-scope="scope">
|
||||
{{scope.row.MonthAmount-scope.row.PrevMonthAmount}}
|
||||
</template> -->
|
||||
</el-table-column>
|
||||
<el-table-column prop="TotalAccountCount" label="账户总数" sortable="custom"></el-table-column>
|
||||
<el-table-column prop="UsingAccountCount" label="使用中个数" sortable="custom"></el-table-column>
|
||||
<el-table-column prop="ExpirdAccountCount" label="过期个数" sortable="custom"></el-table-column>
|
||||
</el-table>
|
||||
<div class="block">
|
||||
<el-pagination
|
||||
v-if="retData.Data.length>0"
|
||||
@current-change="get"
|
||||
:page-size="50"
|
||||
:current-page.sync="searchModel.PageIndex"
|
||||
layout="total,prev, pager, next"
|
||||
:total="retData.TotalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as dateUtil from '@/extend/js/dateFormatUtil';
|
||||
export default {
|
||||
name: "userIndex",
|
||||
components: {
|
||||
phoneHide: () => import("@/components/common/phonehide")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
dateRange1: [],
|
||||
dateRange2: [],
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: "",
|
||||
sortLable:"",
|
||||
sortOrder:0,
|
||||
profile:"",
|
||||
},
|
||||
types:[{ value: '已完成', label: '已完成'},
|
||||
{ value: '高意向客户', label: '高意向客户'},
|
||||
{ value: '待跟进-消费减少', label: '待跟进-消费减少'},
|
||||
{ value: '待跟进-未购买', label: '待跟进-未购买'},
|
||||
{ value: '跟进超时-消费减少', label: '跟进超时-消费减少'},
|
||||
{ value: '跟进超时-未购买', label: '跟进超时-未购买'},
|
||||
{ value: '流失-需求减少', label: '流失-需求减少'},
|
||||
{ value: '流失-暂时不用', label: '流失-暂时不用'},
|
||||
{ value: '流失-价格问题', label: '流失-价格问题'},
|
||||
{ value: '流失-产品问题', label: '流失-产品问题'},
|
||||
{ value: '跟进超时', label: '跟进超时'},
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "用户管理>>消费统计");
|
||||
this.dateRange1[0]=dateUtil.getLastMonthStartDate();
|
||||
this.dateRange1[1]=dateUtil.getLastMonthCurrentDate();
|
||||
|
||||
this.dateRange2[0]=dateUtil.getMonthStartDate();
|
||||
this.dateRange2[1]=dateUtil.getMonthCurrentDate();
|
||||
this.get();
|
||||
},
|
||||
methods: {
|
||||
sort({column, prop, order }){
|
||||
console.log(column)
|
||||
console.log(prop)
|
||||
console.log(order)
|
||||
this.searchModel.sortLable=prop;
|
||||
this.searchModel.sortOrder=order=="ascending"?0:1;
|
||||
this.search()
|
||||
},
|
||||
changeProfile(row,command){
|
||||
row.UserInfo.Profile=command;
|
||||
this.$api
|
||||
.post("baseinfo/v1/user/UpdateProfile",{UserId:row.UserInfo.Id,Profile:command})
|
||||
.then(res => {});
|
||||
},
|
||||
search() {
|
||||
this.searchModel.PageIndex = 1;
|
||||
this.get();
|
||||
},
|
||||
get() {
|
||||
this.loading = true;
|
||||
if (this.dateRange1 && this.dateRange1.length == 2) {
|
||||
this.searchModel.bTime1 = this.dateRange1[0];
|
||||
this.searchModel.eTime1 = this.dateRange1[1];
|
||||
}
|
||||
if (this.dateRange2 && this.dateRange2.length == 2) {
|
||||
this.searchModel.bTime2 = this.dateRange2[0];
|
||||
this.searchModel.eTime2 = this.dateRange2[1];
|
||||
}
|
||||
this.$api
|
||||
.get("course/v1/order/UserConsumeStatistics", this.searchModel)
|
||||
.then(res => {
|
||||
this.retData = res;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
dataExport() {
|
||||
this.$api.getDownloadFile("/course/v1/order/ExportUserConsumeStatistics", this.searchModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
197
src/components/user/userprice.vue
Normal file
197
src/components/user/userprice.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div class="heior_box">
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="showDialogDiscount=true">折扣价格</el-button>
|
||||
<div class="search-box">
|
||||
<el-input v-model="searchModel.keyWord" placeholder="请输入套餐名称/标题" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" @click="get"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<el-tabs tab-position="left" :style="$getStyleHeight(100)">
|
||||
<el-tab-pane :label="item.Product.Name" v-for="(item,index) in product" :key="index">
|
||||
<el-table
|
||||
:data="item.PackageUserPrices"
|
||||
row-key="Id"
|
||||
border
|
||||
size="medium"
|
||||
:height="$getHeight(100)"
|
||||
>
|
||||
<el-table-column prop="Package.Name" label="套餐名称"></el-table-column>
|
||||
<el-table-column prop="Package.Price" label="原价格"></el-table-column>
|
||||
<el-table-column prop="UserPrice.UserPrice" label="会员价格">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.UserPrice.UserPrice||'--'}}
|
||||
</template></el-table-column>
|
||||
<el-table-column prop="UserPrice.RefundDayPrice" label="退款单价"></el-table-column>
|
||||
<el-table-column prop="UserPrice.Remark" label="说明"></el-table-column>
|
||||
<el-table-column prop="UserPrice.Status" label="启用状态" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.UserPrice.Status"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#dcdfe6"
|
||||
@change="changeStatus(scope.row)"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<span class="handel cursor edit" @click="goEdit(scope.row)">编辑</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<el-dialog title="会员价格" :visible.sync="showDialog" width="400px">
|
||||
<el-form
|
||||
:model="current"
|
||||
:rules="rules"
|
||||
ref="inputPackageForm"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item prop="Name" label="套餐名称">
|
||||
<el-input v-model="current.Name" size="small" disabled=""></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Price" label="原价格">
|
||||
<el-input v-model="current.Price" type="number" size="small" disabled=""></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="MinPrice" label="会员价格">
|
||||
<el-input v-model="current.UserPrice" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="RefundDayPrice" label="退款单价">
|
||||
<el-input v-model="current.RefundDayPrice" type="number" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="Remark" label="说明">
|
||||
<el-input v-model="current.Remark" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="resetForm">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="价格折扣" :visible.sync="showDialogDiscount" width="300px">
|
||||
<el-form
|
||||
:model="current"
|
||||
:rules="rules"
|
||||
ref="inputPackageForm"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item prop="Name" label="折扣方案">
|
||||
<el-select size="small" v-model="currentDiscount.schemeId">
|
||||
<el-option v-for="(item,index) in productDiscounts" :key="index" :label="item.Name" :value="item.Id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="showDialogDiscount=false">取 消</el-button>
|
||||
<el-button type="primary" @click="setDiscount">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "treeTable",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showDialog:false,
|
||||
showDialogDiscount:false,
|
||||
retData: { TotalCount: 0, Data: [] },
|
||||
searchModel: {
|
||||
PageIndex: 1,
|
||||
keyWord: ""
|
||||
},
|
||||
product:[],
|
||||
current: {
|
||||
Name:"",
|
||||
Remark:'',
|
||||
Price:0,
|
||||
UserPrice:0,
|
||||
UserId:0,
|
||||
PackageId:0,
|
||||
ProductId:0,
|
||||
RefundDayPrice:0,
|
||||
},
|
||||
rules:{},
|
||||
currentDiscount:{
|
||||
schemeId:null,
|
||||
userId:null,
|
||||
},
|
||||
productDiscounts:[]
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.commit("setCurrentNav", "用户管理>>会员价");
|
||||
this.current.UserId=this.$route.query.id;
|
||||
this.currentDiscount.userId=this.$route.query.id;
|
||||
this.get();
|
||||
this.getProductDiscounts();
|
||||
},
|
||||
methods: {
|
||||
get() {
|
||||
this.$api.get("course/v1/product/ProductUserPrice?userId="+this.current.UserId).then(res => {
|
||||
this.product = res.Data;
|
||||
});
|
||||
},
|
||||
getProductDiscounts(){
|
||||
this.$api
|
||||
.get("course/v1/scheme/page")
|
||||
.then(res => {
|
||||
this.productDiscounts= res.Data;
|
||||
});
|
||||
},
|
||||
goEdit(item) {
|
||||
console.log(item)
|
||||
this.showDialog = true;
|
||||
this.current.Name =item.Package.Name;
|
||||
this.current.Price =item.Package.Price;
|
||||
this.current.ProductId =item.Package.ProductId;
|
||||
this.current.PackageId =item.Package.Id;
|
||||
this.current.UserPrice =item.UserPrice.UserPrice;
|
||||
this.current.RefundDayPrice =item.UserPrice.RefundDayPrice;
|
||||
},
|
||||
save() {
|
||||
this.$api
|
||||
.post("course/v1/product/PutUserPrice", this.current)
|
||||
.then(res => {
|
||||
this.resetForm();
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
changeStatus(item) {
|
||||
this.$api
|
||||
.post("course/v1/product/SetUserPriceStatus?id=" + item.UserPrice.Id)
|
||||
.then(res => {
|
||||
item.Status = res.Data;
|
||||
});
|
||||
},
|
||||
setDiscount() {
|
||||
if(!this.currentDiscount.schemeId){
|
||||
this.$warn('请选择方案')
|
||||
return ;
|
||||
}
|
||||
this.$api
|
||||
.post("course/v1/scheme/SetUserDiscount",this.currentDiscount)
|
||||
.then(res => {
|
||||
this.showDialogDiscount=false;
|
||||
this.get();
|
||||
});
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs["inputPackageForm"].resetFields();
|
||||
this.showDialog = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
338
src/extend/api/api.js
Normal file
338
src/extend/api/api.js
Normal file
@@ -0,0 +1,338 @@
|
||||
import axios from "axios";
|
||||
import qs from 'qs';
|
||||
import router from "../../router";
|
||||
import { Message } from "element-ui";
|
||||
import saveAs from "./../lib/filesaver";
|
||||
import NProgress from 'nprogress';
|
||||
import './../../../static/css/nprogress.css';
|
||||
|
||||
var http = require("./httpurl");
|
||||
function getUserToken(){
|
||||
var data = window.localStorage.getItem("etorcurrentuser");
|
||||
if(data)
|
||||
return JSON.parse(data).Token;
|
||||
return "";
|
||||
}
|
||||
|
||||
var bmsAxios = axios.create({
|
||||
// timeout: 120000,
|
||||
withCredentials: true,
|
||||
baseURL: http.baseURL,
|
||||
headers: {
|
||||
post: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bmsAxios.interceptors.request.use(
|
||||
config => {
|
||||
var data = "";
|
||||
if (window.localStorage.getItem("etorcurrentuser")) {
|
||||
data = window.localStorage.getItem("etorcurrentuser");
|
||||
}
|
||||
|
||||
if (data == "") {
|
||||
config.headers.token = "";
|
||||
config.headers.sid = sid || 0;
|
||||
} else {
|
||||
config.headers.token = JSON.parse(data).Token;
|
||||
//var TenantId = JSON.parse(data).Manager.TenantId;
|
||||
//var OperaterID = JSON.parse(data).Manager.ID;
|
||||
}
|
||||
var sid = window.localStorage.getItem("sid");
|
||||
config.headers.sid = sid || 0;
|
||||
removeNullAndUndefinedProperty(config.data)//没用的参数不要传
|
||||
removeNullAndUndefinedProperty(config.params)//没用的参数不要传
|
||||
if (config.url != "Permission/AgainGetToken") {
|
||||
window.localStorage.setItem(
|
||||
"lastrequesttime",
|
||||
JSON.stringify(Date.now())
|
||||
); //记录用户最后请求时间
|
||||
}
|
||||
//debugger
|
||||
return config;
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
// 返回状态
|
||||
let onceMessage = false;
|
||||
bmsAxios.interceptors.response.use(
|
||||
res => {
|
||||
return res;
|
||||
},
|
||||
error => {
|
||||
//有异常
|
||||
if (error.response) {
|
||||
switch (error.response.status) {
|
||||
case 401:
|
||||
if (onceMessage) return;
|
||||
onceMessage = true;
|
||||
// Message.error("信息过期,请重新登陆");
|
||||
router.replace({
|
||||
path: "/login",
|
||||
query: {
|
||||
redirect: router.currentRoute.fullPath
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 204:
|
||||
Message.error("暂无数据");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export function get(url, config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bmsAxios.get(url, {
|
||||
params: config,
|
||||
paramsSerializer: function (params) {
|
||||
return qs.stringify(params, { arrayFormat: 'repeat' })
|
||||
}
|
||||
}).then(
|
||||
response => {
|
||||
if (response.data.Code == 10000) {
|
||||
return resolve(response.data);
|
||||
} else {
|
||||
Message.error(response.data.Message||"数据异常")
|
||||
}
|
||||
},
|
||||
err => {
|
||||
reject(err);
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function post(url, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bmsAxios.post(url, params).then(
|
||||
response => {
|
||||
if (response.data.Code == 10000) {
|
||||
Message.success("操作成功")
|
||||
return resolve(response.data);
|
||||
} else {
|
||||
Message.error(response.data.Message)
|
||||
}
|
||||
},
|
||||
err => {
|
||||
Message.error("操作失败")
|
||||
reject(err);
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
Message.error("操作异常")
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function put(url, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bmsAxios.put(url, params).then(
|
||||
response => {
|
||||
resolve(response.data);
|
||||
},
|
||||
err => {
|
||||
reject(err);
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
export function del(url, config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
bmsAxios.delete(url, { params: config }).then(
|
||||
response => {
|
||||
resolve(response.data);
|
||||
},
|
||||
err => {
|
||||
reject(err);
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
/** 使用 get HTTP Method 下载文件 */
|
||||
export function getDownloadFile(url, params, name) {
|
||||
NProgress.start();
|
||||
return new Promise((resolve, reject) => {
|
||||
bmsAxios
|
||||
.get(url, {
|
||||
params: {
|
||||
...params,
|
||||
params: params
|
||||
},
|
||||
responseType: "blob"
|
||||
})
|
||||
.then(response => {
|
||||
//确定最终文件名
|
||||
const fileNameHeader = "x-suggested-filename";
|
||||
let suggestedFileName = response.headers[fileNameHeader] || name;
|
||||
if (suggestedFileName)
|
||||
suggestedFileName = decodeURIComponent(suggestedFileName);
|
||||
const effectiveFileName =
|
||||
suggestedFileName === undefined ? "untitled" : suggestedFileName;
|
||||
|
||||
//长度为零给出提示,扔出错误
|
||||
if (response.data.size == 0) throw new Error("文件长度为0");
|
||||
|
||||
//返回json,进行解析,获取Message,扔出错误
|
||||
if (response.data.type == "application/json") {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function (event) {
|
||||
var message = JSON.parse(event.target.result);
|
||||
reject(new Error(message.Message)); //拒绝
|
||||
};
|
||||
reader.readAsText(response.data);
|
||||
} else {
|
||||
saveAs(response.data, effectiveFileName);
|
||||
resolve(); //解决
|
||||
}
|
||||
})
|
||||
.catch(e => reject(e)).finally(function () {
|
||||
NProgress.done();
|
||||
}); //拒绝
|
||||
});
|
||||
}
|
||||
export function all(urlArr) { //并发请求
|
||||
if (urlArr.length > 6) {
|
||||
throw '当前不支持数量大于6个的并发请求';
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.all(urlArr).then(
|
||||
axios.spread((v0, v1, v2, v3, v4, v5) => {
|
||||
let ret = {};
|
||||
arguments.forEach((item, idx) => {
|
||||
if (item)
|
||||
ret[`ret${idx}`] = item
|
||||
})
|
||||
resolve(item);
|
||||
}),
|
||||
err => {
|
||||
reject(err);
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function axiosHttp(url, params, type = 'get') {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios[type](url, { params: params }).then(
|
||||
response => {
|
||||
resolve(response.data);
|
||||
},
|
||||
err => {
|
||||
reject(err);
|
||||
}
|
||||
).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
function removeNullAndUndefinedProperty(model) {//移除对象中值为null、undefined的属性
|
||||
if (model) {
|
||||
for (let key in model) {
|
||||
if (model[key] === null || typeof (model[key]) === 'undefined') {
|
||||
delete model[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createFileInput(accept, onSelect) {
|
||||
var lastFileInput = document.getElementById("f1_id");
|
||||
if (lastFileInput != null) {
|
||||
document.body.removeChild(lastFileInput);
|
||||
}
|
||||
lastFileInput = document.createElement("input");
|
||||
lastFileInput.type = "file";
|
||||
lastFileInput.name = "f1";
|
||||
lastFileInput.id = "f1_id";
|
||||
accept && (lastFileInput.accept = accept);
|
||||
lastFileInput.setAttribute("style", "display:none;");
|
||||
document.body.appendChild(lastFileInput);
|
||||
lastFileInput.onchange = function (e) {
|
||||
var f = lastFileInput.files[0];
|
||||
onSelect && onSelect(f)
|
||||
}
|
||||
return lastFileInput;
|
||||
}
|
||||
export function getUuid(length) {
|
||||
return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36);
|
||||
}
|
||||
|
||||
//通过axios上传文件
|
||||
export function upload(url, uconfig) {
|
||||
var uconfig = uconfig || {};
|
||||
var params = uconfig.params || {};
|
||||
var accept = uconfig.accept || "image/gif, image/jpeg,image/jpg,image/png,image/*";
|
||||
var onProgress = uconfig.onProgress || function () { };
|
||||
var onStart = uconfig.onStart || function () { };
|
||||
var uuid = uconfig.uuid || getUuid(10);
|
||||
let config = {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"token":getUserToken(),
|
||||
"sid":0
|
||||
},
|
||||
transformRequest: [function (data) {
|
||||
return data
|
||||
}],
|
||||
onUploadProgress: e => {
|
||||
var completeProgress = ((e.loaded / e.total * 100) | 0);
|
||||
onProgress && onProgress(uuid, completeProgress);
|
||||
console.log("onUploadProgress:" + completeProgress);
|
||||
}
|
||||
}
|
||||
let formData = new FormData();
|
||||
for (let key of Object.keys(params)) {
|
||||
formData.append(key, params[key] !== null ? params[key] : '')
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
var lastFileInput = createFileInput(accept, file => {
|
||||
if (!file)
|
||||
reject("没有选择文件")
|
||||
formData.append(file.name, file);
|
||||
onStart && onStart(uuid, file);
|
||||
|
||||
var uploadAxios = axios.create({
|
||||
withCredentials: true,
|
||||
baseURL: http.baseURL
|
||||
});
|
||||
uploadAxios.post(url, formData, config).then(
|
||||
response => { resolve(response.data) },
|
||||
err => { reject(err) }
|
||||
).catch(error => { reject(error) })
|
||||
})
|
||||
lastFileInput.click();
|
||||
});
|
||||
}
|
||||
export default {
|
||||
baseURL: http.baseURL,
|
||||
get,
|
||||
post,
|
||||
del,
|
||||
put,
|
||||
upload,//:httpfile.upload,
|
||||
getDownloadFile,
|
||||
all(urlArr) { //并发请求
|
||||
return all(urlArr);
|
||||
}
|
||||
};
|
||||
224
src/extend/api/httpfile.js
Normal file
224
src/extend/api/httpfile.js
Normal file
@@ -0,0 +1,224 @@
|
||||
function then(onthen) {
|
||||
this._then_callback = function (p) { };
|
||||
this._error_callback = function (p) { };
|
||||
this._on_then = onthen;
|
||||
}
|
||||
|
||||
function JsFormData() {
|
||||
this.boundry = "";
|
||||
this.formName = "";
|
||||
this.formValue = "";
|
||||
}
|
||||
JsFormData.prototype.constructor = JsFormData;
|
||||
JsFormData.prototype.getFormString = function () {
|
||||
return "--" + this.boundry + "\r\nContent-Disposition:form-data; name=" + this.formName + "\r\n\r\n" + this.formValue + "\r\n";
|
||||
};
|
||||
JsFormData.prototype.toString = function () {
|
||||
return this.getFormString();
|
||||
};
|
||||
|
||||
function JsFileFormData() {
|
||||
this.formFileName = "";
|
||||
this.contentType = "";
|
||||
JsFormData.call(this);
|
||||
}
|
||||
JsFileFormData.prototype = new JsFileFormData();
|
||||
JsFileFormData.prototype.constructor = JsFileFormData;
|
||||
JsFileFormData.prototype.getFormString = function () {
|
||||
return "--" + this.boundry + "\r\nContent-Disposition:form-data; name=" + this.formName + "; filename=" + this.formFileName + "\r\nContent-Type: " + this.contentType + "\r\n\r\n" + this.formValue + "\r\n";
|
||||
};
|
||||
JsFileFormData.prototype.toString = function () {
|
||||
return this.getFormString();
|
||||
};
|
||||
then.prototype.constructor = then;
|
||||
then.prototype = new then();
|
||||
then.prototype.then = function (p) {
|
||||
this._then_callback = p;
|
||||
this._on_then();
|
||||
return this;
|
||||
};
|
||||
then.prototype.error = function (p) {
|
||||
this._error_callback = p;
|
||||
return this;
|
||||
}
|
||||
then.prototype.invoke_then = function (p) {
|
||||
this._then_callback(p);
|
||||
return this;
|
||||
}
|
||||
then.prototype.invoke_error = function (p) {
|
||||
this._error_callback(p);
|
||||
return this;
|
||||
}
|
||||
|
||||
function JsHttpHelper() {
|
||||
this.formData = new Array();
|
||||
}
|
||||
JsHttpHelper.prototype.boundry = Math.random().toString().substr(2),
|
||||
JsHttpHelper.prototype.addFormValue = function (key, value) {
|
||||
var f = new JsFormData();
|
||||
f.formName = key;
|
||||
f.formValue = value;
|
||||
f.boundry = this.boundry;
|
||||
this.formData.push(f);
|
||||
};
|
||||
JsHttpHelper.prototype.addFileFormValue = function (key, fname, fcontent) {
|
||||
var f = new JsFileFormData();
|
||||
f.formName = key;
|
||||
f.formValue = fcontent;
|
||||
f.contentType = "application/octet-stream";
|
||||
f.formFileName = fname;
|
||||
f.boundry = this.boundry;
|
||||
this.formData.push(f);
|
||||
};
|
||||
JsHttpHelper.prototype.postMultipartFormData = function (url, postCallBack, updateProgress, errorFunc) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
// xhr.onloadend = function (e) {
|
||||
// if (e.total > 0)
|
||||
// postCallBack(e, xhr);
|
||||
// };
|
||||
xhr.onload = function (e) {
|
||||
if((e.status >= 200 && e.status < 300) || e.status == 304){
|
||||
postCallBack(e, xhr);
|
||||
}
|
||||
};
|
||||
xhr.onabort = errorFunc;
|
||||
xhr.onerror = errorFunc;
|
||||
xhr.ontimeout = errorFunc;
|
||||
if (updateProgress != null) {
|
||||
xhr.upload.onprogress = function (e) {
|
||||
if (e.lengthComputable) {
|
||||
updateProgress((e.loaded / e.total) * 100);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + this.boundry);
|
||||
var postBody = "";
|
||||
// console.log(this.formData);
|
||||
for (var s = 0; s < this.formData.length; s++) {
|
||||
postBody += this.formData[s].getFormString();
|
||||
}
|
||||
postBody += "--" + this.boundry + "--\r\n";
|
||||
xhr.send(postBody);
|
||||
this.formData = new Array();
|
||||
console.log(this.formData);
|
||||
};
|
||||
|
||||
JsHttpHelper.prototype.constructor = JsHttpHelper;
|
||||
|
||||
var lastFileInput;
|
||||
|
||||
function compress_image(base64Image, callback, wd) {
|
||||
if (wd == null || wd == undefined) {
|
||||
wd = 200;
|
||||
}
|
||||
var image = document.createElement("img");
|
||||
image.onload = function () {
|
||||
var square = wd;
|
||||
var canvas = document.createElement('canvas');
|
||||
var HoverW = this.height / this.width;
|
||||
var hNew = wd * HoverW;
|
||||
var wNew = wd;
|
||||
canvas.width = wNew;
|
||||
canvas.height = hNew;
|
||||
var context = canvas.getContext('2d');
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
context.drawImage(this, 0, 0, this.width, this.height, 0, 0, wNew, hNew);
|
||||
var data = canvas.toDataURL('image/jpeg');
|
||||
//console.log("compress_image raw " + base64Image.length + " now " + data.length + " decrease rate " + (base64Image.length - data.length) / base64Image.length);
|
||||
callback(data);
|
||||
};
|
||||
image.setAttribute('src', base64Image);
|
||||
}
|
||||
|
||||
function read_file_base64String(funcReadOver, funcReadOutoffLimit, sizeLimit) {
|
||||
if (sizeLimit == null || sizeLimit == undefined) {
|
||||
sizeLimit = 200;
|
||||
}
|
||||
lastFileInput = document.getElementById("f1_id");
|
||||
if (lastFileInput != null) {
|
||||
document.body.removeChild(lastFileInput);
|
||||
lastFileInput = null;
|
||||
}
|
||||
if (lastFileInput == null) {
|
||||
lastFileInput = document.createElement("input");
|
||||
lastFileInput.type = "file";
|
||||
lastFileInput.name = "f1";
|
||||
lastFileInput.id = "f1_id";
|
||||
lastFileInput.setAttribute("style", "display:none;");
|
||||
document.body.appendChild(lastFileInput);
|
||||
}
|
||||
lastFileInput.onchange = null;
|
||||
lastFileInput.onchange = function (e) {
|
||||
var f = lastFileInput.files[0];
|
||||
var reader = new FileReader();
|
||||
var sz = ((f.size / 1024) / 1024);
|
||||
//console.log(sz + "m");
|
||||
reader.onloadend = function (e) {
|
||||
compress_image(e.target.result, function (bs64) {
|
||||
funcReadOver(bs64);
|
||||
}, sizeLimit);
|
||||
//1M == 1398211
|
||||
};
|
||||
reader.readAsDataURL(f);
|
||||
};
|
||||
lastFileInput.click();
|
||||
}
|
||||
|
||||
function upload(url,func, keyValues, isfile, accept) {
|
||||
// var proc = progressBar.start();
|
||||
lastFileInput = document.getElementById("f1_id");
|
||||
if (lastFileInput != null) {
|
||||
document.body.removeChild(lastFileInput);
|
||||
lastFileInput = null;
|
||||
}
|
||||
if (lastFileInput == null) {
|
||||
lastFileInput = document.createElement("input");
|
||||
lastFileInput.type = "file";
|
||||
lastFileInput.name = "f1";
|
||||
lastFileInput.id = "f1_id";
|
||||
accept && (lastFileInput.accept = accept);
|
||||
lastFileInput.setAttribute("style", "display:none;");
|
||||
document.body.appendChild(lastFileInput);
|
||||
}
|
||||
lastFileInput.onchange = null;
|
||||
lastFileInput.onchange = function (e) {
|
||||
var f = lastFileInput.files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function (e) {
|
||||
var sz = ((f.size / 1024) / 1024);
|
||||
if (isfile != undefined && isfile!=='') {
|
||||
var http = new JsHttpHelper();
|
||||
http.addFileFormValue("f2", f.name, e.target.result);
|
||||
if(keyValues){
|
||||
for (var key in keyValues) {
|
||||
http.addFormValue(keyValues[key].key, keyValues[key].value);
|
||||
}
|
||||
}
|
||||
http.postMultipartFormData(url, func, null, function (e, xhr) {
|
||||
});
|
||||
} else {
|
||||
compress_image(e.target.result, function (bs64) {
|
||||
var http = new JsHttpHelper();
|
||||
http.addFileFormValue("f2", f.name, bs64);
|
||||
if(keyValues){
|
||||
for (var key in keyValues) {
|
||||
http.addFormValue(keyValues[key].key, keyValues[key].value);
|
||||
}
|
||||
}
|
||||
http.postMultipartFormData(url, func, null, function (e, xhr) {
|
||||
});
|
||||
});
|
||||
}
|
||||
//1M == 1398211
|
||||
};
|
||||
reader.readAsDataURL(f);
|
||||
};
|
||||
lastFileInput.click();
|
||||
}
|
||||
|
||||
export default{
|
||||
compress_image,
|
||||
read_file_base64String,
|
||||
upload
|
||||
}
|
||||
23
src/extend/api/httpurl.js
Normal file
23
src/extend/api/httpurl.js
Normal file
@@ -0,0 +1,23 @@
|
||||
//npm run build -- dev
|
||||
//npm run build -- test
|
||||
//npm run build -- prod
|
||||
|
||||
const devUrlNew ='http://localhost:5000/api/'
|
||||
const testUrlNew = "http://localhost:5000/api/"
|
||||
const prodUrlNew ="http://www.juip.com/api/";// "http://api.yk.hncore.net/api/"/"http://hapi.hncore.net/api"
|
||||
|
||||
var baseURL= devUrlNew
|
||||
switch (process.env.NODE_ENV) {
|
||||
case "development":
|
||||
baseURL =devUrlNew
|
||||
break;
|
||||
case "test":
|
||||
baseURL =testUrlNew
|
||||
break;
|
||||
case "production":
|
||||
baseURL = prodUrlNew
|
||||
break;
|
||||
}
|
||||
export {
|
||||
baseURL
|
||||
};
|
||||
35
src/extend/components/breadcrumbs.vue
Normal file
35
src/extend/components/breadcrumbs.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<nav class="model-breadcrumbs">
|
||||
<ol>
|
||||
<li style="display:inline-block;" v-for="(item,index) in routes" :key="index">
|
||||
<router-link style="color:#333" v-if="item.link" :to="item.link">{{item.name}}<span style="margin:0 .4em;">></span></router-link>
|
||||
<span v-else>{{item.name}}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
routes:{
|
||||
type:Array,
|
||||
default:function(){
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.model-breadcrumbs{
|
||||
padding:15px;
|
||||
border: 1px solid #dae1f2;
|
||||
font-size:16px;
|
||||
background: white;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color:#333;
|
||||
}
|
||||
</style>
|
||||
38
src/extend/components/drop-down.vue
Normal file
38
src/extend/components/drop-down.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<el-dropdown @command="assignValue">
|
||||
<el-button size="mini">
|
||||
{{value.name}}<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="item" v-for="(item,index) in list" :key="item.code||index">{{item.name||1111}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: 'drop down'
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
value:{
|
||||
type:Object,
|
||||
default:function(){
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
assignValue:function(value){
|
||||
this.$emit('input',value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
32
src/extend/components/empty.vue
Normal file
32
src/extend/components/empty.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<section class="model-empty" style="padding:30px;text-align:center;">
|
||||
<figure :class="`model-empty-figure ${type}`"></figure>
|
||||
<h2 style="font-size:14px;color:#999;font-weight:400;">{{title}}</h2>
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
type:{
|
||||
type:String
|
||||
},
|
||||
title:{
|
||||
type:String,
|
||||
default:'还没有任何数据'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.model-empty-figure{
|
||||
height:100px;
|
||||
background-repeat: no-repeat;
|
||||
background-position:center top;
|
||||
background-size:auto 100%;
|
||||
background-image: url('/static/img/nodata.png');
|
||||
}
|
||||
.model-empty-figure.call{
|
||||
background-image:url('/static/img/no-call.png');
|
||||
}
|
||||
</style>
|
||||
10
src/extend/components/header.vue
Normal file
10
src/extend/components/header.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div data-v-1aadaada="" class="table_tabs" style="justify-content: start;"><span data-v-1aadaada="">{{title}}</span></div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
title:String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
23
src/extend/components/lazy-loader.vue
Normal file
23
src/extend/components/lazy-loader.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div v-if="init||visible">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
visible:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
}
|
||||
},
|
||||
data:function(){
|
||||
init:false
|
||||
},
|
||||
watch:{
|
||||
visible:function(value){
|
||||
if(value) this.init=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
83
src/extend/components/loading.vue
Normal file
83
src/extend/components/loading.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div style="position:relative;" :is="tag" v-if="successCode.indexOf(code-0)!==-1||code==-1"
|
||||
v-loading="animation?code==-1?true:false:false">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div :is="tag" v-else :class="`${position} model-loading`" style="background-color:#fff;">
|
||||
<div class="layout-td">
|
||||
<h2 style="font-size:16px;margin-bottom:.6em"><span>错误({{code}})</span></h2>
|
||||
<p>{{errorMessage}},
|
||||
<span class="cursor" style="color:#6896ff" @click="reload">刷新页面</span>,
|
||||
或者<span class="cursor" style="color:#6896ff" @click="$emit('reloading')">重新加载</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
position: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
},
|
||||
code: {
|
||||
type: [String, Number],
|
||||
default: -1
|
||||
},
|
||||
successCode: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [200, 10000, 304]
|
||||
}
|
||||
},
|
||||
message: {
|
||||
type: String,
|
||||
default: '服务器繁忙'
|
||||
},
|
||||
animation:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
errorMessage: function () {
|
||||
return navigator.onLine ? '服务器繁忙' : '网络错误'
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
product: process.env.NODE_ENV === 'production'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reload: function () {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.model-loading {
|
||||
position: relative;
|
||||
flex-wrap: wrap;
|
||||
margin: 15px auto;
|
||||
padding: 15px;
|
||||
min-height: 50px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.model-loading.middle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
3
src/extend/components/note.vue
Normal file
3
src/extend/components/note.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<p style="font-size:12px;color:#999;margin:.4em auto;"><slot></slot></p>
|
||||
</template>
|
||||
92
src/extend/components/pagination.vue
Normal file
92
src/extend/components/pagination.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<el-pagination
|
||||
:style="[style.original,style[type]]"
|
||||
:current-page.sync="currentPageSelf"
|
||||
:page-sizes="pageSizes" :page-size.sync="pageSizeSelf" :layout="layout" :total="total">
|
||||
</el-pagination>
|
||||
</template>
|
||||
<script>
|
||||
const pageSize =20;
|
||||
let style={
|
||||
original:{
|
||||
position:'static',
|
||||
transform:'translate(0,0)',
|
||||
textAlign:'center'
|
||||
},
|
||||
primary:{
|
||||
backgroundColor:'#fff',
|
||||
padding:'15px',
|
||||
border:'1px solid #EBEEF5',
|
||||
borderTop:0
|
||||
}
|
||||
};
|
||||
export default {
|
||||
props: {
|
||||
type:{
|
||||
type:String,
|
||||
default:'primary'
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [1.5*pageSize, 2 * pageSize, 3 * pageSize, 5 * pageSize,10*pageSize]
|
||||
}
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default:1.5*pageSize
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'total,sizes,prev, pager, next, jumper'
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
currentPage:{
|
||||
type: Number,
|
||||
default:1
|
||||
}
|
||||
},
|
||||
data:function(){
|
||||
return {
|
||||
style:style
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentPageSelf: {
|
||||
get: function () {
|
||||
return this.currentPage
|
||||
},
|
||||
set: function (value){
|
||||
this.$emit('update:currentPage', value);
|
||||
}
|
||||
},
|
||||
pageSizeSelf:{
|
||||
get:function(){
|
||||
return this.pageSize
|
||||
},
|
||||
set:function(value){
|
||||
this.$emit('update:pageSize',value);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
pageSize:function(){
|
||||
this.emitChange()
|
||||
},
|
||||
currentPage:function(){
|
||||
this.emitChange()
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
emitChange:function(){
|
||||
clearTimeout(this.timerId);
|
||||
setTimeout(()=>{
|
||||
this.$emit('change',[this.currentPage,this.pageSize]);
|
||||
},80)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
22
src/extend/components/search-bar.vue
Normal file
22
src/extend/components/search-bar.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<el-form style="background-color:#fdfdfe;padding:10px;" :inline="inline" :label-width="labelWidth">
|
||||
<slot></slot>
|
||||
<div class="layout-tr-between" style="width:100%;">
|
||||
<div><slot name="left"></slot></div>
|
||||
<div><slot name="right"></slot></div>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
labelWidth:{
|
||||
type:String
|
||||
},
|
||||
inline:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
99
src/extend/directive/transferDom copy.js
Normal file
99
src/extend/directive/transferDom copy.js
Normal file
@@ -0,0 +1,99 @@
|
||||
// Thanks to: https://github.com/calebroseland/vue-dom-portal
|
||||
|
||||
/**
|
||||
* Get target DOM Node
|
||||
* @param {(Node|string|Boolean)} [node=document.body] DOM Node, CSS selector, or Boolean
|
||||
* @return {Node} The target that the el will be appended to
|
||||
*/
|
||||
function getTarget (node) {
|
||||
if (node === void 0) {
|
||||
return document.body
|
||||
}
|
||||
|
||||
if (typeof node === 'string' && node.indexOf('?') === 0) {
|
||||
return document.body
|
||||
} else if (typeof node === 'string' && node.indexOf('?') > 0) {
|
||||
node = node.split('?')[0]
|
||||
}
|
||||
|
||||
if (node === 'body' || node === true) {
|
||||
return document.body
|
||||
}
|
||||
|
||||
return node instanceof window.Node ? node : document.querySelector(node)
|
||||
}
|
||||
|
||||
function getShouldUpdate (node) {
|
||||
// do not updated by default
|
||||
if (!node) {
|
||||
return false
|
||||
}
|
||||
if (typeof node === 'string' && node.indexOf('?') > 0) {
|
||||
try {
|
||||
const config = JSON.parse(node.split('?')[1])
|
||||
return config.autoUpdate || false
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const directive = {
|
||||
inserted (el, { value }, vnode) {
|
||||
el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom'
|
||||
const parentNode = el.parentNode
|
||||
var home = document.createComment('')
|
||||
var hasMovedOut = false
|
||||
|
||||
if (value !== false) {
|
||||
parentNode.replaceChild(home, el) // moving out, el is no longer in the document
|
||||
getTarget(value).appendChild(el) // moving into new place
|
||||
hasMovedOut = true
|
||||
}
|
||||
if (!el.__transferDomData) {
|
||||
el.__transferDomData = {
|
||||
parentNode: parentNode,
|
||||
home: home,
|
||||
target: getTarget(value),
|
||||
hasMovedOut: hasMovedOut
|
||||
}
|
||||
}
|
||||
},
|
||||
componentUpdated (el, { value }) {
|
||||
const shouldUpdate = getShouldUpdate(value)
|
||||
if (!shouldUpdate) {
|
||||
return
|
||||
}
|
||||
// need to make sure children are done updating (vs. `update`)
|
||||
var ref$1 = el.__transferDomData
|
||||
// homes.get(el)
|
||||
var parentNode = ref$1.parentNode
|
||||
var home = ref$1.home
|
||||
var hasMovedOut = ref$1.hasMovedOut // recall where home is
|
||||
|
||||
if (!hasMovedOut && value) {
|
||||
// remove from document and leave placeholder
|
||||
parentNode.replaceChild(home, el)
|
||||
// append to target
|
||||
getTarget(value).appendChild(el)
|
||||
el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: true, target: getTarget(value) })
|
||||
} else if (hasMovedOut && value === false) {
|
||||
// previously moved, coming back home
|
||||
parentNode.replaceChild(el, home)
|
||||
el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: false, target: getTarget(value) })
|
||||
} else if (value) {
|
||||
// already moved, going somewhere else
|
||||
getTarget(value).appendChild(el)
|
||||
}
|
||||
},
|
||||
unbind: function unbind (el, binding) {
|
||||
el.className = el.className.replace('v-transfer-dom', '')
|
||||
if (el.__transferDomData && el.__transferDomData.hasMovedOut === true) {
|
||||
el.__transferDomData.parentNode && el.__transferDomData.parentNode.appendChild(el)
|
||||
}
|
||||
el.__transferDomData = null
|
||||
}
|
||||
}
|
||||
|
||||
export default directive
|
||||
49
src/extend/directive/transferDom.js
Normal file
49
src/extend/directive/transferDom.js
Normal file
@@ -0,0 +1,49 @@
|
||||
function getTarget (node = document.body) {
|
||||
if (node === true) return document.body
|
||||
return node instanceof window.Node ? node : document.querySelector(node)
|
||||
}
|
||||
|
||||
const homes = new Map()
|
||||
|
||||
const directive = {
|
||||
inserted (el, { value }, vnode) {
|
||||
console.log('v-transfer-dom:inserted')
|
||||
const { parentNode } = el
|
||||
const home = document.createComment('')
|
||||
let hasMovedOut = false
|
||||
|
||||
if (value !== false) {
|
||||
parentNode&&parentNode.replaceChild(home, el) // moving out, el is no longer in the document
|
||||
getTarget(value).appendChild(el) // moving into new place
|
||||
hasMovedOut = true
|
||||
}
|
||||
|
||||
if (!homes.has(el)) homes.set(el, { parentNode, home, hasMovedOut }) // remember where home is or should be
|
||||
},
|
||||
componentUpdated (el, { value }) { // need to make sure children are done updating (vs. `update`)
|
||||
console.log('v-transfer-dom:componentUpdated')
|
||||
const { parentNode, home, hasMovedOut } = homes.get(el) // recall where home is
|
||||
|
||||
if (!hasMovedOut && value) {
|
||||
// remove from document and leave placeholder
|
||||
parentNode.replaceChild(home, el)
|
||||
// append to target
|
||||
getTarget(value).appendChild(el)
|
||||
|
||||
homes.set(el, Object.assign({}, homes.get(el), { hasMovedOut: true }))
|
||||
} else if (hasMovedOut && value === false) {
|
||||
// previously moved, coming back home
|
||||
parentNode.replaceChild(el, home)
|
||||
homes.set(el, Object.assign({}, homes.get(el), { hasMovedOut: false }))
|
||||
} else if (value) {
|
||||
// already moved, going somewhere else
|
||||
getTarget(value).appendChild(el)
|
||||
}
|
||||
},
|
||||
unbind (el, binding) {
|
||||
console.log('v-transfer-dom:unbind')
|
||||
el.parentNode.removeChild(el);
|
||||
homes.delete(el)
|
||||
}
|
||||
}
|
||||
export default directive
|
||||
56
src/extend/index.js
Normal file
56
src/extend/index.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import vue from 'vue';
|
||||
// element-ui
|
||||
import ElementUI from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
vue.use(ElementUI);
|
||||
|
||||
|
||||
import './js/utils';
|
||||
|
||||
import './js/filter';
|
||||
|
||||
//api
|
||||
import api from './api/api';
|
||||
vue.prototype.$api = api;
|
||||
|
||||
//message
|
||||
import './js/messageTip';
|
||||
|
||||
//localStorage
|
||||
import local from './js/localStorage';
|
||||
vue.prototype.$local = local;
|
||||
|
||||
import vaild from './../../static/js/vaild.js'
|
||||
vue.prototype.$vaild = vaild;
|
||||
|
||||
|
||||
// echarts from baidu
|
||||
//import echarts from 'echarts';
|
||||
//vue.prototype.$echarts = echarts;
|
||||
// components
|
||||
import loading from './components/loading';
|
||||
import dropDown from './components/drop-down';
|
||||
import empty from './components/empty';
|
||||
import pagination from './components/pagination';
|
||||
import ScrollBar from 'element-ui/lib/scrollbar';
|
||||
import modelNote from './components/note';
|
||||
|
||||
// import '../../static/umeditor/themes/default/css/umeditor.css';
|
||||
// import '../../static/umeditor/umeditor.config.js'
|
||||
// import '../../static/umeditor/umeditor.js'
|
||||
// import '../../static/umeditor/lang/zh-cn/zh-cn.js'
|
||||
// import UE from '../../static/umeditor/umeditor.vue';
|
||||
|
||||
import UE from "vue-ueditor-wrap";
|
||||
|
||||
vue.component("model-loading", loading);
|
||||
vue.component("model-drop-down", dropDown);
|
||||
vue.component("model-empty", empty);
|
||||
vue.component("model-pagination", pagination);
|
||||
vue.component("ScrollBar",ScrollBar);
|
||||
vue.component("model-note", modelNote);
|
||||
vue.component("UE",UE);
|
||||
|
||||
|
||||
|
||||
|
||||
137
src/extend/js/dateFormatUtil.js
Normal file
137
src/extend/js/dateFormatUtil.js
Normal file
@@ -0,0 +1,137 @@
|
||||
// 当前日期
|
||||
let now = new Date();
|
||||
// 今天本周的第几天
|
||||
let nowDayOfWeek = now.getDay();
|
||||
// 当前日
|
||||
let nowDay = now.getDate();
|
||||
// 当前月
|
||||
let nowMonth = now.getMonth();
|
||||
// 当前年
|
||||
let nowYear = now.getFullYear();
|
||||
nowYear += (nowYear < 2000) ? 1900 : 0;
|
||||
// 上月日期
|
||||
let lastMonthDate = new Date();
|
||||
lastMonthDate.setDate(1);
|
||||
lastMonthDate.setMonth(lastMonthDate.getMonth() - 1);
|
||||
let lastMonth = lastMonthDate.getMonth();
|
||||
// 日期格式化,时间戳 时分秒 hh:mm:ss
|
||||
export function formatTimeStamp(date, fmt = 'yyyy-MM-dd hh:mm:ss') {
|
||||
if(!date) {
|
||||
return '-';
|
||||
}
|
||||
date = new Date(date);
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
|
||||
}
|
||||
let o = {
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds()
|
||||
};
|
||||
for (let k in o) {
|
||||
if (new RegExp(`(${k})`).test(fmt)) {
|
||||
let str = o[k] + '';
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
function padLeftZero(str) {
|
||||
return ('00' + str).substr(str.length);
|
||||
}
|
||||
// 获取当前时间
|
||||
export function getNowDate() {
|
||||
return formatTimeStamp(new Date());
|
||||
}
|
||||
// 获得某月的天数
|
||||
export function getMonthDays(myMonth) {
|
||||
let monthStartDate = new Date(nowYear, myMonth, 1);
|
||||
let monthEndDate = new Date(nowYear, myMonth + 1, 1);
|
||||
let days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24);
|
||||
return days;
|
||||
}
|
||||
// 获得本季度的开始月份
|
||||
export function getQuarterStartMonth() {
|
||||
let quarterStartMonth = 0;
|
||||
if (nowMonth < 3) {
|
||||
quarterStartMonth = 0;
|
||||
}
|
||||
if (2 < nowMonth && nowMonth < 6) {
|
||||
quarterStartMonth = 3;
|
||||
}
|
||||
if (5 < nowMonth && nowMonth < 9) {
|
||||
quarterStartMonth = 6;
|
||||
}
|
||||
if (nowMonth > 8) {
|
||||
quarterStartMonth = 9;
|
||||
}
|
||||
return quarterStartMonth;
|
||||
}
|
||||
// 获得本周的开始日期
|
||||
export function getWeekStartDate() {
|
||||
let weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek);
|
||||
return formatTimeStamp(weekStartDate);
|
||||
}
|
||||
// 获得本周的结束日期
|
||||
export function getWeekEndDate() {
|
||||
let weekEndDate = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek));
|
||||
return formatTimeStamp(weekEndDate);
|
||||
}
|
||||
// 获得上周的开始日期
|
||||
export function getLastWeekStartDate() {
|
||||
let weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 6);
|
||||
return formatTimeStamp(weekStartDate);
|
||||
}
|
||||
// 获得上周的结束日期
|
||||
export function getLastWeekEndDate() {
|
||||
let weekEndDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek);
|
||||
return formatTimeStamp(weekEndDate);
|
||||
}
|
||||
// 获得本月的开始日期
|
||||
export function getMonthStartDate() {
|
||||
let monthStartDate = new Date(nowYear, nowMonth, 1);
|
||||
return formatTimeStamp(monthStartDate);
|
||||
}
|
||||
// 获得本月的当前日期
|
||||
export function getMonthCurrentDate() {
|
||||
let monthEndDate = new Date(nowYear, nowMonth, now.getDate());
|
||||
return formatTimeStamp(monthEndDate);
|
||||
}
|
||||
// 获得本月的结束日期
|
||||
export function getMonthEndDate() {
|
||||
let monthEndDate = new Date(nowYear, nowMonth, getMonthDays(nowMonth));
|
||||
return formatTimeStamp(monthEndDate);
|
||||
}
|
||||
// 获得上月开始时间
|
||||
export function getLastMonthStartDate() {
|
||||
let lastMonthStartDate = new Date(nowYear, lastMonth, 1);
|
||||
return formatTimeStamp(lastMonthStartDate);
|
||||
}
|
||||
// 获得上月结束时间
|
||||
export function getLastMonthEndDate() {
|
||||
let lastMonthEndDate = new Date(nowYear, lastMonth, getMonthDays(lastMonth));
|
||||
return formatTimeStamp(lastMonthEndDate);
|
||||
}
|
||||
// 获得上月当前时间
|
||||
export function getLastMonthCurrentDate() {
|
||||
let lastMonthCurrentDate = new Date(nowYear, lastMonth, now.getDate());
|
||||
return formatTimeStamp(lastMonthCurrentDate);
|
||||
}
|
||||
// 获得本季度的开始日期
|
||||
export function getQuarterStartDate() {
|
||||
let quarterStartDate = new Date(nowYear, getQuarterStartMonth(), 1);
|
||||
return formatTimeStamp(quarterStartDate);
|
||||
}
|
||||
// 或的本季度的结束日期
|
||||
export function getQuarterEndDate() {
|
||||
let quarterEndMonth = getQuarterStartMonth() + 2;
|
||||
let quarterStartDate = new Date(nowYear, quarterEndMonth, getMonthDays(quarterEndMonth));
|
||||
return formatTimeStamp(quarterStartDate);
|
||||
}
|
||||
// 当时时间减去天数
|
||||
export function getNowDateSubtraction(day) {
|
||||
let nowDateSubtraction = new Date().setDate((new Date().getDate() - day));
|
||||
return formatTimeStamp(nowDateSubtraction);
|
||||
}
|
||||
116
src/extend/js/filter.js
Normal file
116
src/extend/js/filter.js
Normal file
@@ -0,0 +1,116 @@
|
||||
import vue from 'vue';
|
||||
vue.filter("upcase", function (value) {
|
||||
var arr = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
|
||||
// value = arr[value];
|
||||
if (value <= 9) {
|
||||
value = arr[value];
|
||||
} else if (value == 19) {
|
||||
value = '二十'
|
||||
} else if (9 < value <= 18) {
|
||||
value = '十' + arr[value % 10]
|
||||
}
|
||||
// if (value >= 10) {
|
||||
// if (value % 10 == 0) {
|
||||
// value = arr[(value / 10) - 1] + '十'
|
||||
// } else {
|
||||
// value = arr[(value / 10) - 1] + '十' + arr[(value % 10) - 1]
|
||||
// }
|
||||
// }
|
||||
return value;
|
||||
});
|
||||
vue.filter('week', function (value) { // 时间转星期
|
||||
if (!value) return ''
|
||||
let date = new Date(value).getDay();
|
||||
//let weeks = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
|
||||
let weeks = new Array("周日", "周一", "周二", "周三", "周四", "周五", "周六");
|
||||
return weeks[date];
|
||||
})
|
||||
//yyyy-MM-dd HH:mm:ss
|
||||
vue.filter("dateFormat", function (value) {
|
||||
if (value == null || value == '') return '-';
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "-" : "-0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "-" : "-0") + value.getDate() + " " + (value.getHours() > 9 ? "" : "0") + value.getHours() + (value.getMinutes() > 9 ? ":" : ":0") + value.getMinutes() + (value.getSeconds() > 9 ? ":" : ":0") + value.getSeconds();
|
||||
});
|
||||
//yyyyMMddHHmmss
|
||||
vue.filter("dateFormat1", function (value) {
|
||||
if (value == null) return null;
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "" : "0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "" : "0") + value.getDate() + "" + (value.getHours() > 9 ? "" : "0") + value.getHours() + (value.getMinutes() > 9 ? "" : "0") + value.getMinutes() + (value.getSeconds() > 9 ? "" : "0") + value.getSeconds();
|
||||
});
|
||||
//yyyy-MM-dd HH:mm
|
||||
vue.filter("dateMinuteFormat", function (value) {
|
||||
if (value == null) return null;
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "-" : "-0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "-" : "-0") + value.getDate() + " " + (value.getHours() > 9 ? "" : "0") + value.getHours() + (value.getMinutes() > 9 ? ":" : ":0") + value.getMinutes();
|
||||
});
|
||||
//yyyy-MM-dd
|
||||
vue.filter("dateFormat2", function (value) {
|
||||
if (value == null) return null;
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "-" : "-0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "-" : "-0") + value.getDate();
|
||||
});
|
||||
//yyyy-MM
|
||||
vue.filter("dateFormat3", function (value) {
|
||||
if (value == null) return null;
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "-" : "-0") + (value.getMonth() + 1);
|
||||
});
|
||||
//yyyy年MM月dd日
|
||||
vue.filter("dateFormat4", function (value) {
|
||||
if (value == null) return null;
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "年" : "年0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "月" : "月0") + value.getDate() + "日";
|
||||
});
|
||||
|
||||
//null??"-"
|
||||
vue.filter("nullFormat", function (value) {
|
||||
return (value == null || value == undefined || value == '') ? "-" : value;
|
||||
});
|
||||
//0.00
|
||||
vue.filter("roundFormat", function (value) {
|
||||
if (value == null || isNaN(value)) return null;
|
||||
return value.toFixed(2);
|
||||
});
|
||||
//yyyy-MM-dd
|
||||
vue.filter("shortDateFormat", function (value) {
|
||||
if (value == null || value == '') return '-';
|
||||
value = new Date(value);
|
||||
return value.getFullYear() + (value.getMonth() + 1 > 9 ? "-" : "-0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "-" : "-0") + value.getDate();
|
||||
});
|
||||
|
||||
//00:00:00
|
||||
vue.filter("shortTimeFormat", function (value) {
|
||||
if (value == null) return null;
|
||||
value = new Date(value);
|
||||
return (value.getHours() > 9 ? "" : "0") + value.getHours() + (value.getMinutes() > 9 ? ":" : ":0") + value.getMinutes() + (value.getSeconds() > 9 ? ":" : ":0") + value.getSeconds();
|
||||
});
|
||||
|
||||
//字数太多显示不全...
|
||||
vue.filter("partStringFormat", function (value, count = 10) {
|
||||
if (value == null) return null;
|
||||
if (value.length <= count) {
|
||||
return value;
|
||||
}
|
||||
if (value.length > count) {
|
||||
return value.substring(0, count) + '...'
|
||||
}
|
||||
});
|
||||
|
||||
//判断是否初始化时间字段,若是则返回空串
|
||||
vue.filter("iNitStringFormat", function (value) {
|
||||
if (value == "null") return null;
|
||||
if (value == "0001-01-01T00:00:00+08:00") {
|
||||
value = "";
|
||||
} else {
|
||||
value = new Date(value);
|
||||
value = value.getFullYear() + (value.getMonth() + 1 > 9 ? "-" : "-0") + (value.getMonth() + 1) + (value.getDate() > 9 ? "-" : "-0") + value.getDate() + " " + (value.getHours() > 9 ? "" : "0") + value.getHours() + (value.getMinutes() > 9 ? ":" : ":0") + value.getMinutes() + (value.getSeconds() > 9 ? ":" : ":0") + value.getSeconds();
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
vue.filter("phoneHide", function (value) {
|
||||
if (isNaN(Number(value))) return value;
|
||||
if (!value) return '-';
|
||||
var rega = new RegExp("(\\w{3})\\w{" + (value.trim().length - 7) + "}(\\w{4})", "ig");
|
||||
return value = value.replace(rega, '$1****$2');
|
||||
});
|
||||
173
src/extend/js/localStorage.js
Normal file
173
src/extend/js/localStorage.js
Normal file
@@ -0,0 +1,173 @@
|
||||
|
||||
var _setCache=(str)=> {//1支持多用户登录同端,2处理个别浏览器缓存未清理干净
|
||||
let _managerId = 0
|
||||
_managerId=window.localStorage.getItem('unique_login');//唯一登录标识
|
||||
return `${str}_${_managerId}`
|
||||
};
|
||||
export default {
|
||||
setUserCache(data){//设置登录用户信息缓存
|
||||
let _unique_login=data.Manager.ID+data.Manager.Logincode
|
||||
let _cacheName=`etorcurrentuser_${_unique_login}`
|
||||
window.localStorage.setItem( _cacheName, JSON.stringify(data));
|
||||
window.localStorage.setItem('unique_login', _unique_login);
|
||||
window.localStorage.setItem("etorcurrentuser",JSON.stringify(data));//兼容未使用公共方法的页面
|
||||
},
|
||||
getUserByCache: function () {//获取用户信息缓存
|
||||
let _cacheName=_setCache("etorcurrentuser")
|
||||
var str= window.localStorage.getItem(_cacheName);
|
||||
return JSON.parse(str);
|
||||
},
|
||||
setMenus(data){
|
||||
let _cacheName="pmenus"
|
||||
window.localStorage.setItem( _cacheName, JSON.stringify(data));
|
||||
},
|
||||
getMenus(){
|
||||
let _cacheName="pmenus"
|
||||
var str= window.localStorage.getItem(_cacheName);
|
||||
return JSON.parse(str);
|
||||
},
|
||||
isRoot: function () {//是否超级管理员
|
||||
var currentUser=this.getUserByCache();
|
||||
var isRoot=currentUser.Manager.IsRootUser;
|
||||
return isRoot;
|
||||
},
|
||||
freshToken(type) {
|
||||
//刷新token
|
||||
// 0刷新过期时间,1刷新管理小区
|
||||
let etorcurrentuser=this.getUserByCache()
|
||||
newapi
|
||||
.AgainGetToken({ Token: etorcurrentuser.Token, Type: type })
|
||||
.then(res => {
|
||||
if (res.Code == 10000) {
|
||||
console.log(`刷新token成功`);
|
||||
etorcurrentuser.Token = res.Data;
|
||||
this.setUserCache(etorcurrentuser)
|
||||
}
|
||||
})
|
||||
.catch(res => { });
|
||||
},
|
||||
arr: [],
|
||||
dbclick: function (tag) {
|
||||
var img_obj = document.getElementsByClassName(tag);
|
||||
var body = document.getElementsByTagName("body")[0];
|
||||
var obj_arr = new Array();
|
||||
var img_arr = new Array();
|
||||
var nowindex = 0;
|
||||
for (var i = 0; i < img_obj.length; i++) {
|
||||
obj_arr.push(img_obj[i]);
|
||||
img_arr.push(img_obj[i].getAttribute("src"));
|
||||
img_obj[i].ondblclick = function () {
|
||||
var nowurl = this.getAttribute("src");
|
||||
//获取到当前点击是第几个元素
|
||||
for (var t = 0; t < img_arr.length; t++) {
|
||||
if (img_arr[t] == nowurl) nowindex = t;
|
||||
}
|
||||
var cover_div = document.createElement("div");
|
||||
var center_div = document.createElement("div");
|
||||
var img_box = document.createElement("div");
|
||||
var leftspan = document.createElement("span");
|
||||
var rightspan = document.createElement("span");
|
||||
|
||||
cover_div.className = "cover-div";
|
||||
center_div.className = "center-div";
|
||||
img_box.className = "readimg_box";
|
||||
leftspan.className = "leftspan";
|
||||
rightspan.className = "rightspan";
|
||||
|
||||
center_div.appendChild(img_box);
|
||||
body.appendChild(cover_div);
|
||||
body.appendChild(center_div);
|
||||
body.appendChild(leftspan);
|
||||
body.appendChild(rightspan);
|
||||
//外层div点击的时候,删除
|
||||
cover_div.onclick = function () {
|
||||
body.removeChild(cover_div);
|
||||
body.removeChild(leftspan);
|
||||
body.removeChild(rightspan);
|
||||
body.removeChild(center_div);
|
||||
center_div.removeChild(img_box);
|
||||
};
|
||||
//添加图片
|
||||
|
||||
for (var n = 0; n < img_arr.length; n++) {
|
||||
var oimg = document.createElement("img");
|
||||
oimg.className = "img_cover";
|
||||
oimg.src = img_arr[n];
|
||||
img_box.appendChild(oimg);
|
||||
}
|
||||
img_box.style.marginLeft = -nowindex * 500 + "px";
|
||||
rightspan.onclick = function () {
|
||||
nowindex++;
|
||||
if (nowindex >= img_arr.length - 1) {
|
||||
nowindex = img_arr.length - 1;
|
||||
}
|
||||
img_box.style.marginLeft = -nowindex * 500 + "px";
|
||||
};
|
||||
leftspan.onclick = function () {
|
||||
//console.log(img_arr.length - 1);
|
||||
//console.log(nowindex);
|
||||
nowindex--;
|
||||
if (nowindex <= 0) {
|
||||
nowindex = 0;
|
||||
}
|
||||
|
||||
img_box.style.marginLeft = -nowindex * 500 + "px";
|
||||
};
|
||||
};
|
||||
}
|
||||
},
|
||||
uploadimg: function () {
|
||||
var input = document.createElement("input");
|
||||
input.setAttribute("type", "file");
|
||||
var event = document.createEvent("MouseEvents");
|
||||
event.initMouseEvent(
|
||||
"click",
|
||||
false,
|
||||
true,
|
||||
window,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
null
|
||||
);
|
||||
input.dispatchEvent(event);
|
||||
// this.makebase64()
|
||||
var that = this;
|
||||
// console.log(that.makebase64)
|
||||
input.onchange = function (e) {
|
||||
var f = input.files[0];
|
||||
console.log("e");
|
||||
console.log(e);
|
||||
console.log("input.files");
|
||||
console.log(f.name);
|
||||
console.log(f.size / 1024);
|
||||
// if(f.name)
|
||||
if (f.size / 1024 > 2048) {
|
||||
// alert('图片大小不能超过2m')
|
||||
// Message({
|
||||
// type: 'error',
|
||||
// message: '图片大小不能超过2m'
|
||||
// })
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
console.log("reader1");
|
||||
console.log(reader);
|
||||
reader.readAsDataURL(f);
|
||||
console.log("reader");
|
||||
console.log(reader);
|
||||
reader.onloadend = function (e) {
|
||||
e = window.event || e;
|
||||
|
||||
var imgbase = e.target.result;
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
2149
src/extend/js/menus.js
Normal file
2149
src/extend/js/menus.js
Normal file
File diff suppressed because it is too large
Load Diff
27
src/extend/js/messageTip.js
Normal file
27
src/extend/js/messageTip.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import vue from 'vue';
|
||||
vue.prototype.$error = function(text){
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: text
|
||||
})
|
||||
}
|
||||
|
||||
vue.prototype.$info = function(text){
|
||||
this.$message({
|
||||
type: "info",
|
||||
message: text
|
||||
})
|
||||
}
|
||||
|
||||
vue.prototype.$warn = function(text){
|
||||
this.$message({
|
||||
type: "warning",
|
||||
message: text
|
||||
})
|
||||
}
|
||||
vue.prototype.$success = function(text){
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: text
|
||||
})
|
||||
}
|
||||
234
src/extend/js/newMenus.js
Normal file
234
src/extend/js/newMenus.js
Normal file
@@ -0,0 +1,234 @@
|
||||
export var menus = [
|
||||
{
|
||||
"Id": 1,
|
||||
"Permissionlabel": "概况总览",
|
||||
"Permissionurl": "/store/index",
|
||||
"Icon": "icon-gaikuang",
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Permissionlabel": "店铺管理",
|
||||
"Permissionurl": "",
|
||||
"Icon": "icon-zhuangxiu",
|
||||
"Children": [
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "设计",
|
||||
"Permissionurl": "/d",
|
||||
"target":"_blank"
|
||||
},
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "设置",
|
||||
"Permissionurl": "/store/setting",
|
||||
}]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"Permissionlabel": "课程管理",
|
||||
"Permissionurl": "",
|
||||
"Icon": "icon-kecheng" ,
|
||||
"Children": [
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "录播课程",
|
||||
"Permissionurl": "/course/list",
|
||||
},
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "直播课程",
|
||||
"Permissionurl": "/course/live",
|
||||
},
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "课程套餐",
|
||||
"Permissionurl": "/course/package",
|
||||
},
|
||||
{
|
||||
"Id": 10049,
|
||||
"Permissionlabel": "音视频库",
|
||||
"Permissionurl": "/course/asset",
|
||||
},
|
||||
{
|
||||
"Id": 10093,
|
||||
"Permissionlabel": "课程评论",
|
||||
"Permissionurl": "/course/comment",
|
||||
"Icon": "icon-fuwuguanli",
|
||||
"Iconactivate": "icon-fuwuguanli_xuanzhong",
|
||||
},
|
||||
{
|
||||
"Id": 10050,
|
||||
"Permissionlabel": "学习记录",
|
||||
"Permissionurl": "/course/learn",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"Permissionlabel": "题库管理",
|
||||
"Permissionurl": "",
|
||||
"Icon": "icon-zhuxue",
|
||||
"Children": [
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "科目",
|
||||
"Permissionurl": "/questions/subject",
|
||||
},
|
||||
{
|
||||
"Id": 23,
|
||||
"Permissionlabel": "考点",
|
||||
"Permissionurl": "/questions/examsite",
|
||||
},
|
||||
{
|
||||
"Id": 10049,
|
||||
"Permissionlabel": "试题",
|
||||
"Permissionurl": "/questions/question",
|
||||
},
|
||||
{
|
||||
"Id": 10093,
|
||||
"Permissionlabel": "试卷",
|
||||
"Permissionurl": "/questions/paper",
|
||||
"Icon": "icon-fuwuguanli",
|
||||
"Iconactivate": "icon-fuwuguanli_xuanzhong",
|
||||
},
|
||||
{
|
||||
"Id": 10050,
|
||||
"Permissionlabel": "考试",
|
||||
"Permissionurl": "/questions/exam",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 30001,
|
||||
"Permissionlabel": "订单管理",
|
||||
"Permissionurl": "",
|
||||
"Icon": "icon-shuju",
|
||||
"Children": [
|
||||
{
|
||||
"Id": 10099,
|
||||
"Permissionlabel": "订单概况",
|
||||
"Permissionurl": "/order/index",
|
||||
"Icon": "icon-shebeiguanli",
|
||||
"Iconactivate": "icon-shebeiguanli_xuanzhong",
|
||||
},
|
||||
|
||||
{
|
||||
"Id": 10099,
|
||||
"Permissionlabel": "课程订单",
|
||||
"Permissionurl": "/order/courseorder",
|
||||
"Icon": "icon-shebeiguanli",
|
||||
"Iconactivate": "icon-shebeiguanli_xuanzhong",
|
||||
},
|
||||
{
|
||||
"Id": 10053,
|
||||
"Permissionlabel": "套餐订单",
|
||||
"Permissionurl": "/order/packageorder",
|
||||
"Icon": null,
|
||||
|
||||
},
|
||||
{
|
||||
"Id": 10054,
|
||||
"Permissionlabel": "拼团订单",
|
||||
"Permissionurl": "/order/grouporder",
|
||||
},
|
||||
{
|
||||
"Id": 10100,
|
||||
"Permissionlabel": "直播订单",
|
||||
"Permissionurl": "/order/liveorder",
|
||||
},
|
||||
{
|
||||
"Id": 10100,
|
||||
"Permissionlabel": "题库订单",
|
||||
"Permissionurl": "/order/questionorder",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"Permissionlabel": "营销中心",
|
||||
"Permissionurl": "",
|
||||
"Icon": "icon-zhuxue",
|
||||
"Children": [
|
||||
{
|
||||
"Id": 138,
|
||||
"Permissionlabel": "推销员",
|
||||
"Permissionurl": "/sell/seller",
|
||||
},
|
||||
{
|
||||
"Id": 10159,
|
||||
"Permissionlabel": "兑换码",
|
||||
"Permissionurl": "/sell/redeemcode",
|
||||
},
|
||||
{
|
||||
"Id": 12,
|
||||
"Permissionlabel": "优惠券",
|
||||
"Permissionurl": "/sell/coupon",
|
||||
},
|
||||
{
|
||||
"Id": 12,
|
||||
"Permissionlabel": "吸粉器",
|
||||
"Permissionurl": "/sell/fans",
|
||||
},
|
||||
{
|
||||
"Id": 10056,
|
||||
"Permissionlabel": "支付有礼",
|
||||
"Permissionurl": "/sell/payaward",
|
||||
},
|
||||
{
|
||||
"Id": 138,
|
||||
"Permissionlabel": "弹窗广告",
|
||||
"Permissionurl": "/sell/popad",
|
||||
},
|
||||
{
|
||||
"Id": 138,
|
||||
"Permissionlabel": "好友助力",
|
||||
"Permissionurl": "/sell/help",
|
||||
},
|
||||
{
|
||||
"Id": 138,
|
||||
"Permissionlabel": "限时折扣",
|
||||
"Permissionurl": "/sell/timediscount",
|
||||
} ,
|
||||
{
|
||||
"Id": 138,
|
||||
"Permissionlabel": "裂变海报",
|
||||
"Permissionurl": "/sell/fission",
|
||||
} ,
|
||||
{
|
||||
"Id": 10159,
|
||||
"Permissionlabel": "工具",
|
||||
"Permissionurl": "/sell/index",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 9999,
|
||||
"Permissionlabel": "设置",
|
||||
"Permissionurl": "",
|
||||
"Icon": "icon-shezhi",
|
||||
"Children": [
|
||||
{
|
||||
"Id": 10042,
|
||||
"Permissionlabel": "员工管理",
|
||||
"Permissionurl": "/setting/managerlist",
|
||||
},
|
||||
{
|
||||
"Id": 22,
|
||||
"Permissionlabel": "系统通知",
|
||||
"Permissionurl": "/setting/sysNotice",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"Permissionlabel": "资讯管理",
|
||||
"Permissionurl": "/article/list",
|
||||
"Icon": "icon-jiaoyi"
|
||||
},
|
||||
{
|
||||
"Id": 10000,
|
||||
"Permissionlabel": "用户中心",
|
||||
"Permissionurl": "users",
|
||||
"Icon": "icon-yonghu",
|
||||
}
|
||||
]
|
||||
25
src/extend/js/permission.js
Normal file
25
src/extend/js/permission.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
function getPermission(permission, permissionObj) {
|
||||
if (!permissionObj) return true;
|
||||
|
||||
if (permission instanceof Array) return permission.find(item => {
|
||||
return permissionObj[item]
|
||||
});
|
||||
return permissionObj[permission];
|
||||
}
|
||||
|
||||
function permissionInit(value) {
|
||||
let items = ['AllowView', 'AllowAdd', 'AllowEdit', 'AllowDel'];
|
||||
let _items = ['allowView', 'allowAdd', 'allowEdit', 'allowDel'];
|
||||
let permission = [];
|
||||
items.forEach(function (item) {
|
||||
permission.push(getPermission(item,value));
|
||||
});
|
||||
permission.forEach(function (item, index) {
|
||||
Vue.prototype[_items[index]] = item;
|
||||
// console.log(_items[index], item);
|
||||
});
|
||||
|
||||
}
|
||||
export default permissionInit
|
||||
15
src/extend/js/treeDataTransfer.js
Normal file
15
src/extend/js/treeDataTransfer.js
Normal file
@@ -0,0 +1,15 @@
|
||||
export default function convertTree(root) {
|
||||
var that=this;
|
||||
var newRoot=root.Data;
|
||||
if(root.Children&&root.Children.length>0){
|
||||
var children=[];
|
||||
root.Children.forEach(function (child){
|
||||
var newChild=convertTree(child);
|
||||
children.push(newChild);
|
||||
});
|
||||
newRoot.children=children
|
||||
}else{
|
||||
newRoot.children=[];
|
||||
}
|
||||
return newRoot;
|
||||
}
|
||||
156
src/extend/js/utils.js
Normal file
156
src/extend/js/utils.js
Normal file
@@ -0,0 +1,156 @@
|
||||
import vue from "vue";
|
||||
import {
|
||||
MessageBox
|
||||
} from 'element-ui';
|
||||
|
||||
vue.prototype.$makeSure = function (fn, message, title) {
|
||||
try {
|
||||
message = message || '您确定要执行此操作吗';
|
||||
title = title || '温馨提示';
|
||||
MessageBox.confirm(message, title).then(() => {
|
||||
fn();
|
||||
}).catch(() => {});
|
||||
} catch (e) {
|
||||
debugger
|
||||
}
|
||||
};
|
||||
//vue.prototype.$upload = http_upload_picture; //global variable
|
||||
vue.prototype.$getPageSize = function (num) {
|
||||
var winHeight = document.documentElement.clientHeight;
|
||||
// 菜单高62 分页72 page_content的上下padding合30 表头高44 其他内容占据高度num
|
||||
var size = parseInt((winHeight - 62 - 44 - 72 - 30 - num) / 44);
|
||||
size = size <= 1 ? 1 : size
|
||||
//三目运算的判断
|
||||
return size;
|
||||
};
|
||||
vue.prototype.$getStyleHeight = function (num, flag=true) {
|
||||
var winHeight = document.documentElement.clientHeight;
|
||||
|
||||
// 菜单高62 page_content的上下padding合30 其他内容占据高度num
|
||||
var size = parseInt(winHeight - 56 - 15 - num)
|
||||
if (flag) {
|
||||
return {
|
||||
'height': size + 'px',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
'min-height': size + 'px',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
vue.prototype.$getHeight = function (num, flag) {
|
||||
var winHeight = document.documentElement.clientHeight;
|
||||
var size = parseInt(winHeight - 62 - 30 - num)
|
||||
size < 0 && (size = 0);
|
||||
return size + 'px';
|
||||
};
|
||||
|
||||
vue.prototype.$addstyle = function (arr, id) {
|
||||
arr.forEach(element => {
|
||||
var link = document.createElement('link');
|
||||
link.setAttribute("rel", "stylesheet");
|
||||
link.setAttribute("id", id);
|
||||
link.href = element;
|
||||
document.getElementsByTagName("head")[0].appendChild(link)
|
||||
}, this);
|
||||
};
|
||||
|
||||
vue.prototype.$addscript = function (url, callback) {
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
// arr.forEach(element => {
|
||||
var script = document.createElement('script');
|
||||
script.setAttribute('style', 'type/javascript');
|
||||
script.setAttribute('id', 'echarts2');
|
||||
script.src = url;
|
||||
head.appendChild(script)
|
||||
if (typeof (callback) != "undefined") {
|
||||
if (script.readyState) {
|
||||
script.onreadystatechange = function () {
|
||||
if (script.readyState == "loaded" || script.readyState == "complete") {
|
||||
script.onreadystatechange = null;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
script.onload = function () {
|
||||
callback();
|
||||
};
|
||||
}
|
||||
}
|
||||
// }, this)
|
||||
};
|
||||
//获取本日、本周、本月、本年的时间
|
||||
vue.prototype.$getTime = (idx) => {
|
||||
!idx && (idx = 0);
|
||||
let date = new Date(new Date().setHours(23, 59, 59, 0));
|
||||
let year = date.getFullYear(),
|
||||
month = date.getMonth() + 1,
|
||||
day = date.getDate();
|
||||
switch (idx) {
|
||||
case 0: //本日
|
||||
return [new Date(year, month, day), date]
|
||||
case 1: //本周
|
||||
let week = date.getDay();
|
||||
week == 0 && (week = 7);
|
||||
let time = new Date(new Date().setHours(0, 0, 0, 0));
|
||||
time.setDate(day - week + 1);
|
||||
return [new Date(time), date]
|
||||
case 2: //本月
|
||||
return [new Date(year, month, '1'), date]
|
||||
case 3: //本年
|
||||
return [new Date(year + '-01-01'), date]
|
||||
}
|
||||
};
|
||||
vue.prototype.empty = '--';
|
||||
vue.prototype.maxPageSize = 2000;
|
||||
vue.prototype.camelCase=function(str='none',smallCamelCase=true){
|
||||
str=str.toString();
|
||||
if(str.toLowerCase()=='id') return smallCamelCase?'id':'ID';
|
||||
return smallCamelCase?str[0].toLowerCase()+str.slice(1):str[0].toUpperCase()+str.slice(1);
|
||||
};
|
||||
vue.prototype.camelCaseData=function(data,smallCamelCase=true){
|
||||
let agent={};
|
||||
let that=this;
|
||||
Object.keys(data).forEach(function(key){
|
||||
agent[that.camelCase(key,smallCamelCase)]=data[key];
|
||||
});
|
||||
return agent;
|
||||
}
|
||||
vue.prototype.$uuid=function(length){
|
||||
return Number(Math.random().toString().substr(3,length) + Date.now()).toString(36);
|
||||
}
|
||||
|
||||
String.prototype.toJson = function () {
|
||||
return JSON.parse(this);
|
||||
}
|
||||
String.prototype.isEmpty = function () {
|
||||
if (this == null || this == undefined || this.trim() == "") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
String.prototype.DateFormat = function (fmt) {
|
||||
var dt = new Date(this);
|
||||
return dt.Format(fmt);
|
||||
}
|
||||
Date.prototype.Format = function (fmt) { //author: meizz
|
||||
var o = {
|
||||
"M+": this.getMonth() + 1, //月份
|
||||
"d+": this.getDate(), //日
|
||||
"h+": this.getHours(), //小时
|
||||
"m+": this.getMinutes(), //分
|
||||
"s+": this.getSeconds(), //秒
|
||||
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
|
||||
"S": this.getMilliseconds() //毫秒
|
||||
};
|
||||
if (/(y+)/.test(fmt))
|
||||
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
|
||||
for (var k in o)
|
||||
if (new RegExp("(" + k + ")").test(fmt))
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
|
||||
return fmt;
|
||||
}
|
||||
Window.prototype.clone=function(data){
|
||||
return JSON.parse(JSON.stringify(data));
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user