This commit is contained in:
YeMingfei666 2024-10-17 13:41:50 +08:00
commit c224469c35
49 changed files with 2460 additions and 519 deletions

View File

@ -131,4 +131,13 @@ export default {
}
}
}
.image-slot {
width: 100%;
height: 100%;
background-color: #efefef;
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@ -38,20 +38,11 @@ export function puttbConsType(data) {
* 查询耗材信息
* @returns
*/
export function gettbConsInfo(params) {
// return request({
// url: '/api/tbConsInfo',
// method: "get",
// params
// });
export function gettbConsInfo(data) {
return request({
url: "/api/tbConsInfo",
method: "get",
params:{
...params,
shopId: localStorage.getItem("shopId"),
status:1
}
url: "/api/tbConsInfo/allAndPro",
method: "post",
data
});
}
@ -167,27 +158,15 @@ export function deletetbProskuCon(data) {
* 查询耗材流水信息
* @returns
*/
export function gettbConsInfoFlow(params) {
export function gettbConsInfoFlow(data) {
return request({
url: "/api/tbConsInfoFlow",
method: "get",
params
});
}
/**
* 分组查询获取耗材流水信息
*/
export function viewConInfoFlow(data) {
return request({
url: "/api/viewConInfoFlow",
method: "get",
params: {
shopId: localStorage.getItem("shopId"),
...data
}
url: "/api/viewConInfoFlow/get",
method: "post",
data
});
}
/**
* 查询耗材单位列表
*/
@ -240,3 +219,23 @@ export function tbProskuConV2(data) {
data
});
}
/**
* 耗材库存统计
*/
export function tbConsInfoFlowcount(data) {
return request({
url: "/api/tbConsInfoFlow/count",
method: "post",
data
});
}
/**
* 耗材库存记录列表
*/
export function tbConsInfoFlowstock(data) {
return request({
url: "/api/tbConsInfoFlow/stock",
method: "post",
data
});
}

View File

@ -1,7 +1,7 @@
import request from '@/utils/request'
/**
* 增加打印机
* @returns
*/
export function tbPrintMachine(data, method = 'post') {
@ -14,19 +14,58 @@ export function tbPrintMachine(data, method = 'post') {
}
})
}
// 打印机切换
export function switchtbPrintMachine(data, method = 'post') {
return request({
url: '/api/shop-config/printer/update-status',
method: method,
data: {
shopId: localStorage.getItem('shopId'),
...data
}
})
}
// 打印机部分
export function tbShopCategory(params) {
return request({
url: '/api/tbShopCategory',
method: 'get',
params
})
}
/**
* 打印机列表
* @returns
*/
export function tbPrintMachineGet(params) {
return request({
url: '/api/tbPrintMachine',
url: '/api/shop-config/printer/list',
method: 'get',
params: {
shopId: localStorage.getItem('shopId'),
sort: '',
...params
}
})
}
}
// 删除
export function delTableHandle(id) {
return request({
url: '/api/shop-config/printer/' + id,
method: 'DELETE',
})
}
// * 打印机详情
export function printerd(id) {
return request({
url: '/api/shop-config/printer/' + id,
method: 'get',
})
}
// 编辑 新增打印机
export function configprinter(data, method = "post") {
return request({
url: `/api/shop-config/printer`,
method: method,
data
});
}

View File

@ -64,7 +64,8 @@ export function dateAmount(day) {
*/
export function dateProduct(day, page, size) {
return request({
url: "/api/summary/dateProduct",
// url: "/api/summary/dateProduct",
url: "/api/summary/productSaleDate",
method: "get",
params: {
shopId: localStorage.getItem("shopId"),

View File

@ -40,3 +40,12 @@ export function delmsg(ids) {
data: ids
})
}
//获取订阅二维码
export function subQrCode(params) {
return request({
url: '/api/msg/subQrCode',
method: 'get',
params
})
}

View File

@ -573,7 +573,6 @@ export function tbPlussShopStaff(data) {
});
}
export function tbShopPermissionlist(params) {
return request({
url: `/api/tbShopPermission/list`,
@ -582,7 +581,13 @@ export function tbShopPermissionlist(params) {
});
}
export function getHasPermission(params) {
return request({
url: `/api/tbShopPermission/hasPermission`,
method: "get",
params
});
}
/**
* 通过id获取员工信息
@ -615,11 +620,11 @@ export function callRecord(params) {
});
}
export function callTablecall(data) {
return request({
url: `/callTable/call`,
method: 'post',
data
});
return request({
url: `/callTable/call`,
method: "post",
data
});
}
// 删除桌型
export function callTabledelete(data) {
@ -739,11 +744,11 @@ export function queryShopUserFlow(params) {
}
// 商品列表 V2
export function tbProductListV2(params) {
export function tbProductListV2(data) {
return request({
url: `/api/tbProduct/list/v2`,
method: "get",
params
method: "post",
data
});
}
@ -755,3 +760,30 @@ export function updateProductData(data) {
data
});
}
// 商品库存统计列表 统计
export function tbProductStockDetailStockCount(data) {
return request({
url: `/api/tbProductStockDetail/stock/count`,
method: "post",
data
});
}
// 商品库存记录列表
export function tbProductStockDetailStock(data) {
return request({
url: `/api/tbProductStockDetail/stock`,
method: "post",
data
});
}
// 商品库存记录列表
export function stockWarnLine(data) {
return request({
url: `/api/stock/warnLine`,
method: "PUT",
data
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -37,7 +37,7 @@ export default {
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: '首页' }}].concat(matched)
matched = [{ path: '/data_statistics', meta: { title: '首页' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)

View File

@ -110,6 +110,8 @@ import { mapState, mapGetters } from 'vuex'
import Theme from '@/components/ThemePicker'
import Cookies from 'js-cookie'
import Avatar from '@/assets/images/avatar.png'
import { updatePass } from '@/api/login.js'
import { encrypt } from '@/utils/rsaEncrypt'
export default {
name: 'Layout',
components: {
@ -213,6 +215,14 @@ export default {
}
},
methods: {
//
changeInputType(key) {
if (this[key] == 'text') {
this[key] = 'password'
} else {
this[key] = 'text'
}
},
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
},

View File

@ -51,7 +51,7 @@ export const constantRouterMap = [
path: 'data_forms',
component: (resolve) => require(['@/views/home/data_forms'], resolve),
name: 'data_forms',
meta: { title: '数据报表' }
meta: { title: '销量统计' }
},
{
path: 'data_tables',

View File

@ -2,7 +2,7 @@ module.exports = {
/**
* @description 网站标题
*/
title: '管理后台',
title: "管理后台",
/**
* @description 是否显示 tagsView
*/
@ -22,7 +22,7 @@ module.exports = {
/**
* @description token key
*/
TokenKey: 'ELADMIN-TOEKN',
TokenKey: "ELADMIN-TOEKN",
/**
* @description 请求超时时间毫秒默认2分钟
*/
@ -38,36 +38,37 @@ module.exports = {
/**
* 底部文字支持html语法
*/
footerTxt: '© 2018-2024 超掌柜科技 <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>',
footerTxt:
'© 2018-2024 超掌柜科技 <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>',
/**
* 备案号
*/
caseNumber: '陕ICP备2022008069号',
caseNumber: "陕ICP备2022008069号",
typeEnum: [
{
label: '计量商品',
intro: '单价购买',
typeEnum: 'normal'
label: "单规格",
intro: "单价购买",
typeEnum: "normal"
},
{
label: '多规格',
intro: '多种不同规格',
typeEnum: 'sku'
},
{
label: '套餐商品',
intro: '选职多种组合',
typeEnum: 'group'
},
{
label: '称重商品',
intro: '按重量售卖',
typeEnum: 'weight'
},
{
label: '时价商品',
intro: '收银端可更改价格',
typeEnum: 'currentPrice'
label: "多规格",
intro: "多种不同规格",
typeEnum: "sku"
}
// {
// label: '套餐商品',
// intro: '选职多种组合',
// typeEnum: 'group'
// },
// {
// label: '称重商品',
// intro: '按重量售卖',
// typeEnum: 'weight'
// },
// {
// label: '时价商品',
// intro: '收银端可更改价格',
// typeEnum: 'currentPrice'
// }
]
}
};

View File

@ -42,6 +42,7 @@ const user = {
localStorage.setItem("shopName", res.shopName);
localStorage.setItem("logo", res.logo);
localStorage.setItem("loginType", res.loginType);
localStorage.setItem("userInfo", JSON.stringify(res.user.user));
setToken(res.token, rememberMe);
commit("SET_TOKEN", res.token);
setUserInfo(res.user, commit);

153
src/utils/limits.js Normal file
View File

@ -0,0 +1,153 @@
import { getHasPermission } from "@/api/shop";
import { Notification } from 'element-ui'
const userInfo = JSON.parse(localStorage.getItem("userInfo"));
const $PermissionObj = {
data: [{
key: 'yun_xu_cha_kan_jing_ying_shu_ju',
text: '允许查看经营数据'
},
{
key: 'yun_xu_cha_kan_suo_you_jiao_ban_ji_lu',
text: '允许查看所有交班记录'
}
],
default: [{
key: 'yun_xu_xia_dan',
text: '允许下单'
},
{
key: 'yun_xu_shou_kuan',
text: '允许收款'
},
{
key: 'yun_xu_tui_kuan',
text: '允许退款'
},
{
key: 'yun_xu_jiao_ban',
text: '允许交班'
}
],
goods: [{
key: 'yun_xu_xiu_gai_shang_pin',
text: '允许修改商品'
},
{
key: 'yun_xu_shang_xia_jia_shang_pin',
text: '允许上下架商品'
},
{
key: 'yun_xu_xiu_gai_fen_lei',
text: '允许修改分类'
},
{
key: 'yun_xu_xiu_gai_fen_zu',
text: '允许修改分组'
}
],
discount:[
{
key: 'yun_xu_da_zhe',
text: '允许打折'
}
],
vip:[
{
key: 'yun_xu_guan_li_hui_yuan_xin_xi',
text: '允许管理会员信息'
},
{
key: 'yun_xu_xiu_gai_hui_yuan_yu_e',
text: '允许修改会员余额'
}
],
stock:[
{
text: '允许提交报损',
key: 'yun_xu_ti_jiao_bao_sun'
},
{
text: '允许沽清',
key: 'yun_xu_gu_qing'
},
{
text: '允许售罄商品',
key: 'yun_xu_shou_qing_shang_pin'
},
{
text:'允许修改商品库存',
key:'yun_xu_xiu_gai_shang_pin_ku_cun'
},
{
text: '允许耗材入库',
key: 'yun_xu_hao_cai_ru_ku'
},
{
text: '允许耗材出库',
key: 'yun_xu_hao_cai_chu_ku'
},
{
text: '允许耗材盘点',
key: 'yun_xu_hao_cai_pan_dian'
}
]
}
export async function hasPermission (params) {
//如果是商户默认拥有全部权限
const loginType = localStorage.getItem('loginType')
if(loginType=='merchant'){
return true
}
params = returnFormatParams(params)
if (!params) {
return infoBox.showToast('未找到相关权限请检查代码或在权限配置文件commons/utils/hasPermission.js文件进行修改或增加')
}
const option = Object.assign({
tips: true,
key: '',
text: ''
}, params)
const res = await getHasPermission({
userId : userInfo.id,
code: params.key
})
if (!res && option.tips) {
Notification.error({
title: '您没有' + params.text + '权限!',
duration: 5000
})
}
return res
}
export function isObjectButNotArray(value) {
return typeof value === 'object' && Array.isArray(value) === false;
}
export function findPermissionObj(str) {
for (let i in $PermissionObj) {
const obj = $PermissionObj[i].find(v => v.key == str || v.text == str)
if (obj) {
return obj
break
}
}
console.error('未找到相关权限配置请检查权限配置文件commons/utils/hasPermission.js文件进行修改或增加')
return false
}
export function returnFormatParams(params) {
if (typeof params === 'string') {
return findPermissionObj(params)
} else {
if (isObjectButNotArray(params)) {
const obj=findPermissionObj(params.key || params.text)
return {...params,...obj}
} else {
console.error('参数只能是字符串或者对象,不能是数组')
}
}
}

View File

@ -0,0 +1,210 @@
<template>
<div class="app-container">
<el-form :model="forms">
<el-form-item label="打印机品牌">
<el-select v-model="forms.contentType" placeholder="请选择打印机品牌">
<el-option label="云想印" value="yxyPrinter"></el-option>
<el-option label="飞鹅" value="fePrinter"></el-option>
<!-- <el-option label="本地" value="local"></el-option> -->
<!-- <el-option label="USB" value="printer"></el-option> -->
</el-select>
</el-form-item>
<el-form-item label="小票打印">
<el-select v-model="forms.subType" placeholder="请选择小票打印">
<el-option label="标签" value="label"></el-option>
<el-option label="出品" value="kitchen"></el-option>
<el-option label="小票" value="cash"></el-option>
</el-select>
</el-form-item>
<el-form-item label="打印机名称">
<el-input v-model="forms.name" style="width: 280px;" placeholder="请输入打印机名称"></el-input>
</el-form-item>
<!-- <template v-if="forms.contentType == 'network'"> -->
<el-form-item label="打印机编号">
<el-input v-model="forms.address" style="width: 280px;" placeholder="请输入打印机编号"></el-input>
</el-form-item>
<el-form-item label="打印机秘钥">
<el-input v-model="forms.port" style="width: 280px;" placeholder="请输入打印机秘钥"></el-input><br />
<div style="margin-left: 80px;color: #FF4D4F;">* 可在打印机设备底部查看打印机编号和秘钥(key)</div>
</el-form-item>
<!-- </template> -->
<!-- <template v-if="forms.contentType == 'local'"> <el-form-item label="IP地址">
<el-input v-model="forms.address" style="width: 280px;" placeholder="请输入打印机编号"></el-input>
</el-form-item>
<el-form-item label="端口">
<el-input v-model="forms.port" style="width: 280px;" placeholder="请输入打印机秘钥"></el-input><br />
<div style="margin-left: 80px;color: #FF4D4F;">* 可在打印机设备底部查看打印机编号和秘钥(key)</div>
</el-form-item>
</template> -->
<el-form-item label="小票尺寸">
<el-radio-group v-model="forms.receiptSize">
<el-radio label="58mm"></el-radio>
<el-radio label="80mm"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="分类打印">
<el-radio-group v-model="forms.classifyPrint">
<el-radio label="0">打印所有</el-radio>
<el-radio label="1">部分分类</el-radio>
<!-- <el-radio label="2">部分商品</el-radio> -->
</el-radio-group>
<div v-if="forms.classifyPrint == 1" style="margin-left:70px">
<!-- <el-tree :data="partList" show-checkbox node-key="id" ref="tree" :default-checked-keys="this.forms.categoryIds"
:props="{ children: 'childrenList', label: 'name' }">
</el-tree> -->
<el-checkbox-group v-model="forms.selectcheckbox">
<el-checkbox v-for="item in partList" :key="item.id" :label="item.name"></el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<!-- <el-form-item label="桌台打印">
<el-radio-group v-model="forms.tablePrint">
<el-radio label="0">打印所有</el-radio>
<el-radio label="1">打印部分桌台</el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="打印数量">
<el-radio-group v-model="forms.printQty">
<el-radio label="c1m1^2">顾客联+商家联2</el-radio>
<el-radio label="m1^1">只打印商家联1</el-radio>
<el-radio label="c1^1">只打印顾客联1</el-radio>
<el-radio label="c2m1^3">2张顾客联+1张商家联3</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="打印方式">
<el-radio-group v-model="forms.printMethod">
<el-radio label="all">打印全部</el-radio>
<el-radio label="normal">仅打印结账单[前台]</el-radio>
<el-radio label="one">仅打印制作单[厨房]</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="打印类型">
<el-checkbox-group v-model="forms.printType">
<el-checkbox label="refund">确认退款单</el-checkbox>
<el-checkbox label="handover">交班单</el-checkbox>
<el-checkbox label="queue">排队取号</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- <el-form-item label="打印单据">
<el-radio-group v-model="forms.printReceipt">
<el-radio label="0">全部打印</el-radio>
<el-radio label="1">仅厨房</el-radio>
<el-radio label="2">仅前台</el-radio>
</el-radio-group>
<div style="margin-left: 80px;color: #FF4D4F;">如果你的店只使用一台小票机建议选择全部打印</div>
</el-form-item> -->
<el-form-item label="打印机状态">
<el-switch v-model="forms.status" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item label-width="80px">
<el-button type="primary" @click="$router.go(-1)">返回</el-button>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { configprinter, printerd, tbShopCategory } from '@/api/devices'
export default {
components: {
},
data() {
return {
forms: {
sort: "0",
status: "0",
connectionType: "network", printType: [],
selectcheckbox: []
},
partList: []
}
},
filters: {
},
mounted() {
this.getpartList()
},
methods: {
async onSubmit() {
//
if (this.$route.query.id) {
delete this.forms.createdAt
delete this.forms.updatedAt
}
//
if (this.forms.classifyPrint == 1) {
let idstr = ''
let arr = []
this.forms.selectcheckbox.forEach(element => {
let prts = this.partList.filter(ele => ele.name == element)[0]
idstr = idstr + prts.id + ','
arr.push(prts)
})
this.forms.categoryIds = idstr.substring(0, idstr.length - 1)
this.forms.categoryList = JSON.stringify(arr)
}
const res = await configprinter({
shopId: localStorage.getItem('shopId'),
...this.forms,
},
this.$route.query.id ? 'put' : 'post'
)
this.$router.go(-1)
},
async getpartList() {
const res = await tbShopCategory({
shopId: localStorage.getItem('shopId'),
sort: "sort,desc",
page: 0,
size: 500
})
let arr = []
res.content.forEach(ele => {
arr.push({
id: ele.id,
name: ele.name
})
if (ele.childrenList.length > 0) {
ele.childrenList.forEach(element => {
arr.push({
id: element.id,
name: element.name
})
})
}
})
this.partList = arr
if (this.$route.query.id) {
this.getList(this.$route.query.id)
}
},
async getList(id) {
const res = await printerd(id)
this.forms = res
if (res.categoryIds) {
let ids = res.categoryIds.split(',')
let arr = []
ids.forEach(element => {
let prts = this.partList.filter(ele => ele.id == element)[0]
arr.push(prts.name)
})
this.$set(this.forms, 'selectcheckbox', arr)
} else {
this.$set(this.forms, 'selectcheckbox', [])
}
if (res.printType) {
this.forms.printType = JSON.parse(res.printType)
} else {
this.forms.printType = []
}
}
}
}
</script>

View File

@ -1,15 +1,15 @@
export const devices = [
{
value: 'printer',
value: 'local',
name: '本地'
},
{
value: 'yxyPrinter',
value: 'network',
name: '云想印'
},
{
value: 'fePrinter',
name: '飞鹅'
value: 'USB',
name: 'USB打印机'
}
]

View File

@ -17,7 +17,7 @@
</el-form>
</div>
<div class="head-container">
<el-button type="primary" icon="el-icon-plus" @click="$refs.addDevice.show()">
<el-button type="primary" icon="el-icon-plus" @click="toUrl">
添加云打印机
</el-button>
</div>
@ -30,11 +30,11 @@
{{ scope.row.contentType | devicesName }}
</template>
</el-table-column>
<el-table-column label="出品模式" prop="config.model">
<!-- <el-table-column label="出品模式" prop="config.model">
<template v-slot="scope">
{{ scope.row.config.model | modelsName }}
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="打印类型" prop="subType">
<template v-slot="scope">
{{ scope.row.subType | subTypesName }}
@ -45,7 +45,7 @@
{{ scope.row.createdAt | timeFilter }}
</template>
</el-table-column>
<el-table-column label="排序" sortable prop="sort"></el-table-column>
<!-- <el-table-column label="排序" sortable prop="sort"></el-table-column> -->
<el-table-column label="状态" prop="status">
<template v-slot="scope">
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0"
@ -54,9 +54,8 @@
</el-table-column>
<el-table-column label="操作" width="200">
<template v-slot="scope">
<el-button type="text" icon="el-icon-edit"
@click="$refs.addDevice.show(scope.row)">编辑</el-button>
<el-popconfirm title="确定删除吗?" @confirm="delTableHandle([scope.row.id])">
<el-button v-if="scope.row.connectionType == 'network'" type="text" icon="el-icon-edit" @click="toUrl(scope.row)">编辑</el-button>
<el-popconfirm v-if="scope.row.connectionType == 'network'" title="确定删除吗?" @confirm="delTableHandle([scope.row.id])">
<el-button type="text" icon="el-icon-delete" style="margin-left: 20px !important;"
slot="reference">删除</el-button>
</el-popconfirm>
@ -75,7 +74,7 @@
<script>
import { devices, models, subTypes } from './devices'
import addDevice from './components/addDevice'
import { tbPrintMachineGet, tbPrintMachine } from '@/api/devices'
import { tbPrintMachineGet, switchtbPrintMachine, delTableHandle } from '@/api/devices'
import dayjs from 'dayjs'
export default {
components: {
@ -99,16 +98,20 @@ export default {
},
filters: {
devicesName(value) {
const item=devices.find(item => item.value == value)
return item?item.name:''
if (value == 'yxyPrinter') {
return '云想印'
} else if (value == 'fePrinter') '飞鹅'
// const item=devices.find(item => item.value == value)
// return item?item.name:''
},
modelsName(value) {
const item=models.find(item => item.value == value)
return item?item.name:''
const item = models.find(item => item.value == value)
return item ? item.name : ''
},
subTypesName(value) {
const item=subTypes.find(item => item.value == value)
return item?item.name:''
if (value == "label") return '标签'
else if (value == 'kitchen') return '出品'
else if (value == 'cash') return '小票'
},
timeFilter(s) {
return dayjs(s).format('YYYY-MM-DD HH:mm:ss')
@ -118,13 +121,20 @@ export default {
this.getTableData()
},
methods: {
toUrl(item) {
this.$router.push({ path: '/shop/devices/details', query: { id: item.id } })
},
//
async statusChange(e, row) {
try {
this.tableData.loading = true
const data = { ...row }
data.status = e
await tbPrintMachine(data, 'put')
if (data.id) {
delete data.createdAt
delete data.updatedAt
}
await switchtbPrintMachine(data)
this.getTableData()
} catch (error) {
console.log(error)
@ -142,13 +152,20 @@ export default {
this.tableData.page = e - 1
this.getTableData()
},
//
async delTableHandle(item) {
const res = await delTableHandle(item)
this.getTableData()
},
//
async getTableData() {
this.tableData.loading = true
try {
const res = await tbPrintMachineGet({
name: this.query.name,
contentType: this.query.type
shopId: localStorage.getItem('shopId'),
contentType: this.query.type,
sort: '',
})
this.tableData.loading = false
this.tableData.data = res

View File

@ -1,9 +1,9 @@
<template>
<div class="app-container">
<el-tabs v-model="orderType" @tab-click="getTableData">
<!-- <el-tabs v-model="orderType" @tab-click="getTableData">
<el-tab-pane label="收款" name="1"></el-tab-pane>
<el-tab-pane label="销量" name="2"></el-tab-pane>
</el-tabs>
</el-tabs> -->
<div class="head-container">
<el-form :model="query" inline label-position="left">
<template v-if="orderType == 2">
@ -109,22 +109,22 @@
</el-table-column>
</el-table>
<el-table :data="tableData.data" v-loading="tableData.loading" v-if="orderType == 2">
<el-table-column label="商品名称" prop="productName"></el-table-column>
<el-table-column label="商品分类" prop="cateName"></el-table-column>
<!-- <el-table-column label="商品分类" prop="cateName"></el-table-column>
<el-table-column label="商品描述" prop="productSkuName"></el-table-column>
<el-table-column label="单价" prop="price"></el-table-column>
<el-table-column label="单价" prop="price"></el-table-column> -->
<el-table-column label="商品名称" prop="name"></el-table-column>
<el-table-column label="销量" prop="salesNum"></el-table-column>
<el-table-column label="退单量" prop="refNum"></el-table-column>
<el-table-column label="销售金额" prop="salesAmount">
<template v-slot="scope">
{{ scope.row.salesAmount }}
</template>
</el-table-column>
<el-table-column label="退款金额" prop="refAmount">
<template v-slot="scope">
{{ scope.row.refAmount }}
</template>
</el-table-column>
<el-table-column label="销售金额" prop="salesAmount">
<template v-slot="scope">
{{ scope.row.salesAmount }}
</template>
</el-table-column>
</el-table>
</div>
<div class="head-container">
@ -146,7 +146,7 @@ export default {
return {
timeValue: "",
resetQuery: null,
orderType: "1",
orderType: "2",
categorys: [],
query: {
createdAt: [],
@ -169,7 +169,7 @@ export default {
timeFilter(time) {
return dayjs(time).format("YYYY-MM-DD HH:mm:ss");
},
totalfilter(item,d) {
totalfilter(item, d) {
let num = item + d
return num.toFixed(2)
}
@ -362,9 +362,27 @@ export default {
.collect_wrap {
display: flex;
gap: 14px;
justify-content: space-between;
.item:nth-child(1) {
background-image: url(../../assets/images/home/data_forms4.png);
}
.item:nth-child(2) {
background-image: url(../../assets/images/home/data_forms3.png);
}
.item:nth-child(3) {
background-image: url(../../assets/images/home/data_forms2.png);
}
.item:nth-child(4) {
background-image: url(../../assets/images/home/data_forms1.png);
}
.item {
flex: 1;
background-size: 100% 100%;
width: 255px;
display: flex;
align-items: center;
background-color: #f5f5f5;

View File

@ -31,11 +31,11 @@
<el-table-column label="职员名称" prop="staffName"></el-table-column>
<el-table-column label="订单数量" prop="orderNum"></el-table-column>
<el-table-column label="应交金额" prop="payable"></el-table-column>
<el-table-column label="上交金额" prop="handIn"></el-table-column>
<!-- <el-table-column label="上交金额" prop="handIn"></el-table-column> -->
<el-table-column label="快捷收款金额" prop="quickAmount"></el-table-column>
<el-table-column label="退款金额" prop="returnAmount"></el-table-column>
<el-table-column label="总收入" prop="totalAmount"></el-table-column>
<el-table-column label="备用金" prop="imprest"></el-table-column>
<!-- <el-table-column label="备用金" prop="imprest"></el-table-column> -->
<el-table-column label="开始时间" prop="startTime">
<template v-slot="scope">
<div>
@ -75,6 +75,7 @@
<script>
import { tbHandoverGet } from '@/api/homes/record.js'
import { hasPermission } from '@/utils/limits.js'
import XLSX from 'xlsx';
import dayjs from "dayjs";
export default {
@ -147,6 +148,8 @@ export default {
this.getTableData();
},
async getTableData() {
let res = await hasPermission('允许查看所有交班记录');
if ( !res) { return; }
this.tableData.loading = true;
try {
let urlData = null

View File

@ -72,7 +72,20 @@
<div class="item earnings">
<div class="num_wrap">
<div class="num">{{ formatDecimal(tradeSale.incomeAmountAll || 0) }}</div>
<div class="tips">营业实收<el-icon class="el-icon-question" /></div>
<div class="tips">营业实收
<el-tooltip popper-class="popper" effect="light" placement="bottom">
<div class="tips_row" slot="content">
<div class="item" v-for="(item, index) in tradeSale.payCount" :key="index">
<div class="left">
<img class="icon" :src="item.icon">
<span>{{ item.payType }}</span>
</div>
<span class="num">{{ item.payAmount }}</span>
</div>
</div>
<el-icon class="el-icon-question" />
</el-tooltip>
</div>
</div>
<div class="line_wrap">
<div class="line_item">
@ -82,9 +95,11 @@
</div>
<div class="line_gropress">
<div class="gropress l"
:style="{ width: `${tradeSale.incomeAmount / tradeSale.totalSaleAmount * 100}%` }"></div>
:style="{ width: `${tradeSale.incomeAmount ? (tradeSale.incomeAmount / tradeSale.totalSaleAmount * 100) : 0}%` }">
</div>
<div class="gropress r"
:style="{ width: `${tradeSale.refundAmount / tradeSale.totalSaleAmount * 100}%` }"></div>
:style="{ width: `${tradeSale.refundAmount ? (tradeSale.refundAmount / tradeSale.totalSaleAmount * 100) : 0}%` }">
</div>
</div>
<div class="line_btm">
<el-icon class="icon el-icon-caret-right" />
@ -100,10 +115,12 @@
<div class="t">{{ formatDecimal(tradeSale.totalVipAmount || 0) }}</div>
</div>
<div class="line_gropress">
<div class="gropress l" :style="{ width: `${tradeSale.inAmount / tradeSale.totalVipAmount * 100}%` }">
<div class="gropress l"
:style="{ width: `${tradeSale.inAmount ? (tradeSale.inAmount / tradeSale.totalVipAmount * 100) : 0}%` }">
</div>
<div class="gropress r"
:style="{ width: `${tradeSale.outAmount / tradeSale.totalVipAmount * 100}%` }"></div>
:style="{ width: `${tradeSale.inAmount ? (tradeSale.outAmount / tradeSale.totalVipAmount * 100) : 0}%` }">
</div>
</div>
<div class="line_btm">
<el-icon class="icon el-icon-caret-right" />
@ -119,7 +136,7 @@
<div class="data_item">
<div class="num_wrap">
<div class="num">{{ formatDecimal(tradeVip.useAmount || 0) }}</div>
<div class="tips">会员消费<el-icon class="el-icon-question" /></div>
<div class="tips">会员消费</div>
</div>
</div>
<div class="data_item_right">
@ -137,7 +154,11 @@
</div>
</div>
<div class="item item2">
<div class="title">翻台率 <el-icon class="icon el-icon-question" /> </div>
<div class="title">翻台率
<el-tooltip effect="dark" content="翻台率=(客单数-桌台数)/桌台数*100%" placement="top">
<el-icon class="icon el-icon-question" />
</el-tooltip>
</div>
<div class="icon_wrap">
<img class="img" src="@/assets/images/data_home_item2_icon.png" />
<div class="t">{{ tradeCount.turnoverRate }}</div>
@ -186,7 +207,7 @@
<div class="item active">商品销售排行</div>
</div>
<el-radio-group v-model="saleTableActive" @change="rankChange">
<el-radio-button label="1">今天</el-radio-button>
<!-- <el-radio-button label="1">今天</el-radio-button> -->
<el-radio-button label="7">近7天</el-radio-button>
<el-radio-button label="30">30</el-radio-button>
</el-radio-group>
@ -209,13 +230,13 @@
</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="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-column label="数量" prop="salesNum"></el-table-column>
<el-table-column label="金额" prop="salesAmount"></el-table-column>
</el-table>
<div class="head-container" style="padding-top: 20px;display: flex;justify-content: flex-end;">
<el-pagination :total="saleTableTotal" :page-size="saleTableSize" :current-page="saleTablePage"
<el-pagination :total="saleTableTotal" :page-size="saleTableSize" :current-page="saleTablePage + 1"
@current-change="paginationChange" layout="total, prev, pager, next, jumper"></el-pagination>
</div>
</div>
@ -270,10 +291,10 @@ export default {
chartType: 1,
productCount: 0,
productSum: 0,
saleTableActive: "1",
saleTableActive: "7",
saleTable: [],
saleTableLoading: false,
saleTablePage: 1,
saleTablePage: 0,
saleTableTotal: 0,
saleTableSize: 5,
__resizeHandler: null,
@ -285,7 +306,9 @@ export default {
createdAt: '',
},
tradeLoading: false,
tradeSale: '',
tradeSale: {
payCount: []
},
tradeVip: '',
tradeCount: '',
};
@ -294,7 +317,7 @@ export default {
// this.summaryGet();
this.dateAmount();
this.dateProduct();
this.summaryDateGet();
// this.summaryDateGet();
this.timeChange('0')
this.__resizeHandler = debounce(() => {
@ -635,7 +658,7 @@ export default {
}
}
],
color: "#409eff",
color: ["#409eff", "#FFC83A", "#F98B26"],
yAxis: [
{
type: "value",
@ -654,9 +677,22 @@ export default {
],
series: [
{
data: data,
name: '订单金额',
type: "bar",
barWidth: time.length <= 7 ? "50%" : "30%"
barWidth: time.length <= 7 ? "30%" : "20%",
data: data.map(item => item.orderAmount),
},
{
name: '实收金额',
type: "bar",
barWidth: time.length <= 7 ? "30%" : "20%",
data: data.map(item => item.actualAmount),
},
{
name: '优惠金额',
type: "bar",
barWidth: time.length <= 7 ? "30%" : "20%",
data: data.map(item => item.discountAmount),
}
]
});
@ -666,7 +702,10 @@ export default {
this.payChart = echarts.init(this.$refs.payChart);
this.payChart.setOption({
tooltip: {
trigger: "item"
trigger: "item",
formatter: params => {
return `${params.name}${params.value}`
}
},
legend: {
top: "5%",
@ -711,7 +750,13 @@ export default {
try {
this.saleLoading = true;
const res = await dateAmount(this.saleActive);
const data = res.total.map(item => item.amount);
const data = res.total.map(item => {
return {
orderAmount: item.orderAmount,
actualAmount: item.actualAmount,
discountAmount: item.discountAmount
}
});
const time = res.total.map(item => item.tradeDay);
this.initSaleChart(time, data);
setTimeout(() => {
@ -722,7 +767,7 @@ export default {
}
},
paginationChange(e) {
this.saleTablePage = e;
this.saleTablePage = e - 1;
this.dateProduct();
},
//
@ -734,10 +779,12 @@ export default {
this.saleTablePage,
this.saleTableSize
);
this.saleTable = res.totalProduct;
this.saleTableTotal = res.total;
this.productCount = res.productCount;
this.productSum = res.productSum;
this.saleTable = res.productList.content;
this.saleTableTotal = res.productList.totalElements;
this.productCount = res.productCount.payAmount;
this.productSum = res.productSum.payAmount;
this.summaryDateGet(res.countList)
setTimeout(() => {
this.saleTableLoading = false;
}, 300);
@ -788,7 +835,7 @@ export default {
},
rankChange() {
this.dateProduct();
this.summaryDateGet();
// this.summaryDateGet();
},
//
initProduceChart(p1, p2) {
@ -938,17 +985,23 @@ export default {
});
},
//
async summaryDateGet() {
async summaryDateGet(res) {
try {
const res = await summaryDateGet(this.saleTableActive);
console.log(res);
// const res = await summaryDateGet(this.saleTableActive);
let p1 = [
res.numList.map(item => item.tradeDay),
res.numList.map(item => item.count)
res.map(item => item.tradeDay),
res.map(item => item.saleNum)
];
let p2 = [
res.amountList.map(item => item.tradeDay),
res.amountList.map(item => item.count)
res.map(item => item.tradeDay),
res.map(item => item.saleAmount)
];
console.log(p1);
console.log(p2);
this.initProduceChart(p1, p2);
} catch (error) {
console.log(error);
@ -958,7 +1011,43 @@ export default {
};
</script>
<style>
.popper {
border: 1px solid #D9D9D9 !important;
}
</style>
<style scoped lang="scss">
.tips_row {
width: 300px;
padding: 0 10px;
.item {
height: 40px;
display: flex;
align-items: center;
color: #666;
justify-content: space-between;
&:not(:last-child) {
border-bottom: 1px solid #D9D9D9;
}
.left {
display: flex;
align-items: center;
.icon {
font-size: 20px;
margin-right: 10px;
}
}
.num {
color: #1890ff;
}
}
}
.app-container {
padding: 20px;
background-color: #f5f5f5;

View File

@ -68,6 +68,8 @@
<script>
import { formatDecimal } from '@/utils'
import { tbConCheck, tbConCheckGet } from '@/api/invoicing'
import { hasPermission } from '@/utils/limits.js'
export default {
data() {
return {
@ -149,7 +151,9 @@ export default {
}
})
},
show(obj) {
async show(obj) {
let res = await hasPermission('允许耗材盘点');
if ( !res) { return; }
this.form.remark = ''
this.form.stocktakinNum = 0
this.form.lpNum = 0

View File

@ -1,6 +1,6 @@
<!-- 耗材列表 -->
<template>
<el-dialog title="选择耗材" :visible.sync="dialogVisible" @open="resetHandle()">
<el-dialog title="选择耗材" :visible.sync="dialogVisible">
<el-form :model="searchForm" inline>
<el-form-item>
<el-input v-model="searchForm.conTypeName" placeholder="耗材类型名称" @input="onInput"></el-input>
@ -162,7 +162,6 @@ export default {
this.goods = []
}
this.resetHandle()
this.getTableData()
},
close() {
this.dialogVisible = false

View File

@ -1,5 +1,5 @@
<template>
<el-dialog title="选择商品" :visible.sync="dialogVisible" @open="resetHandle()" @close="reset" top="5vh">
<el-dialog title="选择商品" :visible.sync="dialogVisible" @close="reset" top="5vh">
<el-form :model="searhForm" inline>
<el-form-item>
<el-input v-model="searhForm.name" placeholder="商品名称" @input="onInput"></el-input>
@ -192,9 +192,8 @@ export default {
} else {
this.goods = []
}
this.resetHandle()
this.tbShopCategoryGet()
this.getTableData()
this.resetHandle()
},
close() {
this.dialogVisible = false

View File

@ -96,7 +96,7 @@
</template>
<script>
import { gettbConsInfoFlow, viewConInfoFlow } from "@/api/consumable";
import { gettbConsInfoFlow, gettbConsInfo } from "@/api/consumable";
export default {
data() {
return {
@ -206,7 +206,7 @@ export default {
async getTableData() {
try {
this.clickseetableData.loading = true;
const res = await viewConInfoFlow({
const res = await gettbConsInfo({
page: this.clickseetableData.page,
size: this.clickseetableData.size,
consId: "",

View File

@ -11,71 +11,6 @@
</el-form-item>
</el-form>
</div>
<template>
<div class="box">
<div class="boxitem">
<img src="@/assets/images/data_home_item1_icon.png" />
<div class="boxitem_s">
<div class="boxitem_ses">
<div class="es">
<div class="e">现有数量</div>
<div class="s" style="color: #333333;">3,333</div>
</div>
</div>
</div>
</div>
<div class="boxitem">
<img src="@/assets/images/data_home_item1_icon.png" />
<div class="boxitem_s">
<div class="boxitem_ses">
<div class="es">
<div class="e">增加数量:</div>
<div class="s">3,333</div>
</div>
</div>
<div class="boxitem_ses">
<div class="es">
<div class="e">手动增加:</div>
<div class="s">23</div>
</div>
<div class="es">
<div class="e">入库:</div>
<div class="s">1111</div>
</div>
</div>
</div>
</div>
<div class="boxitem">
<img src="@/assets/images/data_home_item1_icon.png" />
<div class="boxitem_s">
<div class="boxitem_ses">
<div class="es">
<div class="e">减少数量:</div>
<div class="s">1111</div>
</div>
</div>
<div class="boxitem_ses">
<div class="es">
<div class="e">手动减少:</div>
<div class="s">1111</div>
</div>
<div class="es">
<div class="e">消耗:</div>
<div class="s">1111</div>
</div>
<div class="es">
<div class="e">报损:</div>
<div class="s">1111</div>
</div>
<div class="es">
<div class="e">出库:</div>
<div class="s">1111</div>
</div>
</div>
</div>
</div>
</div>
</template>
<div class="head-container">
<el-table ref="table" :data="clickseetableData.data" v-loading="clickseetableData.loading" row-key="id">
<el-table-column label="耗材名称" prop="conName" />
@ -97,10 +32,26 @@
<!-- <el-table-column label="创建时间" prop="createTime"></el-table-column> -->
<el-table-column label="所属商品" width="320" align="center">
<template v-slot="scope">
<el-button v-for="(item) in scope.row.product" @click="toGoods(item)" :key="item.productId"
type="text">{{ item.productName }}</el-button>
<div class="goodslang">
<div class="goods-list">
<el-button v-for="(item) in scope.row.product" @click="toGoods(item.productId)" :key="item.productId"
type="text">{{
item.productName }}</el-button>
</div>
<el-dropdown trigger="click" v-if="scope.row.product.length > 1" @command="toGoods">
<span class="el-dropdown-link" style="color: blue;">
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item class="clearfix" v-for="(item) in scope.row.product" :key="item.productId"
:command="item.productId">
{{ item.productName }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template v-slot="scope">
@ -118,10 +69,10 @@
<el-pagination :total="clickseetableData.total" :current-page="clickseetableData.page + 1"
:page-size="clickseetableData.size" layout="total, sizes, prev, pager, next, jumper"
@current-change="paginationChangetype" @size-change="e => {
clickseetableData.size = e;
clickseetableData.page = 0;
getTableData();
}
clickseetableData.size = e;
clickseetableData.page = 0;
getTableData();
}
" />
</div>
@ -130,7 +81,7 @@
</template>
<script>
import { gettbConsInfoFlow, viewConInfoFlow } from "@/api/consumable";
import { gettbConsInfoFlow, gettbConsInfo } from "@/api/consumable";
import consRecordDetail from "../components/cons_record_detail";
export default {
@ -155,11 +106,11 @@ export default {
this.getTableData();
},
methods: {
toGoods(data) {
toGoods(productId) {
this.$router.push({
path: '/product/product',
query: {
productId: data.productId
productId: productId
}
})
},
@ -194,11 +145,12 @@ export default {
async getTableData() {
try {
this.clickseetableData.loading = true;
const res = await viewConInfoFlow({
const res = await gettbConsInfo({
page: this.clickseetableData.page,
size: this.clickseetableData.size,
...this.query,
shopId: localStorage.getItem("shopId")
shopId: localStorage.getItem("shopId"),
sort: 'createTime,desc'
});
this.clickseetableData.loading = false;
this.clickseetableData.data = res.content.map(v => {
@ -226,6 +178,26 @@ export default {
};
</script>
<style lang="scss" scoped>
.goodslang {
display: flex;
justify-content: flex-start;
align-items: center;
.goods-list {
overflow: hidden; //
text-overflow: ellipsis; //
white-space: nowrap; //
}
::v-deep .goods-list .el-button--text span {
display: block;
text-align: left;
}
::v-deep .goods-list .el-button--text {
white-space: break-spaces;
}
}
.green {
color: #13ce66;
font-weight: bold;

View File

@ -12,72 +12,232 @@
style="width: 150px"
@keyup.enter.native="getTableData"
/> -->
<!-- <div style="width: 150px">
<div style="width: 150px">
<el-select v-model="query.conTypeId" placeholder="请选择耗材分类" style="width: 100%">
<el-option :label="item.conTypeName" :value="item.id" v-for="item in consTypeList"
<el-option :label="item.conTypeName" :value="item.id" v-for="item in tableDatatype.data"
:key="item.conTypeId" />
</el-select>
</div>
<el-input v-model="query.conTypeName" size="small" clearable placeholder="请输入类型名称" style="width: 150px"
<!--<el-input v-model="query.conTypeName" size="small" clearable placeholder="请输入类型名称" style="width: 150px"
@keyup.enter.native="getTableData" />
<el-input v-model="query.conCode" size="small" clearable placeholder="请输入耗材代码" style="width: 150px"
@keyup.enter.native="getTableData" /> -->
@keyup.enter.native="getTableData" />
<el-select v-model="query.status" placeholder="请选择商品规格">
<el-option :label="item.label" :value="item.value" v-for="item in typeEnums" :key="item.label" />
</el-select>-->
<el-input v-model="query.conName" size="small" clearable placeholder="请输入耗材名称" style="width: 150px"
@keyup.enter.native="getTableData" />
<div style="width: 150px">
<el-select v-model="query.status" placeholder="请选择商品规格" style="width: 100%">
<el-option :label="item.label" :value="item.value" v-for="item in typeEnums" :key="item.label" />
</el-select>
</div>
<div style="width: 300px;">
<el-select clearable v-model="query.sort" placeholder="排序">
<el-option label="按数量排序" value="balance,desc" />
</el-select>
</div>
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="yyyy-MM-dd">
</el-date-picker>
<el-button type="primary" @click="getTableData">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
</div>
<div class="row">
<el-button @click="$router.push({ name: 'operation_in' })">入库</el-button>
<el-button @click="$router.push({ name: 'operation_out' })">出库</el-button>
<el-button @click="$router.push({ name: 'cons_record' })">库存记录</el-button>
<el-button type="primary" icon="el-icon-plus" @click="clickdialogframe('add')">添加</el-button>
<el-button @click="routerGo('operation_in')">入库</el-button>
<el-button @click="routerGo('operation_out')">出库</el-button>
<el-button @click="$router.push({ name: 'cons_record' })">耗材记录</el-button>
<el-button @click="$router.push({ name: 'type' })">分类管理</el-button>
<el-button @click="$router.push({ name: 'supplier_manage' })">供应商管理</el-button>
<el-button icon="el-icon-download" :loading="downloadLoading" @click="protHandle">导出耗材</el-button>
<el-button icon="el-icon-upload2" :loading="uploadLoading" @click="dialogVisible = true">导入耗材</el-button>
</div>
</div>
<div class="row_wrap" style="margin-top: 12px">
<div class="row">
<!-- <el-button type="primary" icon="el-icon-plus" @click="clickdialogframe('add')">添加</el-button>
<el-button @click="$router.push({ name: 'operation_in' })">入库</el-button>
<el-button @click="$router.push({ name: 'operation_out' })">出库</el-button>
<el-button @click="$router.push({ name: 'cons_record' })">耗材记录</el-button>
<el-button @click="$router.push({ name: 'type' })">分类管理</el-button>
<el-button @click="$router.push({ name: 'supplier_manage' })">供应商管理</el-button> -->
</div>
<div class="row">
<el-select clearable v-model="query.sort" @change="getTableData" placeholder="排序">
<el-option label="创建时间" value="createTime,desc" />
<el-option label="数量由低到高" value="balance,asc" />
</el-select>
</div>
</div>
</div>
<div class="head-container">
<template>
<div class="box">
<div class="boxitem">
<img src="@/assets/images/data_home_item1_icon.png" />
<div class="boxitem_s">
<div class="boxitem_ses">
<div class="es">
<div class="e">耗材种数</div>
<div class="s" style="color: #333333;">{{ tableData.total }}</div>
</div>
</div>
</div>
</div>
<div class="boxitem">
<img src="@/assets/images/data_home_item1_icon.png" />
<div class="boxitem_s">
<div class="boxitem_ses">
<div class="es">
<div class="e">增加数量:</div>
<div class="s"
@click="stockData.column = 'addCountNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{
tongji.addCountNumber }}</div>
</div>
</div>
<div class="boxitem_ses">
<div class="es">
<div class="e">手动增加:</div>
<div class="s"
@click="stockData.column = 'addNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{ tongji.addNumber }}
</div>
</div>
<div class="es">
<div class="e">入库:</div>
<div class="s"
@click="stockData.column = 'stockInNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{
tongji.stockInNumber }}</div>
</div>
</div>
</div>
</div>
<div class="boxitem">
<img src="@/assets/images/data_home_item1_icon.png" />
<div class="boxitem_s">
<div class="boxitem_ses">
<div class="es">
<div class="e">减少数量:</div>
<div class="s"
@click="stockData.column = 'subCountNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{
tongji.subCountNumber }}</div>
</div>
</div>
<div class="boxitem_ses">
<div class="es">
<div class="e">手动减少:</div>
<div class="s"
@click="stockData.column = 'subNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{ tongji.subNumber }}
</div>
</div>
<div class="es">
<div class="e">消耗:</div>
<div class="s"
@click="stockData.column = 'saleNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{ tongji.saleNumber
}}
</div>
</div>
<div class="es">
<div class="e">报损:</div>
<div class="s"
@click="stockData.column = 'lossNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{ tongji.lossNumber
}}
</div>
</div>
<div class="es">
<div class="e">出库:</div>
<div class="s"
@click="stockData.column = 'stockOutNumber', stockData.size = 10, stockData.page = 0, gettbConsInfoFlowstock()">
{{
tongji.stockOutNumber }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<!-- 动态信息 出库 报损 消耗 手动减少 减少数量 入库 手动增加 增加数量 现有数量-->
<el-dialog :title="variabilitytitle" :visible.sync="variabilityshow" width="75%">
<div class="head-container">
<el-table ref="table" :data="stockData.data" v-loading="stockData.loading" row-key="id" height="450">
<!-- 共存前面 -->
<el-table-column label="耗材名称" prop="conName" />
<el-table-column label="原有库存" prop="balance">
<template v-slot="scope">
<span>{{ scope.row.balance > 0 ? (scope.row.balance + (scope.row.bizType == '-' ?
scope.row.amount : -scope.row.amount)) : Number(scope.row.balance) + Number(scope.row.amount) }}</span>
</template>
</el-table-column>
<el-table-column label="变动后库存" prop="balance"></el-table-column>
<el-table-column label="库存变动数量" prop="amount">
<template v-slot="scope">
<span :class="{ red: scope.row.bizType == '-' }">{{ scope.row.bizType }}{{ scope.row.amount }}</span>
</template>
</el-table-column>
<el-table-column label="操作类型" prop="bizName" />
<el-table-column v-if="variabilitytitle == '消耗'" label="订单编号" prop="orderNo">
<template v-slot="scope">
<div>
<el-button type="text" @click="toGoodslist(scope.row.orderNo)">{{ scope.row.orderNo }}</el-button>
</div>
</template>
</el-table-column>
<!-- 减少数量 -->
<el-table-column v-if="variabilitytitle == '报损'" label="图片" prop="coverImg" />
<!-- 尾巴 -->
<el-table-column v-if="variabilitytitle != '消耗'" label="操作人" prop="operator" />
<el-table-column v-if="variabilitytitle != '消耗'" label="备注" prop="remark" />
<el-table-column label="操作时间" prop="createTime"></el-table-column>
<!-- <el-table-column label="现有库存" prop="balance" />
<el-table-column label="业务说明" prop="bizName" />
<el-table-column label="创建时间" prop="createTime"></el-table-column> -->
</el-table>
</div>
<div class="head-container">
<el-pagination :total="stockData.total" :current-page="stockData.page + 1" :page-size="stockData.size"
layout="total, sizes, prev, pager, next, jumper" @current-change="wstockChange" @size-change="(e) => {
stockData.size = e;
stockData.page = 0;
gettbConsInfoFlowstock();
}" />
</div>
</el-dialog>
<!-- <div class="head-container">
<el-row>
<el-col>
<el-button type="primary" icon="el-icon-plus" @click="clickdialogframe('add')">添加</el-button>
</el-col>
</el-row>
</div>
</div> -->
<div class="head-container" id="table_drag">
<el-table ref="table" :data="tableData.data" v-loading="tableData.loading" row-key="id">
<el-table-column label="耗材名称" prop="conName" style="width: 100px;">
<template v-slot="scope">
<div v-if="scope.row.editNYD == 1">
<el-input v-model="scope.row.conName" placeholder="请输入内容" @blur="conNameClick(scope.row)"></el-input>
</div>
<span v-else>
<!-- <div v-if="scope.row.editNYD == 1">
<el-input v-model="scope.row.conName" placeholder="请输入内容"
@blur="conNameClick(scope.row)"></el-input>
</div> -->
<span>
{{ scope.row.conName }}
</span>
<i class="el-icon-edit" @click="scope.row.editNYD = 1"></i>
<!-- <i class="el-icon-edit" @click="scope.row.editNYD = 1"></i> -->
<i class="el-icon-edit" @click="editorHandle(scope.row)"></i>
</template>
</el-table-column>
<!-- <el-table-column label="分类名称" prop="conTypeName"></el-table-column> -->
<el-table-column label="单位" prop="conUnit">
<template v-slot="scope">
<div v-if="scope.row.editNYD == 2">
<!-- <div v-if="scope.row.editNYD == 2">
<el-input v-model="scope.row.conUnit" placeholder="请输入内容" @blur="conNameClick(scope.row)"></el-input>
</div>
<span v-else>
{{ scope.row.conUnit }}
</span>
<i class="el-icon-edit" @click="scope.row.editNYD = 2"></i>
<i class="el-icon-edit" @click="scope.row.editNYD = 2"></i> -->
<span>
{{ scope.row.conUnit }}
</span>
<i class="el-icon-edit" @click="editorHandle(scope.row)"></i>
</template>
</el-table-column>
@ -89,50 +249,67 @@
<el-table-column label="耗材消耗" prop="conConsume" />
<el-table-column label="耗材入库" prop="conIn" />
<el-table-column label="耗材出库" prop="conOut" />
<el-table-column label="耗材反还" prop="conReturn" />
<el-table-column label="库存开关" prop="conReturn">
<template v-slot="scope">
<el-switch v-model="scope.row.isCheck" active-value="1" inactive-value="0"
@change="showChange($event, scope.row)"></el-switch>
</template>
</el-table-column> -->
<el-table-column label="耗材反还" prop="conReturn" />-->
<el-table-column label="所属商品">
<template v-slot="scope">
<div class="goods-list">
<el-button v-for="(item) in scope.row.product" @click="toGoods(item)" :key="item.productId" type="text">{{
item.productName }}</el-button>
<div class="goodslang">
<div class="goods-list">
<el-button v-for="(item) in scope.row.product" @click="toGoods(item.id)" :key="item.productId"
type="text">{{
item.name }}</el-button><span v-if="scope.row.product.length > 1">,</span>
</div>
<el-dropdown trigger="click" v-if="scope.row.product.length > 1" @command="toGoods">
<span class="el-dropdown-link" style="color: blue;">
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item class="clearfix" v-for="(item) in scope.row.product" :key="item.productId"
:command="item.productId">
{{ item.name }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
</el-table-column>
<el-table-column label="库存数量" prop="stockNumber">
<template v-slot="scope">
{{ (scope.row.balance).toFixed(2) }}
<!-- {{ (scope.row.stockNumber - scope.row.stockConsume).toFixed(2) }} -->
{{ (scope.row.stockNumber - scope.row.stockConsume).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="预警值" prop="conWarning">
<template v-slot="scope">
<div v-if="scope.row.editNYD == 3">
<!-- <div v-if="scope.row.editNYD == 3">
<el-input v-model="scope.row.conWarning" placeholder="请输入内容" @blur="conNameClick(scope.row)"></el-input>
</div>
<span v-else>
{{ scope.row.conWarning }}
</span>
<i class="el-icon-edit" @click="scope.row.editNYD = 3"></i>
<i class="el-icon-edit" @click="scope.row.editNYD = 3"></i> -->
<span>
{{ scope.row.conWarning }}
</span>
<i class="el-icon-edit" @click="editorHandle(scope.row)"></i>
</template>
</el-table-column>
<el-table-column label="状态" prop="status">
<el-table-column label="库存开关" prop="conReturn">
<template v-slot="scope">
<el-switch v-model="scope.row.isCheck" active-value="1" inactive-value="0"
@change="showChange($event, scope.row)"></el-switch>
</template>
</el-table-column>
<!-- <el-table-column label="状态" prop="status">
<template v-slot="scope">
<el-switch v-model="scope.row.status" active-value="1" inactive-value="0"
@change="changeswitchstatus(scope.row)"></el-switch>
</template>
</el-table-column>
</el-table-column> -->
<!-- <el-table-column label="创建时间" prop="createTime" width="200"> </el-table-column> -->
<el-table-column label="操作" width="250" fixed="right">
<template v-slot="scope">
<el-button type="text" @click="editorHandle(scope.row)">编辑</el-button>
<el-button type="text" @click="clicksee(scope.row)" style="margin-left: 10px !important">耗材记录</el-button>
<!-- <el-button type="text" @click="clicksee(scope.row)" style="margin-left: 10px !important">耗材记录</el-button> -->
<el-button type="text" size="mini" style="margin-left: 10px !important"
@click="$refs.AddConsTakin.show(scope.row)">耗材盘点</el-button>
<!-- <el-button style="margin-left: 10px !important" type="text" @click="lookDetail(scope.row)">查看详情</el-button> -->
@ -178,13 +355,13 @@
<el-form-item label=" ">
<i class="el-icon-remove-outline color-danger" @click="ruleFormsReduce(index)"></i>
</el-form-item>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="item.conUnit" placeholder="请输入单位"></el-input>
<el-form-item label="耗材信息名称" prop="conName">
<el-input v-model="item.conName" placeholder="请输入耗材信息名称"></el-input>
</el-form-item>
<el-form-item label="耗材类型" prop="conTypeId">
<el-select v-model="item.conTypeId" placeholder="请选择"
@change="selectChange($event, 'refruleForm' + index, 'conTypeId')">
<el-option v-for="option in consTypeList" :key="option.conTypeId" :label="option.conTypeName"
<el-option v-for="option in tableDatatype.data" :key="option.conTypeId" :label="option.conTypeName"
:value="option.id">
</el-option>
</el-select>
@ -205,8 +382,9 @@
>去选择</el-button
>
</el-form-item> -->
<el-form-item label="耗材信息名称" prop="conName">
<el-input v-model="item.conName" placeholder="请输入耗材信息名称"></el-input>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="item.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<!-- <el-form-item label="耗材信息代码" prop="conCode">
<el-input
@ -240,15 +418,13 @@
<template v-else>
<el-form :inline="true" ref="refruleForm" :model="ruleForm" :rules="rules" class="demo-form-inline">
<el-form-item label="单位" prop="conUnit">
<el-input v-model="ruleForm.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<!-- <el-form-item label="单位" prop="conUnit" v-if="dialogtitle == '添加'">
<el-input v-model="ruleForm.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="耗材类型" prop="conTypeId" v-if="dialogtitle == '添加'">
<el-select v-model="ruleForm.conTypeId" placeholder="请选择">
<el-option v-for="item in consTypeList" :key="item.conTypeId" :label="item.conTypeName" :value="item.id">
<el-option v-for="item in tableDatatype.data" :key="item.conTypeId" :label="item.conTypeName" :value="item.id">
</el-option>
</el-select>
</el-form-item> -->
@ -277,15 +453,18 @@
placeholder="请输入耗材信息代码"
></el-input>
</el-form-item> -->
<el-form-item label="耗材价格">
<!-- <el-form-item label="耗材价格">
<el-input v-model="ruleForm.price" placeholder="请输入耗材价格"></el-input>
</el-form-item> -->
<el-form-item label="单位" prop="conUnit">
<el-input v-model="ruleForm.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="预警值">
<el-input v-model="ruleForm.conWarning" placeholder="请输入耗材预警值"></el-input>
</el-form-item>
<el-form-item label="状态" v-if="dialogtitle == '编辑'">
<!-- <el-form-item label="状态" v-if="dialogtitle == '编辑'">
<el-switch v-model="ruleForm.status" active-value="1" inactive-value="0"></el-switch>
</el-form-item>
</el-form-item> -->
<!-- <el-form-item label="单位耗材值" prop="surplusStock">
<el-input v-model="ruleForm.surplusStock" placeholder="请输入单位耗材值"></el-input>
</el-form-item> -->
@ -370,6 +549,7 @@
" />
</div>
</el-dialog>
<!-- 耗材盘点 -->
<AddConsTakin ref="AddConsTakin" @success="resetHandle" />
<!-- 查看详情 -->
@ -403,26 +583,31 @@ import {
posttbConsInfo,
gettbConsInfoFlow,
posttbConsInfostockIn,
postapitbConsInfo
postapitbConsInfo,
tbConsInfoFlowcount,
tbConsInfoFlowstock
} from "@/api/consumable";
import AddConsTakin from "../components/addConsTakin";
import { tbConsInfodownload, tbConsInfoinputStock } from '@/api/invoicing'
import { downloadFile } from "@/utils";
import UploadExcel from '@/components/UploadExcel'
import consRecordDetail from "../components/cons_record_detail";
import { hasPermission } from '@/utils/limits.js'
export default {
components: { AddConsTakin, UploadExcel, consRecordDetail },
data() {
return {
tongji: {},//
dayjs,
consTypeList: [],
query: {
conTypeId: "",
conTypeName: "",
conCode: "",
conName: "",
status: ''
status: '',
createdAt: [],
sort: 'createTime,desc'
},
resetQuery: '',
libraryshow: false, //
@ -464,10 +649,11 @@ export default {
tableDatatype: {
data: [],
page: 0,
size: 30,
size:100,
loading: false,
total: 0
},
clickseetypedialogshow: false,
clickseetableData: {
data: [],
@ -476,6 +662,15 @@ export default {
loading: false,
total: 0
},
variabilityshow: false,
variabilitytitle: '',
stockData: {
data: [],
page: 0,
size: 10,
loading: false,
total: 0
},
ruleFormLoading: false,
ruleForms: [],
ruleForm: {
@ -527,9 +722,16 @@ export default {
this.resetRuleForms()
this.getTableData();
this.getTableDatatype();
this.gettbConsType()
},
methods: {
async routerGo (name) {
let text;
if ( name == 'operation_in') { text = "允许耗材入库"}
if ( name == 'operation_out') { text = "允许耗材出库"}
let res = await hasPermission(text);
if ( !res) { return; }
this.$router.push({ name: name})
},
lookDetail(row) {
this.$refs.recodeDetail.open({
"consId": row.consId,
@ -553,12 +755,21 @@ export default {
this.$message({ type: "error", message: "至少保留一种耗材" });
}
},
toGoods(data) {
toGoods(productId) {
this.$router.push({
path: '/product/product',
query: {
productId: data.productId
productId: productId
}
})
},
//
toGoodslist(orderNo) {
this.$router.push({
path: '/order_manage/order_list',
query: {
orderNo: orderNo
}
})
},
@ -640,6 +851,8 @@ export default {
//
resetHandle() {
this.query = { ...this.resetQuery }
this.query.sort = 'createTime,desc'
this.query.createdAt = []
this.tableData.page = 0;
this.getTableData();
},
@ -655,50 +868,128 @@ export default {
//
async getTableData() {
this.tableData.loading = true;
let arr = []
if (this.query.createdAt.length) {
arr = [this.query.createdAt[0] + ' 00:00:00', this.query.createdAt[1] + ' 23:59:59']
} else {
arr = []
}
try {
const res = await gettbConsInfo({
...this.query,
page: this.tableData.page,
size: this.tableData.size,
shopId: localStorage.getItem("shopId")
shopId: localStorage.getItem("shopId"),
createTime: arr
});
this.tableData.loading = false;
// this.tableData.data = res.content;
this.tableData.total = res.totalElements;
this.tableData.data = res.content.map(v => {
const productIds = v.productId ? v.productId.split(',') : []
return {
...v,
editNYD: 0,
product: productIds.map((str, index) => {
const startIndex = str.indexOf('_')
const productId = str.slice(0, startIndex)
const productName = str.slice(startIndex + 1, str.length)
return {
productId,
productName: productName + `${(index == productIds.length - 1) ? '' : ','}`
}
})
}
});
this.tableData.data = res.content;
this.gettbConsInfoFlowcount()//
console.log(this.tableData.data)
// this.tableData.data = res.content.map(v => {
// const productIds = v.productId ? v.productId.split(',') : []
// return {
// ...v,
// editNYD: 0,
// product: productIds.map((str, index) => {
// const startIndex = str.indexOf('_')
// const productId = str.slice(0, startIndex)
// const productName = str.slice(startIndex + 1, str.length)
// return {
// productId,
// productName: productName + `${(index == productIds.length - 1) ? '' : ','}`
// }
// })
// }
// });
console.log(this.tableData.data)
} catch (error) {
console.log(error);
}
},
//
async gettbConsType() {
//
async gettbConsInfoFlowcount() {
let arr = []
if (this.query.createdAt.length) {
arr = [this.query.createdAt[0] + ' 00:00:00', this.query.createdAt[1] + ' 23:59:59']
} else {
arr = []
}
try {
const res = await gettbConsType({
page: 0,
size: 100,
shopId: localStorage.getItem("shopId")
})
this.consTypeList = res.content
const res = await tbConsInfoFlowcount({
...this.query,
page: this.tableData.page,
size: this.tableData.size,
shopId: localStorage.getItem("shopId"),
startTime: arr[0],
endTime: arr[1]
});
this.tongji = res;
} catch (error) {
console.log(error);
}
},
//
async gettbConsInfoFlowstock() {
this.variabilityshow = true
switch (this.stockData.column) {
case 'stockNumber':
this.variabilitytitle = '现有数量'
break;
case 'addCountNumber':
this.variabilitytitle = '增加数量'
break;
case 'addNumber':
this.variabilitytitle = '手动增加'
break;
case 'stockInNumber':
this.variabilitytitle = '入库'
break;
case 'refundNumber':
this.variabilitytitle = '退货'
break;
case 'subCountNumber':
this.variabilitytitle = '减少数量'
break;
case 'subNumber':
this.variabilitytitle = '手动减少'
break;
case 'saleNumber':
this.variabilitytitle = '消耗'
break;
case 'lossNumber':
this.variabilitytitle = '报损'
break;
case 'stockOutNumber':
this.variabilitytitle = '出库'
break;
}
this.stockData.loading = true;
let arr = []
if (this.query.createdAt.length) {
arr = [this.query.createdAt[0] + ' 00:00:00', this.query.createdAt[1] + ' 23:59:59']
} else {
arr = []
}
let res = await tbConsInfoFlowstock({
page: this.stockData.page,
size: this.stockData.size,
shopId: localStorage.getItem("shopId"),
productId: '',//id
column: this.stockData.column,//
conName: this.query.conName,
createdAt: arr//id
})
this.stockData.loading = false;
this.stockData.data = res.content;
this.stockData.total = res.totalElements;
},
//
wstockChange(e) {
this.stockData.page = e - 1;
this.gettbConsInfoFlowstock();
},
//
async getTableDatatype() {
this.tableDatatype.loading = true;
@ -758,9 +1049,9 @@ export default {
if (type == "add") {
//
this.dialogtitle = "添加";
this.gettbConsType()
this.getTableDatatype()
this.$nextTick(() => {
// this.$refs.refruleForm.resetFields();
this.$refs.refruleForm.resetFields();
this.resetRuleForms()
});
} else {
@ -858,9 +1149,10 @@ export default {
const res = await gettbConsInfoFlow({
page: this.clickseetableData.page,
size: this.clickseetableData.size,
consId: this.consRecordItem.consId,
conName: this.consRecordItem.conName,
shopId: localStorage.getItem("shopId")
// consId: this.consRecordItem.consId,
// conName: this.consRecordItem.conName,
shopId: localStorage.getItem("shopId"),
sort: 'createTime,desc'
});
this.clickseetableData.loading = false;
this.clickseetableData.data = res.content;
@ -874,13 +1166,25 @@ export default {
</script>
<style scoped lang="scss">
::v-deep .goods-list .el-button--text span {
display: block;
text-align: left;
}
.goodslang {
display: flex;
justify-content: flex-start;
align-items: center;
::v-deep .goods-list .el-button--text {
white-space: break-spaces;
.goods-list {
overflow: hidden; //
text-overflow: ellipsis; //
white-space: nowrap; //
}
::v-deep .goods-list .el-button--text span {
display: block;
text-align: left;
}
::v-deep .goods-list .el-button--text {
white-space: break-spaces;
}
}
.color-success {
@ -933,4 +1237,68 @@ export default {
.red {
color: rgb(219, 32, 32);
}
.box {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0px 90px 20px 90px;
.boxitem {
min-width: max-content;
display: flex;
justify-content: center;
align-items: center;
padding: 20px 24px;
background: rgba(244, 249, 255, 0.5);
border-radius: 10px;
.boxitem_s {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.boxitem_ses {
margin-top: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
.es {
border-left: 2px solid #DDDFE6;
padding: 0 10px;
display: flex;
justify-content: flex-start;
align-items: center;
.e {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 12px;
color: #666666;
}
.s {
margin-left: 10px;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 15px;
color: #3F9EFF;
}
}
.es:nth-child(1) {
margin-top: 0;
border-left: none;
}
}
.boxitem_ses:nth-child(1) {
margin-top: 0;
}
}
}
}
</style>

View File

@ -56,7 +56,7 @@
</el-col>
</el-row>
</div>
<div class="head-container">
<!-- <div class="head-container">
<el-row>
<el-col>
<el-button
@ -67,7 +67,7 @@
>
</el-col>
</el-row>
</div>
</div> -->
<div class="head-container" id="table_drag">
<el-table
ref="table"

View File

@ -18,7 +18,7 @@
</el-select>
</div>
<div style="width: 300px;">
<el-select v-model="query.sort" placeholder="排序">
<el-select v-model="query.sort" placeholder="排序">
<el-option label="默认排序" value="false" />
<el-option label="库存降序" value="true" />
</el-select>
@ -68,14 +68,16 @@
</template>
</el-table-column>
<el-table-column label="库存" prop="number">
<template v-slot="scope" >
<span v-if="!scope.row.isStock" :class="[scope.row.stockNumber <= warnLine ? 'colorStyle' : '']">
<span v-if="scope.row.stockNumber < 0" style="font-weight: 700;color: #999;font-size: 14px;">-</span>
<span >
<span> {{ Math.abs(scope.row.stockNumber) }}</span>
<template v-slot="scope">
<span v-if="!scope.row.isStock"
:class="[scope.row.stockNumber <= warnLine ? 'colorStyle' : '']">
<span v-if="scope.row.stockNumber < 0"
style="font-weight: 700;color: #999;font-size: 14px;">-</span>
<span>
<span> {{ Math.abs(scope.row.stockNumber) }}</span>
<span> {{ scope.row.unitName }}</span>
</span>
</span>
<span v-else :class="[scope.row.stockNumber <= warnLine ? 'colorStyle' : '']">
{{ `${scope.row.stockNumber} ${scope.row.unitName}` }}
@ -399,6 +401,12 @@ export default {
</script>
<style scoped lang="scss">
::v-deep .cell {
display: flex;
align-items: center;
/* flex-direction: row-reverse; */
}
.shop_info {
display: flex;
align-items: center;
@ -435,10 +443,3 @@ export default {
font-weight: 700;
}
</style>
<style>
.cell {
display: flex;
align-items: center;
/* flex-direction: row-reverse; */
}
</style>

View File

@ -2,7 +2,7 @@
<div class="app-container">
<div class="head-container">
<el-form ref="queryForm" :model="queryForm" :rules="queryRules" label-position="left" label-width="80px">
<el-form-item label="入库内容">
<!-- <el-form-item label="入库内容">
<div class="shop_type_box">
<div class="item" v-for="item in inTabs" :key="item.value"
:class="{ active: inTabValue == item.value }" @click="tabChange(item.value, item.type)">
@ -12,7 +12,7 @@
</div>
</div>
</div>
</el-form-item>
</el-form-item> -->
<!-- <el-form-item label="入库类型" v-if="inTabValue == 'goods'">
<div class="shop_type_box">
<div class="item" v-for="(item, index) in shopTypes" :key="index"
@ -233,7 +233,7 @@ export default {
data() {
return {
formatDecimal,
inTabValue: 'goods',
inTabValue: 'consumable',
inTabs: [
{
label: '商品入库',
@ -246,7 +246,7 @@ export default {
type: 'in'
}
],
shopTypesActive: 1,
shopTypesActive: 0,
shopTypes: [
{
label: '供应商入库',
@ -275,7 +275,7 @@ export default {
remark: '',
time: dayjs().format('YYYY-MM-DD'),
totalAmount: 0,
type: 'purveyor',
type: 'in',
shopId: localStorage.getItem('shopId')
},
queryRules: {
@ -382,6 +382,7 @@ export default {
},
//
tabChange(value, type) {
console.log(value,type)
this.shopTypesActive = type == 'in' ? 0 : 1
this.inTabValue = value
this.resetHandle()
@ -502,7 +503,7 @@ export default {
item.number = formatDecimal(item.stockNumber - item.stockConsume, 2, true)
item.stockNumber = 0
item.costPrice = item.price
item.conInfold = item.id
item.conInfoId = item.id
return item
})
this.tableData.list = [...this.tableData.list, ...arr]

View File

@ -2,7 +2,7 @@
<div class="app-container">
<div class="head-container">
<el-form ref="queryForm" :model="queryForm" :rules="queryRules" label-position="left" label-width="80px">
<el-form-item label="出库内容">
<!-- <el-form-item label="出库内容">
<div class="shop_type_box">
<div class="item" v-for="item in inTabs" :key="item.value"
:class="{ active: inTabValue == item.value }" @click="tabChange(item.value, item.type)">
@ -12,7 +12,7 @@
</div>
</div>
</div>
</el-form-item>
</el-form-item> -->
<!-- <el-form-item label="出库类型" v-if="inTabValue == 'goods'">
<div class="shop_type_box">
<div class="item" v-for="(item, index) in shopTypes" :key="index"
@ -228,7 +228,7 @@ export default {
data() {
return {
formatDecimal,
inTabValue: 'goods',
inTabValue: 'consumable',
inTabs: [
{
label: '商品出库',
@ -241,7 +241,7 @@ export default {
type: 'out'
}
],
shopTypesActive: 1,
shopTypesActive: 0,
shopTypes: [
{
label: '供应商退货',
@ -466,7 +466,7 @@ export default {
item.number = formatDecimal(item.stockNumber - item.stockConsume, 2, true)
item.stockNumber = 0
item.costPrice = item.price
item.conInfold = item.id
item.conInfoId = item.id
return item
})
this.tableData.list = [...this.tableData.list, ...arr]

View File

@ -1,7 +1,18 @@
<template>
<el-drawer title="订单详情" size="50%" :visible.sync="drawer" direction="rtl" v-loading="loading">
<div class="header">
<div class="title">收银订单</div>
<div class="title" style="text-align: center;">收银订单</div>
<div class="container">
<div class="info_content">
<div class="item">
<div class="label">会员信息</div>
<div class="row">
<div>会员昵称-</div>
<div>联系电话-</div>
</div>
</div>
</div>
</div>
<div class="table">
<div class="item">
<div class="t">订单状态</div>
@ -16,7 +27,25 @@
<div class="b">{{ detail.orderAmount }}</div>
</div>
<div class="item">
<div class="t">订单时间</div>
<div class="t">订单类型</div>
<div class="b">
{{ detail.sendType | sendTypeFilter }}
</div>
</div>
</div>
<div class="table">
<div class="item">
<div class="t">订单编号</div>
<div class="b">
{{ detail.orderNo }}
</div>
</div>
<div class="item">
<div class="t">下单时间</div>
<div class="b">{{ detail.createdAt | timeFilter }}</div>
</div>
<div class="item">
<div class="t">支付时间</div>
<div class="b">
{{ detail.createdAt | timeFilter }}
</div>
@ -24,53 +53,87 @@
</div>
</div>
<div class="container">
<el-tabs v-model="type" @tab-click="getTableData">
<el-tab-pane label="基本信息" name="1">
<div class="info_content">
<div class="item">
<div class="label">会员信息</div>
<div class="row">
<div>会员昵称-</div>
<div>联系电话-</div>
</div>
</div>
<div class="item">
<div class="label">收款详情</div>
<div class="row">
<!-- <div>商品金额{{ detail.productAmount }}</div> -->
<div>打包费{{ detail.packFee || "-" }}</div>
</div>
<div class="row">
<div>订单原价{{ detail.originAmount }}</div>
<div>优惠金额{{ detail.userCouponAmount || "-" }}</div>
<div>
实收金额<span style="color: red;">{{ detail.payAmount }}</span>
</div>
</div>
<div class="row">
<div>
退款金额{{ detail.refundAmount }}
<span style="color: #FF9731;cursor: pointer;" v-if="detail.isRefund" @click="type = '3'">退款详情></span>
</div>
<div>支付方式{{ detail.payType }}</div>
</div>
</div>
<div class="item">
<div class="label">订单信息</div>
<div class="row">
<div>订单编号{{ detail.orderNo }}</div>
<div>订单类型{{ detail.sendType | sendTypeFilter }}</div>
<div>创建时间{{ detail.createdAt | timeFilter }}</div>
</div>
<div class="row">
<div>设备名称-</div>
<div>支付时间{{ detail.paidTime | timeFilter }}</div>
<div>更新时间{{ detail.updatedAt | timeFilter }}</div>
</div>
<!-- <el-tabs v-model="type" @tab-click="getTableData"> -->
<!-- <el-tab-pane label="基本信息" name="1"> -->
<div class="info_content">
<!-- <div class="item">
<div class="label">会员信息</div>
<div class="row">
<div>会员昵称-</div>
<div>联系电话-</div>
</div>
</div> -->
<div class="item">
<div class="label">收款详情</div>
<!-- <div class="row">
<div>商品金额{{ detail.productAmount }}</div>
<div>打包费{{ detail.packFee || "-" }}</div>
</div> -->
<div class="row">
<div>打包费{{ detail.packFee || "-" }}</div>
<div>订单原价{{ detail.originAmount }}</div>
<div>优惠金额{{ detail.userCouponAmount || "-" }}</div>
<div>
实收金额<span style="color: red;">{{ detail.payAmount }}</span>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="商品信息" name="2">
<div class="row">
<div>
退款金额{{ detail.refundAmount }}
<span style="color: #FF9731;cursor: pointer;" v-if="detail.isRefund" @click="type = '3'">退款详情></span>
</div>
<div>支付方式{{ detail.payType }}</div>
</div>
</div>
<!-- <div class="item">
<div class="label">订单信息</div>
<div class="row">
<div>订单编号{{ detail.orderNo }}</div>
<div>订单类型{{ detail.sendType | sendTypeFilter }}</div>
<div>创建时间{{ detail.createdAt | timeFilter }}</div>
</div>
<div class="row">
<div>设备名称-</div>
<div>支付时间{{ detail.paidTime | timeFilter }}</div>
<div>更新时间{{ detail.updatedAt | timeFilter }}</div>
</div>
</div> -->
</div>
<div>
<div style="margin-bottom: 16px;font-size:16px;">商品信息</div>
<el-table :data="detail.detailList">
<el-table-column label="商品">
<template v-slot="scope">
<div class="shop_info">
<el-image :src="scope.row.productImg" style="width: 40px;height: 40px;"></el-image>
<div class="info">
<span :class="[scope.row.isVip == 1 ? 'colorStyle' : '']">{{ scope.row.productName }}</span>
<span style="color: #999;">{{
scope.row.productSkuName
}}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="数量">
<template v-slot="scope">
x{{ scope.row.num }}
</template>
</el-table-column>
<el-table-column label="单价">
<template v-slot="scope">
{{ scope.row.price }}/
</template>
</el-table-column>
<el-table-column label="小计">
<template v-slot="scope">
{{ scope.row.priceAmount }}
</template>
</el-table-column>
</el-table>
</div>
<!-- </el-tab-pane> -->
<!-- <el-tab-pane label="商品信息" name="2">
<el-table :data="detail.detailList">
<el-table-column label="商品">
<template v-slot="scope">
@ -101,7 +164,7 @@
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tab-pane>
<el-tab-pane label="退款详情" name="3" v-if="detail.isRefund">
<div class="refund_wrap">
<div class="row" v-for="item in refoundList" :key="item.id">
@ -127,7 +190,8 @@
</div>
</div>
</el-tab-pane>
</el-tabs>
-->
<!-- </el-tabs> -->
</div>
</el-drawer>
</template>
@ -294,7 +358,7 @@ export default {
padding-top: 20px;
div {
width: 33.333%;
width: 25%;
}
}
}

View File

@ -114,7 +114,7 @@
<el-table-column label="台桌号" prop="tableName"></el-table-column>
<el-table-column label="订单金额">
<template v-slot="scope">
<div>{{ scope.row.orderType | orderTypeFilter }}</div>
<!-- <div>{{ scope.row.orderType | orderTypeFilter }}</div> -->
<div class="refund" v-if="
scope.row.orderType == 'return'
">
@ -244,6 +244,7 @@ export default {
this.getTableData();
}, 200);
}
},
methods: {
//

View File

@ -45,7 +45,7 @@
<el-button type="primary" plain icon="el-icon-plus" @click="$refs.addClassifyRef.show()">添加分类</el-button>
<addClassify ref="addClassifyRef" @success="tbShopCategoryGet" />
</el-form-item>
<el-form-item label="商品图片">
<el-form-item label="商品图片" prop="coverImg">
<div style="display: flex; flex-wrap: wrap">
<div v-for="(item, index) in imgList" :key="index" style="position: relative" class="showStyle">
<i class="el-icon-error buttonstyle" @click="deleteEvent(item)"></i>
@ -332,7 +332,7 @@
</div> -->
</el-form-item>
<template v-if="form.typeEnum != 'group'">
<el-form-item label="上架区域">
<!-- <el-form-item label="上架区域">
<div class="shop_type_box">
<div class="item" :class="{ active: form.isShowCash }" @click="areaChange('isShowCash')">
<div class="s_title">收银台</div>
@ -347,11 +347,17 @@
</div>
</div>
</div>
</el-form-item> -->
<el-form-item label="上架">
<el-switch v-model="form.isGrounding" :active-value="1" :inactive-value="0"></el-switch>
</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.isHot" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item label="库存数量" v-if="form.isStock">
<el-input-number @change="priceFormat(form, 'stockNumber')" @blur="priceFormat(form, 'stockNumber')"
v-model="form.stockNumber" controls-position="right"></el-input-number>
@ -394,7 +400,7 @@
</span>
</el-dialog>
<!-- 选择团购券分类 -->
<groupTypeList ref="groupTypeList" @success="(res) => (form.groupCategoryId = res)" />
<!-- <groupTypeList ref="groupTypeList" @success="(res) => (form.groupCategoryId = res)" /> -->
<!-- 选择图片 -->
<addImg ref="addImg" @successEvent="successEvent"></addImg>
</div>
@ -440,6 +446,13 @@ export default {
callback();
}
};
const validateCoverImg = (rule, value, callback) => {
if (!this.form.images.length) {
callback(new Error("请上传商品图片"));
} else {
callback()
}
}
return {
shopTypesActive: 0,
shopTypes: settings.typeEnum,
@ -454,7 +467,7 @@ export default {
memberPrice: undefined,
costPrice: undefined,
originPrice: undefined,
stockNumber: undefined,
// stockNumber: undefined,
firstShared: 0,
barCode: `${localStorage.getItem("shopId")}${dayjs().valueOf()}`,
isGrounding: 1,
@ -504,7 +517,9 @@ export default {
refundPolicy: "",
usageRules: "",
},
stockNumber: 0
stockNumber: 0,
isHot: 1,
isGrounding: 1
},
imgList: [],
rules: {
@ -520,6 +535,14 @@ export default {
message: "请输入商品名称",
},
],
coverImg: [
{
required: true,
trigger: "change",
validator: validateCoverImg,
message: "请上传商品图片",
}
],
unitId: [
{
required: true,
@ -711,6 +734,11 @@ export default {
specInfo[index].suit = item.suit;
specInfo[index].stockNumber = item.stockNumber;
specInfo[index].isGrounding = item.isGrounding;
specInfo[index].salePrice = item.salePrice;
specInfo[index].memberPrice = item.memberPrice;
specInfo[index].costPrice = item.costPrice;
specInfo[index].originPrice = item.originPrice;
specInfo[index].firstShared = item.firstShared;
return specInfo[index];
});
console.log(this.form.skuList);
@ -724,15 +752,21 @@ export default {
//
submitHandle() {
// undefinedtrue
const hasUndefined = this.form.skuList.some(obj => {
for (const key in obj) {
if (obj[key] === undefined) {
return true; // undefinedtrue
if (this.shopTypesActive == 0) {//
if (obj['salePrice'] == undefined || obj['memberPrice'] == undefined) {
return true;
}
} else {//
if (obj['salePrice'] == undefined || obj['memberPrice'] == undefined || obj['costPrice'] == undefined || obj['originPrice'] == undefined) {
return true;
}
}
}
return false; // undefinedfalse
return false;
});
//
if (hasUndefined) {
this.$message({
message: "请完善规格属性的参数!",
@ -740,6 +774,7 @@ export default {
});
return false;
}
let arr = [];
this.imgList.forEach((ele) => {
arr.push(ele.url);

View File

@ -50,7 +50,12 @@
</div>
<div class="head-container">
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper" @size-change="(e) => {
tableData.size = e;
tableData.page = 0;
getTableData();
}
"></el-pagination>
</div>
</div>
</template>

View File

@ -37,6 +37,8 @@
<script>
import uploadImg from '@/components/uploadImg'
import { tbShopCategoryPost } from '@/api/shop'
import { hasPermission } from '@/utils/limits.js'
export default {
components: {
uploadImg
@ -89,7 +91,9 @@ export default {
}
})
},
show(obj) {
async show(obj) {
let res = await hasPermission('允许修改分类');
if ( !res) { return; }
// console.log(obj)
this.dialogVisible = true
if (obj && obj.pid) {

View File

@ -27,7 +27,7 @@
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="售卖时间管控" v-if="form.id">
<el-form-item label="售卖时间管控" >
<el-radio-group v-model="form.useTime">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">禁用</el-radio>
@ -51,7 +51,7 @@
</el-form-item>
<el-form-item label="分组排序" v-if="form.id">
<el-form-item label="分组排序" >
<el-input-number v-model="form.sort" controls-position="right" :min="0"></el-input-number>
</el-form-item>
@ -68,6 +68,8 @@
<script>
import { tbProductGroupPost, tbProductGroupPut, productListGet } from '@/api/shop'
import shopList from '@/components/shopList'
import { hasPermission } from '@/utils/limits.js'
export default {
components: {
shopList
@ -178,7 +180,9 @@ export default {
console.log(error)
}
},
show(obj) {
async show(obj) {
let res = await hasPermission('允许修改分组');
if ( !res) { return; }
// if()
this.form.useTime = 0
if (obj && obj.id) {

View File

@ -5,9 +5,9 @@
<div class="btn_wrap">
<div class="refund_stock">
<span>退款退回库存</span>
<el-switch v-model="isRefundStock"></el-switch>
<el-switch :active-value="1" :inactive-value="0" v-model="goodsDetail.isRefundStock"></el-switch>
</div>
<el-radio-group v-model="type">
<el-radio-group v-model="type" @change="typeChange">
<el-radio-button label="1">添加至商品</el-radio-button>
<el-radio-button label="2" v-if="goodsDetail.typeEnum == '多规格'">添加至规格</el-radio-button>
</el-radio-group>
@ -16,43 +16,96 @@
<div class="name_wrap">
<div class="name">商品名{{ goodsDetail.name }}</div>
</div>
<el-table :data="tableData.cons">
<!-- 绑定到商品 -->
<el-table :data="tableData.cons" border v-show="type == 1">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="耗材名称">
<el-table-column label="耗材名称" prop="conInfoId">
<template v-slot="scope">
<el-select v-model="scope.row.conInfoId" filterable remote reserve-keyword placeholder="请输入关键词"
:remote-method="remoteMethod" :loading="loading" @change="selectionChange($event, scope.row)">
<el-option v-for="item in options" :key="item.consId" :label="item.conName"
:value="item.consId">
<el-option v-for="item in options" :key="item.id" :label="item.conName"
:value="item.id">
</el-option>
</el-select>
<div class="tips" v-if="scope.row.stockNumber">库存{{ scope.row.stockNumber }}</div>
</template>
</el-table-column>
<el-table-column label="单位">
<el-table-column label="单位" prop="conUnit">
<template v-slot="scope">
<span v-if="scope.row.conInfoId">{{ scope.row.conUnit }}</span>
<span v-else>请选择耗材</span>
</template>
</el-table-column>
<el-table-column label="使用数量">
<el-table-column label="使用数量" prop="surplusStock">
<template v-slot="scope">
<el-input-number v-model="scope.row.surplusStock" :min="0" />
</template>
</el-table-column>
<el-table-column label="操作" width="100px">
<el-table-column label="操作">
<template v-slot="scope">
<div class="table_btn_wrap">
<div class="btn sub" @click="tableData.cons.splice(scope.$index, 1)">
<div class="btn sub" v-if="scope.$index > 0" @click="tableData.cons.splice(scope.$index, 1)">
<i class="el-icon-remove-outline"></i>
</div>
<div class="btn add" @click="createItem">
<div class="btn add" @click="createItem(scope.row)">
<i class="el-icon-circle-plus-outline"></i>
</div>
</div>
</template>
</el-table-column>
</el-table>
<!-- 绑定到规格 -->
<el-table :data="tableData.cons" border v-show="type == 2">
<el-table-column label="序号" type="index" width="100"></el-table-column>
<el-table-column label="规格名称" prop="specSnap"></el-table-column>
<el-table-column label="耗材" width="600">
<el-table-column label="耗材信息">
<template v-slot="scope">
<div class="sku_table_item" v-for="(item, index) in scope.row.consList" :key="index">
<el-select v-model="item.conInfoId" filterable remote reserve-keyword placeholder="请输入关键词"
:remote-method="remoteMethod" :loading="loading"
@change="skuSelectionChange($event, item)">
<el-option v-for="item in options" :key="item.id" :label="item.conName"
:value="item.id">
</el-option>
</el-select>
<div class="tips" v-if="scope.row.stockNumber">库存{{ scope.row.stockNumber }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="耗材单位">
<template v-slot="scope">
<div class="sku_table_item" v-for="(item, index) in scope.row.consList" :key="index">
<div class="t">
<span v-if="item.conInfoId">{{ item.conUnit }}</span>
<span v-else>请选择耗材</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="消耗量">
<template v-slot="scope">
<div class="sku_table_item" v-for="(item, index) in scope.row.consList" :key="index">
<el-input-number v-model="item.surplusStock" :min="0" />
</div>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="scope">
<div class="sku_table_item" v-for="(item, index) in scope.row.consList" :key="index">
<div class="table_btn_wrap t">
<div class="btn sub" v-if="index > 0" @click="scope.row.consList.splice(index, 1)">
<i class="el-icon-remove-outline"></i>
</div>
<div class="btn add" @click="skuCreateItem(scope.$index)">
<i class="el-icon-circle-plus-outline"></i>
</div>
</div>
</div>
</template>
</el-table-column>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" :loading=formLoading @click="onSubmitHandle"> </el-button>
@ -85,19 +138,63 @@ export default {
//
async onSubmitHandle() {
try {
// let flag = true
// this.tableData.cons.map(item => {
// if (!item.conInfoId) {
// flag = false
// }
// })
// if (!flag) {
// this.$message.error('')
// return
// }
let res = null
this.formLoading = true
const res = await tbProskuConV2(this.tableData)
if (this.type == 1) {
res = await tbProskuConV2(this.tableData)
} else if (this.type == 2) {
let data = { ...this.tableData }
let arr = []
data.cons.map(item => {
item.consList.map(val => {
if (val.name) {
let obj = { ...item }
obj.id = val.id
obj.name = val.name
obj.productSkuId = item.productSkuId
obj.conInfoId = val.conInfoId
obj.surplusStock = val.surplusStock
arr.push(obj)
}
})
})
data.cons = arr
res = await tbProskuConV2(data)
}
this.formLoading = false
this.$message.success('编辑成功')
this.dialogVisible = false
this.$emit('refundChange', this.goodsDetail)
} catch (error) {
console.log(error);
this.formLoading = false
}
},
//
//
selectionChange(e, row) {
let item = this.options.find(item => item.consId == e)
let item = this.options.find(item => item.id == e)
row.name = item.conName
row.conUnit = item.conUnit
},
//
skuSelectionChange(e, row) {
let item = this.options.find(item => item.id == e)
row.name = item.conName
row.conUnit = item.conUnit
},
@ -128,15 +225,113 @@ export default {
this.dialogVisible = true
this.goodsDetail = { ...obj }
this.tableData.productId = this.goodsDetail.id
if (obj.conInfos.length) {
this.tableData.cons = [...obj.conInfos]
this.type = this.goodsDetail.isSaveSku
this.initItem()
},
//
typeChange() {
this.initItem(true)
},
//
initItem(radio = false) {
this.tableData.cons = []
if (this.type == 1) {
//
if (radio) {
let item = {}
item.id = ''
item.shopId = localStorage.getItem('shopId')
item.productId = this.goodsDetail.id
item.productSkuId = 0
item.conInfoId = ''
item.name = ''
item.conUnit = ''
item.surplusStock = 0
item.status = 1
this.tableData.cons.push(item)
} else {
if (this.goodsDetail.conInfos.length) {
this.goodsDetail.conInfos.map(val => {
let item = {}
item.id = val.id
item.shopId = val.shopId
item.productId = val.productId
item.productSkuId = 0
item.conInfoId = val.conInfoId
item.name = ''
item.conUnit = val.conUnit
item.surplusStock = val.surplusStock
item.status = 1
item.specSnap = ''
this.tableData.cons.push(item)
})
} else {
let item = {}
item.id = ''
item.shopId = localStorage.getItem('shopId')
item.productId = this.goodsDetail.id
item.productSkuId = 0
item.conInfoId = ''
item.name = ''
item.conUnit = ''
item.surplusStock = 0
item.status = 1
this.tableData.cons.push(item)
}
}
} else {
this.createItem()
//
this.goodsDetail.skuList.map(val => {
let item = {}
item.id = ''
item.shopId = localStorage.getItem('shopId')
item.productId = this.goodsDetail.id
item.productSkuId = val.id
item.conInfoId = ''
item.name = ''
item.conUnit = ''
item.surplusStock = 0
item.status = 1
item.specSnap = val.name
item.consList = [
{
surplusStock: 0,
conInfoId: '',
name: '',
conUnit: ''
}
]
this.tableData.cons.push(item)
})
if (this.goodsDetail.conInfos.length) {
this.tableData.cons.map(val => {
this.goodsDetail.conInfos.map(item => {
if (item.productSkuId == val.productSkuId) {
val.consList.unshift({
id: item.id,
surplusStock: item.surplusStock,
conInfoId: item.conInfoId,
name: item.conName,
conUnit: item.conUnit
})
}
})
})
}
}
},
//
createItem() {
//
createItem(val) {
let item = {}
item.id = ''
item.shopId = localStorage.getItem('shopId')
item.productId = this.goodsDetail.id
@ -146,8 +341,18 @@ export default {
item.conUnit = ''
item.surplusStock = 0
item.status = 1
this.tableData.cons.push(item)
},
//
skuCreateItem($index) {
this.tableData.cons[$index].consList.push({
conInfoId: '',
name: '',
conUnit: '',
surplusStock: 0
})
},
reset() {
this.goodsDetail = ''
this.tableData.productId = ''
@ -212,4 +417,29 @@ export default {
}
}
}
.cons_list_wrap {
.row {
display: flex;
padding: 10px 0;
align-items: center;
gap: 10px;
.item {
flex: 1;
display: flex;
align-items: center;
}
}
}
.sku_table_item {
padding: 10px 0;
.t {
height: 32px;
display: flex;
align-items: center;
}
}
</style>

View File

@ -0,0 +1,281 @@
<!-- 商品库存记录 -->
<template>
<el-dialog width="80%" :title="`${keysList[key]}统计`" :visible.sync="dialogVisible" @close="reset">
<div class="head-container">
<el-table ref="table" :data="tableData.data" v-loading="tableData.loading" height="400px"
v-if="dialogVisible">
<!-- 销量统计 -->
<template v-if="key == 'saleNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="原库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ scope.row.leftNumber + scope.row.stockNumber }}
</template>
</el-table-column>
<el-table-column label="销量" prop="stockNumber"></el-table-column>
<el-table-column label="订单编号" prop="orderNo">
<template v-slot="scope">
<router-link
:to="{ path: '/order_manage/order_list', query: { orderNo: scope.row.orderNo } }">
<el-link type="primary">{{ scope.row.orderNo }}</el-link>
</router-link>
</template>
</el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<!-- 减少数量统计 -->
<template v-if="key == 'subCountNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ `${scope.row.leftNumber + scope.row.stockNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="原有库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}` }}
</template>
</el-table-column>
<el-table-column label="变动数量" prop="stockNumber"></el-table-column>
<el-table-column label="类型" prop="type"></el-table-column>
<el-table-column label="操作人" prop="operator"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<!-- 手动减少统计 -->
<template v-if="key == 'subNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ `${scope.row.leftNumber + scope.row.stockNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="原有库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}` }}
</template>
</el-table-column>
<el-table-column label="变动数量" prop="stockNumber"></el-table-column>
<el-table-column label="类型" prop="type"></el-table-column>
<el-table-column label="操作人" prop="operator"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<!-- 报损统计 -->
<template v-if="key == 'lossNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="原库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ `${scope.row.leftNumber + scope.row.stockNumber}` }}
</template>
</el-table-column>
<el-table-column label="报损数量" prop="stockNumber"></el-table-column>
<el-table-column label="报损人" prop="operator"></el-table-column>
<el-table-column label="图片" prop="coverImg">
<template v-slot="scope">
<el-image :src="scope.row.coverImg" style="width: 40px;height: 40px;">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<!-- 增加数量统计 -->
<template v-if="key == 'addCountNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ `${scope.row.leftNumber + scope.row.stockNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="原库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}` }}
</template>
</el-table-column>
<el-table-column label="变动数量" prop="stockNumber"></el-table-column>
<el-table-column label="类型" prop="type"></el-table-column>
<el-table-column label="操作人" prop="operator"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<!-- 手动增加统计 -->
<template v-if="key == 'addNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ `${scope.row.leftNumber + scope.row.stockNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="原库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}` }}
</template>
</el-table-column>
<el-table-column label="变动数量" prop="stockNumber"></el-table-column>
<el-table-column label="类型" prop="type"></el-table-column>
<el-table-column label="操作人" prop="operator"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
<!-- 退货统计 -->
<template v-if="key == 'refundNumber'">
<el-table-column label="商品名称/规格名称" prop="productName"></el-table-column>
<el-table-column label="变动后库存">
<template v-slot="scope">
{{ `${scope.row.leftNumber + scope.row.stockNumber}${scope.row.unitName}` }}
</template>
</el-table-column>
<el-table-column label="原库存" prop="leftNumber">
<template v-slot="scope">
{{ `${scope.row.leftNumber}` }}
</template>
</el-table-column>
<el-table-column label="退货数量" prop="stockNumber"></el-table-column>
<el-table-column label="订单编号" prop="orderNo">
<template v-slot="scope">
<router-link
:to="{ path: '/order_manage/order_list', query: { orderNo: scope.row.orderNo } }">
<el-link type="primary">{{ scope.row.orderNo }}</el-link>
</router-link>
</template>
</el-table-column>
<el-table-column label="操作人" prop="operator"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column label="操作时间" prop="updatedAt">
<template v-slot="scope">
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</template>
</el-table>
</div>
<div class="head-container">
<el-pagination :total="tableData.total" @size-change="handleSizeChange" :current-page="tableData.page + 1"
:page-size="tableData.size" @current-change="paginationChange"
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
</div>
</el-dialog>
</template>
<script>
import dayjs from 'dayjs'
import { tbProductStockDetailStock } from '@/api/shop.js'
export default {
props: {
query: {
type: Object,
default: {}
}
},
data() {
return {
dayjs,
dialogVisible: false,
key: 'saleNumber',
keysList: {
stockNumber: '现有数量',
addCountNumber: '增加数量',
addNumber: '手动增加',
refundNumber: '退货',
subCountNumber: '减少数量',
subNumber: '手动减少',
saleNumber: '销量',
lossNumber: '报损',
},
productId: '',
tableData: {
sort: 1,
data: [],
page: 0,
size: 30,
loading: false,
total: 0
},
}
},
methods: {
//
async tbProductStockDetailStock() {
try {
this.tableData.loading = true
const res = await tbProductStockDetailStock({
page: this.tableData.page,
size: this.tableData.size,
shopId: localStorage.getItem('shopId'),
column: this.key,
productName: this.query.name,
categoryId: this.query.categoryId,
type: this.query.typeEnum,
startTime: this.query.createdAt[0] || '',
endTime: this.query.createdAt[1] || '',
})
this.tableData.loading = false
this.tableData.data = res.content
this.tableData.total = res.totalElements
} catch (error) {
console.log(error);
}
},
//
paginationChange(e) {
this.tableData.page = e - 1
this.tbProductStockDetailStock()
},
handleSizeChange(val) {
this.tableData.size = val
this.tbProductStockDetailStock()
},
//
show(key) {
this.dialogVisible = true
this.key = key
this.tbProductStockDetailStock()
},
// dialog
reset() {
this.tableData.page = 0
this.tableData.data = []
}
}
}
</script>
<style scoped lang="scss"></style>

View File

@ -1,38 +1,101 @@
<template>
<div class="app-container">
<div class="head-container">
<el-row :gutter="20">
<el-col :span="3">
<el-input v-model="query.name" size="small" clearable placeholder="请输入商品名称" style="width: 100%;"
class="filter-item" @keyup.enter.native="getTableData" />
</el-col>
<el-col :span="3">
<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%;">
<el-option :label="item.label" :value="item.typeEnum" v-for="item in typeEnums" :key="item.typeEnum" />
</el-select>
</el-col>
<el-col :span="6">
<el-button type="primary" @click="queryHandle">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
</el-col>
</el-row>
<div class="flex">
<el-input v-model="query.name" size="small" clearable placeholder="请输入商品名称" @keyup.enter.native="getTableData"
style="width: 200px;" />
<el-select v-model="query.categoryId" placeholder="请选择商品分类">
<el-option :label="item.name" :value="item.id" v-for="item in categorys" :key="item.id" />
</el-select>
<el-select v-model="query.typeEnum" placeholder="请选择商品规格">
<el-option :label="item.label" :value="item.typeEnum" v-for="item in typeEnums" :key="item.typeEnum" />
</el-select>
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
<el-button type="primary" @click="queryHandle">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
<el-button @click="showStockWarningHandle">库存预警{{ warnLine }}</el-button>
</div>
</div>
<div class="head-container">
<el-row>
<el-col>
<router-link :to="{ name: 'add_shop' }">
<el-button type="primary" icon="el-icon-plus">添加商品</el-button>
</router-link>
</el-col>
</el-row>
<div class="header_wrap">
<router-link :to="{ name: 'add_shop' }">
<el-button type="primary" icon="el-icon-plus">添加商品</el-button>
</router-link>
<el-select v-model="tableData.sort" placeholder="排序" @change="getTableData">
<el-option value="createdAt,desc" label="创建时间"></el-option>
<el-option value="stockNumber,asc" label="数量由低到高"></el-option>
</el-select>
</div>
</div>
<div class="head-container">
<div class="data_wrap">
<div class="item">
<div class="icon">
<i class="el-icon-pie-chart"></i>
</div>
<div class="info">
<div class="row">
<span>商品种数</span>
<!-- @click="showStockHistory('stockNumber')" -->
<span>{{ tableData.total || 0 }}</span>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<i class="el-icon-sort-up"></i>
</div>
<div class="info">
<div class="row">
<span>增加数量:</span>
<span class="link" @click="showStockHistory('addCountNumber')">{{ countInfo.addCountNumber || 0 }}</span>
</div>
<div class="row">
<div class="row">
<span>手动增加:</span>
<span class="link" @click="showStockHistory('addNumber')">{{ countInfo.addNumber || 0 }}</span>
</div>
<div class="line"></div>
<div class="row">
<span>退货</span>
<span class="link" @click="showStockHistory('refundNumber')">{{ countInfo.refundNumber || 0 }}</span>
</div>
</div>
</div>
</div>
<div class="item">
<div class="icon">
<i class="el-icon-sort-down"></i>
</div>
<div class="info">
<div class="row">
<span>减少数量:</span>
<span class="link" @click="showStockHistory('subCountNumber')">{{ countInfo.subCountNumber || 0 }}</span>
</div>
<div class="row">
<div class="row">
<span>手动减少:</span>
<span class="link" @click="showStockHistory('subNumber')">{{ countInfo.subNumber || 0 }}</span>
</div>
<div class="line"></div>
<div class="row">
<span>销售量</span>
<span class="link" @click="showStockHistory('saleNumber')">{{ countInfo.saleNumber || 0 }}</span>
</div>
<div class="line"></div>
<div class="row">
<span>报损</span>
<span class="link" @click="showStockHistory('lossNumber')">{{ countInfo.lossNumber || 0 }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="head-container" id="table_drag">
<el-table ref="table" :data="tableData.data" v-loading="tableData.loading" row-key="id"
<el-table ref="table" :data="tableData.data" v-loading="tableData.loading" row-key="key"
:tree-props="{ children: 'skuList', hasChildren: 'hasChildren' }">
<el-table-column width="50px"></el-table-column>
<el-table-column label="商品信息">
@ -73,11 +136,14 @@
</el-table-column>
<el-table-column label="耗材信息" width="200">
<template v-slot="scope">
<div class="cons_wrap">
<div class="cons_wrap" v-if="scope.row.typeEnum">
<div v-if="scope.row.conInfos && scope.row.conInfos.length">
<span v-for="item in scope.row.conInfos" :key="item.id">{{ item.conName }}</span>
<el-button type="text" @click="showBindCons(scope.row)">
{{ scope.row.conInfos | conInfosFilter }}
<i class="el-icon-edit"></i>
</el-button>
</div>
<el-button type="text" @click="showBindCons(scope.row)">
<el-button v-else type="text" @click="showBindCons(scope.row)">
绑定
<i class="el-icon-edit"></i>
</el-button>
@ -91,15 +157,25 @@
<el-button type="text" icon="el-icon-edit"
v-if="!scope.row.isShowCash && !scope.row.isShowMall">未上架</el-button> -->
<el-switch v-model="scope.row.isGrounding" :active-value="1" :inactive-value="0"
@change="changeGrounding($event, scope.row)"></el-switch>
@change="changeGrounding($event, scope.row, 'grounding')"></el-switch>
</template>
</el-table-column>
<el-table-column label="排序" prop="sort" sortable />
<el-table-column label="售罄">
<template v-slot="scope">
<!-- <el-button type="text" icon="el-icon-edit" v-if="scope.row.isShowCash">收银端</el-button>
<el-button type="text" icon="el-icon-edit" v-if="scope.row.isShowMall">小程序</el-button>
<el-button type="text" icon="el-icon-edit"
v-if="!scope.row.isShowCash && !scope.row.isShowMall">未上架</el-button> -->
<el-switch v-model="scope.row.isPauseSale" :active-value="1" :inactive-value="0"
@change="changeGrounding($event, scope.row, 'pauseSale')"></el-switch>
</template>
</el-table-column>
<!-- <el-table-column label="排序" prop="sort" sortable />
<el-table-column label="更新时间" prop="createdAt" width="150">
<template v-slot="scope">
{{ dayjs(scope.row.createdAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
</el-table-column> -->
<!-- <el-table-column label="设为热门" prop="createdAt">
<template v-slot="scope">
<el-switch v-model="scope.row.isHot" :active-value="1" :inactive-value="0"
@ -113,9 +189,7 @@
style="margin-left: 20px !important;">
<el-button type="text" icon="el-icon-edit">编辑</el-button>
</router-link> -->
<router-link :to="{ path: '/product/add_shop', query: { goods_id: scope.row.id } }">
<el-button type="text" icon="el-icon-edit">编辑</el-button>
</router-link>
<el-button type="text" icon="el-icon-edit" @click="toPath( '/product/add_shop' ,scope.row )">编辑</el-button>
<el-popconfirm title="确定删除吗?" @confirm="delTableHandle([scope.row.id])">
<el-button type="text" icon="el-icon-delete" style="margin-left: 20px !important;"
slot="reference">删除</el-button>
@ -130,12 +204,14 @@
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
</div>
<!-- 绑定耗材 -->
<BindCons ref="bindCons" />
<BindCons ref="bindCons" @refundChange="refundChange" />
<!-- 商品库存记录 -->
<StockHistory ref="stockHistory" :query="query" />
<!-- 编辑售价库存 -->
<el-dialog :title="editorEumn[editorForm.key]" :visible.sync="editorVisable" :show-close="false" width="300px">
<el-form :model="editorForm">
<el-form-item>
<el-input-number v-model="editorForm.value" />
<el-input-number v-model="editorForm.value" :min="0" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -143,6 +219,18 @@
<el-button type="primary" :loading="editorFormLoading" @click="editorConfirmChange"> </el-button>
</span>
</el-dialog>
<!-- 库存预警值 -->
<el-dialog title="修改库存预警" :visible.sync="showStockWarning" :show-close="false" width="300px">
<el-form :model="editorForm">
<el-form-item label="库存预警">
<el-input-number v-model="warnLineValue" :min="0" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="showStockWarning = false"> </el-button>
<el-button type="primary" :loading="warnLineLoading" @click="stockWarnLineConfirm"> </el-button>
</span>
</el-dialog>
</div>
</template>
@ -151,10 +239,14 @@ import Sortable from 'sortablejs'
import dayjs from 'dayjs'
import settings from '@/settings'
import BindCons from './components/bindCons.vue'
import { tbProductListV2, tbShopCategoryGet, tbProductDelete, tbProductIsHot, upProSort, updateProductData } from '@/api/shop'
import StockHistory from './components/stockHistory.vue'
import { tbProductListV2, tbShopCategoryGet, tbProductDelete, tbProductIsHot, upProSort, updateProductData, tbProductStockDetailStockCount, stockWarnLine } from '@/api/shop'
import { hasPermission } from '@/utils/limits.js'
export default {
components: {
BindCons
BindCons,
StockHistory
},
data() {
return {
@ -163,11 +255,13 @@ export default {
productId: '',
name: '',
categoryId: '',
typeEnum: ''
typeEnum: '',
createdAt: []
},
categorys: [],
typeEnums: settings.typeEnum,
tableData: {
sort: 'createdAt,desc',
data: [],
page: 0,
size: 30,
@ -188,7 +282,18 @@ export default {
id: '',
key: '',
value: ''
}
},
countInfo: {},
showStockWarning: false, //
warnLineLoading: false,
warnLine: 0,
warnLineValue: 0
}
},
filters: {
conInfosFilter(arr) {
let newarr = arr.map(item => item.conName)
return newarr.join('、')
}
},
async mounted() {
@ -205,10 +310,84 @@ export default {
this.tableDrag()
})
}
this.tbProductStockDetailStockCount()
},
methods: {
changeGrounding(event, row) {
this.editorForm.key = 'grounding'
//
async toPath ( path , row) {
let res = await hasPermission('允许修改商品');
if ( !res) { return; }
this.$router.push({path: path, query: { goods_id: row.id }})
},
// 线
showStockWarningHandle() {
this.showStockWarning = true
this.warnLineValue = this.warnLine
},
// 线
async stockWarnLineConfirm() {
try {
this.warnLineLoading = true
const res = await stockWarnLine({
shopId: localStorage.getItem('shopId'),
warnLine: this.warnLineValue
})
this.warnLineLoading = false
this.showStockWarning = false
this.$message.success('修改成功')
this.getTableData()
} catch (error) {
this.warnLineLoading = false
console.log(error);
}
},
//
showStockHistory(key) {
this.$refs.stockHistory.show(key)
},
//
async tbProductStockDetailStockCount() {
try {
const res = await tbProductStockDetailStockCount({
shopId: localStorage.getItem('shopId'),
productName: this.query.name,
categoryId: this.query.categoryId,
startTime: this.query.createdAt[0] || '',
endTime: this.query.createdAt[1] || ''
})
this.countInfo = res
} catch (error) {
console.log(error);
}
},
// 退退
refundChange(e) {
let row = this.tableData.data.find(item => item.id == e.id)
if (row.isRefundStock != e.isRefundStock) {
this.editorForm.key = 'refundStock'
this.editorForm.id = e.id
this.editorForm.isSku = !e.typeEnum
this.editorForm.value = e.isRefundStock
this.editorConfirmChange()
}
this.getTableData()
},
async changeGrounding(event, row, key) {
let text;
if (key == 'grounding') { text = "允许上下架商品"}
if (key == 'pauseSale') { text = "允许售罄商品"}
let res = await hasPermission(text);
if ( !res) {
if (key == 'grounding') { row.isGrounding = (event == 0 ? 1 : 0);}
if (key == 'pauseSale') { row.isPauseSale = (event == 0 ? 1 : 0);}
return;
}
this.editorForm.key = key
this.editorForm.id = row.id
this.editorForm.isSku = !row.typeEnum
this.editorForm.value = event
@ -221,7 +400,7 @@ export default {
this.editorFormLoading = true
const res = await updateProductData([this.editorForm])
this.editorFormLoading = false
this.$message.success('修改成功')
// this.$message.success('')
this.editorVisable = false
this.getTableData()
} catch (error) {
@ -229,8 +408,10 @@ export default {
this.editorFormLoading = false
}
},
//
changePrice(type, row) {
//
async changePrice(type, row) {
let res = await hasPermission('允许修改商品库存');
if ( !res) { return; }
this.editorVisable = true
this.editorForm.key = type
this.editorForm.id = row.id
@ -258,6 +439,7 @@ export default {
queryHandle() {
localStorage.setItem('shopIndexQuery', JSON.stringify(this.query))
this.getTableData()
this.tbProductStockDetailStockCount()
},
//
tableDrag() {
@ -302,9 +484,11 @@ export default {
this.query.categoryId = ''
this.query.typeEnum = ''
this.query.productId = ''
this.query.createdAt = []
this.tableData.page = 0
localStorage.setItem('shopIndexQuery', JSON.stringify(this.query))
this.getTableData()
this.tbProductStockDetailStockCount()
},
//
paginationChange(e) {
@ -320,7 +504,7 @@ export default {
}
this.tableData.loading = true
console.log(this.query, '调试2')
// console.log(this.query, '2')
const res = await tbProductListV2({
page: this.tableData.page,
size: this.tableData.size,
@ -328,8 +512,22 @@ export default {
categoryId: this.query.categoryId,
id: this.query.productId,
type: this.query.typeEnum,
shopId: localStorage.getItem('shopId')
shopId: localStorage.getItem('shopId'),
sort: this.tableData.sort,
createdAt: this.query.createdAt
})
this.warnLine = res.warnLine
res.content.map(item => {
item.key = item.id
item.skuList.map(val => {
val.key = `${item.id}-${val.id}`
})
})
console.log(res);
this.tableData.loading = false
this.tableData.data = res.content
this.tableData.total = res.totalElements
@ -369,6 +567,81 @@ export default {
</script>
<style scoped lang="scss">
.header_wrap {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.data_wrap {
display: flex;
justify-content: space-between;
padding: 0 60px;
.item {
display: flex;
align-items: center;
background-color: #F4F9FF;
height: 80px;
padding: 20px;
.icon {
width: 37px;
height: 37px;
border-radius: 50%;
background-color: #D4E9FE;
display: flex;
align-items: center;
justify-content: center;
color: #3F9EFF;
font-size: 20px;
}
.info {
flex: 1;
display: flex;
gap: 14px;
flex-direction: column;
padding-left: 14px;
.row {
display: flex;
align-items: center;
gap: 10px;
font-size: 14px;
.line {
margin: 0 14px;
height: 20px;
border-left: 1px solid #DDDFE6;
}
span {
&.link {
color: #3F9EFF;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
&:first-child {
color: #666;
}
}
}
}
}
}
.cons_wrap {
display: flex;
flex-wrap: wrap;

View File

@ -23,9 +23,11 @@
<el-table-column label="操作" width="200">
<template v-slot="scope">
<el-button type="text" size="mini" round icon="el-icon-edit"
:disabled="ShopId == scope.row.shopId ? false : true"
@click="$refs.addUnitRef.show(scope.row)">编辑</el-button>
<el-popconfirm title="确定删除吗?" @confirm="delHandle([scope.row.id])">
<el-button type="text" size="mini" round icon="el-icon-delete" slot="reference">删除</el-button>
<el-button :disabled="ShopId == scope.row.shopId ? false : true" type="text" size="mini"
round icon="el-icon-delete" slot="reference">删除</el-button>
</el-popconfirm>
</template>
</el-table-column>
@ -33,7 +35,12 @@
</div>
<div class="head-container">
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
@current-change="paginationChange" @size-change="(e) => {
tableData.size = e;
tableData.page = 0;
paginationChange();
}
" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
</div>
</div>
</template>
@ -47,6 +54,7 @@ export default {
},
data() {
return {
ShopId: localStorage.getItem('shopId'),
query: {
blurry: ''
},

View File

@ -70,8 +70,8 @@
员工权限设置
</h3>
<div v-for="item in form.permissions" :key="item.id">
<h4>{{ item.label }}</h4>
<el-checkbox v-for="ele in item.children" :true-label="1" :false-label="0" v-model="ele.hasPermission"
<h4 >{{ item.label }}</h4>
<el-checkbox v-for="ele in item.children" :true-label="1" :style="{color: ele.isImportant==1?'#e66c6d':''}" :false-label="0" v-model="ele.hasPermission"
:key="ele.id" :label="ele.label"></el-checkbox>
</div>
</el-form>

View File

@ -12,9 +12,18 @@
<el-form-item label="支付密码">
<el-input v-model="form.payPassword" placeholder="请输入支付密码"></el-input>
</el-form-item>
<el-form-item label="小程序appid">
<el-input v-model="form.smallAppid" placeholder="请输入小程序appid"></el-input>
<el-form-item label="微信appid">
<el-input v-model="form.smallAppid" placeholder="请输入微信小程序appid"></el-input>
</el-form-item>
<el-form-item label="支付宝appid">
<el-input v-model="form.alipaySmallAppid" placeholder="请输入支付宝小程序appid"></el-input>
</el-form-item>
<!-- <el-form-item label="支付宝商户号">
<el-input v-model="form.alipayAppId" placeholder="请输入支付宝商户号"></el-input>
</el-form-item>
<el-form-item label="支付宝商户密钥">
<el-input v-model="form.alipayAppToken" placeholder="请输入支付宝商户密钥"></el-input>
</el-form-item> -->
<el-form-item label="店铺id">
<el-input v-model="form.storeId" placeholder="请输入店铺id"></el-input>
</el-form-item>
@ -52,7 +61,10 @@ export default ({
status: 1,
appId: '',
smallAppid: '',
storeId: ''
storeId: '',
alipaySmallAppid: '',
alipayAppToken: '',
alipayAppId: ''
}
}
},
@ -94,13 +106,16 @@ export default ({
this.form.status = res.status
this.form.appId = res.appId
this.form.smallAppid = res.smallAppid
this.form.alipaySmallAppid = res.alipaySmallAppid
//this.form.alipayAppToken = res.alipayAppToken
//this.form.alipayAppId = res.alipayAppId
this.form.storeId = res.storeId
this.dialogVisible = true
} catch (error) {
console.log(error)
}
},
show(obj) {
this.dialogVisible = true
if (obj && obj.id) {
this.form.id = obj.merchantId
this.getDetail(obj.merchantId)

View File

@ -1,10 +1,11 @@
<template>
<div class="app-container">
<el-radio-group v-model="tableActive" @change="selectItemChange">
<el-radio-button :label="item.autokey" v-for="item in tableData" :key="item.autokey">
<div class="btn_wraps">
<div class="btn" :class="{ active: tableActive == item.autokey }" v-for="item in tableData"
:key="item.autokey" @click="selectItemChange(item.autokey)">
{{ item.title }}
</el-radio-button>
</el-radio-group>
</div>
</div>
<div class="form">
<div class="preview_wrap">
<div class="phone_wrap">
@ -162,7 +163,7 @@
</div>
<div class="form_item">
<el-upload :headers="headers" class="avatar-uploader" :action="qiNiuUploadApi"
:show-file-list="false" :on-success="handleSuccess">
:show-file-list="false" :on-success="handleSuccess" style="width: 200px;height: 200px;">
<img v-if="selectItem.value" :src="selectItem.value" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
@ -217,6 +218,7 @@ export default {
},
//
selectItemChange(key) {
this.tableActive = key
this.selectItem = { ...this.tableData.find(item => item.autokey == key) }
},
//
@ -237,6 +239,30 @@ export default {
</script>
<style scoped lang="scss">
.btn_wraps {
display: flex;
$color: #40A9FF;
gap: 30px;
.btn {
width: 100px;
height: 40px;
border: 1px solid $color;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 0 4px #40a9ff29;
color: $color;
cursor: pointer;
&.active {
background-color: $color;
color: #fff;
}
}
}
.form {
display: flex;
padding-top: 30px;
@ -608,6 +634,13 @@ export default {
display: flex;
align-items: center;
.avatar {
display: block;
width: 200px;
height: 200px;
object-fit: cover;
}
.title {
flex-shrink: 0;
}

View File

@ -3,10 +3,10 @@
<div>
<el-form ref="form" :model="form" :rules="rules" label-width="140px" label-position="left">
<el-form-item label="门店名称" prop="shopName">
<el-input v-model="form.shopName" placeholder="请输入门店名称" style="width: 500px;"></el-input>
<el-input v-model.trim="form.shopName" placeholder="请输入门店名称" style="width: 500px;"></el-input>
</el-form-item>
<el-form-item label="连锁店扩展店名">
<el-input v-model="form.chainName" placeholder="请输入连锁店扩展店名" style="width: 500px;"></el-input>
<el-input v-model.trim="form.chainName" placeholder="请输入连锁店扩展店名" style="width: 500px;"></el-input>
</el-form-item>
<el-form-item label="门店logo">
<el-image :src="form.logo || require('@/assets/images/upload.png')" fit="contain"
@ -34,7 +34,7 @@
style="width: 80px;height: 80px;" @click="downloadImgHandle(form.smallQrcode)"></el-image>
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" style="width: 500px;"></el-input>
<el-input v-model.trim="form.phone" placeholder="请输入联系电话" style="width: 500px;"></el-input>
</el-form-item>
<!-- <el-form-item label="外卖起送金额">
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
@ -58,7 +58,7 @@
<div style="color: #999;">准确的定位便于用户导航到店铺</div>
</el-form-item>
<el-form-item label="门店详细地址">
<el-input type="textarea" v-model="form.address" placeholder="请输入门店详细地址" style="width: 500px;"></el-input>
<el-input type="textarea" v-model.trim="form.address" placeholder="请输入门店详细地址" style="width: 500px;"></el-input>
</el-form-item>
<el-form-item label="营业时间">
<el-select v-model="form.businessStartDay" placeholder="周几开始">
@ -80,15 +80,15 @@
<el-form-item label="桌位费/位/元">
<el-input-number v-model="form.tableFee" :min="0" />
<!-- <el-checkbox v-model="form.isTableFee" :label="1">免餐位费</el-checkbox> -->
<el-switch v-model="form.isTableFee" :active-value="1" :inactive-value="0" active-text="免餐位费">
<el-switch v-model.trim="form.isTableFee" :active-value="1" :inactive-value="0" active-text="免餐位费">
</el-switch>
</el-form-item>
<el-form-item label="是否开启8折活动">
<el-switch v-model="form.isOpenYhq" active-value="true" inactive-value="false"></el-switch>
<el-switch v-model.trim="form.isOpenYhq" active-value="true" inactive-value="false"></el-switch>
<!-- <div style="color: #999;">是否允许用户在小程序端支付订单</div> -->
</el-form-item>
<el-form-item label="是否开启会员支付">
<el-switch v-model="form.isUseVip" :active-value="1" :inactive-value="0"></el-switch>
<el-switch v-model.trim="form.isUseVip" :active-value="1" :inactive-value="0"></el-switch>
<!-- <div style="color: #999;">是否允许用户在小程序端支付订单</div> -->
</el-form-item>
<!-- <el-form-item label="结算类型">
@ -111,7 +111,7 @@
</el-time-picker>
</el-form-item> -->
<el-form-item label="店铺简介">
<el-input type="textarea" v-model="form.detail" placeholder="请输入店铺简介" style="width: 500px;"></el-input>
<el-input type="textarea" v-model.trim="form.detail" placeholder="请输入店铺简介" style="width: 500px;"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
@ -156,7 +156,8 @@
<el-dialog :visible.sync="showUpload" :close-on-click-modal="false" append-to-body width="500px"
@close="showUpload = false">
<el-upload :before-remove="handleBeforeRemove" :on-success="handleSuccess" :on-error="handleError"
:file-list="fileList" :headers="headers" :action="qiNiuUploadApi" class="upload-demo" multiple>
:file-list="fileList" :headers="headers" :action="qiNiuUploadApi" :limit="1" list-type="picture"
class="upload-demo">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" style="display: block;" class="el-upload__tip">
请勿上传违法文件且文件不超过15M
@ -314,6 +315,12 @@ export default {
message: "提交成功",
type: "success"
});
localStorage.setItem('shopName', this.form.shopName)
localStorage.setItem('logo', this.form.logo)
setTimeout(() => {
location.reload()
}, 1000);
} catch (error) { }
}
});

View File

@ -29,7 +29,7 @@
<el-table-column label="店铺信息" width="200">
<template v-slot="scope">
<div class="shop_info">
<el-image :src="scope.row.coverImg"
<el-image :src="scope.row.logo"
style="width: 50px;height: 50px;border-radius: 4px;background-color: #efefef;">
<div class="img_error" slot="error">
<i class="icon el-icon-document-delete"></i>

View File

@ -1,6 +1,6 @@
<template>
<div class="app-container">
<div class="head-container">
<!-- <div class="head-container">
<el-row :gutter="20">
<el-col :span="3">
店铺推送 <el-switch v-model="alldata.allState" :active-value="1" :inactive-value="0"
@ -19,7 +19,24 @@
@change="changeEvent(alldata.stockState, 0)"></el-switch>
</el-col>
</el-row>
</div>
</div> -->
<!-- 查看图片 -->
<el-button v-if="url" type="primary" @click="dialogVisible = true" style="margin-bottom: 28px;">订阅消息</el-button>
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
<div style="width: 100%;text-align: center;">
<el-image style="width: 200px; height: 200px;" :src="url"></el-image>
</div>
<div style="text-align: center;">
使用微信扫描二维码绑定订阅消息
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="downloadUrl">下载</el-button>
</span>
</el-dialog>
<div class="head-container" id="table_drag">
<el-table ref="table" :data="tableData.data" v-loading="tableData.loading" row-key="id">
<el-table-column label="头像">
@ -70,7 +87,7 @@
</template>
<script>
import { msgall, msginfo, shopState, state, delmsg } from '@/api/notifications'
import { msgall, msginfo, shopState, state, delmsg, subQrCode } from '@/api/notifications'
export default {
data() {
return {
@ -87,14 +104,37 @@ export default {
conState: 0,
opeState: 0,
stockState: 0,
}
},
url: '',
dialogVisible: false
}
},
mounted() {
this.getTableData()
this.getlist()
this.getsubQrCode()
},
methods: {
downloadUrl() {
let link = document.createElement("a");
//a
link.style.display = "none";
//a
link.href = this.url;
document.body.appendChild(link);
//abody
link.click();
//a
this.dialogVisible = false
},
//
async getsubQrCode() {
let res = await subQrCode({
shopId: localStorage.getItem('shopId')
})
this.url = res
},
async getlist() {
let res = await state({
shopId: localStorage.getItem('shopId'),

View File

@ -217,6 +217,8 @@
<script>
import { queryAllShopUser, queryAllShopInfo, midfiyAccount, tbShopUseredit, queryShopUserFlow } from "@/api/shop";
import dayjs from "dayjs";
import { hasPermission } from '@/utils/limits.js'
let cacheData = {};
export default {
data() {
@ -321,14 +323,18 @@ export default {
this.$message.success('修改成功')
this.getTableData();
},
editPop(d) {
async editPop(d) {
let res = await hasPermission('允许修改会员余额');
if ( !res) { return; }
this.dialogVisible = true
this.userinfo.nickName = d.nickName
this.userinfo.amounts = d.amount
this.userinfo.id = d.id
this.userinfo.amount = ""
},
edituser(d) {
async edituser(d) {
let res = await hasPermission('允许管理会员信息');
if ( !res) { return; }
let obj = { ...d }
if (d.sex == '男') {
obj.sex = '1'