parent
b5da8b29ff
commit
f68b69f69c
@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
dist/electron/
|
||||
dist/web/*
|
||||
build/*
|
||||
!build/icons
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
npm-debug.log.*
|
||||
thumbs.db
|
||||
!.gitkeep
|
||||
.idea/*
|
||||
/dist
|
||||
/tests
|
||||
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Shengliang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
],
|
||||
'env': {
|
||||
'development': {
|
||||
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
|
||||
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
|
||||
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
|
||||
'plugins': ['dynamic-import-node']
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
module.exports = {
|
||||
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
|
||||
transform: {
|
||||
'^.+\\.vue$': 'vue-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
|
||||
'jest-transform-stub',
|
||||
'^.+\\.jsx?$': 'babel-jest'
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
snapshotSerializers: ['jest-serializer-vue'],
|
||||
testMatch: [
|
||||
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
||||
],
|
||||
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
|
||||
coverageDirectory: '<rootDir>/tests/unit/coverage',
|
||||
// 'collectCoverage': true,
|
||||
'coverageReporters': [
|
||||
'lcov',
|
||||
'text-summary'
|
||||
],
|
||||
testURL: 'http://localhost/'
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
const Mock = require('mockjs')
|
||||
const { param2Obj } = require('./utils')
|
||||
|
||||
const user = require('./user')
|
||||
const table = require('./table')
|
||||
|
||||
const mocks = [
|
||||
...user,
|
||||
...table
|
||||
]
|
||||
|
||||
// for front mock
|
||||
// please use it cautiously, it will redefine XMLHttpRequest,
|
||||
// which will cause many of your third-party libraries to be invalidated(like progress event).
|
||||
function mockXHR() {
|
||||
// mock patch
|
||||
// https://github.com/nuysoft/Mock/issues/300
|
||||
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
||||
Mock.XHR.prototype.send = function() {
|
||||
if (this.custom.xhr) {
|
||||
this.custom.xhr.withCredentials = this.withCredentials || false
|
||||
|
||||
if (this.responseType) {
|
||||
this.custom.xhr.responseType = this.responseType
|
||||
}
|
||||
}
|
||||
this.proxy_send(...arguments)
|
||||
}
|
||||
|
||||
function XHR2ExpressReqWrap(respond) {
|
||||
return function(options) {
|
||||
let result = null
|
||||
if (respond instanceof Function) {
|
||||
const { body, type, url } = options
|
||||
// https://expressjs.com/en/4x/api.html#req
|
||||
result = respond({
|
||||
method: type,
|
||||
body: JSON.parse(body),
|
||||
query: param2Obj(url)
|
||||
})
|
||||
} else {
|
||||
result = respond
|
||||
}
|
||||
return Mock.mock(result)
|
||||
}
|
||||
}
|
||||
|
||||
for (const i of mocks) {
|
||||
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mocks,
|
||||
mockXHR
|
||||
}
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
const chokidar = require('chokidar')
|
||||
const bodyParser = require('body-parser')
|
||||
const chalk = require('chalk')
|
||||
const path = require('path')
|
||||
const Mock = require('mockjs')
|
||||
|
||||
const mockDir = path.join(process.cwd(), 'mock')
|
||||
|
||||
function registerRoutes(app) {
|
||||
let mockLastIndex
|
||||
const { mocks } = require('./index.js')
|
||||
const mocksForServer = mocks.map(route => {
|
||||
return responseFake(route.url, route.type, route.response)
|
||||
})
|
||||
for (const mock of mocksForServer) {
|
||||
app[mock.type](mock.url, mock.response)
|
||||
mockLastIndex = app._router.stack.length
|
||||
}
|
||||
const mockRoutesLength = Object.keys(mocksForServer).length
|
||||
return {
|
||||
mockRoutesLength: mockRoutesLength,
|
||||
mockStartIndex: mockLastIndex - mockRoutesLength
|
||||
}
|
||||
}
|
||||
|
||||
function unregisterRoutes() {
|
||||
Object.keys(require.cache).forEach(i => {
|
||||
if (i.includes(mockDir)) {
|
||||
delete require.cache[require.resolve(i)]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// for mock server
|
||||
const responseFake = (url, type, respond) => {
|
||||
return {
|
||||
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
|
||||
type: type || 'get',
|
||||
response(req, res) {
|
||||
console.log('request invoke:' + req.path)
|
||||
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = app => {
|
||||
// parse app.body
|
||||
// https://expressjs.com/en/4x/api.html#req.body
|
||||
app.use(bodyParser.json())
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}))
|
||||
|
||||
const mockRoutes = registerRoutes(app)
|
||||
var mockRoutesLength = mockRoutes.mockRoutesLength
|
||||
var mockStartIndex = mockRoutes.mockStartIndex
|
||||
|
||||
// watch files, hot reload mock server
|
||||
chokidar.watch(mockDir, {
|
||||
ignored: /mock-server/,
|
||||
ignoreInitial: true
|
||||
}).on('all', (event, path) => {
|
||||
if (event === 'change' || event === 'add') {
|
||||
try {
|
||||
// remove mock routes stack
|
||||
app._router.stack.splice(mockStartIndex, mockRoutesLength)
|
||||
|
||||
// clear routes cache
|
||||
unregisterRoutes()
|
||||
|
||||
const mockRoutes = registerRoutes(app)
|
||||
mockRoutesLength = mockRoutes.mockRoutesLength
|
||||
mockStartIndex = mockRoutes.mockStartIndex
|
||||
|
||||
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
|
||||
} catch (error) {
|
||||
console.log(chalk.redBright(error))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
const Mock = require('mockjs')
|
||||
|
||||
const data = Mock.mock({
|
||||
'items|30': [{
|
||||
id: '@id',
|
||||
title: '@sentence(10, 20)',
|
||||
'status|1': ['published', 'draft', 'deleted'],
|
||||
author: 'name',
|
||||
display_time: '@datetime',
|
||||
pageviews: '@integer(300, 5000)'
|
||||
}]
|
||||
})
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
url: '/vue-admin-template/table/list',
|
||||
type: 'get',
|
||||
response: config => {
|
||||
const items = data.items
|
||||
return {
|
||||
code: 20000,
|
||||
data: {
|
||||
total: items.length,
|
||||
items: items
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,84 @@
|
||||
|
||||
const tokens = {
|
||||
admin: {
|
||||
token: 'admin-token'
|
||||
},
|
||||
editor: {
|
||||
token: 'editor-token'
|
||||
}
|
||||
}
|
||||
|
||||
const users = {
|
||||
'admin-token': {
|
||||
roles: ['admin'],
|
||||
introduction: 'I am a super administrator',
|
||||
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
|
||||
name: 'Super Admin'
|
||||
},
|
||||
'editor-token': {
|
||||
roles: ['editor'],
|
||||
introduction: 'I am an editor',
|
||||
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
|
||||
name: 'Normal Editor'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = [
|
||||
// user login
|
||||
{
|
||||
url: '/vue-admin-template/user/login',
|
||||
type: 'post',
|
||||
response: config => {
|
||||
const { username } = config.body
|
||||
const token = tokens[username]
|
||||
|
||||
// mock error
|
||||
if (!token) {
|
||||
return {
|
||||
code: 60204,
|
||||
message: 'Account and password are incorrect.'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
code: 20000,
|
||||
data: token
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// get user info
|
||||
{
|
||||
url: '/vue-admin-template/user/info\.*',
|
||||
type: 'get',
|
||||
response: config => {
|
||||
const { token } = config.query
|
||||
const info = users[token]
|
||||
|
||||
// mock error
|
||||
if (!info) {
|
||||
return {
|
||||
code: 50008,
|
||||
message: 'Login failed, unable to get user details.'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
code: 20000,
|
||||
data: info
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// user logout
|
||||
{
|
||||
url: '/vue-admin-template/user/logout',
|
||||
type: 'post',
|
||||
response: _ => {
|
||||
return {
|
||||
code: 20000,
|
||||
data: 'success'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns {Object}
|
||||
*/
|
||||
function param2Obj(url) {
|
||||
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
|
||||
if (!search) {
|
||||
return {}
|
||||
}
|
||||
const obj = {}
|
||||
const searchArr = search.split('&')
|
||||
searchArr.forEach(v => {
|
||||
const index = v.indexOf('=')
|
||||
if (index !== -1) {
|
||||
const name = v.substring(0, index)
|
||||
const val = v.substring(index + 1, v.length)
|
||||
obj[name] = val
|
||||
}
|
||||
})
|
||||
return obj
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
param2Obj
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "vue-admin-template",
|
||||
"version": "4.4.0",
|
||||
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
|
||||
"author": "Pan <panfree23@gmail.com>",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
||||
"test:ci": "npm run lint && npm run test:unit"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "0.18.1",
|
||||
"clipboard": "^2.0.11",
|
||||
"core-js": "^3.30.1",
|
||||
"element-ui": "2.13.2",
|
||||
"jquery": "^3.6.3",
|
||||
"js-cookie": "2.2.0",
|
||||
"lrz": "^4.9.41",
|
||||
"moment": "^2.29.4",
|
||||
"normalize.css": "7.0.0",
|
||||
"nprogress": "0.2.0",
|
||||
"path-to-regexp": "2.4.0",
|
||||
"quill": "^2.0.2",
|
||||
"vue": "2.6.10",
|
||||
"vue-axios": "^3.5.2",
|
||||
"vue-barcode": "^1.3.0",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "3.0.6",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "4.4.4",
|
||||
"@vue/cli-plugin-unit-jest": "4.4.4",
|
||||
"@vue/cli-service": "4.4.4",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"autoprefixer": "9.5.1",
|
||||
"babel-jest": "23.6.0",
|
||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||
"chalk": "2.4.2",
|
||||
"connect": "3.6.6",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"mockjs": "1.0.1-beta3",
|
||||
"runjs": "4.3.2",
|
||||
"sass": "1.26.8",
|
||||
"sass-loader": "8.0.2",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
"serve-static": "1.13.2",
|
||||
"svg-sprite-loader": "4.1.3",
|
||||
"svgo": "1.2.2",
|
||||
"vue-template-compiler": "2.6.10"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=8.9",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = {
|
||||
'plugins': {
|
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
'autoprefixer': {}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<!-- <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> -->
|
||||
<link href="/admin/css/font-awesome.min.css" rel="stylesheet">
|
||||
<title><%= webpackConfig.name %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 301 KiB |
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<transition name="router-fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "admin",
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #f5f7f9;
|
||||
font-family: Lato, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
a,
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.content-nav {
|
||||
height: 40px;
|
||||
background: #f5f7fa;
|
||||
margin: 0 0 10px 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.content-nav .breadcrumb {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
flex: 1;
|
||||
color: #8492a6;
|
||||
}
|
||||
|
||||
.content-nav .operation-nav {
|
||||
width: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content-main {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.filter-box {
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-box {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.form-table-box .el-input__inner {
|
||||
max-width: 240px;
|
||||
}
|
||||
|
||||
.form-table-box .el-textarea {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.router-fade-enter-active,
|
||||
.router-fade-leave-active {
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.router-fade-enter,
|
||||
.router-fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.form-table-box .el-form {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.form-tip {
|
||||
color: #888;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getList(params) {
|
||||
return request({
|
||||
url: '/vue-admin-template/table/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: '/vue-admin-template/user/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo(token) {
|
||||
return request({
|
||||
url: '/vue-admin-template/user/info',
|
||||
method: 'get',
|
||||
params: { token }
|
||||
})
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return request({
|
||||
url: '/vue-admin-template/user/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'ad' }">广告列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{infoForm.id ? '编辑广告' : '添加广告'}}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<!--<el-button type="primary" @click="test" icon="arrow-left">test</el-button>-->
|
||||
<el-button type="primary" @click="goBackPage" icon="arrow-left">返回列表</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :rules="infoRules" :model="infoForm" label-width="120px">
|
||||
<el-form-item label="广告图片" prop="image_url" v-if="infoForm.image_url" class="image-uploader-diy new-height">
|
||||
<div class="index-image">
|
||||
<el-image :preview-src-list="previewList" v-if="infoForm.image_url" :src="infoForm.image_url" @click="previewIndexImg"
|
||||
class="image-show" fit="cover"></el-image>
|
||||
<div class="o-shadow" @click="delePicList">
|
||||
<i class="el-icon-delete"></i>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="广告图片" prop="image_url" v-if="!infoForm.image_url">
|
||||
<el-upload name="file" ref="upload" class="upload-demo" :action="qiniuZone" :on-success="handleSuccess"
|
||||
:before-upload="getQiniuToken" :auto-upload="true" list-type="picture-card" :data="picData" :http-request="uploadIndexImg">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型">
|
||||
<el-radio-group v-model="infoForm.link_type">
|
||||
<el-radio :label="0">商品id</el-radio>
|
||||
<el-radio :label="1">链接</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="广告链接" prop="link" v-if="infoForm.link_type == 1">
|
||||
<el-input class="link-input" v-model="infoForm.link"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品id" prop="link" v-if="infoForm.link_type == 0">
|
||||
<el-input class="id-input" v-model="infoForm.goods_id"></el-input>
|
||||
<el-popover
|
||||
placement="right"
|
||||
v-model="related_pop"
|
||||
>
|
||||
<el-table :data="chooseRelateGoods" stripe style="width: 100%">
|
||||
<el-table-column prop="id" label="id" width="100"></el-table-column>
|
||||
<el-table-column prop="list_pic_url" label="商品图片" width="120">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.list_pic_url" alt="" style="width: 40px;height: 40px">
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="商品名称" width="300px"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="relateSelect(scope.row.id)">选择
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button slot="reference" type="primary" @click="relateGoodsClick">添加关联商品</el-button>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="end_time">
|
||||
<el-date-picker
|
||||
v-model="infoForm.end_time"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
default-time="23:59:59">
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort_order">
|
||||
<el-input-number v-model="infoForm.sort_order" :min="1" :max="999"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="广告启用">
|
||||
<el-switch active-value="1" inactive-value="0" v-model="infoForm.enabled"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitInfo">确定保存</el-button>
|
||||
<el-button @click="goBackPage">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
import lrz from 'lrz'
|
||||
import moment from 'moment'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
qiniuZone:'',
|
||||
root: '',
|
||||
fileList: [],
|
||||
infoForm: {
|
||||
id: 0,
|
||||
image_url: '',
|
||||
link_type: 0,
|
||||
enabled: 0,
|
||||
end_time: '',
|
||||
goods_id:0,
|
||||
link:''
|
||||
},
|
||||
infoRules: {
|
||||
image_url: [
|
||||
{required: true, message: '请输入广告图片', trigger: 'blur'},
|
||||
],
|
||||
end_time: [
|
||||
{required: true, message: '请选择时间', trigger: 'blur'},
|
||||
],
|
||||
},
|
||||
picData: {
|
||||
token: ''
|
||||
},
|
||||
url: '',
|
||||
chooseRelateGoods: [],
|
||||
related_pop: false,
|
||||
previewList: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSuccess(){},
|
||||
previewIndexImg() {
|
||||
let that = this;
|
||||
that.previewList = [];
|
||||
that.previewList.push(that.infoForm.image_url);
|
||||
},
|
||||
delePicList() {
|
||||
let that = this;
|
||||
that.$confirm('确定删除该图片?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
that.infoForm.image_url = '';
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
uploadIndexImg(request) {
|
||||
const file = request.file;
|
||||
lrz(file).then((rst) => {
|
||||
const config = {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
};
|
||||
const fileName = moment().format('YYYYMMDDHHmmssSSS') + Math.floor(Math.random() * 100) + file.name; //自定义图片名
|
||||
const formData = new FormData();
|
||||
formData.append('file', rst.file);
|
||||
formData.append('token', this.picData.token);
|
||||
formData.append('key', fileName);
|
||||
this.$http.post(this.qiniuZone, formData, config).then((res) => {
|
||||
this.handleUploadImageSuccess(res.data)
|
||||
})
|
||||
}).catch(function(err){
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
handleUploadImageSuccess(res, file) {
|
||||
let url = this.url;
|
||||
this.infoForm.image_url = url + res.key;
|
||||
},
|
||||
relateSelect(id) {
|
||||
console.log(id);
|
||||
this.infoForm.goods_id = id;
|
||||
this.related_pop = false;
|
||||
},
|
||||
relateGoodsClick() {
|
||||
this.axios.post('ad/getallrelate', {id: this.infoForm.id}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.chooseRelateGoods = response.data.data
|
||||
}
|
||||
});
|
||||
},
|
||||
test() {
|
||||
console.log(this.infoForm.end_time);
|
||||
},
|
||||
beforeAdRemove() {
|
||||
return this.$confirm(`确定移除?`);
|
||||
},
|
||||
adRemove(file, fileList) {
|
||||
this.infoForm.image_url = '';
|
||||
},
|
||||
getQiniuToken() {
|
||||
let that = this
|
||||
this.axios.post('index/getQiniuToken').then((response) => {
|
||||
let resInfo = response.data.data;
|
||||
console.log(resInfo);
|
||||
that.picData.token = resInfo.token;
|
||||
that.url = resInfo.url;
|
||||
})
|
||||
},
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
onSubmitInfo() {
|
||||
console.log(this.infoForm);
|
||||
// return false;
|
||||
let time = this.infoForm.end_time
|
||||
if (time == 0) {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '请选择时间'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.infoForm.link_type == 0) {
|
||||
if(this.infoForm.goods_id == 0 ){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '请选择商品'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.infoForm.link_type == 1) {
|
||||
if(this.infoForm.link == '' ){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '请输入链接'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('ad/store', this.infoForm).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
});
|
||||
this.$router.go(-1);
|
||||
} else if (response.data.errno === 100) {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '该商品已经有广告关联'
|
||||
})
|
||||
}
|
||||
else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getInfo() {
|
||||
if (this.infoForm.id <= 0) {
|
||||
return false
|
||||
}
|
||||
//加载广告详情
|
||||
let that = this
|
||||
this.axios.get('ad/info', {
|
||||
params: {
|
||||
id: that.infoForm.id
|
||||
}
|
||||
}).then((response) => {
|
||||
let resInfo = response.data.data;
|
||||
resInfo.enabled = resInfo.enabled ? "1" : "0";
|
||||
that.infoForm = resInfo;
|
||||
that.infoForm.end_time = resInfo.end_time * 1000;
|
||||
let info = {
|
||||
name: resInfo.name,
|
||||
url: resInfo.image_url
|
||||
};
|
||||
this.fileList.push(info);
|
||||
console.log(this.infoForm);
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.infoForm.id = this.$route.query.id || 0;
|
||||
this.getInfo();
|
||||
this.root = api.rootUrl;
|
||||
this.getQiniuToken();
|
||||
this.qiniuZone = api.qiniu;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-show {
|
||||
width: 375px;
|
||||
height: 220px;
|
||||
background-color: #f9f9f9;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.id-input {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.link-input .el-input__inner {
|
||||
width: 400px !important;
|
||||
}
|
||||
|
||||
.o-shadow {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
opacity: 0;
|
||||
transition: opacity .3s;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.index-image {
|
||||
width: 375px;
|
||||
height: 220px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.index-image:hover .o-shadow {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>广告列表</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<router-link to="/dashboard/ad/add">
|
||||
<el-button type="primary" icon="plus">添加广告</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="70px"></el-table-column>
|
||||
<el-table-column prop="image_url" label="广告">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.image_url" alt="" style="width: 90px;height: 50px">
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="goods_id" label="关联商品"></el-table-column>
|
||||
<el-table-column prop="end_time" label="结束时间"></el-table-column>
|
||||
<el-table-column prop="sort_order" label="排序" width="100" sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.sort_order" placeholder="排序" @blur="submitSort(scope.$index, scope.row)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="enabled" label="状态" width="80px">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.enabled == 1 ? '启用' : '禁用' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开启状态" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.enabled"
|
||||
active-text=""
|
||||
inactive-text=""
|
||||
@change='changeStatus($event,scope.row.id)'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="170">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleRowDelete(scope.$index, scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination @current-change="handlePageChange" :current-page="page" :page-size="10" layout="total, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
test(){
|
||||
console.log(this.tableData);
|
||||
},
|
||||
submitSort(index, row){
|
||||
this.axios.post('ad/updateSort', { id: row.id,sort:row.sort_order }).then((response) => {
|
||||
})
|
||||
},
|
||||
changeStatus($event, para) {
|
||||
this.axios.get('ad/saleStatus', {
|
||||
params: {
|
||||
status: $event,
|
||||
id: para
|
||||
}
|
||||
}).then((response) => {
|
||||
|
||||
})
|
||||
},
|
||||
handlePageChange(val) {
|
||||
this.page = val;
|
||||
//保存到localStorage
|
||||
localStorage.setItem('adPage', this.page)
|
||||
localStorage.setItem('adFilterForm', JSON.stringify(this.filterForm));
|
||||
this.getList()
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({ name: 'ad_add', query: { id: row.id } })
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
this.axios.post('ad/destory', { id: row.id }).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
},
|
||||
onSubmitFilter() {
|
||||
this.page = 1
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('ad', {
|
||||
params: {
|
||||
page: this.page,
|
||||
}
|
||||
}).then((response) => {
|
||||
this.tableData = response.data.data.data
|
||||
this.page = response.data.data.currentPage
|
||||
this.total = response.data.data.count
|
||||
})
|
||||
console.log(this.tableData);
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'admin' }">管理员</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{infoForm.id ? '编辑管理员' : '添加管理员'}}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button type="primary" @click="goBackPage" icon="arrow-left">返回列表</el-button>
|
||||
<!--<el-button type="primary" @click="testa" icon="arrow-left">测试</el-button>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :rules="infoRules" :model="infoForm" label-width="120px">
|
||||
<el-form-item label="管理员用户名" prop="username">
|
||||
<el-input v-model="infoForm.username"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" v-if="infoForm.id" prop="newpassword">
|
||||
<el-switch
|
||||
v-model="change"
|
||||
active-color="#13ce66">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="" v-if="change" prop="newpassword">
|
||||
<el-input type="password" v-model="infoForm.newpassword" placeholder="输入新的密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" v-if="!infoForm.id" prop="password">
|
||||
<el-input type="password" v-model="infoForm.password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button v-if="infoForm.id > 0" type="primary" @click="saveAdminInfo">确定保存</el-button>
|
||||
<el-button v-else type="primary" @click="addAdminInfo">确定添加</el-button>
|
||||
<el-button @click="goBackPage">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
change:false,
|
||||
infoForm: {
|
||||
id: 0,
|
||||
username: "",
|
||||
newpassword: '',
|
||||
password: ''
|
||||
},
|
||||
infoRules: {
|
||||
username: [
|
||||
{required: true, message: '请输入昵称', trigger: 'blur'},
|
||||
],
|
||||
password: [
|
||||
{required: true, message: '请输入密码', trigger: 'blur'},
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
testa() {
|
||||
console.log(this.tableData);
|
||||
console.log(this.infoForm);
|
||||
},
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
saveAdminInfo() {
|
||||
let user = this.infoForm;
|
||||
if(this.change == true){
|
||||
let password = user.newpassword;
|
||||
if(password == undefined){
|
||||
user.newpassword = ''
|
||||
}
|
||||
if(password != undefined && password.replace(/(^\s*)|(\s*$)/g, "").length < 6){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '密码请大于6个字符'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('admin/adminSave', {
|
||||
user: user,
|
||||
change:this.change,
|
||||
}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
});
|
||||
}
|
||||
else if (response.data.errno === 400) {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: response.data.errmsg
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
addAdminInfo() {
|
||||
let user = this.infoForm;
|
||||
let password = user.password;
|
||||
if(password == undefined){
|
||||
user.password = ''
|
||||
}
|
||||
if(password != undefined && password.replace(/(^\s*)|(\s*$)/g, "").length < 6){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '密码请大于6个字符'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('admin/adminAdd', {
|
||||
user: user,
|
||||
}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '添加成功'
|
||||
});
|
||||
this.$router.push({ name: 'admin'} )
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '添加失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getInfo() {
|
||||
//加载品牌详情
|
||||
let that = this
|
||||
this.axios.post('admin/adminDetail', {
|
||||
id: that.infoForm.id
|
||||
}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
let resInfo = response.data.data;
|
||||
that.infoForm = resInfo;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.infoForm.id = this.$route.query.id || 0;
|
||||
console.log(this.infoForm.id);
|
||||
this.getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.image-uploader {
|
||||
height: 105px;
|
||||
}
|
||||
|
||||
.image-uploader .el-upload {
|
||||
border: 1px solid #d9d9d9;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-uploader .el-upload:hover {
|
||||
border-color: #20a0ff;
|
||||
}
|
||||
|
||||
.image-uploader .image-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 187px;
|
||||
height: 105px;
|
||||
line-height: 105px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-uploader .image-show {
|
||||
width: 187px;
|
||||
height: 105px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.image-uploader.new-image-uploader {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 165px;
|
||||
height: 105px;
|
||||
line-height: 105px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-uploader.new-image-uploader .image-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 165px;
|
||||
height: 105px;
|
||||
line-height: 105px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-uploader.new-image-uploader .image-show {
|
||||
width: 165px;
|
||||
height: 105px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>管理员</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<!-- <div class="operation-nav">
|
||||
<router-link to="/dashboard/user">
|
||||
<el-button type="primary" icon="plus">添加管理员</el-button>
|
||||
</router-link>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="60"></el-table-column>
|
||||
<el-table-column prop="username" label="会员名称"></el-table-column>
|
||||
<el-table-column prop="last_login_time" label="最近登录" width="200"></el-table-column>
|
||||
<el-table-column prop="last_login_ip" label="登录IP" width="200"></el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button v-if="scope.row.id != loginInfo.id" plain size="small" type="danger" @click="handleRowDelete(scope.$index, scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
username: ''
|
||||
},
|
||||
tableData: [],
|
||||
loginInfo:null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({ name: 'admin_add', query: { id: row.id } })
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
console.log(row);
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.axios.post('admin/deleAdmin', { id: row.id }).then((response) => {
|
||||
console.log(response.data);
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
onSubmitFilter() {
|
||||
this.page = 1
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('admin').then((response) => {
|
||||
this.tableData = response.data.data;
|
||||
console.log(this.tableData);
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
if(!this.loginInfo){
|
||||
this.loginInfo = JSON.parse(window.localStorage.getItem('userInfo') || null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<span :endTime="endTime" :callback="callback" :endText="endText">
|
||||
<slot>
|
||||
{{content}}
|
||||
</slot>
|
||||
</span>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
endTime:'',
|
||||
}
|
||||
},
|
||||
props: {
|
||||
// endTime: {
|
||||
// type: String,
|
||||
// default: ''
|
||||
// },
|
||||
endText: {
|
||||
type: String,
|
||||
default: '已结束'
|
||||
},
|
||||
callback: {
|
||||
type: Function,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getInfo();
|
||||
|
||||
},
|
||||
methods: {
|
||||
getInfo() {
|
||||
this.axios.get('index',).then((response) => {
|
||||
console.log(response);
|
||||
this.infoData = response.data.data;
|
||||
let time = response.data.data.timestamp;
|
||||
this.endTime = time.toString();
|
||||
this.countdowm(this.endTime)
|
||||
})
|
||||
},
|
||||
countdowm(timestamp) {
|
||||
let self = this;
|
||||
let timer = setInterval(function () {
|
||||
let nowTime = new Date();
|
||||
let endTime = new Date(timestamp * 1000);
|
||||
let t = endTime.getTime() - nowTime.getTime() - 10;
|
||||
if (t > 0) {
|
||||
let day = Math.floor(t / 86400000);
|
||||
let hour = Math.floor((t / 3600000) % 24);
|
||||
let min = Math.floor((t / 60000) % 60);
|
||||
let sec = Math.floor((t / 1000) % 60);
|
||||
hour = hour < 10 ? "0" + hour : hour;
|
||||
min = min < 10 ? "0" + min : min;
|
||||
sec = sec < 10 ? "0" + sec : sec;
|
||||
let format = '';
|
||||
if (day > 0) {
|
||||
format = `${day}天${hour}小时${min}分${sec}秒`;
|
||||
}
|
||||
if (day <= 0 && hour > 0) {
|
||||
format = `${hour}小时${min}分${sec}秒`;
|
||||
}
|
||||
if (day <= 0 && hour <= 0) {
|
||||
format = `${min}分${sec}秒`;
|
||||
}
|
||||
self.content = format;
|
||||
} else {
|
||||
clearInterval(timer);
|
||||
self.content = self.endText;
|
||||
self._callback();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
_callback() {
|
||||
if (this.callback && this.callback instanceof Function) {
|
||||
this.callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div class="right-box">
|
||||
<div class="navbar">
|
||||
<div class="menu">
|
||||
<div class="menu-item">
|
||||
<i class="fa fa-sign-out" @click="logout"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
this.$confirm('是否要退出?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
localStorage.clear();
|
||||
this.$router.replace({name: 'login'});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.right-box {
|
||||
background: #112233;
|
||||
height: 60px;
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 200px;
|
||||
z-index: 5;
|
||||
float: left;
|
||||
width: calc(100% - 200px);
|
||||
overflow: hidden;
|
||||
-webkit-box-shadow: 0 1px 8px rgba(0,21,41,.08);
|
||||
box-shadow: 2px 6px 8px rgba(0,21,41,.08);
|
||||
}
|
||||
.fa:hover{
|
||||
cursor:pointer
|
||||
}
|
||||
/*.fa-sign-out{*/
|
||||
/*color:#000000;*/
|
||||
/*}*/
|
||||
/*.fa-user{*/
|
||||
/*color:#000000;*/
|
||||
/*}*/
|
||||
.navbar {
|
||||
height: 60px;
|
||||
/*background: #fff;*/
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
|
||||
}
|
||||
|
||||
.navbar .menu {
|
||||
flex: 1;
|
||||
margin-top: 15px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.navbar .menu-item {
|
||||
margin: 0 15px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div class="left-box">
|
||||
<div class="logo">
|
||||
<img src="static/images/loading.gif" />
|
||||
</div>
|
||||
<div class="a" style="overflow-x: hidden; overflow-y: auto; height: 100%">
|
||||
<el-menu
|
||||
class="sidebar"
|
||||
:unique-opened="true"
|
||||
:default-active="currentPagePath"
|
||||
@open="handleOpen"
|
||||
:router="true"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-menu-item index="/dashboard/welcome">
|
||||
<i class="fa fa-tachometer"></i>
|
||||
<span>后台主页</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/order">
|
||||
<i class="fa fa-large fa-reorder"></i>
|
||||
<span>订单列表</span>
|
||||
</el-menu-item>
|
||||
<el-submenu index="goods">
|
||||
<template slot="title">
|
||||
<i class="fa fa-shopping-bag"></i>
|
||||
<span>商品管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/dashboard/goods">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>商品列表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/nature">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>商品设置</span>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item index="/dashboard/shopcart">
|
||||
<i class="fa fa-large fa-shopping-cart"></i>
|
||||
<span>购物车</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/user">
|
||||
<i class="fa fa-large fa-users"></i>
|
||||
<span>用户列表</span>
|
||||
</el-menu-item>
|
||||
<el-submenu index="settings">
|
||||
<template slot="title">
|
||||
<i class="fa fa-large fa-wrench"></i>
|
||||
<span>店铺设置</span>
|
||||
</template>
|
||||
<el-menu-item index="/dashboard/settings/showset">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>显示设置</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/ad">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>广告列表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/notice">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>公告管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/freight">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>运费模板</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/shipper">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>快递设置</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/dashboard/admin">
|
||||
<i class="fa fa-circle"></i>
|
||||
<span>管理员</span>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item @click="logout">
|
||||
<i class="fa fa-large fa-sign-out"></i>
|
||||
<span>退出</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentPagePath: "/dashboard",
|
||||
loginInfo: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleOpen(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
handleClose(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
logout() {
|
||||
this.$confirm("是否要退出?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(() => {
|
||||
localStorage.clear();
|
||||
this.$router.replace({ name: "login" });
|
||||
});
|
||||
},
|
||||
checkLogin() {
|
||||
this.axios.get("index/checkLogin").then((response) => {
|
||||
console.log(response.data);
|
||||
if (response.data.errno === 401) {
|
||||
localStorage.clear();
|
||||
this.$router.replace({ name: "login" });
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.$route.path);
|
||||
this.checkLogin();
|
||||
if (!this.loginInfo) {
|
||||
this.loginInfo = JSON.parse(
|
||||
window.localStorage.getItem("userInfo") || null
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.left-box {
|
||||
width: 200px;
|
||||
display: flex;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
height: 100%;
|
||||
float: left;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.left-box .sidebar {
|
||||
width: 200px;
|
||||
flex: 1;
|
||||
border-radius: 0;
|
||||
/*background: #233445;*/
|
||||
}
|
||||
|
||||
.left-box .fa {
|
||||
margin-right: 10px;
|
||||
font-size: 18px;
|
||||
/*color: #ccc;*/
|
||||
}
|
||||
|
||||
.left-box span {
|
||||
/*color: #ccc;*/
|
||||
}
|
||||
|
||||
.left-box .el-submenu .el-menu-item .fa {
|
||||
margin-right: 10px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/*渐变背景*/
|
||||
.back {
|
||||
background: -webkit-linear-gradient(138deg, #8731e8 0%, #4528dc 100%);
|
||||
background: -o-linear-gradient(138deg, #8731e8 0%, #4528dc 100%);
|
||||
background: linear-gradient(-48deg, #8731e8 0%, #4528dc 100%);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.left-box .logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 120px;
|
||||
width: 200px;
|
||||
border-right: solid 1px #e6e6e6;
|
||||
/*box-shadow: 0 1px 1px rgba(0, 0, 0, .5);*/
|
||||
}
|
||||
|
||||
.left-box .logo img {
|
||||
height: 60px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,61 @@
|
||||
<style scoped>
|
||||
body {
|
||||
background: #f5f7fa;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
padding: 20px 20px 20px 220px;
|
||||
min-height: 700px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
color: #999;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="container">
|
||||
<sidebar></sidebar>
|
||||
<!-- <navbar></navbar> -->
|
||||
<div class="content">
|
||||
<transition name="router-fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Sidebar from './Common/Sidebar';
|
||||
import Navbar from './Common/Navbar';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Sidebar,
|
||||
Navbar
|
||||
},
|
||||
methods: {
|
||||
handleOpen(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
handleClose(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,309 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'freight' }">运费模板</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{infoForm.id ? '编辑偏远地区' : '添加偏远地区'}}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button type="primary" @click="goBackPage" icon="arrow-left">返回列表</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :rules="infoRules" :model="infoForm" label-width="120px">
|
||||
<el-form-item label="名称" prop="content">
|
||||
<el-input v-model="infoForm.content" placeholder="请输入名称" autofocus></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="special-freight">
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="areaName" label="偏远地区"></el-table-column>
|
||||
<el-table-column label="操作" width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="primary" plain
|
||||
@click="handleRowEdit(scope.$index, scope.row)">编辑地区
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!--<div class="add-btn" v-if="tableData.length == 0">-->
|
||||
<!--<el-button type="text" @click="add_template">+添加偏远地区</el-button>-->
|
||||
<!--</div>-->
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button v-if="infoForm.id" type="primary" @click="onSaveTemplate">确定保存</el-button>
|
||||
<el-button v-else type="primary" @click="onAddTemplate">确定添加</el-button>
|
||||
<el-button @click="goBackPage">返回列表</el-button>
|
||||
<!--<el-button @click="testCallBack">回调</el-button>-->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog size="tiny" title="设置偏远地区" :visible.sync="specEditVisible">
|
||||
<el-form ref="specForm" class="specFormDialig">
|
||||
<el-form-item label="" label-width="100px">
|
||||
<el-transfer v-model="selectedArea" :props="{key: 'id',label: 'name'}"
|
||||
:data="areaData" :titles="['可选', '已选']"></el-transfer>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="specEditVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="updateArea">确定</el-button>
|
||||
<!--<el-button type="primary" @click="updateSpec" v-if="!is_spec_add">确定修改</el-button>-->
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
areaData: [],
|
||||
selectedArea: [],
|
||||
specEditVisible: false,
|
||||
infoForm: {
|
||||
id: 0,
|
||||
content: ''
|
||||
},
|
||||
infoRules: {
|
||||
content: [
|
||||
{required: true, message: '请输入名称', trigger: 'blur'},
|
||||
],
|
||||
},
|
||||
tableData: [{
|
||||
area: '',
|
||||
ghost: 0
|
||||
}],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
testCallBack() {
|
||||
console.log(this.tableData);
|
||||
},
|
||||
updateArea() {
|
||||
|
||||
let all = this.areaData;
|
||||
let selected = this.selectedArea;
|
||||
selected = selected.join(',')
|
||||
this.tableData[0].area = selected;
|
||||
|
||||
let areaName = this.selectedArea;
|
||||
|
||||
let newName = [];
|
||||
for (const item in areaName) {
|
||||
all.map((ele) => ele.id == areaName[item] ? newName.push(ele.name) : '')
|
||||
}
|
||||
let that = this;
|
||||
let name = newName.join(',');
|
||||
|
||||
that.tableData = [];
|
||||
that.tableData.push({
|
||||
area: selected,
|
||||
areaName: name
|
||||
})
|
||||
|
||||
// console.log(this.tableData[index].areaName);
|
||||
that.specEditVisible = false;
|
||||
|
||||
|
||||
},
|
||||
onSaveTemplate() {
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
let data = this.tableData[0];
|
||||
if (data.area == '') {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '地区不能为空'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
let that = this;
|
||||
this.axios.post('shipper/saveExceptArea', {
|
||||
table: that.tableData,
|
||||
info: that.infoForm
|
||||
}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
});
|
||||
that.getInfo();
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
onAddTemplate() {
|
||||
console.log('哈哈哈');
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
let data = this.tableData[0];
|
||||
if (data.area == '') {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '地区不能为空'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
let that = this;
|
||||
this.axios.post('shipper/addExceptArea', {
|
||||
table: that.tableData,
|
||||
info: that.infoForm
|
||||
}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '添加成功'
|
||||
});
|
||||
this.$router.go(-1);
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '添加失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
test() {
|
||||
console.log(this.defaultData);
|
||||
},
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
getAllAreaData() {
|
||||
let that = this;
|
||||
this.axios.post('shipper/getareadata').then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
that.areaData = response.data.data;
|
||||
}
|
||||
})
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
|
||||
let nowArea = this.tableData[0].area;
|
||||
this.selectedArea = nowArea.split(',').map(Number);
|
||||
|
||||
let area = nowArea;
|
||||
area = area.split(',');
|
||||
let all = this.areaData;
|
||||
|
||||
this.specEditVisible = true;
|
||||
},
|
||||
|
||||
getInfo() {
|
||||
if (this.infoForm.id <= 0) {
|
||||
return false
|
||||
}
|
||||
//加载快递公司详情
|
||||
let that = this
|
||||
this.axios.post('shipper/exceptAreaDetail', {
|
||||
id: that.infoForm.id
|
||||
}).then((response) => {
|
||||
// console.log(response.data.data);
|
||||
let info = response.data.data;
|
||||
that.infoForm = info;
|
||||
that.tableData = [{
|
||||
area: info.area,
|
||||
areaName: info.areaName
|
||||
}]
|
||||
// that.tableData = response.data.data.data;
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.infoForm.id = this.$route.query.id || 0;
|
||||
// console.log(this.infoForm.id);
|
||||
this.getInfo();
|
||||
this.getAllAreaData();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.number_input {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.money_input {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.line-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.default-freight .el-input {
|
||||
width: 130px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.default-freight .el-input .el-input__inner {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.default-freight .line {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
border-right: 1px solid #f1f1f1;
|
||||
/*padding-right: 40px;*/
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.default-freight .line2 {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.default-freight .text {
|
||||
width: 60px;
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.default-freight .text2 {
|
||||
width: 50px;
|
||||
float: left;
|
||||
/*margin: 10px;*/
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
color: #3a8ee6;
|
||||
font-size: 14px;
|
||||
padding: 20px;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-top: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'freight' }">运费模板</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>偏远地区</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button type="primary" plain @click="addExceptArea" icon="arrow-left">添加偏远地区</el-button>
|
||||
<el-button type="primary" @click="goBackPage" icon="arrow-left">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="100px"></el-table-column>
|
||||
<el-table-column prop="content" label="名称" width="200px"></el-table-column>
|
||||
<el-table-column prop="areaName" label="偏远地区"></el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="small" plain
|
||||
@click="handleRowEdit(scope.$index, scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button size="small"
|
||||
@click="handleRowDelete(scope.$index, scope.row)"
|
||||
type="danger" plain>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: true,
|
||||
nowTableIndex: 0,
|
||||
areaData: [],
|
||||
selectedArea: [],
|
||||
hiddenSelectedArea: [],
|
||||
specEditVisible: false,
|
||||
tableData: [],
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
addExceptArea(){
|
||||
this.$router.push({name: 'except_area_add'});
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({ name: 'except_area_add', query: { id: row.id } })
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.axios.post('shipper/exceptAreaDelete', {id: row.id}).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getInfo();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
getInfo() {
|
||||
let that = this;
|
||||
this.axios.get('shipper/exceptarea').then((response) => {
|
||||
that.tableData = response.data.data;
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.number_input {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.money_input {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.line-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.default-freight .el-input {
|
||||
width: 130px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.default-freight .el-input .el-input__inner {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.default-freight .line {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
border-right: 1px solid #f1f1f1;
|
||||
/*padding-right: 40px;*/
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.default-freight .line2 {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.default-freight .text {
|
||||
width: 60px;
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.default-freight .text2 {
|
||||
width: 50px;
|
||||
float: left;
|
||||
/*margin: 10px;*/
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
color: #3a8ee6;
|
||||
font-size: 14px;
|
||||
padding: 20px;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-top: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>快递模板</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<!--<el-button icon="plus" @click="expressList">快递列表</el-button>-->
|
||||
<el-button icon="plus" @click="exceptareaList">偏远地区</el-button>
|
||||
<el-button type="primary" icon="plus" @click="addFreightTemplate">添加快递模板</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="100px"></el-table-column>
|
||||
<el-table-column prop="name" label="名字"></el-table-column>
|
||||
<el-table-column prop="package_price" label="包装费"></el-table-column>
|
||||
<el-table-column prop="freight_type" label="按件/按重" width="200">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.freight_type == 0 ? '按件' : '按重' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="170">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleRowDelete(scope.$index, scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
expressList(){
|
||||
this.$router.push({name: 'shipper'});
|
||||
},
|
||||
exceptareaList(){
|
||||
this.$router.push({name: 'except_area'});
|
||||
},
|
||||
addFreightTemplate(){
|
||||
this.$router.push({name: 'freight_add'});
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({name: 'freight_add', query: {id: row.id}})
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.axios.post('shipper/destory', {id: row.id}).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('shipper/freight').then((response) => {
|
||||
console.log(response);
|
||||
this.tableData = response.data.data
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'dashboard' }">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>数据管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{infoForm.id ? '编辑热门搜索' : '添加热门搜索'}}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button type="primary" @click="goBackPage" icon="arrow-left">返回列表</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :rules="infoRules" :model="infoForm" label-width="120px">
|
||||
|
||||
<el-form-item label="商品ID" prop="id">
|
||||
<el-input v-model="infoForm.id"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="关键词" prop="keyword">
|
||||
<el-input v-model="infoForm.keyword"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="infoForm.sort_order" :min="1" :max="1000"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitInfo">确定保存</el-button>
|
||||
<el-button @click="goBackPage">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
infoForm: {
|
||||
id: 0,
|
||||
keyword: '',
|
||||
},
|
||||
infoRules: {
|
||||
keyword: [
|
||||
{ required: true, message: '请输入关键词', trigger: 'blur' },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
onSubmitInfo() {
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('keywords/store', this.infoForm).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
});
|
||||
this.$router.go(-1)
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getInfo() {
|
||||
if (this.infoForm.id <= 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
//加载热门搜索详情
|
||||
let that = this
|
||||
this.axios.get('keywords/info', {
|
||||
params: {
|
||||
id: that.infoForm.id
|
||||
}
|
||||
}).then((response) => {
|
||||
let resInfo = response.data.data;
|
||||
that.infoForm = resInfo;
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
components: {
|
||||
},
|
||||
mounted() {
|
||||
this.infoForm.id = this.$route.query.id || 0;
|
||||
this.getInfo();
|
||||
console.log(api)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/dashboard' }">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>数据管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>热门搜索</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<router-link to="/dashboard/keywords/add">
|
||||
<el-button type="primary" icon="plus">添加热门搜索</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="filter-box">
|
||||
<el-form :inline="true" :model="filterForm" class="demo-form-inline">
|
||||
<el-form-item label="关键词">
|
||||
<el-input v-model="filterForm.name" placeholder="搜索关键词"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitFilter">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="100px">
|
||||
</el-table-column>
|
||||
<el-table-column prop="keyword" label="关键词">
|
||||
</el-table-column>
|
||||
<el-table-column prop="is_hot" label="is_hot">
|
||||
</el-table-column>
|
||||
<el-table-column prop="is_default" label="is_default">
|
||||
</el-table-column>
|
||||
<el-table-column prop="is_show" label="is_show">
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort_order" label="排序" width="80">
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleRowDelete(scope.$index, scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination @current-change="handlePageChange" :current-page="page" :page-size="10" layout="total, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlePageChange(val) {
|
||||
this.page = val;
|
||||
//保存到localStorage
|
||||
localStorage.setItem('keywordsPage', this.page)
|
||||
localStorage.setItem('keywordsFilterForm', JSON.stringify(this.filterForm));
|
||||
this.getList()
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({ name: 'keywords_add', query: { id: row.id } })
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
this.axios.post('keywords/destory', { id: row.id }).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
},
|
||||
onSubmitFilter() {
|
||||
this.page = 1
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('keywords', {
|
||||
params: {
|
||||
page: this.page,
|
||||
name: this.filterForm.name
|
||||
}
|
||||
}).then((response) => {
|
||||
this.tableData = response.data.data.data
|
||||
this.page = response.data.data.currentPage
|
||||
this.total = response.data.data.count
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div class="login">
|
||||
<div class="login-box">
|
||||
<div class="logo">
|
||||
<img src="static/images/loading.gif" />
|
||||
</div>
|
||||
<div class="body">
|
||||
<p class="tips">海风小店</p>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-position="top">
|
||||
<el-form-item label="" prop="username">
|
||||
<el-input v-model="form.username" placeholder="用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
v-model="form.password"
|
||||
placeholder="密码"
|
||||
@keyup.enter.native="startLogin"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="startLogin"
|
||||
:loading="loading"
|
||||
style="width: 100%"
|
||||
>
|
||||
{{ loading ? "登录中..." : "登录" }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import api from "@/config/api";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
root: "",
|
||||
form: {
|
||||
username: "",
|
||||
password: "",
|
||||
},
|
||||
rules: {
|
||||
username: [
|
||||
{ required: true, message: "请输入用户名", trigger: "blur" },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
{ min: 6, message: "密码不得低于6个字符", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
components: {},
|
||||
methods: {
|
||||
startLogin() {
|
||||
console.log("<<<<<<<<==================>>>>>>>>");
|
||||
console.log(123123);
|
||||
console.log("<<<<<<<<==================>>>>>>>>");
|
||||
this.$refs["form"].validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
this.loading = true;
|
||||
let root = this.root;
|
||||
this.axios
|
||||
.post(root + "auth/login", {
|
||||
username: this.form.username,
|
||||
password: this.form.password,
|
||||
})
|
||||
.then((res) => {
|
||||
let call = res.data;
|
||||
console.log(call);
|
||||
this.loading = false;
|
||||
if (res.data.errno === 0) {
|
||||
console.log(res.data.data);
|
||||
localStorage.setItem("token", res.data.data.token);
|
||||
localStorage.setItem(
|
||||
"userInfo",
|
||||
JSON.stringify(res.data.data.userInfo)
|
||||
);
|
||||
console.log(JSON.stringify(res.data.data.token));
|
||||
console.log(JSON.stringify(res.data.data.userInfo));
|
||||
this.$router.push({ name: "welcome" });
|
||||
let sUserAgent = navigator.userAgent;
|
||||
// todo 手机端
|
||||
let mobileAgents = [
|
||||
"Android",
|
||||
"iPhone",
|
||||
"Symbian",
|
||||
"WindowsPhone",
|
||||
"iPod",
|
||||
"BlackBerry",
|
||||
"Windows CE",
|
||||
];
|
||||
let goUrl = 0;
|
||||
for (var i = 0; i < mobileAgents.length; i++) {
|
||||
if (sUserAgent.indexOf(mobileAgents[i]) > -1) {
|
||||
goUrl = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log(goUrl);
|
||||
if (goUrl == 1) {
|
||||
this.$router.push({ name: "wap" });
|
||||
}
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: call.errmsg,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.loading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.root = api.rootUrl;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.login {
|
||||
align-items: center;
|
||||
background: url("https://www.qile.club/img/back.jpg");
|
||||
/* 以上为登录背景,可以自己更换成自己喜欢的 */
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
font-family: Lato, Helvetica, sans-serif;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: #656565;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
width: 320px;
|
||||
background: #fff;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 2px 2px 12px #ccc;
|
||||
}
|
||||
|
||||
.login-box .logo {
|
||||
height: 100px;
|
||||
padding-top: 30px;
|
||||
/*background: #324157;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.login-box .logo img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.login-box .body {
|
||||
padding: 10px 30px 30px 30px;
|
||||
}
|
||||
|
||||
.login-box .body .tips {
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.login-box .body .author {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #656565;
|
||||
margin-bottom: 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.login-box .body .author a {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>公告管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<div style="margin-left:10px;"></div>
|
||||
<el-button type="primary" icon="plus" @click="addNotice">添加公告</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="60"></el-table-column>
|
||||
<el-table-column prop="content" label="内容"></el-table-column>
|
||||
<el-table-column prop="end_time" label="结束时间" width="180"></el-table-column>
|
||||
<el-table-column prop="enabled" label="状态" width="110px">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.is_delete == 0 ? '启用中' : '已到期下线' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220px">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button plain size="small" type="danger"
|
||||
@click="handleRowDelete(scope.$index, scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="is_add? '添加':'编辑'" :visible.sync="dialog">
|
||||
<el-form :model="noticeData">
|
||||
<el-form-item label="内容:" label-width="120px">
|
||||
<el-input class="el-input" v-model="noticeData.content" auto-complete="off"
|
||||
placeholder="请输入内容"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="到期时间:" label-width="120px">
|
||||
<el-date-picker
|
||||
v-model="noticeData.time"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
default-time="23:59:59">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialog = false">取 消</el-button>
|
||||
<!--<el-button @click="test">取 消</el-button>-->
|
||||
<el-button type="primary" @click="goNotice" v-if="is_add">确定添加</el-button>
|
||||
<el-button type="primary" @click="updateNotice" v-if="!is_add">确定修改</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
noticeData: {
|
||||
time:'',
|
||||
content:''
|
||||
},
|
||||
dialog: false,
|
||||
is_add: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
test(){
|
||||
console.log(this.noticeData);
|
||||
},
|
||||
updateNotice() {
|
||||
console.log(this.noticeData);
|
||||
if(this.noticeData.content == ''){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '内容不能为空'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
else if(this.noticeData.time == null){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '过期时间不能为空'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
this.axios.post('notice/update', this.noticeData).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '添加成功!'
|
||||
});
|
||||
this.getList();
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '添加失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
this.dialog = false;
|
||||
},
|
||||
goNotice() {
|
||||
console.log(this.noticeData);
|
||||
if(this.noticeData.content == ''){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '内容不能为空'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
else if(this.noticeData.time == null){
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '过期时间不能为空'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
this.axios.post('notice/add', this.noticeData).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '添加成功!'
|
||||
});
|
||||
this.getList();
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '添加失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
this.dialog = false;
|
||||
},
|
||||
addNotice() {
|
||||
this.dialog = true;
|
||||
this.is_add = true;
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.noticeData.time = row.end_time;
|
||||
this.noticeData.content = row.content;
|
||||
this.noticeData.id = row.id;
|
||||
this.dialog = true;
|
||||
this.is_add = false;
|
||||
},
|
||||
submitContent(index, row) {
|
||||
this.axios.post('notice/updateContent', {id: row.id, content: row.content}).then((response) => {
|
||||
|
||||
})
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
this.axios.post('notice/destory', {id: row.id}).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('notice').then((response) => {
|
||||
this.tableData = response.data.data;
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'shipper' }">快递设置</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>快递列表</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button plain type="primary" @click="addShipper" icon="arrow-left">添加快递</el-button>
|
||||
<el-button @click="goBackPage" icon="arrow-left">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="filter-box">
|
||||
<el-form :inline="true" :model="filterForm" class="demo-form-inline">
|
||||
<el-form-item label="快递公司">
|
||||
<el-input v-model="filterForm.name" placeholder="搜索快递公司"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitFilter">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="100px">
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名字" width="220">
|
||||
</el-table-column>
|
||||
<el-table-column prop="code" label="代号" width="220">
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort_order" label="排序" width="220">
|
||||
<template slot-scope="scope">
|
||||
<el-input-number class="sort-width" size="mini" :min="1" :max="100" controls-position="right" v-model="scope.row.sort_order" placeholder="排序" @blur="submitSort(scope.$index, scope.row)" @change="submitSort(scope.$index, scope.row)"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.enabled"
|
||||
active-text=""
|
||||
inactive-text=""
|
||||
@change='changeStatus($event,scope.row.id)'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleRowDelete(scope.$index, scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination @current-change="handlePageChange" :current-page="page" :page-size="10" layout="total, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitSort(index, row){
|
||||
this.axios.post('shipper/updateSort', { id: row.id,sort:row.sort_order }).then((response) => {})
|
||||
},
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
handlePageChange(val) {
|
||||
this.page = val;
|
||||
//保存到localStorage
|
||||
localStorage.setItem('shipperPage', this.page)
|
||||
localStorage.setItem('shipperFilterForm', JSON.stringify(this.filterForm));
|
||||
this.getList()
|
||||
},
|
||||
addShipper() {
|
||||
this.$router.push({ name: 'shipper_add', query: { id: 0 } })
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({ name: 'shipper_add', query: { id: row.id } })
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.axios.post('shipper/destory', { id: row.id }).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
onSubmitFilter() {
|
||||
this.page = 1
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('shipper/list', {
|
||||
params: {
|
||||
page: this.page,
|
||||
name: this.filterForm.name
|
||||
}
|
||||
}).then((response) => {
|
||||
this.tableData = response.data.data.data
|
||||
this.page = response.data.data.currentPage
|
||||
this.total = response.data.data.count
|
||||
console.log(this.tableData)
|
||||
for(const item of this.tableData){
|
||||
item.enabled = item.enabled?true:false
|
||||
}
|
||||
})
|
||||
},
|
||||
changeStatus($event, para) {
|
||||
this.axios.get('shipper/enabledStatus', {
|
||||
params: {
|
||||
status: $event,
|
||||
id: para
|
||||
}
|
||||
}).then((response) => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '更新成功!'
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>快递设置</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<router-link to="/dashboard/shipper/list">
|
||||
<el-button type="primary" icon="plus">快递公司列表</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :model="infoForm" :rules="infoRules" label-width="120px">
|
||||
<el-form-item label="打印后自动发货">
|
||||
<el-switch v-model="infoForm.autoDelivery"
|
||||
@change='changeStatus(infoForm.autoDelivery)'></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="寄件人" prop="Name">
|
||||
<el-input v-model="infoForm.Name" placeholder="请输入非代理发货时的寄件人"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="Tel">
|
||||
<el-input v-model="infoForm.Tel" placeholder="请输入电话"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="省份" prop="ProvinceName">
|
||||
<el-cascader
|
||||
:options="options"
|
||||
placeholder="请选择地区"
|
||||
v-model="senderOptions">
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
<!---->
|
||||
<!--<el-form-item label="省份" prop="ProvinceName">-->
|
||||
<!--<el-input v-model="infoForm.ProvinceName" placeholder="请输入省份"></el-input>-->
|
||||
<!--</el-form-item>-->
|
||||
<!--<el-form-item label="城市" prop="CityName">-->
|
||||
<!--<el-input v-model="infoForm.CityName" placeholder="请输入城市"></el-input>-->
|
||||
<!--</el-form-item>-->
|
||||
<!--<el-form-item label="区/县" prop="ExpAreaName">-->
|
||||
<!--<el-input v-model="infoForm.ExpAreaName" placeholder="请输入区/县"></el-input>-->
|
||||
<!--</el-form-item>-->
|
||||
<el-form-item label="地址" prop="Address">
|
||||
<el-input v-model="infoForm.Address" placeholder="请输入具体地址"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSaveSubmit">确定保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
<div class="form-table-box">
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="使用中的快递">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="name" label="名字"></el-table-column>
|
||||
<el-table-column prop="code" label="代号"></el-table-column>
|
||||
<el-table-column prop="CustomerName" label="客户编号"></el-table-column>
|
||||
<el-table-column prop="MonthCode" label="月结账号"></el-table-column>
|
||||
<el-table-column label="操作" width="170">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
infoForm: {},
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: [],
|
||||
options: [],
|
||||
senderOptions:[],
|
||||
infoRules: {
|
||||
Name: [
|
||||
{required: true, message: '请输入寄件人姓名', trigger: 'blur'},
|
||||
],
|
||||
Tel: [
|
||||
{required: true, message: '请输入寄件人电话', trigger: 'blur'},
|
||||
],
|
||||
ProvinceName: [
|
||||
{required: true, message: '请输入寄件省份', trigger: 'blur'},
|
||||
],
|
||||
CityName: [
|
||||
{required: true, message: '请输入寄件城市', trigger: 'blur'},
|
||||
],
|
||||
ExpAreaName: [
|
||||
{required: true, message: '请输入寄件区县', trigger: 'blur'},
|
||||
],
|
||||
Address: [
|
||||
{required: true, message: '请输入寄件人具体地址', trigger: 'blur'},
|
||||
],
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAllRegion() {
|
||||
let that = this;
|
||||
this.axios.get('order/getAllRegion').then((response) => {
|
||||
this.options = response.data.data;
|
||||
})
|
||||
},
|
||||
changeStatus() {
|
||||
this.infoForm.autoDelivery == true ? this.infoForm.autoDelivery = 1 : this.infoForm.autoDelivery = 0;
|
||||
this.axios.post('admin/changeAutoStatus', {status:this.infoForm.autoDelivery}).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '更改成功'
|
||||
});
|
||||
this.infoForm.autoDelivery == 1 ? this.infoForm.autoDelivery = true : this.infoForm.autoDelivery = false
|
||||
}
|
||||
else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '更改失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({name: 'shipper_add', query: {id: row.id}})
|
||||
},
|
||||
onSaveSubmit() {
|
||||
this.infoForm.province_id = this.senderOptions[0];
|
||||
this.infoForm.city_id = this.senderOptions[1];
|
||||
this.infoForm.district_id = this.senderOptions[2];
|
||||
this.infoForm.autoDelivery == true ? this.infoForm.autoDelivery = 1 : this.infoForm.autoDelivery = 0;
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('admin/storeShipperSettings', this.infoForm).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
});
|
||||
this.infoForm.autoDelivery == 1 ? this.infoForm.autoDelivery = true : this.infoForm.autoDelivery = false
|
||||
}
|
||||
else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('shipper').then((response) => {
|
||||
this.infoForm = response.data.data.set;
|
||||
this.tableData = response.data.data.info;
|
||||
this.infoForm.autoDelivery == 1 ? this.infoForm.autoDelivery = true : this.infoForm.autoDelivery = false
|
||||
this.senderOptions.push(
|
||||
this.infoForm.province_id,
|
||||
this.infoForm.city_id,
|
||||
this.infoForm.district_id
|
||||
)
|
||||
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.getList();
|
||||
this.getAllRegion();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.form-table-box {
|
||||
border: 1px solid #f1f1f1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>购物车列表</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="filter-box">
|
||||
<el-form :inline="true" :model="filterForm" class="demo-form-inline">
|
||||
<el-form-item label="商品名称">
|
||||
<el-input v-model="filterForm.name" placeholder="商品名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitFilter">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="60px">
|
||||
</el-table-column>
|
||||
<el-table-column prop="user_id" label="用户ID" width="80px"></el-table-column>
|
||||
<el-table-column prop="nickname" label="用户昵称" width="100px"></el-table-column>
|
||||
<el-table-column prop="goods_id" label="商品ID" width="100px"></el-table-column>
|
||||
<el-table-column prop="list_pic_url" label="图片" width="70px">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.list_pic_url" alt="" style="width: 50px;height: 50px">
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="goods_name" label="商品名称"></el-table-column>
|
||||
<el-table-column prop="goods_specifition_name_value" label="型号"></el-table-column>
|
||||
<el-table-column prop="number" label="数量" width="70px"></el-table-column>
|
||||
<el-table-column prop="retail_price" label="成交价"></el-table-column>
|
||||
<el-table-column prop="add_time" label="加入时间"></el-table-column>
|
||||
<el-table-column prop="is_delete" label="是否删除">
|
||||
<template slot-scope="scope">
|
||||
<label>{{scope.row.is_delete == 1? '已删':''}}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination @current-change="handlePageChange" :current-page="page" :page-size="10" layout="total, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlePageChange(val) {
|
||||
this.page = val;
|
||||
//保存到localStorage
|
||||
localStorage.setItem('shopCartPage', this.page)
|
||||
localStorage.setItem('shopCartFilterForm', JSON.stringify(this.filterForm));
|
||||
this.getList()
|
||||
},
|
||||
|
||||
onSubmitFilter() {
|
||||
this.page = 1
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('shopcart', {
|
||||
params: {
|
||||
page: this.page,
|
||||
name: this.filterForm.name
|
||||
}
|
||||
}).then((response) => {
|
||||
this.tableData = response.data.data.data
|
||||
this.page = response.data.data.currentPage
|
||||
this.total = response.data.data.count
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
|
||||
<el-breadcrumb-item>显示设置</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button type="primary" @click="onSubmitInfo">确定保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :model="infoForm" label-width="120px">
|
||||
<el-form-item label="广告" prop="type">
|
||||
<el-radio-group v-model="infoForm.banner">
|
||||
<el-radio :label="1">显示</el-radio>
|
||||
<el-radio :label="0">不显示</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="公告">
|
||||
<el-radio-group v-model="infoForm.notice">
|
||||
<el-radio :label="1">显示</el-radio>
|
||||
<el-radio :label="0">不显示</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="广告下的图标">
|
||||
<el-radio-group v-model="infoForm.channel">
|
||||
<el-radio :label="1">显示</el-radio>
|
||||
<el-radio :label="0">不显示</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="form-tip">那几个图标</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="首页分类图片或文字">
|
||||
<el-radio-group v-model="infoForm.index_banner_img">
|
||||
<el-radio :label="1">图片</el-radio>
|
||||
<el-radio :label="0">文字</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitInfo">确定保存</el-button>
|
||||
<el-button @click="goBackPage">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: [],
|
||||
infoForm: {
|
||||
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
test(){
|
||||
console.log(this.value);
|
||||
},
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
onSubmitInfo() {
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('admin/showsetStore', this.infoForm).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功'
|
||||
});
|
||||
// this.$router.go(-1)
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getInfo() {
|
||||
if (this.infoForm.id <= 0) {
|
||||
return false
|
||||
}
|
||||
//加载优惠券详情
|
||||
let that = this
|
||||
this.axios.get('admin/showset').then((response) => {
|
||||
let resInfo = response.data.data;
|
||||
that.infoForm = resInfo;
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.el-form-item .date-picker {
|
||||
width: 450px!important;
|
||||
max-width: 410px!important;
|
||||
}
|
||||
.el-form-item .date-picker input {
|
||||
width: 410px!important;
|
||||
max-width: 410px!important;
|
||||
}
|
||||
.margin-left{
|
||||
margin-left:20px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item :to="{ name: 'nature' }">商品设置</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{infoForm.id ? '编辑型号' : '添加型号'}}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="operation-nav">
|
||||
<el-button type="primary" @click="goBackPage" icon="arrow-left">返回列表</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="form-table-box">
|
||||
<el-form ref="infoForm" :rules="infoRules" :model="infoForm" label-width="120px">
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="infoForm.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="infoForm.sort_order" :min="1" :max="1000"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button v-if="infoForm.id > 0" type="primary" @click="updateSpec">确定保存</el-button>
|
||||
<el-button v-else type="primary" @click="addSpec">确定添加</el-button>
|
||||
<el-button v-if="infoForm.id > 0" type="danger" @click="specDelete">删除</el-button>
|
||||
<el-button @click="goBackPage">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
infoForm: {
|
||||
id: 0,
|
||||
name: "",
|
||||
sort_order: 1,
|
||||
},
|
||||
infoRules:{
|
||||
name: [
|
||||
{required: true, message: '请输入名称', trigger: 'blur'},
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addSpec(){
|
||||
let info = {
|
||||
name:this.infoForm.name,
|
||||
sort_order:this.infoForm.sort_order
|
||||
}
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('specification/add', info).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '添加成功!'
|
||||
});
|
||||
this.$router.go(-1);
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '添加失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateSpec(){
|
||||
let info = {
|
||||
id:this.infoForm.id,
|
||||
name:this.infoForm.name,
|
||||
sort_order:this.infoForm.sort_order
|
||||
}
|
||||
this.$refs['infoForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.axios.post('specification/update', info).then((response) => {
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功!'
|
||||
});
|
||||
this.$router.go(-1);
|
||||
} else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '保存失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
specDelete(index, row) {
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.axios.post('specification/delete', {id: row.id}).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.$router.go(-1);
|
||||
}
|
||||
else {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '删除失败,该型号下有商品!'
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
goBackPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
getInfo() {
|
||||
console.log(this.infoForm.id);
|
||||
console.log(this.infoForm.id);
|
||||
console.log(this.infoForm.id);
|
||||
if (this.infoForm.id <= 0) {
|
||||
return false
|
||||
}
|
||||
let that = this
|
||||
this.axios.post('specification/detail', {
|
||||
id: that.infoForm.id
|
||||
}).then((response) => {
|
||||
let resInfo = response.data.data;
|
||||
console.log(resInfo);
|
||||
that.infoForm = resInfo;
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
mounted() {
|
||||
this.infoForm.id = this.$route.query.id || 0;
|
||||
|
||||
this.getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.image-uploader {
|
||||
height: 105px;
|
||||
}
|
||||
|
||||
.image-uploader .el-upload {
|
||||
border: 1px solid #d9d9d9;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-uploader .el-upload:hover {
|
||||
border-color: #20a0ff;
|
||||
}
|
||||
|
||||
.image-uploader .image-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
min-width: 105px;
|
||||
height: 105px;
|
||||
line-height: 105px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-show {
|
||||
background-color: #f8f8f8;
|
||||
min-width: 105px;
|
||||
height: 105px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div class="content-page">
|
||||
<div class="content-nav">
|
||||
<el-breadcrumb class="breadcrumb" separator="/">
|
||||
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="filter-box">
|
||||
<el-form :inline="true" :model="filterForm" class="demo-form-inline">
|
||||
<el-form-item label="用户昵称">
|
||||
<el-input v-model="filterForm.nickname" placeholder="用户昵称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmitFilter">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" border stripe>
|
||||
<el-table-column prop="id" label="ID" width="60">
|
||||
</el-table-column>
|
||||
<el-table-column label="头像" width="80">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.avatar" alt="" style="width: 50px;height: 50px">
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--<el-table-column prop="username" label="会员名称">-->
|
||||
<!--</el-table-column>-->
|
||||
<el-table-column prop="nickname" label="昵称">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.nickname" placeholder="昵称" @blur="submitNick(scope.$index, scope.row)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="gender" label="性别" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.gender == 2 ? '女' : '男' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--<el-table-column prop="mobile" label="手机号"></el-table-column>-->
|
||||
<el-table-column prop="register_time" label="注册时间" width="180">
|
||||
</el-table-column>
|
||||
<el-table-column prop="last_login_time" label="最近登录" width="180">
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleRowEdit(scope.$index, scope.row)">编辑</el-button>
|
||||
<!-- <el-button plain size="small" type="danger" @click="handleRowDelete(scope.$index, scope.row)">删除</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="page-box">
|
||||
<el-pagination background @current-change="handlePageChange" :current-page.sync="page" :page-size="10" layout="total, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: [],
|
||||
loginInfo:null,
|
||||
username:''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitNick(index, row){
|
||||
this.axios.post('user/updateInfo', { id: row.id,nickname:row.nickname }).then((response) => {
|
||||
|
||||
})
|
||||
},
|
||||
handlePageChange(val) {
|
||||
this.page = val;
|
||||
//保存到localStorage
|
||||
localStorage.setItem('userPage', this.page)
|
||||
this.getList()
|
||||
},
|
||||
handleRowEdit(index, row) {
|
||||
this.$router.push({ name: 'user_add', query: { id: row.id } })
|
||||
},
|
||||
handleRowDelete(index, row) {
|
||||
|
||||
this.$confirm('确定要删除?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
this.axios.post('user/destory', { id: row.id }).then((response) => {
|
||||
console.log(response.data)
|
||||
if (response.data.errno === 0) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
},
|
||||
onSubmitFilter() {
|
||||
this.page = 1
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.axios.get('user', {
|
||||
params: {
|
||||
page: this.page,
|
||||
nickname: this.filterForm.nickname
|
||||
}
|
||||
}).then((response) => {
|
||||
console.log(response.data);
|
||||
console.log(response);
|
||||
this.tableData = response.data.data.userData.data;
|
||||
this.page = response.data.data.userData.currentPage;
|
||||
this.total = response.data.data.userData.count;
|
||||
})
|
||||
if(!this.loginInfo){
|
||||
this.loginInfo = JSON.parse(window.localStorage.getItem('userInfo') || null);
|
||||
this.username = this.loginInfo.username;
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
let thePage = localStorage.getItem('userPage');
|
||||
if(thePage == null){
|
||||
thePage = 1;
|
||||
}
|
||||
this.page = Number(thePage);
|
||||
console.log(this.page);
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="wrap">
|
||||
<div class="top">
|
||||
<img src="http://lucky-icon.meiweiyuxian.com/hio/pinwheel.jpg"/>
|
||||
<div class="menu">
|
||||
<div class="menu-item">
|
||||
<router-link to="/dashboard">
|
||||
<i class="fa fa-user"></i>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<i class="fa fa-sign-out" @click="logout"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header clearfix">
|
||||
<el-card class="box-card card-red">
|
||||
|
||||
<div class="text item">商品</div>
|
||||
|
||||
</el-card>
|
||||
<el-card class="box-card card-green">
|
||||
<h1></h1>
|
||||
<div class="text item">订单</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div></div>
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" stripe>
|
||||
<el-table-column prop="list_pic_url" label="图片" width="80">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.list_pic_url" alt="" style="width: 60px;height: 60px">
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="商品名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="retail_price" label="售价" width="90" sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.retail_price" placeholder="售价"
|
||||
@blur="submit(scope.$index, scope.row)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架" width="60">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="tableData[scope.$index].is_on_sale"
|
||||
active-text=""
|
||||
inactive-text=""
|
||||
@change='changeStatus($event,tableData[scope.$index].goods_id)'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script scoped>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
methods: {
|
||||
|
||||
logout() {
|
||||
this.$confirm('是否要退出?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
center: true
|
||||
}).then(() => {
|
||||
localStorage.clear();
|
||||
this.$router.replace({name: 'login'});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
this.root = api.rootUrl;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="footer-box">
|
||||
<el-menu class="foot-wrap" :unique-opened="true" :default-active="currentPagePath"
|
||||
:router="true">
|
||||
<el-menu-item class="btn-footer" index="/wap">
|
||||
<i class="fa fa-cube"></i>
|
||||
<span>商品</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item class="btn-footer" index="/wap/order">
|
||||
<i class="fa fa-inbox"></i>
|
||||
<span>订单</span>
|
||||
|
||||
</el-menu-item>
|
||||
<el-menu-item class="btn-footer" index="" @click="logout">
|
||||
<i class="fa fa-sign-out"></i>
|
||||
<span>退出</span>
|
||||
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentPagePath: '/wap',
|
||||
loginInfo:null,
|
||||
username:''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
this.$confirm('是否要退出?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
center: true
|
||||
}).then(() => {
|
||||
localStorage.clear();
|
||||
this.$router.replace({name: 'login'});
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.$route.path);
|
||||
if(!this.loginInfo){
|
||||
this.loginInfo = JSON.parse(window.localStorage.getItem('userInfo') || null);
|
||||
this.username = this.loginInfo.username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
.footer-box{
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width:100%;
|
||||
height:50px;
|
||||
background: #fff;
|
||||
z-index:999;
|
||||
border-top:1px solid #f1f1f1;
|
||||
}
|
||||
.foot-wrap{
|
||||
width:100%;
|
||||
height:50px;
|
||||
display: flex;;
|
||||
justify-content: space-around;
|
||||
|
||||
}
|
||||
.btn-footer{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top:6px;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.btn-footer span{
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
font-size:12px;
|
||||
}
|
||||
.btn-footer .fa{
|
||||
width:16px;
|
||||
height:16px;
|
||||
font-size:16px;
|
||||
margin:0 auto;
|
||||
}
|
||||
.btn-footer:focus,.btn-footer .is-active {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.el-message-box {
|
||||
width: 300px !important;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="wrap">
|
||||
<div class="main">
|
||||
<el-tabs class="tabs-wrap" v-model="activeName" @tab-click="handleClick">
|
||||
<!--<el-tab-pane label="全部商品" name="first">-->
|
||||
<!--</el-tab-pane>-->
|
||||
<el-tab-pane label="出售中" name="second"></el-tab-pane>
|
||||
<!--<el-tab-pane label="已售完" name="third"></el-tab-pane>-->
|
||||
<el-tab-pane label="已下架" name="fourth"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="form-table-box">
|
||||
<el-table :data="tableData" style="width: 100%" stripe>
|
||||
<el-table-column prop="list_pic_url" label="图片" width="80">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.list_pic_url" alt="" style="width: 60px;height: 60px">
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="商品名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="retail_price" label="售价" width="90" sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.retail_price" placeholder="售价"
|
||||
@blur="submit(scope.$index, scope.row)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架" width="60">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="tableData[scope.$index].is_on_sale"
|
||||
active-text=""
|
||||
inactive-text=""
|
||||
@change='changeStatus($event,tableData[scope.$index].goods_id)'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import api from '@/config/api';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
total: 0,
|
||||
filterForm: {
|
||||
name: ''
|
||||
},
|
||||
tableData: [],
|
||||
activeName: 'second',
|
||||
pIndex: 0,
|
||||
num: 0,
|
||||
activeClass: 0,
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
methods: {
|
||||
submit(index, row) {
|
||||
this.axios.post('wap/updatePrice', {
|
||||
id: row.goods_id,
|
||||
sn: row.goods_sn,
|
||||
price: row.retail_price
|
||||
}).then((response) => {
|
||||
|
||||
})
|
||||
},
|
||||
changeStatus($event, para) {
|
||||
this.axios.get('goods/saleStatus', {
|
||||
params: {
|
||||
status: $event,
|
||||
id: para
|
||||
}
|
||||
|
||||
}).then((response) => {
|
||||
this.getList();
|
||||
})
|
||||
},
|
||||
logout() {
|
||||
this.$confirm('是否要退出?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
center: true
|
||||
}).then(() => {
|
||||
localStorage.clear();
|
||||
this.$router.replace({name: 'login'});
|
||||
});
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
let pindex = tab._data.index;
|
||||
this.activeClass = 0;
|
||||
if (pindex == 0) {
|
||||
this.getOnSaleList();
|
||||
this.pIndex = 0;
|
||||
}
|
||||
else if (pindex == 1) {
|
||||
this.getOutSaleList();
|
||||
this.pIndex = 1;
|
||||
}
|
||||
},
|
||||
// getList() {
|
||||
// this.axios.get('wap').then((response) => {
|
||||
// console.log(response.data)
|
||||
// this.tableData = response.data.data
|
||||
// })
|
||||
// },
|
||||
getOnSaleList() {
|
||||
this.axios.get('wap/onsale').then((response) => {
|
||||
console.log(response.data)
|
||||
this.tableData = response.data.data
|
||||
})
|
||||
},
|
||||
getOutSaleList() {
|
||||
this.axios.get('wap/drop').then((response) => {
|
||||
console.log(response.data)
|
||||
this.tableData = response.data.data
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getOnSaleList();
|
||||
this.root = api.rootUrl;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.tabs-wrap {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 50px 0;
|
||||
}
|
||||
|
||||
.top {
|
||||
width: 100%;
|
||||
background: #233445;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.top img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.top .menu {
|
||||
width: 100px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.menu .menu-item {
|
||||
margin: 0 15px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.menu-item a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
width: 46%;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div class="top-box">
|
||||
<div class="top-wrap">
|
||||
<!--<img class="logo" src="static/images/logo.png"/>-->
|
||||
汇鲜
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentPagePath: '/wap',
|
||||
loginInfo:null,
|
||||
username:''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.$route.path);
|
||||
if(!this.loginInfo){
|
||||
this.loginInfo = JSON.parse(window.localStorage.getItem('userInfo') || null);
|
||||
this.username = this.loginInfo.username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.top-box{
|
||||
position: fixed;
|
||||
top:0;
|
||||
width:100%;
|
||||
height:50px;
|
||||
background: #233445;
|
||||
z-index:999;
|
||||
}
|
||||
.top-wrap{
|
||||
width:100%;
|
||||
height:50px;
|
||||
display: flex;;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size:14px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.top-wrap .logo{
|
||||
width:30px;
|
||||
height:30px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,53 @@
|
||||
<style>
|
||||
body {
|
||||
background: #f5f7fa;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
</style>
|
||||
<template>
|
||||
<div class="container">
|
||||
<sidebar></sidebar>
|
||||
<navbar></navbar>
|
||||
<div class="content">
|
||||
<transition name="router-fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Sidebar from 'Common/Sidebar';
|
||||
import Navbar from 'Common/Navbar';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Sidebar,
|
||||
Navbar
|
||||
},
|
||||
methods: {
|
||||
handleOpen(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
handleClose(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,53 @@
|
||||
<style scoped>
|
||||
body {
|
||||
background: #f5f7fa;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
</style>
|
||||
<template>
|
||||
<div class="container">
|
||||
<topbar></topbar>
|
||||
<footerbar></footerbar>
|
||||
<div class="content">
|
||||
<transition name="router-fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Topbar from './Wap/Topbar';
|
||||
import Footerbar from './Wap/Footerbar';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Topbar,
|
||||
Footerbar
|
||||
},
|
||||
methods: {
|
||||
handleOpen(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
handleClose(key, keyPath) {
|
||||
console.log(key, keyPath);
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,20 @@
|
||||
const rootUrl = 'http://192.168.212.36:8360/admin/';
|
||||
|
||||
const api = {
|
||||
rootUrl : rootUrl,
|
||||
|
||||
qiniu: 'http://up-z2.qiniup.com',
|
||||
// 请根据自己创建的七牛的区域进行设置:
|
||||
// https://developer.qiniu.com/kodo/manual/1671/region-endpoint
|
||||
// 华东 http(s)://up.qiniup.com
|
||||
// 华北 http(s)://up-z1.qiniup.com
|
||||
// 华南 http(s)://up-z2.qiniup.com
|
||||
// 北美 http(s)://up-na0.qiniup.com
|
||||
// 东南亚 http(s)://up-as0.qiniup.com
|
||||
};
|
||||
|
||||
|
||||
// import api from './config/api'
|
||||
// Axios.defaults.baseURL = api.rootUrl;
|
||||
|
||||
export default api
|
||||
@ -0,0 +1,64 @@
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import { Message } from 'element-ui'
|
||||
import NProgress from 'nprogress' // progress bar
|
||||
import 'nprogress/nprogress.css' // progress bar style
|
||||
import { getToken } from '@/utils/auth' // get token from cookie
|
||||
import getPageTitle from '@/utils/get-page-title'
|
||||
|
||||
NProgress.configure({ showSpinner: false }) // NProgress Configuration
|
||||
|
||||
const whiteList = ['/login'] // no redirect whitelist
|
||||
|
||||
router.beforeEach(async(to, from, next) => {
|
||||
// start progress bar
|
||||
NProgress.start()
|
||||
|
||||
// set page title
|
||||
document.title = getPageTitle(to.meta.title)
|
||||
|
||||
// determine whether the user has logged in
|
||||
const hasToken = getToken()
|
||||
|
||||
if (hasToken) {
|
||||
if (to.path === '/login') {
|
||||
// if is logged in, redirect to the home page
|
||||
next({ path: '/' })
|
||||
NProgress.done()
|
||||
} else {
|
||||
const hasGetUserInfo = store.getters.name
|
||||
if (hasGetUserInfo) {
|
||||
next()
|
||||
} else {
|
||||
try {
|
||||
// get user info
|
||||
await store.dispatch('user/getInfo')
|
||||
|
||||
next()
|
||||
} catch (error) {
|
||||
// remove token and go to login page to re-login
|
||||
await store.dispatch('user/resetToken')
|
||||
Message.error(error || 'Has Error')
|
||||
next(`/login?redirect=${to.path}`)
|
||||
NProgress.done()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* has no token*/
|
||||
|
||||
if (whiteList.indexOf(to.path) !== -1) {
|
||||
// in the free login whitelist, go directly
|
||||
next()
|
||||
} else {
|
||||
// other pages that do not have permission to access are redirected to the login page.
|
||||
next(`/login?redirect=${to.path}`)
|
||||
NProgress.done()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
router.afterEach(() => {
|
||||
// finish progress bar
|
||||
NProgress.done()
|
||||
})
|
||||
@ -0,0 +1,342 @@
|
||||
import Vue from "vue";
|
||||
import Router from "vue-router";
|
||||
|
||||
Vue.use(Router);
|
||||
|
||||
/* Layout */
|
||||
|
||||
/**
|
||||
* Note: sub-menu only appear when route children.length >= 1
|
||||
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
|
||||
*
|
||||
* hidden: true if set true, item will not show in the sidebar(default is false)
|
||||
* alwaysShow: true if set true, will always show the root menu
|
||||
* if not set alwaysShow, when item has more than one children route,
|
||||
* it will becomes nested mode, otherwise not show the root menu
|
||||
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
|
||||
* name:'router-name' the name is used by <keep-alive> (must set!!!)
|
||||
* meta : {
|
||||
roles: ['admin','editor'] control the page roles (you can set multiple roles)
|
||||
title: 'title' the name show in sidebar and breadcrumb (recommend set)
|
||||
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
|
||||
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
|
||||
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* constantRoutes
|
||||
* a base page that does not have permission () =>importments
|
||||
* all roles can be accessed
|
||||
*/
|
||||
// export const constantRoutes = [
|
||||
// {
|
||||
// path: '/login',
|
||||
// component: () => import('@/views/login/index'),
|
||||
// hidden: true
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: '/404',
|
||||
// component: () => import('@/views/404'),
|
||||
// hidden: true
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: '/',
|
||||
// component: Layout,
|
||||
// redirect: '/dashboard',
|
||||
// children: [{
|
||||
// path: 'dashboard',
|
||||
// name: 'Dashboard',
|
||||
// component: () => import('@/views/dashboard/index'),
|
||||
// meta: { title: 'Dashboard', icon: 'dashboard' }
|
||||
// }]
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: '/example',
|
||||
// component: Layout,
|
||||
// redirect: '/example/table',
|
||||
// name: 'Example',
|
||||
// meta: { title: 'Example', icon: 'el-icon-s-help' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'table',
|
||||
// name: 'Table',
|
||||
// component: () => import('@/views/table/index'),
|
||||
// meta: { title: 'Table', icon: 'table' }
|
||||
// },
|
||||
// {
|
||||
// path: 'tree',
|
||||
// name: 'Tree',
|
||||
// component: () => import('@/views/tree/index'),
|
||||
// meta: { title: 'Tree', icon: 'tree' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: '/form',
|
||||
// component: Layout,
|
||||
// children: [
|
||||
// {
|
||||
// path: 'index',
|
||||
// name: 'Form',
|
||||
// component: () => import('@/views/form/index'),
|
||||
// meta: { title: 'Form', icon: 'form' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: '/nested',
|
||||
// component: Layout,
|
||||
// redirect: '/nested/menu1',
|
||||
// name: 'Nested',
|
||||
// meta: {
|
||||
// title: 'Nested',
|
||||
// icon: 'nested'
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'menu1',
|
||||
// component: () => import('@/views/nested/menu1/index'), // Parent router-view
|
||||
// name: 'Menu1',
|
||||
// meta: { title: 'Menu1' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'menu1-1',
|
||||
// component: () => import('@/views/nested/menu1/menu1-1'),
|
||||
// name: 'Menu1-1',
|
||||
// meta: { title: 'Menu1-1' }
|
||||
// },
|
||||
// {
|
||||
// path: 'menu1-2',
|
||||
// component: () => import('@/views/nested/menu1/menu1-2'),
|
||||
// name: 'Menu1-2',
|
||||
// meta: { title: 'Menu1-2' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'menu1-2-1',
|
||||
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
|
||||
// name: 'Menu1-2-1',
|
||||
// meta: { title: 'Menu1-2-1' }
|
||||
// },
|
||||
// {
|
||||
// path: 'menu1-2-2',
|
||||
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
|
||||
// name: 'Menu1-2-2',
|
||||
// meta: { title: 'Menu1-2-2' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// path: 'menu1-3',
|
||||
// component: () => import('@/views/nested/menu1/menu1-3'),
|
||||
// name: 'Menu1-3',
|
||||
// meta: { title: 'Menu1-3' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// path: 'menu2',
|
||||
// component: () => import('@/views/nested/menu2/index'),
|
||||
// name: 'Menu2',
|
||||
// meta: { title: 'menu2' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: 'external-link',
|
||||
// component: Layout,
|
||||
// children: [
|
||||
// {
|
||||
// path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
|
||||
// meta: { title: 'External Link', icon: 'link' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
// // 404 page must be placed at the end !!!
|
||||
// { path: '*', redirect: '/404', hidden: true }
|
||||
// ]
|
||||
|
||||
export const constantRoutes = [
|
||||
{
|
||||
path: "/dashboard",
|
||||
name: "dashboard",
|
||||
component: () => import("@/components/DashboardPage"),
|
||||
children: [
|
||||
{
|
||||
path: "welcome",
|
||||
name: "welcome",
|
||||
component: () => import("@/components/WelcomePage"),
|
||||
},
|
||||
{
|
||||
path: "goods",
|
||||
name: "goods",
|
||||
component: () => import("@/components/Goods/GoodsPage"),
|
||||
},
|
||||
{
|
||||
path: "goods/add",
|
||||
name: "goods_add",
|
||||
component: () => import("@/components/Goods/GoodsAddPage"),
|
||||
},
|
||||
{
|
||||
path: "nature",
|
||||
name: "nature",
|
||||
component: () => import("@/components/Nature/NaturePage"),
|
||||
},
|
||||
{
|
||||
path: "specification/detail",
|
||||
name: "specification_detail",
|
||||
component: () =>
|
||||
import("@/components/Specification/SpecificationAddPage"),
|
||||
},
|
||||
{
|
||||
path: "category",
|
||||
name: "category",
|
||||
component: () => import("@/components/Category/CategoryPage"),
|
||||
},
|
||||
{
|
||||
path: "category/add",
|
||||
name: "category_add",
|
||||
component: () => import("@/components/Category/CategoryAddPage"),
|
||||
},
|
||||
{
|
||||
path: "order",
|
||||
name: "order",
|
||||
component: () => import("@/components/Order/OrderPage"),
|
||||
},
|
||||
{
|
||||
path: "order/detail",
|
||||
name: "order_detail",
|
||||
component: () => import("@/components/Order/OrderDetailPage"),
|
||||
},
|
||||
{
|
||||
path: "user",
|
||||
name: "user",
|
||||
component: () => import("@/components/User/UserPage"),
|
||||
},
|
||||
{
|
||||
path: "user/add",
|
||||
name: "user_add",
|
||||
component: () => import("@/components/User/UserAddPage"),
|
||||
},
|
||||
{
|
||||
path: "shipper",
|
||||
name: "shipper",
|
||||
component: () => import("@/components/Shipper/ShipperPage"),
|
||||
},
|
||||
{
|
||||
path: "shipper/list",
|
||||
name: "shipper_list",
|
||||
component: () => import("@/components/Shipper/ShipperListPage"),
|
||||
},
|
||||
{
|
||||
path: "shipper/add",
|
||||
name: "shipper_add",
|
||||
component: () => import("@/components/Shipper/ShipperAddPage"),
|
||||
},
|
||||
{
|
||||
path: "freight",
|
||||
name: "freight",
|
||||
component: () => import("@/components/Freight/FreightPage"),
|
||||
},
|
||||
{
|
||||
path: "except_area",
|
||||
name: "except_area",
|
||||
component: () => import("@/components/Freight/ExceptAreaPage"),
|
||||
},
|
||||
{
|
||||
path: "except_area/add",
|
||||
name: "except_area_add",
|
||||
component: () => import("@/components/Freight/ExceptAreaAddPage"),
|
||||
},
|
||||
{
|
||||
path: "freight/add",
|
||||
name: "freight_add",
|
||||
component: () => import("@/components/Freight/FreightAddPage"),
|
||||
},
|
||||
{
|
||||
path: "notice",
|
||||
name: "notice",
|
||||
component: () => import("@/components/Settings/NoticePage"),
|
||||
},
|
||||
{
|
||||
path: "ad",
|
||||
name: "ad",
|
||||
component: () => import("@/components/Ad/AdPage"),
|
||||
},
|
||||
{
|
||||
path: "ad/add",
|
||||
name: "ad_add",
|
||||
component: () => import("@/components/Ad/AdAddPage"),
|
||||
},
|
||||
{
|
||||
path: "shopcart",
|
||||
name: "shopcart",
|
||||
component: () => import("@/components/ShopCart/ShopCartPage"),
|
||||
},
|
||||
{
|
||||
path: "keywords",
|
||||
name: "keywords",
|
||||
component: () => import("@/components/Keywords/KeywordsPage"),
|
||||
},
|
||||
{
|
||||
path: "keywords/add",
|
||||
name: "keywords_add",
|
||||
component: () => import("@/components/Keywords/KeywordsAddPage"),
|
||||
},
|
||||
{
|
||||
path: "goodsgalleryedit",
|
||||
name: "goodsgalleryedit",
|
||||
component: () =>
|
||||
import("@/components/GoodsGallery/GoodsGalleryEditPage"),
|
||||
},
|
||||
{
|
||||
path: "admin",
|
||||
name: "admin",
|
||||
component: () => import("@/components/Admin/AdminPage"),
|
||||
},
|
||||
{
|
||||
path: "admin/add",
|
||||
name: "admin_add",
|
||||
component: () => import("@/components/Admin/AdminAddPage"),
|
||||
},
|
||||
{
|
||||
path: "settings/showset",
|
||||
name: "showset",
|
||||
component: () => import("@/components/Showset/ShowSetPage"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
name: "login",
|
||||
component: () => import("@/components/LoginPage"),
|
||||
},
|
||||
{
|
||||
path: "*",
|
||||
redirect: "/dashboard",
|
||||
},
|
||||
];
|
||||
|
||||
const createRouter = () =>
|
||||
new Router({
|
||||
// mode: 'history', // () =>import service support
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
routes: constantRoutes,
|
||||
});
|
||||
|
||||
const router = createRouter();
|
||||
|
||||
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
|
||||
export function resetRouter() {
|
||||
const newRouter = createRouter();
|
||||
router.matcher = newRouter.matcher; // reset router
|
||||
}
|
||||
|
||||
export default router;
|
||||
@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
|
||||
title: '海风小店',
|
||||
|
||||
/**
|
||||
* @type {boolean} true | false
|
||||
* @description Whether fix the header
|
||||
*/
|
||||
fixedHeader: false,
|
||||
|
||||
/**
|
||||
* @type {boolean} true | false
|
||||
* @description Whether show the logo in sidebar
|
||||
*/
|
||||
sidebarLogo: false
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
// import Vue from 'vue'
|
||||
// import getters from './getters'
|
||||
// import app from './modules/app'
|
||||
// import settings from './modules/settings'
|
||||
// import user from './modules/user'
|
||||
|
||||
// Vue.use(Vuex)
|
||||
|
||||
// const store = new Vuex.Store({
|
||||
// modules: {
|
||||
// app,
|
||||
// settings,
|
||||
// user
|
||||
// },
|
||||
// getters
|
||||
// })
|
||||
|
||||
// export default store
|
||||
|
||||
import Vuex from 'vuex'
|
||||
import Vue from 'vue'
|
||||
|
||||
import modules from './modules'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules,
|
||||
strict: process.env.NODE_ENV !== 'production'
|
||||
})
|
||||
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* The file enables `@/store/index.js` to import all vuex modules
|
||||
* in a one-shot manner. There should not be any reason to edit this file.
|
||||
*/
|
||||
|
||||
const files = require.context('.', false, /\.js$/)
|
||||
const modules = {}
|
||||
|
||||
files.keys().forEach(key => {
|
||||
if (key === './index.js') return
|
||||
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
|
||||
})
|
||||
|
||||
export default modules
|
||||
@ -0,0 +1,49 @@
|
||||
// cover some element-ui styles
|
||||
|
||||
.el-breadcrumb__inner,
|
||||
.el-breadcrumb__inner a {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.el-upload {
|
||||
input[type="file"] {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload__input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
// to fixed https://github.com/ElemeFE/element/issues/2461
|
||||
.el-dialog {
|
||||
transform: none;
|
||||
left: 0;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
// refine element ui upload
|
||||
.upload-container {
|
||||
.el-upload {
|
||||
width: 100%;
|
||||
|
||||
.el-upload-dragger {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dropdown
|
||||
.el-dropdown-menu {
|
||||
a {
|
||||
display: block
|
||||
}
|
||||
}
|
||||
|
||||
// to fix el-date-picker css style
|
||||
.el-range-separator {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
@import './variables.scss';
|
||||
@import './mixin.scss';
|
||||
@import './transition.scss';
|
||||
@import './element-ui.scss';
|
||||
@import './sidebar.scss';
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
a:focus,
|
||||
a:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a,
|
||||
a:focus,
|
||||
a:hover {
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
&:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// main-container global css
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
@mixin clearfix {
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin scrollBar {
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background: #d3dce6;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #99a9bf;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin relative {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -0,0 +1,226 @@
|
||||
#app {
|
||||
|
||||
.main-container {
|
||||
min-height: 100%;
|
||||
transition: margin-left .28s;
|
||||
margin-left: $sideBarWidth;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
transition: width 0.28s;
|
||||
width: $sideBarWidth !important;
|
||||
background-color: $menuBg;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
font-size: 0px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
overflow: hidden;
|
||||
|
||||
// reset element-ui css
|
||||
.horizontal-collapse-transition {
|
||||
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
|
||||
}
|
||||
|
||||
.scrollbar-wrapper {
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
.el-scrollbar__bar.is-vertical {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.has-logo {
|
||||
.el-scrollbar {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
}
|
||||
|
||||
.is-horizontal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.sub-el-icon {
|
||||
margin-right: 12px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
border: none;
|
||||
height: 100%;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
// menu hover
|
||||
.submenu-title-noDropdown,
|
||||
.el-submenu__title {
|
||||
&:hover {
|
||||
background-color: $menuHover !important;
|
||||
}
|
||||
}
|
||||
|
||||
.is-active>.el-submenu__title {
|
||||
color: $subMenuActiveText !important;
|
||||
}
|
||||
|
||||
& .nest-menu .el-submenu>.el-submenu__title,
|
||||
& .el-submenu .el-menu-item {
|
||||
min-width: $sideBarWidth !important;
|
||||
background-color: $subMenuBg !important;
|
||||
|
||||
&:hover {
|
||||
background-color: $subMenuHover !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hideSidebar {
|
||||
.sidebar-container {
|
||||
width: 54px !important;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
margin-left: 54px;
|
||||
}
|
||||
|
||||
.submenu-title-noDropdown {
|
||||
padding: 0 !important;
|
||||
position: relative;
|
||||
|
||||
.el-tooltip {
|
||||
padding: 0 !important;
|
||||
|
||||
.svg-icon {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.sub-el-icon {
|
||||
margin-left: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-submenu {
|
||||
overflow: hidden;
|
||||
|
||||
&>.el-submenu__title {
|
||||
padding: 0 !important;
|
||||
|
||||
.svg-icon {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.sub-el-icon {
|
||||
margin-left: 19px;
|
||||
}
|
||||
|
||||
.el-submenu__icon-arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu--collapse {
|
||||
.el-submenu {
|
||||
&>.el-submenu__title {
|
||||
&>span {
|
||||
height: 0;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu--collapse .el-menu .el-submenu {
|
||||
min-width: $sideBarWidth !important;
|
||||
}
|
||||
|
||||
// mobile responsive
|
||||
.mobile {
|
||||
.main-container {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
transition: transform .28s;
|
||||
width: $sideBarWidth !important;
|
||||
}
|
||||
|
||||
&.hideSidebar {
|
||||
.sidebar-container {
|
||||
pointer-events: none;
|
||||
transition-duration: 0.3s;
|
||||
transform: translate3d(-$sideBarWidth, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.withoutAnimation {
|
||||
|
||||
.main-container,
|
||||
.sidebar-container {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// when menu collapsed
|
||||
.el-menu--vertical {
|
||||
&>.el-menu {
|
||||
.svg-icon {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.sub-el-icon {
|
||||
margin-right: 12px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.nest-menu .el-submenu>.el-submenu__title,
|
||||
.el-menu-item {
|
||||
&:hover {
|
||||
// you can use $subMenuHover
|
||||
background-color: $menuHover !important;
|
||||
}
|
||||
}
|
||||
|
||||
// the scroll bar appears when the subMenu is too long
|
||||
>.el-menu--popup {
|
||||
max-height: 100vh;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background: #d3dce6;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #99a9bf;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
// global transition css
|
||||
|
||||
/* fade */
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.28s;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* fade-transform */
|
||||
.fade-transform-leave-active,
|
||||
.fade-transform-enter-active {
|
||||
transition: all .5s;
|
||||
}
|
||||
|
||||
.fade-transform-enter {
|
||||
opacity: 0;
|
||||
transform: translateX(-30px);
|
||||
}
|
||||
|
||||
.fade-transform-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(30px);
|
||||
}
|
||||
|
||||
/* breadcrumb transition */
|
||||
.breadcrumb-enter-active,
|
||||
.breadcrumb-leave-active {
|
||||
transition: all .5s;
|
||||
}
|
||||
|
||||
.breadcrumb-enter,
|
||||
.breadcrumb-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
.breadcrumb-move {
|
||||
transition: all .5s;
|
||||
}
|
||||
|
||||
.breadcrumb-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
// sidebar
|
||||
$menuText:#bfcbd9;
|
||||
$menuActiveText:#409EFF;
|
||||
$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
|
||||
|
||||
$menuBg:#304156;
|
||||
$menuHover:#263445;
|
||||
|
||||
$subMenuBg:#1f2d3d;
|
||||
$subMenuHover:#001528;
|
||||
|
||||
$sideBarWidth: 210px;
|
||||
|
||||
// the :export directive is the magic sauce for webpack
|
||||
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
||||
:export {
|
||||
menuText: $menuText;
|
||||
menuActiveText: $menuActiveText;
|
||||
subMenuActiveText: $subMenuActiveText;
|
||||
menuBg: $menuBg;
|
||||
menuHover: $menuHover;
|
||||
subMenuBg: $subMenuBg;
|
||||
subMenuHover: $subMenuHover;
|
||||
sideBarWidth: $sideBarWidth;
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const defaultSettings = require("./src/settings.js");
|
||||
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir);
|
||||
}
|
||||
|
||||
const name = defaultSettings.title || "vue Admin Template"; // page title
|
||||
|
||||
// If your port is set to 80,
|
||||
// use administrator privileges to execute the command line.
|
||||
// For example, Mac: sudo npm run
|
||||
// You can change the port by the following methods:
|
||||
// port = 9528 npm run dev OR npm run dev --port = 9528
|
||||
const port = process.env.port || process.env.npm_config_port || 9528; // dev port
|
||||
|
||||
// All configuration item explanations can be find in https://cli.vuejs.org/config/
|
||||
module.exports = {
|
||||
/**
|
||||
* You will need to set publicPath if you plan to deploy your site under a sub path,
|
||||
* for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
|
||||
* then publicPath should be set to "/bar/".
|
||||
* In most cases please use '/' !!!
|
||||
* Detail: https://cli.vuejs.org/config/#publicpath
|
||||
*/
|
||||
publicPath: "./",
|
||||
outputDir: "dist",
|
||||
assetsDir: "static",
|
||||
lintOnSave: process.env.NODE_ENV === "development",
|
||||
productionSourceMap: false,
|
||||
devServer: {
|
||||
port: port,
|
||||
open: true,
|
||||
overlay: {
|
||||
warnings: false,
|
||||
errors: true,
|
||||
},
|
||||
// lintOnSave: false,
|
||||
// before: require("./mock/mock-server.js"),
|
||||
},
|
||||
configureWebpack: {
|
||||
// provide the app's title in webpack's name field, so that
|
||||
// it can be accessed in index.html to inject the correct title.
|
||||
name: name,
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": resolve("src"),
|
||||
},
|
||||
},
|
||||
},
|
||||
chainWebpack(config) {
|
||||
// it can improve the speed of the first screen, it is recommended to turn on preload
|
||||
config.plugin("preload").tap(() => [
|
||||
{
|
||||
rel: "preload",
|
||||
// to ignore runtime.js
|
||||
// https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
|
||||
fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
|
||||
include: "initial",
|
||||
},
|
||||
]);
|
||||
|
||||
// when there are many pages, it will cause too many meaningless requests
|
||||
config.plugins.delete("prefetch");
|
||||
|
||||
// set svg-sprite-loader
|
||||
config.module.rule("svg").exclude.add(resolve("src/icons")).end();
|
||||
config.module
|
||||
.rule("icons")
|
||||
.test(/\.svg$/)
|
||||
.include.add(resolve("src/icons"))
|
||||
.end()
|
||||
.use("svg-sprite-loader")
|
||||
.loader("svg-sprite-loader")
|
||||
.options({
|
||||
symbolId: "icon-[name]",
|
||||
})
|
||||
.end();
|
||||
|
||||
config.when(process.env.NODE_ENV !== "development", (config) => {
|
||||
config
|
||||
.plugin("ScriptExtHtmlWebpackPlugin")
|
||||
.after("html")
|
||||
.use("script-ext-html-webpack-plugin", [
|
||||
{
|
||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||
inline: /runtime\..*\.js$/,
|
||||
},
|
||||
])
|
||||
.end();
|
||||
config.optimization.splitChunks({
|
||||
chunks: "all",
|
||||
cacheGroups: {
|
||||
libs: {
|
||||
name: "chunk-libs",
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: 10,
|
||||
chunks: "initial", // only package third parties that are initially dependent
|
||||
},
|
||||
elementUI: {
|
||||
name: "chunk-elementUI", // split elementUI into a single package
|
||||
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
||||
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
|
||||
},
|
||||
commons: {
|
||||
name: "chunk-commons",
|
||||
test: resolve("src/components"), // can customize your rules
|
||||
minChunks: 3, // minimum common number
|
||||
priority: 5,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
// https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
|
||||
config.optimization.runtimeChunk("single");
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,37 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Dependency directory
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||
node_modules/
|
||||
|
||||
# IDE config
|
||||
.idea
|
||||
|
||||
# output
|
||||
output/
|
||||
output.tar.gz
|
||||
|
||||
runtime/
|
||||
app/
|
||||
|
||||
config.development.js
|
||||
adapter.development.js
|
||||
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 iamdarcy 黑亮(sligxl@163.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -0,0 +1,16 @@
|
||||
const Application = require('thinkjs');
|
||||
const babel = require('think-babel');
|
||||
const watcher = require('think-watcher');
|
||||
const notifier = require('node-notifier');
|
||||
|
||||
const instance = new Application({
|
||||
ROOT_PATH: __dirname,
|
||||
watcher: watcher,
|
||||
transpiler: [babel, {
|
||||
presets: ['think-node']
|
||||
}],
|
||||
notifier: notifier.notify.bind(notifier),
|
||||
env: 'development'
|
||||
});
|
||||
|
||||
instance.run();
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "hioshop",
|
||||
"description": "hioshop - open source mini program shop",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "node development.js",
|
||||
"compile": "babel --no-babelrc src/ --presets think-node --out-dir app/",
|
||||
"lint": "eslint src/",
|
||||
"lint-fix": "eslint --fix src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"gm": "^1.23.0",
|
||||
"jsonwebtoken": "^8.0.0",
|
||||
"jushuitan": "^1.0.2",
|
||||
"kcors": "^2.2.1",
|
||||
"lodash": "^4.17.4",
|
||||
"md5": "^2.2.1",
|
||||
"mime-types": "^2.1.24",
|
||||
"moment": "^2.18.1",
|
||||
"nanoid": "^2.1.1",
|
||||
"node-wget": "^0.4.3",
|
||||
"pinyin": "^2.9.0",
|
||||
"qiniu": "^7.2.1",
|
||||
"querystring": "^0.2.0",
|
||||
"request": "^2.81.0",
|
||||
"request-promise": "^4.2.1",
|
||||
"think-cache": "^1.0.0",
|
||||
"think-cache-file": "^1.0.8",
|
||||
"think-logger3": "^1.0.0",
|
||||
"think-model": "^1.0.0",
|
||||
"think-model-mysql": "^1.0.0",
|
||||
"think-view": "^1.0.11",
|
||||
"think-view-nunjucks": "^1.0.7",
|
||||
"thinkjs": "^3.0.0",
|
||||
"weixinpay": "^1.0.12",
|
||||
"xml2js": "^0.4.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-preset-think-node": "^1.0.0",
|
||||
"node-notifier": "^5.0.2",
|
||||
"think-watcher": "^3.0.0",
|
||||
"think-inspect": "0.0.2",
|
||||
"think-babel": "^1.0.3",
|
||||
"eslint": "^4.2.0",
|
||||
"eslint-config-think": "^1.0.0"
|
||||
},
|
||||
"repository": "",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"readmeFilename": "README.md"
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"apps": [{
|
||||
"name": "hiolabs",
|
||||
"script": "production.js",
|
||||
"cwd": "/var/www/hioshop-server",
|
||||
"exec_mode": "fork",
|
||||
"max_memory_restart": "1G",
|
||||
"autorestart": true,
|
||||
"node_args": [],
|
||||
"args": [],
|
||||
"env": {
|
||||
|
||||
}
|
||||
}]
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
const Application = require('thinkjs');
|
||||
|
||||
const instance = new Application({
|
||||
ROOT_PATH: __dirname,
|
||||
proxy: true, // use proxy
|
||||
env: 'production'
|
||||
});
|
||||
|
||||
instance.run();
|
||||
@ -0,0 +1,4 @@
|
||||
// default config test
|
||||
module.exports = {
|
||||
|
||||
};
|
||||
@ -0,0 +1,108 @@
|
||||
const Base = require('./base.js');
|
||||
const moment = require('moment');
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size') || 10;
|
||||
const model = this.model('ad');
|
||||
const data = await model.where({
|
||||
is_delete: 0
|
||||
}).order(['id ASC']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
if (item.end_time != 0) {
|
||||
item.end_time = moment.unix(item.end_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
if (item.enabled == 1) {
|
||||
item.enabled = true;
|
||||
} else {
|
||||
item.enabled = false;
|
||||
}
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
async updateSortAction() {
|
||||
const id = this.post('id');
|
||||
const sort = this.post('sort');
|
||||
const model = this.model('ad');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
sort_order: sort
|
||||
});
|
||||
return this.success(data);
|
||||
}
|
||||
async infoAction() {
|
||||
const id = this.get('id');
|
||||
const model = this.model('ad');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).find();
|
||||
return this.success(data);
|
||||
}
|
||||
async storeAction() {
|
||||
if (!this.isPost) {
|
||||
return false;
|
||||
}
|
||||
const values = this.post();
|
||||
console.log(values);
|
||||
values.end_time = parseInt(new Date(values.end_time).getTime() / 1000);
|
||||
const id = this.post('id');
|
||||
const model = this.model('ad');
|
||||
if (id > 0) {
|
||||
await model.where({
|
||||
id: id
|
||||
}).update(values);
|
||||
} else {
|
||||
let ex = await model.where({
|
||||
goods_id: values.goods_id,
|
||||
is_delete:0
|
||||
}).find();
|
||||
if (think.isEmpty(ex)) {
|
||||
delete values.id;
|
||||
if (values.link_type == 0) {
|
||||
values.link = '';
|
||||
} else {
|
||||
values.goods_id = 0;
|
||||
}
|
||||
await model.add(values);
|
||||
} else {
|
||||
return this.fail(100, '发生错误');
|
||||
}
|
||||
}
|
||||
return this.success(values);
|
||||
}
|
||||
async getallrelateAction() {
|
||||
let data = await this.model('goods').where({
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).field('id,name,list_pic_url').select();
|
||||
return this.success(data);
|
||||
}
|
||||
async destoryAction() {
|
||||
const id = this.post('id');
|
||||
await this.model('ad').where({
|
||||
id: id
|
||||
}).limit(1).update({
|
||||
is_delete: 1
|
||||
});
|
||||
return this.success();
|
||||
}
|
||||
async saleStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
let sale = 0;
|
||||
if (status == 'true') {
|
||||
sale = 1;
|
||||
}
|
||||
const model = this.model('ad');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
enabled: sale
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,143 @@
|
||||
const Base = require('./base.js');
|
||||
const moment = require('moment');
|
||||
const md5 = require('md5');
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const data = await this.model('admin').where({
|
||||
// is_show: 1,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const item of data) {
|
||||
if (item.last_login_time != 0) {
|
||||
item.last_login_time = moment.unix(item.last_login_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
} else {
|
||||
item.last_login_time = '还没登录过'
|
||||
}
|
||||
item.password = '';
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
async adminDetailAction() {
|
||||
let id = this.post('id')
|
||||
let info = await this.model('admin').where({
|
||||
id: id
|
||||
}).find();
|
||||
return this.success(info);
|
||||
}
|
||||
async adminAddAction() {
|
||||
let user = this.post('user');
|
||||
let password = user.password;
|
||||
let upData = {
|
||||
username: info.username,
|
||||
password_salt: 'HIOLABS'
|
||||
};
|
||||
if (password.replace(/(^\s*)|(\s*$)/g, "").length != 0) {
|
||||
password = md5(info.password + '' + upData.password_salt);
|
||||
upData.password = password;
|
||||
}
|
||||
await this.model('admin').add(upData);
|
||||
return this.success();
|
||||
}
|
||||
async adminSaveAction() {
|
||||
let user = this.post('user');
|
||||
let change = this.post('change');
|
||||
let upData = {
|
||||
username: user.username,
|
||||
};
|
||||
if (change == true) {
|
||||
let newPassword = user.newpassword;
|
||||
if (newPassword.replace(/(^\s*)|(\s*$)/g, "").length != 0) {
|
||||
newPassword = md5(user.newpassword + '' + user.password_salt);
|
||||
upData.password = newPassword;
|
||||
}
|
||||
}
|
||||
let ex = await this.model('admin').where({
|
||||
username: user.username,
|
||||
id: ['<>', user.id]
|
||||
}).find();
|
||||
if (!think.isEmpty(ex)) {
|
||||
return this.fail(400, '重名了')
|
||||
}
|
||||
// if (user.id == 14) {
|
||||
// return this.fail(400, '演示版后台的管理员密码不能修改!本地开发,删除这个判断')
|
||||
// }
|
||||
await this.model('admin').where({
|
||||
id: user.id
|
||||
}).update(upData);
|
||||
return this.success();
|
||||
}
|
||||
async infoAction() {
|
||||
const id = this.get('id');
|
||||
const model = this.model('user');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).find();
|
||||
return this.success(data);
|
||||
}
|
||||
async storeAction() {
|
||||
if (!this.isPost) {
|
||||
return false;
|
||||
}
|
||||
const values = this.post();
|
||||
const id = this.post('id');
|
||||
const model = this.model('user');
|
||||
values.is_show = values.is_show ? 1 : 0;
|
||||
values.is_new = values.is_new ? 1 : 0;
|
||||
if (id > 0) {
|
||||
await model.where({
|
||||
id: id
|
||||
}).update(values);
|
||||
} else {
|
||||
delete values.id;
|
||||
await model.add(values);
|
||||
}
|
||||
return this.success(values);
|
||||
}
|
||||
async deleAdminAction() {
|
||||
const id = this.post('id');
|
||||
await this.model('admin').where({
|
||||
id: id
|
||||
}).limit(1).delete();
|
||||
return this.success();
|
||||
}
|
||||
async showsetAction() {
|
||||
const model = this.model('show_settings');
|
||||
let data = await model.find();
|
||||
return this.success(data);
|
||||
}
|
||||
async showsetStoreAction() {
|
||||
let id = 1;
|
||||
const values = this.post();
|
||||
const model = this.model('show_settings');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update(values);
|
||||
return this.success(values);
|
||||
}
|
||||
async changeAutoStatusAction() {
|
||||
const status = this.post('status');
|
||||
await this.model('settings').where({
|
||||
id: 1
|
||||
}).update({
|
||||
autoDelivery: status
|
||||
});
|
||||
return this.success();
|
||||
}
|
||||
async storeShipperSettingsAction() {
|
||||
const values = this.post();
|
||||
await this.model('settings').where({
|
||||
id: values.id
|
||||
}).update(values);
|
||||
return this.success();
|
||||
}
|
||||
async senderInfoAction() {
|
||||
let info = await this.model('settings').where({
|
||||
id: 1
|
||||
}).find();
|
||||
return this.success(info);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
const Base = require('./base.js');
|
||||
module.exports = class extends Base {
|
||||
async loginAction() {
|
||||
const username = this.post('username');
|
||||
const password = this.post('password');
|
||||
const admin = await this.model('admin').where({
|
||||
username: username
|
||||
}).find();
|
||||
if (think.isEmpty(admin)) {
|
||||
return this.fail(401, '用户名或密码不正确!');
|
||||
}
|
||||
console.log(think.md5(password + '' + admin.password_salt));
|
||||
console.log(admin.password);
|
||||
if (think.md5(password + '' + admin.password_salt) !== admin.password) {
|
||||
return this.fail(400, '用户名或密码不正确!!');
|
||||
}
|
||||
// 更新登录信息
|
||||
await this.model('admin').where({
|
||||
id: admin.id
|
||||
}).update({
|
||||
last_login_time: parseInt(Date.now() / 1000),
|
||||
last_login_ip: this.ctx.ip
|
||||
});
|
||||
const TokenSerivce = this.service('token', 'admin');
|
||||
let sessionData = {}
|
||||
sessionData.user_id = admin.id
|
||||
const sessionKey = await TokenSerivce.create(sessionData);
|
||||
if (think.isEmpty(sessionKey)) {
|
||||
return this.fail('登录失败');
|
||||
}
|
||||
const userInfo = {
|
||||
id: admin.id,
|
||||
username: admin.username,
|
||||
name:admin.name
|
||||
};
|
||||
return this.success({
|
||||
token: sessionKey,
|
||||
userInfo: userInfo
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
module.exports = class extends think.Controller {
|
||||
async __before() {
|
||||
// 根据token值获取用户id
|
||||
think.token = this.ctx.header['x-hioshop-token'] || '';
|
||||
const tokenSerivce = think.service('token', 'admin');
|
||||
think.userId = await tokenSerivce.getUserId();
|
||||
// 只允许登录操作
|
||||
if (this.ctx.controller != 'auth') {
|
||||
if (think.userId <= 0 || think.userId == undefined) {
|
||||
return this.fail(401, '请先登录');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,161 @@
|
||||
const Base = require('./base.js');
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const model = this.model('category');
|
||||
const data = await model.order(['sort_order ASC']).select();
|
||||
const topCategory = data.filter((item) => {
|
||||
return item.parent_id === 0;
|
||||
});
|
||||
const categoryList = [];
|
||||
topCategory.map((item) => {
|
||||
item.level = 1;
|
||||
categoryList.push(item);
|
||||
data.map((child) => {
|
||||
if (child.parent_id === item.id) {
|
||||
child.level = 2;
|
||||
categoryList.push(child);
|
||||
}
|
||||
if (child.is_show == 1) {
|
||||
child.is_show = true;
|
||||
} else {
|
||||
child.is_show = false;
|
||||
}
|
||||
if (child.is_channel == 1) {
|
||||
child.is_channel = true;
|
||||
} else {
|
||||
child.is_channel = false;
|
||||
}
|
||||
if (child.is_category == 1) {
|
||||
child.is_category = true;
|
||||
} else {
|
||||
child.is_category = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
return this.success(categoryList);
|
||||
}
|
||||
async updateSortAction() {
|
||||
const id = this.post('id');
|
||||
const sort = this.post('sort');
|
||||
const model = this.model('category');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
sort_order: sort
|
||||
});
|
||||
return this.success(data);
|
||||
}
|
||||
async topCategoryAction() {
|
||||
const model = this.model('category');
|
||||
const data = await model.where({
|
||||
parent_id: 0
|
||||
}).order(['id ASC']).select();
|
||||
return this.success(data);
|
||||
}
|
||||
async infoAction() {
|
||||
const id = this.get('id');
|
||||
const model = this.model('category');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).find();
|
||||
return this.success(data);
|
||||
}
|
||||
async storeAction() {
|
||||
if (!this.isPost) {
|
||||
return false;
|
||||
}
|
||||
const values = this.post();
|
||||
const id = this.post('id');
|
||||
const model = this.model('category');
|
||||
values.is_show = values.is_show ? 1 : 0;
|
||||
values.is_channel = values.is_channel ? 1 : 0;
|
||||
values.is_category = values.is_category ? 1 : 0;
|
||||
if (id > 0) {
|
||||
await model.where({
|
||||
id: id
|
||||
}).update(values);
|
||||
} else {
|
||||
delete values.id;
|
||||
await model.add(values);
|
||||
}
|
||||
return this.success(values);
|
||||
}
|
||||
async destoryAction() {
|
||||
const id = this.post('id');
|
||||
let data = await this.model('category').where({
|
||||
parent_id: id
|
||||
}).select();
|
||||
if (data.length > 0) {
|
||||
return this.fail();
|
||||
} else {
|
||||
await this.model('category').where({
|
||||
id: id
|
||||
}).limit(1).delete();
|
||||
return this.success();
|
||||
}
|
||||
}
|
||||
async showStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
let ele = 0;
|
||||
if (status == 'true') {
|
||||
ele = 1;
|
||||
}
|
||||
const model = this.model('category');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
is_show: ele
|
||||
});
|
||||
}
|
||||
async channelStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
let stat = 0;
|
||||
if (status == 'true') {
|
||||
stat = 1;
|
||||
}
|
||||
const model = this.model('category');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
is_channel: stat
|
||||
});
|
||||
}
|
||||
async categoryStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
let stat = 0;
|
||||
if (status == 'true') {
|
||||
stat = 1;
|
||||
}
|
||||
const model = this.model('category');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
is_category: stat
|
||||
});
|
||||
}
|
||||
async deleteBannerImageAction() {
|
||||
let id = this.post('id');
|
||||
await this.model('category').where({
|
||||
id: id
|
||||
}).update({
|
||||
img_url: ''
|
||||
});
|
||||
return this.success();
|
||||
}
|
||||
async deleteIconImageAction() {
|
||||
let id = this.post('id');
|
||||
await this.model('category').where({
|
||||
id: id
|
||||
}).update({
|
||||
icon_url: ''
|
||||
});
|
||||
return this.success();
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,13 @@
|
||||
const Base = require('./base.js');
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const data = await this.model('shipper').where({
|
||||
enabled:1
|
||||
}).select();
|
||||
return this.success(data);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,943 @@
|
||||
const Base = require('./base.js');
|
||||
const moment = require('moment');
|
||||
const fs = require('fs');
|
||||
const path = require("path");
|
||||
const qiniu = require('qiniu');
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size');
|
||||
const name = this.get('name') || '';
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
name: ['like', `%${name}%`],
|
||||
is_delete: 0
|
||||
}).order(['sort_order asc']).page(page, size).countSelect();
|
||||
// let newData = data;
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
async getExpressDataAction() {
|
||||
let kd = [];
|
||||
let cate = [];
|
||||
const kdData = await this.model('freight_template').where({
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const item of kdData) {
|
||||
kd.push({
|
||||
value: item.id,
|
||||
label: item.name
|
||||
})
|
||||
}
|
||||
const cateData = await this.model('category').where({
|
||||
parent_id: 0
|
||||
}).select();
|
||||
for (const item of cateData) {
|
||||
cate.push({
|
||||
value: item.id,
|
||||
label: item.name
|
||||
})
|
||||
}
|
||||
let infoData = {
|
||||
kd: kd,
|
||||
cate: cate
|
||||
};
|
||||
return this.success(infoData);
|
||||
}
|
||||
async copygoodsAction() {
|
||||
const goodsId = this.post('id');
|
||||
let data = await this.model('goods').where({
|
||||
id: goodsId
|
||||
}).find();
|
||||
delete data.id;
|
||||
data.is_on_sale = 0;
|
||||
let insertId = await this.model('goods').add(data);
|
||||
let goodsGallery = await this.model('goods_gallery').where({
|
||||
goods_id: goodsId,
|
||||
is_delete:0,
|
||||
}).select();
|
||||
for (const item of goodsGallery) {
|
||||
let gallery = {
|
||||
img_url: item.img_url,
|
||||
sort_order: item.sort_order,
|
||||
goods_id: insertId
|
||||
}
|
||||
await this.model('goods_gallery').add(gallery);
|
||||
}
|
||||
return this.success(insertId);
|
||||
}
|
||||
async updateStock(goods_sn, goods_number) {
|
||||
console.log('存在,现在就更新');
|
||||
await this.model('product').where({
|
||||
goods_sn: goods_sn
|
||||
}).update({
|
||||
goods_number: goods_number
|
||||
});
|
||||
}
|
||||
async updateGoodsNumberAction() {
|
||||
let all_goods = await this.model('goods').where({
|
||||
is_delete: 0,
|
||||
is_on_sale: 1
|
||||
}).select();
|
||||
for (const item of all_goods) {
|
||||
let goodsSum = await this.model('product').where({
|
||||
goods_id: item.id
|
||||
}).sum('goods_number');
|
||||
await this.model('goods').where({
|
||||
id: item.id
|
||||
}).update({
|
||||
goods_number: goodsSum
|
||||
});
|
||||
await think.timeout(2000);
|
||||
}
|
||||
return this.success();
|
||||
}
|
||||
async onsaleAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size');
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
is_delete: 0,
|
||||
is_on_sale: 1
|
||||
}).order(['sort_order asc']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
// if (info.parent_id != 0) {
|
||||
// const parentInfo = await this.model('category').where({id: info.parent_id}).find();
|
||||
// item.category_p_name = parentInfo.name;
|
||||
// }
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
async outAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size');
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
is_delete: 0,
|
||||
goods_number: ['<=', 0]
|
||||
}).order(['sort_order asc']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
async dropAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size');
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
is_delete: 0,
|
||||
is_on_sale: 0
|
||||
}).order(['id DESC']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
async sortAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size');
|
||||
const model = this.model('goods');
|
||||
const index = this.get('index');
|
||||
if (index == 1) {
|
||||
const data = await model.where({
|
||||
is_delete: 0
|
||||
}).order(['sell_volume DESC']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
} else if (index == 2) {
|
||||
const data = await model.where({
|
||||
is_delete: 0
|
||||
}).order(['retail_price DESC']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
} else if (index == 3) {
|
||||
const data = await model.where({
|
||||
is_delete: 0
|
||||
}).order(['goods_number DESC']).page(page, size).countSelect();
|
||||
for (const item of data.data) {
|
||||
const info = await this.model('category').where({
|
||||
id: item.category_id
|
||||
}).find();
|
||||
item.category_name = info.name;
|
||||
if (item.is_on_sale == 1) {
|
||||
item.is_on_sale = true;
|
||||
} else {
|
||||
item.is_on_sale = false;
|
||||
}
|
||||
if (item.is_index == 1) {
|
||||
item.is_index = true;
|
||||
} else {
|
||||
item.is_index = false;
|
||||
}
|
||||
let product = await this.model('product').where({
|
||||
goods_id: item.id,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
for (const ele of product) {
|
||||
let spec = await this.model('goods_specification').where({
|
||||
id: ele.goods_specification_ids,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
ele.value = spec.value;
|
||||
ele.is_on_sale = ele.is_on_sale ? "1" : "0";
|
||||
}
|
||||
item.product = product;
|
||||
}
|
||||
return this.success(data);
|
||||
}
|
||||
}
|
||||
async saleStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
let sale = 0;
|
||||
if (status == 'true') {
|
||||
sale = 1;
|
||||
}
|
||||
const model = this.model('goods');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
is_on_sale: sale
|
||||
});
|
||||
await this.model('cart').where({
|
||||
goods_id: id
|
||||
}).update({
|
||||
is_on_sale: sale,
|
||||
checked: sale
|
||||
});
|
||||
}
|
||||
async productStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
const model = this.model('product');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
is_on_sale: status
|
||||
});
|
||||
// 4.14更新
|
||||
await this.model('cart').where({
|
||||
product_id: id,
|
||||
is_delete: 0
|
||||
}).update({
|
||||
is_on_sale: status
|
||||
})
|
||||
}
|
||||
async indexShowStatusAction() {
|
||||
const id = this.get('id');
|
||||
const status = this.get('status');
|
||||
let stat = 0;
|
||||
if (status == 'true') {
|
||||
stat = 1;
|
||||
}
|
||||
const model = this.model('goods');
|
||||
await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
is_index: stat
|
||||
});
|
||||
}
|
||||
async infoAction() {
|
||||
const id = this.get('id');
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).find();
|
||||
let category_id = data.category_id;
|
||||
let infoData = {
|
||||
info: data,
|
||||
category_id: category_id,
|
||||
};
|
||||
return this.success(infoData);
|
||||
}
|
||||
async getAllSpecificationAction() {
|
||||
const specInfo = await this.model('specification').where({
|
||||
id: ['>', 0]
|
||||
}).select();
|
||||
let specOptionsData = [];
|
||||
for (const spitem of specInfo) {
|
||||
let info = {
|
||||
value: spitem.id,
|
||||
label: spitem.name
|
||||
};
|
||||
specOptionsData.push(info);
|
||||
}
|
||||
return this.success(specOptionsData);
|
||||
}
|
||||
async getAllCategory1Action() { // 我写的算法
|
||||
const model = this.model('category');
|
||||
const data = await model.where({
|
||||
is_show: 1,
|
||||
level: 'L1'
|
||||
}).select();
|
||||
const c_data = await model.where({
|
||||
is_show: 1,
|
||||
level: 'L2'
|
||||
}).select();
|
||||
let newData = [];
|
||||
for (const item of data) {
|
||||
let children = [];
|
||||
for (const citem of c_data) {
|
||||
if (citem.parent_id == item.id) {
|
||||
children.push({
|
||||
value: citem.id,
|
||||
label: citem.name
|
||||
})
|
||||
}
|
||||
}
|
||||
newData.push({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
children: children
|
||||
});
|
||||
}
|
||||
return this.success(newData);
|
||||
}
|
||||
async getAllCategoryAction() { // 老婆的算法
|
||||
const model = this.model('category');
|
||||
const data = await model.where({
|
||||
is_show: 1,
|
||||
level: 'L1'
|
||||
}).field('id,name').select();
|
||||
let newData = [];
|
||||
for (const item of data) {
|
||||
let children = [];
|
||||
const c_data = await model.where({
|
||||
is_show: 1,
|
||||
level: 'L2',
|
||||
parent_id: item.id
|
||||
}).field('id,name').select();
|
||||
for (const c_item of c_data) {
|
||||
children.push({
|
||||
value: c_item.id,
|
||||
label: c_item.name
|
||||
})
|
||||
}
|
||||
newData.push({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
children: children
|
||||
});
|
||||
}
|
||||
return this.success(newData);
|
||||
}
|
||||
async storeAction() {
|
||||
const values = this.post('info');
|
||||
const specData = this.post('specData');
|
||||
const specValue = this.post('specValue');
|
||||
const cateId = this.post('cateId');
|
||||
const model = this.model('goods');
|
||||
let picUrl = values.list_pic_url;
|
||||
let goods_id = values.id;
|
||||
values.category_id = cateId;
|
||||
values.is_index = values.is_index ? 1 : 0;
|
||||
values.is_new = values.is_new ? 1 : 0;
|
||||
let id = values.id;
|
||||
if (id > 0) {
|
||||
await model.where({
|
||||
id: id
|
||||
}).update(values);
|
||||
await this.model('cart').where({
|
||||
goods_id: id
|
||||
}).update({
|
||||
checked: values.is_on_sale,
|
||||
is_on_sale: values.is_on_sale,
|
||||
list_pic_url: picUrl,
|
||||
freight_template_id: values.freight_template_id
|
||||
});
|
||||
await this.model('product').where({
|
||||
goods_id: id
|
||||
}).update({
|
||||
is_delete: 1
|
||||
});
|
||||
await this.model('goods_specification').where({
|
||||
goods_id: id
|
||||
}).update({
|
||||
is_delete: 1
|
||||
});
|
||||
for (const item of specData) {
|
||||
if (item.id > 0) {
|
||||
await this.model('cart').where({
|
||||
product_id: item.id,
|
||||
is_delete: 0,
|
||||
}).update({
|
||||
retail_price: item.retail_price,
|
||||
goods_specifition_name_value: item.value,
|
||||
goods_sn: item.goods_sn
|
||||
});
|
||||
delete item.is_delete;
|
||||
item.is_delete = 0;
|
||||
await this.model('product').where({
|
||||
id: item.id
|
||||
}).update(item);
|
||||
let specificationData = {
|
||||
value: item.value,
|
||||
specification_id: specValue,
|
||||
is_delete: 0
|
||||
};
|
||||
await this.model('goods_specification').where({
|
||||
id: item.goods_specification_ids
|
||||
}).update(specificationData);
|
||||
} else {
|
||||
let specificationData = {
|
||||
value: item.value,
|
||||
goods_id: id,
|
||||
specification_id: specValue
|
||||
}
|
||||
let specId = await this.model('goods_specification').add(specificationData);
|
||||
item.goods_specification_ids = specId;
|
||||
item.goods_id = id;
|
||||
await this.model('product').add(item);
|
||||
}
|
||||
}
|
||||
for(const [index, item] of values.gallery.entries()){
|
||||
if(item.is_delete == 1 && item.id > 0){
|
||||
await this.model('goods_gallery').where({
|
||||
id:item.id
|
||||
}).update({
|
||||
is_delete:1
|
||||
})
|
||||
}
|
||||
else if(item.is_delete == 0 && item.id > 0){
|
||||
await this.model('goods_gallery').where({
|
||||
id:item.id
|
||||
}).update({
|
||||
sort_order:index
|
||||
})
|
||||
}
|
||||
else if(item.is_delete == 0 && item.id == 0){
|
||||
await this.model('goods_gallery').add({
|
||||
goods_id:id,
|
||||
img_url:item.url,
|
||||
sort_order:index
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete values.id;
|
||||
goods_id = await model.add(values);
|
||||
for (const item of specData) {
|
||||
let specificationData = {
|
||||
value: item.value,
|
||||
goods_id: goods_id,
|
||||
specification_id: specValue
|
||||
}
|
||||
let specId = await this.model('goods_specification').add(specificationData);
|
||||
item.goods_specification_ids = specId;
|
||||
item.goods_id = goods_id;
|
||||
item.is_on_sale = 1;
|
||||
await this.model('product').add(item);
|
||||
}
|
||||
for(const [index, item] of values.gallery.entries()){
|
||||
await this.model('goods_gallery').add({
|
||||
goods_id:goods_id,
|
||||
img_url:item.url,
|
||||
sort_order:index
|
||||
})
|
||||
}
|
||||
}
|
||||
let pro = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
if (pro.length > 1) {
|
||||
let goodsNum = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).sum('goods_number');
|
||||
let retail_price = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).getField('retail_price');
|
||||
let maxPrice = Math.max(...retail_price);
|
||||
let minPrice = Math.min(...retail_price);
|
||||
let cost = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).getField('cost');
|
||||
let maxCost = Math.max(...cost);
|
||||
let minCost = Math.min(...cost);
|
||||
let goodsPrice = '';
|
||||
if(minPrice == maxPrice){
|
||||
goodsPrice = minPrice;
|
||||
}
|
||||
else{
|
||||
goodsPrice = minPrice + '~' + maxPrice;
|
||||
}
|
||||
let costPrice = minCost + '~' + maxCost;
|
||||
await this.model('goods').where({
|
||||
id: goods_id
|
||||
}).update({
|
||||
goods_number: goodsNum,
|
||||
retail_price: goodsPrice,
|
||||
cost_price: costPrice,
|
||||
min_retail_price: minPrice,
|
||||
min_cost_price: minCost,
|
||||
});
|
||||
} else {
|
||||
let info = {
|
||||
goods_number: pro[0].goods_number,
|
||||
retail_price: pro[0].retail_price,
|
||||
cost_price: pro[0].cost,
|
||||
min_retail_price: pro[0].retail_price,
|
||||
min_cost_price: pro[0].cost,
|
||||
}
|
||||
await this.model('goods').where({
|
||||
id: goods_id
|
||||
}).update(info);
|
||||
}
|
||||
return this.success(goods_id);
|
||||
}
|
||||
async updatePriceAction() {
|
||||
let data = this.post('');
|
||||
let goods_id = data.goods_id;
|
||||
await this.model('goods_specification').where({
|
||||
id: data.goods_specification_ids
|
||||
}).update({
|
||||
value: data.value
|
||||
});
|
||||
await this.model('product').where({
|
||||
id: data.id
|
||||
}).update(data);
|
||||
let pro = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).select();
|
||||
if(pro.length == 0){
|
||||
return this.fail(100,'商品的规格数量至少1个')
|
||||
}
|
||||
await this.model('cart').where({
|
||||
product_id: data.id,
|
||||
is_delete: 0,
|
||||
}).update({
|
||||
retail_price: data.retail_price,
|
||||
goods_specifition_name_value: data.value,
|
||||
goods_sn: data.goods_sn
|
||||
});
|
||||
delete data.value;
|
||||
|
||||
if (pro.length > 1) {
|
||||
let goodsNum = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).sum('goods_number');
|
||||
let retail_price = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).getField('retail_price');
|
||||
let maxPrice = Math.max(...retail_price);
|
||||
let minPrice = Math.min(...retail_price);
|
||||
let cost = await this.model('product').where({
|
||||
goods_id: goods_id,
|
||||
is_on_sale: 1,
|
||||
is_delete: 0
|
||||
}).getField('cost');
|
||||
let maxCost = Math.max(...cost);
|
||||
let minCost = Math.min(...cost);
|
||||
let goodsPrice = '';
|
||||
if(minPrice == maxPrice){
|
||||
goodsPrice = minPrice;
|
||||
}
|
||||
else{
|
||||
goodsPrice = minPrice + '~' + maxPrice;
|
||||
}
|
||||
let costPrice = minCost + '~' + maxCost;
|
||||
await this.model('goods').where({
|
||||
id: goods_id
|
||||
}).update({
|
||||
goods_number: goodsNum,
|
||||
retail_price: goodsPrice,
|
||||
cost_price: costPrice,
|
||||
min_retail_price: minPrice,
|
||||
min_cost_price: minCost,
|
||||
});
|
||||
} else if(pro.length == 1){
|
||||
let info = {
|
||||
goods_number: pro[0].goods_number,
|
||||
retail_price: pro[0].retail_price,
|
||||
cost_price: pro[0].cost,
|
||||
min_retail_price: pro[0].retail_price,
|
||||
min_cost_price: pro[0].cost,
|
||||
}
|
||||
await this.model('goods').where({
|
||||
id: goods_id
|
||||
}).update(info);
|
||||
}
|
||||
return this.success();
|
||||
}
|
||||
async checkSkuAction() {
|
||||
const info = this.post('info');
|
||||
if (info.id > 0) {
|
||||
const model = this.model('product');
|
||||
const data = await model.where({
|
||||
id: ['<>', info.id],
|
||||
goods_sn: info.goods_sn,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
if (!think.isEmpty(data)) {
|
||||
return this.fail(100, '重复')
|
||||
} else {
|
||||
return this.success();
|
||||
}
|
||||
} else {
|
||||
const model = this.model('product');
|
||||
const data = await model.where({
|
||||
goods_sn: info.goods_sn,
|
||||
is_delete: 0
|
||||
}).find();
|
||||
if (!think.isEmpty(data)) {
|
||||
return this.fail(100, '重复')
|
||||
} else {
|
||||
return this.success();
|
||||
}
|
||||
}
|
||||
}
|
||||
async updateSortAction() {
|
||||
const id = this.post('id');
|
||||
const sort = this.post('sort');
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
sort_order: sort
|
||||
});
|
||||
return this.success(data);
|
||||
}
|
||||
async updateShortNameAction() {
|
||||
const id = this.post('id');
|
||||
const short_name = this.post('short_name');
|
||||
const model = this.model('goods');
|
||||
const data = await model.where({
|
||||
id: id
|
||||
}).update({
|
||||
short_name: short_name
|
||||
});
|
||||
return this.success(data);
|
||||
}
|
||||
async galleryListAction() {
|
||||
const id = this.get('id');
|
||||
const model = this.model('goods_gallery');
|
||||
const data = await model.where({
|
||||
goods_id: id,
|
||||
is_delete:0
|
||||
}).select();
|
||||
// console.log(data);
|
||||
return this.success(data);
|
||||
}
|
||||
async galleryAction() {
|
||||
const url = this.post('url');
|
||||
const id = this.post('goods_id');
|
||||
let info = {
|
||||
goods_id: id,
|
||||
img_url: url
|
||||
}
|
||||
await this.model('goods_gallery').add(info);
|
||||
return this.success();
|
||||
}
|
||||
async getGalleryListAction() {
|
||||
const goodsId = this.post('goodsId');
|
||||
const data = await this.model('goods_gallery').where({
|
||||
goods_id: goodsId,
|
||||
is_delete:0
|
||||
}).order('sort_order asc').select();
|
||||
let galleryData = [];
|
||||
for (const item of data) {
|
||||
let pdata = {
|
||||
id: item.id,
|
||||
url: item.img_url,
|
||||
is_delete:0,
|
||||
}
|
||||
galleryData.push(pdata);
|
||||
}
|
||||
let info = {
|
||||
galleryData: galleryData,
|
||||
}
|
||||
return this.success(info);
|
||||
}
|
||||
async deleteGalleryFileAction() {
|
||||
const url = this.post('url');
|
||||
const id = this.post('id');
|
||||
await this.model('goods_gallery').where({
|
||||
id: id
|
||||
}).limit(1).update({
|
||||
is_delete: 1
|
||||
});
|
||||
return this.success('文件删除成功');
|
||||
}
|
||||
async galleryEditAction() {
|
||||
if (!this.isPost) {
|
||||
return false;
|
||||
}
|
||||
const values = this.post();
|
||||
let data = values.data;
|
||||
// console.log(data);
|
||||
const model = this.model('goods_gallery');
|
||||
for (const item of data) {
|
||||
let id = item.id;
|
||||
let sort = parseInt(item.sort_order);
|
||||
// console.log(sort);
|
||||
await this.model('goods_gallery').where({
|
||||
id: id
|
||||
}).update({
|
||||
sort_order: sort
|
||||
});
|
||||
}
|
||||
return this.success();
|
||||
}
|
||||
async deleteListPicUrlAction() {
|
||||
const id = this.post('id');
|
||||
console.log(id);
|
||||
await this.model('goods').where({
|
||||
id: id
|
||||
}).limit(1).update({
|
||||
list_pic_url: 0
|
||||
});
|
||||
return this.success();
|
||||
}
|
||||
async destoryAction() {
|
||||
const id = this.post('id');
|
||||
await this.model('goods').where({
|
||||
id: id
|
||||
}).limit(1).update({
|
||||
is_delete: 1
|
||||
});
|
||||
await this.model('product').where({
|
||||
goods_id: id
|
||||
}).update({
|
||||
is_delete: 1
|
||||
});
|
||||
await this.model('goods_specification').where({
|
||||
goods_id: id
|
||||
}).update({
|
||||
is_delete: 1
|
||||
});
|
||||
return this.success();
|
||||
}
|
||||
async uploadHttpsImageAction() {
|
||||
let url = this.post('url');
|
||||
let accessKey = think.config('qiniuHttps.access_key');
|
||||
let secretKey = think.config('qiniuHttps.secret_key');
|
||||
let domain = think.config('qiniuHttps.domain');
|
||||
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
|
||||
var config = new qiniu.conf.Config();
|
||||
let zoneNum = think.config('qiniuHttps.zoneNum');
|
||||
if(zoneNum == 0){
|
||||
config.zone = qiniu.zone.Zone_z0;
|
||||
}
|
||||
else if(zoneNum == 1){
|
||||
config.zone = qiniu.zone.Zone_z1;
|
||||
}
|
||||
else if(zoneNum == 2){
|
||||
config.zone = qiniu.zone.Zone_z2;
|
||||
}
|
||||
else if(zoneNum == 3){
|
||||
config.zone = qiniu.zone.Zone_na0;
|
||||
}
|
||||
else if(zoneNum == 4){
|
||||
config.zone = qiniu.zone.Zone_as0;
|
||||
}
|
||||
var bucketManager = new qiniu.rs.BucketManager(mac, config);
|
||||
let bucket = think.config('qiniuHttps.bucket');
|
||||
let key = think.uuid(32);
|
||||
await think.timeout(500);
|
||||
const uploadQiniu = async() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
bucketManager.fetch(url, bucket, key, function(err, respBody, respInfo) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
//throw err;
|
||||
} else {
|
||||
if (respInfo.statusCode == 200) {
|
||||
resolve(respBody.key)
|
||||
} else {
|
||||
console.log(respInfo.statusCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
return resolve(null);
|
||||
}
|
||||
})
|
||||
};
|
||||
const httpsUrl = await uploadQiniu();
|
||||
console.log(httpsUrl);
|
||||
let lastUrl = domain + httpsUrl;
|
||||
return this.success(lastUrl);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,254 @@
|
||||
const Base = require('./base.js');
|
||||
const moment = require('moment');
|
||||
|
||||
module.exports = class extends Base {
|
||||
async checkLoginAction(){
|
||||
if(think.userId == 0){
|
||||
return this.fail(404,'请登录');
|
||||
}
|
||||
}
|
||||
async indexAction() {
|
||||
const goodsOnsale = await this.model('goods').where({is_on_sale: 1,is_delete:0}).count();
|
||||
const orderToDelivery = await this.model('order').where({order_status: 300}).count();
|
||||
const user = await this.model('user').count();
|
||||
let data = await this.model('settings').field('countdown').find();
|
||||
let timestamp = data.countdown;
|
||||
let info = {
|
||||
user: user,
|
||||
goodsOnsale: goodsOnsale,
|
||||
timestamp:timestamp,
|
||||
orderToDelivery: orderToDelivery,
|
||||
}
|
||||
return this.success(info);
|
||||
}
|
||||
async getQiniuTokenAction(){
|
||||
const TokenSerivce = this.service('qiniu'); // 服务里返回token
|
||||
let data = await TokenSerivce.getQiniuToken(); // 取得token值 goods
|
||||
let qiniuToken = data.uploadToken;
|
||||
let domain = data.domain;
|
||||
let info ={
|
||||
token:qiniuToken,
|
||||
url:domain
|
||||
};
|
||||
return this.success(info);
|
||||
}
|
||||
async mainAction() {
|
||||
const index = this.get('pindex');
|
||||
console.log('index:' + index);
|
||||
let todayTimeStamp = new Date(new Date().setHours(0, 0, 0, 0)) / 1000; //今天零点的时间戳
|
||||
let yesTimeStamp = todayTimeStamp - 86400; //昨天零点的时间戳
|
||||
let sevenTimeStamp = todayTimeStamp - 86400 * 7; //7天前零点的时间戳
|
||||
let thirtyTimeStamp = todayTimeStamp - 86400 * 30; //30天前零点的时间戳
|
||||
let newUser = 1;
|
||||
let oldUser = 0;
|
||||
let addCart = 0;
|
||||
let addOrderNum = 0;
|
||||
let addOrderSum = 0;
|
||||
let payOrderNum = 0;
|
||||
let payOrderSum = 0;
|
||||
let newData = [];
|
||||
let oldData = [];
|
||||
if (index == 0) {
|
||||
newData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['>', todayTimeStamp]
|
||||
}).select();
|
||||
newUser = newData.length;
|
||||
for(const item of newData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
oldData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['<', todayTimeStamp],
|
||||
last_login_time: ['>', todayTimeStamp]
|
||||
}).select();
|
||||
for(const item of oldData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
oldUser = oldData.length;
|
||||
addCart = await this.model('cart').where({is_delete: 0, add_time: ['>', todayTimeStamp]}).count();
|
||||
addOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', todayTimeStamp]
|
||||
}).count();
|
||||
addOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', todayTimeStamp]
|
||||
}).sum('actual_price');
|
||||
payOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', todayTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).count();
|
||||
payOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', todayTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).sum('actual_price');
|
||||
}
|
||||
else if (index == 1) {
|
||||
newData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['BETWEEN', yesTimeStamp, todayTimeStamp]
|
||||
}).select();
|
||||
for(const item of newData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
newUser = newData.length;
|
||||
oldData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['<', yesTimeStamp],
|
||||
last_login_time: ['BETWEEN', yesTimeStamp, todayTimeStamp]
|
||||
}).select();
|
||||
for(const item of oldData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
oldUser = oldData.length;
|
||||
addCart = await this.model('cart').where({
|
||||
is_delete: 0,
|
||||
add_time: ['BETWEEN', yesTimeStamp, todayTimeStamp]
|
||||
}).count();
|
||||
addOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['BETWEEN', yesTimeStamp, todayTimeStamp]
|
||||
}).count();
|
||||
addOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['BETWEEN', yesTimeStamp, todayTimeStamp]
|
||||
}).sum('actual_price');
|
||||
payOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['BETWEEN', yesTimeStamp, todayTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).count();
|
||||
console.log('------------321----------');
|
||||
console.log(payOrderNum);
|
||||
console.log('-----------3321-----------');
|
||||
payOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['BETWEEN', yesTimeStamp, todayTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).sum('actual_price');
|
||||
console.log('-----------123-----------');
|
||||
console.log(payOrderSum);
|
||||
console.log('-----------123-----------');
|
||||
|
||||
}
|
||||
else if (index == 2) {
|
||||
newData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['>', sevenTimeStamp]
|
||||
}).select();
|
||||
for(const item of newData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
newUser = newData.length;
|
||||
oldData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['<', sevenTimeStamp],
|
||||
last_login_time: ['>', sevenTimeStamp]
|
||||
}).select();
|
||||
for(const item of oldData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
oldUser = oldData.length;
|
||||
addCart = await this.model('cart').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', sevenTimeStamp]
|
||||
}).count();
|
||||
addOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', sevenTimeStamp]
|
||||
}).count();
|
||||
addOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', sevenTimeStamp]
|
||||
}).sum('actual_price');
|
||||
payOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', sevenTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).count();
|
||||
payOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', sevenTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).sum('actual_price');
|
||||
}
|
||||
else if (index == 3) {
|
||||
newData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['>', thirtyTimeStamp]
|
||||
}).select();
|
||||
for(const item of newData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
newUser = newData.length;
|
||||
oldData = await this.model('user').where({
|
||||
id: ['>', 0],
|
||||
register_time: ['<', thirtyTimeStamp],
|
||||
last_login_time: ['>', thirtyTimeStamp]
|
||||
}).select();
|
||||
for(const item of oldData){
|
||||
item.nickname = Buffer.from(item.nickname, 'base64').toString();
|
||||
}
|
||||
oldUser = oldData.length;
|
||||
addCart = await this.model('cart').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', thirtyTimeStamp]
|
||||
}).count();
|
||||
addOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', thirtyTimeStamp]
|
||||
}).count();
|
||||
addOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', thirtyTimeStamp]
|
||||
}).sum('actual_price');
|
||||
payOrderNum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', thirtyTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).count();
|
||||
payOrderSum = await this.model('order').where({
|
||||
is_delete: 0,
|
||||
add_time: ['>', thirtyTimeStamp],
|
||||
order_status: ['IN', [201, 802, 300, 301]]
|
||||
}).sum('actual_price');
|
||||
}
|
||||
if (addOrderSum == null) {
|
||||
addOrderSum = 0;
|
||||
}
|
||||
if (payOrderSum == null) {
|
||||
payOrderSum = 0;
|
||||
}
|
||||
if(newData.length > 0){
|
||||
for(const item of newData){
|
||||
item.register_time = moment.unix(item.register_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
item.last_login_time = moment.unix(item.last_login_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
}
|
||||
|
||||
if(oldData.length > 0){
|
||||
for(const item of oldData){
|
||||
item.register_time = moment.unix(item.register_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
item.last_login_time = moment.unix(item.last_login_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
}
|
||||
|
||||
let info = {
|
||||
newUser: newUser,
|
||||
oldUser: oldUser,
|
||||
addCart: addCart,
|
||||
newData: newData,
|
||||
oldData: oldData,
|
||||
addOrderNum: addOrderNum,
|
||||
addOrderSum: addOrderSum,
|
||||
payOrderNum: payOrderNum,
|
||||
payOrderSum: payOrderSum
|
||||
}
|
||||
return this.success(info);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
const Base = require('./base.js');
|
||||
const moment = require('moment');
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const page = this.get('page') || 1;
|
||||
const size = this.get('size') || 10;
|
||||
const name = this.get('name') || '';
|
||||
|
||||
const model = this.model('cart');
|
||||
const data = await model.where({goods_name: ['like', `%${name}%`]}).order(['id DESC']).page(page, size).countSelect();
|
||||
|
||||
for (const item of data.data) {
|
||||
item.add_time = moment.unix(item.add_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
|
||||
return this.success(data);
|
||||
}
|
||||
|
||||
};
|
||||
@ -0,0 +1,76 @@
|
||||
const Base = require('./base.js');
|
||||
const moment = require('moment');
|
||||
|
||||
module.exports = class extends Base {
|
||||
/**
|
||||
* index action
|
||||
* @return {Promise} []
|
||||
*/
|
||||
async indexAction() {
|
||||
const model = this.model('notice');
|
||||
const data = await model.select();
|
||||
|
||||
for (const item of data) {
|
||||
item.end_time = moment.unix(item.end_time).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
|
||||
return this.success(data);
|
||||
}
|
||||
|
||||
async updateContentAction() {
|
||||
const id = this.post('id');
|
||||
const content = this.post('content');
|
||||
const model = this.model('notice');
|
||||
const data = await model.where({id: id}).update({content: content});
|
||||
return this.success(data);
|
||||
}
|
||||
|
||||
|
||||
async addAction() {
|
||||
const content = this.post('content');
|
||||
let end_time = this.post('time');
|
||||
|
||||
end_time = parseInt(new Date(end_time).getTime() / 1000);
|
||||
|
||||
let info = {
|
||||
content:content,
|
||||
end_time:end_time
|
||||
}
|
||||
const model = this.model('notice');
|
||||
const data = await model.add(info);
|
||||
return this.success(data);
|
||||
}
|
||||
|
||||
|
||||
async updateAction() {
|
||||
const content = this.post('content');
|
||||
let end_time = this.post('time');
|
||||
let id = this.post('id');
|
||||
|
||||
end_time = parseInt(new Date(end_time).getTime() / 1000);
|
||||
const currentTime = parseInt(new Date().getTime() / 1000);
|
||||
|
||||
|
||||
let info = {
|
||||
content:content,
|
||||
end_time:end_time
|
||||
};
|
||||
|
||||
if(end_time > currentTime){
|
||||
info.is_delete = 0;
|
||||
}
|
||||
else{
|
||||
info.is_delete = 1;
|
||||
}
|
||||
const model = this.model('notice');
|
||||
const data = await model.where({id:id}).update(info);
|
||||
return this.success(data);
|
||||
}
|
||||
|
||||
|
||||
async destoryAction() {
|
||||
const id = this.post('id');
|
||||
await this.model('notice').where({id: id}).limit(1).delete();
|
||||
return this.success();
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue