Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 81b15c1afe | |||
| 3159d0b459 | |||
| 5ea9e7951f | |||
| 7d9e42ddef | |||
| 0998c30b1a | |||
| 87d084dfed | |||
| d0f69f9eb9 | |||
| 273e20cccc | |||
| bf60ee88e2 | |||
| 799ee9a5b5 | |||
| 0c795bee95 | |||
| 51f0c8233d | |||
| 08e7939a9f | |||
| 43d33bdfe1 | |||
| 435ca0ab6e | |||
| 889919f2fc | |||
| 36f24888ba | |||
| b31f6494b5 | |||
| 259aec07cd | |||
| 640e3bb941 | |||
| 122b979045 | |||
| 966ef627bb | |||
| 26425e7f57 | |||
| 6e62895adb | |||
| 6b83cf4c84 |
@@ -1,7 +1,11 @@
|
||||
ENV = 'development'
|
||||
|
||||
# 接口地址
|
||||
VUE_APP_BASE_API = 'http://192.168.2.128:8000'
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.128:8000' // 刘一帆
|
||||
# VUE_APP_BASE_API = 'https://405465h7n2.vicp.fun ' // 公司测试
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.96:8000' // 阿伟
|
||||
VUE_APP_BASE_API = 'https://cashieradmin.sxczgkj.cn'
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.16:8000'
|
||||
VUE_APP_WS_API = 'ws://192.168.2.128:8000'
|
||||
|
||||
# 是否启用 babel-plugin-dynamic-import-node插件
|
||||
|
||||
@@ -2,6 +2,7 @@ ENV = 'production'
|
||||
|
||||
# 如果使用 Nginx 代理后端接口,那么此处需要改为 '/',文件查看 Docker 部署篇,Nginx 配置
|
||||
# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http
|
||||
VUE_APP_BASE_API = 'api'
|
||||
VUE_APP_BASE_API = 'https://cashieradmin.sxczgkj.cn'
|
||||
# VUE_APP_BASE_API = 'http://192.168.2.98:8000'
|
||||
# 如果接口是 http 形式, wss 需要改为 ws
|
||||
VUE_APP_WS_API = 'wss://123.56.110.252
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"svgo": "svgo -f src/assets/icons/svg --config=src/assets/icons/svgo.yml",
|
||||
"new": "plop",
|
||||
"dev_t": "set NODE_OPTIONS=\"--openssl-legacy-provider\" & npm run dev\n"
|
||||
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -29,6 +28,7 @@
|
||||
"clipboard": "2.0.4",
|
||||
"codemirror": "^5.49.2",
|
||||
"core-js": "^2.6.12",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^4.2.1",
|
||||
"echarts-wordcloud": "^1.1.3",
|
||||
"element-ui": "^2.15.8",
|
||||
@@ -47,11 +47,13 @@
|
||||
"screenfull": "4.2.0",
|
||||
"sortablejs": "1.8.4",
|
||||
"vue": "^2.6.14",
|
||||
"vue-amap": "^0.5.10",
|
||||
"vue-clipboard2": "^0.3.3",
|
||||
"vue-count-to": "^1.0.13",
|
||||
"vue-cropper": "0.4.9",
|
||||
"vue-echarts": "^5.0.0-beta.0",
|
||||
"vue-ele-upload-image": "^2.0.12",
|
||||
"vue-image-crop-upload": "^2.5.0",
|
||||
"vue-image-crop-upload": "^3.0.3",
|
||||
"vue-material": "^1.0.0-beta-15",
|
||||
"vue-router": "3.0.2",
|
||||
"vue-splitpane": "1.0.4",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 17 KiB |
@@ -7,6 +7,11 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= webpackConfig.name %></title>
|
||||
<script type="text/javascript">
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: "0547b69252ef0ed14e11f5c4ac152f07",
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
122
src/App.vue
122
src/App.vue
@@ -9,3 +9,125 @@ export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/*定义滚动条高宽及背景
|
||||
高宽分别对应横竖滚动条的尺寸*/
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
/*定义滚动条轨道
|
||||
内阴影+圆角*/
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
/*定义滑块
|
||||
内阴影+圆角*/
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: #d3d3d3;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.img_error {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.icon {
|
||||
font-size: 20px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.filter_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.shop_type_box {
|
||||
display: flex;
|
||||
|
||||
&.disabled {
|
||||
.item {
|
||||
background-color: #f9f9f9;
|
||||
|
||||
&:hover {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: #ececec;
|
||||
}
|
||||
|
||||
.active_dot {
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
.s_title {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
$borderColor: #1890FF;
|
||||
margin-right: 14px;
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 4px;
|
||||
padding: 6px 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: $borderColor;
|
||||
|
||||
.active_dot {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.active_dot {
|
||||
$size: 26px;
|
||||
background-color: $borderColor;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: $size;
|
||||
height: $size;
|
||||
clip-path: polygon(100% 0, 0 0, 100% 100%);
|
||||
display: none;
|
||||
justify-content: flex-end;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.s_title {
|
||||
font-weight: bold;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.intro {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
32
src/api/devices.js
Normal file
32
src/api/devices.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 增加打印机
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachine(data, method = 'post') {
|
||||
return request({
|
||||
url: '/api/tbPrintMachine',
|
||||
method: method,
|
||||
data: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印机列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachineGet(params) {
|
||||
return request({
|
||||
url: '/api/tbPrintMachine',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: '',
|
||||
...params
|
||||
}
|
||||
})
|
||||
}
|
||||
92
src/api/home.js
Normal file
92
src/api/home.js
Normal file
@@ -0,0 +1,92 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 汇总数据
|
||||
* @returns
|
||||
*/
|
||||
export function summaryGet() {
|
||||
return request({
|
||||
url: '/api/summary',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日数据
|
||||
* @returns
|
||||
*/
|
||||
export function summaryTodayGet() {
|
||||
return request({
|
||||
url: '/api/summary/today',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日数据
|
||||
* @returns
|
||||
*/
|
||||
export function summaryDateGet(day) {
|
||||
return request({
|
||||
url: '/api/summary/date',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 销售额柱状图
|
||||
* @returns
|
||||
*/
|
||||
export function dateAmount(day) {
|
||||
return request({
|
||||
url: '/api/summary/dateAmount',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品销售排行
|
||||
* @returns
|
||||
*/
|
||||
export function dateProduct(day, page, size) {
|
||||
return request({
|
||||
url: '/api/summary/dateProduct',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day,
|
||||
page: page,
|
||||
size: size
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付类型占比
|
||||
* @returns
|
||||
*/
|
||||
export function datePayType(day) {
|
||||
return request({
|
||||
url: '/api/summary/datePayType',
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
day: day
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
146
src/api/invoicing.js
Normal file
146
src/api/invoicing.js
Normal file
@@ -0,0 +1,146 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductGet(params) {
|
||||
return request({
|
||||
url: '/api/tbProduct',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 进销存类型字典
|
||||
* @returns
|
||||
*/
|
||||
export function dictDetail(params) {
|
||||
return request({
|
||||
url: `/api/dictDetail`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 库存记录列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductStockDetail(data) {
|
||||
return request({
|
||||
url: `/api/tbProductStockDetail/stock`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 变动数量
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductStockDetailSum(params) {
|
||||
return request({
|
||||
url: `/api/tbProductStockDetail/sum`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 供应商列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPurveyorGet(params) {
|
||||
return request({
|
||||
url: `/api/tbShopPurveyor`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加供应商
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPurveyor(data, method = 'post') {
|
||||
return request({
|
||||
url: `/api/tbShopPurveyor`,
|
||||
method: method,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 进货/退货账目
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPurveyorTransactGet(params) {
|
||||
return request({
|
||||
url: `/api/tbShopPurveyorTransact`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 进货账目详情
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPurveyorTransactInfo(data) {
|
||||
return request({
|
||||
url: `/api/tbShopPurveyorTransact/info`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 进货账目汇总(单一供应商)
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPurveyorTransactSum(params) {
|
||||
return request({
|
||||
url: `/api/tbShopPurveyorTransact/sum`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作记录
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductStockOperateList(data) {
|
||||
return request({
|
||||
url: `/api/tbProductStockOperate/list`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作记录详情
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductStockOperateDetail(id) {
|
||||
return request({
|
||||
url: `/api/tbProductStockOperate/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作出库/入库
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductStockOperateOutAndOn(data) {
|
||||
return request({
|
||||
url: `/api/tbProductStockOperate/outAndOn`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
61
src/api/order.js
Normal file
61
src/api/order.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 查询订单
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function tbOrderInfoData(data) {
|
||||
return request({
|
||||
url: '/api/tbOrderInfo/date',
|
||||
method: 'post',
|
||||
data: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function tbOrderInfoDownload(data) {
|
||||
return request({
|
||||
url: '/api/tbOrderInfo/download',
|
||||
method: 'post',
|
||||
data: {
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
...data
|
||||
},
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Id查询订单
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function tbOrderInfoDetail(id) {
|
||||
return request({
|
||||
url: `/api/tbOrderInfo/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过Id查询订单
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function payCount() {
|
||||
return request({
|
||||
url: `/api/tbOrderInfo/payCount`,
|
||||
method: 'get',
|
||||
params: {
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}
|
||||
})
|
||||
}
|
||||
25
src/api/setting.js
Normal file
25
src/api/setting.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 支付方式
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPayTypeGet(params) {
|
||||
return request({
|
||||
url: '/api/tbShopPayType',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改/增加支付方式
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopPayType(data, method = 'post') {
|
||||
return request({
|
||||
url: '/api/tbShopPayType',
|
||||
method: method,
|
||||
data
|
||||
})
|
||||
}
|
||||
348
src/api/shop.js
348
src/api/shop.js
@@ -11,3 +11,351 @@ export function tbProduct(params) {
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductDelete(data) {
|
||||
return request({
|
||||
url: '/api/tbProduct',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品单位列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopUnit(params) {
|
||||
return request({
|
||||
url: '/api/tbShopUnit',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 店铺基本配置
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopCurrency(shopId) {
|
||||
return request({
|
||||
url: `/api/tbShopCurrency/${shopId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改店铺信息
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopCurrencyPut(data) {
|
||||
return request({
|
||||
url: `/api/tbShopCurrency`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增单位
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopUnitPost(data) {
|
||||
return request({
|
||||
url: `/api/tbShopUnit`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改单位
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopUnitPut(data) {
|
||||
return request({
|
||||
url: `/api/tbShopUnit`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单位
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopUnitDelete(data) {
|
||||
return request({
|
||||
url: `/api/tbShopUnit`,
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 店铺基本配置
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopCurrencyGet(params) {
|
||||
return request({
|
||||
url: `/api/tbShopUnit`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品分类列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopCategoryGet(params) {
|
||||
return request({
|
||||
url: `/api/tbShopCategory`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增、编辑分类/新增、编辑子分类
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopCategoryPost(data, method = 'post') {
|
||||
return request({
|
||||
url: `/api/tbShopCategory`,
|
||||
method: method,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品分类
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopCategoryDelete(data) {
|
||||
return request({
|
||||
url: `/api/tbShopCategory`,
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 规格增加
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductSpecPost(data) {
|
||||
return request({
|
||||
url: `/api/tbProductSpec`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 规格列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductSpecGet(params) {
|
||||
return request({
|
||||
url: `/api/tbProductSpec`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 规格更改
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductSpecPut(data) {
|
||||
return request({
|
||||
url: `/api/tbProductSpec`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除规格
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductSpecDelete(data) {
|
||||
return request({
|
||||
url: `/api/tbProductSpec`,
|
||||
method: 'DELETE',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增分组
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductGroupPost(data) {
|
||||
return request({
|
||||
url: `/api/tbProductGroup`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改分组
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductGroupPut(data) {
|
||||
return request({
|
||||
url: `/api/tbProductGroup`,
|
||||
method: 'PUT',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品分组列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductGroupGet(params) {
|
||||
return request({
|
||||
url: `/api/tbProductGroup`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品列表(根据分组中的商品id)
|
||||
* @returns
|
||||
*/
|
||||
export function productListGet(productGroup) {
|
||||
return request({
|
||||
url: `/api/tbProductGroup/${productGroup}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分组
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductGroupDelete(data) {
|
||||
return request({
|
||||
url: `/api/tbProductGroup`,
|
||||
method: 'DELETE',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductPost(data) {
|
||||
return request({
|
||||
url: `/api/tbProduct`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductPut(data) {
|
||||
return request({
|
||||
url: `/api/tbProduct`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品详情(单个商品)
|
||||
* product 商品id
|
||||
* @returns
|
||||
*/
|
||||
export function tbProductGetDetail(product) {
|
||||
return request({
|
||||
url: `/api/tbProduct/${product}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 店铺列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopInfo(params) {
|
||||
return request({
|
||||
url: `/api/tbShopInfo`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加激活码
|
||||
* @returns
|
||||
*/
|
||||
export function tbMerchantRegisterPost(data) {
|
||||
return request({
|
||||
url: `/api/tbMerchantRegister`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活码列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbMerchantRegisterList(data) {
|
||||
return request({
|
||||
url: `/api/tbMerchantRegister/list`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加/编辑店铺
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopInfoPost(data, method = 'post') {
|
||||
return request({
|
||||
url: `/api/tbShopInfo`,
|
||||
method: method,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情(配置三方支付)
|
||||
* @returns
|
||||
*/
|
||||
export function tbMerchantThirdApply(shopId) {
|
||||
return request({
|
||||
url: `/api/tbMerchantThirdApply/${shopId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改第三方配置
|
||||
* @returns
|
||||
*/
|
||||
export function tbMerchantThirdApplyPut(data) {
|
||||
return request({
|
||||
url: `/api/tbMerchantThirdApply`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
76
src/api/table.js
Normal file
76
src/api/table.js
Normal file
@@ -0,0 +1,76 @@
|
||||
// 桌台管理
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 台桌列表
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopTableGet(params) {
|
||||
return request({
|
||||
url: `/api/tbShopTable`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 区域
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopAreaGet(params) {
|
||||
return request({
|
||||
url: `/api/tbShopArea`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加区域
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopArea(data, method) {
|
||||
return request({
|
||||
url: `/api/tbShopArea`,
|
||||
method: method,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除区域
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopAreaDelete(data) {
|
||||
return request({
|
||||
url: `/api/tbShopArea`,
|
||||
method: 'DELETE',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加台桌
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopTable(data, method) {
|
||||
return request({
|
||||
url: `/api/tbShopTable`,
|
||||
method: method,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除台桌
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopTableDelete(data) {
|
||||
return request({
|
||||
url: `/api/tbShopTable`,
|
||||
method: 'DELETE',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
24
src/api/user.js
Normal file
24
src/api/user.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 用户详情
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopInfo(shopId) {
|
||||
return request({
|
||||
url: `/api/tbShopInfo/${shopId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改店铺信息
|
||||
* @returns
|
||||
*/
|
||||
export function tbShopInfoPut(data) {
|
||||
return request({
|
||||
url: `/api/tbShopInfo`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
BIN
src/assets/images/background_img.jpg
Normal file
BIN
src/assets/images/background_img.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 364 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
BIN
src/assets/images/upload.png
Normal file
BIN
src/assets/images/upload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 934 B |
@@ -1,5 +1,5 @@
|
||||
.head-container {
|
||||
padding-bottom: 10px;
|
||||
padding-bottom: 20px;
|
||||
.filter-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
// base color
|
||||
$blue:#324157;
|
||||
$light-blue:#3A71A8;
|
||||
$red:#C03639;
|
||||
$pink: #E65D6E;
|
||||
$green: #30B08F;
|
||||
$tiffany: #4AB7BD;
|
||||
$yellow:#FEC171;
|
||||
$panGreen: #30B08F;
|
||||
$blue: #324157;
|
||||
$light-blue: #3a71a8;
|
||||
$red: #c03639;
|
||||
$pink: #e65d6e;
|
||||
$green: #30b08f;
|
||||
$tiffany: #4ab7bd;
|
||||
$yellow: #fec171;
|
||||
$panGreen: #30b08f;
|
||||
|
||||
// sidebar
|
||||
$menuText:#bfcbd9;
|
||||
$menuActiveText:#409EFF;
|
||||
$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
|
||||
$menuText: #bfcbd9;
|
||||
$menuActiveText: #409eff;
|
||||
$subMenuActiveText: #f4f4f5; // https://github.com/ElemeFE/element/issues/12951
|
||||
|
||||
$menuBg:#304156;
|
||||
$menuHover:#263445;
|
||||
$menuBg: #333;
|
||||
$menuHover: #444;
|
||||
|
||||
$subMenuBg:#1f2d3d;
|
||||
$subMenuHover:#001528;
|
||||
$subMenuBg: #444;
|
||||
$subMenuHover: #555;
|
||||
|
||||
$sideBarWidth: 205px;
|
||||
|
||||
|
||||
122
src/components/classify/index.vue
Normal file
122
src/components/classify/index.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<el-dialog title="选择分类" :visible.sync="dialogVisible">
|
||||
<div class="list" v-loading="loading">
|
||||
<div class="row" v-for="(item, index) in categorys" :key="item.id">
|
||||
<div class="list_title">{{ item.name }}</div>
|
||||
<div class="item_wrap">
|
||||
<el-button :type="item.active ? 'primary' : ''" @click="selectHandle(item)">全部</el-button>
|
||||
<el-button :type="val.active ? 'primary' : ''" v-for="val in item.childrenList" :key="val.id"
|
||||
@click="selectHandle(val, index)">{{
|
||||
val.name }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopCategoryGet } from '@/api/shop'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
loading: false,
|
||||
categorys: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbShopCategoryGet()
|
||||
},
|
||||
methods: {
|
||||
// 确认选择分类
|
||||
onSubmitHandle() {
|
||||
let categorys = []
|
||||
for (let item of this.categorys) {
|
||||
if (item.active) {
|
||||
categorys.push({
|
||||
name: `${item.name}`,
|
||||
id: item.id
|
||||
})
|
||||
}
|
||||
if (item.childrenList.length) {
|
||||
for (let val of item.childrenList) {
|
||||
if (val.active) {
|
||||
categorys.push({
|
||||
name: `${val.name}`,
|
||||
id: val.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$emit('success', categorys)
|
||||
this.dialogVisible = false
|
||||
},
|
||||
// 选择分类
|
||||
selectHandle(item, index = -1) {
|
||||
console.log(item, index)
|
||||
if (index != -1) {
|
||||
this.categorys[index].active = false
|
||||
} else {
|
||||
item.childrenList.map(item => {
|
||||
item.active = false
|
||||
})
|
||||
}
|
||||
item.active = !item.active
|
||||
},
|
||||
// 获取分类
|
||||
async tbShopCategoryGet() {
|
||||
try {
|
||||
this.loading = true
|
||||
const res = await tbShopCategoryGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: 'sort,desc',
|
||||
page: 0,
|
||||
size: 500
|
||||
})
|
||||
res.content.map(item => {
|
||||
item.active = false
|
||||
item.childrenList.map(item => {
|
||||
item.active = false
|
||||
})
|
||||
})
|
||||
this.categorys = res.content
|
||||
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
show() {
|
||||
this.dialogVisible = true
|
||||
this.tbShopCategoryGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.list {
|
||||
min-height: 200px;
|
||||
|
||||
.row {
|
||||
padding-bottom: 20px;
|
||||
|
||||
.list_title {
|
||||
color: #999;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.item_wrap {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
178
src/components/shopList/index.vue
Normal file
178
src/components/shopList/index.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<el-dialog title="选择商品" :visible.sync="dialogVisible" @open="resetHandle()">
|
||||
<el-form :model="searhForm" inline>
|
||||
<el-form-item>
|
||||
<el-input v-model="searhForm.name" placeholder="商品名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="searhForm.category" placeholder="商品分类">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in categoryList"
|
||||
:key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="head-container">
|
||||
<el-table ref="table" :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
<el-image :src="scope.row.coverImg" style="width: 30px;height: 30px;">
|
||||
<div class="img_error" slot="error">
|
||||
<i class="icon el-icon-document-delete"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售价">
|
||||
<template v-slot="scope">
|
||||
¥{{ scope.row.lowPrice }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="销量/库存">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.realSalesNumber }}/{{ scope.row.stockNumber }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分类" prop="categoryName"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" @size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopCategoryGet, tbProduct } from "@/api/shop";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
searhForm: {
|
||||
name: '',
|
||||
category: ''
|
||||
},
|
||||
categoryList: [],
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: []
|
||||
},
|
||||
goods: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 确定选商品
|
||||
confirmHandle() {
|
||||
let res = this.$refs.table.selection
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.searhForm.name = ''
|
||||
this.searhForm.category = ''
|
||||
this.tableData.page = 0
|
||||
this.tableData.size = 10
|
||||
this.tableData.list = []
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页大小改变
|
||||
sizeChange(e) {
|
||||
this.tableData.size = e
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProduct({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
name: this.searhForm.name,
|
||||
categoryId: this.searhForm.category,
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: 'id',
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
|
||||
if (this.goods.length) {
|
||||
this.$nextTick(() => {
|
||||
this.selection()
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 商品分类
|
||||
async tbShopCategoryGet() {
|
||||
try {
|
||||
const res = await tbShopCategoryGet({
|
||||
page: 0,
|
||||
size: 100,
|
||||
sort: 'id',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.categoryList = res.content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
show(goods) {
|
||||
this.dialogVisible = true
|
||||
if (goods && goods.length) {
|
||||
this.goods = goods
|
||||
} else {
|
||||
this.goods = []
|
||||
}
|
||||
this.resetHandle()
|
||||
this.tbShopCategoryGet()
|
||||
this.getTableData()
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
selection() {
|
||||
this.goods.forEach(row => {
|
||||
this.tableData.list.forEach((item, index) => {
|
||||
if (row.id == item.id) {
|
||||
this.$refs.table.toggleRowSelection(this.tableData.list[index]);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
79
src/components/uploadImg/index.vue
Normal file
79
src/components/uploadImg/index.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload ref="upload" :action="qiNiuUploadApi" :headers="headers" :file-list="fileList" :limit="limit"
|
||||
:list-type="type" :on-preview="handlePictureCardPreview" :multiple="limit > 1" :on-success="handleSuccess"
|
||||
:on-error="handleError" :on-exceed="onExceed" :on-remove="handleRemove">
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible" :z-index="99">
|
||||
<img width="100%" :src="dialogImageUrl" alt="">
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { Notification } from 'element-ui'
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'qiNiuUploadApi'
|
||||
])
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'picture-card'
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogImageUrl: '',
|
||||
dialogVisible: false,
|
||||
fileList: [],
|
||||
files: [],
|
||||
headers: {
|
||||
'Authorization': getToken()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSuccess(response, file, fileList) {
|
||||
// console.log('上传成功', response)
|
||||
this.files = response.data
|
||||
this.$emit('success', response.data)
|
||||
},
|
||||
// 监听上传失败
|
||||
handleError(e, file, fileList) {
|
||||
// console.log(e)
|
||||
const m = JSON.parse(e.message)
|
||||
Notification.error({
|
||||
title: m.message,
|
||||
duration: 5000
|
||||
})
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
this.dialogImageUrl = file.url;
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
onExceed() {
|
||||
this.$notify.error({
|
||||
title: '错误',
|
||||
message: `最多上传${this.limit}张图片`
|
||||
})
|
||||
},
|
||||
handleRemove(file, fileList) {
|
||||
let arr = fileList.map(item => item.url)
|
||||
this.$emit('remove', arr)
|
||||
},
|
||||
clearFiles() {
|
||||
this.$refs.upload.clearFiles()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,39 +1,34 @@
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||
|
||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container"
|
||||
@toggleClick="toggleSideBar" />
|
||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
<!-- <template v-if="device !== 'mobile'">
|
||||
<search id="header-search" class="right-menu-item" />
|
||||
|
||||
<!-- <el-tooltip content="项目文档" effect="dark" placement="bottom">
|
||||
<el-tooltip content="项目文档" effect="dark" placement="bottom">
|
||||
<Doc class="right-menu-item hover-effect" />
|
||||
</el-tooltip> -->
|
||||
|
||||
</el-tooltip>
|
||||
<el-tooltip content="全屏缩放" effect="dark" placement="bottom">
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip content="布局设置" effect="dark" placement="bottom">
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
||||
</template>
|
||||
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||
</template> -->
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar" class="user-avatar">
|
||||
<i class="el-icon-caret-bottom" />
|
||||
<img :src="logo || Avatar" class="user-avatar">
|
||||
<!-- <i class="el-icon-caret-bottom" /> -->
|
||||
<span class="shop_name">{{ shopName }}</span>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<span style="display:block;" @click="show = true">
|
||||
<!-- <span style="display:block;" @click="show = true">
|
||||
<el-dropdown-item>
|
||||
布局设置
|
||||
</el-dropdown-item>
|
||||
</span>
|
||||
<router-link to="/user/center">
|
||||
</span> -->
|
||||
<router-link to="/shop/shop/shop_configuration">
|
||||
<el-dropdown-item>
|
||||
个人中心
|
||||
</el-dropdown-item>
|
||||
@@ -71,7 +66,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
Avatar: Avatar,
|
||||
dialogVisible: false
|
||||
dialogVisible: false,
|
||||
logo: localStorage.getItem('logo'),
|
||||
shopName: localStorage.getItem('shopName')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -103,6 +100,7 @@ export default {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
localStorage.setItem('logoutHandle', true)
|
||||
this.logout()
|
||||
})
|
||||
},
|
||||
@@ -121,7 +119,7 @@ export default {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
|
||||
|
||||
.hamburger-container {
|
||||
line-height: 46px;
|
||||
@@ -129,7 +127,7 @@ export default {
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
transition: background .3s;
|
||||
-webkit-tap-highlight-color:transparent;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .025)
|
||||
@@ -173,17 +171,18 @@ export default {
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
margin-right: 30px;
|
||||
margin-right: 10px;
|
||||
|
||||
.avatar-wrapper {
|
||||
margin-top: 5px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.user-avatar {
|
||||
cursor: pointer;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.el-icon-caret-bottom {
|
||||
@@ -193,6 +192,11 @@ export default {
|
||||
top: 25px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.shop_name {
|
||||
font-size: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
src/main.js
13
src/main.js
@@ -27,6 +27,11 @@ import './router/index' // permission control
|
||||
|
||||
// 全局引入
|
||||
import EleUploadImage from 'vue-ele-upload-image'
|
||||
import VueAMap from 'vue-amap';
|
||||
|
||||
import VueClipboard from 'vue-clipboard2'
|
||||
|
||||
|
||||
Vue.component(EleUploadImage.name, EleUploadImage)
|
||||
Vue.component('Editor', Editor)
|
||||
|
||||
@@ -36,6 +41,14 @@ Vue.use(dict)
|
||||
Vue.use(Element, {
|
||||
size: Cookies.get('size') || 'small' // set element-ui default size
|
||||
})
|
||||
Vue.use(VueAMap)
|
||||
Vue.use(VueClipboard)
|
||||
|
||||
VueAMap.initAMapApiLoader({
|
||||
key: '6033c97e67bf2e9ceac306e1a3fa35f8',
|
||||
// securityJsCode: '0547b69252ef0ed14e11f5c4ac152f07',
|
||||
plugin: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor']
|
||||
})
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ router.beforeEach((to, from, next) => {
|
||||
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
|
||||
next()
|
||||
} else {
|
||||
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||
next(localStorage.getItem('logoutHandle') ? '/login' : `/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||
NProgress.done()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import Layout from '../layout/index'
|
||||
Vue.use(Router)
|
||||
|
||||
export const constantRouterMap = [
|
||||
{ path: '/login',
|
||||
{
|
||||
path: '/login',
|
||||
meta: { title: '登录', noCache: true },
|
||||
component: (resolve) => require(['@/views/login'], resolve),
|
||||
hidden: true
|
||||
@@ -34,13 +35,23 @@ export const constantRouterMap = [
|
||||
{
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/dashboard',
|
||||
redirect: '/data_statistics',
|
||||
meta: {
|
||||
title: '数据统计',
|
||||
icon: 'index'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: (resolve) => require(['@/views/home'], resolve),
|
||||
name: 'Dashboard',
|
||||
meta: { title: '首页', icon: 'index', affix: true, noCache: true }
|
||||
path: 'data_statistics',
|
||||
component: (resolve) => require(['@/views/home/home'], resolve),
|
||||
name: 'data_statistics',
|
||||
meta: { title: '数据统计' }
|
||||
},
|
||||
{
|
||||
path: 'data_forms',
|
||||
component: (resolve) => require(['@/views/home/data_forms'], resolve),
|
||||
name: 'data_forms',
|
||||
meta: { title: '数据报表' }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -42,5 +42,32 @@ module.exports = {
|
||||
/**
|
||||
* 备案号
|
||||
*/
|
||||
caseNumber: '陕ICP备2022008069号'
|
||||
caseNumber: '陕ICP备2022008069号',
|
||||
typeEnum: [
|
||||
{
|
||||
label: '计量商品',
|
||||
intro: '单价购买',
|
||||
typeEnum: 'normal'
|
||||
},
|
||||
{
|
||||
label: '多规格',
|
||||
intro: '多种不同规格',
|
||||
typeEnum: 'sku'
|
||||
},
|
||||
{
|
||||
label: '套餐商品',
|
||||
intro: '选职多种组合',
|
||||
typeEnum: 'group'
|
||||
},
|
||||
{
|
||||
label: '称重商品',
|
||||
intro: '按重量售卖',
|
||||
typeEnum: 'weight'
|
||||
},
|
||||
{
|
||||
label: '时价商品',
|
||||
intro: '收银端可更改价格',
|
||||
typeEnum: 'currentPrice'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ const state = {
|
||||
withoutAnimation: false
|
||||
},
|
||||
device: 'desktop',
|
||||
size: Cookies.get('size') || 'small'
|
||||
size: Cookies.get('size') || 'default'
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
|
||||
@@ -11,6 +11,10 @@ const user = {
|
||||
},
|
||||
|
||||
mutations: {
|
||||
// 是否为手动退出登录
|
||||
SD_LOGOUT: (state, f) => {
|
||||
state.sdLogout = f
|
||||
},
|
||||
SET_TOKEN: (state, token) => {
|
||||
state.token = token
|
||||
},
|
||||
@@ -31,6 +35,11 @@ const user = {
|
||||
const rememberMe = userInfo.rememberMe
|
||||
return new Promise((resolve, reject) => {
|
||||
login(userInfo.username, userInfo.password, userInfo.code, userInfo.uuid).then(res => {
|
||||
// console.log('登录成功后返回===', res)
|
||||
localStorage.setItem('logoutHandle', false)
|
||||
localStorage.setItem('shopId', res.shopId)
|
||||
localStorage.setItem('shopName', res.shopName)
|
||||
localStorage.setItem('logo', res.logo)
|
||||
setToken(res.token, rememberMe)
|
||||
commit('SET_TOKEN', res.token)
|
||||
setUserInfo(res.user, commit)
|
||||
|
||||
@@ -39,7 +39,7 @@ export function parseTime(time, cFormat) {
|
||||
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key]
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
|
||||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
|
||||
if (result.length > 0 && value < 10) {
|
||||
value = '0' + value
|
||||
}
|
||||
@@ -249,7 +249,7 @@ export function getTime(type) {
|
||||
export function debounce(func, wait, immediate) {
|
||||
let timeout, args, context, timestamp, result
|
||||
|
||||
const later = function() {
|
||||
const later = function () {
|
||||
// 据上一次触发时间间隔
|
||||
const last = +new Date() - timestamp
|
||||
|
||||
@@ -266,7 +266,7 @@ export function debounce(func, wait, immediate) {
|
||||
}
|
||||
}
|
||||
|
||||
return function(...args) {
|
||||
return function (...args) {
|
||||
context = this
|
||||
timestamp = +new Date()
|
||||
const callNow = immediate && !timeout
|
||||
@@ -386,3 +386,15 @@ export function downloadFile(obj, name, suffix) {
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成范围随机数
|
||||
* @param {Object} Min
|
||||
* @param {Object} Max
|
||||
*/
|
||||
export function RandomNumBoth(Max, Min = 0) {
|
||||
var Range = Max - Min;
|
||||
var Rand = Math.random();
|
||||
var num = Min + Math.round(Rand * Range); //四舍五入
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import Cookies from 'js-cookie'
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/', // api 的 base_url
|
||||
// baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/',
|
||||
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
|
||||
timeout: Config.timeout // 请求超时时间
|
||||
})
|
||||
|
||||
@@ -19,9 +20,9 @@ service.interceptors.request.use(
|
||||
config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
config.headers['Content-Type'] = 'application/json'
|
||||
config.headers['loginName']='admin'
|
||||
config.headers['token']='eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyVHlwZSI6Ik1HIiwiZXhwIjoxNjkwMTgwNzE2LCJ1c2VySWQiOiIyNDQiLCJpYXQiOjE2ODg3MDk0ODcsImxvZ2luTmFtZSI6ImFkbWluIn0.lqxxvv2-FcecQngMBorz4MpkB3mIJQDG-IUULQyV-KQ'
|
||||
config.headers["userId"]='244'
|
||||
config.headers['loginName'] = 'admin'
|
||||
config.headers['token'] = 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyVHlwZSI6Ik1HIiwiZXhwIjoxNjkwMTgwNzE2LCJ1c2VySWQiOiIyNDQiLCJpYXQiOjE2ODg3MDk0ODcsImxvZ2luTmFtZSI6ImFkbWluIn0.lqxxvv2-FcecQngMBorz4MpkB3mIJQDG-IUULQyV-KQ'
|
||||
config.headers["userId"] = '244'
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
@@ -39,7 +40,7 @@ service.interceptors.response.use(
|
||||
if (error.response.data instanceof Blob && error.response.data.type.toLowerCase().indexOf('json') !== -1) {
|
||||
const reader = new FileReader()
|
||||
reader.readAsText(error.response.data, 'utf-8')
|
||||
reader.onload = function(e) {
|
||||
reader.onload = function (e) {
|
||||
const errorMsg = JSON.parse(reader.result).message
|
||||
Notification.error({
|
||||
title: errorMsg,
|
||||
|
||||
166
src/views/devices/components/addDevice.vue
Normal file
166
src/views/devices/components/addDevice.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog title="添加云打印机" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="层级">
|
||||
<el-select v-model="form.contentType">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in devices"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备尺寸">
|
||||
<el-radio-group v-model="form.config.width">
|
||||
<el-radio-button label="58">58mm</el-radio-button>
|
||||
<el-radio-button label="80">80mm</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入设备名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备号" prop="address">
|
||||
<el-input v-model="form.address" placeholder="请输入设备号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="打印份数">
|
||||
<el-select v-model="form.config.printerNum">
|
||||
<el-option :label="item" :value="item" v-for="item in 4" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="出品模式">
|
||||
<el-select v-model="form.config.model">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in models"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打印类型">
|
||||
<el-select v-model="form.subType">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in subTypes"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="尾部留空">
|
||||
<el-radio-group v-model="form.config.feet">
|
||||
<el-radio-button :label="`${item}`" v-for="item in feets" :key="item">{{ item
|
||||
}}行</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="自动切刀">
|
||||
<el-switch v-model="form.config.autoCut" :active-value="0" :inactive-value="1"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sort" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类">
|
||||
<div style="cursor: pointer;" @click="$refs.classify.show()">
|
||||
<span style="color: #409eff;" v-for="item in form.config.categoryList">{{ item.name }},</span>
|
||||
<span style="color: #e65d6e;" v-if="!form.config.categoryList.length">请选择分类</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<classify ref="classify" @success="classifySuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { devices, models, subTypes } from '../devices'
|
||||
import { tbPrintMachine } from '@/api/devices'
|
||||
import classify from '@/components/classify'
|
||||
|
||||
export default {
|
||||
components: { classify },
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
devices,
|
||||
models,
|
||||
subTypes,
|
||||
feets: [0, 1, 2, 3, 4, 5, 8],
|
||||
loading: false,
|
||||
form: {
|
||||
id: '',
|
||||
contentType: '',
|
||||
config: {
|
||||
width: '80mm', // 设备尺寸
|
||||
printerNum: 1, //打印份数
|
||||
categoryList: '', // 商品分类
|
||||
model: 'normal', // 出品模式,
|
||||
feet: '0',
|
||||
autoCut: 0
|
||||
},
|
||||
name: '',
|
||||
subType: 'kitchen', // 打印类型
|
||||
status: 0,
|
||||
sort: ''
|
||||
},
|
||||
resetForm: '',
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
address: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form }
|
||||
},
|
||||
methods: {
|
||||
// 确认选择商品分类
|
||||
classifySuccess(e) {
|
||||
this.form.config.categoryList = e
|
||||
},
|
||||
onSubmitHandle() {
|
||||
console.log(this.form)
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.loading = true
|
||||
this.form.shopId = localStorage.getItem('shopId')
|
||||
let res = await tbPrintMachine(this.form, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form = { ...obj }
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form = { ...this.resetForm }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
44
src/views/devices/devices.js
Normal file
44
src/views/devices/devices.js
Normal file
@@ -0,0 +1,44 @@
|
||||
export const devices = [
|
||||
{
|
||||
value: 'printer',
|
||||
name: '本地'
|
||||
},
|
||||
{
|
||||
value: 'yxyPrinter',
|
||||
name: '云想印'
|
||||
},
|
||||
{
|
||||
value: 'fePrinter',
|
||||
name: '飞鹅'
|
||||
}
|
||||
]
|
||||
|
||||
export const models = [
|
||||
{
|
||||
value: 'normal',
|
||||
name: '普通出单'
|
||||
},
|
||||
{
|
||||
value: 'one',
|
||||
name: '一菜一品'
|
||||
},
|
||||
{
|
||||
value: 'category',
|
||||
name: '分类出单'
|
||||
}
|
||||
]
|
||||
|
||||
export const subTypes = [
|
||||
{
|
||||
value: 'kitchen',
|
||||
name: '出品'
|
||||
},
|
||||
{
|
||||
value: 'cash',
|
||||
name: '小票'
|
||||
},
|
||||
{
|
||||
value: 'label',
|
||||
name: '标签'
|
||||
}
|
||||
]
|
||||
159
src/views/devices/devices_list.vue
Normal file
159
src/views/devices/devices_list.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-form :model="query" inline>
|
||||
<el-form-item>
|
||||
<el-input v-model="query.name" placeholder="请输入设备名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="query.type" placeholder="请选择设备类型">
|
||||
<el-option :label="item.name" :value="item.value" v-for="item in devices" :key="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addDevice.show()">
|
||||
添加云打印机
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.data" v-loading="tableData.loading">
|
||||
<el-table-column label="设备名称" prop="name"></el-table-column>
|
||||
<el-table-column label="设备号" prop="address"></el-table-column>
|
||||
<el-table-column label="品牌" prop="contentType">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.contentType | devicesName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出品模式" prop="config.model">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.config.model | modelsName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="打印类型" prop="subType">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.subType | subTypesName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" sortable prop="createdAt">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.createdAt | timeFilter }}
|
||||
</template>
|
||||
</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"
|
||||
@change="statusChange($event, scope.row)"></el-switch>
|
||||
</template>
|
||||
</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 type="text" icon="el-icon-delete" style="margin-left: 20px !important;"
|
||||
slot="reference">删除</el-button>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total"></el-pagination>
|
||||
</div>
|
||||
<addDevice ref="addDevice" @success="getTableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { devices, models, subTypes } from './devices'
|
||||
import addDevice from './components/addDevice'
|
||||
import { tbPrintMachineGet, tbPrintMachine } from '@/api/devices'
|
||||
import dayjs from 'dayjs'
|
||||
export default {
|
||||
components: {
|
||||
addDevice
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
name: '',
|
||||
type: ''
|
||||
},
|
||||
devices,
|
||||
tableData: {
|
||||
data: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
devicesName(value) {
|
||||
return devices.find(item => item.value == value).name
|
||||
},
|
||||
modelsName(value) {
|
||||
return models.find(item => item.value == value).name
|
||||
},
|
||||
subTypesName(value) {
|
||||
return subTypes.find(item => item.value == value).name
|
||||
},
|
||||
timeFilter(s) {
|
||||
return dayjs(s).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 切换状态
|
||||
async statusChange(e, row) {
|
||||
try {
|
||||
this.tableData.loading = true
|
||||
const data = { ...row }
|
||||
data.status = e
|
||||
await tbPrintMachine(data, 'put')
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.tableData.loading = false
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.type = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbPrintMachineGet({
|
||||
name: this.query.name,
|
||||
contentType: this.query.type
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.data = res
|
||||
this.tableData.total = res.length
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,115 +0,0 @@
|
||||
<template>
|
||||
<el-image :src="this.shouye"></el-image>
|
||||
<!-- <div class="dashboard-container">
|
||||
<div class="dashboard-editor-container">
|
||||
<github-corner class="github-corner" />
|
||||
|
||||
<panel-group @handleSetLineChartData="handleSetLineChartData" />
|
||||
|
||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
||||
<line-chart :chart-data="lineChartData" />
|
||||
</el-row>
|
||||
<el-row :gutter="32">
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<radar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<pie-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<bar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GithubCorner from '@/components/GithubCorner'
|
||||
import PanelGroup from './dashboard/PanelGroup'
|
||||
import LineChart from './dashboard/LineChart'
|
||||
import RadarChart from '@/components/Echarts/RadarChart'
|
||||
import PieChart from '@/components/Echarts/PieChart'
|
||||
import BarChart from '@/components/Echarts/BarChart'
|
||||
import shouye from '@/assets/images/background.webp'
|
||||
|
||||
|
||||
const lineChartData = {
|
||||
newVisitis: {
|
||||
expectedData: [100, 120, 161, 134, 105, 160, 165],
|
||||
actualData: [120, 82, 91, 154, 162, 140, 145]
|
||||
},
|
||||
messages: {
|
||||
expectedData: [200, 192, 120, 144, 160, 130, 140],
|
||||
actualData: [180, 160, 151, 106, 145, 150, 130]
|
||||
},
|
||||
purchases: {
|
||||
expectedData: [80, 100, 121, 104, 105, 90, 100],
|
||||
actualData: [120, 90, 100, 138, 142, 130, 130]
|
||||
},
|
||||
shoppings: {
|
||||
expectedData: [130, 140, 141, 142, 145, 150, 160],
|
||||
actualData: [120, 82, 91, 154, 162, 140, 130]
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'Dashboard',
|
||||
components: {
|
||||
GithubCorner,
|
||||
PanelGroup,
|
||||
LineChart,
|
||||
RadarChart,
|
||||
PieChart,
|
||||
BarChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shouye:shouye,
|
||||
lineChartData: lineChartData.newVisitis
|
||||
|
||||
}
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
handleSetLineChartData(type) {
|
||||
this.lineChartData = lineChartData[type]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.dashboard-editor-container {
|
||||
padding: 32px;
|
||||
background-color: rgb(240, 242, 245);
|
||||
position: relative;
|
||||
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.chart-wrapper {
|
||||
background: #fff;
|
||||
padding: 16px 16px 0;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:1024px) {
|
||||
.chart-wrapper {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
3
src/views/home/data_forms.vue
Normal file
3
src/views/home/data_forms.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>数据报表</div>
|
||||
</template>
|
||||
828
src/views/home/home.vue
Normal file
828
src/views/home/home.vue
Normal file
@@ -0,0 +1,828 @@
|
||||
<template>
|
||||
<div class="app-container" style="padding-bottom: 100px;">
|
||||
<div class="card_wrap">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">总销售额</div>
|
||||
<el-tooltip effect="dark" content="订单支付金额" placement="top">
|
||||
<i class="icon el-icon-warning-outline"></i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="number">{{ topData.totalSales || 0 }}</div>
|
||||
<div class="row">平均每单{{ topData.averageSales || 0 }}</div>
|
||||
<div class="row">今日销售额{{ topData.totalSalesToday || 0 }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">支付笔数</div>
|
||||
</div>
|
||||
<div class="number">{{ topData.paymentsNumber }}</div>
|
||||
<div class="row" ref="cardPayChart" style="padding-bottom: 2px;"></div>
|
||||
<div class="row">今日支付笔数{{ topData.paymentsNumberToday || 0 }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">访问量</div>
|
||||
</div>
|
||||
<div class="number">{{ topData.totalVisits }}</div>
|
||||
<div class="row" ref="cardCountChart"></div>
|
||||
<div class="row">
|
||||
<div class="dot"></div> 今日访问 {{ topData.totalVisitsToday || 0 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="card_title">用户数</div>
|
||||
</div>
|
||||
<div class="number">{{ topData.totalUser }}</div>
|
||||
<div class="row" ref="cardUserChart" style="padding-bottom: 2px;"></div>
|
||||
<div class="row">今日新增 {{ topData.userToday || 0 }} <i class="icon el-icon-caret-top"></i> </div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 销售额 -->
|
||||
<div class="chart_wrap">
|
||||
<div class="item">
|
||||
<div class="header">
|
||||
<div class="tab_wrap">
|
||||
<div class="item active">销售额</div>
|
||||
</div>
|
||||
<el-radio-group v-model="saleActive" @change="dateAmount">
|
||||
<el-radio-button label="7">近7天</el-radio-button>
|
||||
<el-radio-button label="30">30天</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="chart" ref="saleChart" v-loading="saleLoading" style="height: 400px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart_wrap" style="display: flex;">
|
||||
<!-- 商品销售排行 -->
|
||||
<div class="item">
|
||||
<div class="header">
|
||||
<div class="tab_wrap">
|
||||
<div class="item active">商品销售排行</div>
|
||||
</div>
|
||||
<el-radio-group v-model="saleTableActive" @change="rankChange">
|
||||
<el-radio-button label="7">近7天</el-radio-button>
|
||||
<el-radio-button label="30">30天</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="sale_data">
|
||||
<div class="card">
|
||||
<div class="sale_data_header">
|
||||
<div class="card_title">销售数量</div>
|
||||
</div>
|
||||
<div class="number">{{ productCount }}</div>
|
||||
<div class="product_chart_wrap" ref="productCountChart"></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="sale_data_header">
|
||||
<div class="card_title">销售金额</div>
|
||||
</div>
|
||||
<div class="number">¥{{ productSum }}</div>
|
||||
<div class="product_chart_wrap" ref="productSumChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table">
|
||||
<el-table :data="saleTable" v-loading="saleTableLoading">
|
||||
<el-table-column label="排名" prop="productId"></el-table-column>
|
||||
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
||||
<el-table-column label="数量" prop="productNum"></el-table-column>
|
||||
<el-table-column label="金额" prop="amount"></el-table-column>
|
||||
</el-table>
|
||||
<div class="head-container" style="padding-top: 20px;display: flex;justify-content: flex-end;">
|
||||
<el-pagination :total="saleTableTotal" :page-size="saleTableSize" :current-page="saleTablePage"
|
||||
@current-change="paginationChange" layout="total, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 支付类型占比 -->
|
||||
<div class="item" style="margin-left: 20px;">
|
||||
<div class="header">
|
||||
<div class="tab_wrap">
|
||||
<div class="item active">支付占比类型</div>
|
||||
</div>
|
||||
<el-radio-group v-model="payChartDay" @change="datePayType">
|
||||
<el-radio-button label="7">近7天</el-radio-button>
|
||||
<el-radio-button label="30">30天</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div style="height: 400px;margin-top: 30px;" ref="payChart" v-loading="payChartLoading"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { summaryGet, summaryTodayGet, dateProduct, dateAmount, datePayType, summaryDateGet } from '@/api/home'
|
||||
import echarts from 'echarts'
|
||||
import { debounce } from '@/utils'
|
||||
export default {
|
||||
name: 'home',
|
||||
data() {
|
||||
return {
|
||||
topData: '',
|
||||
saleTab: 'sale',
|
||||
saleActive: '7',
|
||||
cardPayChart: null,
|
||||
cardCountChart: null,
|
||||
cardUserChart: null,
|
||||
saleLoading: false,
|
||||
saleChart: null,
|
||||
payChartDay: '7',
|
||||
payChartLoading: false,
|
||||
payChart: null,
|
||||
chartType: 1,
|
||||
productCount: 0,
|
||||
productSum: 0,
|
||||
saleTableActive: '7',
|
||||
saleTable: [],
|
||||
saleTableLoading: false,
|
||||
saleTablePage: 1,
|
||||
saleTableTotal: 0,
|
||||
saleTableSize: 5,
|
||||
__resizeHandler: null,
|
||||
productCountChart: null,
|
||||
productSumChart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.summaryGet()
|
||||
this.dateAmount()
|
||||
this.dateProduct()
|
||||
this.datePayType()
|
||||
this.summaryDateGet()
|
||||
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.saleChart) {
|
||||
this.saleChart.resize()
|
||||
}
|
||||
if (this.payChart) {
|
||||
this.payChart.resize()
|
||||
}
|
||||
if (this.cardPayChart) {
|
||||
this.cardPayChart.resize()
|
||||
}
|
||||
if (this.cardUserChart) {
|
||||
this.cardUserChart.resize()
|
||||
}
|
||||
if (this.productCountChart) {
|
||||
this.productCountChart.resize()
|
||||
}
|
||||
if (this.productSumChart) {
|
||||
this.productSumChart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
this.initCardUserChart()
|
||||
},
|
||||
methods: {
|
||||
// 初始化支付笔数柱状图
|
||||
initCardPayChart(time = [], data = []) {
|
||||
this.cardPayChart = echarts.init(this.$refs.cardPayChart)
|
||||
this.cardPayChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 0
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: time,
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: data,
|
||||
type: 'bar',
|
||||
barWidth: '30%'
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 初始化访问量柱状图
|
||||
initCardCountChart(time = [], data = []) {
|
||||
this.cardCountChart = echarts.init(this.$refs.cardCountChart)
|
||||
this.cardCountChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 0
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: time,
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: data,
|
||||
type: 'bar',
|
||||
barWidth: '30%'
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 初始化用户数折线图
|
||||
initCardUserChart(time = [], data = []) {
|
||||
this.cardUserChart = echarts.init(this.$refs.cardUserChart)
|
||||
this.cardUserChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 10,
|
||||
x2: 0,
|
||||
y2: 2
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: time,
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: data,
|
||||
type: 'line',
|
||||
symbol: 'none'
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 初始化销售额图标
|
||||
initSaleChart(time, data) {
|
||||
this.saleChart = null
|
||||
this.saleChart = echarts.init(this.$refs.saleChart)
|
||||
this.saleChart.setOption({
|
||||
title: {
|
||||
text: '销售趋势',
|
||||
x: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: time,
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: time.length <= 7 ? 0 : 45,
|
||||
interval: 0,
|
||||
textStyle: {
|
||||
fontSize: '9'
|
||||
}
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: '#ececec'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: data,
|
||||
type: 'bar',
|
||||
barWidth: time.length <= 7 ? '50%' : '30%'
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 初始化销售额图表
|
||||
initPayChart(data) {
|
||||
this.payChart = echarts.init(this.$refs.payChart)
|
||||
this.payChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
color: ['#409eff', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 20
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 获取销售额柱状图数据
|
||||
async dateAmount() {
|
||||
try {
|
||||
this.saleLoading = true
|
||||
const res = await dateAmount(this.saleActive)
|
||||
const data = res.total.map(item => item.amount)
|
||||
const time = res.total.map(item => item.tradeDay)
|
||||
this.initSaleChart(time, data)
|
||||
setTimeout(() => {
|
||||
this.saleLoading = false
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
paginationChange(e) {
|
||||
this.saleTablePage = e
|
||||
this.dateProduct()
|
||||
},
|
||||
// 获取销售额排行表格数据
|
||||
async dateProduct() {
|
||||
try {
|
||||
this.saleTableLoading = true
|
||||
const res = await dateProduct(this.saleTableActive, this.saleTablePage, this.saleTableSize)
|
||||
this.saleTable = res.totalProduct
|
||||
this.saleTableTotal = res.total
|
||||
this.productCount = res.productCount
|
||||
this.productSum = res.productSum
|
||||
setTimeout(() => {
|
||||
this.saleTableLoading = false
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 支付类型占比 饼图
|
||||
async datePayType() {
|
||||
try {
|
||||
this.payChartLoading = true
|
||||
const res = await datePayType(this.payChartDay)
|
||||
const data = res.countPayType.map(item => {
|
||||
return {
|
||||
value: item.count,
|
||||
name: item.payType
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.payChartLoading = false
|
||||
}, 300);
|
||||
this.initPayChart(data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 汇总数据
|
||||
async summaryGet() {
|
||||
try {
|
||||
const res1 = await summaryGet()
|
||||
const res2 = await summaryTodayGet()
|
||||
this.topData = {
|
||||
...res1,
|
||||
...res2
|
||||
}
|
||||
let payTime = res1.countDateList.map(item => item.tradeDay)
|
||||
let payData = res1.countDateList.map(item => item.count)
|
||||
|
||||
let countTime = res1.visitsCountList.map(item => item.tradeDay)
|
||||
let countData = res1.visitsCountList.map(item => item.count)
|
||||
|
||||
this.initCardPayChart(payTime, payData)
|
||||
this.initCardCountChart(countTime, countData)
|
||||
console.log(this.topData)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
rankChange() {
|
||||
this.dateProduct()
|
||||
this.summaryDateGet()
|
||||
},
|
||||
// 初始化销售图标
|
||||
initProduceChart(p1, p2) {
|
||||
this.productCountChart = echarts.init(this.$refs.productCountChart)
|
||||
this.productSumChart = echarts.init(this.$refs.productSumChart)
|
||||
|
||||
this.productCountChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 0
|
||||
},
|
||||
xAxis: [{
|
||||
boundaryGap: false,
|
||||
type: 'category',
|
||||
data: p1[0],
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: p1[1],
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: '#409eff' // 渐变颜色
|
||||
}, {
|
||||
offset: 1,
|
||||
color: '#409eff' // 渐变颜色
|
||||
}])
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
this.productSumChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 0
|
||||
},
|
||||
xAxis: [{
|
||||
boundaryGap: false,
|
||||
type: 'category',
|
||||
data: p2[0],
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}],
|
||||
color: '#409eff',
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
|
||||
axisTick: {
|
||||
show: false // 不显示坐标轴刻度线
|
||||
},
|
||||
axisLine: {
|
||||
show: false, // 不显示坐标轴线
|
||||
},
|
||||
axisLabel: {
|
||||
show: false, // 不显示坐标轴上的文字
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示网格线
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: p2[1],
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: '#409eff' // 渐变颜色
|
||||
}, {
|
||||
offset: 1,
|
||||
color: '#409eff' // 渐变颜色
|
||||
}])
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
// 日期汇总数据
|
||||
async summaryDateGet() {
|
||||
try {
|
||||
const res = await summaryDateGet(this.saleTableActive)
|
||||
let p1 = [res.numList.map(item => item.tradeDay), res.numList.map(item => item.count)]
|
||||
let p2 = [res.amountList.map(item => item.tradeDay), res.amountList.map(item => item.count)]
|
||||
this.initProduceChart(p1, p2)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.card_wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
|
||||
.card {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 0 20px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
padding-top: 20px;
|
||||
|
||||
.card_title {
|
||||
font-size: 14px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.number {
|
||||
padding: 20px 0 10px 0;
|
||||
font-size: 24px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.row {
|
||||
height: 50px;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.icon {
|
||||
color: rgb(255, 85, 85);
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.dot {
|
||||
$size: 6px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
background-color: #1890FF;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart_wrap {
|
||||
margin-top: 20px;
|
||||
|
||||
.sale_data {
|
||||
display: flex;
|
||||
|
||||
.card {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 0 20px;
|
||||
|
||||
.sale_data_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
padding-top: 20px;
|
||||
|
||||
.card_title {
|
||||
font-size: 14px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.number {
|
||||
padding-top: 10px;
|
||||
font-size: 24px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.product_chart_wrap {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #ececec;
|
||||
padding: 0 20px;
|
||||
|
||||
.tab_wrap {
|
||||
display: flex;
|
||||
$color: #1890FF;
|
||||
|
||||
.item {
|
||||
padding: 0 10px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
color: $color;
|
||||
|
||||
&.active {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
border-bottom: 2px solid $color;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
padding: 20px 0;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.table {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
93
src/views/invoicing/components/addSupplier.vue
Normal file
93
src/views/invoicing/components/addSupplier.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<el-dialog :title="`${form.id ? '编辑' : '添加'}供应商`" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="供应商" prop="purveyorName">
|
||||
<el-input v-model="form.purveyorName" placeholder="请输入供应商名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.purveyorTelephone" placeholder="请输入联系电话"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input type="textarea" v-model="form.address" placeholder="请输入地址"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签">
|
||||
<el-input v-model="form.tip" placeholder="请输入标签"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input type="textarea" v-model="form.remark" placeholder="请输入备注"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopPurveyor } from '@/api/invoicing'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
form: {
|
||||
id: '',
|
||||
purveyorName: '',
|
||||
purveyorTelephone: '',
|
||||
address: '',
|
||||
tip: '',
|
||||
remark: '',
|
||||
},
|
||||
rules: {
|
||||
purveyorName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入供应商名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
let res = await tbShopPurveyor({
|
||||
...this.form,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form = JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.id = ''
|
||||
this.form.purveyorName = ''
|
||||
this.form.purveyorTelephone = ''
|
||||
this.form.address = ''
|
||||
this.form.tip = ''
|
||||
this.form.remark = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
178
src/views/invoicing/components/invoicingDetail.vue
Normal file
178
src/views/invoicing/components/invoicingDetail.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<!-- 进销存详情记录 -->
|
||||
<template>
|
||||
<el-dialog title="详情记录" width="80%" :visible.sync="dialogVisible" @close="dialogVisible = false">
|
||||
<div class="head-container">
|
||||
<el-select v-model="query.type" placeholder="选择类型">
|
||||
<el-option :label="item.label" :value="item.value" v-for="item in typeList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss">
|
||||
</el-date-picker>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="exchange_wrap">
|
||||
<div class="item">
|
||||
<span>{{ exchange || 0 }}</span>
|
||||
<span>变动数量</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="变动数量" prop="stockNumber">
|
||||
<template v-slot="scope">
|
||||
<span class="num" :class="{ active: scope.row.stockNumber > 0 }">{{ scope.row.stockNumber }} {{
|
||||
scope.row.unitName
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型">
|
||||
<template v-slot="scope">
|
||||
<el-tag type="info">{{ scope.row.tagName }}</el-tag>
|
||||
</template>
|
||||
</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="updatedAt">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.updatedAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<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>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { dictDetail, tbProductStockDetail, tbProductStockDetailSum } from '@/api/invoicing'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
dialogVisible: false,
|
||||
typeList: [],
|
||||
query: {
|
||||
type: '',
|
||||
createdAt: []
|
||||
},
|
||||
goods: '',
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
},
|
||||
exchange: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProductStockDetail({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: this.tableData.sort,
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
productId: this.goods.id,
|
||||
type: this.query.type,
|
||||
createdAt: this.query.createdAt
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content.map(item => {
|
||||
item.tagName = this.typeList.find(val => val.value == item.type).label
|
||||
return item
|
||||
})
|
||||
console.log(this.tableData.list)
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.blurry = ''
|
||||
this.tableData.page = 0
|
||||
this.tableData.list = []
|
||||
this.getTableData()
|
||||
},
|
||||
async show(obj) {
|
||||
this.dialogVisible = true
|
||||
this.goods = obj
|
||||
this.tbProductStockDetailSum()
|
||||
await this.dictDetail()
|
||||
await this.getTableData()
|
||||
},
|
||||
async tbProductStockDetailSum() {
|
||||
try {
|
||||
const { exchange } = await tbProductStockDetailSum({
|
||||
productId: this.goods.id
|
||||
})
|
||||
this.exchange = exchange
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
async dictDetail() {
|
||||
try {
|
||||
const res = await dictDetail({
|
||||
dictName: 'product_stock_type',
|
||||
page: 0,
|
||||
size: 100
|
||||
})
|
||||
this.typeList = res.content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.head-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.num {
|
||||
color: #67C23A;
|
||||
|
||||
&.active {
|
||||
color: #F56C6C;
|
||||
}
|
||||
}
|
||||
|
||||
.exchange_wrap {
|
||||
display: flex;
|
||||
padding: 20px 30px;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
span:nth-child(1) {
|
||||
padding-bottom: 10px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
66
src/views/invoicing/components/operatingDetail.vue
Normal file
66
src/views/invoicing/components/operatingDetail.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<el-dialog title="详情" width="80%" :visible.sync="dialogVisible" @close="dialogVisible = false">
|
||||
<div class="head-container">
|
||||
<span>【退货出库】</span>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.detail.stockSnap" v-loading="tableData.loading" height="400px">
|
||||
<el-table-column :label="`商品名称${tableData.detail.stockSnap.length}`" prop="name"></el-table-column>
|
||||
<el-table-column label="变动数量" prop="number">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.number }}{{ scope.row.unitName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="row">备注:{{ tableData.detail.remark }}</div>
|
||||
<div class="row">操作人:{{ tableData.detail.operatorSnap.name }}</div>
|
||||
<div class="row">创建时间:{{ tableData.detail.createdAt }}</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { tbProductStockOperateDetail } from '@/api/invoicing'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
dialogVisible: false,
|
||||
tableData: {
|
||||
loading: false,
|
||||
detail: {
|
||||
stockSnap: [],
|
||||
operatorSnap: {
|
||||
name: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show(id) {
|
||||
this.dialogVisible = true
|
||||
this.getTableData(id)
|
||||
},
|
||||
async getTableData(id) {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProductStockOperateDetail(id)
|
||||
this.tableData.loading = false
|
||||
this.tableData.detail = res
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.row {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
151
src/views/invoicing/goods_stoks.vue
Normal file
151
src/views/invoicing/goods_stoks.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<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="6">
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
<el-image :src="scope.row.coverImg" class="cover">
|
||||
<div class="img_error" slot="error">
|
||||
<i class="icon el-icon-document-delete"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<div class="info">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
<div>
|
||||
<el-tag type="primary">{{ scope.row.typeEnum | typeEnum }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存" prop="stockNumber">
|
||||
<template v-slot="scope">
|
||||
{{ `${scope.row.stockNumber} ${scope.row.unitName}` }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存开关">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.isStock" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini"
|
||||
@click="$refs.invoicingDetail.show(scope.row)">库存记录</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
<invoicingDetail ref="invoicingDetail" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbProductGet } from '@/api/invoicing'
|
||||
import settings from '@/settings'
|
||||
import invoicingDetail from './components/invoicingDetail'
|
||||
export default {
|
||||
components: {
|
||||
invoicingDetail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
name: ''
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
typeEnum(m) {
|
||||
return settings.typeEnum.find(item => item.typeEnum == m).label
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProductGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: this.tableData.sort,
|
||||
name: this.query.name,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content.map(item => {
|
||||
let stockNumber = 0
|
||||
for (let i of item.skuList) {
|
||||
stockNumber += i.stockNumber
|
||||
}
|
||||
item.stockNumber = stockNumber
|
||||
return item
|
||||
})
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.blurry = ''
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.cover {
|
||||
$size: 50px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 2px;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
110
src/views/invoicing/operating_record.vue
Normal file
110
src/views/invoicing/operating_record.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" @change="getTableData">
|
||||
</el-date-picker>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="类型" prop="type">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.type == 'reject' ? '退货出库' : '供应商入库' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品数量" prop="totalAmount">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.stockSnap.length }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" prop="remark"></el-table-column>
|
||||
<el-table-column label="操作人" prop="status">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.operatorSnap.account }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="updatedAt">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.stockTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini" @click="$refs.operatingDetail.show(scope.row.id)">
|
||||
详情
|
||||
</el-button>
|
||||
<!-- <el-button type="text" size="mini" @click="$refs.operatingDetail.show(scope.row.id)">
|
||||
作废
|
||||
</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<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>
|
||||
<operatingDetail ref="operatingDetail" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { tbProductStockOperateList } from '@/api/invoicing'
|
||||
import operatingDetail from './components/operatingDetail'
|
||||
export default {
|
||||
components: {
|
||||
operatingDetail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
query: {
|
||||
createdAt: []
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProductStockOperateList({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
createdAt: this.query.createdAt
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.createdAt = []
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
276
src/views/invoicing/operation_in.vue
Normal file
276
src/views/invoicing/operation_in.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<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="出库类型">
|
||||
<div class="shop_type_box">
|
||||
<div class="item" v-for="(item, index) in shopTypes" :key="index"
|
||||
:class="{ active: shopTypesActive == index }" @click="changeTypeEnum(index)">
|
||||
<div class="s_title">{{ item.label }}</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="8" v-if="shopTypes[shopTypesActive].value == 'purveyor'">
|
||||
<el-form-item label="供应商" prop="purveyorId">
|
||||
<el-select v-model="queryForm.purveyorId" placeholder="请选择供应商" style="width: 220px;">
|
||||
<el-option :label="item.purveyorName" :value="item.id" v-for="item in purveyorList"
|
||||
:key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入库时间" prop="time">
|
||||
<el-date-picker v-model="queryForm.time" type="date" format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd" placeholder="选择日期" style="width: 220px;">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="应收金额">
|
||||
<el-input v-model="queryForm.totalAmount" placeholder="请输入应收金额"
|
||||
style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="实收金额">
|
||||
<el-input v-model="queryForm.paidAmount" placeholder="请输入实收金额"
|
||||
style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款时间">
|
||||
<el-date-picker v-model="queryForm.paidAt" type="date" format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd" placeholder="选择日期" style="width: 220px;">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="批号">
|
||||
<el-input v-model="queryForm.batchNumber" placeholder="请输入批号"
|
||||
style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="queryForm.remark" placeholder="请输入备注" style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="$refs.shopList.show(tableData.list)">选择商品</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" plain>
|
||||
共{{ tableData.list.length }}种商品,金额合计<span style="color: red;">¥{{ queryForm.totalAmount }}</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list">
|
||||
<el-table-column type="index" width="50"></el-table-column>
|
||||
<el-table-column label="商品名称" prop="name">
|
||||
<template v-slot="scope">
|
||||
<div class="name_wrap">
|
||||
<span class="name">{{ scope.row.name }}</span>
|
||||
<el-tag type="info" v-if="scope.row.specSnap" size="mini">{{ scope.row.specSnap }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进价">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.guidePrice" :min="0" controls-position="right"
|
||||
@change="e => scope.row.totalAmount = e * scope.row.number"></el-input-number>
|
||||
<div class="tips">成本价¥{{ scope.row.costPrice }}/{{ scope.row.unitName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.number" :min="0" controls-position="right"
|
||||
@change="e => scope.row.totalAmount = e * scope.row.guidePrice"></el-input-number>
|
||||
<div class="tips">入库前:{{ scope.row.stockNumber }}{{ scope.row.unitName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="小计">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.totalAmount" :min="0"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="变动后剩余库存">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.unitName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="tableData.list.splice(scope.$index, 1)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" @click="submitHandle" :loading="queryFormLoading">确定</el-button>
|
||||
</div>
|
||||
<shopList ref="shopList" @success="selectShop" />
|
||||
<el-dialog :visible.sync="showResult" :show-close="false" :close-on-press-escape="false"
|
||||
:close-on-click-modal="false">
|
||||
<el-result icon="success" title="入库提交成功" :subTitle="`共操作${tableData.list.length}件商品`">
|
||||
<template slot="extra">
|
||||
<el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button>
|
||||
<router-link to="/invoicing/operating_record">
|
||||
<el-button size="medium">历史提交</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-result>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import shopList from '@/components/shopList'
|
||||
import { tbShopPurveyorGet, tbProductStockOperateOutAndOn } from '@/api/invoicing'
|
||||
export default {
|
||||
components: {
|
||||
shopList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shopTypesActive: 0,
|
||||
shopTypes: [
|
||||
{
|
||||
label: '供应商入库',
|
||||
value: 'purveyor'
|
||||
},
|
||||
{
|
||||
label: '其他入库',
|
||||
value: 'purchase'
|
||||
}
|
||||
],
|
||||
resetForm: '',
|
||||
queryFormLoading: false,
|
||||
queryForm: {
|
||||
batchNumber: '',
|
||||
list: [],
|
||||
paidAmount: 0,
|
||||
paidAt: '',
|
||||
purveyorId: '',
|
||||
purveyorName: '',
|
||||
remark: '',
|
||||
time: dayjs().format('YYYY-MM-DD'),
|
||||
totalAmount: 0,
|
||||
type: 'purveyor',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
},
|
||||
queryRules: {
|
||||
purveyorId: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
time: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
},
|
||||
purveyorList: [],
|
||||
tableData: {
|
||||
list: []
|
||||
},
|
||||
showResult: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.queryForm }
|
||||
this.tbShopPurveyorGet()
|
||||
},
|
||||
methods: {
|
||||
// 提交
|
||||
submitHandle() {
|
||||
this.$refs.queryForm.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.queryFormLoading = true
|
||||
this.queryForm.list = this.tableData.list
|
||||
await tbProductStockOperateOutAndOn(this.queryForm)
|
||||
this.queryFormLoading = false
|
||||
this.showResult = true
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.queryFormLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 选择商品
|
||||
selectShop(res) {
|
||||
let arr = []
|
||||
res.forEach(item => {
|
||||
item.skuList.forEach(i => {
|
||||
arr.push({
|
||||
name: item.name,
|
||||
unitName: item.unitName,
|
||||
productId: item.id,
|
||||
number: 0,
|
||||
totalAmount: '',
|
||||
...i
|
||||
})
|
||||
})
|
||||
})
|
||||
console.log(arr)
|
||||
this.tableData.list = arr
|
||||
},
|
||||
// 初始化
|
||||
resetHandle() {
|
||||
this.showResult = false
|
||||
this.queryForm = { ...this.resetForm }
|
||||
this.tableData.list = []
|
||||
},
|
||||
// 切换类型
|
||||
changeTypeEnum(index) {
|
||||
this.shopTypesActive = index
|
||||
this.queryForm.type = this.shopTypes[index].value
|
||||
},
|
||||
// 获取供应商列表
|
||||
async tbShopPurveyorGet() {
|
||||
try {
|
||||
const res = await tbShopPurveyorGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
page: 0,
|
||||
size: 100
|
||||
})
|
||||
this.purveyorList = res.content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
274
src/views/invoicing/operation_out.vue
Normal file
274
src/views/invoicing/operation_out.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<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="出库类型">
|
||||
<div class="shop_type_box">
|
||||
<div class="item" v-for="(item, index) in shopTypes" :key="index"
|
||||
:class="{ active: shopTypesActive == index }" @click="changeTypeEnum(index)">
|
||||
<div class="s_title">{{ item.label }}</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="8" v-if="shopTypes[shopTypesActive].value == 'reject'">
|
||||
<el-form-item label="供应商" prop="purveyorId">
|
||||
<el-select v-model="queryForm.purveyorId" placeholder="请选择供应商" style="width: 220px;">
|
||||
<el-option :label="item.purveyorName" :value="item.id" v-for="item in purveyorList"
|
||||
:key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出库时间" prop="time">
|
||||
<el-date-picker v-model="queryForm.time" type="date" format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd" placeholder="选择日期" style="width: 220px;">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="shopTypes[shopTypesActive].value == 'reject'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="应收金额">
|
||||
<el-input v-model="queryForm.totalAmount" placeholder="请输入应收金额"
|
||||
style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="实收金额">
|
||||
<el-input v-model="queryForm.paidAmount" placeholder="请输入实收金额" style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="shopTypes[shopTypesActive].value == 'reject'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款时间">
|
||||
<el-date-picker v-model="queryForm.paidAt" type="date" format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd" placeholder="选择日期" style="width: 220px;">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="批号">
|
||||
<el-input v-model="queryForm.batchNumber" placeholder="请输入批号" style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="queryForm.remark" placeholder="请输入备注" style="width: 220px;"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="$refs.shopList.show(tableData.list)">选择商品</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" plain>
|
||||
共{{ tableData.list.length }}种商品,金额合计<span style="color: red;">¥{{ queryForm.totalAmount }}</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list">
|
||||
<el-table-column type="index" width="50"></el-table-column>
|
||||
<el-table-column label="商品名称" prop="name">
|
||||
<template v-slot="scope">
|
||||
<div class="name_wrap">
|
||||
<span class="name">{{ scope.row.name }}</span>
|
||||
<el-tag type="info" v-if="scope.row.specSnap" size="mini">{{ scope.row.specSnap }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进价">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.guidePrice" :min="0" controls-position="right"
|
||||
@change="e => scope.row.totalAmount = e * scope.row.number"></el-input-number>
|
||||
<div class="tips">成本价¥{{ scope.row.costPrice }}/{{ scope.row.unitName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.number" :min="0" controls-position="right"
|
||||
@change="e => scope.row.totalAmount = e * scope.row.guidePrice"></el-input-number>
|
||||
<div class="tips">出库前:{{ scope.row.stockNumber }}{{ scope.row.unitName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="小计">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.totalAmount" :min="0"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="变动后剩余库存">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.stockNumber - scope.row.number }}{{ scope.row.unitName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="tableData.list.splice(scope.$index, 1)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" @click="submitHandle" :loading="queryFormLoading">确定</el-button>
|
||||
</div>
|
||||
<shopList ref="shopList" @success="selectShop" />
|
||||
<el-dialog :visible.sync="showResult" :show-close="false" :close-on-press-escape="false"
|
||||
:close-on-click-modal="false">
|
||||
<el-result icon="success" title="出库提交成功" :subTitle="`共操作${tableData.list.length}件商品`">
|
||||
<template slot="extra">
|
||||
<el-button type="primary" size="medium" @click="resetHandle">创建新的出库单</el-button>
|
||||
<router-link to="/invoicing/operating_record">
|
||||
<el-button size="medium">历史提交</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-result>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import shopList from '@/components/shopList'
|
||||
import { tbShopPurveyorGet, tbProductStockOperateOutAndOn } from '@/api/invoicing'
|
||||
export default {
|
||||
components: {
|
||||
shopList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shopTypesActive: 0,
|
||||
shopTypes: [
|
||||
{
|
||||
label: '供应商退货',
|
||||
value: 'reject'
|
||||
},
|
||||
{
|
||||
label: '其他出库',
|
||||
value: 'other-out'
|
||||
}
|
||||
],
|
||||
resetForm: '',
|
||||
queryFormLoading: false,
|
||||
queryForm: {
|
||||
batchNumber: '',
|
||||
list: [],
|
||||
paidAmount: 0,
|
||||
paidAt: '',
|
||||
purveyorId: '',
|
||||
purveyorName: '',
|
||||
remark: '',
|
||||
time: dayjs().format('YYYY-MM-DD'),
|
||||
totalAmount: 0,
|
||||
type: 'reject',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
},
|
||||
queryRules: {
|
||||
purveyorId: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
time: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
},
|
||||
purveyorList: [],
|
||||
tableData: {
|
||||
list: []
|
||||
},
|
||||
showResult: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.queryForm }
|
||||
this.tbShopPurveyorGet()
|
||||
},
|
||||
methods: {
|
||||
// 提交
|
||||
submitHandle() {
|
||||
this.$refs.queryForm.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.queryFormLoading = true
|
||||
this.queryForm.list = this.tableData.list
|
||||
await tbProductStockOperateOutAndOn(this.queryForm)
|
||||
this.queryFormLoading = false
|
||||
this.showResult = true
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.queryFormLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 选择商品
|
||||
selectShop(res) {
|
||||
let arr = []
|
||||
res.forEach(item => {
|
||||
item.skuList.forEach(i => {
|
||||
arr.push({
|
||||
name: item.name,
|
||||
unitName: item.unitName,
|
||||
productId: item.id,
|
||||
number: 0,
|
||||
totalAmount: '',
|
||||
...i
|
||||
})
|
||||
})
|
||||
})
|
||||
console.log(arr)
|
||||
this.tableData.list = arr
|
||||
},
|
||||
// 初始化
|
||||
resetHandle() {
|
||||
this.showResult = false
|
||||
this.queryForm = { ...this.resetForm }
|
||||
this.tableData.list = []
|
||||
},
|
||||
// 切换类型
|
||||
changeTypeEnum(index) {
|
||||
this.shopTypesActive = index
|
||||
this.queryForm.type = this.shopTypes[index].value
|
||||
},
|
||||
// 获取供应商列表
|
||||
async tbShopPurveyorGet() {
|
||||
try {
|
||||
const res = await tbShopPurveyorGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
page: 0,
|
||||
size: 100
|
||||
})
|
||||
this.purveyorList = res.content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
136
src/views/invoicing/supplier_manage/purchase.vue
Normal file
136
src/views/invoicing/supplier_manage/purchase.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-input v-model="query.name" clearable placeholder="供应商" @keyup.enter.native="getTableData"
|
||||
style="width: 200px;" />
|
||||
<el-select v-model="query.type" placeholder="付款状态">
|
||||
<el-option :label="item.label" :value="item.value" v-for="item in types" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="供应商" prop="purveyorName"></el-table-column>
|
||||
<el-table-column label="剩余付款金额" prop="waitAmount">
|
||||
<template v-slot="scope">
|
||||
<span class="num" v-if="scope.row.waitAmount > 0">¥{{ scope.row.waitAmount }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="待付款笔数" prop="waitCount">
|
||||
<template v-slot="scope">
|
||||
<template v-if="scope.row.waitCount > 0">
|
||||
有<span class="count">{{ scope.row.waitCount }}笔</span>未付
|
||||
</template>
|
||||
<template v-else>-</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" prop="type">
|
||||
<template v-slot="scope">
|
||||
<el-tag :type="scope.row.type == 0 ? 'warning' : 'success'">
|
||||
{{ scope.row.type == 0 ? '待支付' : '已完结' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上笔进货日期" prop="lastTransactAt">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.lastTransactAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<router-link :to="{ name: 'purchase_detail', query: { purveyorId: scope.row.purveyorId } }">
|
||||
<el-button type="text" size="mini">查看详情</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { tbShopPurveyorTransactGet, dictDetail } from '@/api/invoicing'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
types: [],
|
||||
query: {
|
||||
name: '',
|
||||
type: ''
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.dictDetail()
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopPurveyorTransactGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: this.tableData.sort,
|
||||
purveyorName: this.query.name,
|
||||
status: this.query.type,
|
||||
type: 'purveyor',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.type = ''
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
async dictDetail() {
|
||||
const { content } = await dictDetail({
|
||||
dictName: 'purveyor_transact_status',
|
||||
size: 100,
|
||||
page: 0
|
||||
})
|
||||
this.types = content
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.num {
|
||||
color: #F56C6C;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: #409EFF;
|
||||
}
|
||||
</style>
|
||||
350
src/views/invoicing/supplier_manage/purchase_detail.vue
Normal file
350
src/views/invoicing/supplier_manage/purchase_detail.vue
Normal file
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-radio-group v-model="query.time" @change="timeChange">
|
||||
<el-radio-button :label="item.value" v-for="item in timeList" :key="item.label">{{ item.label
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="head-container" v-if="query.time == 'custom'">
|
||||
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" @change="getTableData">
|
||||
</el-date-picker>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-select v-model="query.type" placeholder="付款状态">
|
||||
<el-option :label="item.label" :value="item.value" v-for="item in types" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="info_list">
|
||||
<div class="item">
|
||||
<div class="icon_wrap" style="background-color: #F2D7FF;">
|
||||
<i class="icon el-icon-info" style="color:#C978EE;"></i>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="n">¥{{ info.totalAmount }}</div>
|
||||
<div class="intro">总交易{{ info.waitCount }}笔</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon_wrap" style="background-color: #DFFECC;">
|
||||
<i class="icon el-icon-success" style="color:#47B505;"></i>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="n">¥{{ info.paidAmount }}</div>
|
||||
<div class="intro">已支付金额</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon_wrap" style="background-color: #FFE7D6;">
|
||||
<i class="icon el-icon-circle-plus" style="color: #FF6B00;"></i>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="n">¥{{ info.waitAmount }}</div>
|
||||
<div class="intro">待支付金额</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon_wrap" style="background-color: #FFF1D5;">
|
||||
<i class="icon el-icon-warning" style="color: #FEB420;"></i>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="n">{{ info.waitNumber }}</div>
|
||||
<div class="intro">待支付笔数</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="select_count_wrap">
|
||||
<div class="select_count">
|
||||
<i class="icon el-icon-warning"></i>
|
||||
已选中
|
||||
<span class="n">{{ selectCount }}</span>
|
||||
项
|
||||
</div>
|
||||
<el-button>批量付款</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading" @select="selectHandle"
|
||||
@select-all="selectHandle">
|
||||
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||||
<el-table-column label="创建日期" prop="createdAt">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.createdAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" prop="type">
|
||||
<template v-slot="scope">
|
||||
进货单
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总金额" prop="totalAmount">
|
||||
<template v-slot="scope">
|
||||
¥{{ scope.row.totalAmount }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="待付款金额" prop="waitAmount">
|
||||
<template v-slot="scope">
|
||||
<span class="num" v-if="scope.row.waitAmount > 0">¥{{ scope.row.waitAmount }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" prop="status">
|
||||
<template v-slot="scope">
|
||||
<el-tag type="info">{{ types.find(item => item.value == scope.row.status).label }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" prop="remark"></el-table-column>
|
||||
<el-table-column label="付款时间" prop="updatedAt">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.paidAt && dayjs(scope.row.paidAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<router-link :to="{ name: 'purchase_detail', query: { purveyorId: scope.row.purveyorId } }">
|
||||
<el-button type="text" size="mini">查看详情</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { tbShopPurveyorTransactInfo, dictDetail, tbShopPurveyorTransactSum } from '@/api/invoicing'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
timeList: [
|
||||
{
|
||||
label: '全部',
|
||||
value: 'all'
|
||||
},
|
||||
{
|
||||
label: '今天',
|
||||
value: '0'
|
||||
},
|
||||
{
|
||||
label: '昨天',
|
||||
value: '-1'
|
||||
},
|
||||
{
|
||||
label: '最近7天',
|
||||
value: '-7'
|
||||
},
|
||||
{
|
||||
label: '最近30天',
|
||||
value: '-30'
|
||||
},
|
||||
{
|
||||
label: '本周',
|
||||
value: 'week'
|
||||
},
|
||||
{
|
||||
label: '本月',
|
||||
value: 'moth'
|
||||
},
|
||||
{
|
||||
label: '自定义',
|
||||
value: 'custom'
|
||||
}
|
||||
],
|
||||
types: [],
|
||||
selectCount: 0,
|
||||
query: {
|
||||
type: '',
|
||||
time: 'all',
|
||||
createdAt: []
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
},
|
||||
info: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.dictDetail()
|
||||
this.getTableData()
|
||||
this.tbShopPurveyorTransactSum()
|
||||
},
|
||||
methods: {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopPurveyorTransactInfo({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: this.tableData.sort,
|
||||
purveyorId: this.$route.query.purveyorId,
|
||||
status: this.query.type,
|
||||
type: 'purveyor',
|
||||
createdAt: this.query.createdAt
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.time = 'all'
|
||||
this.query.createdAt = []
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
async dictDetail() {
|
||||
const { content } = await dictDetail({
|
||||
dictName: 'purveyor_transact_status',
|
||||
size: 100,
|
||||
page: 0
|
||||
})
|
||||
this.types = content
|
||||
},
|
||||
// 选择时间
|
||||
timeChange(e) {
|
||||
this.query.createdAt = []
|
||||
const format0 = 'YYYY-MM-DD 00:00:00'
|
||||
const format1 = 'YYYY-MM-DD 23:59:59'
|
||||
switch (e) {
|
||||
case '0':
|
||||
this.query.createdAt = [dayjs().format(format0), dayjs().format(format1)]
|
||||
break;
|
||||
case '-1':
|
||||
this.query.createdAt = [dayjs().add(-1, 'day').format(format0), dayjs().add(-1, 'day').format(format1)]
|
||||
break;
|
||||
case '-7':
|
||||
this.query.createdAt = [dayjs().add(-7, 'day').format(format0), dayjs().format(format1)]
|
||||
break;
|
||||
case '-30':
|
||||
this.query.createdAt = [dayjs().add(-30, 'day').format(format0), dayjs().format(format1)]
|
||||
break;
|
||||
case 'week':
|
||||
this.query.createdAt = [dayjs().startOf('week').format(format0), dayjs().endOf('week').format(format1)]
|
||||
break;
|
||||
case 'moth':
|
||||
this.query.createdAt = [dayjs().startOf('month').format(format0), dayjs().endOf('month').format(format1)]
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.getTableData()
|
||||
},
|
||||
selectHandle(selection, row) {
|
||||
this.selectCount = 0
|
||||
this.selectCount = selection.length
|
||||
},
|
||||
async tbShopPurveyorTransactSum() {
|
||||
this.info = await tbShopPurveyorTransactSum({ purveyorId: this.$route.query.purveyorId, type: 'purveyor' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.select_count_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.select_count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #e7f3ff;
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
margin-right: 10px;
|
||||
border-radius: 4px;
|
||||
|
||||
.icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.n {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.icon,
|
||||
.n {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.num {
|
||||
color: #F56C6C;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.info_list {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.icon_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
padding: 2px;
|
||||
|
||||
.icon {
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 20px;
|
||||
|
||||
.n {
|
||||
font-size: 28px;
|
||||
text-indent: -6px;
|
||||
}
|
||||
|
||||
.intro {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
136
src/views/invoicing/supplier_manage/refund.vue
Normal file
136
src/views/invoicing/supplier_manage/refund.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-input v-model="query.name" clearable placeholder="供应商" @keyup.enter.native="getTableData"
|
||||
style="width: 200px;" />
|
||||
<el-select v-model="query.type" placeholder="付款状态">
|
||||
<el-option :label="item.label" :value="item.value" v-for="item in types" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="供应商" prop="purveyorName"></el-table-column>
|
||||
<el-table-column label="剩余付款金额" prop="waitAmount">
|
||||
<template v-slot="scope">
|
||||
<span class="num" v-if="scope.row.waitAmount > 0">¥{{ scope.row.waitAmount }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="待付款笔数" prop="waitCount">
|
||||
<template v-slot="scope">
|
||||
<template v-if="scope.row.waitCount > 0">
|
||||
有<span class="count">{{ scope.row.waitCount }}笔</span>未付
|
||||
</template>
|
||||
<template v-else>-</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" prop="type">
|
||||
<template v-slot="scope">
|
||||
<el-tag :type="scope.row.type == 0 ? 'warning' : 'success'">
|
||||
{{ scope.row.type == 0 ? '待支付' : '已完结' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上笔进货日期" prop="lastTransactAt">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.lastTransactAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<router-link :to="{ name: 'purchase_detail', query: { purveyorId: scope.row.purveyorId } }">
|
||||
<el-button type="text" size="mini">查看详情</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { tbShopPurveyorTransactGet, dictDetail } from '@/api/invoicing'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
types: [],
|
||||
query: {
|
||||
name: '',
|
||||
type: ''
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.dictDetail()
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopPurveyorTransactGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: this.tableData.sort,
|
||||
purveyorName: this.query.name,
|
||||
status: this.query.type,
|
||||
type: 'reject',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.type = ''
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
async dictDetail() {
|
||||
const { content } = await dictDetail({
|
||||
dictName: 'purveyor_transact_status',
|
||||
size: 100,
|
||||
page: 0
|
||||
})
|
||||
this.types = content
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.num {
|
||||
color: #F56C6C;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: #409EFF;
|
||||
}
|
||||
</style>
|
||||
110
src/views/invoicing/supplier_manage/supplier_list.vue
Normal file
110
src/views/invoicing/supplier_manage/supplier_list.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-input v-model="query.name" size="small" clearable placeholder="供应商" @keyup.enter.native="getTableData"
|
||||
style="width: 200px;" />
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addSupplier.show()">添加供应商</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="供应商" prop="purveyorName"></el-table-column>
|
||||
<el-table-column label="联系电话" prop="purveyorTelephone"></el-table-column>
|
||||
<el-table-column label="地址" prop="address"></el-table-column>
|
||||
<el-table-column label="标签" prop="tip"></el-table-column>
|
||||
<el-table-column label="备注" prop="remark"></el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini" round icon="el-icon-edit"
|
||||
@click="$refs.addSupplier.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-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<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>
|
||||
<addSupplier ref="addSupplier" @success="getTableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopPurveyorGet, tbShopPurveyor } from '@/api/invoicing'
|
||||
import addSupplier from '../components/addSupplier'
|
||||
export default {
|
||||
components: {
|
||||
addSupplier
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
name: ''
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
sort: 'id',
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 删除
|
||||
async delHandle(ids) {
|
||||
try {
|
||||
await tbShopPurveyor(ids, 'delete')
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `删除成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopPurveyorGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: this.tableData.sort,
|
||||
purveyorName: this.query.name,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="login" :style="'background-image:url('+ Background +');'">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
|
||||
<div class="login" :style="'background-image:url(' + Background + ');'">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px"
|
||||
class="login-form">
|
||||
<h3 class="title">
|
||||
收银机后台
|
||||
银收客后台管理
|
||||
</h3>
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
|
||||
@@ -10,23 +11,28 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
|
||||
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
|
||||
@keyup.enter.native="handleLogin">
|
||||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
|
||||
<div class="code_wrap">
|
||||
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%"
|
||||
@keyup.enter.native="handleLogin">
|
||||
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
|
||||
</el-input>
|
||||
<div class="login-code">
|
||||
<img :src="codeUrl" @click="getCode">
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;">
|
||||
记住我
|
||||
</el-checkbox>
|
||||
<el-form-item style="width:100%;">
|
||||
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
|
||||
<el-button :loading="loading" size="medium" type="primary" style="width:100%;"
|
||||
@click.native.prevent="handleLogin">
|
||||
<span v-if="!loading">登 录</span>
|
||||
<span v-else>登 录 中...</span>
|
||||
</el-button>
|
||||
@@ -47,7 +53,7 @@ import Config from '@/settings'
|
||||
import { getCodeImg } from '@/api/login'
|
||||
import Cookies from 'js-cookie'
|
||||
import qs from 'qs'
|
||||
import Background from '@/assets/images/background.webp'
|
||||
import Background from '@/assets/images/background_img.jpg'
|
||||
export default {
|
||||
name: 'Login',
|
||||
data() {
|
||||
@@ -56,8 +62,8 @@ export default {
|
||||
codeUrl: '',
|
||||
cookiePass: '',
|
||||
loginForm: {
|
||||
username: 'admin',
|
||||
password: '123456',
|
||||
username: '',
|
||||
password: '',
|
||||
rememberMe: false,
|
||||
code: '',
|
||||
uuid: ''
|
||||
@@ -73,7 +79,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler: function(route) {
|
||||
handler: function (route) {
|
||||
const data = route.query
|
||||
if (data && data.redirect) {
|
||||
this.redirect = data.redirect
|
||||
@@ -169,47 +175,60 @@ export default {
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
.login {
|
||||
.login {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
}
|
||||
.title {
|
||||
margin: 0 auto 30px auto;
|
||||
padding-right: 15%;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0 auto 50px auto;
|
||||
text-align: center;
|
||||
color: #707070;
|
||||
}
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
.login-form {
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
width: 385px;
|
||||
padding: 25px 25px 5px 25px;
|
||||
width: 500px;
|
||||
padding: 50px 50px 50px 50px;
|
||||
|
||||
.el-input {
|
||||
height: 38px;
|
||||
|
||||
input {
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
.input-icon{
|
||||
height: 39px;width: 14px;margin-left: 2px;
|
||||
|
||||
.input-icon {
|
||||
height: 39px;
|
||||
width: 14px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
.login-tip {
|
||||
}
|
||||
|
||||
.login-tip {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
.login-code {
|
||||
}
|
||||
.code_wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.login-code {
|
||||
width: 33%;
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
float: right;
|
||||
img{
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
vertical-align:middle
|
||||
}
|
||||
vertical-align: middle
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
340
src/views/order_manage/components/orderDetail.vue
Normal file
340
src/views/order_manage/components/orderDetail.vue
Normal file
@@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<el-drawer title="订单详情" size="50%" :visible.sync="drawer" direction="rtl" v-loading="loading">
|
||||
<div class="header">
|
||||
<div class="title">【收银订单】</div>
|
||||
<div class="table">
|
||||
<div class="item">
|
||||
<div class="t">订单状态</div>
|
||||
<div class="b">
|
||||
<el-tag :type="detail.status == 'closed' ? 'success' : 'warning'">{{
|
||||
detail.status |
|
||||
statusFilter
|
||||
}}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="t">订单金额</div>
|
||||
<div class="b">
|
||||
¥{{ detail.orderAmount }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="t">订单时间</div>
|
||||
<div class="b">
|
||||
{{ detail.createdAt | timeFilter }}
|
||||
</div>
|
||||
</div>
|
||||
</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>支付方式:现金</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>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="商品信息" name="2">
|
||||
<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>{{ 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>
|
||||
</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">
|
||||
<div class="time">{{ item.createdAt | timeFilter }}</div>
|
||||
<div class="list">
|
||||
<div class="list_row" v-for="val in item.detailList">
|
||||
<div class="item">
|
||||
<el-image :src="val.productImg" style="width: 50px;height: 50px;"></el-image>
|
||||
<span class="name">{{ val.productName }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span>退-{{ val.num }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span>¥{{ val.priceAmount }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span>¥-{{ val.priceAmount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot">退款:¥-{{item.refundAmount}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import orderEnum from '../orderEnum';
|
||||
import dayjs from 'dayjs'
|
||||
import { tbOrderInfoDetail, tbOrderInfoData } from '@/api/order'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderEnum,
|
||||
drawer: false,
|
||||
type: '1',
|
||||
detail: '',
|
||||
loading: false,
|
||||
refoundList: []
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
orderTypeFilter(t) {
|
||||
if (t) {
|
||||
return t && orderEnum.orderType.find(item => item.key == t).label
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
},
|
||||
sendTypeFilter(t) {
|
||||
if (t) {
|
||||
return orderEnum.sendType.find(item => item.key == t).label
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
},
|
||||
statusFilter(t) {
|
||||
if (t) {
|
||||
return t && orderEnum.status.find(item => item.key == t).label
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
},
|
||||
timeFilter(t) {
|
||||
if (t) {
|
||||
return dayjs(t).format('YYYY-MM-DD HH:mm:ss')
|
||||
} else {
|
||||
return '-'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换类型
|
||||
getTableData() {
|
||||
if (this.type == '3') {
|
||||
this.tbOrderInfoData()
|
||||
}
|
||||
},
|
||||
// 获取退单列表
|
||||
async tbOrderInfoData() {
|
||||
try {
|
||||
const res = await tbOrderInfoData({
|
||||
source: this.detail.id,
|
||||
page: 0,
|
||||
pageSize: 500,
|
||||
orderType: '0'
|
||||
})
|
||||
this.refoundList = res.content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取订单详情
|
||||
async tbOrderInfoDetail(id) {
|
||||
try {
|
||||
this.loading = true
|
||||
const res = await tbOrderInfoDetail(id)
|
||||
this.detail = res
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
show(obj) {
|
||||
this.drawer = true
|
||||
this.type = '1'
|
||||
this.detail = ''
|
||||
this.tbOrderInfoDetail(obj.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0 20px 0;
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
color: #FF9731;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: flex;
|
||||
padding: 20px 0;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
|
||||
.b {
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
|
||||
.info_content {
|
||||
padding: 20px 0;
|
||||
|
||||
.item {
|
||||
border-bottom: 1px dashed #ececec;
|
||||
padding-bottom: 20px;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.label {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
color: #333;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
color: #555;
|
||||
padding-top: 20px;
|
||||
|
||||
div {
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.refund_wrap {
|
||||
.row {
|
||||
border-bottom: 1px dashed #ececec;
|
||||
padding-bottom: 20px;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.list {
|
||||
.list_row {
|
||||
display: flex;
|
||||
padding-top: 10px;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
color: #555;
|
||||
|
||||
.name {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.foot {
|
||||
color: #333;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
84
src/views/order_manage/orderEnum.js
Normal file
84
src/views/order_manage/orderEnum.js
Normal file
@@ -0,0 +1,84 @@
|
||||
export default {
|
||||
status: [
|
||||
{
|
||||
key: 'unpaid',
|
||||
label: '待支付'
|
||||
},
|
||||
{
|
||||
key: 'unsend',
|
||||
label: '待发货'
|
||||
},
|
||||
{
|
||||
key: 'closed',
|
||||
label: '订单完成'
|
||||
},
|
||||
{
|
||||
key: 'send',
|
||||
label: '已发'
|
||||
},
|
||||
{
|
||||
key: 'refunding',
|
||||
label: '申请退单'
|
||||
},
|
||||
{
|
||||
key: 'refund',
|
||||
label: '退单'
|
||||
},
|
||||
{
|
||||
key: 'cancelled',
|
||||
label: '取消订单'
|
||||
},
|
||||
{
|
||||
key: 'merge',
|
||||
label: '合台'
|
||||
},
|
||||
{
|
||||
key: 'pending',
|
||||
label: '挂单'
|
||||
},
|
||||
{
|
||||
key: 'activate',
|
||||
label: '激活'
|
||||
},
|
||||
{
|
||||
key: 'paying',
|
||||
label: '支付中'
|
||||
}
|
||||
],
|
||||
sendType: [
|
||||
{
|
||||
key: 'post',
|
||||
label: '快递'
|
||||
},
|
||||
{
|
||||
key: 'takeaway',
|
||||
label: '外卖'
|
||||
},
|
||||
{
|
||||
key: 'takeself',
|
||||
label: '自提'
|
||||
},
|
||||
{
|
||||
key: 'table',
|
||||
label: '堂食'
|
||||
}
|
||||
],
|
||||
orderType: [
|
||||
{
|
||||
key: 'cash',
|
||||
label: '收银'
|
||||
},
|
||||
{
|
||||
key: 'miniapp',
|
||||
label: '小程序'
|
||||
},
|
||||
{
|
||||
key: 'offline',
|
||||
label: '线下'
|
||||
},
|
||||
{
|
||||
key: 'return',
|
||||
label: '退单'
|
||||
}
|
||||
]
|
||||
}
|
||||
446
src/views/order_manage/order_list.vue
Normal file
446
src/views/order_manage/order_list.vue
Normal file
@@ -0,0 +1,446 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-tabs v-model="orderType" @tab-click="getTableData">
|
||||
<el-tab-pane label="全部订单" name=""></el-tab-pane>
|
||||
<el-tab-pane label="收银订单" name="cash"></el-tab-pane>
|
||||
<el-tab-pane label="小程序订单" name="miniapp"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="head-container">
|
||||
<el-form :model="query" label-width="100px" label-position="left">
|
||||
<el-form-item label="订单状态">
|
||||
<el-radio-group v-model="query.status">
|
||||
<el-radio-button label="">全部</el-radio-button>
|
||||
<el-radio-button :label="item.key" v-for="item in orderEnum.status" :key="item.key">
|
||||
{{ item.label }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式">
|
||||
<el-radio-group v-model="query.payType">
|
||||
<el-radio-button label="">全部</el-radio-button>
|
||||
<el-radio-button :label="item.payType" v-for="item in payTypes" :key="item.payType">
|
||||
{{ item.payName }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-radio-group v-model="timeValue" @change="timeChange">
|
||||
<el-radio-button label="">全部</el-radio-button>
|
||||
<el-radio-button label="0">今天</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-button label="week">本周</el-radio-button>
|
||||
<el-radio-button label="month">本月</el-radio-button>
|
||||
<el-radio-button label="custom">自定义</el-radio-button>
|
||||
</el-radio-group>
|
||||
<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" v-if="timeValue == 'custom'">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单号">
|
||||
<el-input v-model="query.orderNo" placeholder="请输入订单号" style="width: 300px;"></el-input>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
<el-button icon="el-icon-download" v-loading="downloadLoading" @click="downloadHandle">
|
||||
<span v-if="!downloadLoading">导出Excel</span>
|
||||
<span v-else>下载中...</span>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="collect_wrap">
|
||||
<div class="item">
|
||||
<div class="icon_wrap" style="--bg-color:#C978EE">
|
||||
<i class="icon el-icon-s-goods"></i>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="m">¥{{ payCountTotal }}</div>
|
||||
<div class="t">总金额</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" v-for="item in payCountList" :key="item.payType">
|
||||
<div class="icon_wrap" style="--bg-color:#fff">
|
||||
<el-image class="img" :src="item.icon"></el-image>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="m">¥{{ item.payAmount || 0 }}</div>
|
||||
<div class="t">{{ item.payType }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.data" v-loading="tableData.loading">
|
||||
<el-table-column label="订单号信息">
|
||||
<template v-slot="scope">
|
||||
<div class="table_order_info">
|
||||
<div class="order_no">{{ scope.row.orderNo }}</div>
|
||||
<!-- <div>会员 {{ scope.row.orderNo }}</div> -->
|
||||
<div class="type">【{{ scope.row.orderType | orderTypeFilter }} {{ scope.row.sendType |
|
||||
sendTypeFilter }}】</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
<div class="goods_info">
|
||||
<div class="row" v-for="item in scope.row.detailList" :key="item.id">
|
||||
<el-image :src="item.productImg" class="cover" lazy></el-image>
|
||||
<div class="info">
|
||||
<div class="name">{{ item.productName }} <span class="refund"
|
||||
v-if="item.status == 'refunding' || item.status == 'refund'">(退 - {{
|
||||
item.num }})</span></div>
|
||||
<div class="sku">{{ item.productSkuName }} </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单金额">
|
||||
<template v-slot="scope">
|
||||
<div>{{ scope.row.orderType | orderTypeFilter }}</div>
|
||||
<div class="refund" v-if="scope.row.status == 'refunding' || scope.row.status == 'refund'">
|
||||
退款:-¥{{
|
||||
scope.row.refundAmount }}</div>
|
||||
<div>¥{{ scope.row.productAmount }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template v-slot="scope">
|
||||
<template v-if="scope.row.status == 'refund' && scope.row.orderType != 'return'">
|
||||
<el-tag type="primary">已完成</el-tag>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-tag type="primary" v-if="scope.row.status == 'closed'">
|
||||
{{ scope.row.status | statusFilter }}
|
||||
</el-tag>
|
||||
<el-tag type="warning" v-if="scope.row.status != 'closed'">
|
||||
{{ scope.row.status | statusFilter }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.createdAt | timeFilter }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="$refs.orderDetail.show(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" @size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
<orderDetail ref="orderDetail" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import orderEnum from './orderEnum'
|
||||
import { tbShopPayTypeGet } from '@/api/setting'
|
||||
import { tbOrderInfoData, tbOrderInfoDownload, payCount } from '@/api/order'
|
||||
import dayjs from 'dayjs'
|
||||
import { downloadFile } from '@/utils/index'
|
||||
|
||||
import orderDetail from './components/orderDetail'
|
||||
|
||||
export default {
|
||||
components: { orderDetail },
|
||||
data() {
|
||||
return {
|
||||
orderEnum,
|
||||
payTypes: [],
|
||||
timeValue: '',
|
||||
resetQuery: null,
|
||||
orderType: "",
|
||||
query: {
|
||||
id: '',
|
||||
status: '',
|
||||
payType: '',
|
||||
orderNo: '',
|
||||
createdAt: []
|
||||
},
|
||||
tableData: {
|
||||
data: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false,
|
||||
total: 0
|
||||
},
|
||||
downloadLoading: false,
|
||||
payCountList: '',
|
||||
payCountTotal: 0
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
orderTypeFilter(t) {
|
||||
if (t) {
|
||||
return t && orderEnum.orderType.find(item => item.key == t).label
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
},
|
||||
sendTypeFilter(t) {
|
||||
if (t) {
|
||||
return orderEnum.sendType.find(item => item.key == t).label
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
},
|
||||
statusFilter(t) {
|
||||
if (t) {
|
||||
return t && orderEnum.status.find(item => item.key == t).label
|
||||
} else {
|
||||
return t
|
||||
}
|
||||
},
|
||||
timeFilter(time) {
|
||||
return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetQuery = { ...this.query }
|
||||
this.tbShopPayTypeGet()
|
||||
this.getTableData()
|
||||
this.payCount()
|
||||
},
|
||||
methods: {
|
||||
// 获取订单汇总
|
||||
async payCount() {
|
||||
try {
|
||||
const res = await payCount()
|
||||
this.payCountList = res
|
||||
|
||||
let total = 0
|
||||
res.map(item => {
|
||||
total += item.payAmount
|
||||
})
|
||||
this.payCountTotal = Math.floor(total * 100) / 100
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 导出Excel
|
||||
async downloadHandle() {
|
||||
try {
|
||||
this.downloadLoading = true
|
||||
const file = await tbOrderInfoDownload({
|
||||
orderType: this.orderType,
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
...this.query
|
||||
})
|
||||
downloadFile(file, '订单数据', 'xlsx')
|
||||
this.downloadLoading = false
|
||||
} catch (error) {
|
||||
this.downloadLoading = false
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.timeValue = ''
|
||||
this.query = { ...this.resetQuery }
|
||||
this.page = 0
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页大小改变
|
||||
sizeChange(e) {
|
||||
this.tableData.size = e
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbOrderInfoData({
|
||||
page: this.tableData.page,
|
||||
pageSize: this.tableData.size,
|
||||
orderType: this.orderType,
|
||||
...this.query
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.data = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 切换时间
|
||||
timeChange(e) {
|
||||
const format = ['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59']
|
||||
switch (e) {
|
||||
case '':
|
||||
// 全部
|
||||
this.query.createdAt = []
|
||||
break;
|
||||
case '0':
|
||||
// 今天
|
||||
this.query.createdAt = [dayjs().format(format[0]), dayjs().format(format[1])]
|
||||
break;
|
||||
case '-1':
|
||||
// 昨天
|
||||
this.query.createdAt = [dayjs().add(-1, 'd').format(format[0]), dayjs().add(-1, 'd').format(format[1])]
|
||||
break;
|
||||
case '-7':
|
||||
// 最近7天
|
||||
this.query.createdAt = [dayjs().add(-7, 'd').format(format[0]), dayjs().format(format[1])]
|
||||
break;
|
||||
case '-30':
|
||||
// 最近7天
|
||||
this.query.createdAt = [dayjs().add(-30, 'd').format(format[0]), dayjs().format(format[1])]
|
||||
break;
|
||||
case 'week':
|
||||
// 本周
|
||||
this.query.createdAt = [dayjs().startOf('week').format(format[0]), dayjs().endOf('week').format(format[1])]
|
||||
break;
|
||||
case 'month':
|
||||
// 本周
|
||||
this.query.createdAt = [dayjs().startOf('month').format(format[0]), dayjs().endOf('month').format(format[1])]
|
||||
break;
|
||||
case 'custom':
|
||||
// 自定义
|
||||
this.query.createdAt = []
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 获取支付方式
|
||||
async tbShopPayTypeGet() {
|
||||
try {
|
||||
const { content } = await tbShopPayTypeGet({
|
||||
page: 0,
|
||||
size: 100,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.payTypes = content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.collect_wrap {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
|
||||
.icon_wrap {
|
||||
$size: 34px;
|
||||
$border: 6px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: $size + $border;
|
||||
height: $size + $border;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: var(--bg-color);
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
|
||||
.m {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.t {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.refund {
|
||||
color: #FF9731;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table_order_info {
|
||||
.order_no {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.type {
|
||||
color: #E6A23C;
|
||||
}
|
||||
}
|
||||
|
||||
.goods_info {
|
||||
.row {
|
||||
display: flex;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.cover {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
|
||||
.sku {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
717
src/views/product/add_shop.vue
Normal file
717
src/views/product/add_shop.vue
Normal file
@@ -0,0 +1,717 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="商品类型" prop="typeEnum">
|
||||
<div class="shop_type_box" :class="{ disabled: form.id }">
|
||||
<div class="item" v-for="(item, index) in shopTypes" :key="index"
|
||||
:class="{ active: shopTypesActive == index }" @click="changeTypeEnum(index)">
|
||||
<div class="s_title">{{ item.label }}</div>
|
||||
<div class="intro">({{ item.intro }})</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入商品名称" style="width: 500px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="单位">
|
||||
<el-select v-model="form.unitId" placeholder="请选择单位" style="width: 500px;" @change="selectUnitt">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in units" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" plain icon="el-icon-plus" @click="$refs.addUnitRef.show()">添加单位</el-button>
|
||||
<addUnit ref="addUnitRef" @success="tbShopUnit" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类" prop="categoryId">
|
||||
<el-select v-model="form.categoryId" placeholder="请选择商品分类" style="width: 500px;">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in categorys" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<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="商品图片">
|
||||
<uploadImg ref="uploadImg" :limit="9" @success="uploadSuccess" @remove="uploadRemove" />
|
||||
<div class="tips">注:第一张图为商品封面图,图片尺寸为750×750(可拖动图片排序)</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="套餐商品" v-if="shopTypes[shopTypesActive].typeEnum == 'group'">
|
||||
<el-table :data="form.groupSnap" border v-if="form.groupSnap.length">
|
||||
<el-table-column label="标题" prop="title">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.title" placeholder="请输入标题:自选小吃"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_list">
|
||||
<div class="item" v-for="item in scope.row.goods" :key="item.id">
|
||||
<span class="dot"></span>
|
||||
<div class="name">
|
||||
<div class="t">{{ item.name }}</div>
|
||||
</div>
|
||||
<i class="del el-icon-delete"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="几选几">
|
||||
<template v-slot="scope">
|
||||
<span>{{ scope.row.goods.length }}选</span>
|
||||
<el-input-number v-model="scope.row.number" controls-position="right"
|
||||
:min="1"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="160">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="tableAddShop(scope.$index, scope.row.goods)">添加商品</el-button>
|
||||
<el-button type="text" @click="form.groupSnap.splice(scope.$index, 1)">删除分组</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button type="text" @click="$refs.shopListRef.show()">添加分组</el-button>
|
||||
<shopList ref="shopListRef" @success="selectShopRes" />
|
||||
</el-form-item>
|
||||
<el-form-item label="规格属性" v-if="shopTypes[shopTypesActive].typeEnum != 'sku'">
|
||||
<el-table :data="form.skuList" border>
|
||||
<el-table-column label="售价" prop="salePrice">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.salePrice" controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会员价" prop="memberPrice">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.memberPrice"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价" prop="costPrice">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.costPrice" controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原价" prop="originPrice">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.originPrice"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存数量" prop="stockNumber">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.stockNumber" :disabled="!!form.id"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分销金额" prop="firstShared">
|
||||
<template v-slot="scope">
|
||||
<el-input-number v-model="scope.row.firstShared"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品条码">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.barCode" disabled></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="tips" v-if="form.isShowMall">注:小程序商城必须设置库存数量大于0</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择规格" v-if="shopTypes[shopTypesActive].typeEnum == 'sku' && !form.id">
|
||||
<el-select v-model="form.specId" placeholder="请选择规格" style="width: 500px;" @change="selectSpecHandle">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in specList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="item.name" v-if="selectSpec.length && !isEditor" v-for="item in selectSpec"
|
||||
:key="item.name">
|
||||
<el-checkbox-group v-model="item.selectSpecResult" @change="selectSpecResultChange">
|
||||
<el-checkbox :label="item" v-for="(item, index) in item.value
|
||||
" :key="index"></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="selectSpecResult && shopTypes[shopTypesActive].typeEnum == 'sku'">
|
||||
<el-table :data="form.skuList" border>
|
||||
<el-table-column :label="item.label" :prop="item.value" v-for="(item, index) in specTableHeaders"
|
||||
:key="index">
|
||||
</el-table-column>
|
||||
<el-table-column label="图片" prop="coverImg" width="80">
|
||||
|
||||
<template v-slot="scope">
|
||||
<uploadImg type="text" :limit="1" @success="res => scope.row.coverImg = res[0]"
|
||||
v-if="!scope.row.coverImg" />
|
||||
<el-image style="width:30px;height:30px;" :src="scope.row.coverImg" v-else />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售价" prop="salePrice">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>售价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('salePrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.salePrice" controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会员价" prop="memberPrice">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>会员价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('memberPrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.memberPrice"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价" prop="costPrice">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>成本价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('costPrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.costPrice" controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原价" prop="originPrice">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>原价</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('originPrice')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.originPrice"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存数量" prop="stockNumber">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>库存数量</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('stockNumber')" v-if="!form.id"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.stockNumber" :disabled="!!form.id"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分销金额" prop="firstShared">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<span>分销金额</span>
|
||||
<i class="icon el-icon-edit" @click="batchNumber('firstShared')"></i>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.firstShared"
|
||||
controls-position="right"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品条码">
|
||||
<template v-slot="scope">
|
||||
<el-input v-model="scope.row.barCode" disabled></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="form.skuList.splice(scope.$index, 1)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="tips" v-if="form.isShowMall">注:小程序商城必须设置库存数量大于0</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="上架区域">
|
||||
<div class="shop_type_box">
|
||||
<div class="item" :class="{ active: form.isShowCash }" @click="areaChange('isShowCash')">
|
||||
<div class="s_title">收银台</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" :class="{ active: form.isShowMall }" @click="areaChange('isShowMall')">
|
||||
<div class="s_title">小程序商城</div>
|
||||
<div class="active_dot">
|
||||
<i class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="库存开关">
|
||||
<el-switch v-model="form.isStock" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips">注:关闭则不计算出入库数据</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签打印">
|
||||
<el-switch v-model="form.enableLabel" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips">开启后: 收银完成后会自动打印对应数量的标签数</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="打包费">
|
||||
<el-input-number v-model="form.packFee" controls-position="right" :min="0"></el-input-number>
|
||||
<div class="tips">单份商品打包费。注:店铺开启外卖模式下该数据才生效</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="虚拟销量">
|
||||
<el-input-number v-model="form.baseSalesNumber" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sort" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" v-loading="loading" @click="submitHandle">确定</el-button>
|
||||
<el-button @click="$router.back()">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog title="批量修改" width="400px" :visible.sync="showBatchModal">
|
||||
<el-form :model="batchNumberForm">
|
||||
<el-form-item>
|
||||
<el-input-number v-model="batchNumberForm.batchNumber" :min="0" controls-position="right"
|
||||
style="width: 100%;"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="showBatchModal = false">取 消</el-button>
|
||||
<el-button type="primary" @click="batchNumberFormConfirm">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopUnit, tbShopCategoryGet, tbProductPost, tbProductSpecGet, tbProductGetDetail, tbProductPut } from "@/api/shop";
|
||||
import addUnit from './components/addUnit'
|
||||
import addClassify from './components/addClassify'
|
||||
import shopList from '@/components/shopList'
|
||||
import uploadImg from '@/components/uploadImg'
|
||||
import settings from '@/settings'
|
||||
import dayjs from 'dayjs'
|
||||
import { RandomNumBoth } from "@/utils";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
addUnit,
|
||||
addClassify,
|
||||
uploadImg,
|
||||
shopList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shopTypesActive: 0,
|
||||
shopTypes: settings.typeEnum,
|
||||
specTableHeaders: [],
|
||||
specTableBodys: [],
|
||||
specId: '',
|
||||
specList: [],
|
||||
selectSpec: [],
|
||||
selectSpecResult: false,
|
||||
defaultSku: {
|
||||
salePrice: 0,
|
||||
memberPrice: 0,
|
||||
costPrice: 0,
|
||||
originPrice: 0,
|
||||
stockNumber: 0,
|
||||
firstShared: 0,
|
||||
barCode: `${localStorage.getItem('shopId')}${dayjs().valueOf()}`
|
||||
},
|
||||
tableAddShopIndex: null,
|
||||
isEditor: false,
|
||||
loading: false,
|
||||
form: {
|
||||
id: '',
|
||||
typeEnum: 'normal',
|
||||
name: '',
|
||||
unitId: '',
|
||||
unitName: '',
|
||||
categoryId: '', // 商品分类id
|
||||
coverImg: '',
|
||||
images: [],
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
lowPrice: '',
|
||||
skuList: [],
|
||||
isShowMall: 1,
|
||||
isShowCash: 1,
|
||||
isStock: 0,
|
||||
packFee: 0,
|
||||
specId: '',
|
||||
baseSalesNumber: 0,
|
||||
sort: 0,
|
||||
groupSnap: [],
|
||||
specInfo: [],
|
||||
selectSpec: [],
|
||||
specTableHeaders: [],
|
||||
skuSnap: ''
|
||||
},
|
||||
rules: {
|
||||
typeEnum: [
|
||||
{
|
||||
required: true
|
||||
}
|
||||
],
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '请输入商品名称'
|
||||
}
|
||||
],
|
||||
categoryId: [
|
||||
{
|
||||
required: true,
|
||||
trigger: 'change',
|
||||
message: '请选择商品分类'
|
||||
}
|
||||
]
|
||||
},
|
||||
units: [],
|
||||
categorys: [],
|
||||
// 批量修改规格
|
||||
showBatchModal: false,
|
||||
batchNumberKey: '',
|
||||
batchNumberForm: {
|
||||
batchNumber: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbShopUnit()
|
||||
this.tbShopCategoryGet()
|
||||
this.changeTypeEnum(0)
|
||||
|
||||
if (this.$route.query.goods_id) {
|
||||
this.tbProductGetDetail()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 修改商家区域
|
||||
areaChange(key) {
|
||||
if (this.form[key] == 1) {
|
||||
this.form[key] = 0
|
||||
} else {
|
||||
this.form[key] = 1
|
||||
}
|
||||
},
|
||||
selectUnitt(e) {
|
||||
this.form.unitName = this.units.find(item => item.id == e).name
|
||||
},
|
||||
// 批量修改规格
|
||||
batchNumber(key) {
|
||||
this.batchNumberKey = key
|
||||
this.showBatchModal = true
|
||||
},
|
||||
// 确认批量修改规格
|
||||
batchNumberFormConfirm() {
|
||||
this.form.skuList.map(item => {
|
||||
item[this.batchNumberKey] = this.batchNumberForm.batchNumber
|
||||
})
|
||||
this.showBatchModal = false
|
||||
this.batchNumberForm.batchNumber = 0
|
||||
},
|
||||
// 商品详情
|
||||
async tbProductGetDetail() {
|
||||
try {
|
||||
const res = await tbProductGetDetail(this.$route.query.goods_id)
|
||||
|
||||
// 赋值商品类型
|
||||
this.changeTypeEnum(this.shopTypes.findIndex(item => item.typeEnum == res.typeEnum))
|
||||
this.specTableHeaders = JSON.parse(res.specTableHeaders)
|
||||
this.selectSpec = JSON.parse(res.selectSpec)
|
||||
|
||||
// 初始化上传图片
|
||||
this.$refs.uploadImg.fileList = res.images.map(item => {
|
||||
return {
|
||||
url: item
|
||||
}
|
||||
})
|
||||
|
||||
this.form = res
|
||||
if (res.typeEnum == 'sku') {
|
||||
let skuList = [...res.skuList]
|
||||
let specInfo = JSON.parse(res.specInfo)
|
||||
this.isEditor = true
|
||||
this.form.skuList = skuList.map((item, index) => {
|
||||
specInfo[index].id = item.id
|
||||
return specInfo[index]
|
||||
})
|
||||
this.selectSpecResult = true
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 提交
|
||||
submitHandle() {
|
||||
this.$refs.formRef.validate(async faild => {
|
||||
try {
|
||||
if (faild) {
|
||||
this.loading = true
|
||||
this.form.lowPrice = this.form.skuList[0].salePrice
|
||||
this.form.coverImg = this.form.images[0]
|
||||
this.form.selectSpec = JSON.stringify(this.selectSpec)
|
||||
this.form.specTableHeaders = JSON.stringify(this.specTableHeaders)
|
||||
this.form.specInfo = JSON.stringify(this.form.skuList)
|
||||
if (this.form.id) {
|
||||
await tbProductPut(this.form)
|
||||
} else {
|
||||
await tbProductPost(this.form)
|
||||
}
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.$router.back()
|
||||
this.loading = false
|
||||
}
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
console.log(error)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 给分组添加商品
|
||||
tableAddShop(index, goods) {
|
||||
this.tableAddShopIndex = index
|
||||
this.$refs.shopListRef.show([...goods])
|
||||
},
|
||||
// 分组选择商品
|
||||
selectShopRes(res) {
|
||||
if (this.tableAddShopIndex != null) {
|
||||
this.form.groupSnap[this.tableAddShopIndex].goods = res;
|
||||
this.tableAddShopIndex = null
|
||||
} else {
|
||||
this.form.groupSnap.push({
|
||||
title: '',
|
||||
goods: res,
|
||||
number: 1
|
||||
})
|
||||
}
|
||||
},
|
||||
// 切换类型
|
||||
changeTypeEnum(index) {
|
||||
if (this.form.id) return
|
||||
this.shopTypesActive = index
|
||||
const typeEnum = this.shopTypes[index].typeEnum
|
||||
this.form.typeEnum = typeEnum
|
||||
|
||||
if (typeEnum == 'sku') {
|
||||
this.tbProductSpecGet()
|
||||
} else {
|
||||
this.specId = ''
|
||||
this.form.specId = ''
|
||||
this.selectSpec = []
|
||||
this.selectSpecResult = ''
|
||||
this.form.skuList = [JSON.parse(JSON.stringify(this.defaultSku))]
|
||||
}
|
||||
},
|
||||
// 上传图片
|
||||
uploadSuccess(res) {
|
||||
this.form.images.push(res[0])
|
||||
},
|
||||
// 删除突破按
|
||||
uploadRemove(arr) {
|
||||
this.form.images = arr
|
||||
},
|
||||
// 选择规格属性
|
||||
selectSpecResultChange() {
|
||||
this.createSkuHeader()
|
||||
this.createSkuBody()
|
||||
},
|
||||
// 生成多规格表体
|
||||
createSkuBody() {
|
||||
let bodys = []
|
||||
let skuSnap = []
|
||||
for (let item of this.selectSpec) {
|
||||
if (item.selectSpecResult.length) {
|
||||
let arr = []
|
||||
for (let val of item.selectSpecResult) {
|
||||
arr.push({
|
||||
[item.name]: val
|
||||
})
|
||||
}
|
||||
skuSnap.push({
|
||||
name: item.name,
|
||||
value: item.selectSpecResult.join(',')
|
||||
})
|
||||
bodys.push(arr)
|
||||
}
|
||||
}
|
||||
this.form.skuSnap = JSON.stringify(skuSnap)
|
||||
|
||||
let arr = this.cartesian(bodys)
|
||||
// console.log(arr)
|
||||
let newarr = []
|
||||
|
||||
const m = {
|
||||
coverImg: '',
|
||||
...this.defaultSku
|
||||
}
|
||||
|
||||
for (let item of arr) {
|
||||
if (Array.isArray(item)) {
|
||||
let obj = {}
|
||||
let specSnap = []
|
||||
for (let v of item) {
|
||||
for (let key in v) {
|
||||
obj[`${key}`] = v[key]
|
||||
specSnap.push(v[key])
|
||||
}
|
||||
}
|
||||
newarr.push({
|
||||
specSnap: specSnap.join(','),
|
||||
...m,
|
||||
...obj,
|
||||
barCode: `${dayjs().valueOf()}${RandomNumBoth(1, 9999)}`
|
||||
})
|
||||
} else {
|
||||
let specSnap = []
|
||||
for (let key in item) {
|
||||
specSnap.push(item[key])
|
||||
}
|
||||
newarr.push({
|
||||
specSnap: specSnap.join(','),
|
||||
...m,
|
||||
...item,
|
||||
barCode: `${dayjs().valueOf()}${RandomNumBoth(1, 9999)}`
|
||||
})
|
||||
}
|
||||
}
|
||||
this.form.skuList = []
|
||||
this.form.skuList = newarr
|
||||
},
|
||||
// 笛卡尔积算法
|
||||
cartesian(arr) {
|
||||
if (arr.length < 2) return arr[0] || [];
|
||||
return [].reduce.call(arr, (col, set) => {
|
||||
let res = [];
|
||||
col.forEach(c => {
|
||||
set.forEach(s => {
|
||||
let t = [].concat(Array.isArray(c) ? c : [c]);
|
||||
t.push(s);
|
||||
res.push(t);
|
||||
})
|
||||
});
|
||||
return res;
|
||||
});
|
||||
},
|
||||
// 生成多规格表头
|
||||
createSkuHeader() {
|
||||
let i = 0
|
||||
const headers = []
|
||||
for (let item of this.selectSpec) {
|
||||
if (item.selectSpecResult.length) {
|
||||
i++
|
||||
headers.push({
|
||||
label: item.name,
|
||||
value: item.name
|
||||
})
|
||||
}
|
||||
}
|
||||
this.selectSpecResult = i
|
||||
this.specTableHeaders = headers
|
||||
},
|
||||
// 选择规格
|
||||
selectSpecHandle(e) {
|
||||
this.isEditor = false
|
||||
const selectSpec = JSON.parse(JSON.stringify(this.specList.find(item => item.id == e).specList))
|
||||
for (let item in selectSpec) {
|
||||
selectSpec[item].selectSpecResult = []
|
||||
}
|
||||
this.selectSpec = selectSpec
|
||||
this.form.skuList = []
|
||||
},
|
||||
// 获取规格列表
|
||||
async tbProductSpecGet() {
|
||||
try {
|
||||
const res = await tbProductSpecGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: 'id',
|
||||
page: 0,
|
||||
size: 100
|
||||
})
|
||||
this.specList = res.content
|
||||
} catch (error) { }
|
||||
},
|
||||
// 获取单位
|
||||
async tbShopUnit() {
|
||||
try {
|
||||
const res = await tbShopUnit({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: 'id',
|
||||
page: 0,
|
||||
size: 100
|
||||
})
|
||||
this.units = res.content
|
||||
} catch (error) { }
|
||||
},
|
||||
// 商品分类列表
|
||||
async tbShopCategoryGet() {
|
||||
try {
|
||||
const res = await tbShopCategoryGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
sort: 'id',
|
||||
page: 0,
|
||||
size: 100
|
||||
})
|
||||
let categorys = []
|
||||
for (let item of res.content) {
|
||||
categorys.push({
|
||||
name: `|----${item.name}`,
|
||||
id: item.id
|
||||
})
|
||||
if (item.childrenList.length) {
|
||||
for (let val of item.childrenList) {
|
||||
categorys.push({
|
||||
name: `|----|----${val.name}`,
|
||||
id: val.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.categorys = categorys
|
||||
} catch (error) {
|
||||
console.log('商品分类列表', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shop_list {
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.dot {
|
||||
$size: 6px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
background-color: #1890FF;
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
margin-left: 10px;
|
||||
|
||||
.t {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
max-width: 100px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.del {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 14px;
|
||||
color: #1890FF;
|
||||
margin-left: 10px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
130
src/views/product/category.vue
Normal file
130
src/views/product/category.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addClassifyRef.show()">添加分类</el-button>
|
||||
<addClassify ref="addClassifyRef" @success="getTableData" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading" row-key="id"
|
||||
:tree-props="{ children: 'childrenList' }">
|
||||
<el-table-column label="排序" prop="sort" sortable width="100"></el-table-column>
|
||||
<el-table-column label="分类名称" prop="name"></el-table-column>
|
||||
<el-table-column label="分类图片">
|
||||
<template v-slot="scope">
|
||||
<el-image :src="scope.row.pic"
|
||||
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>
|
||||
</div>
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.isShow" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="颜色">
|
||||
<template v-slot="scope">
|
||||
<div
|
||||
:style="{ width: '20px', height: '20px', borderRadius: '50%', backgroundColor: scope.row.style || '#efefef' }">
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini" round icon="el-icon-plus"
|
||||
@click="$refs.addClassifyRef.show({ pid: scope.row.id })"
|
||||
v-if="!scope.row.pid">添加子分类</el-button>
|
||||
<el-button type="text" size="mini" round icon="el-icon-edit"
|
||||
@click="$refs.addClassifyRef.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-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addClassify from './components/addClassify'
|
||||
import { tbShopCategoryGet, tbShopCategoryDelete } from '@/api/shop'
|
||||
export default {
|
||||
components: {
|
||||
addClassify
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 添加子分类
|
||||
addChildGatgory(row) {
|
||||
|
||||
},
|
||||
// 查询table
|
||||
toQuery() {
|
||||
this.getTableData()
|
||||
},// 重置查询
|
||||
resetHandle() {
|
||||
this.tableData.page = 0;
|
||||
this.query.blurry = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e -1;
|
||||
this.getTableData()
|
||||
},
|
||||
// 删除
|
||||
async delHandle(ids) {
|
||||
try {
|
||||
await tbShopCategoryDelete(ids)
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `删除成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopCategoryGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: 'id,desc',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
120
src/views/product/components/addClassify.vue
Normal file
120
src/views/product/components/addClassify.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<el-dialog title="添加分类" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<!-- <el-form-item label="层级">
|
||||
<el-select v-model="form.index">
|
||||
<el-option label="顶级" :value="1"></el-option>
|
||||
<el-option label="饮品" :value="2"></el-option>
|
||||
<el-option label="烤串" :value="3"></el-option>
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入分类名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类图片">
|
||||
<uploadImg ref="uploadImg" @success="res => form.pic = res[0]" @remove="form.pic = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item label="颜色标识">
|
||||
<el-color-picker v-model="form.style"></el-color-picker>
|
||||
<div style="color: #999;">
|
||||
标识色用在无图模式时的商品点单按钮显示,可以更有效的从视觉.上进行商品分组。
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="开关">
|
||||
<el-switch v-model="form.isShow" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sort" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uploadImg from '@/components/uploadImg'
|
||||
import { tbShopCategoryPost } from '@/api/shop'
|
||||
export default {
|
||||
components: {
|
||||
uploadImg
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
form: {
|
||||
id: '',
|
||||
pid: '',
|
||||
isShow: 1,
|
||||
name: '',
|
||||
sort: '',
|
||||
style: '#000000',
|
||||
pic: ''
|
||||
},
|
||||
resetForm: '',
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form }
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
console.log(this.form)
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.form.shopId = localStorage.getItem('shopId')
|
||||
let res = await tbShopCategoryPost(this.form, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
// console.log(obj)
|
||||
this.dialogVisible = true
|
||||
if (obj.pid) {
|
||||
this.form.pid = obj.pid
|
||||
}
|
||||
if (obj && obj.id) {
|
||||
this.form = obj
|
||||
if (obj.pic) {
|
||||
setTimeout(() => {
|
||||
this.$refs.uploadImg.fileList = [
|
||||
{
|
||||
url: obj.pic
|
||||
}
|
||||
]
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form = { ...this.resetForm }
|
||||
this.$refs.uploadImg.clearFiles()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
222
src/views/product/components/addGroup.vue
Normal file
222
src/views/product/components/addGroup.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog title="添加分组" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="分组名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入分组名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择商品">
|
||||
<div>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.shopListRef.show([...productIds])">
|
||||
添加商品
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="shop_list">
|
||||
<div class="item_wrap" v-for="(item, index) in productIds" :key="item.id"
|
||||
@click="productIds.splice(index, 1)">
|
||||
<div class="item" :data-index="index + 1">
|
||||
<el-image :src="item.coverImg" style="width: 100%;height: 100%;"></el-image>
|
||||
</div>
|
||||
<div class="name">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组状态">
|
||||
<el-radio-group v-model="form.isShow">
|
||||
<el-radio :label="1">启用</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组排序">
|
||||
<el-input-number v-model="form.sort" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<shopList ref="shopListRef" @success="slectShop" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbProductGroupPost, tbProductGroupPut, productListGet } from '@/api/shop'
|
||||
import shopList from '@/components/shopList'
|
||||
export default {
|
||||
components: {
|
||||
shopList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
loading: false,
|
||||
form: {
|
||||
id: '',
|
||||
name: '',
|
||||
isShow: 1,
|
||||
sort: 0,
|
||||
productIds: [],
|
||||
shopId: localStorage.getItem('shopId')
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
productIds: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
slectShop(res) {
|
||||
if (this.productIds.length) {
|
||||
res.map(async item => {
|
||||
if (!await this.checkShop(item.id)) {
|
||||
this.productIds.push({ ...item })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.productIds = res
|
||||
}
|
||||
},
|
||||
// 判断是否存在重复商品
|
||||
checkShop(id) {
|
||||
let falg = false
|
||||
this.productIds.map(item => {
|
||||
if (item.id == id) {
|
||||
falg = true
|
||||
}
|
||||
})
|
||||
return falg
|
||||
},
|
||||
onSubmitHandle() {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
try {
|
||||
this.form.productIds = this.productIds.map(item => item.id);
|
||||
let res = null
|
||||
if (!this.form.id) {
|
||||
await tbProductGroupPost(this.form)
|
||||
} else {
|
||||
await tbProductGroupPut(this.form)
|
||||
}
|
||||
this.loading = false
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async getProduts() {
|
||||
try {
|
||||
const res = await productListGet(this.form.id)
|
||||
this.productIds = res
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
show(obj) {
|
||||
if (obj && obj.id) {
|
||||
this.form.id = obj.id
|
||||
this.form.isShow = obj.isShow
|
||||
this.form.name = obj.name
|
||||
this.form.sort = obj.sort
|
||||
this.form.productIds = obj.productIds
|
||||
this.getProduts()
|
||||
}
|
||||
this.dialogVisible = true
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.isShow = 1
|
||||
this.form.name = ''
|
||||
this.form.sort = 0
|
||||
this.form.productIds = []
|
||||
this.productIds = []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shop_list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item_wrap {
|
||||
$size: 80px;
|
||||
|
||||
.item {
|
||||
$radius: 4px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: $radius;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
margin-top: 10px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: attr(data-index);
|
||||
font-size: 12px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
border-radius: 0 0 $radius 0;
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(10px);
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '删除';
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(10px);
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
transition: all .1s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
width: $size;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
203
src/views/product/components/addSpecification.vue
Normal file
203
src/views/product/components/addSpecification.vue
Normal file
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<el-dialog title="添加模板" width="840px" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px" label-position="left">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="模板名称,如:衣服"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="item.name" v-for="(item, index) in form.specList" :key="index">
|
||||
<div class="tag_wrap">
|
||||
<el-tag v-for="(val, i) in item.value" :key="i" closable size="medium" :disable-transitions="true"
|
||||
@close="handleClose(index, i)">
|
||||
{{ val }}
|
||||
</el-tag>
|
||||
<el-input class="input-new-tag" v-show="item.inputVisible" v-model="item.inputValue" ref="saveTagInput"
|
||||
size="small" placeholder="请输入规格值,回车添加" @keyup.enter.native="handleInputConfirm(index)"
|
||||
@blur="handleInputConfirm(index)">
|
||||
</el-input>
|
||||
<el-button v-show="!item.inputVisible" size="mini" icon="el-icon-plus" plain @click="showInput(index)">
|
||||
添加
|
||||
</el-button>
|
||||
<el-button size="mini" icon="el-icon-delete" plain @click="deleteTag(index)">删除</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form ref="skuForm" :model="skuForm" :rules="skuRules" label-width="80px" label-position="left">
|
||||
<el-row :gutter="20" v-if="showSkuForm">
|
||||
<el-col :span="10">
|
||||
<el-form-item label="规格" prop="skuValidate1">
|
||||
<el-input v-model="skuForm.label" placeholder="规格,如:尺码"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item label="规格值" prop="skuValidate2">
|
||||
<el-input v-model="skuForm.value" placeholder="规格值,如:S、M"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button type="primary" @click="addSkuSubmit">添加</el-button>
|
||||
<el-button @click="showSkuForm = false">取消</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item v-if="!showSkuForm">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="showSkuForm = true">添加规格</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbProductSpecPost, tbProductSpecPut } from '@/api/shop'
|
||||
export default {
|
||||
data() {
|
||||
const validateSku1 = (rule, value, callback) => {
|
||||
if (!this.skuForm.label) {
|
||||
callback(new Error(' '))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validateSku2 = (rule, value, callback) => {
|
||||
if (!this.skuForm.value) {
|
||||
callback(new Error(' '))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
dialogVisible: false,
|
||||
showSkuForm: true,
|
||||
skuForm: {
|
||||
label: '',
|
||||
value: ''
|
||||
},
|
||||
skuRules: {
|
||||
skuValidate1: {
|
||||
required: true,
|
||||
validator: validateSku1,
|
||||
trigger: 'blur'
|
||||
},
|
||||
skuValidate2: {
|
||||
required: true,
|
||||
validator: validateSku2,
|
||||
trigger: 'blur'
|
||||
}
|
||||
},
|
||||
form: {
|
||||
id: '',
|
||||
name: '',
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
specList: []
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
console.log(this.form)
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
let res = null
|
||||
if (!this.form.id) {
|
||||
res = await tbProductSpecPost(this.form)
|
||||
} else {
|
||||
res = await tbProductSpecPut(this.form)
|
||||
}
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.pid ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
const newObj = JSON.parse(JSON.stringify(obj));
|
||||
this.form.id = newObj.id
|
||||
this.form.name = newObj.name
|
||||
const specList = newObj.specList
|
||||
for (let item of specList) {
|
||||
item.inputVisible = false
|
||||
item.inputValue = ''
|
||||
}
|
||||
this.form.specList = specList
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.id = ''
|
||||
this.form.name = ''
|
||||
this.form.specList = []
|
||||
},
|
||||
// sku from
|
||||
addSkuSubmit() {
|
||||
this.$refs.skuForm.validate(async valid => {
|
||||
if (valid) {
|
||||
this.form.specList.push({
|
||||
name: this.skuForm.label,
|
||||
value: [this.skuForm.value],
|
||||
inputVisible: false,
|
||||
inputValue: ''
|
||||
})
|
||||
this.skuForm.label = ''
|
||||
this.skuForm.value = ''
|
||||
this.showSkuForm = false
|
||||
}
|
||||
})
|
||||
},
|
||||
handleClose(index, i) {
|
||||
this.form.specList[index].value.splice(i, 1);
|
||||
},
|
||||
showInput(index) {
|
||||
this.form.specList[index].inputVisible = true;
|
||||
},
|
||||
handleInputConfirm(index) {
|
||||
let inputValue = this.form.specList[index].inputValue;
|
||||
if (inputValue) {
|
||||
this.form.specList[index].value.push(inputValue);
|
||||
}
|
||||
this.form.specList[index].inputVisible = false;
|
||||
this.form.specList[index].inputValue = '';
|
||||
},
|
||||
// 删除已添加的规格
|
||||
deleteTag(index) {
|
||||
this.form.specList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tag_wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.input-new-tag {
|
||||
width: 180px;
|
||||
margin-left: 10px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
</style>
|
||||
86
src/views/product/components/addUnit.vue
Normal file
86
src/views/product/components/addUnit.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<el-dialog title="添加单位" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120" label-position="left">
|
||||
<el-form-item label="单位名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="单位名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input v-model="form.sort"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopUnitPost, tbShopUnitPut } from '@/api/shop'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
formLoading: false,
|
||||
form: {
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.formLoading = true
|
||||
let res = null
|
||||
if (!this.form.id) {
|
||||
res = await tbShopUnitPost(this.form)
|
||||
} else {
|
||||
res = await tbShopUnitPut(this.form)
|
||||
}
|
||||
this.close()
|
||||
this.formLoading = false
|
||||
this.$emit('success', res)
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
this.formLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
// 编辑
|
||||
this.form.name = obj.name
|
||||
this.form.id = obj.id
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.id = ''
|
||||
this.form.name = ''
|
||||
this.form.sort = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,128 +1,99 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
<!--表单组件(增改)-->
|
||||
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
|
||||
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-form-item label="分组名称" prop="name">
|
||||
<el-input v-model="form.name" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图标">
|
||||
<el-input v-model="form.pic" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示:" prop="isShow">
|
||||
<el-input v-model="form.isShow" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类描述">
|
||||
<el-input v-model="form.detail" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="添加商品">
|
||||
<el-input v-model="form.productIds" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
|
||||
<el-button type="primary" @click="addProduct">+添加商品
|
||||
<el-dialog title="选择商品" :visible.sync="productClick">
|
||||
<el-table :data="productList.content" style="width: 100%;">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column property="name" label="商品信息" width="150" />
|
||||
<el-table-column property="lowPrice" label="售价" width="200" />
|
||||
<el-table-column property="address" label="地址" />
|
||||
</el-table>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="centerDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addProduct">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addGroupRef.show()">
|
||||
添加分组
|
||||
</el-button>
|
||||
|
||||
<el-form-item label="创建时间">
|
||||
<el-input v-model="form.createdAt" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||
<addGroup ref="addGroupRef" @success="resetHandle" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--表格渲染(查)-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="name" label="分组名称" />
|
||||
<el-table-column prop="pic" label="图标" />
|
||||
<el-table-column prop="isShow" label="是否显示" />
|
||||
<el-table-column prop="detail" label="分类描述" />
|
||||
<el-table-column prop="productIds" label="商品列表" />
|
||||
<el-table-column prop="createdAt" label="创建时间" />
|
||||
<el-table-column v-if="checkPer(['admin','tbProductGroup:edit','tbProductGroup:del'])" label="操作" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
/>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="排序" sortable prop="sort"></el-table-column>
|
||||
<el-table-column label="分组名称" prop="name"></el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.isShow" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini" round icon="el-icon-edit"
|
||||
@click="$refs.addGroupRef.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-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudTbProductGroup from '@/api/tbProductGroup'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import udOperation from '@crud/UD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
import { addProduct } from '@/api/tbProductGroup'
|
||||
|
||||
const defaultForm = { id: null, name: null, merchantId: null, shopId: null, pic: null, isShow: null, detail: null, style: null, sort: null, productIds: null, createdAt: null, updatedAt: null }
|
||||
import addGroup from '../components/addGroup'
|
||||
import { tbProductGroupGet, tbProductGroupDelete } from '@/api/shop'
|
||||
export default {
|
||||
name: 'TbProductGroup',
|
||||
components: { pagination, crudOperation, rrOperation, udOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({ title: 'product/group', url: 'api/tbProductGroup', idField: 'id', sort: 'id,desc', crudMethod: { ...crudTbProductGroup }})
|
||||
components: {
|
||||
addGroup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permission: {
|
||||
add: ['admin', 'tbProductGroup:add'],
|
||||
edit: ['admin', 'tbProductGroup:edit'],
|
||||
del: ['admin', 'tbProductGroup:del']
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '分组名称不能为空', trigger: 'blur' }
|
||||
],
|
||||
isShow: [
|
||||
{ required: true, message: '是否显示:1显示 0不显示不能为空', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
productList: [],
|
||||
productClick: false
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
addProduct(data) {
|
||||
this.productClick = true
|
||||
addProduct(data).then(res => {
|
||||
this.productList = res
|
||||
methods: {
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 删除
|
||||
async delHandle(ids) {
|
||||
try {
|
||||
await tbProductGroupDelete(ids)
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `删除成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProductGroupGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: 'id',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -3,30 +3,21 @@
|
||||
<div class="head-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="3">
|
||||
<el-input
|
||||
v-model="query.blurry"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="请输入商品名称"
|
||||
style="width: 100%;"
|
||||
class="filter-item"
|
||||
@keyup.enter.native="toQuery"
|
||||
/>
|
||||
<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.class" placeholder="请选择商品分类" style="width: 100%;">
|
||||
<el-option label="饮品" :value="1" />
|
||||
<el-option label="烤串" :value="2" />
|
||||
<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.sku" placeholder="请选择商品规格" style="width: 100%;">
|
||||
<el-option label="饮品" :value="1" />
|
||||
<el-option label="烤串" :value="2" />
|
||||
<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="toQuery">查询</el-button>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -34,19 +25,23 @@
|
||||
<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>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.data">
|
||||
<el-table :data="tableData.data" v-loading="tableData.loading">
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
<el-image
|
||||
:src="scope.row.coverImg"
|
||||
style="width: 50px;height: 50px;border-radius: 4px;background-color: #efefef;"
|
||||
/>
|
||||
<el-image :src="scope.row.coverImg"
|
||||
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>
|
||||
</div>
|
||||
</el-image>
|
||||
<div class="info">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</div>
|
||||
@@ -60,77 +55,125 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="销量/库存">
|
||||
<template v-slot="scope">
|
||||
<span>{{ scope.row.xl }}/{{ scope.row.kc }}</span>
|
||||
<span>{{ scope.row.realSalesNumber }}/{{ scope.row.stockNumber }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架区域">
|
||||
<template v-slot="scope">
|
||||
<div v-if="scope.row.isShowCash">收银端</div>
|
||||
<div v-if="scope.row.isShowMall">小程序</div>
|
||||
<div v-if="!scope.row.isShowCash && !scope.row.isShowMall">未上架</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上架区域" prop="area" />
|
||||
<el-table-column label="排序" prop="sort" sortable />
|
||||
<el-table-column label="更新时间" prop="update" />
|
||||
<el-table-column label="更新时间" prop="createdAt">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.createdAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button type="primary" size="mini" round icon="el-icon-edit">编辑</el-button>
|
||||
<el-button type="danger" size="mini" round icon="el-icon-delete">删除</el-button>
|
||||
<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-popconfirm 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>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbProduct } from '@/api/shop'
|
||||
import dayjs from 'dayjs'
|
||||
import settings from '@/settings'
|
||||
import { tbProduct, tbShopCategoryGet, tbProductDelete } from '@/api/shop'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayjs,
|
||||
query: {
|
||||
blurry: '',
|
||||
class: '',
|
||||
sku: ''
|
||||
name: '',
|
||||
categoryId: '',
|
||||
typeEnum: ''
|
||||
},
|
||||
categorys: [],
|
||||
typeEnums: settings.typeEnum,
|
||||
tableData: {
|
||||
data: [
|
||||
{
|
||||
url: 'https://cash-register.oss-cn-beijing.aliyuncs.com/shop/f12c3cc097e147daa33ac4b55aca8ef3/2023-08-21/20230821-110556-2425668054.png?x-oss-process=image/resize,w_50,h_50,m_fill',
|
||||
title: '套餐商品',
|
||||
class: '烤串',
|
||||
price: 2,
|
||||
xl: 0,
|
||||
kc: 0,
|
||||
area: '收银端',
|
||||
sort: 0,
|
||||
update: '2023-11-20 16:08'
|
||||
}
|
||||
],
|
||||
data: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false
|
||||
loading: false,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbProduct()
|
||||
this.getTableData()
|
||||
this.tbShopCategoryGet()
|
||||
},
|
||||
methods: {
|
||||
// 查询
|
||||
toQuery() {
|
||||
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.blurry = ''
|
||||
this.query.class = ''
|
||||
this.query.sku = ''
|
||||
this.query.name = ''
|
||||
this.query.categoryId = ''
|
||||
this.query.typeEnum = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 获取商品列表
|
||||
async tbProduct() {
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProduct({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size
|
||||
size: this.tableData.size,
|
||||
name: this.query.name,
|
||||
categoryId: this.query.categoryId,
|
||||
typeEnum: this.query.typeEnum,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.data = res.content
|
||||
} catch (error) { }
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取商品分类列表
|
||||
async tbShopCategoryGet() {
|
||||
try {
|
||||
const res = await tbShopCategoryGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
page: 0,
|
||||
size: 100,
|
||||
sort: 'id'
|
||||
})
|
||||
this.categorys = res.content
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 删除商品
|
||||
async delTableHandle(ids) {
|
||||
try {
|
||||
await tbProductDelete(ids)
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -141,7 +184,13 @@ export default {
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 4px;
|
||||
padding-left: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.tag_wrap {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
118
src/views/product/specification.vue
Normal file
118
src/views/product/specification.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-input v-model="query.blurry" size="small" clearable placeholder="请输入模板名称" style="width: 100%;"
|
||||
class="filter-item" @keyup.enter.native="getTableData" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addSpecificationRef.show()">添加规格</el-button>
|
||||
<addSpecification ref="addSpecificationRef" @success="getTableData" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="模板名称" prop="name"></el-table-column>
|
||||
<el-table-column label="规格详情">
|
||||
<template v-slot="scope">
|
||||
<el-row v-for="(item, index) in scope.row.specList" :key="index">
|
||||
<span>{{ item.name }}:</span>
|
||||
<span>{{ item.value.join('、') }}</span>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" sortable></el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini" round icon="el-icon-edit"
|
||||
@click="$refs.addSpecificationRef.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-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addSpecification from './components/addSpecification'
|
||||
import { tbProductSpecGet, tbProductSpecDelete } from '@/api/shop'
|
||||
export default {
|
||||
components: {
|
||||
addSpecification
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
blurry: '',
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.blurry = ''
|
||||
this.tableData.page = 0;
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 删除
|
||||
async delHandle(ids) {
|
||||
try {
|
||||
const res = await tbProductSpecDelete(ids)
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `删除成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbProductSpecGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: 'id',
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
112
src/views/product/unit.vue
Normal file
112
src/views/product/unit.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-input v-model="query.blurry" size="small" clearable placeholder="请输入单位名称" style="width: 100%;"
|
||||
class="filter-item" @keyup.enter.native="toQuery" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button type="primary" @click="toQuery">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addUnitRef.show()">添加单位</el-button>
|
||||
<addUnit ref="addUnitRef" @success="getTableData()" />
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="单位名称" prop="name"></el-table-column>
|
||||
<el-table-column label="排序" prop="id" sortable></el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" size="mini" round icon="el-icon-edit"
|
||||
@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-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
|
||||
@current-change="paginationChange" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopCurrencyGet, tbShopUnitDelete } from '@/api/shop'
|
||||
import addUnit from './components/addUnit'
|
||||
export default {
|
||||
components: {
|
||||
addUnit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
blurry: ''
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 查询table
|
||||
toQuery() {
|
||||
this.getTableData()
|
||||
},// 重置查询
|
||||
resetHandle() {
|
||||
this.tableData.page = 0;
|
||||
this.query.blurry = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1;
|
||||
this.getTableData()
|
||||
},
|
||||
// 删除
|
||||
async delHandle(ids) {
|
||||
try {
|
||||
await tbShopUnitDelete(ids)
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `删除成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.getTableData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopCurrencyGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
sort: 'id',
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
name: this.query.blurry
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
80
src/views/register/components/addActivationCode.vue
Normal file
80
src/views/register/components/addActivationCode.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<el-dialog title="生产激活码" :visible.sync="dialogVisible" width="500px" @close="reset">
|
||||
<el-form :model="form" :rules="rules" label-width="100px" label-position="left">
|
||||
<el-form-item label="激活时长" prop="periodYear">
|
||||
<el-input-number v-model="form.periodYear" controls-position="right" :min="1" :step="1"
|
||||
step-strictly></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="生产数量" prop="number">
|
||||
<el-input-number v-model="form.number" controls-position="right" :min="1" :step="1"
|
||||
step-strictly></el-input-number>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="所属代理" prop="agent">
|
||||
<el-input v-model="form.agent" placeholder="请输入完整的代理账号查找"></el-input>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" v-loading="loading" @click="tbMerchantRegisterPost">生产激活码</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbMerchantRegisterPost } from '@/api/shop.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
loading: false,
|
||||
form: {
|
||||
periodYear: 1,
|
||||
number: 1,
|
||||
agent: ''
|
||||
},
|
||||
rules: {
|
||||
periodYear: [{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}],
|
||||
number: [{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async tbMerchantRegisterPost() {
|
||||
try {
|
||||
this.loading = true
|
||||
const res = await tbMerchantRegisterPost(this.form)
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `添加成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
show() {
|
||||
this.dialogVisible = true
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.periodYear = 1
|
||||
this.form.number = 1
|
||||
this.form.agent = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,146 +1,160 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<!-- 搜索 -->
|
||||
<label class="el-form-item-label">id</label>
|
||||
<el-input v-model="query.id" clearable placeholder="id" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">激活码</label>
|
||||
<el-input v-model="query.registerCode" clearable placeholder="激活码" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">店铺名称</label>
|
||||
<el-input v-model="query.shopName" clearable placeholder="店铺名称" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">版本类型</label>
|
||||
<el-input v-model="query.type" clearable placeholder="版本类型" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">激活码金额</label>
|
||||
<el-input v-model="query.amount" clearable placeholder="激活码金额" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">激活时长(月)</label>
|
||||
<el-input v-model="query.periodYear" clearable placeholder="激活时长(月)" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">状态0未使用1已使用</label>
|
||||
<el-input v-model="query.status" clearable placeholder="状态0未使用1已使用" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">创建时间</label>
|
||||
<el-input v-model="query.createdAt" clearable placeholder="创建时间" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<rrOperation :crud="crud" />
|
||||
<div class="filter_wrap">
|
||||
<!-- <el-input v-model="query.name" size="small" clearable placeholder="请输入完整的代理商账号查找" style="width: 250px"
|
||||
@keyup.enter.native="getTableData" /> -->
|
||||
<el-select v-model="query.type" placeholder="请选择类型" style="width: 200px">
|
||||
<el-option label="快餐版" value="munchies" />
|
||||
<el-option label="餐饮版" value="restaurant" />
|
||||
</el-select>
|
||||
<el-select v-model="query.status" placeholder="请选择状态" style="width: 200px">
|
||||
<el-option label="待激活" :value="0" />
|
||||
<el-option label="已使用" :value="1" />
|
||||
</el-select>
|
||||
<el-date-picker v-model="query.createdAt" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" style="width: 400px" @change="getTableData">
|
||||
</el-date-picker>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</div>
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
<!--表单组件-->
|
||||
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
|
||||
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-form-item label="id" prop="id">
|
||||
<el-input v-model="form.id" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="激活码">
|
||||
<el-input v-model="form.registerCode" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称">
|
||||
<el-input v-model="form.shopName" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="版本类型">
|
||||
<el-input v-model="form.type" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="激活码金额">
|
||||
<el-input v-model="form.amount" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="激活时长(月)">
|
||||
<el-input v-model="form.periodYear" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态0未使用1已使用">
|
||||
<el-input v-model="form.status" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-input v-model="form.createdAt" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="id" label="id" />
|
||||
<el-table-column prop="registerCode" label="激活码" />
|
||||
<el-table-column prop="shopName" label="店铺名称" />
|
||||
<el-table-column prop="type" label="版本类型">
|
||||
<template slot-scope="scope">
|
||||
{{ dict.label.register_type[scope.row.type] }}
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addActivationCode.show()">添加激活码</el-button>
|
||||
<el-button icon="el-icon-download">导出Excel</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="激活码" prop="registerCode" width="500px">
|
||||
<template v-slot="scope">
|
||||
<el-tooltip content="点击复制">
|
||||
<el-tag type="success" @click="copyHandle(scope.row.registerCode)">
|
||||
<i class="el-icon-paperclip"></i>
|
||||
{{ scope.row.registerCode }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="amount" label="激活码金额" />
|
||||
<el-table-column prop="periodYear" label="激活时长(月)" />
|
||||
<el-table-column prop="status" label="状态0未使用1已使用">
|
||||
<template slot-scope="scope">
|
||||
{{ dict.label.register_status[scope.row.status] }}
|
||||
<el-table-column label="商户名称" prop="name"></el-table-column>
|
||||
<el-table-column label="联系电话" prop="telephone"></el-table-column>
|
||||
<el-table-column label="版本类型" prop="type">
|
||||
<template v-slot="scope">
|
||||
<span v-if="scope.row.type == 'munchies'">快餐版</span>
|
||||
<span v-if="scope.row.type == 'restaurant'">餐饮版</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="创建时间" />
|
||||
<el-table-column v-if="checkPer(['admin','viewRegister:edit','viewRegister:del'])" label="操作" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
/>
|
||||
<el-table-column label="激活时长" prop="periodYear"></el-table-column>
|
||||
<el-table-column label="状态" prop="status">
|
||||
<template v-slot="scope">
|
||||
<el-tag type="info" v-if="scope.row.status == 0">待激活</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status == 1">已使用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createdAt">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.createdAt && dayjs(scope.row.createdAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</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>
|
||||
</div>
|
||||
<addActivationCode ref="addActivationCode" @success="getTableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudViewRegister from '@/api/viewRegister'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import udOperation from '@crud/UD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { id: null, registerCode: null, shopName: null, type: null, amount: null, periodYear: null, status: null, createdAt: null }
|
||||
import dayjs from 'dayjs'
|
||||
import { tbMerchantRegisterList } from '@/api/shop.js'
|
||||
import addActivationCode from './components/addActivationCode'
|
||||
import VueClipboard from 'vue-clipboard2'
|
||||
export default {
|
||||
name: 'ViewRegister',
|
||||
components: { pagination, crudOperation, rrOperation, udOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
dicts: ['register_type', 'register_status'],
|
||||
cruds() {
|
||||
return CRUD({ title: '/register', url: 'api/viewRegister', idField: 'id', sort: 'id,desc', crudMethod: { ...crudViewRegister }})
|
||||
},
|
||||
components: { addActivationCode },
|
||||
data() {
|
||||
return {
|
||||
permission: {
|
||||
add: ['admin', 'viewRegister:add'],
|
||||
edit: ['admin', 'viewRegister:edit'],
|
||||
del: ['admin', 'viewRegister:del']
|
||||
dayjs,
|
||||
query: {
|
||||
name: '',
|
||||
type: '',
|
||||
status: '',
|
||||
createdAt: []
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: '不能为空', trigger: 'blur' }
|
||||
]
|
||||
status: [
|
||||
{
|
||||
type: 1,
|
||||
label: '开启'
|
||||
},
|
||||
queryTypeOptions: [
|
||||
{ key: 'id', display_name: 'id' },
|
||||
{ key: 'registerCode', display_name: '激活码' },
|
||||
{ key: 'shopName', display_name: '店铺名称' },
|
||||
{ key: 'type', display_name: '版本类型' },
|
||||
{ key: 'amount', display_name: '激活码金额' },
|
||||
{ key: 'periodYear', display_name: '激活时长(月)' },
|
||||
{ key: 'status', display_name: '状态0未使用1已使用' },
|
||||
{ key: 'createdAt', display_name: '创建时间' }
|
||||
]
|
||||
{
|
||||
type: 0,
|
||||
label: '关闭'
|
||||
}
|
||||
],
|
||||
tableData: {
|
||||
list: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
copyHandle(text) {
|
||||
this.$copyText(text).then((e) => {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `复制成功`,
|
||||
type: 'success'
|
||||
});
|
||||
})
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.account = ''
|
||||
this.query.status = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbMerchantRegisterList({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
type: this.query.type,
|
||||
status: this.query.status,
|
||||
createdAt: this.query.createdAt
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
351
src/views/shop/components/addShop.vue
Normal file
351
src/views/shop/components/addShop.vue
Normal file
@@ -0,0 +1,351 @@
|
||||
<template>
|
||||
<el-dialog :title="form.id ? '编辑店铺' : '添加店铺'" :visible.sync="dialogVisible" @close="reset">
|
||||
<div style="height: 50vh;overflow-y: auto;">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="店铺名称" prop="shopName">
|
||||
<el-input v-model="form.shopName" placeholder="请输入门店名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店logo" prop="logo">
|
||||
<el-image :src="form.logo || require('@/assets/images/upload.png')" fit="contain"
|
||||
style="width: 80px;height: 80px;" @click="showUpload = true; uploadIndex = 1"></el-image>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店照片">
|
||||
<el-image :src="form.coverImg || require('@/assets/images/upload.png')" fit="contain"
|
||||
style="width: 80px;height: 80px;" @click="showUpload = true; uploadIndex = 2"></el-image>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺类型">
|
||||
<el-radio-group v-model="form.registerType">
|
||||
<el-radio-button label="munchies">快餐版</el-radio-button>
|
||||
<el-radio-button label="restaurant">餐饮版</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips">请谨慎修改!!!</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="试用/正式">
|
||||
<el-radio-group v-model="form.profiles">
|
||||
<el-radio-button label="probation">试用</el-radio-button>
|
||||
<el-radio-button label="release">正式</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="激活码">
|
||||
<el-input v-model="form.registerCode" placeholder="请输入激活码"></el-input>
|
||||
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录账号" prop="account">
|
||||
<el-input v-model="form.account" placeholder="请输入登录账号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录密码" prop="password">
|
||||
<el-input type="password" show-password v-model="form.password" placeholder="请输入登录密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.phone" placeholder="请输入联系电话"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备数量">
|
||||
<el-input-number v-model="form.supportDeviceNumber" controls-position="right" :min="1" :step="1"
|
||||
step-strictly></el-input-number>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="外卖起送金额">
|
||||
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
||||
:min="0"></el-input-number>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="店铺经度">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-input v-model="form.lng" placeholder="经度"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-input v-model="form.lat" placeholder="纬度" style="margin-left: 10px;"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button type="primary" plain icon="el-icon-place" style="margin-left: 20px;"
|
||||
@click="showLocation = true">选择坐标</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺详细地址">
|
||||
<el-input type="textarea" v-model="form.address" placeholder="请输入门店详细地址"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺简介">
|
||||
<el-input type="textarea" v-model="form.detail" placeholder="请输入店铺简介"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :label="1">开启</el-radio>
|
||||
<el-radio :label="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-dialog title="选择地址" :visible.sync="showLocation" :modal="false" :modal-append-to-body="false">
|
||||
<div class="map_box">
|
||||
<div class="map">
|
||||
<el-amap :center="amapOptions.center">
|
||||
<el-amap-marker :position="amapOptions.center"></el-amap-marker>
|
||||
</el-amap>
|
||||
</div>
|
||||
<div class="search_box">
|
||||
<el-amap-search-box :search-option="searchOption"
|
||||
:on-search-result="onSearchResult"></el-amap-search-box>
|
||||
</div>
|
||||
|
||||
<div class="search_wrap">
|
||||
<div class="item" v-for="item in locationSearchList" :key="item.id">
|
||||
<div class="left">
|
||||
<div class="name">{{ item.name }}-{{ item.address }}</div>
|
||||
<div class="location">
|
||||
经纬度:{{ item.lng }},{{ item.lat }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="selectLocationHandle(item)">
|
||||
选择
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<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>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" style="display: block;" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
||||
</el-upload>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="doSubmit">确认</el-button>
|
||||
<el-button @click="uploadClose">取消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||
<span v-if="!formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { mapGetters } from 'vuex'
|
||||
import crudQiNiu from '@/api/tools/qiniu'
|
||||
import { tbShopInfoPost } from '@/api/shop'
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'qiNiuUploadApi'
|
||||
])
|
||||
},
|
||||
data() {
|
||||
const validateLogo = (rule, value, callback) => {
|
||||
if (!this.form.logo) {
|
||||
callback(new Error('请上传门店logo'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
dialogVisible: false,
|
||||
showLocation: false,
|
||||
showUpload: false,
|
||||
uploadIndex: 1,
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
formLoading: false,
|
||||
form: {
|
||||
id: '',
|
||||
shopName: '',
|
||||
registerType: 'restaurant',
|
||||
profiles: 'release',
|
||||
registerCode: '',
|
||||
account: '',
|
||||
password: '',
|
||||
phone: '',
|
||||
supportDeviceNumber: '',
|
||||
lat: '',
|
||||
lng: '',
|
||||
address: '',
|
||||
detail: '',
|
||||
status: 1,
|
||||
logo: '',
|
||||
coverImg: ''
|
||||
},
|
||||
resetForm: '',
|
||||
rules: {
|
||||
shopName: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
logo: [
|
||||
{
|
||||
required: true,
|
||||
validator: validateLogo,
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
account: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
},
|
||||
fileList: [],
|
||||
files: [],
|
||||
headers: {
|
||||
'Authorization': getToken()
|
||||
},
|
||||
searchOption: {
|
||||
city: '西安',
|
||||
citylimit: false
|
||||
},
|
||||
locationSearchList: [],
|
||||
amapOptions: {
|
||||
center: [108.946465, 34.347984],
|
||||
position: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form }
|
||||
},
|
||||
methods: {
|
||||
onSearchResult(res) {
|
||||
this.locationSearchList = res
|
||||
this.amapOptions.center = [res[0].lng, res[0].lat]
|
||||
},
|
||||
// 确认地址选择
|
||||
selectLocationHandle(item) {
|
||||
this.form.lng = item.lng
|
||||
this.form.lat = item.lat
|
||||
this.showLocation = false
|
||||
},
|
||||
// 保存
|
||||
submitHandle() {
|
||||
this.$refs.form.validate(async (valid) => {
|
||||
if (valid) {
|
||||
this.formLoading = true
|
||||
try {
|
||||
await tbShopInfoPost(this.form, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success')
|
||||
this.formLoading = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.close()
|
||||
} catch (error) {
|
||||
this.formLoading = false
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSuccess(response, file, fileList) {
|
||||
// const uid = file.uid
|
||||
// const id = response.id
|
||||
// this.files.push({ uid, id })
|
||||
console.log('上传成功', response)
|
||||
this.files = response.data
|
||||
},
|
||||
handleBeforeRemove(file, fileList) {
|
||||
for (let i = 0; i < this.files.length; i++) {
|
||||
if (this.files[i].uid === file.uid) {
|
||||
crudQiNiu.del([this.files[i].id]).then(res => { })
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
this.dialogImageUrl = file.url
|
||||
this.dialogVisible = true
|
||||
},
|
||||
// 监听上传失败
|
||||
handleError(e, file, fileList) {
|
||||
const msg = JSON.parse(e.message)
|
||||
this.crud.notify(msg.message, CRUD.NOTIFICATION_TYPE.ERROR)
|
||||
},
|
||||
// 刷新列表数据
|
||||
doSubmit() {
|
||||
this.fileList = []
|
||||
this.showUpload = false
|
||||
switch (this.uploadIndex) {
|
||||
case 1:
|
||||
this.form.logo = this.files[0]
|
||||
break;
|
||||
case 2:
|
||||
this.form.coverImg = this.files[0]
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form = { ...obj }
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
uploadClose() {
|
||||
this.showUpload = false
|
||||
},
|
||||
reset() {
|
||||
this.form = { ...this.resetForm }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.map_box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.map {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.search_box {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.search_wrap {
|
||||
padding: 6px 0;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
padding: 12px 0;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-right: 20px;
|
||||
|
||||
.location {
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
107
src/views/shop/components/detailModal.vue
Normal file
107
src/views/shop/components/detailModal.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-dialog :visible.sync="dialogVisible" :show-close="false" @close="reset">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="聚合支付" name="pay">
|
||||
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
||||
<el-form-item label="商户号">
|
||||
<el-input v-model="form.appId" placeholder="请输入商户号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户密钥">
|
||||
<el-input type="textarea" v-model="form.appToken" placeholder="请输入商户密钥"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付密码">
|
||||
<el-input v-model="form.payPassword" placeholder="请输入支付密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :label="1">启用</el-radio>
|
||||
<el-radio :label="-1">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||
<span v-if="!formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbMerchantThirdApply, tbMerchantThirdApplyPut } from '@/api/shop'
|
||||
export default ({
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
activeName: 'pay',
|
||||
formLoading: false,
|
||||
form: {
|
||||
appToken: '',
|
||||
id: '',
|
||||
payPassword: '',
|
||||
status: 1,
|
||||
appId: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 保存
|
||||
async submitHandle() {
|
||||
this.formLoading = true
|
||||
try {
|
||||
await tbMerchantThirdApplyPut(this.form)
|
||||
this.$emit('success')
|
||||
this.formLoading = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `提交成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.close()
|
||||
} catch (error) {
|
||||
this.formLoading = false
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.appToken = ''
|
||||
this.form.id = ''
|
||||
this.form.payPassword = ''
|
||||
this.form.status = 1
|
||||
this.form.appId = ''
|
||||
},
|
||||
// 详情(配置三方支付)
|
||||
async getDetail(id) {
|
||||
try {
|
||||
const res = await tbMerchantThirdApply(id)
|
||||
this.form.appToken = res.appToken
|
||||
this.form.payPassword = res.payPassword
|
||||
this.form.status = res.status
|
||||
this.form.appId = res.appId
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form.id = obj.merchantId
|
||||
this.getDetail(obj.merchantId)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep(.el-dialog__header) {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
313
src/views/shop/components/shopInfo.vue
Normal file
313
src/views/shop/components/shopInfo.vue
Normal file
@@ -0,0 +1,313 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="门店名称" prop="shopName">
|
||||
<el-input v-model="form.shopName" 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"
|
||||
style="width: 80px;height: 80px;" @click="showUpload = true; uploadIndex = 1"></el-image>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店照片">
|
||||
<el-image :src="form.coverImg || require('@/assets/images/upload.png')" fit="contain"
|
||||
style="width: 80px;height: 80px;" @click="showUpload = true; uploadIndex = 2"></el-image>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="phone">
|
||||
<el-input v-model="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"
|
||||
:min="0"></el-input-number>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="店铺经度">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-input v-model="form.lng" placeholder="经度"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-input v-model="form.lat" placeholder="纬度" style="margin-left: 10px;"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button type="primary" plain icon="el-icon-place" style="margin-left: 20px;"
|
||||
@click="showLocation = true">选择坐标</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<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-form-item>
|
||||
<el-form-item label="营业时间">
|
||||
<el-time-picker placeholder="起始时间" v-model="startTime" :picker-options="{
|
||||
selectableRange: '00:00:00 - 23:59:59',
|
||||
format: 'HH:mm'
|
||||
}" format="HH:mm" value-format="HH:mm">
|
||||
</el-time-picker>
|
||||
<el-time-picker placeholder="结束时间" v-model="endTime" :picker-options="{
|
||||
selectableRange: `${startTime}:00 - 23:59:59`
|
||||
}" format="HH:mm" value-format="HH:mm">
|
||||
</el-time-picker>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="结算类型">
|
||||
<el-radio-group v-model="form.settleType">
|
||||
<el-radio :label="0">今日</el-radio>
|
||||
<el-radio :label="1">次日</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="结算时间" prop="settleTime">
|
||||
<el-time-picker placeholder="请选择结算时间" v-model="form.settleTime" :picker-options="{
|
||||
selectableRange: '00:00:00 - 23:59:59',
|
||||
format: 'HH:mm'
|
||||
}" format="HH:mm" value-format="HH:mm">
|
||||
</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-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :label="1">营业中</el-radio>
|
||||
<el-radio :label="2">休息中</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||
<span v-if="!formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-dialog title="选择地址" :visible.sync="showLocation">
|
||||
<div class="map_box">
|
||||
<div class="map">
|
||||
<el-amap :center="amapOptions.center">
|
||||
<el-amap-marker :position="amapOptions.center"></el-amap-marker>
|
||||
</el-amap>
|
||||
</div>
|
||||
<div class="search_box">
|
||||
<el-amap-search-box :search-option="searchOption"
|
||||
:on-search-result="onSearchResult"></el-amap-search-box>
|
||||
</div>
|
||||
|
||||
<div class="search_wrap">
|
||||
<div class="item" v-for="item in locationSearchList" :key="item.id">
|
||||
<div class="left">
|
||||
<div class="name">{{ item.name }}-{{ item.address }}</div>
|
||||
<div class="location">
|
||||
经纬度:{{ item.lng }},{{ item.lat }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="selectLocationHandle(item)">
|
||||
选择
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<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>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" style="display: block;" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
||||
</el-upload>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="doSubmit">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { mapGetters } from 'vuex'
|
||||
import crudQiNiu from '@/api/tools/qiniu'
|
||||
import { tbShopInfo, tbShopInfoPut } from '@/api/user'
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'qiNiuUploadApi'
|
||||
])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showLocation: false,
|
||||
showUpload: false,
|
||||
uploadIndex: 1,
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
formLoading: false,
|
||||
form: {},
|
||||
rules: {
|
||||
shopName: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
settleTime: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
fileList: [],
|
||||
files: [],
|
||||
headers: {
|
||||
'Authorization': getToken()
|
||||
},
|
||||
searchOption: {
|
||||
city: '西安',
|
||||
citylimit: false
|
||||
},
|
||||
locationSearchList: [],
|
||||
amapOptions: {
|
||||
center: [108.946465, 34.347984],
|
||||
position: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbShopInfo()
|
||||
},
|
||||
methods: {
|
||||
onSearchResult(res) {
|
||||
this.locationSearchList = res
|
||||
this.amapOptions.center = [res[0].lng, res[0].lat]
|
||||
},
|
||||
// 确认地址选择
|
||||
selectLocationHandle(item) {
|
||||
this.form.lng = item.lng
|
||||
this.form.lat = item.lat
|
||||
this.showLocation = false
|
||||
},
|
||||
// 获取用户详情
|
||||
async tbShopInfo() {
|
||||
try {
|
||||
const shopId = localStorage.getItem('shopId')
|
||||
const res = await tbShopInfo(shopId)
|
||||
this.form = res
|
||||
if (res.businessTime) {
|
||||
const businessTime = res.businessTime.split('-')
|
||||
this.startTime = businessTime[0]
|
||||
this.endTime = businessTime[1]
|
||||
}
|
||||
} catch (error) { }
|
||||
},
|
||||
// 保存
|
||||
submitHandle() {
|
||||
this.$refs.form.validate(async (valid) => {
|
||||
if (valid) {
|
||||
this.formLoading = true
|
||||
try {
|
||||
if (this.startTime && this.endTime) {
|
||||
this.form.businessTime = `${this.startTime}-${this.endTime}`
|
||||
}
|
||||
console.log(this.startTime, this.endTime);
|
||||
const res = await tbShopInfoPut(this.form)
|
||||
this.formLoading = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '提交成功',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) { }
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSuccess(response, file, fileList) {
|
||||
// const uid = file.uid
|
||||
// const id = response.id
|
||||
// this.files.push({ uid, id })
|
||||
console.log('上传成功', response)
|
||||
this.files = response.data
|
||||
},
|
||||
handleBeforeRemove(file, fileList) {
|
||||
for (let i = 0; i < this.files.length; i++) {
|
||||
if (this.files[i].uid === file.uid) {
|
||||
crudQiNiu.del([this.files[i].id]).then(res => { })
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
this.dialogImageUrl = file.url
|
||||
this.dialogVisible = true
|
||||
},
|
||||
// 监听上传失败
|
||||
handleError(e, file, fileList) {
|
||||
const msg = JSON.parse(e.message)
|
||||
this.crud.notify(msg.message, CRUD.NOTIFICATION_TYPE.ERROR)
|
||||
},
|
||||
// 刷新列表数据
|
||||
doSubmit() {
|
||||
this.fileList = []
|
||||
this.showUpload = false
|
||||
switch (this.uploadIndex) {
|
||||
case 1:
|
||||
this.form.logo = this.files[0]
|
||||
break;
|
||||
case 2:
|
||||
this.form.coverImg = this.files[0]
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.map_box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.map {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.search_box {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.search_wrap {
|
||||
padding: 6px 0;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
padding: 12px 0;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-right: 20px;
|
||||
|
||||
.location {
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
85
src/views/shop/components/shopSetting.vue
Normal file
85
src/views/shop/components/shopSetting.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
||||
<el-form-item label="货币单位">
|
||||
<el-radio-group v-model="form.currency">
|
||||
<el-radio-button label="¥">¥</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备用金">
|
||||
<el-input v-model="form.prepareAmount" placeholder="0.00" style="width: 200px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="保留小数位">
|
||||
<el-radio-group v-model="form.decimalsDigits">
|
||||
<el-radio-button label="0">元</el-radio-button>
|
||||
<el-radio-button label="1">角</el-radio-button>
|
||||
<el-radio-button label="2">分</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="语音通知">
|
||||
<el-switch v-model="form.voiceNotification" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div style="color: #999;">开启后将语音播报待处理事件</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="移动端支付">
|
||||
<el-switch v-model="form.allowWebPay" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div style="color: #999;">是否允许用户在小程序端支付订单</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="自动锁屏">
|
||||
<el-select v-model="form.autoLockScreen" placeholder="请选择锁屏时间">
|
||||
<el-option label="不自动锁屏" :value="0"></el-option>
|
||||
<el-option label="30s" value="30"></el-option>
|
||||
<el-option label="1min" value="60s"></el-option>
|
||||
<el-option label="2min" value="120s"></el-option>
|
||||
<el-option label="5min" value="300s"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||
<span v-if="!formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopCurrency, tbShopCurrencyPut } from '@/api/shop'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
formLoading: false,
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbShopCurrency()
|
||||
},
|
||||
methods: {
|
||||
// 保存
|
||||
submitHandle() {
|
||||
this.$refs.form.validate(async (valid) => {
|
||||
if (valid) {
|
||||
this.formLoading = true
|
||||
try {
|
||||
const res = await tbShopCurrencyPut(this.form)
|
||||
this.formLoading = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '提交成功',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) { }
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取基本配置
|
||||
async tbShopCurrency() {
|
||||
try {
|
||||
const res = await tbShopCurrency(localStorage.getItem('shopId'))
|
||||
this.form = res
|
||||
} catch (error) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,135 +1,185 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
<!--表单组件-->
|
||||
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
|
||||
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-form-item label="自增id" prop="id">
|
||||
<el-input v-model="form.id" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺帐号">
|
||||
<el-input v-model="form.account" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称" prop="shopName">
|
||||
<el-input v-model="form.shopName" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.phone" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺log">
|
||||
<el-input v-model="form.logo" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="封面图">
|
||||
<el-input v-model="form.coverImg" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="详细地址">
|
||||
<el-input v-model="form.address" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="营业时间">
|
||||
<el-input v-model="form.businessTime" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="到期时间">
|
||||
<el-input v-model="form.expireAt" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店状态" prop="status">
|
||||
<el-input v-model="form.status" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||
<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-input v-model="query.account" 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.status" placeholder="请选择店铺状态" style="width: 100%;">
|
||||
<el-option :label="item.label" :value="item.type" v-for="item in status" :key="item.type" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addShop.show()">添加店铺</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||
<el-table-column label="店铺信息" width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
<el-image :src="scope.row.coverImg"
|
||||
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>
|
||||
</div>
|
||||
</el-image>
|
||||
<div class="info">
|
||||
<span>{{ scope.row.shopName }}</span>
|
||||
<div class="tag_wrap">
|
||||
<el-tag type="info" effect="dark" v-if="scope.row.profiles == 'no'">未激活</el-tag>
|
||||
<el-tag type="warning" effect="dark" v-if="scope.row.profiles == 'probation'">试用</el-tag>
|
||||
<el-tag type="success" effect="dark" v-if="scope.row.profiles == 'release'">正式</el-tag>
|
||||
<el-tag type="primary" effect="dark" v-if="scope.row.isWxMaIndependent">独立小程序</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="id" label="自增id" />
|
||||
<el-table-column prop="account" label="店铺帐号" />
|
||||
<el-table-column prop="shopName" label="店铺名称" />
|
||||
<el-table-column prop="phone" label="联系电话" />
|
||||
<el-table-column prop="logo" label="店铺log" width="100px">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.logo" width="80px" height="50px" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="coverImg" label="封面图" width="150px">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.coverImg" width="100px" height="100px" />
|
||||
<el-table-column prop="registerType" label="类型">
|
||||
<template v-slot="scope">
|
||||
<span v-if="scope.row.registerType == 'munchies'">快餐版</span>
|
||||
<span v-if="scope.row.registerType == 'restaurant'">餐饮版</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="address" label="详细地址" />
|
||||
<el-table-column prop="businessTime" label="营业时间" />
|
||||
<el-table-column prop="expireAt" label="到期时间" />
|
||||
<el-table-column prop="status" label="门店状态">
|
||||
<template slot-scope="scope">
|
||||
{{ dict.label.shop_status[scope.row.status] }}
|
||||
<el-table-column prop="address" label="商户号"></el-table-column>
|
||||
<el-table-column prop="lowPrice" label="来源"></el-table-column>
|
||||
<el-table-column prop="lowPrice" label="认证状态">-</el-table-column>
|
||||
<el-table-column prop="status" label="店铺状态">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" disabled></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="checkPer(['admin','tbShopInfo:edit','tbShopInfo:del'])" label="操作" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
/>
|
||||
<el-table-column prop="createdAt" label="到期时间">
|
||||
<template v-slot="scope">
|
||||
{{ dayjs(scope.row.expireAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" icon="el-icon-edit" @click="$refs.addShop.show(scope.row)">编辑</el-button>
|
||||
<el-dropdown @command="dropdownClick">
|
||||
<el-button type="text">更多<i class="el-icon-arrow-down"></i></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="{ row: scope.row, command: 1 }">详情</el-dropdown-item>
|
||||
<el-dropdown-item :command="2">续费记录</el-dropdown-item>
|
||||
<el-dropdown-item :command="3">前往店铺</el-dropdown-item>
|
||||
<el-dropdown-item :command="4">重置密码</el-dropdown-item>
|
||||
<el-dropdown-item divided :command="5">删除</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</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>
|
||||
</div>
|
||||
<addShop ref="addShop" @success="getTableData" />
|
||||
<detailModal ref="detailModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudTbShopInfo from '@/api/tbShopInfo'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import udOperation from '@crud/UD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { id: null, account: null, shopCode: null, subTitle: null, merchantId: null, shopName: null, chainName: null, backImg: null, frontImg: null, contactName: null, phone: null, logo: null, isDeposit: null, isSupply: null, coverImg: null, shareImg: null, view: null, detail: null, lat: null, lng: null, mchId: null, registerType: null, isWxMaIndependent: null, address: null, city: null, type: null, industry: null, industryName: null, businessTime: null, postTime: null, postAmountLine: null, onSale: null, settleType: null, settleTime: null, enterAt: null, expireAt: null, status: null, average: null, orderWaitPayMinute: null, supportDeviceNumber: null, distributeLevel: null, createdAt: null, updatedAt: null, proxyId: null }
|
||||
import dayjs from 'dayjs'
|
||||
import { tbShopInfo } from '@/api/shop.js'
|
||||
import addShop from '../components/addShop'
|
||||
import detailModal from '../components/detailModal'
|
||||
export default {
|
||||
name: 'TbShopInfo',
|
||||
components: { pagination, crudOperation, rrOperation, udOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
dicts: ['shop_status'],
|
||||
cruds() {
|
||||
return CRUD({ title: '/shop/list', url: 'api/tbShopInfo', idField: 'id', sort: 'id,desc', crudMethod: { ...crudTbShopInfo }})
|
||||
},
|
||||
components: { addShop, detailModal },
|
||||
data() {
|
||||
return {
|
||||
permission: {
|
||||
add: ['admin', 'tbShopInfo:add'],
|
||||
edit: ['admin', 'tbShopInfo:edit'],
|
||||
del: ['admin', 'tbShopInfo:del']
|
||||
dayjs,
|
||||
query: {
|
||||
name: '',
|
||||
account: '',
|
||||
status: ''
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: '自增id不能为空', trigger: 'blur' }
|
||||
],
|
||||
shopName: [
|
||||
{ required: true, message: '店铺名称不能为空', trigger: 'blur' }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: '门店状态不能为空', trigger: 'blur' }
|
||||
]
|
||||
} }
|
||||
{
|
||||
type: 1,
|
||||
label: '开启'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
label: '关闭'
|
||||
}
|
||||
],
|
||||
tableData: {
|
||||
list: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
dropdownClick(e) {
|
||||
switch (e.command) {
|
||||
case 1:
|
||||
this.$refs.detailModal.show(e.row)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.account = ''
|
||||
this.query.status = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 获取商家列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopInfo({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
shopName: this.query.name,
|
||||
account: this.query.account,
|
||||
status: this.query.status
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
26
src/views/shop/shop_configuration.vue
Normal file
26
src/views/shop/shop_configuration.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-tabs v-model="activeName" type="card">
|
||||
<el-tab-pane label="店铺信息" name="1"></el-tab-pane>
|
||||
<el-tab-pane label="基础配置" name="2"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<shopInfo v-if="activeName == 1" />
|
||||
<shopSetting v-if="activeName == 2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import shopInfo from './components/shopInfo'
|
||||
import shopSetting from './components/shopSetting'
|
||||
export default {
|
||||
components: {
|
||||
shopInfo,
|
||||
shopSetting
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: '1',
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -4,15 +4,17 @@
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<!-- 搜索 -->
|
||||
<el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" style="width: 200px;"
|
||||
class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<date-range-picker v-model="query.createTime" class="date-item" />
|
||||
<rrOperation />
|
||||
</div>
|
||||
<crudOperation :permission="permission" />
|
||||
</div>
|
||||
<!--表单渲染-->
|
||||
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="580px">
|
||||
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU"
|
||||
:visible.sync="crud.status.cu > 0" :title="crud.status.title" width="680px">
|
||||
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="100px">
|
||||
<el-form-item label="菜单类型" prop="type">
|
||||
<el-radio-group v-model="form.type" size="mini" style="width: 178px">
|
||||
<el-radio-button label="0">目录</el-radio-button>
|
||||
@@ -21,15 +23,11 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-show="form.type.toString() !== '2'" label="菜单图标" prop="icon">
|
||||
<el-popover
|
||||
placement="bottom-start"
|
||||
width="450"
|
||||
trigger="click"
|
||||
@show="$refs['iconSelect'].reset()"
|
||||
>
|
||||
<el-popover placement="bottom-start" width="450" trigger="click" @show="$refs['iconSelect'].reset()">
|
||||
<IconSelect ref="iconSelect" @selected="selected" />
|
||||
<el-input slot="reference" v-model="form.icon" style="width: 450px;" placeholder="点击选择图标" readonly>
|
||||
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 32px;width: 16px;" />
|
||||
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon"
|
||||
style="height: 32px;width: 16px;" />
|
||||
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
|
||||
</el-input>
|
||||
</el-popover>
|
||||
@@ -53,34 +51,37 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type.toString() !== '2'" label="菜单标题" prop="title">
|
||||
<el-input v-model="form.title" :style=" form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'" placeholder="菜单标题" />
|
||||
<el-input v-model="form.title" :style="form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'"
|
||||
placeholder="菜单标题" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type.toString() === '2'" label="按钮名称" prop="title">
|
||||
<el-input v-model="form.title" placeholder="按钮名称" style="width: 178px;" />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="form.type.toString() !== '0'" label="权限标识" prop="permission">
|
||||
<el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="权限标识" style="width: 178px;" />
|
||||
<el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="权限标识"
|
||||
style="width: 178px;" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path">
|
||||
<el-input v-model="form.path" placeholder="路由地址" style="width: 178px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单排序" prop="menuSort">
|
||||
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" style="width: 178px;" />
|
||||
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right"
|
||||
style="width: 178px;" />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName">
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称"
|
||||
prop="componentName">
|
||||
<el-input v-model="form.componentName" style="width: 178px;" placeholder="匹配组件内Name字段" />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component">
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径"
|
||||
prop="component">
|
||||
<el-input v-model="form.component" style="width: 178px;" placeholder="组件路径" />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="选中父级菜单">
|
||||
<el-input v-model="form.activeMenu" placeholder="请输入父级菜单path" style="width: 178px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="上级类目" prop="pid">
|
||||
<treeselect
|
||||
v-model="form.pid"
|
||||
:options="menus"
|
||||
:load-options="loadMenus"
|
||||
style="width: 450px;"
|
||||
placeholder="选择上级类目"
|
||||
/>
|
||||
<treeselect v-model="form.pid" :options="menus" :load-options="loadMenus" style="width: 450px;"
|
||||
placeholder="选择上级类目" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@@ -89,18 +90,9 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--表格渲染-->
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="crud.loading"
|
||||
lazy
|
||||
:load="getMenus"
|
||||
:data="crud.data"
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
row-key="id"
|
||||
@select="crud.selectChange"
|
||||
@select-all="crud.selectAllChange"
|
||||
@selection-change="crud.selectionChangeHandler"
|
||||
>
|
||||
<el-table ref="table" v-loading="crud.loading" lazy :load="getMenus" :data="crud.data"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" row-key="id" @select="crud.selectChange"
|
||||
@select-all="crud.selectAllChange" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column :show-overflow-tooltip="true" label="菜单标题" width="125px" prop="title" />
|
||||
<el-table-column prop="icon" label="图标" align="center" width="60px">
|
||||
@@ -134,13 +126,10 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" width="135px" />
|
||||
<el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="130px" align="center" fixed="right">
|
||||
<el-table-column v-if="checkPer(['admin', 'menu:edit', 'menu:del'])" label="操作" width="130px" align="center"
|
||||
fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!"
|
||||
/>
|
||||
<udOperation :data="scope.row" :permission="permission" msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -165,7 +154,7 @@ export default {
|
||||
name: 'Menu',
|
||||
components: { Treeselect, IconSelect, crudOperation, rrOperation, udOperation, DateRangePicker },
|
||||
cruds() {
|
||||
return CRUD({ title: '菜单', url: 'api/menus', crudMethod: { ...crudMenu }})
|
||||
return CRUD({ title: '菜单', url: 'api/menus', crudMethod: { ...crudMenu } })
|
||||
},
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
data() {
|
||||
@@ -209,7 +198,7 @@ export default {
|
||||
},
|
||||
getSupDepts(id) {
|
||||
crudMenu.getMenuSuperior(id).then(res => {
|
||||
const children = res.map(function(obj) {
|
||||
const children = res.map(function (obj) {
|
||||
if (!obj.leaf && !obj.children) {
|
||||
obj.children = null
|
||||
}
|
||||
@@ -221,7 +210,7 @@ export default {
|
||||
loadMenus({ action, parentNode, callback }) {
|
||||
if (action === LOAD_CHILDREN_OPTIONS) {
|
||||
crudMenu.getMenusTree(parentNode.id).then(res => {
|
||||
parentNode.children = res.map(function(obj) {
|
||||
parentNode.children = res.map(function (obj) {
|
||||
if (!obj.leaf) {
|
||||
obj.children = null
|
||||
}
|
||||
@@ -242,11 +231,14 @@ export default {
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
::v-deep .el-input-number .el-input__inner {
|
||||
::v-deep .el-input-number .el-input__inner {
|
||||
text-align: left;
|
||||
}
|
||||
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
|
||||
}
|
||||
|
||||
::v-deep .vue-treeselect__control,
|
||||
::v-deep .vue-treeselect__placeholder,
|
||||
::v-deep .vue-treeselect__single-value {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
163
src/views/systemMerchant/components/addPayType.vue
Normal file
163
src/views/systemMerchant/components/addPayType.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<el-dialog title="添加支付方式" :visible.sync="dialogVisible" :show-close="false" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="支付类型" prop="payType">
|
||||
<el-select v-model="form.payType" placeholder="请选择支付类型" @change="typeChange">
|
||||
<el-option :label="item.lable" :value="item.key" v-for="item in payTypes"
|
||||
:key="item.key"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式" prop="payName" v-if="form.payType == 'virtual'">
|
||||
<el-input v-model="form.payName" placeholder="请输入自定义支付方式"></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="图标" prop="icon">
|
||||
<uploadImg ref="uploadImg" :limit="9" @success="e => form.icon = e[0]" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="是否虚拟">
|
||||
<el-radio-group v-model="form.isIdeal">
|
||||
<el-radio :label="1">虚拟</el-radio>
|
||||
<el-radio :label="0">非虚拟</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="tips">虚拟:微信、支付宝支付等。 非虚拟:现金</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="开钱箱权限">
|
||||
<el-switch v-model="form.isOpenCashDrawer" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否生效">
|
||||
<el-switch v-model="form.isDisplay" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sorts" controls-position="right" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||
<span v-if="!formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uploadImg from '@/components/uploadImg'
|
||||
import { tbShopPayType } from '@/api/setting'
|
||||
import payTypes from '../payTypes'
|
||||
|
||||
export default ({
|
||||
components: { uploadImg },
|
||||
data() {
|
||||
const validateIcon = (rule, value, callback) => {
|
||||
if (!this.form.icon) {
|
||||
callback(new Error('请上传图标'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
payTypes,
|
||||
dialogVisible: false,
|
||||
formLoading: false,
|
||||
resetForm: '',
|
||||
form: {
|
||||
id: '',
|
||||
icon: '',
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
payType: '',
|
||||
payName: '',
|
||||
isIdeal: 1,
|
||||
isOpenCashDrawer: 1,
|
||||
isDisplay: 1,
|
||||
sorts: 0
|
||||
},
|
||||
rules: {
|
||||
payType: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
triiger: 'blur'
|
||||
}
|
||||
],
|
||||
payName: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
triiger: 'blur'
|
||||
}
|
||||
],
|
||||
icon: [
|
||||
{
|
||||
required: true,
|
||||
validator: validateIcon,
|
||||
triiger: 'change'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form }
|
||||
},
|
||||
methods: {
|
||||
typeChange(e) {
|
||||
this.form.icon = payTypes.find(item => item.key == e).icon
|
||||
if (e == 'virtual') {
|
||||
this.form.payName = ''
|
||||
} else {
|
||||
this.form.payName = payTypes.find(item => item.key == e).lable
|
||||
}
|
||||
},
|
||||
// 保存
|
||||
submitHandle() {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.formLoading = true
|
||||
await tbShopPayType(this.form, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success')
|
||||
this.formLoading = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.pid ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.close()
|
||||
} catch (error) {
|
||||
this.formLoading = false
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form = { ...this.resetForm }
|
||||
// this.$refs.uploadImg.fileList = []
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form.id = obj.id
|
||||
this.form.icon = obj.icon
|
||||
this.form.payType = obj.payType
|
||||
this.form.payName = obj.payName
|
||||
this.form.isIdeal = obj.isIdeal
|
||||
this.form.isOpenCashDrawer = obj.isOpenCashDrawer
|
||||
this.form.isDisplay = obj.isDisplay
|
||||
this.form.sorts = obj.sorts
|
||||
|
||||
// if (obj.icon) {
|
||||
// setTimeout(() => {
|
||||
// this.$refs.uploadImg.fileList = [{
|
||||
// url: obj.icon
|
||||
// }]
|
||||
// }, 100);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,158 +1,130 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<!-- 搜索 -->
|
||||
<label class="el-form-item-label">自增id</label>
|
||||
<el-input v-model="query.id" clearable placeholder="自增id" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">支付类型</label>
|
||||
<el-input v-model="query.payType" clearable placeholder="支付类型" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">支付类型名称</label>
|
||||
<el-input v-model="query.payName" clearable placeholder="支付类型名称" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">是否快捷展示</label>
|
||||
<el-input v-model="query.isShowShortcut" clearable placeholder="是否快捷展示" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">店铺id</label>
|
||||
<el-input v-model="query.shopId" clearable placeholder="店铺id" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">是否打开钱箱</label>
|
||||
<el-input v-model="query.isOpenCashDrawer" clearable placeholder="是否打开钱箱" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">createdAt</label>
|
||||
<el-input v-model="query.createdAt" clearable placeholder="createdAt" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<label class="el-form-item-label">排序</label>
|
||||
<el-input v-model="query.sorts" clearable placeholder="排序" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
|
||||
<rrOperation :crud="crud" />
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addPayType.show()">添加支付方式</el-button>
|
||||
</div>
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
<!--表单组件-->
|
||||
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
|
||||
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-form-item label="自增id" prop="id">
|
||||
<el-input v-model="form.id" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="支付类型">
|
||||
<el-input v-model="form.payType" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="支付类型名称">
|
||||
<el-input v-model="form.payName" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否快捷展示">
|
||||
<el-radio-group v-model="form.isShowShortcut" style="width: 140px">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺id">
|
||||
<el-input v-model="form.shopId" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否打开钱箱">
|
||||
<el-radio-group v-model="form.isOpenCashDrawer" style="width: 140px">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="createdAt">
|
||||
<el-input v-model="form.createdAt" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input v-model="form.sorts" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="id" label="自增id" />
|
||||
<el-table-column prop="payType" label="支付类型" />
|
||||
<el-table-column prop="payName" label="支付类型名称" />
|
||||
<el-table-column prop="isShowShortcut" label="是否快捷展示" >
|
||||
<template slot-scope="scope">
|
||||
<span>{{ form.isShowShortcut == 1 ? '是' : '否' }}</span>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading"><el-table-column prop="icon" label="图标">
|
||||
<template v-slot="scope">
|
||||
<el-image :src="scope.row.icon" style="width: 40px;height: 40px;"></el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="payName" label="支付方式"></el-table-column>
|
||||
<el-table-column prop="payType" label="类型"></el-table-column>
|
||||
<el-table-column prop="isOpenCashDrawer" label="开钱箱权限">
|
||||
|
||||
<el-table-column prop="shopId" label="店铺id" />
|
||||
|
||||
<el-table-column prop="isOpenCashDrawer" label="是否打开钱箱">
|
||||
<el-switch
|
||||
v-model="form.isOpenCashDrawer"
|
||||
class="switch"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
/>
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.isOpenCashDrawer" :active-value="1" :inactive-value="0" disabled></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="createdAt" />
|
||||
<el-table-column prop="sorts" label="排序" />
|
||||
<el-table-column v-if="checkPer(['admin','tbShopPayType:edit','tbShopPayType:del'])" label="操作" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
/>
|
||||
<el-table-column prop="isDisplay" label="是否生效">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.isDisplay" :active-value="1" :inactive-value="0" disabled></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sorts" label="条件排序"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" icon="el-icon-edit" @click="$refs.addPayType.show(scope.row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</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>
|
||||
</div>
|
||||
<addPayType ref="addPayType" @success="getTableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudTbShopPayType from '@/api/tbShopPayType'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import udOperation from '@crud/UD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { id: null, payType: null, payName: null, isShowShortcut: null, shopId: null, isRefundable: null, isOpenCashDrawer: null, isSystem: null, isIdeal: null, isDisplay: null, createdAt: null, updatedAt: null, sorts: null }
|
||||
import dayjs from 'dayjs'
|
||||
import { tbShopPayTypeGet } from '@/api/setting.js'
|
||||
import addPayType from './components/addPayType'
|
||||
export default {
|
||||
name: 'TbShopPayType',
|
||||
components: { pagination, crudOperation, rrOperation, udOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({ title: '/merchant/system/paytype', url: 'api/tbShopPayType', idField: 'id', sort: 'id,desc', crudMethod: { ...crudTbShopPayType }})
|
||||
},
|
||||
components: { addPayType },
|
||||
data() {
|
||||
return {
|
||||
permission: {
|
||||
add: ['admin', 'tbShopPayType:add'],
|
||||
edit: ['admin', 'tbShopPayType:edit'],
|
||||
del: ['admin', 'tbShopPayType:del']
|
||||
dayjs,
|
||||
query: {
|
||||
name: '',
|
||||
account: '',
|
||||
status: ''
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: '自增id不能为空', trigger: 'blur' }
|
||||
]
|
||||
status: [
|
||||
{
|
||||
type: 1,
|
||||
label: '开启'
|
||||
},
|
||||
queryTypeOptions: [
|
||||
{ key: 'id', display_name: '自增id' },
|
||||
{ key: 'payType', display_name: '支付类型' },
|
||||
{ key: 'payName', display_name: '支付类型' },
|
||||
{ key: 'isShowShortcut', display_name: '是否快捷展示' },
|
||||
{ key: 'shopId', display_name: '店铺id' },
|
||||
{ key: 'isOpenCashDrawer', display_name: '是否打开钱箱' },
|
||||
{ key: 'createdAt', display_name: 'createdAt' },
|
||||
{ key: 'sorts', display_name: '排序' }
|
||||
]
|
||||
{
|
||||
type: 0,
|
||||
label: '关闭'
|
||||
}
|
||||
],
|
||||
tableData: {
|
||||
list: [],
|
||||
page: 0,
|
||||
size: 10,
|
||||
loading: false,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTableData()
|
||||
},
|
||||
methods: {
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
dropdownClick(e) {
|
||||
switch (e.command) {
|
||||
case 1:
|
||||
this.$refs.detailModal.show(e.row)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.query.name = ''
|
||||
this.query.account = ''
|
||||
this.query.status = ''
|
||||
this.getTableData()
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1
|
||||
this.getTableData()
|
||||
},
|
||||
// 获取商家列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true
|
||||
try {
|
||||
const res = await tbShopPayTypeGet({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tableData.loading = false
|
||||
this.tableData.list = res.content
|
||||
this.tableData.total = res.totalElements
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
32
src/views/systemMerchant/payTypes.js
Normal file
32
src/views/systemMerchant/payTypes.js
Normal file
@@ -0,0 +1,32 @@
|
||||
export default [
|
||||
{
|
||||
lable: '现金',
|
||||
key: 'cash',
|
||||
icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240302/2dab947729d640fba7709b7c0b42bfef.png'
|
||||
},
|
||||
{
|
||||
lable: '银行卡',
|
||||
key: 'bank',
|
||||
icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240302/14b20cf721304b7fa2f01e6e75fab403.png'
|
||||
},
|
||||
{
|
||||
lable: '扫码支付',
|
||||
key: 'scanCode',
|
||||
icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240302/9ff08224680446c8b3978844da99bbaa.png'
|
||||
},
|
||||
{
|
||||
lable: '储值卡',
|
||||
key: 'deposit',
|
||||
icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240302/18d40f471a924d55b4eb13e5f553734d.png'
|
||||
},
|
||||
// {
|
||||
// lable: '挂单',
|
||||
// key: 'arrears',
|
||||
// icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240304/fcf337b999f14a12ad75f76e74fcb344.png'
|
||||
// },
|
||||
{
|
||||
lable: '自定义',
|
||||
key: 'virtual',
|
||||
icon: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240304/6702fbf953504f89aa6a3db1f33d49b6.png'
|
||||
}
|
||||
]
|
||||
73
src/views/table/components/addEara.vue
Normal file
73
src/views/table/components/addEara.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<el-dialog :title="form.id ? '编辑区域' : '添加区域'" :visible.sync="dialogVisible" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="区域名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入区域名称"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopArea } from '@/api/table'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
form: {
|
||||
id: '',
|
||||
name: ''
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入区域名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
try {
|
||||
let res = await tbShopArea({
|
||||
...this.form,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form = JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form.id = ''
|
||||
this.form.name = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
121
src/views/table/components/addTable.vue
Normal file
121
src/views/table/components/addTable.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<el-dialog :title="form.id ? '编辑台桌' : '添加台桌'" :visible.sync="dialogVisible" @open="tbShopAreaGet" @close="reset">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="选择区域" prop="areaId">
|
||||
<el-select v-model="form.areaId" placeholder="请选择区域">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in areaList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="台桌名称">
|
||||
<el-input v-model="form.name" placeholder="请输入台桌名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="客座数">
|
||||
<el-input-number v-model="form.maxCapacity" :min="0" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="网络预定开关">
|
||||
<el-switch v-model="form.isPredate" :active-value="1" :inactive-value="2"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-radio-group v-model="form.type">
|
||||
<el-radio-button :label="0">低消</el-radio-button>
|
||||
<el-radio-button :label="2">计时</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="最低消费" v-if="form.type == 0">
|
||||
<el-input-number v-model="form.amount" :min="0" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="每小时收费" v-if="form.type == 2">
|
||||
<el-input-number v-model="form.perhour" :min="0" controls-position="right"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="onSubmitHandle">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { tbShopTable, tbShopAreaGet } from '@/api/table'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
resetForm: '',
|
||||
loading: false,
|
||||
form: {
|
||||
id: '',
|
||||
name: '',
|
||||
areaId: '',
|
||||
maxCapacity: 0,
|
||||
isPredate: 1,
|
||||
type: 2,
|
||||
perhour: 0,
|
||||
amount: 0
|
||||
},
|
||||
rules: {
|
||||
areaId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择区域',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
areaList: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form }
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
this.$refs.form.validate(async valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
try {
|
||||
let res = await tbShopTable({
|
||||
...this.form,
|
||||
shopId: localStorage.getItem('shopId')
|
||||
}, this.form.id ? 'put' : 'post')
|
||||
this.$emit('success', res)
|
||||
this.close()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: `${this.form.id ? '编辑' : '添加'}成功`,
|
||||
type: 'success'
|
||||
});
|
||||
this.loading = false
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
show(obj) {
|
||||
this.dialogVisible = true
|
||||
if (obj && obj.id) {
|
||||
this.form = JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
reset() {
|
||||
this.form = { ...this.resetForm }
|
||||
},
|
||||
// 获取区域
|
||||
async tbShopAreaGet() {
|
||||
try {
|
||||
const { content } = await tbShopAreaGet({
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.areaList = content
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
61
src/views/table/table_config.vue
Normal file
61
src/views/table/table_config.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="form" label-width="120px">
|
||||
<el-form-item label="网络预定开关">
|
||||
<el-switch v-model="form.yd" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="预定时间" v-if="form.timeList.length">
|
||||
<div class="time_row" v-for="(item, index) in form.timeList" :key="index">
|
||||
<el-time-picker is-range v-model="item.time" range-separator="至" start-placeholder="开始时间"
|
||||
end-placeholder="结束时间" placeholder="选择时间范围">
|
||||
</el-time-picker>
|
||||
<i class="icon el-icon-delete" @click="form.timeList.splice(index, 1)"></i>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button plain icon="el-icon-plus" @click="form.timeList.push({ time: [] })">添加时间段</el-button>
|
||||
<div class="tips">注:结束时间不能小于开始时间</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="允许预约天数">
|
||||
<el-input-number v-model="form.dayMax" controls-position="right" :min="0"></el-input-number>
|
||||
<div class="tips">注:最多预约几天后的日期</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="允许预约天数">
|
||||
<el-input type="textarea" v-model="form.info" placeholder="充值说明" style="width: 500px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
yd: 0,
|
||||
timeList: [],
|
||||
dayMax: 3,
|
||||
info: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.time_row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
256
src/views/table/table_list.vue
Normal file
256
src/views/table/table_list.vue
Normal file
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-tabs v-model="tabVlaue" type="card" @tab-click="tabClick">
|
||||
<el-tab-pane label="全部" name=""></el-tab-pane>
|
||||
<el-tab-pane v-for="item in tabs" :key="item.id" :label="item.name" :name="`${item.id}`">
|
||||
<div slot="label">
|
||||
{{ item.name }}
|
||||
<i class="icon el-icon-edit" @click.stop="$refs.addEara.show(item)"></i>
|
||||
<el-popconfirm title="确定删除吗?" @confirm="delHandle([item.id])">
|
||||
<i class="icon el-icon-delete" slot="reference" @click.stop=""></i>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="head-container">
|
||||
<div class="filter_wrap">
|
||||
<el-button icon="el-icon-plus" @click="$refs.addEara.show()">添加区域</el-button>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="$refs.addTable.show()">添加台桌</el-button>
|
||||
<el-button type="primary" icon="el-icon-download">下载台桌码</el-button>
|
||||
<el-button type="primary" icon="el-icon-download">下载店铺码</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<div class="table_list" v-loading="loading">
|
||||
<div class="item" v-for="item in tableList" :key="item.id">
|
||||
<div class="top">
|
||||
<div class="row row1">
|
||||
<span>{{ item.name }}</span>
|
||||
<div class="state">
|
||||
<span class="dot" :style="{ backgroundColor: status[item.status].type }"></span>
|
||||
{{ status[item.status].label }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-tag type="warning" size="mini">{{ item.type == 0 ? '低消' : '计时' }}</el-tag>
|
||||
<el-tag :type="item.isPredate == 1 ? '' : 'info'" size="mini">{{ item.isPredate == 1 ? '可预约' : '不可预约' }}</el-tag>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="tips">客座次数:{{ item.maxCapacity }}人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btm">
|
||||
<!-- <div class="btm_item">
|
||||
<i class="i el-icon-edit"></i>
|
||||
</div> -->
|
||||
<div class="btm_item" @click="$refs.addTable.show(item)">
|
||||
<i class="i el-icon-edit"></i>
|
||||
</div>
|
||||
<el-popconfirm title="确定删除吗?" @confirm="delTableHandle([item.id])" style="flex: 1;">
|
||||
<div class="btm_item" slot="reference">
|
||||
<i class="i el-icon-delete"></i>
|
||||
</div>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
<div class="empty_wrap">
|
||||
<el-empty description="空空如也~" v-if="!tableList.length"></el-empty>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<addEara ref="addEara" @success="tbShopAreaGet" />
|
||||
<addTable ref="addTable" @success="tbShopTableGet" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addEara from './components/addEara'
|
||||
import addTable from './components/addTable'
|
||||
import { tbShopTableGet, tbShopAreaGet, tbShopAreaDelete, tbShopTableDelete } from '@/api/table'
|
||||
export default {
|
||||
components: {
|
||||
addEara,
|
||||
addTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabVlaue: '',
|
||||
tabs: [],
|
||||
loading: false,
|
||||
tableList: [],
|
||||
status: {
|
||||
subscribe: {
|
||||
label: '预定',
|
||||
type: '#E6A23C'
|
||||
},
|
||||
closed: {
|
||||
label: '关台',
|
||||
type: '#F56C6C'
|
||||
},
|
||||
opening: {
|
||||
label: '开台中',
|
||||
type: '#67C23A'
|
||||
},
|
||||
cleaning: {
|
||||
label: '台桌清理中',
|
||||
type: '#909399'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.tbShopAreaGet()
|
||||
},
|
||||
methods: {
|
||||
tabClick() {
|
||||
this.tbShopTableGet()
|
||||
},
|
||||
// 删除桌台
|
||||
async delTableHandle(ids) {
|
||||
try {
|
||||
await tbShopTableDelete(ids)
|
||||
this.tbShopTableGet()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 删除区域
|
||||
async delHandle(ids) {
|
||||
try {
|
||||
await tbShopAreaDelete(ids)
|
||||
this.tabVlaue = ''
|
||||
this.tbShopAreaGet()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 台桌列表
|
||||
async tbShopTableGet() {
|
||||
this.loading = true
|
||||
try {
|
||||
const { content } = await tbShopTableGet({
|
||||
shopId: localStorage.getItem('shopId'),
|
||||
areaId: this.tabVlaue
|
||||
})
|
||||
this.tableList = content
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 300)
|
||||
} catch (error) {
|
||||
this.loading = false
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
// 获取区域
|
||||
async tbShopAreaGet() {
|
||||
try {
|
||||
const { content } = await tbShopAreaGet({
|
||||
shopId: localStorage.getItem('shopId')
|
||||
})
|
||||
this.tabs = content
|
||||
this.tbShopTableGet()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-tabs {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
.icon {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.table_list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
min-height: 150px;
|
||||
|
||||
.empty_wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.item {
|
||||
border: 1px solid #ddd;
|
||||
|
||||
.top {
|
||||
padding: 20px;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
||||
.tips {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
&.row1 {
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
|
||||
.state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 80px;
|
||||
|
||||
.dot {
|
||||
$size: 6px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
margin-right: $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btm {
|
||||
border-top: 1px solid #ddd;
|
||||
background-color: #efefef;
|
||||
display: flex;
|
||||
|
||||
.btm_item {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
&::before {
|
||||
content: '';
|
||||
height: 50%;
|
||||
border-right: 1px solid #ddd;
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.i {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -6,38 +6,27 @@
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<!-- 搜索 -->
|
||||
<el-input v-model="query.key" clearable size="small" placeholder="输入文件名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery" />
|
||||
<el-input v-model="query.key" clearable size="small" placeholder="输入文件名称搜索" style="width: 200px;"
|
||||
class="filter-item" @keyup.enter.native="toQuery" />
|
||||
<date-range-picker v-model="query.createTime" class="date-item" />
|
||||
<rrOperation />
|
||||
</div>
|
||||
<crudOperation :permission="permission">
|
||||
<template slot="left">
|
||||
<!-- 上传 -->
|
||||
<el-button class="filter-item" size="mini" type="primary" icon="el-icon-upload" @click="dialog = true">上传</el-button>
|
||||
<el-button class="filter-item" size="mini" type="primary" icon="el-icon-upload"
|
||||
@click="dialog = true">上传</el-button>
|
||||
<!-- 同步 -->
|
||||
<el-button :icon="icon" class="filter-item" size="mini" type="warning" @click="synchronize">同步</el-button>
|
||||
<!-- 配置 -->
|
||||
<el-button
|
||||
class="filter-item"
|
||||
size="mini"
|
||||
type="success"
|
||||
icon="el-icon-s-tools"
|
||||
@click="doConfig"
|
||||
>配置</el-button>
|
||||
<el-button class="filter-item" size="mini" type="success" icon="el-icon-s-tools"
|
||||
@click="doConfig">配置</el-button>
|
||||
</template>
|
||||
</crudOperation>
|
||||
<!-- 文件上传 -->
|
||||
<el-dialog :visible.sync="dialog" :close-on-click-modal="false" append-to-body width="500px" @close="doSubmit">
|
||||
<el-upload
|
||||
:before-remove="handleBeforeRemove"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
:file-list="fileList"
|
||||
:headers="headers"
|
||||
:action="qiNiuUploadApi"
|
||||
class="upload-demo"
|
||||
multiple
|
||||
>
|
||||
<el-upload :before-remove="handleBeforeRemove" :on-success="handleSuccess" :on-error="handleError"
|
||||
:file-list="fileList" :headers="headers" :action="qiNiuUploadApi" class="upload-demo" multiple>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" style="display: block;" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
||||
</el-upload>
|
||||
@@ -46,14 +35,17 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;"
|
||||
@selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="name" :show-overflow-tooltip="true" label="文件名">
|
||||
<template slot-scope="scope">
|
||||
<a href="JavaScript:" class="el-link el-link--primary" target="_blank" type="primary" @click="download(scope.row.id)">{{ scope.row.key }}</a>
|
||||
<a href="JavaScript:" class="el-link el-link--primary" target="_blank" type="primary"
|
||||
@click="download(scope.row.id)">{{ scope.row.key }}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" prop="suffix" label="文件类型" @selection-change="crud.selectionChangeHandler" />
|
||||
<el-table-column :show-overflow-tooltip="true" prop="suffix" label="文件类型"
|
||||
@selection-change="crud.selectionChangeHandler" />
|
||||
<el-table-column prop="bucket" label="空间名称" />
|
||||
<el-table-column prop="size" label="文件大小" />
|
||||
<el-table-column prop="type" label="空间类型" />
|
||||
@@ -79,7 +71,7 @@ import DateRangePicker from '@/components/DateRangePicker'
|
||||
export default {
|
||||
components: { eForm, pagination, crudOperation, rrOperation, DateRangePicker },
|
||||
cruds() {
|
||||
return CRUD({ title: '七牛云文件', url: 'api/qiNiuContent', crudMethod: { ...crudQiNiu }})
|
||||
return CRUD({ title: '七牛云文件', url: 'api/qiNiuContent', crudMethod: { ...crudQiNiu } })
|
||||
},
|
||||
mixins: [presenter(), header(), crud()],
|
||||
data() {
|
||||
@@ -132,7 +124,7 @@ export default {
|
||||
handleBeforeRemove(file, fileList) {
|
||||
for (let i = 0; i < this.files.length; i++) {
|
||||
if (this.files[i].uid === file.uid) {
|
||||
crudQiNiu.del([this.files[i].id]).then(res => {})
|
||||
crudQiNiu.del([this.files[i].id]).then(res => { })
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -188,6 +180,4 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user