优化添加商品问题 新增添加设备
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
ENV = 'development'
|
||||
|
||||
# 接口地址
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.128:8000'
|
||||
VUE_APP_BASE_API = 'https://cashieradmin.sxczgkj.cn'
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.128:8000' // 刘一帆
|
||||
VUE_APP_BASE_API = 'http://192.168.2.98:8000'
|
||||
# VUE_APP_BASE_API = 'https://cashieradmin.sxczgkj.cn'
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.16:8000'
|
||||
VUE_APP_WS_API = 'ws://192.168.2.128:8000'
|
||||
|
||||
|
||||
@@ -3,5 +3,6 @@ ENV = 'production'
|
||||
# 如果使用 Nginx 代理后端接口,那么此处需要改为 '/',文件查看 Docker 部署篇,Nginx 配置
|
||||
# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http
|
||||
VUE_APP_BASE_API = 'https://cashieradmin.sxczgkj.cn'
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.98:8000'
|
||||
# 如果接口是 http 形式, wss 需要改为 ws
|
||||
VUE_APP_WS_API = 'wss://123.56.110.252
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 17 KiB |
@@ -71,7 +71,6 @@ export default {
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-color: $borderColor;
|
||||
}
|
||||
|
||||
&.active {
|
||||
|
||||
32
src/api/devices.js
Normal file
32
src/api/devices.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 增加打印机
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachine(data, method = 'post') {
|
||||
return request({
|
||||
url: '/api/tbPrintMachine',
|
||||
method: method,
|
||||
data: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印机列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachineGet(params) {
|
||||
return request({
|
||||
url: '/api/tbPrintMachine',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: '',
|
||||
...params
|
||||
}
|
||||
})
|
||||
}
|
||||
91
src/api/home.js
Normal file
91
src/api/home.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 汇总数据
|
||||
* @returns
|
||||
*/
|
||||
export function summaryGet() {
|
||||
return request({
|
||||
url: '/api/summary',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日数据
|
||||
* @returns
|
||||
*/
|
||||
export function summaryTodayGet() {
|
||||
return request({
|
||||
url: '/api/summary/today',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日数据
|
||||
* @returns
|
||||
*/
|
||||
export function summaryDateGet(day) {
|
||||
return request({
|
||||
url: '/api/summary/date',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 销售额柱状图
|
||||
* @returns
|
||||
*/
|
||||
export function dateAmount(day) {
|
||||
return request({
|
||||
url: '/api/summary/dateAmount',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品销售排行
|
||||
* @returns
|
||||
*/
|
||||
export function dateProduct(day, page) {
|
||||
return request({
|
||||
url: '/api/summary/dateProduct',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day,
|
||||
page: page
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付类型占比
|
||||
* @returns
|
||||
*/
|
||||
export function datePayType(day) {
|
||||
return request({
|
||||
url: '/api/summary/datePayType',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
BIN
src/assets/images/background_img.jpg
Normal file
BIN
src/assets/images/background_img.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 364 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
@@ -1,23 +1,23 @@
|
||||
// base color
|
||||
$blue:#324157;
|
||||
$light-blue:#3A71A8;
|
||||
$red:#C03639;
|
||||
$pink: #E65D6E;
|
||||
$green: #30B08F;
|
||||
$tiffany: #4AB7BD;
|
||||
$yellow:#FEC171;
|
||||
$panGreen: #30B08F;
|
||||
$blue: #324157;
|
||||
$light-blue: #3a71a8;
|
||||
$red: #c03639;
|
||||
$pink: #e65d6e;
|
||||
$green: #30b08f;
|
||||
$tiffany: #4ab7bd;
|
||||
$yellow: #fec171;
|
||||
$panGreen: #30b08f;
|
||||
|
||||
// sidebar
|
||||
$menuText:#bfcbd9;
|
||||
$menuActiveText:#409EFF;
|
||||
$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
|
||||
$menuText: #bfcbd9;
|
||||
$menuActiveText: #409eff;
|
||||
$subMenuActiveText: #f4f4f5; // https://github.com/ElemeFE/element/issues/12951
|
||||
|
||||
$menuBg:#304156;
|
||||
$menuHover:#263445;
|
||||
$menuBg: #333;
|
||||
$menuHover: #444;
|
||||
|
||||
$subMenuBg:#1f2d3d;
|
||||
$subMenuHover:#001528;
|
||||
$subMenuBg: #444;
|
||||
$subMenuHover: #555;
|
||||
|
||||
$sideBarWidth: 205px;
|
||||
|
||||
|
||||
119
src/components/classify/index.vue
Normal file
119
src/components/classify/index.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<el-dialog title="选择分类" :visible.sync="dialogVisible">
|
||||
<div class="list" v-loading="loading">
|
||||
<div class="row" v-for="(item, index) in categorys" :key="item.id">
|
||||
<div class="list_title">{{ item.name }}</div>
|
||||
<div class="item_wrap">
|
||||
<el-button :type="item.active ? 'primary' : ''" @click="selectHandle(item)">全部</el-button>
|
||||
<el-button :type="item.active ? 'primary' : ''" v-for="val in item.childrenList" :key="val.id"
|
||||
@click="selectHandle(val, index)">{{
|
||||
val.name }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopCategoryGet } from '@/api/shop'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
loading: false,
|
||||
categorys: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbShopCategoryGet()
|
||||
},
|
||||
methods: {
|
||||
// 确认选择分类
|
||||
onSubmitHandle() {
|
||||
let categorys = []
|
||||
for (let item of this.categorys) {
|
||||
if (item.active) {
|
||||
categorys.push({
|
||||
name: `${item.name}`,
|
||||
id: item.id
|
||||
})
|
||||
}
|
||||
if (item.childrenList.length) {
|
||||
for (let val of item.childrenList) {
|
||||
if (val.active) {
|
||||
categorys.push({
|
||||
name: `${val.name}`,
|
||||
id: val.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$emit('success', categorys)
|
||||
this.dialogVisible = false
|
||||
},
|
||||
// 选择分类
|
||||
selectHandle(item, index = -1) {
|
||||
if (index != -1) {
|
||||
this.categorys[index].childrenList.map(val => {
|
||||
val.active = false
|
||||
})
|
||||
}
|
||||
item.active = !item.active
|
||||
},
|
||||
// 获取分类
|
||||
async tbShopCategoryGet() {
|
||||
try {
|
||||
this.loading = true
|
||||
const res = await tbShopCategoryGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: 'sort,desc',
|
||||
page: 0,
|
||||
size: 500
|
||||
})
|
||||
res.content.map(item => {
|
||||
item.active = false
|
||||
item.childrenList.map(item => {
|
||||
item.active = false
|
||||
})
|
||||
})
|
||||
this.categorys = res.content
|
||||
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
show() {
|
||||
this.dialogVisible = true
|
||||
this.tbShopCategoryGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.list {
|
||||
min-height: 200px;
|
||||
|
||||
.row {
|
||||
padding-bottom: 20px;
|
||||
|
||||
.list_title {
|
||||
color: #999;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.item_wrap {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -2,39 +2,32 @@
|
||||
<div class="navbar">
|
||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container"
|
||||
@toggleClick="toggleSideBar" />
|
||||
|
||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="device !== 'mobile'">
|
||||
<!-- <template v-if="device !== 'mobile'">
|
||||
<search id="header-search" class="right-menu-item" />
|
||||
|
||||
<!-- <el-tooltip content="项目文档" effect="dark" placement="bottom">
|
||||
<el-tooltip content="项目文档" effect="dark" placement="bottom">
|
||||
<Doc class="right-menu-item hover-effect" />
|
||||
</el-tooltip> -->
|
||||
|
||||
</el-tooltip>
|
||||
<el-tooltip content="全屏缩放" effect="dark" placement="bottom">
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip content="布局设置" effect="dark" placement="bottom">
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
||||
</template>
|
||||
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||
</template> -->
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar" class="user-avatar">
|
||||
<i class="el-icon-caret-bottom" />
|
||||
<!-- <i class="el-icon-caret-bottom" /> -->
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<span style="display:block;" @click="show = true">
|
||||
<!-- <span style="display:block;" @click="show = true">
|
||||
<el-dropdown-item>
|
||||
布局设置
|
||||
</el-dropdown-item>
|
||||
</span>
|
||||
<router-link to="/user/center">
|
||||
</span> -->
|
||||
<router-link to="/shop/shop/shop_configuration">
|
||||
<el-dropdown-item>
|
||||
个人中心
|
||||
</el-dropdown-item>
|
||||
@@ -175,7 +168,7 @@ export default {
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
margin-right: 30px;
|
||||
margin-right: 10px;
|
||||
|
||||
.avatar-wrapper {
|
||||
margin-top: 5px;
|
||||
@@ -185,7 +178,7 @@ export default {
|
||||
cursor: pointer;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.el-icon-caret-bottom {
|
||||
|
||||
@@ -5,7 +5,8 @@ import Layout from '../layout/index'
|
||||
Vue.use(Router)
|
||||
|
||||
export const constantRouterMap = [
|
||||
{ path: '/login',
|
||||
{
|
||||
path: '/login',
|
||||
meta: { title: '登录', noCache: true },
|
||||
component: (resolve) => require(['@/views/login'], resolve),
|
||||
hidden: true
|
||||
@@ -34,13 +35,23 @@ export const constantRouterMap = [
|
||||
{
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/dashboard',
|
||||
redirect: '/data_statistics',
|
||||
meta: {
|
||||
title: '数据统计',
|
||||
icon: 'index'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: (resolve) => require(['@/views/home'], resolve),
|
||||
name: 'Dashboard',
|
||||
meta: { title: '首页', icon: 'index', affix: true, noCache: true }
|
||||
path: 'data_statistics',
|
||||
component: (resolve) => require(['@/views/home/home'], resolve),
|
||||
name: 'data_statistics',
|
||||
meta: { title: '数据统计' }
|
||||
},
|
||||
{
|
||||
path: 'data_forms',
|
||||
component: (resolve) => require(['@/views/home/data_forms'], resolve),
|
||||
name: 'data_forms',
|
||||
meta: { title: '数据报表' }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@ export function parseTime(time, cFormat) {
|
||||
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key]
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
|
||||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
|
||||
if (result.length > 0 && value < 10) {
|
||||
value = '0' + value
|
||||
}
|
||||
@@ -165,12 +165,12 @@ export function param2Obj(url) {
|
||||
}
|
||||
return JSON.parse(
|
||||
'{"' +
|
||||
decodeURIComponent(search)
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/&/g, '","')
|
||||
.replace(/=/g, '":"')
|
||||
.replace(/\+/g, ' ') +
|
||||
'"}'
|
||||
decodeURIComponent(search)
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/&/g, '","')
|
||||
.replace(/=/g, '":"')
|
||||
.replace(/\+/g, ' ') +
|
||||
'"}'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ export function getTime(type) {
|
||||
export function debounce(func, wait, immediate) {
|
||||
let timeout, args, context, timestamp, result
|
||||
|
||||
const later = function() {
|
||||
const later = function () {
|
||||
// 据上一次触发时间间隔
|
||||
const last = +new Date() - timestamp
|
||||
|
||||
@@ -266,7 +266,7 @@ export function debounce(func, wait, immediate) {
|
||||
}
|
||||
}
|
||||
|
||||
return function(...args) {
|
||||
return function (...args) {
|
||||
context = this
|
||||
timestamp = +new Date()
|
||||
const callNow = immediate && !timeout
|
||||
@@ -386,3 +386,15 @@ export function downloadFile(obj, name, suffix) {
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成范围随机数
|
||||
* @param {Object} Min
|
||||
* @param {Object} Max
|
||||
*/
|
||||
export function RandomNumBoth(Max, Min = 0) {
|
||||
var Range = Max - Min;
|
||||
var Rand = Math.random();
|
||||
var num = Min + Math.round(Rand * Range); //四舍五入
|
||||
return num;
|
||||
}
|
||||
|
||||
192
src/views/devices/components/addDevice.vue
Normal file
192
src/views/devices/components/addDevice.vue
Normal file
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog title="添加云打印机" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="层级">
|
||||
<el-select v-model="form.contentType">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in devices"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备尺寸">
|
||||
<el-radio-group v-model="form.config.width">
|
||||
<el-radio-button label="58mm"></el-radio-button>
|
||||
<el-radio-button label="80mm"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入设备名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备号" prop="address">
|
||||
<el-input v-model="form.address" placeholder="请输入设备号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="打印份数">
|
||||
<el-select v-model="form.config.printerNum">
|
||||
<el-option :label="item" :value="item" v-for="item in 4" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="出品模式">
|
||||
<el-select v-model="form.config.model">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in models"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打印类型">
|
||||
<el-select v-model="form.subType">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in subTypes"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="尾部留空">
|
||||
<el-radio-group v-model="form.config.feet">
|
||||
<el-radio-button :label="`${item}`" v-for="item in feets" :key="item">{{ item
|
||||
}}行</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="自动切刀">
|
||||
<el-switch v-model="form.config.autoCut" :active-value="0" :inactive-value="1"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-switch v-model="form.status" :active-value="0" :inactive-value="1"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sort" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类">
|
||||
<div style="cursor: pointer;" @click="$refs.classify.show()">
|
||||
<span style="color: #409eff;" v-for="item in form.config.categoryList">{{ item.name }},</span>
|
||||
<span style="color: #e65d6e;" v-if="!form.config.categoryList.length">请选择分类</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<classify ref="classify" @success="classifySuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import devices from '../devices'
|
||||
import { tbPrintMachine } from '@/api/devices'
|
||||
import classify from '@/components/classify'
|
||||
|
||||
export default {
|
||||
components: { classify },
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
devices,
|
||||
models: [
|
||||
{
|
||||
value: 'normal',
|
||||
name: '普通出单'
|
||||
},
|
||||
{
|
||||
value: 'one',
|
||||
name: '一菜一品'
|
||||
},
|
||||
{
|
||||
value: 'category',
|
||||
name: '分类出单'
|
||||
}
|
||||
],
|
||||
subTypes: [
|
||||
{
|
||||
value: 'kitchen',
|
||||
name: '出品'
|
||||
},
|
||||
{
|
||||
value: 'cash',
|
||||
name: '小票'
|
||||
},
|
||||
{
|
||||
value: 'label',
|
||||
name: '标签'
|
||||
}
|
||||
],
|
||||
feets: [0, 1, 2, 3, 4, 5, 8],
|
||||
loading: false,
|
||||
form: {
|
||||
id: '',
|
||||
contentType: '',
|
||||
config: {
|
||||
width: '80mm', // 设备尺寸
|
||||
printerNum: 1, //打印份数
|
||||
categoryList: '', // 商品分类
|
||||
model: 'normal', // 出品模式,
|
||||
feet: '0',
|
||||
autoCut: 0
|
||||
},
|
||||
name: '',
|
||||
subType: 'kitchen', // 打印类型
|
||||
status: 0,
|
||||
sort: ''
|
||||
},
|
||||
resetForm: '',
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
address: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form }
|
||||
},
|
||||
methods: {
|
||||
// 确认选择商品分类
|
||||
classifySuccess(e) {
|
||||
this.form.config.categoryList = e
|
||||
},
|
||||
onSubmitHandle() {
|
||||
console.log(this.form)
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.loading = true
|
||||
this.form.shopId = localStorage.getItem('shopId')
|
||||
let res = await tbPrintMachine(this.form, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form = obj
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form = { ...this.resetForm }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
10
src/views/devices/devices.js
Normal file
10
src/views/devices/devices.js
Normal file
@@ -0,0 +1,10 @@
|
||||
export default [
|
||||
{
|
||||
value: 'yxyPrinter',
|
||||
name: '云想印'
|
||||
},
|
||||
{
|
||||
value: 'fePrinter',
|
||||
name: '飞鹅'
|
||||
}
|
||||
]
|
||||
94
src/views/devices/devices_list.vue
Normal file
94
src/views/devices/devices_list.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-form :model="query" inline>
|
||||
<el-form-item>
|
||||
<el-input v-model="query.name" placeholder="请输入设备名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="query.type" placeholder="请选择设备类型">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in devices" :key="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary">查询</el-button>
|
||||
<el-button>重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addDevice.show()">添加云打印机</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.data" v-loading="tableData.loading">
|
||||
<el-table-column label="设备名称" prop="name"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total"></el-pagination>
|
||||
</div>
|
||||
<addDevice ref="addDevice" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import devices from './devices'
|
||||
import addDevice from './components/addDevice'
|
||||
import { tbPrintMachineGet } from '@/api/devices'
|
||||
export default {
|
||||
components: {
|
||||
addDevice
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
name: '',
|
||||
type: ''
|
||||
},
|
||||
devices,
|
||||
tableData: {
|
||||
data: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.categoryId = ''
|
||||
this.query.typeEnum = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbPrintMachineGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
name: this.query.name,
|
||||
contentType: this.query.type
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.data = res
|
||||
this.tableData.total = res.length
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,115 +0,0 @@
|
||||
<template>
|
||||
<el-image :src="this.shouye"></el-image>
|
||||
<!-- <div class="dashboard-container">
|
||||
<div class="dashboard-editor-container">
|
||||
<github-corner class="github-corner" />
|
||||
|
||||
<panel-group @handleSetLineChartData="handleSetLineChartData" />
|
||||
|
||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
||||
<line-chart :chart-data="lineChartData" />
|
||||
</el-row>
|
||||
<el-row :gutter="32">
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<radar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<pie-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<bar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GithubCorner from '@/components/GithubCorner'
|
||||
import PanelGroup from './dashboard/PanelGroup'
|
||||
import LineChart from './dashboard/LineChart'
|
||||
import RadarChart from '@/components/Echarts/RadarChart'
|
||||
import PieChart from '@/components/Echarts/PieChart'
|
||||
import BarChart from '@/components/Echarts/BarChart'
|
||||
import shouye from '@/assets/images/background.webp'
|
||||
|
||||
|
||||
const lineChartData = {
|
||||
newVisitis: {
|
||||
expectedData: [100, 120, 161, 134, 105, 160, 165],
|
||||
actualData: [120, 82, 91, 154, 162, 140, 145]
|
||||
},
|
||||
messages: {
|
||||
expectedData: [200, 192, 120, 144, 160, 130, 140],
|
||||
actualData: [180, 160, 151, 106, 145, 150, 130]
|
||||
},
|
||||
purchases: {
|
||||
expectedData: [80, 100, 121, 104, 105, 90, 100],
|
||||
actualData: [120, 90, 100, 138, 142, 130, 130]
|
||||
},
|
||||
shoppings: {
|
||||
expectedData: [130, 140, 141, 142, 145, 150, 160],
|
||||
actualData: [120, 82, 91, 154, 162, 140, 130]
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'Dashboard',
|
||||
components: {
|
||||
GithubCorner,
|
||||
PanelGroup,
|
||||
LineChart,
|
||||
RadarChart,
|
||||
PieChart,
|
||||
BarChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shouye:shouye,
|
||||
lineChartData: lineChartData.newVisitis
|
||||
|
||||
}
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
handleSetLineChartData(type) {
|
||||
this.lineChartData = lineChartData[type]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.dashboard-editor-container {
|
||||
padding: 32px;
|
||||
background-color: rgb(240, 242, 245);
|
||||
position: relative;
|
||||
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.chart-wrapper {
|
||||
background: #fff;
|
||||
padding: 16px 16px 0;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:1024px) {
|
||||
.chart-wrapper {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
3
src/views/home/data_forms.vue
Normal file
3
src/views/home/data_forms.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>数据报表</div>
|
||||
</template>
|
||||
448
src/views/home/home.vue
Normal file
448
src/views/home/home.vue
Normal file
@@ -0,0 +1,448 @@
|
||||
<template>
|
||||
<div class="app-container" style="padding-bottom: 100px;">
|
||||
<div class="card_wrap">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">总销售额</div>
|
||||
<el-tooltip effect="dark" content="订单支付金额" placement="top">
|
||||
<i class="icon el-icon-warning-outline"></i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="number">{{ topData.totalSales || 0 }}</div>
|
||||
<div class="row">平均每单{{ topData.averageSales || 0 }}</div>
|
||||
<div class="row">今日销售额{{ topData.totalSalesToday || 0 }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">支付笔数</div>
|
||||
</div>
|
||||
<div class="number">{{ topData.paymentsNumber }}</div>
|
||||
<div class="row"></div>
|
||||
<div class="row">今日支付笔数{{ topData.paymentsNumberToday || 0 }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">用户数</div>
|
||||
</div>
|
||||
<div class="number">{{ topData.totalUser }}</div>
|
||||
<div class="row"></div>
|
||||
<div class="row">今日新增 {{ topData.userToday || 0 }} <i class="icon el-icon-caret-top"></i> </div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 销售额 -->
|
||||
<div class="chart_wrap">
|
||||
<div class="item">
|
||||
<div class="header">
|
||||
<div class="tab_wrap">
|
||||
<div class="item active">销售额</div>
|
||||
</div>
|
||||
<el-radio-group v-model="saleActive" @change="dateAmount">
|
||||
<el-radio-button label="7">近7天</el-radio-button>
|
||||
<el-radio-button label="30">30天</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="chart" ref="saleChart" v-loading="saleLoading" style="height: 400px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart_wrap" style="display: flex;">
|
||||
<!-- 商品销售排行 -->
|
||||
<div class="item">
|
||||
<div class="header">
|
||||
<div class="tab_wrap">
|
||||
<div class="item active">商品销售排行</div>
|
||||
</div>
|
||||
<el-radio-group v-model="saleTableActive" @change="dateProduct">
|
||||
<el-radio-button label="7">近7天</el-radio-button>
|
||||
<el-radio-button label="30">30天</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="sale_data">
|
||||
<div class="card">
|
||||
<div class="sale_data_header">
|
||||
<div class="card_title">销售数量</div>
|
||||
</div>
|
||||
<div class="number">{{ productCount }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="sale_data_header">
|
||||
<div class="card_title">销售金额</div>
|
||||
</div>
|
||||
<div class="number">¥{{ productSum }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table">
|
||||
<el-table :data="saleTable" v-loading="saleTableLoading">
|
||||
<el-table-column label="排名" prop="productId"></el-table-column>
|
||||
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
||||
<el-table-column label="数量" prop="productNum"></el-table-column>
|
||||
<el-table-column label="金额" prop="amount"></el-table-column>
|
||||
</el-table>
|
||||
<div class="head-container" style="padding-top: 20px;display: flex;justify-content: flex-end;">
|
||||
<el-pagination :total="saleTableTotal" :current-page="saleTablePage" @current-change="paginationChange"
|
||||
layout="total, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 支付类型占比 -->
|
||||
<div class="item" style="margin-left: 20px;">
|
||||
<div class="header">
|
||||
<div class="tab_wrap">
|
||||
<div class="item active">支付占比类型</div>
|
||||
</div>
|
||||
<el-radio-group v-model="payChartDay" @change="datePayType">
|
||||
<el-radio-button label="7">近7天</el-radio-button>
|
||||
<el-radio-button label="30">30天</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div style="height: 400px;margin-top: 30px;" ref="payChart" v-loading="payChartLoading"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { summaryGet, summaryTodayGet, dateProduct, dateAmount, datePayType } from '@/api/home'
|
||||
import echarts from 'echarts'
|
||||
import { debounce } from '@/utils'
|
||||
export default {
|
||||
name: 'home',
|
||||
data() {
|
||||
return {
|
||||
topData: '',
|
||||
saleTab: 'sale',
|
||||
saleActive: '7',
|
||||
saleLoading: false,
|
||||
saleChart: null,
|
||||
payChartDay: '7',
|
||||
payChartLoading: false,
|
||||
payChart: null,
|
||||
chartType: 1,
|
||||
productCount: 0,
|
||||
productSum: 0,
|
||||
saleTableActive: '7',
|
||||
saleTable: [],
|
||||
saleTableLoading: false,
|
||||
saleTablePage: 1,
|
||||
saleTableTotal: 0,
|
||||
__resizeHandler: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.summaryGet()
|
||||
this.dateAmount()
|
||||
this.dateProduct()
|
||||
this.datePayType()
|
||||
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.saleChart) {
|
||||
this.saleChart.resize()
|
||||
}
|
||||
if (this.payChart) {
|
||||
this.payChart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
},
|
||||
methods: {
|
||||
// 初始化销售额图标
|
||||
initSaleChart(time, data) {
|
||||
this.saleChart = null
|
||||
this.saleChart = echarts.init(this.$refs.saleChart)
|
||||
this.saleChart.setOption({
|
||||
title: {
|
||||
text: '销售趋势',
|
||||
x: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: time,
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: time.length <= 7 ? 0 : 45,
|
||||
interval: 0,
|
||||
textStyle: {
|
||||
fontSize: '9'
|
||||
}
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: '#ececec'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: data,
|
||||
type: 'bar',
|
||||
barWidth: time.length <= 7 ? '50%' : '30%'
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 初始化销售额图表
|
||||
initPayChart(data) {
|
||||
this.payChart = echarts.init(this.$refs.payChart)
|
||||
this.payChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
color: ['#409eff', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 20
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 获取销售额柱状图数据
|
||||
async dateAmount() {
|
||||
try {
|
||||
this.saleLoading = true
|
||||
const res = await dateAmount(this.saleActive)
|
||||
const data = res.total.map(item => item.amount)
|
||||
const time = res.total.map(item => item.tradeDay)
|
||||
this.initSaleChart(time, data)
|
||||
setTimeout(() => {
|
||||
this.saleLoading = false
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
paginationChange(e) {
|
||||
this.saleTablePage = e
|
||||
this.dateProduct()
|
||||
},
|
||||
// 获取销售额排行表格数据
|
||||
async dateProduct() {
|
||||
try {
|
||||
this.saleTableLoading = true
|
||||
const res = await dateProduct(this.saleTableActive, this.saleTablePage)
|
||||
this.saleTable = res.totalProduct
|
||||
this.saleTableTotal = res.productCount
|
||||
this.productCount = res.productCount
|
||||
this.productSum = res.productSum
|
||||
setTimeout(() => {
|
||||
this.saleTableLoading = false
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 支付类型占比 饼图
|
||||
async datePayType() {
|
||||
try {
|
||||
this.payChartLoading = true
|
||||
const res = await datePayType(this.payChartDay)
|
||||
const data = res.countPayType.map(item => {
|
||||
return {
|
||||
value: item.count,
|
||||
name: item.payType
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.payChartLoading = false
|
||||
}, 300);
|
||||
this.initPayChart(data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 汇总数据
|
||||
async summaryGet() {
|
||||
try {
|
||||
const res1 = await summaryGet()
|
||||
const res2 = await summaryTodayGet()
|
||||
this.topData = {
|
||||
...res1,
|
||||
...res2
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.card_wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
|
||||
.card {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 0 20px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
padding-top: 20px;
|
||||
|
||||
.card_title {
|
||||
font-size: 14px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.number {
|
||||
padding: 20px 0 10px 0;
|
||||
font-size: 24px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.row {
|
||||
height: 40px;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.icon {
|
||||
color: rgb(255, 85, 85);
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart_wrap {
|
||||
margin-top: 20px;
|
||||
|
||||
.sale_data {
|
||||
display: flex;
|
||||
|
||||
.card {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 0 20px;
|
||||
|
||||
.sale_data_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
padding-top: 20px;
|
||||
|
||||
.card_title {
|
||||
font-size: 14px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.number {
|
||||
padding-top: 10px;
|
||||
font-size: 24px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #ececec;
|
||||
padding: 0 20px;
|
||||
|
||||
.tab_wrap {
|
||||
display: flex;
|
||||
$color: #1890FF;
|
||||
|
||||
.item {
|
||||
padding: 0 10px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
color: $color;
|
||||
|
||||
&.active {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
border-bottom: 2px solid $color;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
padding: 20px 0;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.table {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -125,9 +125,9 @@
|
||||
<shopList ref="shopList" @success="selectShop" />
|
||||
<el-dialog :visible.sync="showResult" :show-close="false" :close-on-press-escape="false"
|
||||
:close-on-click-modal="false">
|
||||
<el-result icon="success" title="出库提交成功" :subTitle="`共操作${tableData.list.length}件商品`">
|
||||
<el-result icon="success" title="入库提交成功" :subTitle="`共操作${tableData.list.length}件商品`">
|
||||
<template slot="extra">
|
||||
<el-button type="primary" size="medium" @click="resetHandle">创建新的出库单</el-button>
|
||||
<el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button>
|
||||
<router-link to="/invoicing/operating_record">
|
||||
<el-button size="medium">历史提交</el-button>
|
||||
</router-link>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="login" :style="'background-image:url('+ Background +');'">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
|
||||
<div class="login" :style="'background-image:url(' + Background + ');'">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px"
|
||||
class="login-form">
|
||||
<h3 class="title">
|
||||
收银机后台
|
||||
银收客后台管理
|
||||
</h3>
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
|
||||
@@ -10,23 +11,28 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
|
||||
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
|
||||
@keyup.enter.native="handleLogin">
|
||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
|
||||
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
|
||||
</el-input>
|
||||
<div class="login-code">
|
||||
<img :src="codeUrl" @click="getCode">
|
||||
<div class="code_wrap">
|
||||
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%"
|
||||
@keyup.enter.native="handleLogin">
|
||||
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
|
||||
</el-input>
|
||||
<div class="login-code">
|
||||
<img :src="codeUrl" @click="getCode">
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;">
|
||||
记住我
|
||||
</el-checkbox>
|
||||
<el-form-item style="width:100%;">
|
||||
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
|
||||
<el-button :loading="loading" size="medium" type="primary" style="width:100%;"
|
||||
@click.native.prevent="handleLogin">
|
||||
<span v-if="!loading">登 录</span>
|
||||
<span v-else>登 录 中...</span>
|
||||
</el-button>
|
||||
@@ -47,7 +53,7 @@ import Config from '@/settings'
|
||||
import { getCodeImg } from '@/api/login'
|
||||
import Cookies from 'js-cookie'
|
||||
import qs from 'qs'
|
||||
import Background from '@/assets/images/background.webp'
|
||||
import Background from '@/assets/images/background_img.jpg'
|
||||
export default {
|
||||
name: 'Login',
|
||||
data() {
|
||||
@@ -56,8 +62,8 @@ export default {
|
||||
codeUrl: '',
|
||||
cookiePass: '',
|
||||
loginForm: {
|
||||
username: 'admin',
|
||||
password: '123456',
|
||||
username: '',
|
||||
password: '',
|
||||
rememberMe: false,
|
||||
code: '',
|
||||
uuid: ''
|
||||
@@ -73,7 +79,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler: function(route) {
|
||||
handler: function (route) {
|
||||
const data = route.query
|
||||
if (data && data.redirect) {
|
||||
this.redirect = data.redirect
|
||||
@@ -169,47 +175,60 @@ export default {
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
.login {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
}
|
||||
.title {
|
||||
margin: 0 auto 30px auto;
|
||||
text-align: center;
|
||||
color: #707070;
|
||||
.login {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
padding-right: 15%;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0 auto 50px auto;
|
||||
text-align: center;
|
||||
color: #707070;
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
width: 500px;
|
||||
padding: 50px 50px 50px 50px;
|
||||
|
||||
.el-input {
|
||||
height: 38px;
|
||||
|
||||
input {
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
width: 385px;
|
||||
padding: 25px 25px 5px 25px;
|
||||
.el-input {
|
||||
height: 38px;
|
||||
input {
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
.input-icon{
|
||||
height: 39px;width: 14px;margin-left: 2px;
|
||||
}
|
||||
.input-icon {
|
||||
height: 39px;
|
||||
width: 14px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.login-tip {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
.login-code {
|
||||
width: 33%;
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
float: right;
|
||||
img{
|
||||
cursor: pointer;
|
||||
vertical-align:middle
|
||||
}
|
||||
}
|
||||
|
||||
.login-tip {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
.code_wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.login-code {
|
||||
width: 33%;
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
vertical-align: middle
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -78,42 +78,42 @@
|
||||
<el-form-item label="规格属性" v-if="shopTypes[shopTypesActive].typeEnum != 'sku'">
|
||||
<el-table :data="form.skuList" border>
|
||||
<el-table-column label="售价" prop="salePrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.salePrice"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会员价" prop="memberPrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.memberPrice"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价" prop="costPrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.costPrice"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原价" prop="originPrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.originPrice"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存数量" prop="stockNumber">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.stockNumber"></el-input-number>
|
||||
<el-input-number v-model="scope.row.stockNumber" :disabled="!!form.id"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分销金额" prop="firstShared">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.firstShared"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品条码">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.barCode" disabled></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="tips" v-if="form.isShowMall">注:小程序商城必须设置库存数量大于0</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择规格" v-if="shopTypes[shopTypesActive].typeEnum == 'sku'">
|
||||
<el-select v-model="form.specId" placeholder="请选择规格" style="width: 500px;" @change="selectSpecHandle">
|
||||
@@ -141,66 +141,103 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售价" prop="salePrice">
|
||||
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>售价</span>
|
||||
<i class="icon el-icon-edit" @click="showNumberChange(scope.$index)"></i>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('salePrice')"></i>
|
||||
</template>
|
||||
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.salePrice" controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会员价" prop="memberPrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>会员价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('memberPrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.memberPrice"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价" prop="costPrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>成本价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('costPrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.costPrice" controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原价" prop="originPrice">
|
||||
|
||||
<template v-slot="scope">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>原价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('originPrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.originPrice"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存数量" prop="stockNumber">
|
||||
|
||||
<template v-slot="scope">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>库存数量</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('stockNumber')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.stockNumber"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分销金额" prop="firstShared">
|
||||
|
||||
<template v-slot="scope">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>分销金额</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('firstShared')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.firstShared"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品条码">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.barCode" disabled></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="form.skuList.splice(scope.$index, 1)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="tips" v-if="form.isShowMall">注:小程序商城必须设置库存数量大于0</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="上架区域">
|
||||
<div class="shop_type_box">
|
||||
<div class="item" :class="{ active: form.isShowCash }" @click="areaChange('isShowCash')">
|
||||
<div class="s_title">收银台</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" :class="{ active: form.isShowMall }" @click="areaChange('isShowMall')">
|
||||
<div class="s_title">小程序商城</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="库存开关">
|
||||
<el-switch v-model="form.isStock" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips">注:关闭则不计算出入库数据</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签打印">
|
||||
<el-switch v-model="form.enableLabel" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips">开启后: 收银完成后会自动打印对应数量的标签数</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="打包费">
|
||||
<el-input-number v-model="form.packFee" controls-position="right" :min="0"></el-input-number>
|
||||
<div class="tips">单份商品打包费。注:店铺开启外卖模式下该数据才生效</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="虚拟销量">
|
||||
<el-input-number v-model="form.baseSalesNumber" controls-position="right" :min="0"></el-input-number>
|
||||
@@ -210,9 +247,21 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" v-loading="loading" @click="submitHandle">确定</el-button>
|
||||
<el-button>取消</el-button>
|
||||
<el-button @click="$router.back()">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog title="批量修改" width="400px" :visible.sync="showBatchModal">
|
||||
<el-form :model="batchNumberForm">
|
||||
<el-form-item>
|
||||
<el-input-number v-model="batchNumberForm.batchNumber" :min="0" controls-position="right"
|
||||
style="width: 100%;"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="showBatchModal = false">取 消</el-button>
|
||||
<el-button type="primary" @click="batchNumberFormConfirm">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -223,6 +272,9 @@ import addClassify from './components/addClassify'
|
||||
import shopList from '@/components/shopList'
|
||||
import uploadImg from '@/components/uploadImg'
|
||||
import settings from '@/settings'
|
||||
import dayjs from 'dayjs'
|
||||
import { RandomNumBoth } from "@/utils";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
addUnit,
|
||||
@@ -234,32 +286,6 @@ export default {
|
||||
return {
|
||||
shopTypesActive: 0,
|
||||
shopTypes: settings.typeEnum,
|
||||
skuList: [
|
||||
{
|
||||
label: '售价',
|
||||
value: 'salePrice'
|
||||
},
|
||||
{
|
||||
label: '会员价',
|
||||
value: 'memberPrice'
|
||||
},
|
||||
{
|
||||
label: '成本价',
|
||||
value: 'costPrice'
|
||||
},
|
||||
{
|
||||
label: '原价',
|
||||
value: 'originPrice'
|
||||
},
|
||||
{
|
||||
label: '库存数量',
|
||||
value: 'stockNumber'
|
||||
},
|
||||
{
|
||||
label: '一级分销金额',
|
||||
value: 'firstShared'
|
||||
}
|
||||
],
|
||||
specTableHeaders: [],
|
||||
specTableBodys: [],
|
||||
specId: '',
|
||||
@@ -272,7 +298,8 @@ export default {
|
||||
costPrice: 0,
|
||||
originPrice: 0,
|
||||
stockNumber: 0,
|
||||
firstShared: 0
|
||||
firstShared: 0,
|
||||
barCode: `${localStorage.getItem('shopId')}${dayjs().valueOf()}`
|
||||
},
|
||||
tableAddShopIndex: null,
|
||||
isEditor: false,
|
||||
@@ -289,7 +316,8 @@ export default {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
lowPrice: '',
|
||||
skuList: [],
|
||||
isStock: 0,
|
||||
isShowMall: 1,
|
||||
isShowCash: 1,
|
||||
isStock: 0,
|
||||
packFee: 0,
|
||||
specId: '',
|
||||
@@ -323,7 +351,13 @@ export default {
|
||||
]
|
||||
},
|
||||
units: [],
|
||||
categorys: []
|
||||
categorys: [],
|
||||
// 批量修改规格
|
||||
showBatchModal: false,
|
||||
batchNumberKey: '',
|
||||
batchNumberForm: {
|
||||
batchNumber: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -336,11 +370,29 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 修改商家区域
|
||||
areaChange(key) {
|
||||
if (this.form[key] == 1) {
|
||||
this.form[key] = 0
|
||||
} else {
|
||||
this.form[key] = 1
|
||||
}
|
||||
},
|
||||
selectUnitt(e) {
|
||||
this.form.unitName = this.units.find(item => item.id == e).name
|
||||
},
|
||||
showNumberChange(index) {
|
||||
console.log(index)
|
||||
// 批量修改规格
|
||||
batchNumber(key) {
|
||||
this.batchNumberKey = key
|
||||
this.showBatchModal = true
|
||||
},
|
||||
// 确认批量修改规格
|
||||
batchNumberFormConfirm() {
|
||||
this.form.skuList.map(item => {
|
||||
item[this.batchNumberKey] = this.batchNumberForm.batchNumber
|
||||
})
|
||||
this.showBatchModal = false
|
||||
this.batchNumberForm.batchNumber = 0
|
||||
},
|
||||
// 商品详情
|
||||
async tbProductGetDetail() {
|
||||
@@ -494,7 +546,8 @@ export default {
|
||||
newarr.push({
|
||||
specSnap: specSnap.join(','),
|
||||
...m,
|
||||
...obj
|
||||
...obj,
|
||||
barCode: `${dayjs().valueOf()}${RandomNumBoth(1, 9999)}`
|
||||
})
|
||||
} else {
|
||||
let specSnap = []
|
||||
@@ -504,7 +557,8 @@ export default {
|
||||
newarr.push({
|
||||
specSnap: specSnap.join(','),
|
||||
...m,
|
||||
...item
|
||||
...item,
|
||||
barCode: `${dayjs().valueOf()}${RandomNumBoth(1, 9999)}`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
class="filter-item" @keyup.enter.native="getTableData" />
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-cascader :options="categorys" v-model="query.categoryId" :show-all-levels="false"
|
||||
:props="{ value: 'id', label: 'name', children: 'childrenList', expandTrigger: 'hover', emitPath: false }"
|
||||
clearable placeholder="请选择商品分类"></el-cascader>
|
||||
<el-select v-model="query.categoryId" placeholder="请选择商品分类" style="width: 100%;">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in categorys" :key="item.id" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-select v-model="query.typeEnum" placeholder="请选择商品规格" style="width: 100%;">
|
||||
@@ -55,10 +55,16 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="销量/库存">
|
||||
<template v-slot="scope">
|
||||
<span>{{ scope.row.xl }}/{{ scope.row.kc }}</span>
|
||||
<span>{{ scope.row.realSalesNumber }}/{{ scope.row.stockNumber }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架区域">
|
||||
<template v-slot="scope">
|
||||
<div v-if="scope.row.isShowCash">收银端</div>
|
||||
<div v-if="scope.row.isShowMall">小程序</div>
|
||||
<div v-if="!scope.row.isShowCash && !scope.row.isShowMall">未上架</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架区域" prop="area" />
|
||||
<el-table-column label="排序" prop="sort" sortable />
|
||||
<el-table-column label="更新时间" prop="createdAt">
|
||||
<template v-slot="scope">
|
||||
|
||||
Reference in New Issue
Block a user