Commit 673feb90 by 高淑倩

add:layout

parent 5a5be2ab
......@@ -8,11 +8,5 @@
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
......@@ -2,4 +2,3 @@
/config/
/dist/
/*.js
/test/unit/coverage/
......@@ -4,9 +4,6 @@ node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
/test/unit/coverage/
/test/e2e/reports/
selenium-debug.log
# Editor directories and files
.idea
......
......@@ -95,7 +95,7 @@ exports.createNotifierCallback = () => {
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'icon-person.png')
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
// const ExtractTextPlugin = require('extract-text-webpack-plugin');
//
// // // 创建多个实例
// const extractCSS = new ExtractTextPlugin('stylesheets/[name]-[contenthash].css');
// const extractLESS = new ExtractTextPlugin('stylesheets/[name]-[contenthash].less.css');
// const extractSASS = new ExtractTextPlugin('stylesheets/[name]-[contenthash].scss.css');
function resolve (dir) {
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
......@@ -22,31 +15,32 @@ const createLintingRule = () => ({
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
emitWarning: !config.dev.showEslintErrorsInOverlay,
},
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
app: './src/main.js',
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
chunkFilename: '[name].[hash:7].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',
vue$: 'vue/dist/vue.esm.js',
'@': resolve('src'),
'assets': resolve('src/assets'),
// 'views': resolve('src/views'),
// 'components': resolve('src/components')
}
api: resolve('src/api'),
assets: resolve('src/assets'),
pages: resolve('src/pages'),
common: resolve('src/common'),
components: resolve('src/components'),
},
},
module: {
rules: [
......@@ -54,38 +48,38 @@ module.exports = {
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
options: vueLoaderConfig,
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
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]')
}
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]')
}
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]')
}
name: utils.assetsPath('fonts/[name].[hash:7].[ext]'),
},
},
]
],
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
......@@ -97,13 +91,6 @@ module.exports = {
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
// plugins: [
// new webpack.optimize.CommonsChunkPlugin('common.js'),
// new webpack.ProvidePlugin({
// jQuery: "jquery",
// $: "jquery"
// })
// ]
child_process: 'empty',
},
}
......@@ -5,12 +5,10 @@ const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const dev = require('../config/dev.env')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
......@@ -22,7 +20,7 @@ const devWebpackConfig = merge(baseWebpackConfig, {
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/baseHttp.js
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
......@@ -47,11 +45,8 @@ const devWebpackConfig = merge(baseWebpackConfig, {
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': merge(dev, {
host:`'//localhost:${PORT || config.dev.port}/api'`
})
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
......@@ -69,8 +64,7 @@ const devWebpackConfig = merge(baseWebpackConfig, {
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
]),
new ExtractTextPlugin('css/[name].css?[contenthash]')
])
]
})
......
......@@ -11,9 +11,8 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
......@@ -24,9 +23,8 @@ const webpackConfig = merge(baseWebpackConfig, {
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: path.resolve(__dirname, `../dist/${env.baseUrl.replace(/['"]/g,"")}/${env.url.replace(/['"]/g,"")}`),//config.build.assetsRoot,
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
publicPath:['',env.baseUrl.replace(/['"]/g,""),env.url.replace(/['"]/g,""),''].join('/'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
......@@ -37,7 +35,6 @@ const webpackConfig = merge(baseWebpackConfig, {
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console:true,
warnings: false
}
},
......@@ -49,7 +46,7 @@ const webpackConfig = merge(baseWebpackConfig, {
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`,
// 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,
}),
......@@ -64,9 +61,7 @@ const webpackConfig = merge(baseWebpackConfig, {
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: path.resolve(__dirname, `../dist/${env.baseUrl.replace(/['"]/g,"")}/${env.url.replace(/['"]/g,"")}/index.html`),
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
......@@ -123,6 +118,7 @@ const webpackConfig = merge(baseWebpackConfig, {
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
......
module.exports = {
"preProduct": {
"host":"//10.0.16.179:8080",
"url":"minapro",
"baseUrl":"vue"
},
"product": {
"host":"//wxapp.hotwind.net",
"baseUrl":"vue",
"url":"minapro"
},
"devProduct": {
"host":"//wxapp.hotwind.net",
"baseUrl":"vue",
"url":"mina"
}
}
module.exports = {
config: [{
project: '',
requestUrl: ''
}]
}
\ No newline at end of file
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
'NODE_ENV': "'development'",
'host': "'//localhost'",
'requestUrl': "''",
'project': "''"
NODE_ENV: '"development"'
})
......@@ -10,16 +10,7 @@ module.exports = {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: '', // 接口的域名
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
pathRewrite: {
'^/api': ''
}
}
},
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
......@@ -59,8 +50,7 @@ module.exports = {
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
// assetsPublicPath: '/minapro/vue/', // '/minapro/vue/'
assetsPublicPath: '',
assetsPublicPath: '/',
/**
* Source Maps
......
module.exports = {
"host": "''",
"project": "''",
"requestUrl": "''"
}
'use strict'
const configRequest = require('./config.request')
const yargs = require('yargs').argv
const env = yargs.env
let path = './prod.prod.env'
if (env === 'dev') {
path = './prod.dev.env'
} else if (env === 'uat') {
path = './prod.uat.env'
}
const envConfig = require(path)
module.exports = {
NODE_ENV: '"production"',
configRequest: JSON.stringify(configRequest),
...envConfig
NODE_ENV: '"production"'
}
module.exports = {
"host": "''",
"project": "''",
"requestUrl": "''"
}
module.exports = {
"host": "''",
"project": "''",
"requestUrl": "'minapro'"
}
'use strict'
const merge = require('webpack-merge')
const devEnv = require('./dev.env')
module.exports = merge(devEnv, {
NODE_ENV: '"testing"'
})
......@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>热风断码调货小程序后台管理系统</title>
<title>vue-new-template</title>
</head>
<body>
<div id="app"></div>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "hotwind-manage",
"name": "vue-new-template",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "汤强勇 <tangqy@bigaka.com>",
"author": "",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
"lint:fix": "eslint --ext .js,.vue src test/unit test/e2e/specs --fix",
"build:dev": "node build/build.js --env=dev",
"build:uat": "node build/build.js --env=uat",
"build": "node build/build.js --env=prod"
"lint": "eslint --fix --ext .js,.vue src",
"build": "node build/build.js"
},
"dependencies": {
"axios": "^0.18.0",
"es6-promise": "^4.2.4",
"moment": "^2.22.2",
"ramda": "^0.25.0",
"rxjs": "^6.2.1",
"underscore": "^1.9.1",
"validate": "^4.4.1",
"vee-validate": "^2.0.9",
"element-ui": "^2.4.9",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vue-rx": "^6.0.0",
"vuex": "^3.0.1",
"vuex-router-sync": "^5.0.0"
"vuex": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-jest": "^21.0.2",
"babel-loader": "^7.1.1",
"babel-plugin-component": "^1.1.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"chromedriver": "^2.27.2",
"copy-webpack-plugin": "^4.0.1",
"cross-spawn": "^5.0.1",
"css-loader": "^0.28.11",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
......@@ -65,14 +44,8 @@
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"jest": "^22.0.4",
"jest-serializer-vue": "^0.3.0",
"json5-loader": "^1.0.1",
"less": "^3.0.4",
"less-loader": "^4.1.0",
"nightwatch": "^0.9.12",
"moment": "^2.22.2",
"node-notifier": "^5.1.2",
"node-sass": "^4.9.0",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
......@@ -80,22 +53,19 @@
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"sass-loader": "^7.0.3",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"style-loader": "^0.21.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-jest": "^1.0.2",
"vue-loader": "^13.3.0",
"vue-style-loader": "^4.1.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",
"yargs": "^12.0.1"
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
......@@ -106,4 +76,4 @@
"last 2 versions",
"not ie <= 8"
]
}
\ No newline at end of file
}
# common-templete
# vue-new-template
> A Vue.js project
......@@ -16,17 +16,6 @@ npm run build
# build for production and view the bundle analyzer report
npm run build --report
# run unit tests
npm run unit
# run e2e tests
npm run e2e
# run all tests
npm test
# dq
```
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).
<template>
<div id="app">
app work!!!
<transition name="bounce">
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
<router-view />
</div>
</template>
<style lang="scss">
@import "~@/assets/scss/main";
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
@charset "utf-8";html{background-color:#fff;color:#000;font-size:12px}
body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding:0}
body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{font-size:100%}
h1,h2,h3,h4,h5,h6{font-family:tahoma,arial,"Hiragino Sans GB","微软雅黑",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,b,strong{font-weight:normal}
address,cite,dfn,em,i,optgroup,var{font-style:normal}
table{border-collapse:collapse;border-spacing:0;text-align:left}
caption,th{text-align:inherit}
ul,ol,menu{list-style:none}
fieldset,img{border:0}
img,object,input,textarea,button,select{vertical-align:middle}
article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{display:block}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
blockquote:before,blockquote:after,q:before,q:after{content:"\0020"}
textarea{overflow:auto;resize:vertical}
input,textarea,button,select,a{outline:0 none;border: none;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
mark{background-color:transparent}
a,ins,s,u,del{text-decoration:none}
sup,sub{vertical-align:baseline}
html {overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
body {font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
hr {height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
a {color: #25a4bb;text-decoration: none;}
<template>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<i class="el-icon-menu"></i>
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropdown-item>
<el-dropdown-item>新增</el-dropdown-item>
<el-dropdown-item>删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>王小虎</span>
</el-header>
</el-container>
</template>
<style>
.el-header {
background-color: gray;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
<template>
<div class="hello">
<h1>{{ msg }}{{count}}</h1>
<h2>Essential Links</h2>
</div>
</template>
<script>
// import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent } from 'rxjs';
// import { map, filter, scan } from 'rxjs/operators';
// import { webSocket } from 'rxjs/webSocket';
// import { ajax } from 'rxjs/ajax';
// import { TestScheduler } from 'rxjs/testing';
import { merge } from 'rxjs'
import { map, startWith, scan } from 'rxjs/operators'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
// declare the receiving Subjects
domStreams: ['plus$', 'minus$'],
subscriptions () {
// ...then create subscriptions using the Subjects as source stream.
// the source stream emits in the format of `{ event: HTMLEvent, data?: any }`
return {
count: merge(
this.plus$.pipe(map(() => 1)),
this.minus$.pipe(map(() => -1))
).pipe(
startWith(0),
scan((total, change) => total + change)
)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
<template>
<el-main>
<el-table :data="dataList">
<el-table-column prop="id" label="id" width="140">
</el-table-column>
<el-table-column prop="push_state" label="状态" width="120">
</el-table-column>
<el-table-column prop="title" label="title">
</el-table-column>
<el-table-column label="time">
<template slot-scope="scope">
{{scope.row.push_time | fomatDate}}
</template>
</el-table-column>
</el-table>
</el-main>
</template>
<script>
export default {
data () {
return {
dataList: []
}
},
created () {
this.getDataList()
},
methods: {
getDataList () {
this.axios.get('/static/getStoreNoticeListByPageAction.json').then(res => {
if (res && res.data && res.data.data) {
const { dataList } = res.data.data
this.dataList = dataList
}
})
}
}
}
</script>
<style>
.el-main {
width: 100%;
}
</style>
<template>
<div class="materialist">
<el-carousel :interval="4000" type="card" height="200px" :autoplay="false" trigger="click" arrow="never">
<el-carousel-item v-for="(item, index) in MateriaList" :key="index">
<img :src="item.imgUrl">
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
data () {
return {
MateriaList: [
{
imgUrl: 'http://img.zcool.cn/community/0125fd5770dfa50000018c1b486f15.jpg@1280w_1l_2o_100sh.jpg'
},
{
imgUrl: 'http://img.zcool.cn/community/0125fd5770dfa50000018c1b486f15.jpg@1280w_1l_2o_100sh.jpg'
},
{
imgUrl: 'http://img.zcool.cn/community/0125fd5770dfa50000018c1b486f15.jpg@1280w_1l_2o_100sh.jpg'
},
{
imgUrl: 'http://img.zcool.cn/community/0125fd5770dfa50000018c1b486f15.jpg@1280w_1l_2o_100sh.jpg'
},
{
imgUrl: 'http://img.zcool.cn/community/0125fd5770dfa50000018c1b486f15.jpg@1280w_1l_2o_100sh.jpg'
}
]
}
}
}
</script>
<style lang="stylus" scoped>
.materialist
.el-carousel__item:nth-child(2n)
background-color #99a9bf
.el-carousel__item:nth-child(2n+1)
background-color #d3dce6
</style>
<template>
<div class="marketing-detail">
<div>
<div v-for="(item, index) in dataList" :key="index" class="detail-single">
<div class="detail-top">
<span class="top-name">{{item.name}}</span>
<div class="top-right">
<span class="top-time">{{item.time}}</span>
<span class="top-state">{{item.state}}</span>
</div>
</div>
<div class="detail-data">
<span class="">推送人数: {{item.num}}</span>
<span>推送成功: {{item.suc}}</span>
<span>{{item.type}}</span>
</div>
<div class="detail-node">
<span>创建推送节点: {{item.node}}</span>
</div>
</div>
</div>
<!-- <div class="marketing-total">
<span class="demonstration">显示总数</span>
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="currentPage1" :page-size="100" layout="total, prev, pager, next" :total="1000">
</el-pagination>
</div> -->
</div>
</template>
<script>
export default {
data () {
return {
currentPage1: 5,
dataList: []
}
},
created () {
this.GetPushDetail()
},
methods: {
GetPushDetail () {
this.axios.get('static/msg-mass.json').then(res => {
if (res && res.data) {
this.dataList = res.data.dataList
}
})
},
handleSizeChange (val) {
console.log(`每页 ${val} 条`)
},
handleCurrentChange (val) {
console.log(`当前页: ${val}`)
}
}
}
</script>
<style lang="stylus" scoped>
.marketing-detail
.detail-single
background-color #eee
padding 0px 10px
margin-bottom 10px
box-sizing border-box
float left
width 50%
.detail-top
.top-name, .top-right
display inline-block
height 40px
line-height 40px
.top-right
float right
.detail-data, .detail-node
height 40px
line-height 40px
</style>
<template>
<div class="push-detail">
<div class="detail-top">
<span>
<i class="el-icon-edit-outline"></i>
</span>
<span class="detail-title">推送详情</span>
</div>
<detail class="detail-info"></detail>
</div>
</template>
<script>
import Detail from './Detail'
export default {
components: {
Detail
}
}
</script>
<style lang="stylus" scoped>
.push-detail
background #fff
.detail-top
height 50px
line-height 50px
padding 0 15px
.detail-title
font-size 14px
</style>
<template>
<div class="sidebar">
<el-row>
<el-col :span="7">
<div class="sidebar-left" v-for="(item,index) in sidebarList" :key="item.routes.path">
<el-button @click="handleClick(index)" type="primary" icon="el-icon-service">{{index}}</el-button>
</div>
</el-col>
<el-col :span="16">
<el-menu :collapse-transition="false" class="sidebar-el-menu" :default-active="onRoutes" :collapse="collapse" unique-opened :router="true">
<el-submenu :index="item.path" v-for="item in menus" :key="item.path">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{item.title}}</span>
</template>
<el-menu-item v-for="subItem in item.children" :key="subItem.path" :index="subItem.path">{{subItem.title}}</el-menu-item>
</el-submenu>
</el-menu>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data () {
return {
collapse: false,
currentRouteIndex: 0,
sidebarList: [
{
routes: [
{
path: 'home',
title: '首页'
}
]
},
{
routes: [
{
path: 'home',
title: '精准营销',
children: [
{
path: 'marketing',
title: '营销推送'
},
{
path: 'addmarketing',
title: '推送详情'
}
]
}
]
}
],
menus: []
}
},
computed: {
onRoutes (e) {
console.log(1)
return this.$route.path.replace('/', '')
}
},
created () {
this.menus = this.sidebarList[this.currentRouteIndex].routes
},
methods: {
handleClick (index) {
this.currentRouteIndex = index
this.menus = this.sidebarList[this.currentRouteIndex].routes
}
}
}
</script>
<style lang="stylus" scoped>
.sidebar {
font-weight: lighter;
letter-spacing: 1px;
display: block;
position: absolute;
left: 0;
top: 0;
bottom: 0;
min-height: 720px;
width: 250px;
background-color: gray;
}
.sidebar-el-menu:not(.el-menu--collapse) {
width: 170px;
}
</style>
<template>
<el-tabs v-model="tabActive" type="card" @tab-click="handleClick">
<el-tab-pane label="图文素材消息" name="first">
<materia-list></materia-list>
<push-detail></push-detail>
</el-tab-pane>
<el-tab-pane label="营销模版消息" name="second">表格</el-tab-pane>
<el-tab-pane label="短信营销消息" name="third">表格</el-tab-pane>
</el-tabs>
</template>
<script>
import MateriaList from 'components/MateriaList'
import PushDetail from 'components/PushList'
export default {
data () {
return {
tabActive: 'first'
}
},
components: {
PushDetail,
MateriaList
},
methods: {
handleClick (tab, event) {
console.log(tab, event)
}
}
}
</script>
<template>
<div class="breadcrumb">
<el-row>
<el-col class="nav" :span="24">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item
:key="key"
v-for=" (value , key) in breadcrumbItems"
>{{ value }}</el-breadcrumb-item>
</el-breadcrumb>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'breadcrumb',
data () {
return {
}
},
created () {
},
computed: {
router () {
this.breadcrumbItems()
return this.$store.state.route
},
breadcrumbItems () {
let o = {}
this.$route.matched.map((item) => {
if (item.meta.title) {
const name = item.name
const title = item.meta.title
o[name] = title
}
})
return o
}
}
}
</script>
<style scoped>
.nav {
padding: 15px;
background: #f5f5f5;
}
</style>
import {
orderStatus as orderMixin,
logistics as logisticsMixin,
format,
calcPrice
} from './order'
export {
orderMixin,
format,
logisticsMixin,
calcPrice
}
export default {
methods: {
/**
* 计算选择的商品优惠价格
* @param activitys 商品
* @returns {*} 商品价格
*/
calcActivityPrice (activitys) {
activitys = activitys || []
return activitys.reduce((total, item) => {
const activityPrice = item.activityPrice || 0
total += activityPrice * item.count
return total
}, 0)
},
initSelection (rows) {
if (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row)
})
} else {
this.$refs.multipleTable.clearSelection()
}
}
}
}
import moment from 'moment'
export default {
methods: {
formatDate (date, format) {
let dateStr = ''
format = format || 'YYYY-MM-DD hh:mm:ss'
if (date) {
dateStr = moment(date).format(format)
}
return dateStr
}
}
}
import orderStatus from './orderStatus'
import logistics from './logistics'
import format from './formatDate'
import calcActivityPrice from './calcActivityPrice'
export {
orderStatus,
format,
logistics,
calcActivityPrice as calcPrice
}
export default {
data () {
return {
showLogisticsInfo: false
}
},
computed: {
expressInfo () {
return this.$store.getters.getExpress
}
},
methods: {
getExpress (order) {
if (!(order.logisticsBillno && order.logisticsCode)) {
return false
}
const params = {
logisticsCode: order.logisticsCode,
logisticsNo: order.logisticsBillno
}
this.$store.dispatch('getExpress', params)
},
showLogistics () {
this.showLogisticsInfo = true
}
}
}
export default {
methods: {
/**
* 获取订单状态
* @param order
* @param isReturnStatus 是否使用订单的returnStatus字段 (目前只有订单详情,订单列表使用returnStatus)
* @returns {string}
*/
orderStatus (order, isReturnStatus) {
// <c:if test="${order.orderStatus ==0 }">已取消</c:if> <c:if
// test="${order.orderStatus ==1 }">待付款</c:if> <c:if
// test="${order.orderStatus ==2 && order.returnStatus != 6}">待发货</c:if> <c:if
// test="${order.orderStatus ==3 && order.returnStatus != 6}">待收货</c:if> <c:if
// test="${order.orderStatus ==4 && order.returnStatus != 6}">已签收</c:if><c:if
// test="${order.returnStatus == 6}">已退款</c:if>
let orderStatus, orderReturnstatus
try {
orderStatus = `${order.orderStatus}`
orderReturnstatus = `${isReturnStatus ? order.returnStatus : order.orderReturnstatus}`
} catch (e) {
console.log(e)
orderStatus = ''
orderReturnstatus = ''
}
let status = ''
if (orderReturnstatus === '6') {
status = '已退款'
} else if (orderStatus === '0') {
status = '已取消'
} else if (orderStatus === '1') {
status = '待付款'
} else if (orderStatus === '2') {
status = '待发货'
} else if (orderStatus === '3') {
status = '待收货'
} else if (orderStatus === '4') {
status = '已签收'
}
// console.log('========== status ==========%o', status)
return status
},
returnOrderStates () {
return {
0: '无退货',
1: '待审核',
2: '待退款',
3: '已驳回',
4: '已取消',
5: '待收货',
6: '已完成',
7: '待退货'
}
},
returnOrderStatus (order, isReturnStatus) {
const status = isReturnStatus ? order.returnStatus : order.orderReturnStatus
const state = this.returnOrderStates()
return state[status]
},
showReTurnBtn (order) {
let showBtn = false
const status = this.orderStatus(order, true)
const state = this.returnOrderStatus(order, true)
if (state === '无退货') {
if (['待发货', '已签收'].indexOf(status) > -1) {
showBtn = true
}
}
return showBtn
}
}
}
<template>
<div class="order">
<section class="form-content">
<el-form :inline="true" :model="formInline" ref="formInline" class="demo-form-inline">
<el-form-item label="订单编号">
<el-input v-model="formInline.orderId" placeholder="请输入订单编号"></el-input>
</el-form-item>
<el-form-item label="订单状态:">
<el-select v-model="formInline.orderStatus" placeholder="请选择订单状态">
<el-option label="全部" value="-1"></el-option>
<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-option label="已退款" value="14"></el-option>
</el-select>
</el-form-item>
<el-form-item label="会员手机号">
<el-input v-model="formInline.customerMobile" placeholder="请输入会员手机号"></el-input>
</el-form-item>
<el-form-item label="快递单号">
<el-input v-model="formInline.logisticsBillno" placeholder="请输入快递单号"></el-input>
</el-form-item>
<el-form-item label="下单时间">
<el-date-picker
v-model="dateData"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="会员卡号">
<el-input v-model="formInline.custNo" placeholder="请输入会员卡号"></el-input>
</el-form-item>
<el-form-item label="下单门店">
<el-input v-model="formInline.storeName" placeholder="请输入下单门店号"></el-input>
</el-form-item>
<el-form-item label="客服备注">
<el-select v-model="formInline.remark" placeholder="请选择">
<el-option label="有备注" value="1"></el-option>
<el-option label="无备注" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
<el-button @click="resetForm()">重置</el-button>
</el-form-item>
</el-form>
</section>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="订单编号"
width="180">
<template slot-scope="scope">
<span >{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column
label="下单时间"
width="180">
<template slot-scope="scope">
<span >{{ formatDate(scope.row.createTime,'YYYY-MM-DD hh:mm:ss')}}</span>
</template>
</el-table-column>
<el-table-column
label="下单门店"
width="160">
<template slot-scope="scope">
<span >{{ scope.row.storeName }}</span>
</template>
</el-table-column>
<el-table-column
label="会员"
width="120">
<template slot-scope="scope">
<span >{{ scope.row.customerMobile }}</span>
</template>
</el-table-column>
<el-table-column
label="订单金额"
width="100">
<template slot-scope="scope">
<span>{{ scope.row.paidFee }}</span>
</template>
</el-table-column>
<el-table-column
label="微信支付单号"
width="180">
<template slot-scope="scope">
<span>{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column
label="快递单号"
width="140">
<template slot-scope="scope">
<span>{{ scope.row.logisticsBillno }}</span>
</template>
</el-table-column>
<el-table-column
label="备注信息"
width="100">
<template slot-scope="scope">
<span>{{ scope.row.remark }}</span>
</template>
</el-table-column>
<el-table-column
label="退货信息"
width="100">
<template slot-scope="scope">
<span>{{ returnOrderStatus(scope.row,true) }}</span>
</template>
</el-table-column>
<el-table-column
label="会员卡号"
width="160">
<template slot-scope="scope">
<span>{{ scope.row.custNo }}</span>
</template>
</el-table-column>
<el-table-column
label="订单状态"
width="80">
<template slot-scope="scope">
<!--<el-popover trigger="hover" placement="top">-->
<!--<p>姓名: {{ scope.row.name }}</p>-->
<!--<p>住址: {{ scope.row.address }}</p>-->
<!--<div slot="reference" class="name-wrapper">-->
<!--<el-tag size="medium">{{ scope.row.couponStatus }}</el-tag>-->
<!--</div>-->
<!--</el-popover>-->
<span>{{ orderStatus(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">详情</el-button>
<el-button v-if="showReTurnBtn(scope.row)"
size="mini"
type="danger"
@click="handleRetrun(scope.$index, scope.row)">退货</el-button>
</template>
</el-table-column>
</el-table>
<section>
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNo"
:page-sizes="[20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</section>
</div>
</template>
<script>
import { orderMixin, format } from '../mixin'
export default {
mixins: [orderMixin, format],
data () {
return {
pageNo: 1,
pageSize: 20,
formInline: {
orderId: '',
customerMobile: '',
logisticsBillno: '',
custNo: '',
storeName: '',
remark: '',
orderStatus: ''
},
dateData: []
}
},
created () {
this.$store.dispatch('getOrders', {pageNo: this.pageNo, pageSize: this.pageSize})
console.log(this)
},
computed: {
tableData () {
return this.$store.getters.getOrders
},
total () {
return this.$store.getters.getOrdersTotal
}
},
methods: {
handleEdit (index, row) {
console.log(index, row)
this.$router.push({
name: 'detail',
params: { id: row.id }
})
},
handleRetrun (index, row) {
this.$router.push({
name: 'returnOrderCreate',
params: { id: row.id }
})
},
handleSizeChange (val) {
this.pageSize = val
const params = this.getParmas()
this.$store.dispatch('getOrders', params)
},
handleCurrentChange (val) {
// console.log(`当前页: ${val}`)
this.pageNo = val
const params = this.getParmas()
this.$store.dispatch('getOrders', params)
},
resetPageNo () {
this.pageNo = 1
},
getParmas () {
const len = this.dateData.length
// theStartDate 下单时间
let theStartDate = len > 0 ? this.dateData[0] : ''
// theEndDate 结束时间
let theEndDate = len > 1 ? this.dateData[1] : ''
theStartDate = this.formatDate(theStartDate, 'YYYY-MM-DD')
theEndDate = this.formatDate(theEndDate, 'YYYY-MM-DD')
const params = {
pageNo: this.pageNo,
theStartDate,
theEndDate,
pageSize: this.pageSize,
...this.formInline
}
return params
},
onSubmit () {
this.resetPageNo()
const params = this.getParmas()
this.$store.dispatch('getOrders', params)
},
resetForm () {
this.formInline = {
orderId: '',
customerMobile: '',
logisticsBillno: '',
custNo: '',
storeName: '',
remark: '',
orderStatus: ''
}
this.dateData = []
}
}
}
</script>
<style scoped>
section {
margin-top: 20px;
}
</style>
<template>
<div class="order-setting">
<el-row>
<el-col :span="12">
<el-form ref="form" label-position="left" :model="form" label-width="120px">
<el-form-item label="下单送券">
<el-switch
:active-value="1"
:inactive-value="0"
v-model="form.sendCouponFlag"></el-switch>
</el-form-item>
<el-form-item label="优惠券code">
<el-row :gutter="20">
<el-col :span="10">
<el-input v-model.trim="couponCode"
placeholder="请输入优惠券code码"
clearable
@keyup.enter="addCouponCode()"
></el-input>
</el-col>
<el-col :span="2">
<el-button icon="el-icon-circle-plus-outline" type="primary" @click="addCouponCode()">添加优惠券</el-button>
</el-col>
</el-row>
<el-row style="margin-top: 20px;" :key="index" v-for="(code,index ) in couponCodes">
<el-col :span="8">
<el-button icon="el-icon-remove-outline" type="danger" @click="deleteCoupou(index)">{{code}}</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="下单限制">
<el-switch
:active-value="1"
:inactive-value="0"
v-model="form.inventoryLimitFlag"></el-switch>
</el-form-item>
<el-form-item>
<el-row style="min-width: 420px;">
<el-col :span="5" style="min-width: 130px;">当门店库存数量少于</el-col>
<el-col :span="2" style="min-width: 80px;"><el-input size="small" v-model="form.inventoryLimitQuantity"></el-input></el-col>
<el-col :span="6" style="min-width: 180px;">&nbsp;&nbsp;件时,可进行快递到家下单</el-col>
</el-row>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存设置</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'orderSetting',
data () {
return {
form: {
id: '1',
inventoryLimitQuantity: '',
sendCouponFlag: 0,
couponCode: '',
inventoryLimitFlag: 0
},
couponCode: '',
couponCodes: []
}
},
created () {
this.$store.dispatch('getEntityById')
.then(res => {
if (`${res.data.code}` === `0`) {
this.initForm(res.data.data)
} else {
this.$alert(res.data.message)
}
})
},
methods: {
onSubmit () {
this.form.couponCode = this.couponCodes.join(',')
const params = this.form
this.$store.dispatch('saveOrUpdate', params).then(res => {
this.$alert(res.data.message)
})
// const pass = this.validate()
// if (pass) {
// this.$store.dispatch('saveOrUpdate', params).then(res => {
// this.$alert(res.data.message)
// })
// } else {
// this.$alert('请检查配置项!')
// }
},
initForm (orderConfig) {
if (orderConfig.couponCode) {
const codes = orderConfig.couponCode.split(',')
this.couponCodes = codes
}
Object.assign(this.form, orderConfig)
},
validate () {
let validates = []
for (let prop in this.form) {
const value = this.form[prop]
if (!value) {
validates.push(prop)
}
}
if (validates.indexOf('sendCouponFlag') > -1 && validates.indexOf('inventoryLimitFlag') > -1) {
return false
}
return true
},
addCouponCode () {
const code = this.couponCode
if (!code) {
this.$alert('请输入优惠券code')
return
}
if (this.couponCodes.length > 10) {
this.$alert('优惠券数量超过10个!')
return
}
this.couponCodes.push(code)
this.couponCode = ''
},
deleteCoupou (index) {
this.couponCodes = this.couponCodes.filter((item, idx) => idx !== index)
}
}
}
</script>
<style scoped>
.order-setting {
margin-top: 20px;
}
</style>
<template>
<div class="order">
<section class="form-content">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="会员手机号">
<el-input v-model="formInline.returnUser" placeholder="请输入会员手机号"></el-input>
</el-form-item>
<el-form-item label="订单编号">
<el-input v-model="formInline.orderIdStr" placeholder="请输入订单编号"></el-input>
</el-form-item>
<el-form-item label="退单编号">
<el-input v-model="formInline.returnId" placeholder="请输入订单编号"></el-input>
</el-form-item>
<el-form-item label="物流号">
<el-input v-model="formInline.logisticsNo" placeholder="请输入快递单号"></el-input>
</el-form-item>
<el-form-item label="退单申请时间">
<el-date-picker
v-model="dateData"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="下单门店">
<el-input v-model="formInline.storeName" placeholder="请输入下单门店号"></el-input>
</el-form-item>
<el-form-item label="退单状态:">
<el-select v-model="formInline.orderReturnStatus" placeholder="请选择订单状态">
<el-option v-if="key !== '0'" :key="key" :label="value" :value="key" v-for="(value,key) in returnOrderStates()"></el-option>
</el-select>
</el-form-item>
<el-form-item label="会员卡号">
<el-input v-model="formInline.custNo" placeholder="请输入会员卡号"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
<el-button @click="resetForm()">重置</el-button>
</el-form-item>
</el-form>
</section>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="退货单号"
width="180">
<template slot-scope="scope">
<span >{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column
label="订单编号"
width="180">
<template slot-scope="scope">
<span >{{ scope.row.orderId }}</span>
</template>
</el-table-column>
<el-table-column
label="下单门店"
width="180">
<template slot-scope="scope">
<span >{{ scope.row.storeName }}</span>
</template>
</el-table-column>
<el-table-column
label="物流号"
width="180">
<template slot-scope="scope">
<span >{{ scope.row.logisticsNo }}</span>
</template>
</el-table-column>
<el-table-column
label="退款金额"
width="100">
<template slot-scope="scope">
<span>{{ scope.row.realRefundAmount }}</span>
</template>
</el-table-column>
<el-table-column
label="手机号"
width="180">
<template slot-scope="scope">
<span>{{ scope.row.returnUser }}</span>
</template>
</el-table-column>
<el-table-column
label="申请时间"
width="180">
<template slot-scope="scope">
<span >{{ formatDate(scope.row.createTime,'YYYY-MM-DD hh:mm:ss')}}</span>
</template>
</el-table-column>
<el-table-column
label="会员卡号"
width="160">
<template slot-scope="scope">
<span >{{ scope.row.custNo }}</span>
</template>
</el-table-column>
<el-table-column
label="退货状态"
width="100">
<template slot-scope="scope">
<span>{{ returnOrderStatus(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column
label="优惠券状态"
width="140">
<template slot-scope="scope">
<span>{{ scope.row.returnCouponStatus }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
<section>
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNo"
:page-sizes="[20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</section>
</div>
</template>
<script>
import { orderMixin, format } from '../mixin'
export default {
mixins: [orderMixin, format],
data () {
return {
pageNo: 1,
pageSize: 20,
formInline: {
returnUser: '',
orderIdStr: '',
storeName: '',
returnId: '',
logisticsNo: '',
orderReturnStatus: '',
custNo: ''
},
dateData: []
}
},
created () {
this.$store.dispatch('getReturnOrders', {pageNo: this.pageNo, pageSize: this.pageSize})
},
computed: {
tableData () {
return this.$store.getters.getReturnOrders
},
total () {
return this.$store.getters.getReturnOrdersTotal
}
},
methods: {
handleEdit (index, row) {
this.$router.push({
name: 'returnOrderDetail',
params: { id: row.id }
})
},
handleRetrun (index, row) {
this.$router.push({
name: 'returnOrderCreate',
params: { id: row.id }
})
},
handleSizeChange (val) {
this.pageSize = val
const params = this.getParmas()
this.$store.dispatch('getReturnOrders', params)
},
handleCurrentChange (val) {
// console.log(`当前页: ${val}`)
this.pageNo = val
const params = this.getParmas()
this.$store.dispatch('getReturnOrders', params)
},
resetForm () {
this.formInline = {
returnUser: '',
orderIdStr: '',
returnId: '',
storeName: '',
logisticsNo: '',
orderReturnStatus: '',
custNo: ''
}
this.dateData = []
},
getParmas () {
const len = this.dateData.length
// theStartDate 下单时间
let theStartDate = len > 0 ? this.dateData[0] : ''
// theEndDate 结束时间
let theEndDate = len > 1 ? this.dateData[1] : ''
theStartDate = this.formatDate(theStartDate, 'YYYY-MM-DD')
theEndDate = this.formatDate(theEndDate, 'YYYY-MM-DD')
const params = {
pageNo: this.pageNo,
theStartDate,
theEndDate,
pageSize: this.pageSize,
...this.formInline
}
return params
},
resetPageNo () {
this.pageNo = 1
},
onSubmit () {
this.resetPageNo()
const params = this.getParmas()
this.$store.dispatch('getReturnOrders', params)
}
}
}
</script>
<style scoped>
section {
margin-top: 20px;
}
</style>
<template>
<div class="return-order">
<el-form>
<el-row class="content" >
<el-col :sm="20" :lg="22">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>发起退货</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="goBack()">返回列表</el-button>
</div>
<el-row class="row div-margin">
<h5>订单基本信息</h5>
</el-row>
<el-row class="row div-margin">
<el-col :md="8">订单编号: {{order.id }}</el-col>
<el-col :md="8">订单交易号: {{order.id }}</el-col>
</el-row>
<el-row>
<el-col :md="8">下单金额: {{order.paidFee}}</el-col>
<el-col :md="8">
订单状态:{{orderStatus(order,true)}}
</el-col>
</el-row>
<el-row class="row div-margin">
<el-col :md="8">下单时间: {{formatDate(order.createTime)}}</el-col>
<el-col :md="8">下单门店: {{order.storeName }}</el-col>
</el-row>
<el-row class="row div-margin">
<el-col :md="8">物流公司:{{order.logisticsName }}</el-col>
<el-col :md="8">快递单号:{{order.logisticsBillno }}</el-col>
</el-row>
<el-row class="row div-margin">
<el-col :md="8">运费: {{order.logisticsTotalFee ? (order.logisticsTotalFee + '元') : '无运费'}}</el-col>
</el-row>
<el-row class="row div-margin">
<el-col :md="8">
退货原因:
<el-select v-model="ruleForm.reason" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</el-col>
</el-row>
<hr>
<el-row >
<h5>退货商品信息</h5>
</el-row>
<el-table
ref="multipleTable"
:data="order.orderProducts"
select-on-indeterminate
@selection-change="handleSelectionChange"
style="width: 100%">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="商品ID"
>
<template slot-scope="scope">
<span >{{ scope.row.girard }}</span>
</template>
</el-table-column>
<el-table-column
label="商品名称"
>
<template slot-scope="scope">
<span >{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column
label="SKU"
>
<template slot-scope="scope">
<span >{{ scope.row.barCode }}</span>
</template>
</el-table-column>
<el-table-column
label="颜色"
>
<template slot-scope="scope">
<span >{{ scope.row.colorName }}</span>
</template>
</el-table-column>
<el-table-column
label="尺码"
>
<template slot-scope="scope">
<span>{{ scope.row.sizeName }}</span>
</template>
</el-table-column>
<el-table-column
label="商品活动价"
>
<template slot-scope="scope">
<span >{{ scope.row.activityPrice }}</span>
</template>
</el-table-column>
<el-table-column
label="商品数量"
>
<template slot-scope="scope">
<span >{{ scope.row.count }}</span>
</template>
</el-table-column>
</el-table>
<hr>
<el-form-item label="退款金额" prop="pass">
<el-input-number :precision="2" :step="0.1" v-model="ruleForm.price" ></el-input-number>
<el-checkbox v-model="ruleForm.hasLogistics">退运费</el-checkbox>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm()">提交</el-button>
<!--<el-button @click="resetForm()">取消</el-button>-->
</el-form-item>
</el-card>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { orderMixin, format, calcPrice } from '../mixin'
export default {
name: 'returnOrder',
mixins: [orderMixin, format, calcPrice],
data () {
return {
ruleForm: {
price: 0,
reason: '',
hasLogistics: false
},
options: [{ // 所有退货原因
value: 0,
name: '请选择'
}, {
value: 1,
name: '质量问题'
}, {
value: 2,
name: '大小尺码问题'
}, {
value: 3,
name: '不想要了'
}, {
value: 4,
name: '卖家发错漏发'
}, {
value: 5,
name: '拍错商品'
}, {
value: 6,
name: '商品实物与描述不同'
}],
multipleSelection: []
}
},
created () {
const orderId = this.$route.params.id
this.$store.dispatch('getOrder', orderId)
},
computed: {
order () {
const order = this.$store.getters.getOrder
this.$nextTick(() => {
this.initSelection(order.orderProducts)
this.setHasLogistics(this.orderStatus(order, true) === '待发货')
})
return order
}
},
watch: {
'ruleForm.hasLogistics': function (newV) {
this.changeLogistics(newV)
}
},
methods: {
goBack () {
this.$router.back()
},
setHasLogistics (hasLogistics) {
this.ruleForm.hasLogistics = hasLogistics
},
changeLogistics (logistics) {
const goodsPrice = this.calcPrice(this.order.orderProducts)
if (logistics) {
const price = goodsPrice + this.order.logisticsTotalFee
this.setPrice(price)
} else {
this.setPrice(goodsPrice)
}
},
resetForm () {
this.ruleForm = {
price: 0,
reason: ''
}
this.multipleSelection = []
},
submitForm () {
const orderReturnProductList = this.multipleSelection.map((item) => {
return {
barCode: item.barCode,
colorCode: item.colorCode,
colorName: item.colorName,
girard: item.girard,
name: item.name,
orderId: item.orderId,
orderProductId: item.id,
price: item.price,
quantity: item.count,
sizeId: item.sizeId,
sizeName: item.sizeName
}
})
const params = {
orderId: this.$route.params.id,
custNo: this.order.custNo,
storeId: this.order.storeId,
storeName: this.order.storeName,
orderReturnProductList,
remark: '',
returnUser: this.order.customerMobile,
reason: this.ruleForm.reason,
realRefundAmount: this.ruleForm.price,
orderReturnImage: [],
promotionName: this.order.promotionName,
promotionPrice: this.order.promotionPrice,
couponName: this.order.couponName,
couponPrice: this.order.couponPrice
}
const pass = this.validate(params, 'realRefundAmount', '大于0')
if (pass) {
this.$store.dispatch('saveOrderReturn', params).then((res) => {
this.$alert('发起退货成功!').then(() => {
this.goBack()
})
})
} else {
this.$message('退款金额要大于0!')
}
},
validate (parmas, props, rule) {
if (rule === '大于0') {
return parmas[props] && parmas[props] > 0
}
},
calcPrice (activitys) {
return this.calcActivityPrice(activitys)
},
setPrice (price) {
this.ruleForm.price = price
},
handleSelectionChange (val) {
this.multipleSelection = val
this.changeLogistics(this.ruleForm.hasLogistics)
}
}
}
</script>
<style scoped>
.text {
font-size: 14px;
}
.item {
margin-bottom: 18px;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.box-card {
margin-top: 20px;
}
.el-row {
min-height: 40px;
line-height: 40px;
}
h5 {
color:#303133;
font-weight: bold;
}
.order-title {
font-weight: bold;
}
.el-row + .el-row {
margin-top: 20px;
}
</style>
let env = process.env
let api = `${env.host}`
export default {
base: `${api}/${env.project}/${env.requestUrl}/`,
...env
}
import moment from 'moment'
export function fomatDate (value, format) {
return moment(value).format(format || 'YYYY-MM-DD, HH:mm:ss')
}
export function fomatDQ (value, format) {
return 'daqianhao'
}
import axios from 'axios'
// import qs from 'qs'
import store from '@/store'
import config from '../config'
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
// console.log('======= config =======%o', config)
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Do something with response data
if (response.data.code === -1) {
return Promise.reject(response.data.message)
}
if (response.status >= 500) {
console.log(`========== response ======== %o`, response)
}
return response
}, function (error) {
// Do something with response error
return Promise.reject(error)
})
const api = axios.create({
baseURL: config.base
})
api.interceptors.request.use(function (config) {
store.dispatch('show_loading')
// Do something before request is sent
if (config.method === 'post') {
// config.data = qs.stringify(config.data)
}
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
// Add a response interceptor
api.interceptors.response.use(function (response) {
store.dispatch('hide_loading')
// Do something with response data
if (response.status >= 500) {
throw new Error('500!!!')
}
return response
}, function (error) {
// Do something with response error
return Promise.reject(error)
})
// api.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
class BaseHttpServer {
constructor (url) {
if (url) {
this.baseUrl = url
}
this.api = api
}
get (url, params) {
return this.api.get(`${this.baseUrl}/${url}`, { params })
.catch((error) => {
console.log(error)
})
}
post (url, params) {
return this.api.post(`${this.baseUrl}/${url}`, params)
.catch((error) => {
console.log(error)
})
}
}
export {
axios,
api,
BaseHttpServer as Http
}
// {
// // `url` is the server URL that will be used for the request
// url: '/user',
//
// // `method` is the request method to be used when making the request
// method: 'get', // default
//
// // `baseURL` will be prepended to `url` unless `url` is absolute.
// // It can be convenient to set `baseURL` for an instance of axios to pass relative URLs
// // to methods of that instance.
// baseURL: 'https://some-domain.com/api/',
//
// // `transformRequest` allows changes to the request data before it is sent to the server
// // This is only applicable for request methods 'PUT', 'POST', and 'PATCH'
// // The last function in the array must return a string or an instance of Buffer, ArrayBuffer,
// // FormData or Stream
// // You may modify the headers object.
// transformRequest: [function (data, headers) {
// // Do whatever you want to transform the data
//
// return data;
// }],
//
// // `transformResponse` allows changes to the response data to be made before
// // it is passed to then/catch
// transformResponse: [function (data) {
// // Do whatever you want to transform the data
//
// return data;
// }],
//
// // `headers` are custom headers to be sent
// headers: {'X-Requested-With': 'XMLHttpRequest'},
//
// // `params` are the URL parameters to be sent with the request
// // Must be a plain object or a URLSearchParams object
// params: {
// ID: 12345
// },
//
// // `paramsSerializer` is an optional function in charge of serializing `params`
// // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
// paramsSerializer: function(params) {
// return Qs.stringify(params, {arrayFormat: 'brackets'})
// },
//
// // `data` is the data to be sent as the request body
// // Only applicable for request methods 'PUT', 'POST', and 'PATCH'
// // When no `transformRequest` is set, must be of one of the following types:
// // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// // - Browser only: FormData, File, Blob
// // - Node only: Stream, Buffer
// data: {
// firstName: 'Fred'
// },
//
// // `timeout` specifies the number of milliseconds before the request times out.
// // If the request takes longer than `timeout`, the request will be aborted.
// timeout: 1000,
//
// // `withCredentials` indicates whether or not cross-site Access-Control requests
// // should be made using credentials
// withCredentials: false, // default
//
// // `adapter` allows custom handling of requests which makes testing easier.
// // Return a promise and supply a valid response (see lib/adapters/README.md).
// adapter: function (config) {
// /* ... */
// },
//
// // `auth` indicates that HTTP Basic auth should be used, and supplies credentials.
// // This will set an `Authorization` header, overwriting any existing
// // `Authorization` custom headers you have set using `headers`.
// auth: {
// username: 'janedoe',
// password: 's00pers3cret'
// },
//
// // `responseType` indicates the type of data that the server will respond with
// // options are 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
// responseType: 'json', // default
//
// // `responseEncoding` indicates encoding to use for decoding responses
// // Note: Ignored for `responseType` of 'stream' or client-side requests
// responseEncoding: 'utf8', // default
//
// // `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
// xsrfCookieName: 'XSRF-TOKEN', // default
//
// // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
// xsrfHeaderName: 'X-XSRF-TOKEN', // default
//
// // `onUploadProgress` allows handling of progress events for uploads
// onUploadProgress: function (progressEvent) {
// // Do whatever you want with the native progress event
// },
//
// // `onDownloadProgress` allows handling of progress events for downloads
// onDownloadProgress: function (progressEvent) {
// // Do whatever you want with the native progress event
// },
//
// // `maxContentLength` defines the max size of the http response content in bytes allowed
// maxContentLength: 2000,
//
// // `validateStatus` defines whether to resolve or reject the promise for a given
// // HTTP response status code. If `validateStatus` returns `true` (or is set to `null`
// // or `undefined`), the promise will be resolved; otherwise, the promise will be
// // rejected.
// validateStatus: function (status) {
// return status >= 200 && status < 300; // default
// },
//
// // `maxRedirects` defines the maximum number of redirects to follow in node.js.
// // If set to 0, no redirects will be followed.
// maxRedirects: 5, // default
//
// // `socketPath` defines a UNIX Socket to be used in node.js.
// // e.g. '/var/run/docker.sock' to send requests to the docker daemon.
// // Only either `socketPath` or `proxy` can be specified.
// // If both are specified, `socketPath` is used.
// socketPath: null, // default
//
// // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
// // and https requests, respectively, in node.js. This allows options to be added like
// // `keepAlive` that are not enabled by default.
// httpAgent: new http.Agent({ keepAlive: true }),
// httpsAgent: new https.Agent({ keepAlive: true }),
//
// // 'proxy' defines the hostname and port of the proxy server
// // Use `false` to disable proxies, ignoring environment variables.
// // `auth` indicates that HTTP Basic auth should be used to connect to the proxy, and
// // supplies credentials.
// // This will set an `Proxy-Authorization` header, overwriting any existing
// // `Proxy-Authorization` custom headers you have set using `headers`.
// proxy: {
// host: '127.0.0.1',
// port: 9000,
// auth: {
// username: 'mikeymike',
// password: 'rapunz3l'
// }
// },
//
// // `cancelToken` specifies a cancel token that can be used to cancel the request
// // (see Cancellation section below for details)
// cancelToken: new CancelToken(function (cancel) {
// })
// }
import userApi from './user'
import orderApi from './order'
import returnOrderApi from './returnOrder'
import OrderConfigApi from './orderConfig'
export const user = userApi
export const order = orderApi
export const returnOrder = returnOrderApi
export const orderConfig = OrderConfigApi
import { Http } from '../baseHttp'
const baseUrl = '/back/iorder'
class Order extends Http {
constructor () {
super(baseUrl)
}
getOrders (params) {
const __OPTIONS__ = {
pageNo: 1,
pageSize: 50,
orderId: '',
customerMobile: '',
logisticsBillno: '',
custNo: '',
storeName: '',
remark: '',
orderStatus: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`orderlist`, params)
}
getOrderById (id) {
return this.get(`orderDetail`, { orderId: id })
}
getExpress (params) {
const __OPTIONS__ = {
logisticsCode: '',
logisticsNo: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`getExpress`, params)
}
updateOrderRemark (params) {
const __OPTIONS__ = {
orderId: '',
remark: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`updateOrderRemark`, params)
}
updateOrderLogisticsInfo (params) {
const __OPTIONS__ = {
orderId: '',
logisticsCode: '',
logisticsName: '',
logisticsNo: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`updateOrderLogisticsInfo`, params)
}
}
export default new Order()
import { Http } from '../baseHttp'
const baseUrl = '/back/iorderConfig'
class OrderConfig extends Http {
constructor () {
super(baseUrl)
}
saveOrUpdate (params) {
const __OPTIONS__ = {
id: '',
inventoryLimitQuantity: '',
sendCouponFlag: '',
couponCode: '',
inventoryLimitFlag: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.post(`saveOrUpdate`, params)
}
getEntityById (params = {}) {
const __OPTIONS__ = {
orderConfigId: 1
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`getEntityById`, params)
}
}
export default new OrderConfig()
import { Http } from '../baseHttp'
const baseUrl = '/back/ireturn'
class ReturnOrder extends Http {
constructor () {
super(baseUrl)
}
saveOrderReturn (params) {
const __OPTIONS__ = {
orderId: 1,
custNo: '',
storeId: '',
storeName: '',
returnUser: '',
orderReturnProductList: '',
remark: '',
reason: '',
isCustomer: 2, // 写死区分是后台发起的退货
orderReturnImage: [],
promotionName: '',
promotionPrice: '',
couponName: '',
couponPrice: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.post('saveOrderReturn', params)
}
getReturnOrders (params) {
const __OPTIONS__ = {
// pageNo: 1,
// pageSize: 50,
// orderId: '',
// customerMobile: '',
// logisticsId: '',
// custNo: '',
// orderStatus: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`returnlist`, params)
}
getReturnOrderById (id) {
return this.get(`returnDetail`, { returnId: id })
}
updateStatus (params) {
const __OPTIONS__ = {
orderId: '',
returnId: '',
oldStatus: '',
status: '',
realRefundAmount: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`updateStatus`, params)
}
payReturn (params) {
const __OPTIONS__ = {
orderId: '',
returnId: '',
status: '',
realRefundAmount: ''
}
params = Object.assign({}, __OPTIONS__, params)
return this.get(`payReturn`, params)
}
}
export default new ReturnOrder()
import { api as http } from '../baseHttp'
export default {
login: ({username, password}) => {
const params = { username, password }
return http.get('/user/login', {params})
}
}
......@@ -3,30 +3,25 @@
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import './assets/styles/reset.css'
import 'element-ui/lib/theme-chalk/index.css'
import Axios from 'axios'
import * as filters from './filters'
import 'es6-promise/auto'
import store from './store'
Vue.use(ElementUI)
// import VueRx from 'vue-rx'
import { sync } from 'vuex-router-sync'
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
import { momentPlugin, utils } from '@/plugin'
// Vue.use(VueRx)
Vue.config.productionTip = false
// 注册router 到 store
sync(store, router)
// const unsync = sync(store, router)
// unsync()
Vue.use(momentPlugin)
Vue.use(utils)
Vue.prototype.axios = Axios
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
<template>
<div>msg</div>
</template>
<template>
<div class="wrapper">
<home-header></home-header>
<home-sidebar></home-sidebar>
<div class="content-box">
<div class="content">
<transition name="move" mode="out-in">
<!-- <keep-alive exclude="prize"> -->
<router-view></router-view>
<!-- </keep-alive> -->
</transition>
</div>
</div>
</div>
</template>
<script>
import HomeSidebar from 'components/Sidebar'
import HomeHeader from 'components/Header'
export default {
components: {
HomeSidebar,
HomeHeader
}
}
</script>
<style lang="stylus" scoped>
.wrapper
width 100%
height 100%
overflow hidden
.content-box
position absolute
left 260px
right 0
top 70px
bottom 0
overflow-y scroll
-webkit-transition left 0.3s ease-in-out
transition left 0.3s ease-in-out
background #F3F2F8
min-height 720px
.content
width auto
padding 15px
</style>
<template>
<div>
<router-view></router-view>
</div>
<div>Form</div>
</template>
<script>
export default {
name: 'index'
name: 'Form'
}
</script>
<style scoped>
</style>
<template>
<div>tip</div>
</template>
<template>
<div class="login">
333333333
</div>
</template>
<script>
import LoginForm from './components/Form'
export default {
name: 'Login',
components: {
LoginForm
},
data () {
return {
LoginSwiper: [
{
imgUrl: './../../../static/image/swiper1.jpg'
},
{
imgUrl: './../../../static/image/swiper2.jpg'
}
]
}
}
}
</script>
<template>
<div class="marketing">
<div class="marketing-title">
<el-row class="top-left">
<el-col :span="12">
<span class="top-title">营销推送</span>
<span class="top-tips">* 支持<a href="#">会员标签</a>
体系下的精准消息推送</span>
</el-col>
<el-col :span="12" class="top-right">
<span><i class="el-icon-question"></i>营销推送</span>
<span><i class="el-icon-question"></i>营销推送</span>
<span><i class="el-icon-question"></i>营销推送</span>
</el-col>
</el-row>
<el-row></el-row>
<el-row class="marketing-subtitle">
<el-col :span="5" class="subtitle-img">
<span><i class="el-icon-news iconimg"></i></span>
</el-col>
<el-col :span="18" class="subtitle-tips">
<div>在全域营销环节中,营销消息推送作为最直接的会员触达方式,在会员标签体系的加持下通过不同的触达域支持无限可能的精准营销。</div>
<div class="tips-wechat">
<el-row>
<el-col :span="12">
<span>
<i class="el-icon-news"></i>
</span>
<span>微信触达域-公众号</span>
<span>
<a href="#">
立即授权</a>
</span>
</el-col>
<el-col :span="12">
<span>
<i class="el-icon-message"></i>
</span>
<span>移动触达域-短信</span>
<span>
<a href="#">
前往开通</a>
</span>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
</div>
<el-row class="marketing-button">
<el-col :span="14" class="button-left">
<div class="left-title">
<div class="left-title-name">
<span><i class="el-icon-news"></i></span>
<span>微信触达域-公众号</span>
<span>*</span>
<a href="#">点击新建群发</a>
</div>
<div class="left-title-message">
<span><i class="el-icon-success"></i></span>
<span>已授权</span>
</div>
</div>
<div class="left-icon">
<div class="icon-left">
<span class="icon-wechat">
<i class="el-icon-picture-outline"></i>
</span>
<p class="icon-wechat-msg">图文素材消息</p>
</div>
<div class="icon-right">
<span class="icon-wechat">
<i class="el-icon-document"></i>
</span>
<p class="icon-wechat-msg">营销模板消息</p>
</div>
</div>
</el-col>
<el-col :span="10" class="button-right">
<div class="left-title">
<div class="left-title-name">
<span><i class="el-icon-message"></i></span>
<span>移动触达域-短信</span>
<span>*</span>
<a href="#">点击新建群发</a>
</div>
<div class="left-title-message">
<span><i class="el-icon-success"></i></span>
<span>未授权</span>
</div>
</div>
<div class="right-marketing">
<div>
<span class="icon-wechat">
<i class="el-icon-message"></i>
</span>
<p class="icon-wechat-msg">短信营销消息</p>
</div>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<div class="marketing-white"></div>
</el-col>
</el-row>
<marketing-tab class="marketing-tabs"></marketing-tab>
</div>
</template>
<script>
import MarketingTab from 'components/Tab/MarketingTab'
export default {
components: {
MarketingTab
}
}
</script>
<style lang="stylus" scoped>
.marketing
.marketing-title
height 177px
background-color #fff
.top-left
height 50px
line-height 50px
border-bottom 1px solid gray
margin 0 15px
.top-title
font-size 20px
.top-tips
padding-left 20px
.top-right
span
padding-right 20px
.marketing-subtitle
height 130px
.subtitle-img
.iconimg
font-size 70px
line-height 130px
padding-left 70px
.subtitle-tips
padding-top 30px
.tips-wechat
padding 30px
.marketing-button
margin-top 10px
background-color #fff
height 182px
.button-left, .button-right
padding-left 10px
.left-title
height 50px
line-height 50px
.left-title-name
float left
.left-title-message
float right
padding-right 20px
.left-icon
height 140px
.icon-left
float left
width 50%
.icon-right, .icon-left
padding 20px 0
text-align center
.icon-wechat
font-size 40px
.icon-wechat-msg
font-size 14px
padding-top 10px
.button-right
.right-marketing
padding 20px 0
text-align center
.icon-wechat
font-size 40px
.icon-wechat-msg
font-size 14px
padding-top 10px
.marketing-white
background-color #fff
height 27px
.marketing-tabs
position relative
top -10px
</style>
import momentPlugin from './moment'
import validate from './validate'
import utils from './underscore'
export {
momentPlugin,
utils,
validate
}
import moment from 'moment'
class Moment {
install (Vue, options) {
// 4. 添加实例方法
Vue.prototype.$moment = moment
}
}
export default new Moment()
// https://www.npmjs.com/package/validate
import _ from 'underscore'
class Utils {
install (Vue, options) {
// 4. 添加实例方法
Vue.prototype.$_ = _
}
}
export default new Utils()
// https://www.npmjs.com/package/validate
import Schema from 'validate'
class Validate {
install (Vue, options) {
// 4. 添加实例方法
Vue.prototype.$validator = Schema
}
}
export default new Validate()
/* eslint-disable no-return-assign */
import Vue from 'vue'
import Router from 'vue-router'
import config from '../config'
Vue.use(Router)
function getConfigRouters () {
// 分页面加载路由 避免router.js过大
let cache = {}
let routers = []// 所有的路由配置数组
function importAll (r) {
r.keys().forEach((key) => {
routers.push(r(key).default)
return cache[key] = r(key)
})
}
importAll(require.context('../views/', true, /\.router\.js$/))
return routers
}
Vue.use(Router)
// 配置路由
let routers = getConfigRouters()
const router = new Router({
base: `/${config.baseUrl}/${config.url}/`,
mode: 'history',
export default new Router({
routes: [
...routers,
{
path: '**',
redirect: ''
path: '/',
redirect: '/home',
component: () => import(/* webpackChunkName: 'wxhome' */ 'pages/home')
},
{
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: 'wxlogin' */ 'pages/login')
},
{
path: '/home',
name: 'Home',
component: () => import(/* web packChunkName: 'wxhome' */ 'pages/home'),
children: [
{
path: '/marketing',
name: 'marketing',
component: () =>
import(/* webpackChunkName: 'marketing' */ 'pages/marketing-center')
},
{
path: '/addmarketing',
name: 'addmarketing',
component: () =>
import(/* webpackChunkName: 'wxlogin' */ 'pages/addmarketing')
}
]
}
]
})
router.beforeEach((to, from, next) => {
next()
})
export default router
import * as types from './mutations_types'
export default {
show_loading: ({
commit
}) => {
return new Promise((resolve, reject) => {
commit(types.SHOW_LOADING)
resolve()
})
},
hide_loading: ({
commit
}) => {
return new Promise((resolve, reject) => {
commit(types.HIDE_LOADING)
resolve()
})
}
}
export default {
getLoadStatus (state) {
return state.ajax_loading
}
}
import state from './state'
import mutations from './mutations'
import getters from './getters'
import actions from './actions'
export default {
state,
mutations,
getters,
actions
}
import * as types from './mutations_types'
// import { store } from 'utils/'
export default {
[types.SHOW_LOADING] (state) {
state.ajax_loading = true
},
[types.HIDE_LOADING] (state) {
state.ajax_loading = false
}
}
// 显示加载
export const SHOW_LOADING = 'SHOW_LOADING'
// 关闭加载
export const HIDE_LOADING = 'HIDE_LOADING'
export default {
ajax_loading: false
}
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
import createLogger from 'vuex/dist/logger'
import global from './global'
// import user from './user'
// import order from './order'
// import returnOrder from './returnOrder'
// import orderConfig from './orderConfig'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
const store = new Vuex.Store({
modules: {
global
// user,
// order,
// returnOrder,
// orderConfig
},
export default new Vuex.Store({
actions,
getters,
state,
mutations,
strict: debug,
plugins: debug ? [createLogger()] : []
})
if (module.hot) {
module.hot.accept([
// './getters',
// './actions',
// './mutations'
], () => {
store.hotUpdate({
// getters: require('./getters'),
// actions: require('./actions'),
// mutations: require('./mutations')
})
})
}
export default store
import { order } from '@/http'
// 获取订单
const GET_ORDERS = 'GET_ORDERS'
// 获取单个订单
const GET_ORDER = 'GET_ORDER'
// 订单总数
const TOTAL_ORDERS = 'TOTAL_ORDERS'
// 物流信息
const GET_EXPRESS = 'GET_EXPRESS'
const state = {
orders: [],
order: {},
express: [],
total: 0
}
const actions = {
getOrders ({
commit, dispatch
}, parmas) {
return order.getOrders(parmas).then((res) => {
const orders = res.data.page.result
const total = res.data.page.totalCount
commit(GET_ORDERS, orders)
dispatch('getOrdersTotal', total)
})
},
getOrdersTotal ({commit}, total) {
commit(TOTAL_ORDERS, total)
},
getOrder ({commit, dispatch}, id) {
return order.getOrderById(id).then(res => {
const order = res.data.order
// orderStatus === '3' && returnStatus !== '6'
if (`${order.orderStatus}` === '3' && `${order.returnStatus}` !== '6') {
dispatch('getExpress', {
logisticsCode: order.logisticsCode,
logisticsNo: order.logisticsNo
})
}
commit(GET_ORDER, order)
})
},
getExpress ({
commit, dispatch
}, parmas) {
return order.getExpress(parmas).then((res) => {
let express = []
const data = JSON.parse(res.data)
if (`${data.code}` === '500') {
express.push({
context: data.message
// ftime: new Date().getTime()
})
} else {
express = data.data
}
commit(GET_EXPRESS, express)
})
},
updateOrderRemark ({
commit, dispatch
}, parmas) {
return order.updateOrderRemark(parmas)
},
updateOrderLogisticsInfo ({
commit, dispatch
}, parmas) {
return order.updateOrderLogisticsInfo(parmas)
}
}
const getters = {
getOrders (state) {
return state.orders
},
getOrdersTotal (state) {
return state.total
},
getOrder (state) {
return state.order
},
getExpress (state) {
return state.express
}
}
const mutations = {
[GET_ORDERS] (state, orders) {
state.orders = orders
},
[TOTAL_ORDERS] (state, total) {
state.total = total
},
[GET_ORDER] (state, order) {
state.order = order
},
[GET_EXPRESS] (state, express) {
state.express = express
}
}
export default {
state,
mutations,
actions,
getters
}
import { orderConfig } from '@/http'
// 保存下单配置
// const SAVE_OR_UPDATE = 'saveOrUpdate'
// 获取下单配置
const GET_ENTITY_BY_ID = 'getEntityById'
const state = {
detail: {
id: '',
inventoryLimitQuantity: '',
sendCouponFlag: '',
couponCode: '',
inventoryLimitFlag: ''
}
}
const actions = {
saveOrUpdate ({
commit, dispatch
}, parmas) {
return orderConfig.saveOrUpdate(parmas)
},
getEntityById ({commit, dispatch}, id = 1) {
return orderConfig.getEntityById(id).then(res => {
const orderConfig = res.data.data
commit(GET_ENTITY_BY_ID, orderConfig)
return Promise.resolve(res)
})
}
}
const getters = {
orderConfig (state) {
return state.detail
}
}
const mutations = {
[GET_ENTITY_BY_ID] (state, orderConfig) {
state.detail = { ...orderConfig }
}
}
export default {
state,
mutations,
actions,
getters
}
import { returnOrder } from '@/http'
// 获取退货订单
const GET_RETURN_ORDERS = 'GET_TETURN_ORDERS'
// 获取单个退货订单
const GET_RETURN_ORDER = 'GET_RETURN_ORDER'
// 订单总数
const TOTAL_TETURN_ORDER = 'TOTAL_TETURN_ORDER'
const state = {
returnOrders: [],
detail: {},
returnTotal: 0
}
const actions = {
getReturnOrders ({
commit, dispatch
}, parmas) {
return returnOrder.getReturnOrders(parmas).then((res) => {
const orders = res.data.page.result
const total = res.data.page.totalCount
commit(GET_RETURN_ORDERS, orders)
dispatch('getReturnOrdersTotal', total)
})
},
getReturnOrdersTotal ({commit}, total) {
commit(TOTAL_TETURN_ORDER, total)
},
getReturnOrder ({commit}, id) {
return returnOrder.getReturnOrderById(id).then(res => {
const orderReturn = res.data.orderReturn
const order = res.data.order
commit('GET_ORDER', order)
commit(GET_RETURN_ORDER, orderReturn)
})
},
saveOrderReturn ({commit}, parmas) {
return returnOrder.saveOrderReturn(parmas)
},
updateStatus ({commit}, parmas) {
// const state = {
// 2: '审核通过',
// 3: '驳回退货',
// 7: '确认退货',
// 4: '取消退货',
// 5: '确认收货'
// }
// const status = parmas.status
return returnOrder.updateStatus(parmas).then(res => {
console.log(res)
if (`${res.data.code}` === '0') {
return Promise.resolve({
data: {
message: `操作成功`
}})
} else {
return Promise.resolve({
data: {
message: `操作失败`
}})
}
})
},
payReturn ({commit}, parmas) {
return returnOrder.payReturn(parmas).then(res => {
if (`${res.data.code}` === '0') {
return Promise.resolve({
data: {
message: `退款成功`
}})
} else {
return Promise.resolve({
data: {
message: `退款失败`
}})
}
})
}
}
const getters = {
getReturnOrders (state) {
return state.returnOrders
},
getReturnOrdersTotal (state) {
return state.returnTotal
},
getReturnOrder (state) {
return state.detail
}
}
const mutations = {
[GET_RETURN_ORDERS] (state, orders) {
state.returnOrders = [...orders]
},
[TOTAL_TETURN_ORDER] (state, total) {
state.returnTotal = total
},
[GET_RETURN_ORDER] (state, orderReturn) {
state.detail = orderReturn
}
}
export default {
state,
mutations,
actions,
getters
}
import * as types from './mutations_types.js'
import { user } from '@/http'
export default {
login ({
commit,
dispatch
}, userInfo) {
return user.login(userInfo)
.then((res) => {
if (res.data.code === 0) {
dispatch('updateUserInfo', userInfo)
return Promise.resolve(res)
} else {
return Promise.resolve({
data: {
message: '登陆失败'
}})
}
})
},
updateUserInfo ({commit}, userInfo) {
commit(types.UPDATE_USERINFO, userInfo)
}
}
export default {
getUserinfo (state) {
return state.userinfo
},
getToken (state) {
return state.userinfo && state.userinfo.token ? state.userinfo.token : ''
},
getRemumber (state) {
return state.remumber
}
}
import state from './state.js'
import mutations from './mutations.js'
import actions from './actions.js'
import getters from './getters.js'
export default {
state,
mutations,
actions,
getters
}
import * as types from './mutations_types'
export default {
[types.UPDATE_USERINFO] (state, userDb) {
state.userinfo = userDb.userinfo || {}
}
}
// 用户登陆
export const USER_LOGIN = 'USER_LOGIN'
// 更新用户信息
export const UPDATE_USERINFO = 'UPDATE_USERINFO'
export default {
// 登录成功后的用户信息
userinfo: {
username: ''
},
// 记住密码相关信息,现在暂且只做记住一个账号密码
// 后期:每次登录成功一次,就缓存到列表中,然后在登录表单,输入时,会出现下拉列表选择之前登录过得用户
remumber: {
remumberFlag: true,
remumberLoginInfo: {
username: '',
token: ''
}
}
}
import date from './moment'
export const M = date
import moment from 'moment'
export default moment
<template>
<div class="container-fluid">
<div class="page-header"><h1>页面不存在.</h1></div>
<div><a href="javascript:" onclick="history.go(-1);" class="btn">返回上一页</a></div>
</div>
</template>
<script>
export default {
name: 'code404'
}
</script>
<style scoped>
</style>
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment