Compare commits

...

103 Commits

Author SHA1 Message Date
YeMingfei666 30faee9dac add: 多门店代码合并 2025-09-09 15:08:32 +08:00
YeMingfei666 73e20ad617 feat: 代码合并 2025-04-22 10:17:05 +08:00
YeMingfei666 21eda68ab0 fix: 代码合并冲突解决 2025-04-22 10:16:48 +08:00
YeMingfei666 f5ff208fd6 fix: 代码合并冲突解决 2025-04-22 10:14:20 +08:00
YeMingfei666 cfc925e55c fix: 代码合并 2025-04-22 10:14:05 +08:00
duan 593f5693ef fix: 合并代码-修改空格 2025-04-21 15:31:04 +08:00
duan 2993c1375f fix: 合并代码 2025-04-21 15:26:19 +08:00
YeMingfei666 ddf7045346 Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-21 11:05:49 +08:00
duan a6bca24c1a fix: 修改时间字段 2025-04-18 18:00:00 +08:00
duan e9a606c71e fix: 商品列表库存修改,没提交成功不修改表格 2025-04-17 13:41:02 +08:00
YeMingfei666 2602916201 Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-16 17:31:49 +08:00
YeMingfei666 beade81a68 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-16 09:45:29 +08:00
YeMingfei666 9b6dd9f0da Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-16 09:38:14 +08:00
YeMingfei666 f4b939433d fix: 代码合并冲突解决 2025-04-16 09:28:58 +08:00
duan 0a73635b78 fix: 合并冲突 2025-04-15 16:29:40 +08:00
YeMingfei666 4f987ae3d2 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-15 11:13:33 +08:00
wwz 0d495c20ef feat: 耗材报损 2025-04-15 10:41:12 +08:00
wwz c093c618b2 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-12 13:45:46 +08:00
wwz 7fb9f30c45 feat: 更新通知中心1 2025-04-12 13:45:35 +08:00
GaoHao 901d56b648 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-12 11:02:06 +08:00
GaoHao 05aaa2fd64 feat: 登录类型增加 2025-04-12 11:01:38 +08:00
wwz 2fe5e38e85 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-12 11:01:21 +08:00
wwz 1d848b7227 feat: 更新通知中心 2025-04-12 11:01:17 +08:00
GaoHao ce3b817e42 feat: 商品报损更新列表 2025-04-12 09:42:12 +08:00
GaoHao b92f39fe89 feat: 增加权限校验 2025-04-11 18:26:10 +08:00
GaoHao cc13161f16 feat: 商品同步规则优化 2025-04-11 17:57:35 +08:00
GaoHao 688f30635b feat: 同步规则优化 2025-04-11 17:25:02 +08:00
GaoHao 85eba13919 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-11 16:53:19 +08:00
GaoHao c956972cb3 feat: 同步规格优化 2025-04-11 16:53:14 +08:00
YeMingfei666 583b79bc8f fix: 代码合并 2025-04-11 16:51:59 +08:00
GaoHao 6df2050d2b Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-11 15:50:32 +08:00
GaoHao 331f438f99 feat: 同步规格优化 2025-04-11 15:50:15 +08:00
wwz ef600c9e3c Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-11 15:47:01 +08:00
wwz 9a0170471a feat: 角色级别 2025-04-11 15:46:48 +08:00
GaoHao 8fd3565bac feat: 增加同步规则 2025-04-11 14:57:26 +08:00
GaoHao 04ae1c342b feat: 销售统计分类筛选隐藏,商品同步优化 2025-04-11 11:34:10 +08:00
YeMingfei666 273684678b Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-11 09:57:32 +08:00
GaoHao 299c6327b7 Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-11 09:47:22 +08:00
GaoHao cf626cb862 feat: 分店列表筛选name名称字段修改 2025-04-11 09:47:00 +08:00
wwz bfca8f4013 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-11 09:37:31 +08:00
wwz 682fe03165 feat: 更改跳转 2025-04-11 09:37:28 +08:00
GaoHao 8290462eda Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-10 18:27:26 +08:00
GaoHao 6c72027a86 feat: 商品同步增加 2025-04-10 18:27:09 +08:00
wwz 462f75ce3e Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-10 17:51:47 +08:00
wwz 6cb1968b80 feat: 进销存更改 2025-04-10 17:51:14 +08:00
GaoHao c3c9437939 Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-10 17:39:48 +08:00
GaoHao 61bd37de32 feat: 供应商账单付款回显修改 2025-04-10 17:39:34 +08:00
YeMingfei666 8126907093 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-10 16:42:58 +08:00
YeMingfei666 34ab5a9643 Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-10 16:02:25 +08:00
GaoHao dbf8f8f05d feat: 供应商账单默认值显示处理 2025-04-10 14:42:18 +08:00
wwz 2922de551a Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-10 14:29:22 +08:00
wwz 5b30b23ad3 feat: 通知中心 2025-04-10 14:29:10 +08:00
GaoHao dedaaac375 feat: 销售统计分类获取优化 2025-04-10 11:00:58 +08:00
GaoHao eb6dffb3d2 feat:数据统计自定义增加默认时间 2025-04-10 10:38:39 +08:00
GaoHao 7df5163ee0 Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-10 09:16:12 +08:00
GaoHao dce9fa7cdb feat: 筛选时间条件增加时分秒 2025-04-09 18:27:35 +08:00
YeMingfei666 787f6606e4 Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-09 18:21:30 +08:00
YeMingfei666 49d43dc22c Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-09 18:12:24 +08:00
YeMingfei666 29ab771472 Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-09 18:12:13 +08:00
GaoHao d4c4989b26 feat: 筛选时间条件增加时分秒 2025-04-09 18:02:02 +08:00
GaoHao d3e18f3a8c Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-09 17:33:05 +08:00
GaoHao f1e85eeb27 feat:分店筛选显示条件增加 2025-04-09 17:32:50 +08:00
YeMingfei666 fd3167d325 fix: 更新readme文档测试服务器相关文档 2025-04-09 17:17:21 +08:00
YeMingfei666 78806f627e Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-09 17:08:32 +08:00
GaoHao 448261e7b2 feat:桌台统计增加分店条件 2025-04-09 16:53:51 +08:00
GaoHao 2b09e4df2c Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-09 16:43:57 +08:00
GaoHao 3dc62a6802 fix:分店筛选增加 2025-04-09 16:43:18 +08:00
wwz c5f75a20af Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-09 16:26:21 +08:00
wwz 0b81b8355e feat: 数据更改 2025-04-09 16:26:02 +08:00
GaoHao cb1f4b3a8c fix:店铺列表添加修改 2025-04-09 16:13:26 +08:00
GaoHao 2546bdbd2d fix:添加店铺主店列表修改 2025-04-09 15:15:41 +08:00
GaoHao f8c3c41247 fix:添加店铺主店列表修改 2025-04-09 15:08:43 +08:00
GaoHao 373fd88226 fix: 多门店切换修改 2025-04-09 10:46:56 +08:00
GaoHao 1cc9949cd8 Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-08 17:49:23 +08:00
GaoHao 7ccd96a775 多门店切换修改 2025-04-08 17:49:08 +08:00
wwz d6a576f729 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-08 17:41:44 +08:00
wwz 86f68a5cdf feat: 进销存更新 2025-04-08 17:41:30 +08:00
GaoHao 250f42ec01 fix: 分店同步更新 2025-04-08 16:15:46 +08:00
GaoHao 684a83b0db fix: 分店同步更新 2025-04-08 16:13:33 +08:00
GaoHao 6b5290d355 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into gaohao 2025-04-08 16:06:08 +08:00
GaoHao acc76c2faf fix: 分店显示修改 2025-04-08 16:05:00 +08:00
GaoHao 920f686897 Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-08 14:50:16 +08:00
GaoHao 2de1576f76 fix:店铺列表分店相关修改 2025-04-08 14:49:59 +08:00
wwz 6fb991ff32 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into wwz 2025-04-08 11:26:41 +08:00
YeMingfei666 367efae393 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-08 11:20:22 +08:00
wwz 5809e0ec0b feat: 解决冲突 2025-04-08 11:19:36 +08:00
GaoHao 143de9fa21 Merge branch 'gaohao' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-08 11:19:31 +08:00
GaoHao a2361b39c4 fix:供应商账单测试 2025-04-08 11:18:37 +08:00
wwz d34a8c71e9 feat: 通知管理 2025-04-08 11:18:36 +08:00
YeMingfei666 8b84eee933 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-08 09:40:57 +08:00
YeMingfei666 62076b4472 feat: 代码合并 2025-04-07 18:27:14 +08:00
wwz 7b46671373 Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into multi-store 2025-04-07 18:25:18 +08:00
YeMingfei666 035aa6bc21 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-07 18:24:03 +08:00
wwz 95f22ede1d feat: 耗材补充修改 2025-04-07 18:13:52 +08:00
YeMingfei666 4be210727c Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-07 17:21:08 +08:00
YeMingfei666 b1d175b108 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-07 16:21:56 +08:00
YeMingfei666 b74adf2010 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-07 15:11:56 +08:00
YeMingfei666 20462cca44 Merge branch 'master' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-07 14:09:32 +08:00
YeMingfei666 98c6f5175f Merge branch 'multi-store' of https://e.coding.net/g-cphe0354/cashier/cashier-web into ymf_test 2025-04-07 10:12:29 +08:00
GaoHao 164dd52afa fix:增加收银中心,供应商账单,分店管理修改 2025-04-03 14:29:25 +08:00
GaoHao 11b297baa5 新需求修改:菜单调整,分店下拉增加,分店管理增加,增加店铺修改 2025-04-02 17:14:55 +08:00
GaoHao d0a757957d 1 2025-04-02 13:40:02 +08:00
GaoHao 13a39e1b13 导航修改 2025-04-02 11:49:08 +08:00
68 changed files with 3263 additions and 1164 deletions

View File

@ -89,5 +89,9 @@
}, },
"[jsonc]": { "[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features" "editor.defaultFormatter": "vscode.json-language-features"
},
"files.associations": {
"*.ttml": "xml",
"*.ttss": "css"
} }
} }

View File

@ -10,6 +10,19 @@ const ShopApi = {
params: params, params: params,
}); });
}, },
getBranchList(params: PageQuery) {
return request<any, ShopInfoEditDTO[]>({
url: `${baseURL}/branchList`,
method: "get",
params: params,
});
},
getBranchChange(id: PageQuery) {
return request<any, ShopInfoEditDTO[]>({
url: `${baseURL}/change/${id}`,
method: "post",
});
},
add(data: ShopInfoEditDTO) { add(data: ShopInfoEditDTO) {
return request<any, ShopInfoEditDTO>({ return request<any, ShopInfoEditDTO>({
url: `${baseURL}`, url: `${baseURL}`,

View File

@ -0,0 +1,54 @@
import request from "@/utils/request";
import { Account_BaseUrl } from "@/api/config";
const baseURL = Account_BaseUrl + "/admin/shop/branch";
const ShopBranchApi = {
getList(params: any) {
return request<any>({
url: `${baseURL}/page`,
method: "get",
params
});
},
getDataSync(params: any) {
return request<any>({
url: `${baseURL}/get/dataSyncMethod`,
method: "get",
params
});
},
setDataSync(id: any) {
return request<any>({
url: `${baseURL}/setting/dataSyncMethod?dataSyncMethod=${id}`,
method: "post",
});
},
dataSync(id: any) {
return request<any>({
url: `${baseURL}/data/sync/enable?branchShopId=${id}`,
method: "post",
});
},
enable(id: any) {
return request<any>({
url: `${baseURL}/account/enable?branchShopId=${id}`,
method: "post",
});
},
disable(id: any) {
return request<any>({
url: `${baseURL}/account/disable?branchShopId=${id}`,
method: "post",
});
},
};
export interface Responseres {
code?: number | null;
data?: any;
msg?: null | string;
[property: string]: any;
}
export default ShopBranchApi;

View File

@ -0,0 +1,58 @@
import request from "@/utils/request";
import { Account_BaseUrl } from "@/api/config";
const baseURL = Account_BaseUrl + "/admin";
// 供应商
const Api = {
/** 通知消息列表*/
getList(params: any) {
return request<any>({
url: `${baseURL}/syncNotice`,
method: "get",
params,
});
},
/** 全部*/
getAllList(params: any) {
return request<any>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
get(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "get",
});
},
add(data: any) {
return request<any>({
url: `${baseURL}`,
method: "post",
data,
});
},
edit(data: any) {
return request<any>({
url: `${baseURL}/syncNotice/read`,
method: "put",
data,
});
},
delete(id: string | number) {
return request<any>({
url: `${baseURL}/syncNotice?id=` + id,
method: "delete",
});
},
// 清空已读
syncNoticeclear() {
return request<any>({
url: `${baseURL}/syncNotice/clear`,
method: "delete",
});
},
};
export default Api;

View File

@ -55,7 +55,7 @@ const AuthAPI = {
method: "delete", method: "delete",
}); });
}, },
// 退款退回 // 同步
refundToStock(data: any) { refundToStock(data: any) {
return request<any, Responseres>({ return request<any, Responseres>({
url: `${baseURL}/refundToStock`, url: `${baseURL}/refundToStock`,
@ -63,6 +63,14 @@ const AuthAPI = {
data, data,
}); });
}, },
// 退款退回
sync(data: any) {
return request<any, Responseres>({
url: `${baseURL}/sync`,
method: "post",
data,
});
},
// 耗材列表 // 耗材列表
productcons(params: any) { productcons(params: any) {

View File

@ -0,0 +1,51 @@
import request from "@/utils/request";
import { Product_BaseUrl } from "@/api/config";
const baseURL = Product_BaseUrl + "/admin/product";
// 供应商
const Api = {
/** 耗材库存变动记录*/
getList(params: any) {
return request<any>({
url: `${baseURL}/stock/flow`,
method: "get",
params,
});
},
/** 全部*/
getAllList(params: any) {
return request<any>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
get(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "get",
});
},
add(data: any) {
return request<any>({
url: `${baseURL}`,
method: "post",
data,
});
},
edit(data: any) {
return request<any>({
url: `${baseURL}`,
method: "put",
data,
});
},
delete(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "delete",
});
},
};
export default Api;

View File

@ -8,7 +8,7 @@ const Api = {
return request<any>({ return request<any>({
url: `${baseURL}/in`, url: `${baseURL}/in`,
method: "post", method: "post",
data data,
}); });
}, },
//出库 //出库
@ -16,7 +16,7 @@ const Api = {
return request<any>({ return request<any>({
url: `${baseURL}/out`, url: `${baseURL}/out`,
method: "post", method: "post",
data data,
}); });
}, },
// 库存盘点记录 // 库存盘点记录
@ -24,7 +24,7 @@ const Api = {
return request<any>({ return request<any>({
url: `${baseURL}/checkRecord`, url: `${baseURL}/checkRecord`,
method: "get", method: "get",
params params,
}); });
}, },
//库存盘点 //库存盘点
@ -32,7 +32,7 @@ const Api = {
return request<any>({ return request<any>({
url: `${baseURL}/check`, url: `${baseURL}/check`,
method: "post", method: "post",
data data,
}); });
}, },
//耗材报损 //耗材报损
@ -41,7 +41,7 @@ const Api = {
return request<any>({ return request<any>({
url: `${baseURL}/reportDamage`, url: `${baseURL}/reportDamage`,
method: "post", method: "post",
data data,
}); });
}, },
//耗材库存变动记录 //耗材库存变动记录
@ -49,11 +49,17 @@ const Api = {
return request<any>({ return request<any>({
url: `${baseURL}/flow`, url: `${baseURL}/flow`,
method: "get", method: "get",
params params,
});
},
//耗材库存变动记录
reportinglosses(data: any) {
return request<any>({
url: `${baseURL}/reportDamage`,
method: "POST",
data,
}); });
}, },
}; };
export default Api; export default Api;

60
src/api/supplier/index.ts Normal file
View File

@ -0,0 +1,60 @@
import request from "@/utils/request";
const baseURL = "/product/admin/product/vendor";
// 供应商账单
const AuthAPI = {
/** 供应商账单统计*/
getSummary(params: any) {
return request<any, Responseres>({
url: `${baseURL}/summary`,
method: "get",
params,
});
},
/** 分页*/
getPage(params: any) {
return request<any, Responseres>({
url: `${baseURL}/bill`,
method: "get",
params,
});
},
// 账单记录
getRecordList(params: any) {
return request<any, Responseres>({
url: `${baseURL}/bill/record`,
method: "get",
params,
});
},
// 账单付款记录
getPayRecordList(params: any) {
return request<any, Responseres>({
url: `${baseURL}/bill/pay/record`,
method: "get",
params,
});
},
// 账单付款
billPay(data: any) {
return request<any, Responseres>({
url: `${baseURL}/bill/pay`,
method: "post",
data,
});
},
};
export interface Responseres {
code?: number | null;
data?: any;
msg?: null | string;
[property: string]: any;
}
export default AuthAPI;

View File

@ -246,6 +246,7 @@ export interface UserInfo {
* *
*/ */
export interface UserPageQuery extends PageQuery { export interface UserPageQuery extends PageQuery {
times: any;
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;

View File

@ -1,19 +1,70 @@
<template> <template>
<div class="logo"> <div class="logo wh-full flex-center">
<transition name="el-fade-in-linear" mode="out-in"> <!-- <transition name="el-fade-in-linear" mode="out-in"> -->
<router-link :key="+collapse" class="wh-full flex-center" to="/"> <!-- <router-link :key="+collapse" class="wh-full flex-center" to="/"> -->
<img :src="userStore.userInfo.logo" class="w20px h20px" /> <img :src="state.userInfo.logo" class="w20px h20px" />
<span v-if="!collapse" class="title">{{ userStore.userInfo.shopName }}</span> <!-- <span v-if="!collapse" class="title">{{ userStore.userInfo.shopName }}</span> -->
</router-link> <el-dropdown trigger="click" @command="handleCommand">
</transition> <div class="el-dropdown-link" style="display: flex;">
<div v-if="!collapse" class="title">{{ state.shopName }}</div>
<el-icon class="el-icon--right" v-if="loginType == 0">
<arrow-down />
</el-icon>
</div>
<template #dropdown>
<el-dropdown-menu v-if="loginType == 0">
<el-dropdown-item :command="item.shopId" v-for="(item, index) in state.branchList" :key="index"> {{
item.shopName }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- </router-link> -->
<!-- </transition> -->
</div> </div>
</template> </template>
<script lang="ts" setup> <script setup>
import defaultSettings from "@/settings"; import defaultSettings from "@/settings";
import { useUserStore } from "@/store"; import { useUserStore } from "@/store";
import ShopApi from "@/api/account/shop";
const userStore = useUserStore(); const userStore = useUserStore();
const state = reactive({
branchList: [],
userInfo: useUserStore().userInfo,
shopName: useUserStore().userInfo.shopName
});
const loginType = ref(localStorage.getItem("loginType"))
onMounted(() => {
geiShopList()
});
async function geiShopList() {
let res = await ShopApi.getBranchList()
state.branchList = res;
if (!localStorage.getItem("shopName")) {
state.shopName = state.branchList[0].shopName
localStorage.setItem("branch_shopId", state.branchList[0].id)
localStorage.setItem("shopName", state.branchList[0].shopName)
} else {
state.shopName = localStorage.getItem("shopName")
}
}
async function handleCommand(command) {
console.log(command)
let res = state.branchList.filter(v => v.shopId == command)[0]
// localStorage.getItem("shopId")
if (localStorage.getItem("shopId") == command) {
return
}
await ShopApi.getBranchChange(res.shopId)
// localStorage.setItem("branch_shopId", res.shopId)
localStorage.setItem("shopName", res.shopName)
state.shopName = res.shopName
location.reload()
console.log(res)
console.log(command)
}
defineProps({ defineProps({
collapse: { collapse: {
@ -28,16 +79,18 @@ defineProps({
width: 100%; width: 100%;
height: $navbar-height; height: $navbar-height;
background-color: $sidebar-logo-background; background-color: $sidebar-logo-background;
cursor: pointer;
.title { .title {
flex-shrink: 0; /* 防止容器在空间不足时缩小 */ flex-shrink: 0;
/* 防止容器在空间不足时缩小 */
margin-left: 10px; margin-left: 10px;
font-size: 16px; font-size: 16px;
color: #5a5e66; color: #5a5e66;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
max-width: 150px; max-width: 100px;
} }
} }

View File

@ -63,38 +63,6 @@ export const constantRoutes: RouteRecordRaw[] = [
keepAlive: true, keepAlive: true,
}, },
}, },
{
path: "credit",
name: "",
component: () => import("@/views/data/credit/index.vue"),
meta: {
title: "挂账管理",
affix: false,
keepAlive: true,
},
},
{
path: "credit-detail",
name: "",
component: () => import("@/views/data/credit/detail.vue"),
meta: {
title: "挂账明细",
affix: false,
keepAlive: true,
hidden: true
},
},
{
path: "work",
name: "",
component: () => import("@/views/data/work.vue"),
meta: {
title: "交班记录",
affix: false,
keepAlive: true,
},
},
{ {
path: "401", path: "401",
component: () => import("@/views/error/401.vue"), component: () => import("@/views/error/401.vue"),
@ -473,7 +441,6 @@ export const constantRoutes: RouteRecordRaw[] = [
// /**列表end */ // /**列表end */
// ], // ],
// }, // },
// { // {

View File

@ -31,13 +31,14 @@ export const useUserStore = defineStore("user", () => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
AuthAPI.login(loginRequest) AuthAPI.login(loginRequest)
.then((data) => { .then((data) => {
isShopAdmin.value = data.loginType == 0 ? true : false; isShopAdmin.value = data.loginType == 0 ? true : false;
Object.assign(userInfo.value, { ...data.shopInfo, shopId: data.shopInfo.id }); Object.assign(userInfo.value, { ...data.shopInfo, shopId: data.shopInfo.id });
promissionList.value = data.promissionList; promissionList.value = data.promissionList;
const token = data.tokenInfo.tokenValue; const token = data.tokenInfo.tokenValue;
setToken(token); setToken(token);
setRefreshToken(token); setRefreshToken(token);
localStorage.setItem("shopId", "" + data.shopInfo.id);
localStorage.setItem("branch_shopId", data.shopInfo.id)
resolve(); resolve();
}) })
.catch((error) => { .catch((error) => {
@ -51,16 +52,18 @@ export const useUserStore = defineStore("user", () => {
* *
* @returns {UserInfo} * @returns {UserInfo}
*/ */
function getUserInfo() { function getUserInfo(shopId?: string | number) {
return new Promise<UserInfo>((resolve, reject) => { return new Promise<UserInfo>((resolve, reject) => {
ShopApi.get({ id: userInfo.value.shopId }) ShopApi.get({ id: shopId || userInfo.value.shopId })
.then((data) => { .then((data) => {
if (!data) { if (!data) {
reject("Verification failed, please Login again."); reject("Verification failed, please Login again.");
return; return;
} }
localStorage.setItem("shopId", "" + userInfo.value.shopId); console.log(userInfo)
Object.assign(userInfo.value, { ...data, roles: [], promissionList: [], shopId: userInfo.value.shopId }); console.log(data)
localStorage.setItem("shopId", "" + data.id);
Object.assign(userInfo.value, { ...data, roles: [], promissionList: [], shopId: data.id });
resolve(userInfo.value); resolve(userInfo.value);
}) })
.catch((error) => { .catch((error) => {

View File

@ -117,3 +117,28 @@ export function downloadFile(obj: BlobPart, name: string, suffix: string, useUni
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
} }
/**
*
*/
export function isSyncStatus() {
let userInfo = ref(JSON.parse(localStorage.getItem('userInfo') || '{}'))
if (userInfo.value.isHeadShop == 0 && userInfo.value.isEnableProdSync == 1 && userInfo.value.isEnableVipSync == 1 && userInfo.value.isEnableConsSync == 1) {
return true
}else {
return false
}
}
/**
*
*/
export function hasPermission(params: any) {
let $PermissionObj = JSON.parse(localStorage.getItem("permission") || '[]' )
const obj = $PermissionObj.find((v: any) => v == params || v == params)
if (obj) {
return obj
}
return false
}

View File

@ -22,6 +22,7 @@ service.interceptors.request.use(
} else { } else {
delete config.headers.token; delete config.headers.token;
} }
// config.headers.shopId = config.headers.shopId || localStorage.getItem("branch_shopId");
config.headers.shopId = config.headers.shopId || useUserStoreHook().userInfo.id; config.headers.shopId = config.headers.shopId || useUserStoreHook().userInfo.id;
return config; return config;
}, },

View File

@ -40,7 +40,7 @@
}" }"
@row-click="handleRowClick" @row-click="handleRowClick"
> >
<el-table-column label="菜单名称" min-width="100"> <el-table-column label="菜单名称" min-width="140">
<template #default="scope"> <template #default="scope">
{{ scope.row.title }} {{ scope.row.title }}
</template> </template>
@ -162,7 +162,7 @@
<el-radio :value="2">接口</el-radio> <el-radio :value="2">接口</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="是否外链" prop="path"> <el-form-item label="是否外链" >
<el-switch <el-switch
v-model="formData.iFrame" v-model="formData.iFrame"
:active-value="1" :active-value="1"

View File

@ -28,16 +28,8 @@
</div> </div>
</div> </div>
<el-tree <el-tree ref="permTreeRef" node-key="value" show-checkbox :data="menuPermOptions"
ref="permTreeRef" :filter-node-method="handlePermFilter" :default-expand-all="true" :check-strictly="!parentChildLinked" class="mt-5">
node-key="value"
show-checkbox
:data="menuPermOptions"
:filter-node-method="handlePermFilter"
:default-expand-all="true"
:check-strictly="!parentChildLinked"
class="mt-5"
>
<template #default="{ data }"> <template #default="{ data }">
{{ data.label }} {{ data.label }}
</template> </template>
@ -110,7 +102,7 @@ onMounted(() => {
watch( watch(
() => modelValue.value, () => modelValue.value,
(newval) => {} (newval) => { }
); );
function getPerms() { function getPerms() {
@ -122,7 +114,6 @@ function reset() {
} }
function setChecked(checkedMenuIds) { function setChecked(checkedMenuIds) {
checkedMenuIds.forEach((menuId) => { checkedMenuIds.forEach((menuId) => {
console.log(menuId);
permTreeRef.value.setChecked(menuId, true, false); permTreeRef.value.setChecked(menuId, true, false);
}); });
} }

View File

@ -338,8 +338,6 @@ async function handleOpenDialog(row: SysRole) {
dialog.title = "新增角色"; dialog.title = "新增角色";
} }
} }
//test
async function handleSubmit() {}
// //
function handleSubmit() { function handleSubmit() {

View File

@ -81,6 +81,7 @@ import couponEnum from "./couponEnum";
import couponDetails from "./components/coupon_details.vue"; import couponDetails from "./components/coupon_details.vue";
import couponAdd from "./components/add.vue"; import couponAdd from "./components/add.vue";
import couponApi from "@/api/account/coupon"; import couponApi from "@/api/account/coupon";
import { hasPermission } from "@/utils/index";
export default { export default {
// eslint-disable-next-line vue/no-unused-components // eslint-disable-next-line vue/no-unused-components
@ -100,6 +101,9 @@ export default {
}, },
mounted() { mounted() {
this.getTableData(); this.getTableData();
console.log(hasPermission('coupon:add'))
console.log(hasPermission('coupon:edit'))
// coupon:add shopStaff:add
}, },
methods: { methods: {
toAdd(data) { toAdd(data) {

View File

@ -47,11 +47,15 @@
</div> --> </div> -->
<div class="h_card_wrap"> <div class="h_card_wrap">
<div class="status_wrap"> <div class="status_wrap">
<div class="left"> <div class="left" style="flex-shrink: 0">
<div class="dot" /> <div class="dot" />
<span>营业</span> <span>营业</span>
</div> </div>
<div class="time_wrap u-flex"> <div class="u-flex" style="flex-wrap: wrap">
<el-select v-if="isHeadShop == 1&&loginType == 0" v-model="shopId" placeholder="选择分店" style="width: 200px; margin-right: 10px;" @change="shopChange">
<el-option v-for="item in branchList" :key="item.shopId" :label="item.shopName" :value="item.shopId" />
</el-select>
<div class="time_wrap u-flex" style="flex-shrink: 0">
<el-radio-group v-model="timeValue" class="m-r-5" @change="timeChange"> <el-radio-group v-model="timeValue" class="m-r-5" @change="timeChange">
<el-radio-button value="0">今天</el-radio-button> <el-radio-button value="0">今天</el-radio-button>
<el-radio-button value="-1">昨天</el-radio-button> <el-radio-button value="-1">昨天</el-radio-button>
@ -62,8 +66,10 @@
<el-radio-button value="custom">自定义</el-radio-button> <el-radio-button value="custom">自定义</el-radio-button>
</el-radio-group> </el-radio-group>
<div class="u-flex"> <div class="u-flex">
<el-date-picker v-if="timeValue == 'custom'" v-model="query.createdAt" type="daterange" range-separator="" <el-date-picker v-if="timeValue == 'custom'" v-model="query.createdAt" type="daterange"
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD " @change="summarytrade" /> range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD HH:mm:ss"
@change="summarytrade" />
</div>
</div> </div>
</div> </div>
</div> </div>
@ -332,6 +338,7 @@
<script> <script>
import dataSummaryApi from "@/api/order/data-summary"; import dataSummaryApi from "@/api/order/data-summary";
import ShopApi from "@/api/account/shop";
import dayjs from "dayjs"; import dayjs from "dayjs";
import * as echarts from "echarts"; import * as echarts from "echarts";
import { debounce, formatDecimal } from "@/utils/tools"; import { debounce, formatDecimal } from "@/utils/tools";
@ -383,6 +390,8 @@ export default {
saveAmount: null, saveAmount: null,
}, },
], ],
branchList: [],
shopId: null,
trade: {}, trade: {},
formatDecimal, formatDecimal,
topData: "", topData: "",
@ -419,6 +428,8 @@ export default {
}, },
tradeVip: "", tradeVip: "",
tradeCount: "", tradeCount: "",
isHeadShop: JSON.parse(localStorage.getItem("userInfo")).isHeadShop,
loginType: localStorage.getItem("loginType")
}; };
}, },
computed: { computed: {
@ -473,9 +484,22 @@ export default {
// } // }
}, 100); }, 100);
window.addEventListener("resize", this.__resizeHandler); window.addEventListener("resize", this.__resizeHandler);
this.geiShopList()
// this.initCardUserChart(); // this.initCardUserChart();
}, },
methods: { methods: {
/**
* 获取分店列表
*/
async geiShopList() {
let res = await ShopApi.getBranchList()
this.branchList = res;
},
shopChange(){
this.summarytrade();
this.lineChartTypeChange(this.lineChartType)
this.dateProduct()
},
// //
timeChange(e) { timeChange(e) {
const format = ["YYYY-MM-DD 00:00:00", "YYYY-MM-DD 23:59:59"]; const format = ["YYYY-MM-DD 00:00:00", "YYYY-MM-DD 23:59:59"];
@ -525,7 +549,9 @@ export default {
break; break;
case "custom": case "custom":
// //
this.query.createdAt = []; this.query.createdAt = [
dayjs().add(-30, "d").format(format[0]),
dayjs().format(format[1]),];
break; break;
default: default:
break; break;
@ -538,9 +564,13 @@ export default {
async summarytrade() { async summarytrade() {
try { try {
this.tradeLoading = true; this.tradeLoading = true;
if( this.query.createdAt[1] ){
this.query.createdAt.splice(1,1,this.query.createdAt[1].replace("00:00:00","23:59:59"))
}
const res = await dataSummaryApi.trade({ const res = await dataSummaryApi.trade({
beginDate: this.query.createdAt[0], beginDate: this.query.createdAt[0],
endDate: this.query.createdAt[1], endDate: this.query.createdAt[1],
shopId: this.shopId
}); });
this.trade = res; this.trade = res;
this.tradeLoading = false; this.tradeLoading = false;
@ -864,7 +894,7 @@ export default {
async dateAmount() { async dateAmount() {
try { try {
this.saleLoading = true; this.saleLoading = true;
const res = await dataSummaryApi.dateAmount({ day: this.saleActive }); const res = await dataSummaryApi.dateAmount({ day: this.saleActive,shopId: this.shopId });
const data = res.total.map((item) => { const data = res.total.map((item) => {
return { return {
orderAmount: item.orderAmount, orderAmount: item.orderAmount,
@ -893,6 +923,7 @@ export default {
day: this.saleTableActive, day: this.saleTableActive,
page: this.saleTablePage, page: this.saleTablePage,
size: this.saleTableSize, size: this.saleTableSize,
shopId: this.shopId
}); });
this.saleTable = res.records; this.saleTable = res.records;
this.saleTableTotal = res.totalRow * 1; this.saleTableTotal = res.totalRow * 1;
@ -908,7 +939,7 @@ export default {
async datePayType() { async datePayType() {
try { try {
this.payChartLoading = true; this.payChartLoading = true;
const res = await dataSummaryApi.datePayType({ day: this.saleActive }); const res = await dataSummaryApi.datePayType({ day: this.saleActive,shopId: this.shopId });
const data = res.countPayType.map((item) => { const data = res.countPayType.map((item) => {
return { return {
value: item.count, value: item.count,

View File

@ -10,16 +10,18 @@
<el-form-item> <el-form-item>
<el-input placeholder="商品名称" v-model="query.productName" /> <el-input placeholder="商品名称" v-model="query.productName" />
</el-form-item> </el-form-item>
<el-form-item>
<el-select v-model="query.prodCategoryId" placeholder="商品分类" style="width: 140px"> <el-form-item v-if="isHeadShop == 1&&loginType == 0">
<el-option <el-select v-model="shopId" placeholder="选择分店" style="width: 200px; margin-right: 10px"
:label="item.name" @change="getCategory">
:value="item.id" <el-option v-for="item in branchList" :key="item.shopId" :label="item.shopName" :value="item.shopId" />
v-for="item in categorys"
:key="item.id"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item>
<el-select v-model="query.prodCategoryId" placeholder="商品分类" style="width: 140px">
<el-option :label="item.name" :value="item.id" v-for="item in categorys" :key="item.id"></el-option>
</el-select>
</el-form-item> -->
</template> </template>
<el-form-item> <el-form-item>
<el-radio-group v-model="timeValue" @change="timeChange"> <el-radio-group v-model="timeValue" @change="timeChange">
@ -32,16 +34,9 @@
<el-radio-button value="month">本月</el-radio-button> <el-radio-button value="month">本月</el-radio-button>
<el-radio-button value="custom">自定义</el-radio-button> <el-radio-button value="custom">自定义</el-radio-button>
</el-radio-group> </el-radio-group>
<el-date-picker <el-date-picker class="u-m-l-10" v-model="query.createdAt" type="daterange" range-separator=""
class="u-m-l-10" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD HH:mm:ss"
v-model="query.createdAt" v-if="timeValue == 'custom'"></el-date-picker>
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
v-if="timeValue == 'custom'"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getTableData">查询</el-button> <el-button type="primary" @click="getTableData">查询</el-button>
@ -57,7 +52,9 @@
<div class="collect_wrap"> <div class="collect_wrap">
<div class="item"> <div class="item">
<div class="icon_wrap" style="--bg-color: #c978ee"> <div class="icon_wrap" style="--bg-color: #c978ee">
<el-icon color="#fff"><Coin /></el-icon> <el-icon color="#fff">
<Coin />
</el-icon>
</div> </div>
<div class="info"> <div class="info">
<div class="m">{{ payCount.totalAmount || 0 }}</div> <div class="m">{{ payCount.totalAmount || 0 }}</div>
@ -66,7 +63,9 @@
</div> </div>
<div class="item"> <div class="item">
<div class="icon_wrap" style="--bg-color: #c978ee"> <div class="icon_wrap" style="--bg-color: #c978ee">
<el-icon color="#fff"><Coin /></el-icon> <el-icon color="#fff">
<Coin />
</el-icon>
</div> </div>
<div class="info"> <div class="info">
<div class="m">{{ payCount.refundAmount || 0 }}</div> <div class="m">{{ payCount.refundAmount || 0 }}</div>
@ -75,7 +74,9 @@
</div> </div>
<div class="item"> <div class="item">
<div class="icon_wrap" style="--bg-color: #c978ee"> <div class="icon_wrap" style="--bg-color: #c978ee">
<el-icon color="#fff"><ShoppingCartFull /></el-icon> <el-icon color="#fff">
<ShoppingCartFull />
</el-icon>
</div> </div>
<div class="info"> <div class="info">
<div class="m">{{ payCount.saleCount || 0 }}</div> <div class="m">{{ payCount.saleCount || 0 }}</div>
@ -84,7 +85,9 @@
</div> </div>
<div class="item"> <div class="item">
<div class="icon_wrap" style="--bg-color: #c978ee"> <div class="icon_wrap" style="--bg-color: #c978ee">
<el-icon color="#fff"><ShoppingCart /></el-icon> <el-icon color="#fff">
<ShoppingCart />
</el-icon>
</div> </div>
<div class="info"> <div class="info">
<div class="m">{{ payCount.refundCount || 0 }}</div> <div class="m">{{ payCount.refundCount || 0 }}</div>
@ -145,14 +148,9 @@
</el-table> </el-table>
</div> </div>
<div class="head-container"> <div class="head-container">
<el-pagination <el-pagination :total="tableData.total" :current-page="tableData.page" :page-size="tableData.size"
:total="tableData.total" @current-change="paginationChange" @size-change="sizeChange"
:current-page="tableData.page" layout="total, sizes, prev, pager, next, jumper"></el-pagination>
:page-size="tableData.size"
@current-change="paginationChange"
@size-change="sizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
</div> </div>
</div> </div>
</template> </template>
@ -160,6 +158,7 @@
<script> <script>
import saleSummaryApi from "@/api/order/sale-summary"; import saleSummaryApi from "@/api/order/sale-summary";
import categoryApi from "@/api/product/productclassification"; import categoryApi from "@/api/product/productclassification";
import ShopApi from "@/api/account/shop";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { downloadFile } from "@/utils/index"; import { downloadFile } from "@/utils/index";
@ -185,6 +184,11 @@ export default {
downloadLoading: false, downloadLoading: false,
payCount: "", payCount: "",
payCountTotal: 0, payCountTotal: 0,
branchList: [],
shopId: null,
isHeadShop: JSON.parse(localStorage.getItem("userInfo")).isHeadShop,
loginType: localStorage.getItem("loginType")
}; };
}, },
filters: { filters: {
@ -196,8 +200,16 @@ export default {
this.resetQuery = { ...this.query }; this.resetQuery = { ...this.query };
this.getTableData(); this.getTableData();
this.getCategory(); this.getCategory();
this.geiShopList();
}, },
methods: { methods: {
/**
* 获取分店列表
*/
async geiShopList() {
let res = await ShopApi.getBranchList()
this.branchList = res;
},
totalfilter(item, d) { totalfilter(item, d) {
let num = item + d; let num = item + d;
return num.toFixed(2); return num.toFixed(2);
@ -205,10 +217,12 @@ export default {
// //
async getCategory() { async getCategory() {
try { try {
this.query.prodCategoryId = ""
const res = await categoryApi.getList({ const res = await categoryApi.getList({
page: 1, page: 1,
size: 200, size: 200,
orderBy: "name asc", orderBy: "name asc",
shopId: this.shopId
}); });
this.categorys = res; this.categorys = res;
} catch (error) { } catch (error) {
@ -218,12 +232,15 @@ export default {
// //
async daycount() { async daycount() {
try { try {
if (this.query.createdAt[1]) {
this.query.createdAt.splice(1, 1, this.query.createdAt[1].replace("00:00:00", "23:59:59"))
}
const res = await saleSummaryApi.count({ const res = await saleSummaryApi.count({
beginDate: this.query.createdAt[0], beginDate: this.query.createdAt[0],
endDate: this.query.createdAt[1], endDate: this.query.createdAt[1],
prodCategoryId: this.query.prodCategoryId, prodCategoryId: this.query.prodCategoryId,
productName: this.query.productName, productName: this.query.productName,
shopId: this.shopId,
type: this.orderType, type: this.orderType,
}); });
this.payCount = res; this.payCount = res;
@ -235,11 +252,15 @@ export default {
async downloadHandle() { async downloadHandle() {
try { try {
this.downloadLoading = true; this.downloadLoading = true;
if (this.query.createdAt[1]) {
this.query.createdAt.splice(1, 1, this.query.createdAt[1].replace("00:00:00", "23:59:59"))
}
const file = await saleSummaryApi.export({ const file = await saleSummaryApi.export({
beginDate: this.query.createdAt[0], beginDate: this.query.createdAt[0],
endDate: this.query.createdAt[1], endDate: this.query.createdAt[1],
prodCategoryId: this.query.prodCategoryId, prodCategoryId: this.query.prodCategoryId,
productName: this.query.productName, productName: this.query.productName,
shopId: this.shopId
}); });
downloadFile(file, "数据", "xlsx"); downloadFile(file, "数据", "xlsx");
this.downloadLoading = false; this.downloadLoading = false;
@ -269,6 +290,9 @@ export default {
this.tableData.loading = true; this.tableData.loading = true;
try { try {
this.daycount(); this.daycount();
if (this.query.createdAt[1]) {
this.query.createdAt.splice(1, 1, this.query.createdAt[1].replace("00:00:00", "23:59:59"))
}
const res = await saleSummaryApi.page({ const res = await saleSummaryApi.page({
page: this.tableData.page, page: this.tableData.page,
size: this.tableData.size, size: this.tableData.size,
@ -277,6 +301,7 @@ export default {
endDate: this.query.createdAt[1], endDate: this.query.createdAt[1],
productName: this.query.productName, productName: this.query.productName,
prodCategoryId: this.query.prodCategoryId, prodCategoryId: this.query.prodCategoryId,
shopId: this.shopId
}); });
this.tableData.loading = false; this.tableData.loading = false;
this.tableData.data = res.records; this.tableData.data = res.records;

View File

@ -6,7 +6,7 @@
</el-tabs> --> </el-tabs> -->
<div class="head-container"> <div class="head-container">
<el-form :model="query" inline label-position="left"> <el-form :model="query" inline label-position="left">
<div class="u-flex gap-10"> <div class="u-flex gap-10" style="flex-wrap: wrap;">
<el-radio-group v-model="timeValue" @change="timeChange"> <el-radio-group v-model="timeValue" @change="timeChange">
<el-radio-button value="">全部</el-radio-button> <el-radio-button value="">全部</el-radio-button>
<el-radio-button value="0">今天</el-radio-button> <el-radio-button value="0">今天</el-radio-button>
@ -18,14 +18,14 @@
<el-radio-button value="custom">自定义</el-radio-button> <el-radio-button value="custom">自定义</el-radio-button>
</el-radio-group> </el-radio-group>
<div> <div>
<el-date-picker <el-date-picker v-model="query.createdAt" type="daterange" range-separator="" start-placeholder="开始日期"
v-model="query.createdAt" end-placeholder="结束日期" value-format="YYYY-MM-DD HH:mm:ss"></el-date-picker>
type="daterange" </div>
range-separator="至" <div>
start-placeholder="开始日期" <el-select v-model="shopId" v-if="isHeadShop == 1&& loginType == 0" placeholder="选择分店"
end-placeholder="结束日期" style="width: 200px; margin-right: 10px">
value-format="YYYY-MM-DD" <el-option v-for="item in branchList" :key="item.shopId" :label="item.shopName" :value="item.shopId" />
></el-date-picker> </el-select>
</div> </div>
<div> <div>
<el-button type="primary" @click="getTableData">查询</el-button> <el-button type="primary" @click="getTableData">查询</el-button>
@ -100,6 +100,7 @@
<script> <script>
import tableSummaryApi from "@/api/order/table-summary"; import tableSummaryApi from "@/api/order/table-summary";
import ShopApi from "@/api/account/shop";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { downloadFile } from "@/utils/index"; import { downloadFile } from "@/utils/index";
@ -125,6 +126,11 @@ export default {
downloadLoading: false, downloadLoading: false,
payCountList: "", payCountList: "",
payCountTotal: 0, payCountTotal: 0,
shopId: null,
branchList: [],
isHeadShop: JSON.parse(localStorage.getItem("userInfo")).isHeadShop,
loginType: localStorage.getItem("loginType")
}; };
}, },
filters: { filters: {
@ -135,8 +141,16 @@ export default {
mounted() { mounted() {
this.resetQuery = { ...this.query }; this.resetQuery = { ...this.query };
this.getTableData(); this.getTableData();
this.geiShopList();
}, },
methods: { methods: {
/**
* 获取分店列表
*/
async geiShopList() {
let res = await ShopApi.getBranchList()
this.branchList = res;
},
//table id //table id
toTableOrderList(data) { toTableOrderList(data) {
// console.log(data) // console.log(data)
@ -152,9 +166,13 @@ export default {
async downloadHandle() { async downloadHandle() {
try { try {
this.downloadLoading = true; this.downloadLoading = true;
if (this.query.createdAt[1]) {
this.query.createdAt.splice(1, 1, this.query.createdAt[1].replace("00:00:00", "23:59:59"))
}
const file = await tableSummaryApi.export({ const file = await tableSummaryApi.export({
beginDate: this.query.createdAt[0], beginDate: this.query.createdAt[0],
endDate: this.query.createdAt[1], endDate: this.query.createdAt[1],
shopId: this.shopId
}); });
downloadFile(file, "数据", "xlsx"); downloadFile(file, "数据", "xlsx");
this.downloadLoading = false; this.downloadLoading = false;
@ -183,11 +201,15 @@ export default {
async getTableData() { async getTableData() {
this.tableData.loading = true; this.tableData.loading = true;
try { try {
if (this.query.createdAt[1]) {
this.query.createdAt.splice(1, 1, this.query.createdAt[1].replace("00:00:00", "23:59:59"))
}
const res = await tableSummaryApi.list({ const res = await tableSummaryApi.list({
page: this.tableData.page, page: this.tableData.page,
size: this.tableData.size, size: this.tableData.size,
beginDate: this.query.createdAt[0], beginDate: this.query.createdAt[0],
endDate: this.query.createdAt[1], endDate: this.query.createdAt[1],
shopId: this.shopId
}); });
this.tableData.loading = false; this.tableData.loading = false;
this.tableData.data = res; this.tableData.data = res;

View File

@ -0,0 +1,171 @@
<template>
<div class="app-container">
<div class="head-container">
<el-card shadow="never">
<el-alert title="当前列表仅作为数据记录,不产生任何实际交易。" type="warning" show-icon :closable="false"
style="margin-bottom: 15px;" />
<el-row :gutter="20">
<el-col :span="4">
<el-input v-model="state.query.name" clearable placeholder="请输入耗材名称" style="width: 100%" class="filter-item"
@keyup.enter="getTableData" />
</el-col>
<el-col :span="16">
<el-button type="primary" @click="getTableData">查询</el-button>
<el-button type="primary" @click="handlePayment('all')" plain>批量付款</el-button>
<el-text tag="b" size="large" style="margin-left: 15px;">供应商{{ state.supplierName }}</el-text>
</el-col>
</el-row>
</el-card>
</div>
<div class="head-container">
<el-card shadow="never">
<el-table @selection-change="handleSelectionChange" v-loading="state.tableData.loading"
:data="state.tableData.list">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="ID" width="80" />
<el-table-column label="耗材信息">
<template v-slot="scope">
<div>{{ scope.row.conName }}</div>
<div>单价{{ scope.row.purchasePrice }}</div>
<div>入库数量{{ scope.row.inOutNumber }}</div>
</template>
</el-table-column>
<el-table-column prop="amountPayable" label="账单金额" width="120" />
<el-table-column prop="actualPaymentAmount" label="已付款金额" width="120" />
<el-table-column prop="unPaidAmount" label="未付款金额" width="120" />
<el-table-column prop="createTime" label="创建时间" width="120" />
<el-table-column prop="remark" label="备注" />
<el-table-column label="操作" width="200">
<template v-slot="scope">
<el-button type="primary" size="small" link @click="handlePayment(scope.row)">
付款
</el-button>
<el-button type="primary" size="small" link @click="handleRecord(scope.row.id)">
付款记录
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<div class="head-container">
<el-pagination v-model:current-page="state.tableData.page" v-model:page-size="state.tableData.size"
:total="state.tableData.total" :page-sizes="[10, 20, 30, 50, 100]"
layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
</div>
<payment ref="refPayment" @refresh="getTableData"></payment>
</div>
</template>
<script setup>
import AuthAPI from "@/api/supplier/index";
import payment from "./components/payment.vue";
import { ElMessage } from "element-plus";
const route = useRoute();
const router = useRouter();
const state = reactive({
query: {
name: "",
vendorId: null,
},
tableData: {
list: [],
page: 1,
size: 10,
loading: false,
total: 0,
},
supplierName: '',
flowIdList: [],
allAmount: 0
});
onMounted(() => {
if (route.query.vendorId) {
state.query.vendorId = route.query.vendorId
}
if (route.query.supplierName) {
state.supplierName = route.query.supplierName
}
getTableData();
});
//
async function getTableData() {
state.tableData.loading = true;
try {
const res = await AuthAPI.getRecordList({
page: state.tableData.page,
size: state.tableData.size,
key: state.query.name,
vendorId: state.query.vendorId,
});
state.tableData.loading = false;
state.tableData.list = res.records;
state.tableData.total = res.totalRow * 1;
} catch (error) {
console.log(error);
}
}
const refPayment = ref();
function handlePayment(item) {
if (item != 'all') {
state.flowIdList = [item.id]
state.allAmount = item.unPaidAmount
} else {
if( state.flowIdList.length <= 0 ){
ElMessage({ type: "error", message: "请选择付款耗材" });
return;
}
}
refPayment.value.open({ flowIdList: state.flowIdList, supplierName: state.supplierName,allAmount:state.allAmount });
}
function handleSelectionChange(e) {
state.flowIdList = []
state.allAmount = 0
e.map(item => {
state.flowIdList.push(item.id)
state.allAmount += item.unPaidAmount
})
}
//
function handleRecord(id) {
router.push({ name: "financePaymentRecord", query: { id: id, supplierName: state.supplierName } });
}
//
function resetHandle() {
state.query.name = "";
getTableData();
}
//
function paginationChange(e) {
state.tableData.page = e;
getTableData();
}
</script>
<style scoped lang="scss">
.head-container {
margin-bottom: 20px;
}
.shop_info {
display: flex;
.info {
flex: 1;
padding-left: 4px;
}
}
.el-link {
min-height: 23px;
margin: 0 5px;
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<!-- 修改和增加 -->
<el-dialog title="付款" v-model="show" width="400px" @close="reset">
<el-form :inline="false" ref="refform" label-width="90" :model="form" :rules="rules" class="demo-form-inline">
<el-form-item label="供应商">
<el-input v-model="supplierName" placeholder="请输入供应商名称" readonly></el-input>
</el-form-item>
<el-form-item label="付款金额 " prop="amount">
<el-input-number v-model="form.amount" :readonly="form.flowIdList.length > 1" :max="maxAmount" placeholder="请输入付款金额"
style="width: 100%;"></el-input-number>
</el-form-item>
<el-form-item label="付款方式" prop="type">
<el-input v-model="form.type" placeholder="请输入付款方式"></el-input>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注"></el-input>
</el-form-item>
<el-form-item style="display: flex; justify-content: flex-end">
<el-button @click="close"> </el-button>
<el-button type="primary" @click="submitForm('refform')"> </el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup>
import AuthAPI from "@/api/supplier/index";
import { ElMessage } from "element-plus";
const emits = defineEmits(["refresh"]);
const rules = {
amount: [{ required: true, message: "请输入付款金额", trigger: "blur" }],
type: [{ required: true, message: "请输入付款方式", trigger: "blur" }],
};
const basicForm = {
flowIdList: [],
amount: undefined,
type: '',
remark: '',
};
const form = reactive({
...basicForm,
});
const supplierName = ref('');
const maxAmount = ref(0);
const show = ref(false);
function open(item) {
form.flowIdList = item.flowIdList
supplierName.value = item.supplierName
form.amount = item.allAmount
maxAmount.value = item.allAmount
// Object.assign(form, item);
show.value = true;
}
function close() {
show.value = false;
}
const refform = ref();
async function submitForm() {
refform.value.validate(async (valid) => {
if (valid) {
const res = await AuthAPI.billPay(form);
ElMessage({ type: "success", message: "付款成功" });
emits("refresh");
close();
}
});
}
function reset() {
console.log("reset");
Object.assign(form, basicForm);
close();
}
defineExpose({
open,
close,
});
</script>

View File

@ -0,0 +1,148 @@
<template>
<div class="app-container">
<div class="head-container">
<el-card shadow="never">
<el-alert title="当前列表仅作为数据记录,不产生任何实际交易。" type="warning" show-icon :closable="false"
style="margin-bottom: 15px;" />
<el-row :gutter="20">
<el-col :span="4">
<el-input v-model="state.query.name" clearable placeholder="请输入供应商名称" style="width: 100%"
class="filter-item" @keyup.enter="getTableData" />
</el-col>
<el-col :span="16">
<el-button type="primary" @click="getTableData">查询</el-button>
</el-col>
</el-row>
</el-card>
</div>
<div class="head-container">
<el-card shadow="never">
<el-row :gutter="24">
<el-col :span="8" style="display: flex;flex-direction: column; justify-content: center;align-items: center;">
<div>账单总金额全部/本月</div>
<div>{{ state.summaryData.amountPayable || 0 }} / {{ state.summaryData.mouthAmountPayable || 0 }}</div>
</el-col>
<el-col :span="8" style="display: flex;flex-direction: column; justify-content: center;align-items: center;">
<div>已付款总金额全部/本月</div>
<div>{{ state.summaryData.actualPaymentAmount || 0 }} / {{ state.summaryData.mouthActualPaymentAmount || 0 }}</div>
</el-col>
<el-col :span="8" style="display: flex;flex-direction: column; justify-content: center;align-items: center;">
<div>未付款总金额全部/本月</div>
<div>{{ state.summaryData.unPaidAmount || 0 }} / {{ state.summaryData.mouthUnPaidAmount || 0 }}</div>
</el-col>
</el-row>
</el-card>
</div>
<div class="head-container">
<el-card shadow="never">
<el-table v-loading="state.tableData.loading" :data="state.tableData.list">
<el-table-column prop="name" label="供应商" width="220" />
<el-table-column prop="amountPayable" label="账单金额" width="200" />
<el-table-column prop="actualPaymentAmount" label="已付款金额" width="200" />
<el-table-column prop="unPaidAmount" label="未付款金额" width="200" />
<el-table-column prop="remark" label="备注" />
<el-table-column label="操作" width="120">
<template v-slot="scope">
<el-button type="primary" size="small" link @click="handleTo(scope.row)">
账单记录
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<div class="head-container">
<el-pagination v-model:current-page="state.tableData.page" v-model:page-size="state.tableData.size"
:total="state.tableData.total" :page-sizes="[10, 20, 30, 50, 100]"
layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
</div>
</div>
</template>
<script setup>
import AuthAPI from "@/api/supplier/index";
const router = useRouter();
const state = reactive({
query: {
name: "",
},
summaryData: {},
tableData: {
list: [],
page: 1,
size: 10,
loading: false,
total: 0,
},
});
onMounted(() => {
getSummary();
getTableData();
});
async function getSummary() {
try {
const res = await AuthAPI.getSummary();
state.summaryData = res;
} catch (error) {
console.log(error);
}
}
//
async function getTableData() {
state.tableData.loading = true;
try {
const res = await AuthAPI.getPage({
page: state.tableData.page,
size: state.tableData.size,
key: state.query.name,
});
state.tableData.loading = false;
state.tableData.list = res.records;
state.tableData.total = res.totalRow * 1;
} catch (error) {
console.log(error);
}
}
function handleTo(row) {
// router.push({ path: "/finance/supplierBill/billingRecord", query: { id: e.id } });
router.push({ name: "financeBillingRecord", query: { vendorId: row.vendorId, supplierName: row.name } });
}
//
function resetHandle() {
state.query.name = "";
getTableData();
}
//
function paginationChange(e) {
state.tableData.page = e;
getTableData();
}
</script>
<style scoped lang="scss">
.head-container {
margin-bottom: 20px;
}
.shop_info {
display: flex;
.info {
flex: 1;
padding-left: 4px;
}
}
.el-link {
min-height: 23px;
margin: 0 5px;
}
</style>

View File

@ -0,0 +1,137 @@
<template>
<div class="app-container">
<div class="head-container">
<el-card shadow="never">
<el-alert title="当前列表仅作为数据记录,不产生任何实际交易。" type="warning" show-icon :closable="false"
style="margin-bottom: 15px;" />
<el-text tag="b" size="large" style="margin-left: 15px;">供应商{{ state.supplierName }}</el-text>
</el-card>
</div>
<div class="head-container">
<el-card shadow="never">
<el-table v-loading="state.tableData.loading" :data="state.tableData.list">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column label="耗材信息">
<template v-slot="scope">
<div>{{ scope.row.conName }}</div>
<div>单价{{ scope.row.purchasePrice }}</div>
<div>入库数量{{ scope.row.inOutNumber }}</div>
</template>
</el-table-column>
<el-table-column prop="amount" label="付款金额" width="120" />
<el-table-column prop="type" label="付款方式" width="120" />
<el-table-column prop="remark" label="备注" />
<el-table-column prop="createTime" label="创建时间" />
<el-table-column label="操作人" width="200">
<template v-slot="scope">
<div>员工名称{{ scope.row.nickname }}</div>
<div>员工编号{{ scope.row.code }}</div>
<div>员工账号{{ scope.row.account }}</div>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<div class="head-container">
<el-pagination v-model:current-page="state.tableData.page" v-model:page-size="state.tableData.size"
:total="state.tableData.total" :page-sizes="[10, 20, 30, 50, 100]"
layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
</div>
</div>
</template>
<script setup>
import ShopApi from "@/api/account/shop";
import AuthAPI from "@/api/supplier/index";
import { ElMessageBox } from "element-plus";
const route = useRoute();
const state = reactive({
query: {
name: "",
flowId: null,
},
tableData: {
list: [],
page: 1,
size: 10,
loading: false,
total: 0,
},
supplierName: '',
});
onMounted(() => {
console.log(route.query);
if (route.query.id) {
state.query.flowId = route.query.id
}
if (route.query.supplierName) {
state.supplierName = route.query.supplierName
}
getTableData();
});
//
async function getTableData() {
state.tableData.loading = true;
try {
const res = await AuthAPI.getPayRecordList({
page: state.tableData.page,
size: state.tableData.size,
flowId: state.query.flowId,
});
state.tableData.loading = false;
state.tableData.list = res.records;
state.tableData.total = res.totalRow * 1;
} catch (error) {
console.log(error);
}
}
function handleSync(e) {
console.log(e)
ElMessageBox.confirm(`同步功能开启后不能关闭,请确认是否给${e.shopName}开启同步?`, "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
const res = await ShopApi.delete({ id: row.id });
ElMessage({
type: "success",
message: "同步成功",
});
getTableData();
}).catch(() => { });
}
//
function resetHandle() {
state.query.name = "";
getTableData();
}
//
function paginationChange(e) {
state.tableData.page = e;
getTableData();
}
</script>
<style scoped lang="scss">
.head-container {
margin-bottom: 20px;
}
.shop_info {
display: flex;
.info {
flex: 1;
padding-left: 4px;
}
}
.el-link {
min-height: 23px;
margin: 0 5px;
}
</style>

View File

@ -20,7 +20,15 @@ const contentConfig: IContentConfig = {
return Api.edit(data); return Api.edit(data);
}, },
pk: "id", pk: "id",
toolbar: ["add"], toolbar: [
{
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
],
defaultToolbar: ["refresh", "filter", "search"], defaultToolbar: ["refresh", "filter", "search"],
cols: [ cols: [
// { type: "selection", width: 50, align: "center" }, // { type: "selection", width: 50, align: "center" },
@ -49,7 +57,7 @@ const contentConfig: IContentConfig = {
fixed: "right", fixed: "right",
width: 280, width: 280,
templet: "tool", templet: "tool",
operat: ["edit"], operat: [{ text: "编辑", icon: 'edit', name: "edit"}],
}, },
], ],
}; };

View File

@ -71,6 +71,7 @@ import contentConfig from "./config/content";
import editModalConfig from "./config/edit"; import editModalConfig from "./config/edit";
import searchConfig from "./config/search"; import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config"; import { returnOptionsLabel } from "./config/config";
import { isSyncStatus } from "@/utils/index";
const { const {
searchRef, searchRef,
@ -87,6 +88,14 @@ const {
handleFilterChange, handleFilterChange,
} = usePage(); } = usePage();
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true
} else {
contentConfig.toolbar[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false
}
// //
async function handleAddClick() { async function handleAddClick() {
addModalRef.value?.setModalVisible(); addModalRef.value?.setModalVisible();

View File

@ -77,8 +77,40 @@
</div> </div>
</div> </div>
</div> </div>
<!--<div style="
<stockHistory ref="refStockHistory"></stockHistory> width: 200px;
flex-direction: column;
justify-content: center;
align-items: center;
background: #fff;
">
<div style="font-weight: bold">入库</div>
<div style="margin-top: 10px">{{ data.stockInNum || 0 }}</div>
<div style="margin-top: 10px">{{ data.totalRow || 0 }}</div>
</div>
<div style="
width: 200px;
flex-direction: column;
justify-content: center;
align-items: center;
background: #fff;
">
<div style="font-weight: bold">出库</div>
<div style="margin-top: 10px">{{ data.stockOutNum || 0 }}</div>
<div style="margin-top: 10px">{{ data.totalRow || 0 }}</div>
</div>
<div style="
width: 200px;
flex-direction: column;
justify-content: center;
align-items: center;
background: #fff;
">
<div style="font-weight: bold">报损</div>
<div style="margin-top: 10px">{{ data.damageNum || 0 }}</div>
<div style="margin-top: 10px">{{ data.totalRow || 0 }}</div>
</div> -->
<stockHistory ref="refStockHistory" />
</div> </div>
</template> </template>
<script setup> <script setup>
@ -97,7 +129,6 @@ function refStockHistoryShow(key) {
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.DataStatistics { .DataStatistics {
border: 1px solid #e4e7ed; border: 1px solid #e4e7ed;
@ -110,7 +141,7 @@ function refStockHistoryShow(key) {
align-items: center; align-items: center;
justify-content: space-around; justify-content: space-around;
> div { >div {
height: 80px; height: 80px;
background-color: #f4f9ff; background-color: #f4f9ff;
display: flex; display: flex;
@ -130,6 +161,7 @@ function refStockHistoryShow(key) {
span { span {
color: #666; color: #666;
font-size: 14px; font-size: 14px;
&.num { &.num {
color: #3f9eff; color: #3f9eff;
cursor: pointer; cursor: pointer;

View File

@ -1,197 +0,0 @@
<template>
<!-- 修改和增加 -->
<el-dialog :title="dialogtitle" v-model="show" width="85%">
<div v-if="dialogtitle != '编辑'">
<div v-for="(item, index) in forms" :key="index">
<el-form
:inline="true"
:ref="(el) => setFormRef(el, index)"
:model="item"
:rules="rules"
class="demo-form-inline"
>
<el-form-item label=" ">
<el-icon color="red" @click="formsReduce(index)"><Remove /></el-icon>
</el-form-item>
<el-form-item label="耗材名称" prop="conName">
<el-input v-model="item.conName" placeholder="请输入耗材信息名称"></el-input>
</el-form-item>
<el-form-item label="耗材类型" prop="conTypeId">
<el-select v-model="item.conTypeId" placeholder="请选择耗材类型" style="width: 200px">
<el-option
v-for="option in consGroups"
:key="option.conTypeId"
:label="option.conTypeName"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="item.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="耗材价格">
<el-input v-model="item.price" placeholder="请输入耗材价格"></el-input>
</el-form-item>
<el-form-item label="预警值">
<el-input v-model="item.conWarning" placeholder="请输入耗材预警值"></el-input>
</el-form-item>
<el-form-item label=" ">
<el-icon color="green" @click="formsAdd(index)"><CirclePlus /></el-icon>
</el-form-item>
</el-form>
</div>
<div style="display: flex; justify-content: flex-end">
<el-button @click="dialogshow = false"> </el-button>
<el-button type="primary" @click="submitForms()"> </el-button>
</div>
</div>
<el-form
v-else
:inline="true"
ref="refform"
:model="form"
:rules="rules"
class="demo-form-inline"
>
{{ dialogtitle }}
<el-form-item label="耗材信息名称" prop="conName">
<el-input v-model="form.conName" placeholder="请输入耗材信息名称"></el-input>
</el-form-item>
<el-form-item label="耗材价格">
<el-input v-model="form.price" placeholder="请输入耗材价格"></el-input>
</el-form-item>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="form.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="预警值">
<el-input v-model="form.conWarning" placeholder="请输入耗材预警值"></el-input>
</el-form-item>
<!-- <el-form-item label="状态" v-if="dialogtitle == '编辑'">
<el-switch v-model="form.status" active-value="1" inactive-value="0"></el-switch>
</el-form-item> -->
<!-- <el-form-item label="单位耗材值" prop="surplusStock">
<el-input v-model="form.surplusStock" placeholder="请输入单位耗材值"></el-input>
</el-form-item> -->
<el-form-item style="display: flex; justify-content: flex-end">
<el-button @click="dialogshow = false"> </el-button>
<el-button type="primary" @click="submitForm('refform')"> </el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup>
import consApi from "@/api/product/cons";
import consGroupApi from "@/api/product/cons-group";
import { ElMessage } from "element-plus";
const consGroups = ref([]);
const rules = {
conCode: [{ required: true, message: "请输入耗材信息代码", trigger: "blur" }],
conName: [{ required: true, message: "请输入耗材信息名称", trigger: "blur" }],
conTypeId: [{ required: true, message: "请选择耗材类型", trigger: "change" }],
price: [{ required: true, message: "请输入耗材价格", trigger: "blur" }],
conWarning: [{ required: true, message: "请输入耗材预警值", trigger: "blur" }],
conTypeId: [{ required: true, message: "请输入耗材类型id", trigger: "blur" }],
conUnit: [{ required: true, message: "请输入单位", trigger: "blur" }],
conWarning: [
{
required: true,
message: "请输入单位",
trigger: "blur",
},
],
};
function getConsGroups() {
consGroupApi.getAllList().then((res) => {
consGroups.value = res.map((v) => {
return {
...v,
label: v.name,
value: v.id,
};
});
});
}
getConsGroups();
const basicForm = {
conCode: "",
conName: "",
conTypeId: "",
price: "0",
conNames: "",
conUnit: "",
conWarning: "999",
shopId: localStorage.getItem("shopId"),
status: "",
};
const forms = ref([{ ...basicForm }]);
const form = reactive({
...basicForm,
});
const show = ref(false);
let dialogtitle = ref("");
function open(item) {
dialogtitle.value = item ? "编辑" : "新增";
show.value = true;
}
function formsAdd(index) {
forms.value.push({ ...basicForm });
}
function close() {
show.value = false;
}
const refForms = ref([]);
function setFormRef(el, index) {
if (el) {
refForms.value[index] = el;
}
}
function returnPromise(index, prosise) {
return new Promise((resolve, reject) => {
prosise
.then((res) => {
console.log(res);
resolve({ sucees: true });
})
.catch((err) => {
console.log(err);
resolve({ sucees: false });
});
});
}
async function submitForms() {
let isAllPassForm = 0;
for (let i in this.forms) {
console.log(refForms.value[i]);
const res = await returnPromise(i, refForms.value[i].validate());
console.log(res);
isAllPassForm += res.sucees ? 1 : 0;
}
//
if (isAllPassForm === this.forms.length) {
await consApi.add(this.forms);
ElMessage({ type: "success", message: "添加成功" });
// for(let i of this.forms){
// const res=await posttbConsInfo(i)
// this.$message({ type: "success", message: "" });
// }
this.dialogshow = false;
this.resetRuleForms();
this.ruleFormLoading = false;
this.getTableData();
}
}
defineExpose({
open,
close,
});
</script>

View File

@ -13,11 +13,11 @@ const contentConfig: IContentConfig = {
pageSizes: [10, 20, 30, 50], pageSizes: [10, 20, 30, 50],
}, },
indexAction: function (params) { indexAction: function (params) {
let obj = { ...params } let obj = { ...params };
if (obj.createAt) { if (obj.createAt) {
obj.beginTime = obj.createAt[0] obj.beginTime = obj.createAt[0];
obj.endTime = obj.createAt[1] obj.endTime = obj.createAt[1];
delete obj.createAt delete obj.createAt;
} }
return Api.getList(obj); return Api.getList(obj);
}, },
@ -25,28 +25,62 @@ const contentConfig: IContentConfig = {
// modifyAction: function (data) { // modifyAction: function (data) {
// // return Api.edit(data); // // return Api.edit(data);
// }, // },
indexActionData: {},
pk: "id", pk: "id",
toolbar: [ toolbar: [
"add", {
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
{
icon: "refresh",
text: "同步",
type: "danger",
name: "sync",
auth: "import",
},
{ {
text: "入库", text: "入库",
name: 'ruku', name: "ruku",
auth: 'ruku' auth: "ruku",
}, },
{ {
text: "出库", text: "出库",
name: 'chuku', name: "chuku",
auth: '' auth: "",
}, },
{ {
text: "分类管理", text: "分类管理",
name: 'category', name: "category",
auth: '' auth: "",
}, },
{ {
text: "供应商管理", text: "供应商管理",
name: 'gongyinsahng', name: "gongyinsahng",
auth: '' auth: "",
},
{
text: "入库记录",
name: "manual-in",
auth: "",
},
{
text: "出库记录",
name: "manual-out",
auth: "",
},
{
text: "报损记录",
name: "damage-out",
auth: "",
},
{
text: "报损",
name: "reportinglosses",
auth: "",
}, },
], ],
defaultToolbar: ["refresh", "filter", "search"], defaultToolbar: ["refresh", "filter", "search"],
@ -68,8 +102,8 @@ const contentConfig: IContentConfig = {
{ {
label: "所属商品", label: "所属商品",
align: "center", align: "center",
templet: 'custom', templet: "custom",
slotName: 'goods' slotName: "goods",
}, },
{ {
label: "库存数量", label: "库存数量",
@ -94,7 +128,7 @@ const contentConfig: IContentConfig = {
fixed: "right", fixed: "right",
width: 150, width: 150,
templet: "custom", templet: "custom",
slotName: 'operate' slotName: "operate",
}, },
], ],
}; };

View File

@ -1,5 +1,5 @@
import type { ISearchConfig } from "@/components/CURD/types"; import type { ISearchConfig } from "@/components/CURD/types";
import consGroupApi from '@/api/product/cons-group' import consGroupApi from "@/api/product/cons-group";
import { statusOptions, payTypeOptions } from "./config"; import { statusOptions, payTypeOptions } from "./config";
const searchConfig: ISearchConfig = { const searchConfig: ISearchConfig = {
pageName: "sys:user", pageName: "sys:user",
@ -20,14 +20,14 @@ const searchConfig: ISearchConfig = {
initialValue: "", initialValue: "",
initFn(formItem) { initFn(formItem) {
console.log(formItem); console.log(formItem);
consGroupApi.getAllList({}).then(res => { consGroupApi.getAllList({}).then((res) => {
formItem.options = res.map((item: { name: any; id: any; }) => { formItem.options = res.map((item: { name: any; id: any }) => {
return { return {
label: item?.name, label: item?.name,
value: item?.id value: item?.id,
} };
}) });
}) });
}, },
}, },
@ -42,22 +42,23 @@ const searchConfig: ISearchConfig = {
width: "200px", width: "200px",
}, },
}, },
initialValue: "",
}, },
{ // {
type: "date-picker", // type: "date-picker",
label: "创建时间", // label: "创建时间",
prop: "createAt", // prop: "createAt",
attrs: { // attrs: {
type: "daterange", // type: "daterange",
"range-separator": "~", // "range-separator": "~",
"start-placeholder": "开始时间", // "start-placeholder": "开始时间",
"end-placeholder": "截止时间", // "end-placeholder": "截止时间",
"value-format": "YYYY-MM-DD", // "value-format": "YYYY-MM-DD",
style: { // style: {
width: "240px", // width: "240px",
}, // },
}, // },
}, // },
], ],
}; };

View File

@ -2,26 +2,14 @@
<div class="app-container"> <div class="app-container">
<!-- 列表 --> <!-- 列表 -->
<!-- 搜索 --> <!-- 搜索 -->
<page-search <page-search ref="searchRef" :search-config="searchConfig" @query-click="newHandleQueryClick"
ref="searchRef" @reset-click="handleResetClick" />
:search-config="searchConfig"
@query-click="newHandleQueryClick"
@reset-click="handleResetClick"
/>
<!-- 统计 --> <!-- 统计 -->
<data-tongji :data="gongjiData"></data-tongji> <data-tongji :data="gongjiData" />
<!-- 列表 --> <!-- 列表 -->
<page-content <page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
ref="contentRef" @edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
:content-config="contentConfig" @toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope"> <template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'"> <el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }} {{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
@ -33,28 +21,22 @@
<template #goods="scope"> <template #goods="scope">
<div class="goodslang"> <div class="goodslang">
<div class="goods-list"> <div class="goods-list">
<el-button <el-button v-for="item in scope.row.productList" :key="item.productId" type="text"
v-for="item in scope.row.productList" @click="toGoods(item.id)">
@click="toGoods(item.id)"
:key="item.productId"
type="text"
>
{{ item.name }} {{ item.name }}
</el-button> </el-button>
<span v-if="scope.row.productList.length > 1">,</span> <span v-if="scope.row.productList.length > 1">,</span>
</div> </div>
<el-dropdown trigger="click" v-if="scope.row.productList.length > 1" @command="toGoods"> <el-dropdown v-if="scope.row.productList.length > 1" trigger="click" @command="toGoods">
<span class="el-dropdown-link" style="color: blue"> <span class="el-dropdown-link" style="color: blue">
<el-icon><CaretBottom /></el-icon> <el-icon>
<CaretBottom />
</el-icon>
</span> </span>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item <el-dropdown-item v-for="item in scope.row.productList" :key="item.id" class="clearfix"
class="clearfix" :command="item.id">
v-for="item in scope.row.productList"
:key="item.id"
:command="item.id"
>
{{ item.name }} {{ item.name }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@ -73,25 +55,34 @@
</template> </template>
<template #mobile="scope"> <template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text> <el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button <copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template> </template>
<template #operate="scope"> <template #operate="scope">
<div> <div style="
<el-button @click="refAddHaocaiOpen(scope.row)" type="primary" link>编辑</el-button> display: flex;
<el-button @click="refAddHaocaiTakinShow(scope.row)" link type="primary"> flex-direction: column;
justify-content: center;
align-items: center;
">
<el-button v-if="!isSyncStatus()" type="primary" link @click="refAddHaocaiOpen(scope.row)">
编辑
</el-button>
<el-button link type="primary" @click="refAddHaocaiTakinShow(scope.row, 'consumables')">
耗材盘点 耗材盘点
</el-button> </el-button>
<el-button link type="primary" @click="refAddHaocaiTakinShow(scope.row, 'manual-in')">
入库记录
</el-button>
<!-- <el-button link type="primary" @click="refAddHaocaiTakinShow(scope.row, 'delete')">
删除
</el-button> -->
</div> </div>
</template> </template>
</page-content> </page-content>
<!-- 耗材添加编辑 --> <!-- 耗材添加编辑 -->
<add-haocai ref="refAddHaocai" @refresh="refresh"></add-haocai> <add-haocai ref="refAddHaocai" @refresh="refresh" />
<!-- 耗材盘点 --> <!-- 耗材盘点 -->
<addConsTakin ref="refAddHaocaiTakin" @success="refresh"></addConsTakin> <addConsTakin ref="refAddHaocaiTakin" @success="refresh" />
</div> </div>
</template> </template>
@ -100,12 +91,16 @@ import addHaocai from "./components/add-haocai.vue";
import dataTongji from "./components/DataStatistics.vue"; import dataTongji from "./components/DataStatistics.vue";
import addConsTakin from "./components/addConsTakin.vue"; import addConsTakin from "./components/addConsTakin.vue";
import consApi from "@/api/product/cons"; import consApi from "@/api/product/cons";
import UserAPI from "@/api/product/index";
import type { IObject, IOperatData } from "@/components/CURD/types"; import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage"; import usePage from "@/components/CURD/usePage";
import contentConfig from "./config/content"; import contentConfig from "./config/content";
import editModalConfig from "./config/edit"; import editModalConfig from "./config/edit";
import searchConfig from "./config/search"; import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config"; import { returnOptionsLabel } from "./config/config";
import { isSyncStatus } from "@/utils/index";
const router = useRouter(); const router = useRouter();
const { const {
searchRef, searchRef,
@ -123,6 +118,24 @@ function toGoods(id: number | string) {
router.push({ path: "/product/index", query: { id: id } }); router.push({ path: "/product/index", query: { id: id } });
} }
//
const route = useRoute();
const { conName } = route.query;
if (conName) {
contentConfig.indexActionData = { conName };
if (conName) {
searchConfig.formItems[1].initialValue = conName;
}
}
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true;
contentConfig.toolbar[1].hidden = false;
} else {
contentConfig.toolbar[0].hidden = false;
contentConfig.toolbar[1].hidden = true;
}
// //
const gongjiData = reactive({ totalRow: 0 }); const gongjiData = reactive({ totalRow: 0 });
function getTongji(params: IObject | undefined) { function getTongji(params: IObject | undefined) {
@ -152,7 +165,20 @@ watch(
// //
const refAddHaocaiTakin = ref(); const refAddHaocaiTakin = ref();
function refAddHaocaiTakinShow(item: any) { function refAddHaocaiTakinShow(item: any, type: string) {
console.log(item);
if (type === "manual-in") {
router.push({ path: "/inventory/libraryrecords", query: { inOutItem: type, conId: item.id } });
return;
}
if (type === "delete") {
refAddHaocaiTakin.value.show(item, type);
return;
}
if (type === "consumables") {
refAddHaocaiTakin.value.show(item, type);
return;
}
refAddHaocaiTakin.value.show(item); refAddHaocaiTakin.value.show(item);
} }
@ -177,8 +203,13 @@ async function handleEditClick(row: IObject) {
editModalRef.value?.setFormData({ ...row, url: [row.url] }); editModalRef.value?.setFormData({ ...row, url: [row.url] });
} }
// //
function handleToolbarClick(name: string) { async function handleToolbarClick(name: string) {
console.log(name); console.log(name);
if (name === "sync") {
let res = await UserAPI.sync();
ElMessage.success("操作成功,数据正在后台同步中...");
return;
}
if (name === "category") { if (name === "category") {
router.push({ path: "/inventory/classification" }); router.push({ path: "/inventory/classification" });
return; return;
@ -195,6 +226,14 @@ function handleToolbarClick(name: string) {
router.push({ path: "/inventory/operation_in", query: { type: "out" } }); router.push({ path: "/inventory/operation_in", query: { type: "out" } });
return; return;
} }
if (name == "reportinglosses") {
router.push({ path: "/inventory/operation_in", query: { type: "reportinglosses" } });
return;
}
if (name == "damage-out" || name == "manual-out" || name == "manual-in") {
router.push({ path: "/inventory/libraryrecords", query: { inOutItem: name } });
return;
}
} }
// //
async function handleOperatClick(data: IOperatData) { async function handleOperatClick(data: IOperatData) {

View File

@ -0,0 +1,77 @@
import Api from "@/api/product/vendor";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "添加供应商",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.add({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "名称",
prop: "name",
rules: [{ required: true, message: "请输入名称", trigger: "blur" }],
attrs: {
placeholder: "请输入名称",
},
},
{
label: "联系人名字",
prop: "contactName",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "联系人电话",
prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "供应商地址",
prop: "address",
rules: [{ required: false, message: "请输入供应商地址", trigger: "blur" }],
attrs: {
placeholder: "请输入供应商地址",
},
},
{
label: "备注",
prop: "remark",
rules: [{ required: false, message: "请输入备注", trigger: "blur" }],
attrs: {
placeholder: "请输入备注",
},
},
{
label: "排序",
prop: "sort",
rules: [{ required: true, message: "请输入排序", trigger: "blur" }],
type: "input-number",
attrs: {
placeholder: "请输入排序",
},
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@ -0,0 +1,46 @@
export interface options {
label: string;
value: string | number;
[property: string]: any;
}
export interface optionObject {
[property: string]: options[];
}
const options: optionObject = {
payType: [
{ label: "现金", value: "cash" },
{ label: "微信", value: "weixin" },
{ label: "银行卡", value: "bank" },
{ label: "会员支付", value: "member-account" },
{ label: "支付宝", value: "alipay" },
{ label: "刷卡", value: "deposit" },
{ label: "挂账", value: "arrears" },
{ label: "刷卡", value: "deposit" },
{ label: "储值", value: "member-account" },
{ label: "自定义", value: "virtual" },
],
isIdeal: [
{ label: "否", value: 0 },
{ label: "是", value: 1 },
],
};
export const switchAttr = {
"active-value": 1,
"inactive-value": 0,
};
export type optionsType = string;
export function returnOptions(type: optionsType) {
return options[type];
}
export function returnOptionsLabel(optionsType: optionsType, value: string | number) {
const options = returnOptions(optionsType);
if (!options) {
return "";
}
const option = options.find((item) => item.value === value);
return option ? option.label : "";
}

View File

@ -0,0 +1,94 @@
import Api from "@/api/product/libraryrecords";
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig = {
pageName: "sys:user",
table: {
border: true,
highlightCurrentRow: true,
},
pagination: {
background: true,
layout: "prev,pager,next,jumper,total,sizes",
pageSize: 20,
pageSizes: [10, 20, 30, 50],
},
indexAction: function (params) {
return Api.getList(params);
},
deleteAction: function (id) {
return Api.delete(id);
},
modifyAction: function (data) {
return Api.edit(data);
},
indexActionData: {},
pk: "id",
toolbar: [
// {
// text: "入库记录",
// name: "manual-in",
// auth: "",
// },
// {
// text: "出库记录",
// name: "manual-out",
// auth: "",
// },
// {
// text: "报损记录",
// name: "damage-out",
// auth: "",
// },
],
defaultToolbar: ["refresh", "filter", "search"],
cols: [
// { type: "selection", width: 50, align: "center" },
{
label: "耗材名称",
align: "center",
prop: "conName",
},
{
label: "单位",
align: "center",
prop: "unitName",
},
{
label: "供应商",
align: "center",
prop: "vendorName",
},
{
label: "变动原因",
align: "center",
templet: "custom",
slotName: "conUnit",
},
{
label: "出入库数量",
align: "center",
prop: "inOutNumber",
},
{
label: "变动后的库存",
align: "center",
prop: "afterNumber",
},
{
label: "创建时间",
align: "center",
prop: "createTime",
},
// {
// label: "操作",
// align: "center",
// fixed: "right",
// width: 280,
// templet: "tool",
// operat: ["edit", "delete"],
// },
],
};
export default contentConfig;

View File

@ -0,0 +1,75 @@
import Api from "@/api/product/vendor";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "编辑供应商",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.edit({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "名称",
prop: "name",
rules: [{ required: true, message: "请输入名称", trigger: "blur" }],
attrs: {
placeholder: "请输入名称",
},
},
{
label: "联系人名字",
prop: "contactName",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "联系人电话",
prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "供应商地址",
prop: "address",
rules: [{ required: false, message: "请输入供应商地址", trigger: "blur" }],
attrs: {
placeholder: "请输入供应商地址",
},
},
{
label: "备注",
prop: "remark",
rules: [{ required: false, message: "请输入备注", trigger: "blur" }],
attrs: {
placeholder: "请输入备注",
},
},
{
label: "排序",
prop: "sort",
rules: [{ required: true, message: "请输入排序", trigger: "blur" }],
type: "input-number",
attrs: {
placeholder: "请输入排序",
},
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@ -0,0 +1,58 @@
import type { ISearchConfig } from "@/components/CURD/types";
const searchConfig: ISearchConfig = {
pageName: "sys:user",
isExpandable: false,
formItems: [
{
type: "select",
label: "类型",
prop: "inOutType",
attrs: {
placeholder: "请选择",
clearable: true,
style: {
width: "200px",
},
},
options: [
{
label: "增加",
value: "in",
},
{
label: "减少",
value: "out",
},
],
},
{
type: "select",
label: "名目",
prop: "inOutItem",
attrs: {
placeholder: "请选择",
clearable: true,
style: {
width: "200px",
},
},
options: [
{
label: "入库记录",
value: "manual-in",
},
{
label: "出库记录",
value: "manual-out",
},
{
label: "报损记录",
value: "damage-out",
},
],
initialValue: "",
},
],
};
export default searchConfig;

View File

@ -0,0 +1,106 @@
<template>
<div class="app-container">
<!-- 搜索 -->
<page-search
ref="searchRef"
:search-config="searchConfig"
@query-click="handleQueryClick"
@reset-click="handleResetClick"
/>
<!-- 列表 -->
<page-content
ref="contentRef"
:content-config="contentConfig"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #conUnit="scope">
<span v-if="scope.row.inOutItem == 'manual-in'">手动入库</span>
<span v-if="scope.row.inOutItem == 'manual-out'">手动出库</span>
<span v-if="scope.row.inOutItem == 'win-in'">盘盈入库</span>
<span v-if="scope.row.inOutItem == 'loss-out'">盘亏出库</span>
<span v-if="scope.row.inOutItem == 'order-in'">订单退款入库</span>
<span v-if="scope.row.inOutItem == 'order-out'">订单消费出库</span>
</template>
</page-content>
<!-- 新增 -->
<page-modal
ref="addModalRef"
:modal-config="addModalConfig"
@submit-click="handleSubmitClick"
/>
<!-- 编辑 -->
<page-modal
ref="editModalRef"
:modal-config="editModalConfig"
@submit-click="handleSubmitClick"
/>
</div>
</template>
<script setup lang="ts">
import VersionApi from "@/api/system/version";
import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import addModalConfig from "./config/add";
import contentConfig from "./config/content";
import editModalConfig from "./config/edit";
import searchConfig from "./config/search";
const {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
// handleAddClick,
// handleEditClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
handleFilterChange,
} = usePage();
//
const route = useRoute();
const { inOutItem, conId } = route.query;
if (inOutItem || conId) {
contentConfig.indexActionData = { inOutItem, conId };
if (inOutItem) {
searchConfig.formItems[1].initialValue = inOutItem;
}
}
//
async function handleAddClick() {
addModalRef.value?.setModalVisible();
// addModalConfig.formItems[2]!.attrs!.data =
}
//
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
editModalRef.value?.setModalVisible();
// id
console.log(row);
editModalRef.value?.setFormData({ ...row });
}
//
function handleToolbarClick(name: string) {
console.log(name);
if (name === "custom1") {
ElMessage.success("点击了自定义1按钮");
}
}
//
async function handleOperatClick(data: IOperatData) {
console.log(data);
}
</script>

View File

@ -1,16 +1,12 @@
<!-- 耗材列表 --> <!-- 耗材列表 -->
<template> <template>
<el-dialog title="选择耗材" v-model="dialogVisible"> <el-dialog v-model="dialogVisible" title="选择耗材">
<el-form :model="searchForm" inline> <el-form :model="searchForm" inline>
<el-form-item> <el-form-item>
<el-input <el-input v-model="searchForm.conTypeName" placeholder="耗材类型名称" @input="onInput" />
v-model="searchForm.conTypeName"
placeholder="耗材类型名称"
@input="onInput"
></el-input>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-input v-model="searchForm.conName" placeholder="耗材名称" @input="onInput"></el-input> <el-input v-model="searchForm.conName" placeholder="耗材名称" @input="onInput" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getTableData">查询</el-button> <el-button type="primary" @click="getTableData">查询</el-button>
@ -18,21 +14,13 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="head-container"> <div class="head-container">
<el-table <el-table ref="table" v-loading="tableData.loading" :data="tableData.list" :row-key="getRowKey"
ref="table" @select="firstSelectChange" @selection-change="onSelectionChange">
:data="tableData.list" <el-table-column type="selection" width="55" align="center" />
v-loading="tableData.loading" <el-table-column label="耗材名称" prop="conName" />
@select="firstSelectChange" <el-table-column label="所属分类" prop="consGroupName" />
:row-key="getRowKey" <el-table-column label="价格" prop="price" />
@selection-change="onSelectionChange" <el-table-column label="单位" prop="conUnit" />
>
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column label="耗材名称" prop="conName"></el-table-column>
<el-table-column label="价格" prop="price"></el-table-column>
<el-table-column label="耗材代码" prop="conCode"></el-table-column>
<el-table-column label="耗材类型名称" prop="conTypeName"></el-table-column>
<el-table-column label="单位" prop="conUnit"></el-table-column>
<el-table-column label="最近入库量" prop="lasterInStock"></el-table-column>
<el-table-column label="库存数量" prop="stockNumber"> <el-table-column label="库存数量" prop="stockNumber">
<template v-slot="scope"> <template v-slot="scope">
{{ formatDecimal(scope.row.stockNumber, 2, true) }} {{ formatDecimal(scope.row.stockNumber, 2, true) }}
@ -45,14 +33,8 @@
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
</div> </div>
<el-pagination <el-pagination :total="tableData.total" :current-page="tableData.page + 1" :page-size="tableData.size"
:total="tableData.total" layout="total, sizes, prev, pager, next, jumper" @current-change="paginationChange" @size-change="sizeChange" />
:current-page="tableData.page + 1"
:page-size="tableData.size"
@current-change="paginationChange"
@size-change="sizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false"> </el-button>

View File

@ -1,128 +1,81 @@
<template> <template>
<div class="app-container bg-fff u-m-20"> <div class="app-container bg-fff u-m-20">
<div class="head-container"> <div class="head-container">
<el-form <el-form ref="queryForm" :model="queryForm" :rules="queryRules" label-position="left" label-width="100px">
ref="queryForm"
:model="queryForm"
:rules="queryRules"
label-position="left"
label-width="100px"
>
<el-row> <el-row>
<el-form-item label="类型"> <el-form-item label="类型">
<el-radio-group :model-value="type"> <el-radio-group :model-value="type" @change="tabChange">
<el-radio-button value="in">入库</el-radio-button> <el-radio v-if="type == 'reportinglosses'" value="reportinglosses">报损</el-radio>
<el-radio-button value="out">出库</el-radio-button> <div v-else>
<el-radio value="in">入库</el-radio>
<el-radio value="out">出库</el-radio>
</div>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-row> </el-row>
<div v-if="type != 'reportinglosses'">
<el-row> <el-row>
<el-col :span="8"> <el-col v-if="type == 'in'" :span="8">
<el-form-item label="供应商"> <el-form-item label="供应商">
<el-select <el-select v-model="queryForm.vendorId" placeholder="请选择供应商" clearable style="width: 220px"
v-model="queryForm.vendorId" @change="changeTypeEnum">
placeholder="请选择供应商" <el-option v-for="item in purveyorList" :key="item.id" :label="item.name" :value="item.id" />
clearable
style="width: 220px"
@change="changeTypeEnum"
>
<el-option
:label="item.name"
:value="item.id"
v-for="item in purveyorList"
:key="item.id"
></el-option>
</el-select> </el-select>
{{ queryForm.waitAmount }} {{ queryForm.waitAmount }}
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="出入库时间" prop="inOutDate"> <el-form-item label="出入库时间" prop="inOutDate">
<el-date-picker <el-date-picker v-model="queryForm.inOutDate" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
v-model="queryForm.inOutDate" placeholder="选择日期" style="width: 220px" disabled="false" />
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 220px"
></el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="应付金额"> <el-form-item label="应付金额">
<el-input <el-input v-model="queryForm.amountPayable" placeholder="请输入应收金额" style="width: 220px" />
v-model="queryForm.amountPayable"
placeholder="请输入应收金额"
style="width: 220px"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="实付金额"> <el-form-item label="实付金额">
<el-input <el-input v-model="queryForm.actualPaymentAmount" placeholder="请输入实收金额" style="width: 220px" />
v-model="queryForm.actualPaymentAmount"
placeholder="请输入实收金额"
style="width: 220px"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="付款时间"> <el-form-item label="付款时间">
<el-date-picker <el-date-picker v-model="queryForm.paymentDate" type="date" format="YYYY-MM-DD"
v-model="queryForm.paymentDate" value-format="YYYY-MM-DD" placeholder="选择日期" style="width: 220px" />
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 220px"
></el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <!-- <el-col :span="8">
<el-form-item label="批号"> <el-form-item label="批号">
<el-input <el-input v-model="queryForm.batchNo" placeholder="请输入批号" style="width: 220px" />
v-model="queryForm.batchNo"
placeholder="请输入批号"
style="width: 220px"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
</el-row> </el-row>
<el-row> <!-- <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="备注"> <el-form-item label="备注">
<el-input <el-input v-model="queryForm.remark" placeholder="请输入备注" style="width: 220px" />
v-model="queryForm.remark"
placeholder="请输入备注"
style="width: 220px"
></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row> -->
</div>
<el-form-item label="选择耗材"> <el-form-item label="选择耗材">
<div></div> <div />
<el-button type="primary" @click="showHaocai">选择耗材</el-button> <el-button type="primary" @click="showHaocai">选择耗材</el-button>
<el-autocomplete <el-autocomplete v-model="autocompletename" :fetch-suggestions="querySearchAsync" value-key="conName"
v-model="autocompletename" placeholder="耗材搜索" style="width: 200px; margin-left: 20px" @select="handleSelect" />
:fetch-suggestions="querySearchAsync"
value-key="conName"
placeholder="耗材搜索"
@select="handleSelect"
style="width: 200px; margin-left: 20px"
></el-autocomplete>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="head-container"> <div style="font-weight: bold; font-size: 16px; color: #666">
<el-button type="primary" plain>
{{ tableData.list.length }}种耗材金额合计 {{ tableData.list.length }}种耗材金额合计
<span style="color: red">{{ amountPayable }}</span> <span style="color: red">{{ amountPayable }}</span>
</el-button>
</div> </div>
<div class="head-container"> <div class="head-container">
<el-table :data="tableData.list"> <el-table :data="tableData.list">
@ -131,13 +84,14 @@
{{ scope.row.conName }} {{ scope.row.conName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="进价"> <el-table-column label="所属分类">
<template v-slot="scope"> <template v-slot="scope">
<el-input-number {{ scope.row.consGroupName }}
v-model="scope.row.price" </template>
:min="0" </el-table-column>
controls-position="right" <el-table-column>
></el-input-number> <template v-slot="scope">
<el-input-number v-model="scope.row.price" :min="0" controls-position="right" />
<div class="tips" style="font-size: 16px"> <div class="tips" style="font-size: 16px">
原价 原价
@ -149,30 +103,17 @@
</el-table-column> </el-table-column>
<el-table-column label="单位"> <el-table-column label="单位">
<template v-slot="scope"> <template v-slot="scope">
<el-select <el-select v-model="scope.row.unit" :placeholder="scope.row.unit" @change="changeUnit(scope.row)">
v-model="scope.row.unit" <el-option :label="scope.row.conUnit" :value="scope.row.conUnit" />
:placeholder="scope.row.unit" <el-option v-if="scope.row.conUnitTwo" :label="scope.row.conUnitTwo" :value="scope.row.conUnitTwo" />
@change="changeUnit(scope.row)"
>
<el-option :label="scope.row.conUnit" :value="scope.row.conUnit"></el-option>
<el-option
:label="scope.row.conUnitTwo"
:value="scope.row.conUnitTwo"
v-if="scope.row.conUnitTwo"
></el-option>
</el-select> </el-select>
<div class="tips">&nbsp;</div> <div class="tips">&nbsp;</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="数量"> <el-table-column label="数量">
<template v-slot="scope"> <template v-slot="scope">
<el-input-number <el-input-number v-model="scope.row.stockNumber" :min="0" :step="1" step-strictly
v-model="scope.row.stockNumber" controls-position="right" />
:min="0"
:step="1"
step-strictly
controls-position="right"
></el-input-number>
<div class="tips" style="font-size: 16px"> <div class="tips" style="font-size: 16px">
{{ type == "in" ? "入库" : "出库" }} {{ type == "in" ? "入库" : "出库" }}
{{ returnStockNumber(scope.row, scope.row.number) }} {{ returnStockNumber(scope.row, scope.row.number) }}
@ -181,12 +122,27 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="小计"> <!-- <el-table-column v-if="type == 'reportinglosses'" label="报损数量">
<template v-slot="scope"> <template v-slot="scope">
<el-input :value="xiaoji(scope.row)" readonly style="width: 100px" /> {{ scope.row.number }}
<div class="tips" style="font-size: 16px">
入库前
{{ returnStockNumber(scope.row, scope.row.number) }}
{{ scope.row.unit }}
</div>
</template>
</el-table-column> -->
<el-table-column v-if="type == 'reportinglosses'" label="上传图片">
<template v-slot="scope">
<MultiImageUpload v-model="scope.row.imgUrls" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="备注">
<template v-slot="scope">
<el-input v-model="textarea" stype="textarea" placeholder="" />
</template>
</el-table-column> -->
<el-table-column label="操作" width="80"> <el-table-column label="操作" width="80">
<template v-slot="scope"> <template v-slot="scope">
<el-button link @click="tableData.list.splice(scope.$index, 1)">删除</el-button> <el-button link @click="tableData.list.splice(scope.$index, 1)">删除</el-button>
@ -195,21 +151,14 @@
</el-table> </el-table>
</div> </div>
<div> <div>
<el-button type="primary" @click="submitHandle" :loading="queryFormLoading">确定</el-button> <el-button type="primary" :loading="queryFormLoading" @click="submitHandle">
保存并返回
</el-button>
</div> </div>
<!-- 选择耗材 --> <!-- 选择耗材 -->
<ConsumableList ref="ConsumableList" @success="selectConsumable" /> <ConsumableList ref="ConsumableList" @success="selectConsumable" />
<el-dialog <el-dialog v-model="showResult" :show-close="false" :close-on-press-escape="false" :close-on-click-modal="false">
v-model="showResult" <el-result icon="success" title="入库提交成功" :subTitle="`共操作${tableData.list.length}件商品`">
:show-close="false"
:close-on-press-escape="false"
:close-on-click-modal="false"
>
<el-result
icon="success"
title="入库提交成功"
:subTitle="`共操作${tableData.list.length}件商品`"
>
<template #extra> <template #extra>
<template> <template>
<el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button> <el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button>
@ -231,6 +180,8 @@ import vendorApi from "@/api/product/vendor";
import stockApi from "@/api/product/stock"; import stockApi from "@/api/product/stock";
import dayjs from "dayjs"; import dayjs from "dayjs";
import goodsList from "./components/goods-list.vue"; import goodsList from "./components/goods-list.vue";
import MultiImageUpload from "@/components/Upload/MultiImageUpload.vue";
import ConsumableList from "./components/consumableList.vue"; import ConsumableList from "./components/consumableList.vue";
import { formatDecimal } from "@/utils/tools.js"; import { formatDecimal } from "@/utils/tools.js";
export default { export default {
@ -248,7 +199,7 @@ export default {
{ {
label: "商品入库", label: "商品入库",
value: "goods", value: "goods",
type: "purveyor", type: "out",
}, },
{ {
label: "耗材入库", label: "耗材入库",
@ -257,22 +208,6 @@ export default {
}, },
], ],
shopTypesActive: 0, shopTypesActive: 0,
shopTypes: [
{
label: "供应商入库",
value: "purveyor",
},
{
label: "其他入库",
value: "purchase",
},
],
shopTypes2: [
{
label: "供应商入库",
value: "purveyor",
},
],
resetForm: "", resetForm: "",
queryFormLoading: false, queryFormLoading: false,
queryForm: { queryForm: {
@ -314,11 +249,6 @@ export default {
timeout: null, timeout: null,
}; };
}, },
mounted() {
this.type = this.$route.query.type || "in";
this.resetForm = { ...this.queryForm };
this.tbShopPurveyorGet();
},
computed: { computed: {
amountPayable() { amountPayable() {
if (!this.tableData.list.length) return 0; if (!this.tableData.list.length) return 0;
@ -333,6 +263,11 @@ export default {
this.queryForm.amountPayable = newval; this.queryForm.amountPayable = newval;
}, },
}, },
mounted() {
this.type = this.$route.query.type || "in";
this.resetForm = { ...this.queryForm };
this.tbShopPurveyorGet();
},
methods: { methods: {
changeUnit(row) { changeUnit(row) {
row.price = this.returnPrice(row, row.originPrice); row.price = this.returnPrice(row, row.originPrice);
@ -393,6 +328,7 @@ export default {
const price = row.price * row.stockNumber; const price = row.price * row.stockNumber;
return price; return price;
}, },
handleSelect(item) { handleSelect(item) {
// //
this.autocompletename = ""; this.autocompletename = "";
@ -400,12 +336,13 @@ export default {
}, },
// //
tabChange(value, type) { tabChange(value) {
this.shopTypesActive = type == "in" ? 0 : 1; this.shopTypesActive = value == "in" ? 0 : 1;
this.inTabValue = value; this.inTabValue = value;
this.type = value;
this.resetHandle(); this.resetHandle();
this.$refs.shopList.reset(); // // this.$refs.shopList.reset(); //
this.$refs.ConsumableList.reset(); // // this.$refs.ConsumableList.reset(); //
}, },
// //
changeTypeEnum(index) { changeTypeEnum(index) {
@ -452,21 +389,26 @@ export default {
unitName: v.conUnit, unitName: v.conUnit,
inOutNumber, inOutNumber,
subTotal: this.xiaoji(v), subTotal: this.xiaoji(v),
imgUrls: v.imgUrls,
number: v.number,
}; };
}); });
if (this.type == "in") { if (this.type == "in") {
await stockApi.in({ ...this.queryForm, bodyList }); await stockApi.in({ ...this.queryForm, bodyList });
} else { } else if (this.type == "out") {
await stockApi.out({ ...this.queryForm, bodyList }); await stockApi.out({ ...this.queryForm, bodyList });
} else if (this.type == "reportinglosses") {
await stockApi.reportinglosses(bodyList);
} }
this.queryFormLoading = false; this.queryFormLoading = false;
const title = this.type == "in" ? "入库" : "出库"; // const title = this.type == "in" ? "" : "";
ElMessage({ ElMessage({
message: title + "提交成功", // message: title + "",
message: "提交成功",
type: "success", type: "success",
}); });
this.resetHandle(); // this.$router.push("/inventory/consumables");
// this.showResult = true this.showResult = true;
// this.$refs.shopList.reset()// // this.$refs.shopList.reset()//
// this.$refs.ConsumableList.reset()// // this.$refs.ConsumableList.reset()//
} catch (error) { } catch (error) {
@ -487,6 +429,7 @@ export default {
item.unit = item.defaultUnit || item.conUnit; item.unit = item.defaultUnit || item.conUnit;
item.originPrice = item.price; item.originPrice = item.price;
item.price = this.returnPrice(item, item.price); item.price = this.returnPrice(item, item.price);
item.imgUrls = item.imgUrls ? item.imgUrls : [];
return item; return item;
}); });
this.tableData.list = [...this.tableData.list, ...arr]; this.tableData.list = [...this.tableData.list, ...arr];
@ -496,7 +439,8 @@ export default {
resetHandle() { resetHandle() {
this.showResult = false; this.showResult = false;
this.queryForm = { ...this.resetForm }; this.queryForm = { ...this.resetForm };
this.queryForm.type = this.inTabs.find((item) => item.value == this.inTabValue).type; console.log(this.inTabs, this.inTabValue);
this.queryForm.type = this.inTabs.find((item) => item.type == this.inTabValue).type;
this.tableData.list = []; this.tableData.list = [];
this.$refs.queryForm.resetFields(); this.$refs.queryForm.resetFields();
}, },
@ -524,6 +468,5 @@ export default {
} }
} }
.app-container { .app-container {}
}
</style> </style>

View File

@ -19,7 +19,6 @@ const modalConfig: IModalConfig = {
console.log("提交之前处理", data); console.log("提交之前处理", data);
}, },
formItems: [ formItems: [
{ {
label: "名称", label: "名称",
prop: "name", prop: "name",
@ -41,7 +40,7 @@ const modalConfig: IModalConfig = {
prop: "telephone", prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }], rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: { attrs: {
placeholder: "请输入联系人名字", placeholder: "请输入联系人电话",
}, },
}, },
{ {
@ -69,7 +68,6 @@ const modalConfig: IModalConfig = {
placeholder: "请输入排序", placeholder: "请输入排序",
}, },
}, },
], ],
}; };

View File

@ -23,7 +23,15 @@ const contentConfig: IContentConfig = {
return Api.edit(data); return Api.edit(data);
}, },
pk: "id", pk: "id",
toolbar: ["add"], toolbar: [
{
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
],
defaultToolbar: ["refresh", "filter", "search"], defaultToolbar: ["refresh", "filter", "search"],
cols: [ cols: [
// { type: "selection", width: 50, align: "center" }, // { type: "selection", width: 50, align: "center" },
@ -57,13 +65,13 @@ const contentConfig: IContentConfig = {
align: "center", align: "center",
prop: "createTime", prop: "createTime",
}, },
{ // {
label: "状态", // label: "状态",
align: "center", // align: "center",
prop: "status", // prop: "status",
templet: 'custom', // templet: 'custom',
slotName: 'switch' // slotName: 'switch'
}, // },
{ {
label: "操作", label: "操作",
@ -71,7 +79,7 @@ const contentConfig: IContentConfig = {
fixed: "right", fixed: "right",
width: 280, width: 280,
templet: "tool", templet: "tool",
operat: ["edit", 'delete'], operat: [{ text: "编辑", icon: 'edit', name: "edit"}, { text: "删除", icon: 'delete', type: 'danger', name: "delete"}],
}, },
], ],
}; };

View File

@ -19,7 +19,6 @@ const modalConfig: IModalConfig = {
console.log("提交之前处理", data); console.log("提交之前处理", data);
}, },
formItems: [ formItems: [
{ {
label: "名称", label: "名称",
prop: "name", prop: "name",
@ -41,7 +40,7 @@ const modalConfig: IModalConfig = {
prop: "telephone", prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }], rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: { attrs: {
placeholder: "请输入联系人名字", placeholder: "请输入联系人电话",
}, },
}, },
{ {
@ -69,7 +68,6 @@ const modalConfig: IModalConfig = {
placeholder: "请输入排序", placeholder: "请输入排序",
}, },
}, },
], ],
}; };

View File

@ -71,6 +71,7 @@ import contentConfig from "./config/content";
import editModalConfig from "./config/edit"; import editModalConfig from "./config/edit";
import searchConfig from "./config/search"; import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config"; import { returnOptionsLabel } from "./config/config";
import { isSyncStatus } from "@/utils/index";
const { const {
searchRef, searchRef,
@ -87,6 +88,16 @@ const {
handleFilterChange, handleFilterChange,
} = usePage(); } = usePage();
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = true
} else {
contentConfig.toolbar[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = false
}
// //
async function handleAddClick() { async function handleAddClick() {
addModalRef.value?.setModalVisible(); addModalRef.value?.setModalVisible();

View File

@ -1,13 +1,7 @@
<template> <template>
<div class="login" :style="'background-image:url(' + Background + ');'"> <div class="login" :style="'background-image:url(' + Background + ');'">
<el-form <el-form ref="loginForm" :model="state.loginForm" :rules="state.loginRules" label-position="left" label-width="0px"
ref="loginForm" class="login-form">
:model="state.loginForm"
:rules="state.loginRules"
label-position="left"
label-width="0px"
class="login-form"
>
<h3 class="title">银收客后台管理</h3> <h3 class="title">银收客后台管理</h3>
<el-form-item> <el-form-item>
<el-radio-group v-model="state.loginForm.loginType"> <el-radio-group v-model="state.loginForm.loginType">
@ -16,39 +10,19 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input v-model="state.loginForm.username" type="text" auto-complete="off" placeholder="商户号"></el-input>
v-model="state.loginForm.username"
type="text"
auto-complete="off"
placeholder="商户号"
></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="staffUserName" v-if="state.loginForm.loginType == 1"> <el-form-item prop="staffUserName" v-if="state.loginForm.loginType == 1">
<el-input <el-input v-model="state.loginForm.staffUserName" type="text" auto-complete="off" placeholder="账号"></el-input>
v-model="state.loginForm.staffUserName"
type="text"
auto-complete="off"
placeholder="账号"
></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input v-model="state.loginForm.password" type="password" auto-complete="off" placeholder="密码"
v-model="state.loginForm.password" @keyup.enter="handleLogin"></el-input>
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter="handleLogin"
></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code"> <el-form-item prop="code">
<div class="code_wrap"> <div class="code_wrap">
<el-input <el-input v-model="state.loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%"
v-model="state.loginForm.code" @keyup.enter="handleLogin"></el-input>
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter="handleLogin"
></el-input>
<div class="login-code"> <div class="login-code">
<img :src="state.codeUrl" @click="getCode" /> <img :src="state.codeUrl" @click="getCode" />
</div> </div>
@ -56,13 +30,8 @@
</el-form-item> </el-form-item>
<el-form-item style="width: 100%"> <el-form-item style="width: 100%">
<el-button <el-button :loading="state.loading" size="default" type="primary" style="width: 100%"
:loading="state.loading" @click.prevent="handleLogin">
size="default"
type="primary"
style="width: 100%"
@click.prevent="handleLogin"
>
<span v-if="!state.loading"> </span> <span v-if="!state.loading"> </span>
<span v-else> 中...</span> <span v-else> 中...</span>
</el-button> </el-button>
@ -198,11 +167,14 @@ function handleLogin() {
loginName: userStore.userInfo.phone, loginName: userStore.userInfo.phone,
token, token,
}).then((checkInfo) => { }).then((checkInfo) => {
console.log("checkInfo", checkInfo.userInfo); console.log("checkInfo", checkInfo);
userStore.meituan_douyin_info = checkInfo.userInfo; userStore.meituan_douyin_info = checkInfo.userInfo;
setDouyinToken(checkInfo.userInfo.token); setDouyinToken(checkInfo.userInfo.token);
}); });
await userStore.getUserInfo(); localStorage.removeItem("shopName")
let resData = await $API_login.getPermission()
localStorage.setItem("permission",JSON.stringify(resData))
localStorage.setItem("loginType",state.loginForm.loginType)
const { path, queryParams } = parseRedirect(); const { path, queryParams } = parseRedirect();
console.log(path, queryParams); console.log(path, queryParams);

View File

@ -0,0 +1,75 @@
import Api from "@/api/product/vendor";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "添加供应商",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.add({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "名称",
prop: "name",
rules: [{ required: true, message: "请输入名称", trigger: "blur" }],
attrs: {
placeholder: "请输入名称",
},
},
{
label: "联系人名字",
prop: "contactName",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "联系人电话",
prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "供应商地址",
prop: "address",
rules: [{ required: false, message: "请输入供应商地址", trigger: "blur" }],
attrs: {
placeholder: "请输入供应商地址",
},
},
{
label: "备注",
prop: "remark",
rules: [{ required: false, message: "请输入备注", trigger: "blur" }],
attrs: {
placeholder: "请输入备注",
},
},
{
label: "排序",
prop: "sort",
rules: [{ required: true, message: "请输入排序", trigger: "blur" }],
type: "input-number",
attrs: {
placeholder: "请输入排序",
},
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@ -0,0 +1,46 @@
export interface options {
label: string;
value: string | number;
[property: string]: any;
}
export interface optionObject {
[property: string]: options[];
}
const options: optionObject = {
payType: [
{ label: "现金", value: "cash" },
{ label: "微信", value: "weixin" },
{ label: "银行卡", value: "bank" },
{ label: "会员支付", value: "member-account" },
{ label: "支付宝", value: "alipay" },
{ label: "刷卡", value: "deposit" },
{ label: "挂账", value: "arrears" },
{ label: "刷卡", value: "deposit" },
{ label: "储值", value: "member-account" },
{ label: "自定义", value: "virtual" },
],
isIdeal: [
{ label: "否", value: 0 },
{ label: "是", value: 1 },
],
};
export const switchAttr = {
"active-value": 1,
"inactive-value": 0,
};
export type optionsType = string;
export function returnOptions(type: optionsType) {
return options[type];
}
export function returnOptionsLabel(optionsType: optionsType, value: string | number) {
const options = returnOptions(optionsType);
if (!options) {
return "";
}
const option = options.find((item) => item.value === value);
return option ? option.label : "";
}

View File

@ -0,0 +1,88 @@
import Api from "@/api/notifications";
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig = {
pageName: "sys:user",
table: {
border: true,
highlightCurrentRow: true,
},
pagination: {
background: true,
layout: "prev,pager,next,jumper,total,sizes",
pageSize: 20,
pageSizes: [10, 20, 30, 50],
},
indexAction: function (params) {
return Api.getList(params);
},
deleteAction: function (id) {
return Api.delete(id);
},
modifyAction: function (data) {
return Api.edit(data);
},
indexActionData: {},
pk: "id",
toolbar: [
{
text: "全部已读",
name: "mark_all_read",
auth: "",
type: "primary",
},
{
text: "清空已读",
name: "Clear_Read",
auth: "",
type: "danger",
},
],
defaultToolbar: ["refresh", "filter", "search"],
cols: [
// { type: "selection", width: 50, align: "center" },
{
label: "通知类型",
align: "center",
prop: "title",
},
{
label: "是否已读",
align: "center",
prop: "isRead",
slotName: "isRead",
templet: "custom",
},
{
label: "消息内容",
align: "center",
prop: "content",
slotName: "content",
templet: "custom",
},
{
label: "创建时间",
align: "center",
prop: "createTime",
},
{
label: "操作",
align: "center",
fixed: "right",
width: 280,
templet: "custom",
slotName: "operate",
operat: ["delete"],
},
// {
// label: "操作",
// align: "center",
// fixed: "right",
// width: 150,
// templet: "custom",
// slotName: "operate",
// },
],
};
export default contentConfig;

View File

@ -0,0 +1,75 @@
import Api from "@/api/product/vendor";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "编辑供应商",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.edit({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "名称",
prop: "name",
rules: [{ required: true, message: "请输入名称", trigger: "blur" }],
attrs: {
placeholder: "请输入名称",
},
},
{
label: "联系人名字",
prop: "contactName",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "联系人电话",
prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "供应商地址",
prop: "address",
rules: [{ required: false, message: "请输入供应商地址", trigger: "blur" }],
attrs: {
placeholder: "请输入供应商地址",
},
},
{
label: "备注",
prop: "remark",
rules: [{ required: false, message: "请输入备注", trigger: "blur" }],
attrs: {
placeholder: "请输入备注",
},
},
{
label: "排序",
prop: "sort",
rules: [{ required: true, message: "请输入排序", trigger: "blur" }],
type: "input-number",
attrs: {
placeholder: "请输入排序",
},
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@ -0,0 +1,57 @@
import type { ISearchConfig } from "@/components/CURD/types";
const searchConfig: ISearchConfig = {
pageName: "sys:user",
isExpandable: false,
formItems: [
{
type: "select",
label: "通知类型 ",
prop: "type",
attrs: {
placeholder: "请选择",
clearable: true,
style: {
width: "200px",
},
},
options: [
{
label: "数据同步",
value: "数据同步",
},
{
label: "数据变动",
value: "数据变动",
},
{
label: "库存预警",
value: "库存预警",
},
],
},
{
type: "select",
label: "是否已读",
prop: "isRead",
attrs: {
placeholder: "请选择",
clearable: true,
style: {
width: "200px",
},
},
options: [
{
label: "未读",
value: "0",
},
{
label: "已读",
value: "1",
},
],
},
],
};
export default searchConfig;

View File

@ -0,0 +1,148 @@
<template>
<div class="app-container">
<!-- 搜索 -->
<page-search ref="searchRef" :search-config="searchConfig" @query-click="handleQueryClick"
@reset-click="handleResetClick" />
<!-- 列表 -->
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
<!-- <template #type="scope">
<span v-if="scope.row.type == 0">商品新增</span>
<span v-if="scope.row.type == 1">商品编辑</span>
<span v-if="scope.row.type == 2">耗材新增</span>
<span v-if="scope.row.type == 3">耗材编辑</span>
</template> -->
<template #content="scope">
<span>{{ scope.row.title }}</span>
<!-- <span v-if="scope.row.type == 1">商品编辑</span>
<span v-if="scope.row.type == 2">耗材新增</span>
<span v-if="scope.row.type == 3">耗材编辑</span> -->
<div v-for="(item, index) in matchedProducts(scope.row.content)" :key="index">
<span v-for="i in item.map" :key="i.id" style="color: #6161f7" @click="handleContentClick(item, i)">
{{ i.name }},
</span>
</div>
请及时确认
</template>
<template #isRead="scope">
<el-tag :type="scope.row.isRead == 1 ? 'success' : 'info'">
{{ scope.row.isRead == 1 ? "已读" : "未读" }}
</el-tag>
</template>
<template #operate="scope">
<div style="
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
">
<div v-if="scope.row.isRead != 1">
<el-button link type="primary" @click="refAddHaocaiTakinShow(scope.row, '')">
设为已读
</el-button>
</div>
<el-button link type="primary" @click="refAddHaocaiTakinShow(scope.row, 'delete')">
删除
</el-button>
</div>
</template>
</page-content>
<!-- 新增 -->
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick" />
<!-- 编辑 -->
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick" />
</div>
</template>
<script setup lang="ts">
import VersionApi from "@/api/system/version";
import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import addModalConfig from "./config/add";
import contentConfig from "./config/content";
import editModalConfig from "./config/edit";
import searchConfig from "./config/search";
import Api from "@/api/notifications";
import router from "@/router";
import { log } from "console";
const {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
// handleAddClick,
// handleEditClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
handleFilterChange,
} = usePage();
//
async function handleAddClick() {
addModalRef.value?.setModalVisible();
// addModalConfig.formItems[2]!.attrs!.data =
}
//
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
editModalRef.value?.setModalVisible();
// id
editModalRef.value?.setFormData({ ...row });
}
//
async function handleToolbarClick(name: string) {
if (name === "mark_all_read") {
await Api.edit({
noticeIdList: [],
});
}
if (name == "Clear_Read") {
await Api.syncNoticeclear();
}
contentRef.value?.fetchPageData();
}
const matchedProducts = (data: string) => {
return JSON.parse(data);
};
//
async function refAddHaocaiTakinShow(item: any, type: string) {
if (type === "delete") {
await Api.delete(item.id);
} else {
await Api.edit({
noticeIdList: [item.id],
});
}
contentRef.value?.fetchPageData();
}
//
async function handleOperatClick(data: IOperatData) {
console.log(data);
}
// Handle content click
function handleContentClick(scope: any, item: any) {
if (scope.type == "product") {
router.push({
path: "/product/addgoods",
query: { goods_id: item.id },
});
}
if (scope.type == "consInfo") {
router.push({
path: "/inventory/consumables",
query: { conName: item.name },
});
}
}
</script>

View File

@ -234,6 +234,8 @@ import searchConfig from "./goodsGroupconfig/search";
import searchConfig2 from "./goodsGroupconfig/search2"; import searchConfig2 from "./goodsGroupconfig/search2";
import myDialog from "@/components/mycomponents/myDialog.vue"; import myDialog from "@/components/mycomponents/myDialog.vue";
import selectGoodslist from "./goodsGroupconfig/selectGoodslist.vue"; import selectGoodslist from "./goodsGroupconfig/selectGoodslist.vue";
import { isSyncStatus } from "@/utils/index";
const { const {
searchRef, searchRef,
searchRefs, searchRefs,
@ -252,6 +254,18 @@ const {
handleFilterChange, handleFilterChange,
} = usePage(); } = usePage();
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = true;
contentConfig.cols[3].templet = "custom";
} else {
contentConfig.toolbar[0].hidden = false;
contentConfig.cols[3].templet = "switch";
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false;
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = false;
}
let switchref = ref(false); let switchref = ref(false);
// //

View File

@ -73,7 +73,7 @@ const contentConfig: IContentConfig<UserPageQuery> = {
fixed: "right", fixed: "right",
width: 280, width: 280,
templet: "tool", templet: "tool",
operat: ["edit", "delete"], operat: [{ text: "编辑", icon: 'edit', name: "edit"}, { text: "删除", icon: 'delete', type: 'danger', name: "delete"}],
}, },
], ],
}; };

View File

@ -95,6 +95,7 @@ import contentConfig from "./categoryconfig/content";
import contentConfig2 from "./categoryconfig/content2"; import contentConfig2 from "./categoryconfig/content2";
import editModalConfig from "./categoryconfig/edit"; import editModalConfig from "./categoryconfig/edit";
import searchConfig from "./categoryconfig/search"; import searchConfig from "./categoryconfig/search";
import { isSyncStatus } from "@/utils/index";
const { const {
searchRef, searchRef,
@ -111,6 +112,17 @@ const {
handleFilterChange, handleFilterChange,
} = usePage(); } = usePage();
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = true
contentConfig.cols[2].templet = "custom"
} else {
contentConfig.toolbar[0].hidden = false
contentConfig.cols[2].templet = "switch"
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = false
}
// //
async function handleAddClick() { async function handleAddClick() {
addModalRef.value?.setModalVisible(); addModalRef.value?.setModalVisible();

View File

@ -44,7 +44,15 @@ const contentConfig: IContentConfig<UserPageQuery> = {
// return res.list; // return res.list;
// }, // },
pk: "id", pk: "id",
toolbar: ["add"], toolbar: [
{
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
],
cols: [ cols: [
// { type: "selection", width: 50, align: "center" }, // { type: "selection", width: 50, align: "center" },
{ label: "分类名称", align: "center", prop: "name" }, { label: "分类名称", align: "center", prop: "name" },
@ -68,7 +76,7 @@ const contentConfig: IContentConfig<UserPageQuery> = {
fixed: "right", fixed: "right",
width: 280, width: 280,
templet: "tool", templet: "tool",
operat: ["edit", "delete"], operat: [{ text: "编辑", icon: 'edit', name: "edit"}, { text: "删除", icon: 'delete', type: 'danger', name: "delete"}],
}, },
], ],
}; };

View File

@ -127,7 +127,7 @@
<MyDialog ref="myDialogRefbaosun" @confirm="confirmbaosun" title="报损"> <MyDialog ref="myDialogRefbaosun" @confirm="confirmbaosun" title="报损">
<el-form :model="form"> <el-form :model="form">
<el-form-item label="报损数量" label-width=""> <el-form-item label="报损数量" label-width="">
<el-input-number v-model="datas.number" label="描述文字"></el-input-number> <el-input-number v-model="datas.number" :min="1" label="描述文字"></el-input-number>
</el-form-item> </el-form-item>
<el-form-item label="报损照片" label-width=""> <el-form-item label="报损照片" label-width="">
<MultiImageUpload v-model="datas.images" /> <MultiImageUpload v-model="datas.images" />
@ -206,7 +206,7 @@
</MyDialog> </MyDialog>
<!-- 库存修改 --> <!-- 库存修改 -->
<MyDialog ref="myDialogRefkucun" @confirm="confirmkucun" width="30%" title="库存修改"> <MyDialog ref="myDialogRefkucun" @confirm="confirmkucun" width="30%" title="库存修改">
<el-input-number v-model="kucundata.stockNumber" :min="0" /> <el-input-number v-model="kucundata.stockNumbers" :min="0" />
</MyDialog> </MyDialog>
</div> </div>
</template> </template>
@ -216,6 +216,7 @@ import UserAPI from "@/api/product/index";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import type { IObject, IOperatData } from "@/components/CURD/types"; import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage"; import usePage from "@/components/CURD/usePage";
import { isSyncStatus } from "@/utils/index";
import addModalConfig from "./indexconfig/add"; import addModalConfig from "./indexconfig/add";
import contentConfig from "./indexconfig/content"; import contentConfig from "./indexconfig/content";
import MultiImageUpload from "@/components/Upload/MultiImageUpload.vue"; import MultiImageUpload from "@/components/Upload/MultiImageUpload.vue";
@ -224,6 +225,7 @@ import editModalConfig from "./indexconfig/edit";
import searchConfig from "./indexconfig/search"; import searchConfig from "./indexconfig/search";
import MyDialog from "@/components/mycomponents/myDialog.vue"; import MyDialog from "@/components/mycomponents/myDialog.vue";
import Statistics from "./indexconfig/statistics.vue"; import Statistics from "./indexconfig/statistics.vue";
import { min } from "lodash";
const { const {
searchRef, searchRef,
@ -255,6 +257,83 @@ let datas = reactive({
number: 0, number: 0,
remark: "", remark: "",
images: [], images: [],
productId: null, // Added productId property
});
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true;
contentConfig.toolbar[1].hidden = false;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = true;
} else {
contentConfig.toolbar[0].hidden = false;
contentConfig.toolbar[1].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = false;
}
onMounted(() => {
console.log(route.query);
if (route.query.id) {
contentRef.value?.fetchPageData({ id: route.query.id });
}
//
gethaocaiList();
});
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true;
contentConfig.toolbar[1].hidden = false;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = true;
} else {
contentConfig.toolbar[0].hidden = false;
contentConfig.toolbar[1].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = false;
}
onMounted(() => {
console.log(route.query);
if (route.query.id) {
contentRef.value?.fetchPageData({ id: route.query.id });
}
//
gethaocaiList();
});
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true;
contentConfig.toolbar[1].hidden = false;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = true;
} else {
contentConfig.toolbar[0].hidden = false;
contentConfig.toolbar[1].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = false;
}
onMounted(() => {
console.log(route.query);
if (route.query.id) {
contentRef.value?.fetchPageData({ id: route.query.id });
}
//
gethaocaiList();
});
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true;
contentConfig.toolbar[1].hidden = false;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = true;
} else {
contentConfig.toolbar[0].hidden = false;
contentConfig.toolbar[1].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[2].hidden = false;
}
onMounted(() => {
console.log(route.query);
if (route.query.id) {
contentRef.value?.fetchPageData({ id: route.query.id });
}
//
gethaocaiList();
}); });
function newHandleQueryClick(e: IObject | undefined) { function newHandleQueryClick(e: IObject | undefined) {
const filterParams = contentRef.value?.getFilterParams(); const filterParams = contentRef.value?.getFilterParams();
@ -264,13 +343,15 @@ function newHandleQueryClick(e: IObject | undefined) {
// //
function kucunedit(item) { function kucunedit(item) {
kucundata.value = item; kucundata.value = item;
kucundata.value.stockNumbers = item.stockNumber;
myDialogRefkucun.value.open(); myDialogRefkucun.value.open();
} }
async function confirmkucun() { async function confirmkucun() {
let res = await UserAPI.modifyStock({ let res = await UserAPI.modifyStock({
id: kucundata.value.id, id: kucundata.value.id,
stockNumber: kucundata.value.stockNumber, stockNumber: kucundata.value.stockNumbers,
}); });
kucundata.value.stockNumber = kucundata.value.stockNumbers;
ElMessage.success("成功"); ElMessage.success("成功");
myDialogRefkucun.value.close(); myDialogRefkucun.value.close();
} }
@ -354,16 +435,25 @@ async function handleSwitchhaocai(row: IObject) {
// //
async function handleEditClick(row: IObject) { async function handleEditClick(row: IObject) {
try {
router.push({ name: "addgoods", query: { goods_id: row.id } }); router.push({ name: "addgoods", query: { goods_id: row.id } });
} catch (error) {
ElMessage.error("没有编辑权限");
}
} }
// //
function handleToolbarClick(name: string) { async function handleToolbarClick(name: string) {
console.log(name); console.log(name);
if (name === "custom1") { if (name === "custom1") {
// ElMessage.success("1"); // ElMessage.success("1");
myDialogRef.value.open(); myDialogRef.value.open();
} }
if (name === "sync") {
//
let res = await UserAPI.sync();
ElMessage.success("操作成功,数据正在后台同步中...");
}
} }
async function confirm() { async function confirm() {
let res = await UserAPI.stockWarning(form.warnLine); let res = await UserAPI.stockWarning(form.warnLine);
@ -380,6 +470,7 @@ async function confirmbaosun() {
let res = await UserAPI.reportDamage(datas); let res = await UserAPI.reportDamage(datas);
ElMessage.success("成功"); ElMessage.success("成功");
myDialogRefbaosun.value.close(); myDialogRefbaosun.value.close();
contentRef.value?.fetchPageData();
} }
async function confirmhaocai() { async function confirmhaocai() {
let obj = { let obj = {
@ -409,16 +500,10 @@ function typeFilter(item: any) {
async function handleOperatClick(data: IOperatData) { async function handleOperatClick(data: IOperatData) {
datas.productId = data.row.id; datas.productId = data.row.id;
myDialogRefbaosun.value.open(); myDialogRefbaosun.value.open();
datas.number = 1;
datas.remark = "";
} }
onMounted(() => {
console.log(route.query);
if (route.query.id) {
contentRef.value?.fetchPageData({ id: route.query.id });
}
//
gethaocaiList();
});
async function gethaocaiList() { async function gethaocaiList() {
let res = await UserAPI.productcons({ id: route.query.id }); let res = await UserAPI.productcons({ id: route.query.id });
options.value = res.records; options.value = res.records;

View File

@ -14,7 +14,7 @@
</template> </template>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number size="default" v-model="scope.row.salePrice" @change="priceFormat(scope.row, 'salePrice')" <el-input-number size="default" v-model="scope.row.salePrice" @change="priceFormat(scope.row, 'salePrice')"
@blur="priceFormat(scope.row, 'salePrice')" controls-position="right"></el-input-number> @blur="priceFormat(scope.row, 'salePrice')" controls-position="right" :disabled="isSyncStatus()"></el-input-number>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="originPrice"> <el-table-column prop="originPrice">
@ -26,7 +26,7 @@
</template> </template>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number @change="priceFormat(scope.row, 'originPrice')" v-model="scope.row.originPrice" <el-input-number @change="priceFormat(scope.row, 'originPrice')" v-model="scope.row.originPrice"
@blur="priceFormat(scope.row, 'originPrice')" controls-position="right"></el-input-number> @blur="priceFormat(scope.row, 'originPrice')" controls-position="right" :disabled="isSyncStatus()"></el-input-number>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="costPrice"> <el-table-column prop="costPrice">
@ -38,7 +38,7 @@
</template> </template>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number @change="priceFormat(scope.row, 'costPrice')" v-model="scope.row.costPrice" <el-input-number @change="priceFormat(scope.row, 'costPrice')" v-model="scope.row.costPrice"
@blur="priceFormat(scope.row, 'costPrice')" controls-position="right"></el-input-number> @blur="priceFormat(scope.row, 'costPrice')" controls-position="right" :disabled="isSyncStatus()"></el-input-number>
</template> </template>
</el-table-column> </el-table-column>
@ -51,7 +51,7 @@
</template> </template>
<template v-slot="scope"> <template v-slot="scope">
<el-input-number @change="priceFormat(scope.row, 'memberPrice')" v-model="scope.row.memberPrice" <el-input-number @change="priceFormat(scope.row, 'memberPrice')" v-model="scope.row.memberPrice"
@blur="priceFormat(scope.row, 'memberPrice')" controls-position="right"></el-input-number> @blur="priceFormat(scope.row, 'memberPrice')" controls-position="right" :disabled="isSyncStatus()"></el-input-number>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="起售数量" prop="suitNum"> <el-table-column label="起售数量" prop="suitNum">
@ -64,9 +64,9 @@
<template v-slot="scope"> <template v-slot="scope">
<el-input-number @change="priceFormat(scope.row, 'suitNum')" v-model="scope.row.suitNum" <el-input-number @change="priceFormat(scope.row, 'suitNum')" v-model="scope.row.suitNum"
@blur="priceFormat(scope.row, 'suitNum')" :min="0" controls-position="right" @blur="priceFormat(scope.row, 'suitNum')" :min="0" controls-position="right"
v-if="props.info.type == 'weigh'"></el-input-number> v-if="props.info.type == 'weigh'" :disabled="isSyncStatus()"></el-input-number>
<el-input-number @change="priceFormat(scope.row, 'suitNum')" v-model="scope.row.suitNum" <el-input-number @change="priceFormat(scope.row, 'suitNum')" v-model="scope.row.suitNum"
@blur="priceFormat(scope.row, 'suitNum')" :min="1" controls-position="right" v-else></el-input-number> @blur="priceFormat(scope.row, 'suitNum')" :min="1" controls-position="right" :disabled="isSyncStatus()" v-else></el-input-number>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -77,7 +77,7 @@
<el-form-item> <el-form-item>
<el-input-number @change="priceFormat(batchNumberForm, 'batchNumber')" <el-input-number @change="priceFormat(batchNumberForm, 'batchNumber')"
@blur="priceFormat(batchNumberForm, 'batchNumber')" v-model="batchNumberForm.batchNumber" @blur="priceFormat(batchNumberForm, 'batchNumber')" v-model="batchNumberForm.batchNumber"
controls-position="right" style="width: 100%"></el-input-number> controls-position="right" style="width: 100%" :disabled="isSyncStatus()"></el-input-number>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -93,6 +93,8 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import { isSyncStatus } from "@/utils/index";
const ruleFormRef = ref(null) const ruleFormRef = ref(null)
let batchNumberKey = ref(null) let batchNumberKey = ref(null)
let batchNumberForm = reactive({ let batchNumberForm = reactive({

View File

@ -4,21 +4,21 @@
<el-form-item label="商品名称" required> <el-form-item label="商品名称" required>
<el-col :span="12"> <el-col :span="12">
<el-form-item prop="name"> <el-form-item prop="name">
<el-input v-model="ruleForm.name" placeholder="请输入商品名称" /> <el-input v-model="ruleForm.name" placeholder="请输入商品名称" :disabled="isSyncStatus()" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item label="商品介绍"> <el-form-item label="商品介绍">
<el-col :span="12"> <el-col :span="12">
<el-form-item> <el-form-item>
<el-input v-model="ruleForm.shortTitle" type="textarea" placeholder="请输入商品介绍" /> <el-input v-model="ruleForm.shortTitle" type="textarea" placeholder="请输入商品介绍" :disabled="isSyncStatus()" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item label="单位" required> <el-form-item label="单位" required>
<el-col :span="12"> <el-col :span="12">
<el-form-item prop="unitId"> <el-form-item prop="unitId">
<el-select v-model="ruleForm.unitId" placeholder="请选择单位"> <el-select v-model="ruleForm.unitId" placeholder="请选择单位" :disabled="isSyncStatus()">
<el-option :label="item.name" :value="item.id" v-for="item in datas.Company" :key="item.id" /> <el-option :label="item.name" :value="item.id" v-for="item in datas.Company" :key="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -27,7 +27,7 @@
<el-form-item label="商品分类" required> <el-form-item label="商品分类" required>
<el-col :span="12"> <el-col :span="12">
<el-form-item prop="region"> <el-form-item prop="region">
<el-select v-model="ruleForm.categoryId" placeholder="请选择商品分类"> <el-select v-model="ruleForm.categoryId" placeholder="请选择商品分类" :disabled="isSyncStatus()">
<el-option :label="item.name" :value="item.id" v-for="item in datas.classification" :key="item.id" /> <el-option :label="item.name" :value="item.id" v-for="item in datas.classification" :key="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -54,7 +54,7 @@
<AddImg ref="addImg" @successEvent="successEvent"></AddImg> <AddImg ref="addImg" @successEvent="successEvent"></AddImg>
<el-form-item label="商品类型"> <el-form-item label="商品类型">
<el-radio-group v-model="ruleForm.type" @change="changeTypeEnum(ruleForm.type)"> <el-radio-group v-model="ruleForm.type" @change="changeTypeEnum(ruleForm.type)" :disabled="isSyncStatus()">
<el-radio value="single">单规格商品</el-radio> <el-radio value="single">单规格商品</el-radio>
<el-radio value="sku">多规格商品</el-radio> <el-radio value="sku">多规格商品</el-radio>
<el-radio value="package">套餐商品</el-radio> <el-radio value="package">套餐商品</el-radio>
@ -63,7 +63,7 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="套餐商品" v-if="ruleForm.type == 'package'"> <el-form-item label="套餐商品" v-if="ruleForm.type == 'package'">
<div style="display: block;width: 100%;"> <div style="display: block; width: 100%">
<div class="head-container"> <div class="head-container">
<el-radio-group v-model="ruleForm.groupType" @change="typeChange"> <el-radio-group v-model="ruleForm.groupType" @change="typeChange">
<el-radio-button :label="0">固定套餐</el-radio-button> <el-radio-button :label="0">固定套餐</el-radio-button>
@ -73,7 +73,7 @@
<div v-if="ruleForm.groupType == '0'"> <div v-if="ruleForm.groupType == '0'">
<el-table border :data="item.goods" v-for="(item, index) in ruleForm.proGroupVo" :key="index"> <el-table border :data="item.goods" v-for="(item, index) in ruleForm.proGroupVo" :key="index">
<el-table-column label="名称" prop="proName"></el-table-column> <el-table-column label="名称" prop="proName"></el-table-column>
<el-table-column label="规格" prop="skuName"> </el-table-column> <el-table-column label="规格" prop="skuName"></el-table-column>
<el-table-column label="价格" prop="price"></el-table-column> <el-table-column label="价格" prop="price"></el-table-column>
<el-table-column label="数量" prop="number"> <el-table-column label="数量" prop="number">
<template v-slot="scope"> <template v-slot="scope">
@ -82,10 +82,12 @@
</el-table-column> </el-table-column>
<el-table-column width="150"> <el-table-column width="150">
<template #header> <template #header>
<el-button type="primary" @click="addgoods(-1)">添加商品</el-button> <el-button type="primary" @click="addgoods(-1)" :disabled="isSyncStatus()">
添加商品
</el-button>
</template> </template>
<template v-slot="scope"> <template v-slot="scope">
<el-button type="text" :disabled="scope.row.type != 'sku'" <el-button type="text" :disabled="scope.row.type != 'sku' && isSyncStatus()"
@click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button> @click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button>
<el-button type="text" <el-button type="text"
@click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)">删除</el-button> @click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)">删除</el-button>
@ -97,45 +99,52 @@
<div class="group_wrap" v-for="(item, index) in ruleForm.proGroupVo" :key="index"> <div class="group_wrap" v-for="(item, index) in ruleForm.proGroupVo" :key="index">
<el-form inline :model="item"> <el-form inline :model="item">
<el-form-item label="规格组名"> <el-form-item label="规格组名">
<el-input v-model="item.title" /> <el-input v-model="item.title" :disabled="isSyncStatus()" />
</el-form-item> </el-form-item>
<el-form-item :label="`本组菜品${item.goods.length}选`"> <el-form-item :label="`本组菜品${item.goods.length}选`">
<el-input v-model="item.number" /> <el-input v-model="item.number" :disabled="isSyncStatus()" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="ruleForm.proGroupVo.splice(index, 1)">删除</el-button> <el-button @click="ruleForm.proGroupVo.splice(index, 1)" :disabled="isSyncStatus()">
删除
</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="margin-top: 20px;"> <div style="margin-top: 20px">
<el-table border :data="item.goods"> <el-table border :data="item.goods">
<el-table-column label="名称" prop="proName"></el-table-column> <el-table-column label="名称" prop="proName"></el-table-column>
<el-table-column label="规格" prop="skuName"></el-table-column> <el-table-column label="规格" prop="skuName"></el-table-column>
<el-table-column label="价格" prop="price"></el-table-column> <el-table-column label="价格" prop="price"></el-table-column>
<el-table-column label="数量" prop="number"> <el-table-column label="数量" prop="number">
<template v-slot="scope"> <template v-slot="scope">
<el-input-number v-model="scope.row.number" :min="0" /> <el-input-number v-model="scope.row.number" :min="0" :disabled="isSyncStatus()" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column width="150"> <el-table-column width="150">
<template #header> <template #header>
<el-button type="primary" @click="addgoods(index);">添加商品</el-button> <el-button type="primary" @click="addgoods(index)" :disabled="isSyncStatus()">
添加商品
</el-button>
</template> </template>
<template v-slot="scope"> <template v-slot="scope">
<el-button type="text" :disabled="scope.row.type != 'sku'" <el-button type="text" :disabled="scope.row.type != 'sku' && isSyncStatus()"
@click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button> @click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button>
<el-button type="text" <el-button type="text" @click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)"
@click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)">删除</el-button> :disabled="isSyncStatus()">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<el-button type="primary" @click="addtaocan">添加套餐组</el-button> <el-button type="primary" @click="addtaocan" :disabled="isSyncStatus()">
添加套餐组
</el-button>
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="选择规格" v-if="ruleForm.type == 'sku'"> <el-form-item label="选择规格" v-if="ruleForm.type == 'sku'">
<el-select v-model="ruleForm.specId" placeholder="请选择规格" style="width: 500px" @change="selectSpecHandle"> <el-select v-model="ruleForm.specId" placeholder="请选择规格" style="width: 500px" @change="selectSpecHandle"
:disabled="isSyncStatus()">
<el-option :label="item.name" :value="item.id" v-for="item in datas.specificationsconfig" <el-option :label="item.name" :value="item.id" v-for="item in datas.specificationsconfig"
:key="item.id"></el-option> :key="item.id"></el-option>
</el-select> </el-select>
@ -156,8 +165,8 @@
:info="ruleForm" :list="list" ref="specificationAttributeRef"></SpecificationAttribute> :info="ruleForm" :list="list" ref="specificationAttributeRef"></SpecificationAttribute>
<el-form-item label="重量"> <el-form-item label="重量">
<el-col :span="12"> <el-col :span="12">
<div style="display: block;"> <div style="display: block">
<el-input v-model="ruleForm.weight" placeholder=""> <el-input v-model="ruleForm.weight" placeholder="" :disabled="isSyncStatus()">
<template #append>千克</template> <template #append>千克</template>
</el-input> </el-input>
<!-- <div style="color: #999;">用于快递或配送运费计重</div> --> <!-- <div style="color: #999;">用于快递或配送运费计重</div> -->
@ -165,7 +174,7 @@
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item label="是否允许临时改价"> <el-form-item label="是否允许临时改价">
<el-radio-group v-model="ruleForm.isAllowTempModifyPrice"> <el-radio-group v-model="ruleForm.isAllowTempModifyPrice" :disabled="isSyncStatus()">
<el-radio :value="1">允许</el-radio> <el-radio :value="1">允许</el-radio>
<el-radio :value="0">不允许</el-radio> <el-radio :value="0">不允许</el-radio>
</el-radio-group> </el-radio-group>
@ -187,10 +196,15 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-col :span="12"> <el-col :span="20">
<el-time-picker v-model="ruleForm.useTime" is-range range-separator="" start-placeholder="开始时间" <!-- <el-time-picker v-model="ruleForm.useTime" is-range range-separator="" start-placeholder="开始时间"
end-placeholder="结束时间" :default-value="[new Date('00:00:00'), new Date('23:59:59')]" value-format="HH:mm:ss" end-placeholder="结束时间" value-format="HH:mm:ss" format="HH:mm:ss" />
format="HH:mm:ss" /> -->
<el-time-picker v-model="ruleForm.startTime" value-format="HH:mm:ss" format="HH:mm:ss" placeholder="选择开始时间">
</el-time-picker>-
<el-time-picker v-model="ruleForm.endTime" value-format="HH:mm:ss" format="HH:mm:ss" placeholder="选择结束时间">
</el-time-picker>
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item label="上架"> <el-form-item label="上架">
@ -198,7 +212,7 @@
</el-form-item> </el-form-item>
<el-form-item label="库存开关"> <el-form-item label="库存开关">
<div style="display: block;"> <div style="display: block;">
<el-switch v-model="ruleForm.isStock" :active-value="1" :inactive-value="0" /> <el-switch v-model="ruleForm.isStock" :active-value="1" :inactive-value="0" :disabled="isSyncStatus()" />
<div style="color: #999;">关闭则不计算出入库数据</div> <div style="color: #999;">关闭则不计算出入库数据</div>
</div> </div>
</el-form-item> </el-form-item>
@ -211,14 +225,13 @@
<el-form-item label="打包费" prop="delivery"> <el-form-item label="打包费" prop="delivery">
<div style="display: block;"> <div style="display: block;">
<el-input-number v-model="ruleForm.packFee" controls-position="right"></el-input-number> <el-input-number v-model="ruleForm.packFee" controls-position="right"
:disabled="isSyncStatus()"></el-input-number>
<div style="color: #999;">单份商品打包费店铺开启外卖模式下该数据才生效</div> <div style="color: #999;">单份商品打包费店铺开启外卖模式下该数据才生效</div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)"> <el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
确定
</el-button>
<el-button @click="resetForm(ruleFormRef)">取消</el-button> <el-button @click="resetForm(ruleFormRef)">取消</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -247,30 +260,33 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue' import { reactive, ref } from "vue";
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from "element-plus";
// //
import SpecificationAttribute from './SpecificationAttribute.vue' import SpecificationAttribute from "./SpecificationAttribute.vue";
import { isSyncStatus } from "@/utils/index";
import UserAPI from "@/api/product/productclassification"; import UserAPI from "@/api/product/productclassification";
import UserAPI2 from "@/api/product/commonUnits"; import UserAPI2 from "@/api/product/commonUnits";
import UserAPI3 from "@/api/product/index"; import UserAPI3 from "@/api/product/index";
import UserAPI4 from "@/api/product/specificationsconfig"; import UserAPI4 from "@/api/product/specificationsconfig";
import shopList from "@/components/mycomponents/shopList.vue"; import shopList from "@/components/mycomponents/shopList.vue";
import AddImg from '@/components/mycomponents/addImg.vue'; import AddImg from "@/components/mycomponents/addImg.vue";
import { useRouter } from 'vue-router'; import { useRouter } from "vue-router";
import { useTagsViewStore } from "@/store"; import { useTagsViewStore } from "@/store";
const tagsViewStore = useTagsViewStore(); const tagsViewStore = useTagsViewStore();
const router = useRouter(); const router = useRouter();
let list = ref<any[]>([{ let list = ref<any[]>([
"originPrice": 0, {
"costPrice": 0, originPrice: 0,
"salePrice": 0, costPrice: 0,
"memberPrice": 0, salePrice: 0,
"suitNum": 1, memberPrice: 0,
"coverImg": "", suitNum: 1,
"weight": 0, coverImg: "",
"barCode": "88888888888888888888" weight: 0,
}]); barCode: "88888888888888888888",
},
]);
let datas = reactive<datasForm>({ let datas = reactive<datasForm>({
cycle: [ cycle: [
{ label: "周一", value: "Monday" }, { label: "周一", value: "Monday" },
@ -279,7 +295,7 @@ let datas = reactive<datasForm>({
{ label: "周四", value: "Thursday" }, { label: "周四", value: "Thursday" },
{ label: "周五", value: "Friday" }, { label: "周五", value: "Friday" },
{ label: "周六", value: "Saturday" }, { label: "周六", value: "Saturday" },
{ label: "周七", value: "Sunday" } { label: "周七", value: "Sunday" },
], ],
Company: [], Company: [],
classification: [], classification: [],
@ -287,14 +303,14 @@ let datas = reactive<datasForm>({
specificationsconfig: [], specificationsconfig: [],
selectSpeclist: [], selectSpeclist: [],
defaultSku: { defaultSku: {
"originPrice": 0, originPrice: 0,
"costPrice": 0, costPrice: 0,
"salePrice": 0, salePrice: 0,
"memberPrice": 0, memberPrice: 0,
"suitNum": 1, suitNum: 1,
"coverImg": "", coverImg: "",
"weight": 0, weight: 0,
"barCode": "88888888888888888888" barCode: "88888888888888888888",
}, },
specTableHeaders: [], specTableHeaders: [],
// -index // -index
@ -303,78 +319,79 @@ let datas = reactive<datasForm>({
showSelectSku: false, showSelectSku: false,
selectSkuItem: {}, selectSkuItem: {},
addGroupIndex: -1, addGroupIndex: -1,
});
}) let shopListRef = ref(null);
let shopListRef = ref(null) let addImg = ref(null);
let addImg = ref(null) let isedit = ref(true);
let isedit = ref(true)
interface datasForm { interface datasForm {
cycle: { label: string, value: string }[], cycle: { label: string; value: string }[];
Company: any[], Company: any[];
classification: any[], classification: any[];
specificationsconfig: any[], specificationsconfig: any[];
selectSpeclist: any[], selectSpeclist: any[];
defaultSku: any, defaultSku: any;
specTableHeaders: any[], specTableHeaders: any[];
selectSkuTableIndex: any, selectSkuTableIndex: any;
selectSkuConfirmIndex: number, selectSkuConfirmIndex: number;
showSelectSku: boolean, showSelectSku: boolean;
selectSkuItem: any, selectSkuItem: any;
addGroupIndex: any, addGroupIndex: any;
} }
interface RuleForm { interface RuleForm {
name: string, name: string;
shortTitle: string, shortTitle: string;
unitId: string, unitId: string;
categoryId: string, categoryId: string;
coverImg: string, coverImg: string;
images: string[], images: string[];
type: string, type: string;
specId: any, specId: any;
groupType: any, groupType: any;
skuList: string[], skuList: string[];
weight: any, weight: any;
isAllowTempModifyPrice: any, isAllowTempModifyPrice: any;
days: any, days: any;
useTime: string[], useTime: string[];
startTime: string, startTime: string;
endTime: string, endTime: string;
isSale: string, isSale: string;
isStock: string, isStock: string;
isHot: string, isHot: string;
stockNumber: any, stockNumber: any;
packFee: any, packFee: any;
sort: Number, sort: Number;
proGroupVo: any[], proGroupVo: any[];
selectSpecInfo: any selectSpecInfo: any;
} }
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>();
const ruleForm = reactive<RuleForm>({ const ruleForm = reactive<RuleForm>({
// //
name: '', name: "",
// //
shortTitle: '', shortTitle: "",
// id // id
unitId: '', unitId: "",
// id // id
categoryId: '', categoryId: "",
// url // url
coverImg: '', coverImg: "",
// urls // urls
images: [], images: [],
// //
type: 'single', type: "single",
// id // id
specId: '', specId: "",
// //
groupType: '0', groupType: "0",
// //
proGroupVo: [{ proGroupVo: [
title: '', {
count: '', title: "",
number: '', count: "",
goods: [] number: "",
}], goods: [],
},
],
// sku // sku
skuList: [], skuList: [],
// //
@ -382,10 +399,10 @@ const ruleForm = reactive<RuleForm>({
// //
isAllowTempModifyPrice: 1, isAllowTempModifyPrice: 1,
// //
days: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
useTime: ['00:00:00', '23:59:59'], useTime: ["00:00:00", "23:59:59"],
// //
startTime: '', startTime: "",
// //
endTime: "", endTime: "",
// //
@ -400,37 +417,34 @@ const ruleForm = reactive<RuleForm>({
packFee: 0, packFee: 0,
// //
sort: 1, sort: 1,
selectSpecInfo: {} selectSpecInfo: {},
}) });
const rules = reactive<FormRules<RuleForm>>({ const rules = reactive<FormRules<RuleForm>>({
name: [ name: [{ required: true, message: "请输入商品名称", trigger: "blur" }],
{ required: true, message: '请输入商品名称', trigger: 'blur' },
],
unitId: [ unitId: [
{ {
required: true, required: true,
message: '请选择单位', message: "请选择单位",
trigger: 'change', trigger: "change",
}, },
], ],
categoryId: [ categoryId: [
{ {
required: true, required: true,
message: '请选择商品分类', message: "请选择商品分类",
trigger: 'change', trigger: "change",
}, },
], ],
images: [ images: [
{ {
required: true, required: true,
message: '请选择图片', message: "请选择图片",
trigger: 'change', trigger: "change",
}, },
], ],
});
})
onMounted(() => { onMounted(() => {
getList() getList();
if (router.currentRoute.value.query.goods_id) { if (router.currentRoute.value.query.goods_id) {
tbProductGetDetail(router.currentRoute.value.query.goods_id); tbProductGetDetail(router.currentRoute.value.query.goods_id);
} }
@ -438,50 +452,51 @@ onMounted(() => {
watch(() => router.currentRoute.value.query.goods_id, (val) => { watch(() => router.currentRoute.value.query.goods_id, (val) => {
tbProductGetDetail(val); tbProductGetDetail(val);
}) })
async function tbProductGetDetail(id: any) { async function tbProductGetDetail(id: any) {
// //
const res = await UserAPI3.getDetail(id); const res = await UserAPI3.getDetail(id);
changeTypeEnum(res.type) changeTypeEnum(res.type);
for (const key in res) { for (const key in res) {
if (key !== 'images' && key !== 'days') { if (key !== "images" && key !== "days") {
(ruleForm as any)[key] = res[key]; (ruleForm as any)[key] = res[key];
} }
} }
ruleForm.images = res.images.map((item: any, index: number) => item); ruleForm.images = res.images.map((item: any, index: number) => item);
ruleForm.days = res.days.split(','); ruleForm.days = res.days.split(",");
ruleForm.useTime = [res.startTime, res.endTime]; ruleForm.useTime = [res.startTime, res.endTime];
ruleForm.proGroupVo = res.groupSnap ruleForm.proGroupVo = res.groupSnap;
if (res.type === "sku") { if (res.type === "sku") {
await tbProductSpecGet() await tbProductSpecGet();
selectSpecHandle(ruleForm.specId) selectSpecHandle(ruleForm.specId);
datas.selectSpeclist.forEach((item: any) => { datas.selectSpeclist.forEach((item: any) => {
item.selectSpecResult = res.selectSpecInfo[item.name] item.selectSpecResult = res.selectSpecInfo[item.name];
// if (item.name === res.selectSpecInfo.name // if (item.name === res.selectSpecInfo.name
// ) { } // ) { }
// item.children.forEach((ele: any) => { // item.children.forEach((ele: any) => {
// item.selectSpecResult.push(ele.name) // item.selectSpecResult.push(ele.name)
// }) // })
}) });
selectSpecResultChange() selectSpecResultChange();
} else { } else {
list.value = ruleForm.skuList list.value = ruleForm.skuList;
} }
} }
// sku // sku
function selectSkuHandle(item: any, index: number) { function selectSkuHandle(item: any, index: number) {
// false // false
datas.selectSkuItem.skuList.map((item: any, index: number) => { datas.selectSkuItem.skuList.map((item: any, index: number) => {
let nitem = { ...item } let nitem = { ...item };
nitem.active = false nitem.active = false;
datas.selectSkuItem.skuList[index] = nitem datas.selectSkuItem.skuList[index] = nitem;
}) });
if (item.active) { if (item.active) {
item.active = false item.active = false;
} else { } else {
item.active = true item.active = true;
} }
datas.selectSkuItem.skuList[index] = { ...item } datas.selectSkuItem.skuList[index] = { ...item };
// let arr = datas.selectSkuItem.skuList.filter((item:any) => item.active) // let arr = datas.selectSkuItem.skuList.filter((item:any) => item.active)
@ -492,35 +507,49 @@ function selectSkuHandle(item: any, index: number) {
// } // }
} }
function addimgEvent() { function addimgEvent() {
(addImg.value as any)?.show() if (isSyncStatus()) {
ElMessage.error('当前同步启用状态下不可修改')
return
}
(addImg.value as any)?.show();
} }
// //
function showSelectSkuConfirm() { function showSelectSkuConfirm() {
let item = datas.selectSkuItem.skuList.filter((item: any) => item.active) let item = datas.selectSkuItem.skuList.filter((item: any) => item.active);
ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex] = { ...ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex], skuId: item[0].id } ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex] = {
ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex] = { ...ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex], skuName: item[0].specInfo } ...ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex],
datas.showSelectSku = false skuId: item[0].id,
};
ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex] = {
...ruleForm.proGroupVo[datas.selectSkuTableIndex].goods[datas.selectSkuConfirmIndex],
skuName: item[0].specInfo,
};
datas.showSelectSku = false;
} }
// //
function showSelectSkuHandle(row: any, index: any, tabIndex: any) { function showSelectSkuHandle(row: any, index: any, tabIndex: any) {
datas.selectSkuTableIndex = tabIndex datas.selectSkuTableIndex = tabIndex;
datas.selectSkuConfirmIndex = index datas.selectSkuConfirmIndex = index;
datas.showSelectSku = true datas.showSelectSku = true;
let obj = { ...row } let obj = { ...row };
obj.skuList.map((item: any) => { obj.skuList.map((item: any) => {
item.active = false item.active = false;
}) });
datas.selectSkuItem = obj datas.selectSkuItem = obj;
} }
// //
function addgoods(index: number = -1) { function addgoods(index: number = -1) {
datas.addGroupIndex = index; datas.addGroupIndex = index;
(shopListRef.value as any)?.opens() (shopListRef.value as any)?.opens();
} }
function deleteEvent(d: any) { function deleteEvent(d: any) {
if (isSyncStatus()) {
ElMessage.error('当前同步启用状态下不可修改')
return
}
let index = ruleForm.images.findIndex((ele) => ele == d); let index = ruleForm.images.findIndex((ele) => ele == d);
ruleForm.images.splice(index, 1); ruleForm.images.splice(index, 1);
} }
@ -529,45 +558,45 @@ function successEvent(d: any) {
} }
// //
function selectShopRes(res: Array<any>) { function selectShopRes(res: Array<any>) {
let newres = res.map(item => { let newres = res.map((item) => {
item.proId = item.id item.proId = item.id;
item.proName = item.name item.proName = item.name;
item.price = item.lowPrice item.price = item.lowPrice;
item.skuId = item.skuList[0].id item.skuId = item.skuList[0].id;
item.skuName = '' item.skuName = "";
item.number = 1 item.number = 1;
// skuid // skuid
return item return item;
}) });
if (ruleForm.groupType == '0') { if (ruleForm.groupType == "0") {
let obj = { let obj = {
title: '', title: "",
count: newres.length, count: newres.length,
number: '', number: "",
goods: newres goods: newres,
} };
ruleForm.proGroupVo = [{ ...obj }] ruleForm.proGroupVo = [{ ...obj }];
} else { } else {
if (datas.addGroupIndex != -1) { if (datas.addGroupIndex != -1) {
ruleForm.proGroupVo[datas.addGroupIndex].count = newres.length ruleForm.proGroupVo[datas.addGroupIndex].count = newres.length;
ruleForm.proGroupVo[datas.addGroupIndex].goods = newres ruleForm.proGroupVo[datas.addGroupIndex].goods = newres;
} else { } else {
let arr = [...ruleForm.proGroupVo] let arr = [...ruleForm.proGroupVo];
arr.push({ arr.push({
title: '', title: "",
count: newres.length, count: newres.length,
number: '', number: "",
goods: newres goods: newres,
}) });
ruleForm.proGroupVo = [...arr] ruleForm.proGroupVo = [...arr];
} }
} }
} }
// //
async function getList() { async function getList() {
datas.Company = (await UserAPI2.getList(null)) as any[] datas.Company = (await UserAPI2.getList(null)) as any[];
datas.classification = (await UserAPI.getList(null)) as any[] datas.classification = (await UserAPI.getList(null)) as any[];
} }
// //
function selectSpecResultChange() { function selectSpecResultChange() {
@ -591,7 +620,7 @@ function createSkuHeader() {
// //
function addtaocan() { function addtaocan() {
datas.addGroupIndex = -1; datas.addGroupIndex = -1;
(shopListRef.value as any)?.opens() (shopListRef.value as any)?.opens();
} }
// //
function createSkuBody() { function createSkuBody() {
@ -621,7 +650,6 @@ function createSkuBody() {
for (let key in v) { for (let key in v) {
obj[`${key}`] = v[key]; obj[`${key}`] = v[key];
specSnap.push(v[key]); specSnap.push(v[key]);
} }
} }
let specSnapStr = specSnap.join(","); let specSnapStr = specSnap.join(",");
@ -649,18 +677,18 @@ function createSkuBody() {
} }
if (ruleForm.skuList.length) { if (ruleForm.skuList.length) {
if (isedit.value) { if (isedit.value) {
let arr: any[] = [] let arr: any[] = [];
ruleForm.skuList.forEach((item: any, index: number) => { ruleForm.skuList.forEach((item: any, index: number) => {
newarr.forEach((val: any, i: number) => { newarr.forEach((val: any, i: number) => {
if (item.specInfo == val.specInfo) { if (item.specInfo == val.specInfo) {
// newarr[i] = item // newarr[i] = item
Object.assign(val, item) Object.assign(val, item);
arr.push(val) arr.push(val);
} }
}); });
}); });
list.value = arr list.value = arr;
isedit.value = false isedit.value = false;
} else { } else {
list.value = newarr; list.value = newarr;
} }
@ -671,13 +699,13 @@ function createSkuBody() {
// //
function changeTypeEnum(item: string) { function changeTypeEnum(item: string) {
// single- sku- package- weight- coupon- // single- sku- package- weight- coupon-
list.value = [] list.value = [];
if (item == 'sku') { if (item == "sku") {
tbProductSpecGet(); tbProductSpecGet();
} else { } else {
ruleForm.specId = "" ruleForm.specId = "";
datas.selectSpeclist = [] datas.selectSpeclist = [];
list.value = [datas.defaultSku] list.value = [datas.defaultSku];
} }
} }
// //
@ -698,115 +726,112 @@ function cartesian(arr) {
// //
function typeChange() { function typeChange() {
// ruleForm.typeEnum = 'normal' // ruleForm.typeEnum = 'normal'
if (ruleForm.groupType == '0') { if (ruleForm.groupType == "0") {
ruleForm.proGroupVo = [] ruleForm.proGroupVo = [];
ruleForm.proGroupVo[0] = { ruleForm.proGroupVo[0] = {
title: '', title: "",
count: '', count: "",
number: 1, number: 1,
goods: [] goods: [],
} };
} else { } else {
ruleForm.proGroupVo = [] ruleForm.proGroupVo = [];
} }
// this.changeTypeEnum() // this.changeTypeEnum()
} }
// //
async function tbProductSpecGet() { async function tbProductSpecGet() {
datas.specificationsconfig = (await UserAPI4.getPage(null)) as [] datas.specificationsconfig = (await UserAPI4.getPage(null)) as [];
} }
// //
function selectSpecHandle(e: any) { function selectSpecHandle(e: any) {
const selectSpec = JSON.parse(JSON.stringify(datas.specificationsconfig.find((item) => item.id == e).children)); const selectSpec = JSON.parse(
JSON.stringify(datas.specificationsconfig.find((item) => item.id == e).children)
);
for (let item in selectSpec) { for (let item in selectSpec) {
selectSpec[item].selectSpecResult = []; selectSpec[item].selectSpecResult = [];
} }
datas.selectSpeclist = selectSpec; datas.selectSpeclist = selectSpec;
} }
const specificationAttributeRef = ref(null) const specificationAttributeRef = ref(null);
const submitForm = async (formEl: FormInstance | undefined) => { const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return;
await formEl.validate(async (valid, fields) => { await formEl.validate(async (valid, fields) => {
if (valid) { if (valid) {
ruleForm.days = ruleForm.days.join(',')
// //
ruleForm.coverImg = ruleForm.images[0] ruleForm.coverImg = ruleForm.images[0];
// id // id
// ruleForm.specId = specIdFunction(ruleForm.type) // ruleForm.specId = specIdFunction(ruleForm.type)
let selectTitle = false let selectTitle = false;
ruleForm.proGroupVo.forEach((item: any) => { ruleForm.proGroupVo.forEach((item: any) => { });
})
if (selectTitle) { if (selectTitle) {
ElMessage.error('请填写组名和几选几') ElMessage.error("请填写组名和几选几");
return return;
} }
//
ruleForm.startTime = ruleForm.useTime[0]
ruleForm.endTime = ruleForm.useTime[1]
// sku // sku
ruleForm.skuList = (specificationAttributeRef.value as any)?.getdata() ruleForm.skuList = (specificationAttributeRef.value as any)?.getdata();
// selectSpecInfo // selectSpecInfo
if (ruleForm.type == 'sku') { if (ruleForm.type == "sku") {
let obj: any = {} let obj: any = {};
datas.selectSpeclist.forEach((item: any) => { datas.selectSpeclist.forEach((item: any) => {
obj[item.name] = item.selectSpecResult obj[item.name] = item.selectSpecResult;
}) });
ruleForm.selectSpecInfo = obj ruleForm.selectSpecInfo = obj;
} else if (ruleForm.type == 'package') { } else if (ruleForm.type == "package") {
// console.log(ruleForm, '') // console.log(ruleForm, '')
} }
setTimeout(() => {
ruleForm.days = ruleForm.days.split(',')
}, 200);
// //
if (ruleForm.type == "package") { if (ruleForm.type == "package") {
if (ruleForm.groupType == '1') { if (ruleForm.groupType == "1") {
let selectTitle = false let selectTitle = false;
ruleForm.proGroupVo.forEach((item: any) => { ruleForm.proGroupVo.forEach((item: any) => {
if (item.number == '' || item.title == '') { if (item.number == "" || item.title == "") {
selectTitle = true selectTitle = true;
} }
}) });
if (selectTitle) { if (selectTitle) {
ElMessage.error('请填写组名和几选几') ElMessage.error("请填写组名和几选几");
return return;
} }
} }
} }
ruleForm.days = ruleForm.days.join(',')
setTimeout(() => {
ruleForm.days = ruleForm.days.split(",");
}, 200);
if (ruleForm.type == 'weight') { if (ruleForm.type == "weight") {
ruleForm.specId = '' ruleForm.specId = "";
} }
if (ruleForm.id) { if (ruleForm.id) {
let res = await UserAPI3.update(ruleForm) let res = await UserAPI3.update(ruleForm);
if (res.code == 200) { if (res.code == 200) {
ElMessage.success("修改成功"); ElMessage.success("修改成功");
} }
} else { } else {
let res = await UserAPI3.addunit(ruleForm);
let res = await UserAPI3.addunit(ruleForm)
if (res.code == 200) { if (res.code == 200) {
ElMessage.success("添加成功"); ElMessage.success("添加成功");
} }
} }
setTimeout(() => { setTimeout(() => {
closeSelectedTag({ closeSelectedTag({
"name": "addgoods", name: "addgoods",
"title": "新增商品", title: "新增商品",
"path": "/product/addgoods", path: "/product/addgoods",
"fullPath": "/product/addgoods", fullPath: "/product/addgoods",
}) });
}, 500); }, 500);
setTimeout(() => { setTimeout(() => {
router.push({ path: '/product/index' }); router.push({ path: "/product/index" });
}, 1000); }, 1000);
} else { } else {
ElMessage.error("请填写完整信息"); ElMessage.error("请填写完整信息");
console.log('error submit!', fields) console.log("error submit!", fields);
} }
}) });
} };
// //
function closeSelectedTag(view: TagView) { function closeSelectedTag(view: TagView) {
@ -818,31 +843,31 @@ function closeSelectedTag(view: TagView) {
} }
// id // id
const specIdFunction = (type: string) => { const specIdFunction = (type: string) => {
if (type === 'single') { if (type === "single") {
return '' return "";
} else if (type === '2') { } else if (type === "2") {
return 2 return 2;
} else if (type === '3') { } else if (type === "3") {
return 3 return 3;
} else if (type === '4') { } else if (type === "4") {
return 4 return 4;
} else if (type === '5') { } else if (type === "5") {
return 5 return 5;
} }
} };
const resetForm = (formEl: FormInstance | undefined) => { const resetForm = (formEl: FormInstance | undefined) => {
closeSelectedTag({ closeSelectedTag({
"name": "addgoods", name: "addgoods",
"title": "新增商品", title: "新增商品",
"path": "/product/addgoods", path: "/product/addgoods",
"fullPath": "/product/addgoods", fullPath: "/product/addgoods",
"affix": false, affix: false,
"keepAlive": true, keepAlive: true,
"query": {} query: {},
}) });
if (!formEl) return if (!formEl) return;
formEl.resetFields() formEl.resetFields();
} };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.addgoods { .addgoods {
@ -865,7 +890,7 @@ const resetForm = (formEl: FormInstance | undefined) => {
} }
.tag { .tag {
background-color: #F7F7FA; background-color: #f7f7fa;
padding: 6px 12px; padding: 6px 12px;
margin-right: 10px; margin-right: 10px;
border-radius: 4px; border-radius: 4px;
@ -876,7 +901,7 @@ const resetForm = (formEl: FormInstance | undefined) => {
} }
&.active { &.active {
background-color: #46A6FF; background-color: #46a6ff;
color: #fff; color: #fff;
} }
} }
@ -886,7 +911,7 @@ const resetForm = (formEl: FormInstance | undefined) => {
.group_wrap { .group_wrap {
padding: 20px; padding: 20px;
background-color: #F7F7FA; background-color: #f7f7fa;
margin-bottom: 20px; margin-bottom: 20px;
} }

View File

@ -58,7 +58,20 @@ const contentConfig: IContentConfig<UserPageQuery> = {
}, },
pk: "id", pk: "id",
toolbar: [ toolbar: [
"add", {
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
{
icon: "refresh",
text: "同步",
type: "danger",
name: "sync",
auth: "import",
},
{ {
icon: "edit", icon: "edit",
text: "库存预警", text: "库存预警",
@ -66,6 +79,7 @@ const contentConfig: IContentConfig<UserPageQuery> = {
name: "custom1", name: "custom1",
auth: "import", auth: "import",
}, },
], ],
cols: [ cols: [
// { type: "selection", width: 50, align: "center" }, // { type: "selection", width: 50, align: "center" },
@ -113,7 +127,7 @@ const contentConfig: IContentConfig<UserPageQuery> = {
fixed: "right", fixed: "right",
width: 280, width: 280,
templet: "tool", templet: "tool",
operat: [{ text: "报损" }, "edit", "delete"], operat: [{ text: "报损", name: ''}, { text: "编辑", icon: 'edit', name: "edit"}, { text: "删除", icon: 'delete', type: 'danger', name: "delete"}],
}, },
], ],
}; };

View File

@ -29,10 +29,10 @@
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" /> <copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
</template> </template>
<template #operates="scope"> <template #operates="scope">
<el-button type="text" size="small" v-if="scope.row.level < 3" <el-button type="text" size="small" v-if="scope.row.level < 3&&!isSyncStatus()"
@click="addlowerLevel(scope.row)">添加下一级</el-button> @click="addlowerLevel(scope.row)">添加下一级</el-button>
<el-button type="text" size="small" @click="handleEditClick(scope.row)">编辑</el-button> <el-button type="text" size="small" v-if="!isSyncStatus()" @click="handleEditClick(scope.row)">编辑</el-button>
<el-button type="text" size="small" @click="deleteClick(scope.row)">删除</el-button> <el-button type="text" size="small" v-if="!isSyncStatus()" @click="deleteClick(scope.row)">删除</el-button>
</template> </template>
</page-content> </page-content>
<!-- 添加下一级-编辑 --> <!-- 添加下一级-编辑 -->
@ -123,6 +123,8 @@ import contentConfig2 from "./specificationsconfig/content2";
import editModalConfig from "./specificationsconfig/edit"; import editModalConfig from "./specificationsconfig/edit";
import searchConfig from "./specificationsconfig/search"; import searchConfig from "./specificationsconfig/search";
import { pid } from "process"; import { pid } from "process";
import { isSyncStatus } from "@/utils/index";
const validateSku1 = (rule, value, callback) => { const validateSku1 = (rule, value, callback) => {
if (!datas.skuForm.label) { if (!datas.skuForm.label) {
callback(new Error(' ')) callback(new Error(' '))
@ -190,6 +192,12 @@ let datas = reactive({
addchilderinfo: {} addchilderinfo: {}
}) })
let myDialogRef = ref(null) let myDialogRef = ref(null)
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true
} else {
contentConfig.toolbar[0].hidden = false
}
function subitgood() { function subitgood() {
skuForm.value.validate(async valid => { skuForm.value.validate(async valid => {
if (valid) { if (valid) {

View File

@ -41,7 +41,13 @@ const contentConfig: IContentConfig<UserPageQuery> = {
// }, // },
pk: "id", pk: "id",
toolbar: [ toolbar: [
"add", {
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
], ],
cols: [ cols: [
// { type: "selection", width: 50, align: "center" }, // { type: "selection", width: 50, align: "center" },

View File

@ -61,6 +61,7 @@ import contentConfig from "./unitconfig/content";
import contentConfig2 from "./unitconfig/content2"; import contentConfig2 from "./unitconfig/content2";
import editModalConfig from "./unitconfig/edit"; import editModalConfig from "./unitconfig/edit";
import searchConfig from "./unitconfig/search"; import searchConfig from "./unitconfig/search";
import { isSyncStatus } from "@/utils/index";
const { const {
searchRef, searchRef,
@ -77,6 +78,16 @@ const {
handleFilterChange, handleFilterChange,
} = usePage(); } = usePage();
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = true
} else {
contentConfig.toolbar[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = false
}
// //
async function handleAddClick() { async function handleAddClick() {
addModalRef.value?.setModalVisible(); addModalRef.value?.setModalVisible();

View File

@ -38,7 +38,13 @@ const contentConfig: IContentConfig<UserPageQuery> = {
}, },
pk: "id", pk: "id",
toolbar: [ toolbar: [
"add", {
icon: "plus",
text: "新增",
type: "primary",
name: "add",
auth: "import",
},
], ],
cols: [ cols: [
// { type: "selection", width: 50, align: "center" }, // { type: "selection", width: 50, align: "center" },
@ -50,7 +56,7 @@ const contentConfig: IContentConfig<UserPageQuery> = {
fixed: "right", fixed: "right",
width: 280, width: 280,
templet: "tool", templet: "tool",
operat: ["edit", "delete"], operat: [{ text: "编辑", icon: 'edit', name: "edit"}, { text: "删除", icon: 'delete', type: 'danger', name: "delete"}],
}, },
], ],
}; };

View File

@ -0,0 +1,196 @@
<template>
<div class="app-container">
<div class="head-container">
<el-card shadow="never">
<el-row :gutter="20">
<el-col :span="4">
<el-input v-model="state.query.name" clearable placeholder="请输入分店名称" style="width: 100%" class="filter-item"
@keyup.enter="getTableData" />
</el-col>
<el-col :span="16">
<el-button type="primary" @click="getTableData">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
<span style="margin-left: 30px;">设置同步方式</span>
<el-select v-model="state.par.dataSyncMethod" @change="setDataSync" placeholder="请设置同步方式"
style="width: 200px">
<el-option v-for="item in state.status" :key="item.type" :label="item.label" :value="item.type" />
</el-select>
</el-col>
</el-row>
</el-card>
</div>
<div class="head-container">
<el-card shadow="never">
<el-table v-loading="state.tableData.loading" :data="state.tableData.list">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column label="店铺信息">
<template v-slot="scope">
<div>{{ scope.row.shopName }}{{ scope.row.shopType == 'chain' ? '(连锁店)' : scope.row.shopType == 'join' ? '(加盟店)' : '' }}</div>
<div>账号{{ scope.row.account }}</div>
<div>联系电话{{ scope.row.phone }}</div>
</template>
</el-table-column>
<el-table-column prop="isEnableProdSync" label="商品同步" width="120">
<template v-slot="scope">
<el-tag :type="scope.row.isEnableProdSync == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isEnableProdSync == 1 ? '启用' : '禁用' }} </el-tag>
</template>
</el-table-column>
<el-table-column prop="isEnableVipSync" label="会员同步" width="120">
<template v-slot="scope">
<el-tag :type="scope.row.isEnableVipSync == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isEnableVipSync == 1 ? '启用' : '禁用' }} </el-tag>
</template>
</el-table-column>
<el-table-column prop="isEnableConsSync" label="耗材同步" width="120">
<template v-slot="scope">
<el-tag :type="scope.row.isEnableConsSync == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isEnableConsSync == 1 ? '启用' : '禁用' }} </el-tag>
</template>
</el-table-column>
<el-table-column prop="isAllowAccountLogin" label="账号状态" width="120">
<template v-slot="scope">
<el-tag :type="scope.row.isAllowAccountLogin == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isAllowAccountLogin == 1 ? '启用' : '禁用' }} </el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="备注" />
<el-table-column label="操作" width="200">
<template v-slot="scope">
<el-button v-if="!scope.row.isEnableProdSync || !scope.row.isEnableVipSync || !scope.row.isEnableConsSync"
type="primary" size="small" link icon="edit" @click="handleSync(scope.row)">
同步启用
</el-button>
<el-button type="primary" size="small" link icon="edit" @click="handleAccount(scope.row)">
{{ scope.row.isAllowAccountLogin ? '账号禁用' : '账号启用' }}
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<div class="head-container">
<el-pagination v-model:current-page="state.tableData.page" v-model:page-size="state.tableData.size"
:total="state.tableData.total" :page-sizes="[10, 20, 30, 50, 100]"
layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
</div>
</div>
</template>
<script setup>
import dayjs from "dayjs";
import ShopBranchApi from "@/api/account/shopBranch";
import { ElNotification, ElMessageBox } from "element-plus";
const state = reactive({
query: {
name: "",
},
par: {
dataSyncMethod: '',
},
status: [
{ type: 'auto', label: "实时自动同步", },
{ type: 'manual', label: "手动同步", }
],
tableData: {
list: [],
page: 1,
size: 10,
loading: false,
total: 0,
},
});
onMounted(() => {
getTableData();
getDataSync()
});
async function getDataSync () {
let res = await ShopBranchApi.getDataSync()
state.par.dataSyncMethod = res
}
//
async function getTableData() {
state.tableData.loading = true;
try {
const res = await ShopBranchApi.getList({
page: state.tableData.page,
size: state.tableData.size,
branchShopName: state.query.name,
});
state.tableData.loading = false;
state.tableData.list = res.records;
state.tableData.total = res.totalRow * 1;
} catch (error) {
console.log(error);
}
}
//
async function setDataSync() {
await ShopBranchApi.setDataSync(state.par.dataSyncMethod);
ElMessage({
type: "success",
message: "设置成功",
});
}
//
function handleSync(e) {
console.log(e)
ElMessageBox.confirm(`同步功能开启后不能关闭,请确认是否给${e.shopName}开启同步?`, "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
await ShopBranchApi.dataSync(e.id)
ElMessage({
type: "success",
message: "同步成功",
});
getTableData();
}).catch(() => { });
}
// /
async function handleAccount(row) {
if (row.isAllowAccountLogin) {
await ShopBranchApi.disable(row.id);
} else {
await ShopBranchApi.enable(row.id);
}
getTableData();
}
//
function resetHandle() {
state.query.name = "";
getTableData();
}
//
function paginationChange(e) {
state.tableData.page = e;
getTableData();
}
</script>
<style scoped lang="scss">
.head-container {
margin-bottom: 20px;
}
.shop_info {
display: flex;
.info {
flex: 1;
padding-left: 4px;
}
}
.el-link {
min-height: 23px;
margin: 0 5px;
}
</style>

View File

@ -1,44 +1,31 @@
<template> <template>
<el-dialog <el-dialog :title="state.form.id ? '编辑店铺' : '添加店铺'" v-model="state.dialogVisible" @close="reset">
:title="state.form.id ? '编辑店铺' : '添加店铺'"
v-model="state.dialogVisible"
@close="reset"
>
<div style="height: 50vh; overflow-y: auto"> <div style="height: 50vh; overflow-y: auto">
<el-form <el-form ref="refForm" :model="state.form" :rules="state.rules" label-width="120px" label-position="left">
ref="refForm"
:model="state.form"
:rules="state.rules"
label-width="120px"
label-position="left"
>
<el-form-item label="店铺名称" prop="shopName"> <el-form-item label="店铺名称" prop="shopName">
<el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input> <el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="店铺类型"> <el-form-item label="店铺类型">
<el-radio-group v-model="state.form.shopType"> <el-radio-group v-model="state.form.shopType" :disabled="state.isEdit || state.type == 'addBranch'">
<el-radio-button value="only">单店</el-radio-button> <el-radio-button value="only">单店</el-radio-button>
<el-radio-button value="chain">连锁店</el-radio-button> <el-radio-button value="chain">连锁店</el-radio-button>
<el-radio-button value="join">加盟店</el-radio-button> <el-radio-button value="join">加盟店</el-radio-button>
</el-radio-group> </el-radio-group>
<div class="tips">请谨慎修改</div> <div class="tips"><el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false"/></div>
</el-form-item> </el-form-item>
<el-form-item label="主店账号" prop="mainId" v-if="state.form.shopType != 'only'"> <el-form-item label="是否为主店" prop="isHeadShop" v-if="state.form.shopType != 'only'">
<el-select <el-radio-group v-model="state.form.isHeadShop" @change=" state.form.mainId = ''" :disabled="state.isEdit || state.type == 'addBranch'">
v-model="state.form.mainId" <el-radio :value="1"></el-radio>
placeholder="请选择主店铺" <el-radio :value="0"></el-radio>
filterable </el-radio-group>
remote </el-form-item>
reserve-keyword <el-form-item label="选择主店" prop="mainId" v-if="state.form.isHeadShop == '0'&&state.form.shopType != 'only'">
:remote-method="getTableData" <!-- <el-form-item label="主店账号" prop="mainId" v-if="state.form.shopType != 'only'"> -->
:loading="state.shopListLoading" <el-select v-model="state.form.mainId" placeholder="请选择主店铺" filterable reserve-keyword
> :remote-method="getTableData" :loading="state.shopListLoading" :disabled="state.isEdit || state.type == 'addBranch'">
<el-option <el-option v-for="item in state.shopList" :label="`${item.shopName}`" :value="item.id"
v-for="item in state.shopList" :key="item.id"></el-option>
:label="`ID:${item.id} - 名称:${item.shopName}`"
:value="item.id"
:key="item.id"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="连锁店扩展店名"> <el-form-item label="连锁店扩展店名">
@ -55,14 +42,16 @@
<el-radio-button value="before">先付费</el-radio-button> <el-radio-button value="before">先付费</el-radio-button>
<el-radio-button value="after">后付费</el-radio-button> <el-radio-button value="after">后付费</el-radio-button>
</el-radio-group> </el-radio-group>
<div class="tips">请谨慎修改</div> <div class="tips"><el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false"/></div>
</el-form-item> </el-form-item>
<el-form-item label="管理方式" v-if="state.form.shopType != 'only'"> <el-form-item label="管理方式" v-if="state.form.shopType != 'only'">
<el-radio-group v-model="state.form.tube_type"> <el-radio-group v-model="state.form.tubeType">
<el-radio-button value="0">不可直接管理</el-radio-button> <el-radio-button :value="0">不可直接管理</el-radio-button>
<el-radio-button value="1">直接管理</el-radio-button> <el-radio-button :value="1">直接管理</el-radio-button>
</el-radio-group> </el-radio-group>
<div class="tips">请谨慎修改</div> <div class="tips"><el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false"/></div>
</el-form-item> </el-form-item>
<el-form-item label="试用/正式"> <el-form-item label="试用/正式">
<el-radio-group v-model="state.form.profiles"> <el-radio-group v-model="state.form.profiles">
@ -78,24 +67,14 @@
<el-input v-model="state.form.accountName" placeholder="请输入登录账号"></el-input> <el-input v-model="state.form.accountName" placeholder="请输入登录账号"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="登录密码" prop="password" v-if="!state.form.id"> <el-form-item label="登录密码" prop="password" v-if="!state.form.id">
<el-input <el-input type="password" show-password v-model="state.form.accountPwd" placeholder="请输入登录密码"></el-input>
type="password"
show-password
v-model="state.form.accountPwd"
placeholder="请输入登录密码"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="联系电话" prop="phone"> <el-form-item label="联系电话" prop="phone">
<el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input> <el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="设备数量"> <el-form-item label="设备数量">
<el-input-number <el-input-number v-model="state.form.supportDeviceNumber" controls-position="right" :min="1" :step="1"
v-model="state.form.supportDeviceNumber" step-strictly></el-input-number>
controls-position="right"
:min="1"
:step="1"
step-strictly
></el-input-number>
</el-form-item> </el-form-item>
<!-- <el-form-item label="外卖起送金额"> <!-- <el-form-item label="外卖起送金额">
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right" <el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
@ -104,10 +83,7 @@
<el-form-item label="店铺经度" prop="lat"> <el-form-item label="店铺经度" prop="lat">
<el-row> <el-row>
<el-col :span="9" v-if="state.form.provinces"> <el-col :span="9" v-if="state.form.provinces">
<el-input <el-input :value="`${state.form.provinces}-${state.form.cities}-${state.form.districts}`" disabled />
:value="`${state.form.provinces}-${state.form.cities}-${state.form.districts}`"
disabled
/>
</el-col> </el-col>
<el-col :span="4" v-if="state.form.lng"> <el-col :span="4" v-if="state.form.lng">
<el-input v-model="state.form.lng" placeholder="经度" disabled></el-input> <el-input v-model="state.form.lng" placeholder="经度" disabled></el-input>
@ -123,18 +99,10 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="店铺详细地址"> <el-form-item label="店铺详细地址">
<el-input <el-input type="textarea" v-model="state.form.address" placeholder="请输入门店详细地址"></el-input>
type="textarea"
v-model="state.form.address"
placeholder="请输入门店详细地址"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="店铺简介"> <el-form-item label="店铺简介">
<el-input <el-input type="textarea" v-model="state.form.detail" placeholder="请输入店铺简介"></el-input>
type="textarea"
v-model="state.form.detail"
placeholder="请输入店铺简介"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="状态"> <el-form-item label="状态">
<el-radio-group v-model="state.form.status"> <el-radio-group v-model="state.form.status">
@ -144,12 +112,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<el-dialog <el-dialog title="选择地址" v-model="state.showLocation" :modal="false" :modal-append-to-body="false">
title="选择地址"
v-model="state.showLocation"
:modal="false"
:modal-append-to-body="false"
>
<div class="map_box"> <div class="map_box">
<div class="map"> <div class="map">
<el-amap ref="map" :center="state.amapOptions.center" @init="mapInit"> <el-amap ref="map" :center="state.amapOptions.center" @init="mapInit">
@ -157,13 +120,8 @@
</el-amap> </el-amap>
</div> </div>
<div class="search_box"> <div class="search_box">
<el-input <el-input v-model="state.searchOption.keyword" placeholder="请输入关键字" @focus="state.searchOption.focus = true"
v-model="state.searchOption.keyword" @blur="autoCompleteSearchBlur" @input="autoCompleteSearch(state.searchOption.keyword)">
placeholder="请输入关键字"
@focus="state.searchOption.focus = true"
@blur="autoCompleteSearchBlur"
@input="autoCompleteSearch(state.searchOption.keyword)"
>
<template #append> <template #append>
<el-button type="primary" @click="placeSearchSearch(state.searchOption.keyword)"> <el-button type="primary" @click="placeSearchSearch(state.searchOption.keyword)">
搜索 搜索
@ -171,12 +129,8 @@
</template> </template>
</el-input> </el-input>
<div class="list" v-if="state.searchOption.focus && state.searchOption.show"> <div class="list" v-if="state.searchOption.focus && state.searchOption.show">
<div <div class="item" @click="autoCompleteListClick(item)" v-for="item in state.autoCompleteList"
class="item" :key="item.id">
@click="autoCompleteListClick(item)"
v-for="item in state.autoCompleteList"
:key="item.id"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
@ -234,11 +188,11 @@ const state = reactive({
endTime: "", endTime: "",
formLoading: false, formLoading: false,
form: { form: {
id: "", id: null,
shopName: "", shopName: "",
mainId: "", mainId: "",
shopType: "only", shopType: "only",
tube_type: "0", tubeType: 0,
registerType: "before", registerType: "before",
profiles: "release", profiles: "release",
activateCode: "", activateCode: "",
@ -257,7 +211,9 @@ const state = reactive({
cities: "", cities: "",
districts: "", districts: "",
chainName: "", chainName: "",
isHeadShop: 0,
}, },
type: '',
resetForm: "", resetForm: "",
rules: { rules: {
activateCode: [ activateCode: [
@ -274,6 +230,13 @@ const state = reactive({
trigger: "blur", trigger: "blur",
}, },
], ],
isHeadShop: [
{
required: true,
message: " ",
trigger: "blur",
},
],
mainId: [ mainId: [
{ {
required: true, required: true,
@ -337,6 +300,7 @@ const state = reactive({
}, },
shopListLoading: false, shopListLoading: false,
shopList: [], shopList: [],
isEdit: false,
}); });
onBeforeMount(async () => { onBeforeMount(async () => {
const res = await initMapLoad(); const res = await initMapLoad();
@ -347,6 +311,7 @@ onMounted(() => {
// //
async function getTableData(query = "") { async function getTableData(query = "") {
console.log(123)
state.shopListLoading = true; state.shopListLoading = true;
try { try {
const res = await ShopApi.getList({ const res = await ShopApi.getList({
@ -354,9 +319,10 @@ async function getTableData(query = "") {
size: 100, size: 100,
shopName: query, shopName: query,
type: "only", type: "only",
isHeadShop: 1,
}); });
state.shopListLoading = false; state.shopListLoading = false;
state.shopList = res.content; state.shopList = res.records;
} catch (error) { } catch (error) {
state.shopListLoading = false; state.shopListLoading = false;
console.log(error); console.log(error);
@ -394,6 +360,7 @@ function submitHandle() {
type: "success", type: "success",
}); });
close(); close();
location.reload()
} catch (error) { } catch (error) {
state.formLoading = false; state.formLoading = false;
console.log(error); console.log(error);
@ -409,13 +376,24 @@ function handleSuccess(response, file, fileList) {
state.files = response.data; state.files = response.data;
} }
function show(obj) { function show(obj,type) {
getTableData(); getTableData();
state.dialogVisible = true; state.dialogVisible = true;
if (obj && obj.id) { if (obj && obj.id) {
console.log(obj); console.log(obj);
state.form = { ...obj }; state.form = { ...obj };
} }
if (obj && obj.mainId) {
Object.assign(state.form, obj);
}
if( type ){
state.type = type
}
console.log(state.form);
console.log(state.type);
if( state.form.shopType != 'only'){
state.isEdit = true
}
for (let key in state.rules) { for (let key in state.rules) {
if (key === "accountName") { if (key === "accountName") {
if (obj.id) { if (obj.id) {
@ -429,9 +407,14 @@ function show(obj) {
} }
function close() { function close() {
state.dialogVisible = false; state.dialogVisible = false;
state.form = { ...state.resetForm };
state.type = "";
state.isEdit = false
} }
function reset() { function reset() {
state.form = { ...state.resetForm }; state.form = { ...state.resetForm };
state.type = "";
state.isEdit = false
} }
let ElMap = undefined; let ElMap = undefined;
@ -525,14 +508,17 @@ defineExpose({
top: 10px; top: 10px;
left: 10px; left: 10px;
z-index: 3000; z-index: 3000;
.list { .list {
background-color: #fff; background-color: #fff;
.item { .item {
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
padding: 0 10px; padding: 0 10px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background-color: #eee; background-color: #eee;
} }
@ -565,4 +551,7 @@ defineExpose({
.amap-sug-result { .amap-sug-result {
z-index: 2000; z-index: 2000;
} }
.tips{
margin-left: 10px;
}
</style> </style>

View File

@ -3,33 +3,16 @@
<div class="head-container"> <div class="head-container">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="3"> <el-col :span="3">
<el-input <el-input v-model="state.query.name" clearable placeholder="请输入店铺名称" style="width: 100%" class="filter-item"
v-model="state.query.name" @keyup.enter="getTableData" />
clearable
placeholder="请输入店铺名称"
style="width: 100%"
class="filter-item"
@keyup.enter="getTableData"
/>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<el-input <el-input v-model="state.query.account" clearable placeholder="请输入商户号" style="width: 100%" class="filter-item"
v-model="state.query.account" @keyup.enter="getTableData" />
clearable
placeholder="请输入商户号"
style="width: 100%"
class="filter-item"
@keyup.enter="getTableData"
/>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<el-select v-model="state.query.status" placeholder="请选择店铺状态" style="width: 100%"> <el-select v-model="state.query.status" placeholder="请选择店铺状态" style="width: 100%">
<el-option <el-option v-for="item in state.status" :key="item.type" :label="item.label" :value="item.type" />
:label="item.label"
:value="item.type"
v-for="item in state.status"
:key="item.type"
/>
</el-select> </el-select>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
@ -42,33 +25,31 @@
<el-button type="primary" icon="plus" @click="addShopShow">添加店铺</el-button> <el-button type="primary" icon="plus" @click="addShopShow">添加店铺</el-button>
</div> </div>
<div class="head-container"> <div class="head-container">
<el-table :data="state.tableData.list" v-loading="state.tableData.loading"> <el-table v-loading="state.tableData.loading" :data="state.tableData.list">
<el-table-column label="店铺信息" width="200"> <el-table-column label="店铺信息" width="200">
<template v-slot="scope"> <template v-slot="scope">
<div class="shop_info"> <div class="shop_info">
<el-image <el-image :src="scope.row.logo"
:src="scope.row.logo" style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef">
style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef"
>
<template #error> <template #error>
<div class="img_error"> <div class="img_error">
<i class="icon el-icon-document-delete"></i> <i class="icon el-icon-document-delete" />
</div> </div>
</template> </template>
</el-image> </el-image>
<div class="info"> <div class="info">
<span>{{ scope.row.shopName }}</span> <span>{{ scope.row.shopName }}</span>
<div class="tag_wrap"> <div class="tag_wrap">
<el-tag type="info" effect="dark" v-if="scope.row.profiles == 'no'"> <el-tag v-if="scope.row.profiles == 'no'" type="info" effect="dark">
未激活 未激活
</el-tag> </el-tag>
<el-tag type="warning" effect="dark" v-if="scope.row.profiles == 'probation'"> <el-tag v-if="scope.row.profiles == 'probation'" type="warning" effect="dark">
试用 试用
</el-tag> </el-tag>
<el-tag type="success" effect="dark" v-if="scope.row.profiles == 'release'"> <el-tag v-if="scope.row.profiles == 'release'" type="success" effect="dark">
正式 正式
</el-tag> </el-tag>
<el-tag type="primary" effect="dark" v-if="scope.row.isWxMaIndependent"> <el-tag v-if="scope.row.isWxMaIndependent" type="primary" effect="dark">
独立小程序 独立小程序
</el-tag> </el-tag>
</div> </div>
@ -76,23 +57,26 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="registerType" label="类型"> <el-table-column prop="registerType" label="经营模式">
<template v-slot="scope"> <template v-slot="scope">
<span v-if="scope.row.registerType == 'before'">快餐版</span> <span v-if="scope.row.registerType == 'before'">快餐版</span>
<span v-if="scope.row.registerType == 'after'">餐饮版</span> <span v-if="scope.row.registerType == 'after'">餐饮版</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="address" label="商户号"></el-table-column> <el-table-column prop="address" label="商户号" />
<el-table-column prop="lowPrice" label="来源"></el-table-column> <el-table-column prop="status" label="店铺类型" align="center">
<el-table-column prop="lowPrice" label="认证状态">-</el-table-column> <template v-slot="scope">
<div>
<span v-if="scope.row.shopType == 'only'">单店</span>
<span v-if="scope.row.shopType == 'chain'">连锁店</span>
<span v-if="scope.row.shopType == 'join'">加盟店</span>
<div v-if="scope.row.shopType != 'only'&&scope.row.isHeadShop == 0">(主店{{ scope.row.headShopName }})</div>
</div>
</template>
</el-table-column>
<el-table-column prop="status" label="店铺状态"> <el-table-column prop="status" label="店铺状态">
<template v-slot="scope"> <template v-slot="scope">
<el-switch <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" disabled />
v-model="scope.row.status"
:active-value="1"
:inactive-value="0"
disabled
></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createdAt" label="到期时间"> <el-table-column prop="createdAt" label="到期时间">
@ -106,21 +90,28 @@
<el-table-column label="操作" width="200"> <el-table-column label="操作" width="200">
<template v-slot="scope"> <template v-slot="scope">
<el-link @click="addShopShow(scope.row)"> <el-link @click="addShopShow(scope.row)">
<el-icon><Edit /></el-icon> <el-icon>
<Edit />
</el-icon>
编辑 编辑
</el-link> </el-link>
<el-link @click="activateCodeShow(scope.row)"> <el-link @click="activateCodeShow(scope.row)">
<el-icon><Edit /></el-icon> <el-icon>
<Edit />
</el-icon>
激活 激活
</el-link> </el-link>
<el-dropdown @command="dropdownClick($event, scope.row)"> <el-dropdown @command="dropdownClick($event, scope.row)">
<el-link> <el-link>
更多 更多
<el-icon><ArrowDown /></el-icon> <el-icon>
<ArrowDown />
</el-icon>
</el-link> </el-link>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item v-if="scope.row.isHeadShop == 1" :command="0">添加分店</el-dropdown-item>
<el-dropdown-item :command="{ row: scope.row, command: 1 }"> <el-dropdown-item :command="{ row: scope.row, command: 1 }">
三方配置 三方配置
</el-dropdown-item> </el-dropdown-item>
@ -136,14 +127,9 @@
</el-table> </el-table>
</div> </div>
<div class="head-container"> <div class="head-container">
<el-pagination <el-pagination v-model:current-page="state.tableData.page" v-model:page-size="state.tableData.size"
:total="state.tableData.total" :total="state.tableData.total" :page-sizes="[10, 20, 30, 50, 100]"
v-model:current-page="state.tableData.page" layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
v-model:page-size="state.tableData.size"
:page-sizes="[10, 20, 30, 50, 100]"
@current-change="paginationChange"
layout="total, sizes , prev, pager ,next, jumper "
></el-pagination>
</div> </div>
<addShop ref="refAddShop" @success="getTableData" /> <addShop ref="refAddShop" @success="getTableData" />
<detailModal ref="refDetailModal" /> <detailModal ref="refDetailModal" />
@ -199,6 +185,11 @@ const refDetailModal = ref(null);
function dropdownClick(e, row) { function dropdownClick(e, row) {
console.log(e); console.log(e);
console.log(row); console.log(row);
if (e == 0) {
refAddShop.value.show({mainId:row.id,shopType:row.shopType,isHeadShop:0},'addBranch');
return;
}
if (e.command == 1) { if (e.command == 1) {
refDetailModal.value.show(e.row); refDetailModal.value.show(e.row);
return; return;
@ -217,7 +208,7 @@ function dropdownClick(e, row) {
}); });
getTableData(); getTableData();
}) })
.catch(() => {}); .catch(() => { });
return; return;
} }
} }
@ -257,6 +248,7 @@ async function getTableData() {
.head-container { .head-container {
margin-bottom: 20px; margin-bottom: 20px;
} }
.shop_info { .shop_info {
display: flex; display: flex;
@ -265,6 +257,7 @@ async function getTableData() {
padding-left: 4px; padding-left: 4px;
} }
} }
.el-link { .el-link {
min-height: 23px; min-height: 23px;
margin: 0 5px; margin: 0 5px;

View File

@ -1,9 +1,38 @@
import type { ISearchConfig } from "@/components/CURD/types"; import type { ISearchConfig } from "@/components/CURD/types";
import { paramTypeOptions } from './config' import { paramTypeOptions } from './config'
import UserAPI from "@/api/product/productclassification";
import ShopApi from "@/api/account/shop";
const searchConfig: ISearchConfig = { const searchConfig: ISearchConfig = {
pageName: "sys:user", pageName: "sys:user",
formItems: [ formItems: [
{
type: "select",
label: "分店选择",
prop: "shopId",
attrs: {
placeholder: "请选择分店",
clearable: true,
style: {
width: "200px",
},
},
options: [],
async initFn(formItem) {
// formItem.options = await UserAPI.getList();
let res = await ShopApi.getBranchList();
let options = [];
res.map(v=>{
options.push({
label: v.shopName,
value: v.shopId,
})
})
formItem.options = options
},
},
{ {
type: "input", type: "input",
label: "账号名", label: "账号名",

View File

@ -47,12 +47,8 @@
<!-- <h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3> <!-- <h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3>
<div> <div>
<el-checkbox-group v-model="addPagePathIdList"> <el-checkbox-group v-model="addPagePathIdList">
<el-checkbox <el-checkbox v-for="(item, index) in pagePathIdLists" :key="index" :value="item.value"
v-for="(item, index) in pagePathIdLists" :label="item.label" />
:key="index"
:value="item.value"
:label="item.label"
/>
</el-checkbox-group> </el-checkbox-group>
</div> </div>
<h3 style="color: rgb(63, 158, 255)">员工权限设置</h3> <h3 style="color: rgb(63, 158, 255)">员工权限设置</h3>
@ -67,7 +63,7 @@
:modal-config="editModalConfig" :modal-config="editModalConfig"
@submit-click="handleSubmitClick" @submit-click="handleSubmitClick"
> >
<!-- <template #formFooter> <template #formFooter>
<h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3> <h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3>
<div> <div>
<el-checkbox-group v-model="editPagePathIdList"> <el-checkbox-group v-model="editPagePathIdList">
@ -82,7 +78,8 @@
<h3 style="color: rgb(63, 158, 255)">员工权限设置</h3> <h3 style="color: rgb(63, 158, 255)">员工权限设置</h3>
<selectPermission v-model="selPermissionList" :list="permissionList"></selectPermission> <selectPermission v-model="selPermissionList" :list="permissionList"></selectPermission>
</template> --> </template>
-->
</page-modal> </page-modal>
<!-- 修改密码 --> <!-- 修改密码 -->
@ -143,6 +140,12 @@ const oldeditSubmitFunc = editModalConfig.formAction;
// //
async function init() { async function init() {
// //
if (
JSON.parse(localStorage.getItem("userInfo") || "{}").isHeadShop == 0 &&
localStorage.getItem("loginType") == "0"
) {
searchConfig.formItems.splice(0, 1);
}
addModalConfig.formAction = function (data) { addModalConfig.formAction = function (data) {
return ShopStaffApi.add({ return ShopStaffApi.add({
...data, ...data,