Merge branch 'ymf' of https://e.coding.net/g-cphe0354/cashier/cashier-web
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
"exceljs": "^4.4.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mitt": "^3.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
|
||||
@@ -1,104 +1,99 @@
|
||||
// 代客下单
|
||||
import request from "@/utils/request-php";
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { useUserStore } from "@/store";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
function getLoginName() {
|
||||
const obj = localStorage.getItem("userInfo") || '';
|
||||
const { username } = obj ? JSON.parse(obj) : {};
|
||||
return username
|
||||
return userStore.userInfo.phone;
|
||||
}
|
||||
// 抖音团购核销准备
|
||||
export function $douyin_fulfilmentcertificateprepare(data) {
|
||||
return request({
|
||||
url: 'douyin/fulfilmentcertificateprepare',
|
||||
method: "post",
|
||||
data: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/fulfilmentcertificateprepare",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 抖音团购核销
|
||||
export function $douyin_certificateprepare(data) {
|
||||
return request({
|
||||
url: 'douyin/certificateprepare',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/certificateprepare",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 抖音团购核销撤销
|
||||
export function $douyin_fulfilmentcertificatecancel(data) {
|
||||
return request({
|
||||
url: 'douyin/fulfilmentcertificatecancel',
|
||||
method: "post",
|
||||
data: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/fulfilmentcertificatecancel",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 抖音团购核销记录
|
||||
export function $douyin_orderlist(data) {
|
||||
return request({
|
||||
url: 'douyin/orderlist',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/orderlist",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 抖音门店列表
|
||||
export function $douyin_storelist(data) {
|
||||
return request({
|
||||
url: 'douyin/storelist',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/storelist",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 抖音绑定门店
|
||||
export function $douyin_bindstore(data) {
|
||||
return request({
|
||||
url: 'douyin/bindstore',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/bindstore",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 抖音订单查询
|
||||
|
||||
export function $douyin_orderquery(data) {
|
||||
return request({
|
||||
url: 'douyin/orderquery',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/orderquery",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
//会员签入
|
||||
export function $douyin_checkIn(data) {
|
||||
return request({
|
||||
url: 'douyin/checkIn',
|
||||
method: "post",
|
||||
data: {
|
||||
clientType: 'ADMIN',
|
||||
token: getToken(),
|
||||
loginName: getLoginName(),
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "douyin/checkIn",
|
||||
method: "post",
|
||||
data: {
|
||||
clientType: "ADMIN",
|
||||
token: getToken(),
|
||||
loginName: getLoginName(),
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//美团
|
||||
@@ -106,100 +101,89 @@ export function $douyin_checkIn(data) {
|
||||
// 美团获取uisdk 绑定 链接
|
||||
|
||||
export function $meituan_getuisdkurl(data) {
|
||||
return request({
|
||||
url: 'meituan/getuisdkurl',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/getuisdkurl",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 美团获取uisdk 解绑 链接
|
||||
|
||||
export function $meituan_getuisdkuniurl(data) {
|
||||
return request({
|
||||
url: 'meituan/getuisdkuniurl',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/getuisdkuniurl",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 美团团购核销准备
|
||||
|
||||
export function $meituan_fulfilmentcertificateprepare(data) {
|
||||
return request({
|
||||
url: 'meituan/fulfilmentcertificateprepare',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/fulfilmentcertificateprepare",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 美团执行核销
|
||||
|
||||
export function $meituan_certificateprepare(data) {
|
||||
return request({
|
||||
url: 'meituan/certificateprepare',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/certificateprepare",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
// 美团团购核销记录
|
||||
|
||||
|
||||
export function $meituan_orderlist(data) {
|
||||
return request({
|
||||
url: 'meituan/orderlist',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/orderlist",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 美团团购撤销
|
||||
|
||||
|
||||
export function $meituan_fulfilmentcertificatecancel(data) {
|
||||
return request({
|
||||
url: 'meituan/fulfilmentcertificatecancel',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/fulfilmentcertificatecancel",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 美团查询绑定状态
|
||||
export function $meituan_searchstorestatus(data) {
|
||||
return request({
|
||||
url: 'meituan/searchstorestatus',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "meituan/searchstorestatus",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 登出
|
||||
export function $logout(data) {
|
||||
return request({
|
||||
url: 'user/logout',
|
||||
method: "post",
|
||||
data: {
|
||||
|
||||
...data
|
||||
}
|
||||
});
|
||||
return request({
|
||||
url: "user/logout",
|
||||
method: "post",
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
58
src/api/product/cons-group.ts
Normal file
58
src/api/product/cons-group.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import request from "@/utils/request";
|
||||
import { Product_BaseUrl } from "@/api/config";
|
||||
const baseURL = Product_BaseUrl + "/admin/product/cons-group";
|
||||
|
||||
const Api = {
|
||||
/** 分页*/
|
||||
getList(params: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/page`,
|
||||
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
|
||||
});
|
||||
},
|
||||
disable(id: number | string) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/disable/` + id,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
enable(id: number | string) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/enable/` + id,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default Api;
|
||||
70
src/api/product/cons.ts
Normal file
70
src/api/product/cons.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import request from "@/utils/request";
|
||||
import { Product_BaseUrl } from "@/api/config";
|
||||
const baseURL = Product_BaseUrl + "/admin/product/cons";
|
||||
|
||||
const Api = {
|
||||
/** 分页*/
|
||||
getList(params: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/page`,
|
||||
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
|
||||
});
|
||||
},
|
||||
disable(id: number | string) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/disable/` + id,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
enable(id: number | string) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/enable/` + id,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
onOff(id: number | string) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/on-off/`,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
modifySubUnit(id: number | string) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/modifySubUnit`,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default Api;
|
||||
51
src/api/product/stock.ts
Normal file
51
src/api/product/stock.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import request from "@/utils/request";
|
||||
import { Product_BaseUrl } from "@/api/config";
|
||||
const baseURL = Product_BaseUrl + "/admin/product/stock";
|
||||
// 耗材
|
||||
const Api = {
|
||||
/** 耗材入库*/
|
||||
in(data: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/in`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
},
|
||||
//出库
|
||||
out(data: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/out`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
},
|
||||
// 库存盘点记录
|
||||
checkRecord(params: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/check-record`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
},
|
||||
//库存盘点
|
||||
check(data: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/check`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
},
|
||||
//耗材报损
|
||||
|
||||
reportDamage(data: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/reportDamage`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default Api;
|
||||
53
src/api/product/vendor.ts
Normal file
53
src/api/product/vendor.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import request from "@/utils/request";
|
||||
import { Product_BaseUrl } from "@/api/config";
|
||||
const baseURL = Product_BaseUrl + "/admin/product/vendor";
|
||||
// 供应商
|
||||
const Api = {
|
||||
/** 分页*/
|
||||
getList(params: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/page`,
|
||||
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;
|
||||
@@ -545,17 +545,17 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
children: [
|
||||
{
|
||||
path: "consumables",
|
||||
component: () => import("@/views/inventory/consumables.vue"),
|
||||
component: () => import("@/views/inventory/consumables/index.vue"),
|
||||
name: "consumables",
|
||||
meta: {
|
||||
title: "耗材列表",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "supplier",
|
||||
component: () => import("@/views/inventory/supplier.vue"),
|
||||
component: () => import("@/views/inventory/supplier/index.vue"),
|
||||
name: "supplier",
|
||||
meta: {
|
||||
title: "供应商管理",
|
||||
@@ -564,23 +564,35 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "paymentRecord",
|
||||
component: () => import("@/views/inventory/paymentRecord.vue"),
|
||||
name: "paymentRecord",
|
||||
path: "operation_in",
|
||||
component: () => import("@/views/inventory/operation_in/index.vue"),
|
||||
name: "operation_in",
|
||||
meta: {
|
||||
title: "结款记录",
|
||||
title: "入库",
|
||||
affix: false,
|
||||
hidden: true
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "paymentRecord",
|
||||
component: () => import("@/views/inventory/payment-record.vue"),
|
||||
name: "paymentRecord",
|
||||
meta: {
|
||||
title: "结款记录",
|
||||
affix: false,
|
||||
hidden: true,
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "classification",
|
||||
component: () => import("@/views/inventory/classification.vue"),
|
||||
component: () => import("@/views/inventory/classification/index.vue"),
|
||||
name: "classification",
|
||||
meta: {
|
||||
title: "分类管理",
|
||||
affix: false,
|
||||
hidden: true
|
||||
hidden: true,
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -412,6 +412,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||
detailMap: returnDetailMap(data.detailMap)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param initParams 购物车初始化参数
|
||||
@@ -428,9 +429,12 @@ export const useCartsStore = defineStore("carts", () => {
|
||||
setOldOrder($oldOrder)
|
||||
}
|
||||
|
||||
console.log('oldOrder.detailMap', oldOrder.value.detailMap)
|
||||
|
||||
table_code.value = initParams && initParams.table_code ? initParams.table_code : '';
|
||||
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
|
||||
// const cache_table_code = localStorage.getItem('cache_table_code');
|
||||
// const randomTableCode = cache_table_code ? cache_table_code : ('APC' + (1000 + Math.floor(Math.random() * 9000)))
|
||||
initParams.table_code = initParams.table_code ? initParams.table_code : ''
|
||||
table_code.value = initParams.table_code
|
||||
// localStorage.setItem('cache_table_code', table_code.value);
|
||||
|
||||
WebSocketManager.subscribeToTopic(initParams, (msg) => {
|
||||
console.log("收到消息:", msg);
|
||||
@@ -444,6 +448,10 @@ export const useCartsStore = defineStore("carts", () => {
|
||||
if (msg.data.table_code) {
|
||||
table_code.value = table_code.value ? table_code.value : msg.data.table_code
|
||||
}
|
||||
if (msg.table_code) {
|
||||
table_code.value = table_code.value ? table_code.value : msg.table_code
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -34,11 +34,9 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||
if (!isTest) {
|
||||
const dynamicRoutes = parseDynamicRoutes(data.filter(v => v.type == 0));
|
||||
routes.value = [...constantRoutes, ...dynamicRoutes];
|
||||
console.log(routes.value);
|
||||
isRoutesLoaded.value = true;
|
||||
resolve(dynamicRoutes);
|
||||
} else {
|
||||
|
||||
isRoutesLoaded.value = true;
|
||||
resolve(constantRoutes);
|
||||
}
|
||||
|
||||
163
src/utils/limits.js
Normal file
163
src/utils/limits.js
Normal file
@@ -0,0 +1,163 @@
|
||||
import { ElMessage } from "element-plus";
|
||||
function getHasPermission() {
|
||||
return true;
|
||||
}
|
||||
const userInfo = JSON.parse(localStorage.getItem("userInfo"));
|
||||
const $PermissionObj = {
|
||||
data: [
|
||||
{
|
||||
key: "yun_xu_cha_kan_jing_ying_shu_ju",
|
||||
text: "允许查看经营数据",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_cha_kan_suo_you_jiao_ban_ji_lu",
|
||||
text: "允许查看所有交班记录",
|
||||
},
|
||||
],
|
||||
default: [
|
||||
{
|
||||
key: "yun_xu_xia_dan",
|
||||
text: "允许下单",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_shou_kuan",
|
||||
text: "允许收款",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_tui_kuan",
|
||||
text: "允许退款",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_jiao_ban",
|
||||
text: "允许交班",
|
||||
},
|
||||
],
|
||||
goods: [
|
||||
{
|
||||
key: "yun_xu_xiu_gai_shang_pin",
|
||||
text: "允许修改商品",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_shang_xia_jia_shang_pin",
|
||||
text: "允许上下架商品",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_xiu_gai_fen_lei",
|
||||
text: "允许修改分类",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_xiu_gai_fen_zu",
|
||||
text: "允许修改分组",
|
||||
},
|
||||
],
|
||||
discount: [
|
||||
{
|
||||
key: "yun_xu_da_zhe",
|
||||
text: "允许打折",
|
||||
},
|
||||
],
|
||||
vip: [
|
||||
{
|
||||
key: "yun_xu_guan_li_hui_yuan_xin_xi",
|
||||
text: "允许管理会员信息",
|
||||
},
|
||||
{
|
||||
key: "yun_xu_xiu_gai_hui_yuan_yu_e",
|
||||
text: "允许修改会员余额",
|
||||
},
|
||||
],
|
||||
stock: [
|
||||
{
|
||||
text: "允许提交报损",
|
||||
key: "yun_xu_ti_jiao_bao_sun",
|
||||
},
|
||||
{
|
||||
text: "允许沽清",
|
||||
key: "yun_xu_gu_qing",
|
||||
},
|
||||
{
|
||||
text: "允许售罄商品",
|
||||
key: "yun_xu_shou_qing_shang_pin",
|
||||
},
|
||||
{
|
||||
text: "允许修改商品库存",
|
||||
key: "yun_xu_xiu_gai_shang_pin_ku_cun",
|
||||
},
|
||||
{
|
||||
text: "允许耗材入库",
|
||||
key: "yun_xu_hao_cai_ru_ku",
|
||||
},
|
||||
{
|
||||
text: "允许耗材出库",
|
||||
key: "yun_xu_hao_cai_chu_ku",
|
||||
},
|
||||
{
|
||||
text: "允许耗材盘点",
|
||||
key: "yun_xu_hao_cai_pan_dian",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export async function hasPermission(params) {
|
||||
//如果是商户默认拥有全部权限
|
||||
const loginType = localStorage.getItem("loginType");
|
||||
if (loginType == "merchant") {
|
||||
return true;
|
||||
}
|
||||
params = returnFormatParams(params);
|
||||
if (!params) {
|
||||
return ElMessage.error(
|
||||
"未找到相关权限,请检查代码或在权限配置文件commons/utils/hasPermission.js文件进行修改或增加"
|
||||
);
|
||||
}
|
||||
const option = Object.assign(
|
||||
{
|
||||
tips: true,
|
||||
key: "",
|
||||
text: "",
|
||||
},
|
||||
params
|
||||
);
|
||||
const res = await getHasPermission({
|
||||
userId: userInfo.id,
|
||||
|
||||
code: params.key,
|
||||
});
|
||||
if (!res && option.tips) {
|
||||
ElMessage.error({
|
||||
title: "您没有" + params.text + "权限!",
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export function isObjectButNotArray(value) {
|
||||
return typeof value === "object" && Array.isArray(value) === false;
|
||||
}
|
||||
|
||||
export function findPermissionObj(str) {
|
||||
for (let i in $PermissionObj) {
|
||||
const obj = $PermissionObj[i].find((v) => v.key == str || v.text == str);
|
||||
if (obj) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
console.error(
|
||||
"未找到相关权限配置,请检查权限配置文件commons/utils/hasPermission.js文件进行修改或增加"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
export function returnFormatParams(params) {
|
||||
if (typeof params === "string") {
|
||||
return findPermissionObj(params);
|
||||
} else {
|
||||
if (isObjectButNotArray(params)) {
|
||||
const obj = findPermissionObj(params.key || params.text);
|
||||
return { ...params, ...obj };
|
||||
} else {
|
||||
console.error("参数只能是字符串或者对象,不能是数组");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { getToken } from "@/utils/auth";
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: "https://czgdoumei.sxczgkj.com/index.php/api/", // api 的 base_url
|
||||
baseURL: "https://newblockwlx.sxczgkj.cn/index.php/api/", // api 的 base_url
|
||||
timeout: 1000 * 20, // 请求超时时间
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ const contentConfig: IContentConfig<editRequest> = {
|
||||
indexAction: function (params) {
|
||||
return VersionApi.getList();
|
||||
},
|
||||
modifyAction: function (data: any) {
|
||||
return VersionApi.edit(data);
|
||||
},
|
||||
deleteAction: VersionApi.delete,
|
||||
// modifyAction: function (data) {
|
||||
// // return VersionApi.edit(data);
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<template>
|
||||
<!-- 结款记录 -->
|
||||
<div style="padding: 15px;">结款记录
|
||||
<!-- 搜索 -->
|
||||
<!-- <Search></Search> -->
|
||||
<!-- 数据统计 -->
|
||||
<!-- <DataStatistics></DataStatistics> -->
|
||||
<!-- 表格 -->
|
||||
<!-- <Content></Content> -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import Search from './paymentRecordconfig/Search.vue'
|
||||
import DataStatistics from './paymentRecordconfig/DataStatistics.vue'
|
||||
import Content from './paymentRecordconfig/Content.vue'
|
||||
</script>
|
||||
@@ -1,10 +0,0 @@
|
||||
<template>
|
||||
<!-- 分类模块 -->
|
||||
<div style="padding: 15px;">
|
||||
<!-- 表格 -->
|
||||
<Content></Content>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import Content from './classification/Content.vue'
|
||||
</script>
|
||||
@@ -1,157 +0,0 @@
|
||||
<template>
|
||||
<div class="Table">
|
||||
<!-- 按钮 -->
|
||||
<AddButton @add="add"></AddButton>
|
||||
<!-- 表格 -->
|
||||
<Table :list="datas.tableData" @handleDelete="handleDelete" @handleEdit="handleEdit"
|
||||
@handleStatusChange="handleStatusChange"></Table>
|
||||
<!-- 分页 -->
|
||||
<Paging :pagingConfig="datas.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
|
||||
<!-- 其他模板 -->
|
||||
<!-- 新增/编辑 -->
|
||||
<myDialog ref="myDialogRef" :title="datas.title" @confirm="confirm" width="30%">
|
||||
<el-form ref="ruleFormRef" :rules="datas.rules" :model="datas.DialogForm" label-width="120px">
|
||||
<el-form-item label="耗材类型名称" prop="name">
|
||||
<el-input v-model="datas.DialogForm.name" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否禁用">
|
||||
<el-switch v-model="datas.DialogForm.status" :active-value="1" :inactive-value="0" active-color="#13ce66"
|
||||
inactive-color="#ff4949" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</myDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import AddButton from './component/AddButton.vue'
|
||||
import Table from './component/Table.vue'
|
||||
import Paging from './component/Paging.vue'
|
||||
import myDialog from '@/components/mycomponents/myDialog.vue'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import API from './api'
|
||||
|
||||
const datas = reactive({
|
||||
tableData: [], // 表格数据
|
||||
title: '新增数据',
|
||||
pagingConfig: {
|
||||
total: 0, // 总数
|
||||
pageSize: 10, // 每页数据数量
|
||||
pageNumber: 1, // 当前页码
|
||||
},
|
||||
DialogForm: { // 弹窗表单数据
|
||||
status: 1
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '请输入供应商名称', trigger: 'blur' },
|
||||
], switch: [
|
||||
{ required: true, message: ' ', trigger: 'blur' },
|
||||
],
|
||||
|
||||
}
|
||||
})
|
||||
const myDialogRef = ref(null)
|
||||
const ruleFormRef = ref(null)
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
eventBus.on('search', (res) => {
|
||||
getList(res)
|
||||
})
|
||||
async function getList(data = {}) {
|
||||
const res = await API.getPage({ page: datas.pagingConfig.pageNumber, size: datas.pagingConfig.pageSize, ...data })
|
||||
datas.tableData = res.records
|
||||
datas.pagingConfig.total = res.totalRow
|
||||
datas.pagingConfig.pageSize = res.pageSize
|
||||
datas.pagingConfig.pageNumber = res.pageNumber
|
||||
}
|
||||
function add() {
|
||||
rest()
|
||||
datas.title = '新增数据'
|
||||
myDialogRef.value.open()
|
||||
}
|
||||
async function handleEdit(row) {
|
||||
datas.title = '编辑数据'
|
||||
const res = await API.getinfo(row.id)
|
||||
datas.DialogForm = res
|
||||
myDialogRef.value.open()
|
||||
}
|
||||
// 修改状态
|
||||
async function handleStatusChange(row) {
|
||||
let res = null
|
||||
if (row.status == 1) {
|
||||
res = await API.onOff(row.id)
|
||||
} else {
|
||||
res = await API.onOff2(row.id)
|
||||
}
|
||||
if (res.code == 200) {
|
||||
getList()
|
||||
ElMessage({
|
||||
message: '成功',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
}
|
||||
async function confirm() {
|
||||
ruleFormRef.value.validate(async valid => {
|
||||
if (valid) {
|
||||
let res = null
|
||||
if (datas.title == '新增数据') {
|
||||
res = await API.add(datas.DialogForm)
|
||||
} else {
|
||||
res = await API.update(datas.DialogForm)
|
||||
}
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '成功',
|
||||
type: 'success',
|
||||
})
|
||||
rest()
|
||||
getList()
|
||||
myDialogRef.value.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 重置
|
||||
function rest() {
|
||||
datas.DialogForm = { sort: "1" }
|
||||
}
|
||||
async function handleDelete(id) {
|
||||
ElMessageBox.confirm("是否删除数据项?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(
|
||||
async () => {
|
||||
let res = await API.deleteByIds(id)
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
})
|
||||
getList()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// 分页
|
||||
function sizeChange(val) {
|
||||
datas.pagingConfig.pageSize = val
|
||||
getList()
|
||||
}
|
||||
function currentChange(val) {
|
||||
datas.pagingConfig.pageNumber = val
|
||||
getList()
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.Table {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
margin-top: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,73 +0,0 @@
|
||||
import request from "@/utils/request";
|
||||
const baseURL = "/product/admin/product/cons-group";
|
||||
// 耗材-配置
|
||||
const AuthAPI = {
|
||||
// 列表
|
||||
getList(params: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/list`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
},
|
||||
/** 分页*/
|
||||
getPage(params: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/page`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
},
|
||||
// 新增
|
||||
add(data: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}`,
|
||||
method: "post",
|
||||
data: { ...data },
|
||||
});
|
||||
},
|
||||
// 详情
|
||||
getinfo(id: number) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
// 编辑
|
||||
update(data: Object) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}`,
|
||||
method: "put",
|
||||
data,
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteByIds(id: number | String) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
// 修改状态-启用
|
||||
onOff(id: number | String) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/enable/${id}`,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
// 修改状态-禁用
|
||||
onOff2(id: number | String) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/disable/${id}`,
|
||||
method: "post",
|
||||
});
|
||||
}
|
||||
};
|
||||
export interface Responseres {
|
||||
code?: number | null;
|
||||
data?: any;
|
||||
msg?: null | string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
export default AuthAPI;
|
||||
@@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<el-button type="primary" icon="Plus" @click="addEvent">新增</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
const emit = defineEmits(['add']);
|
||||
function addEvent() {
|
||||
emit('add');
|
||||
}
|
||||
</script>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-pagination background :page-size="props.pagingConfig.pageSize" :page-sizes="[10, 20, 30, 40]"
|
||||
layout="prev,pager,next,jumper,total,sizes" v-model:current-page="props.pagingConfig.pageNumber"
|
||||
:total="props.pagingConfig.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
pagingConfig: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['sizeChange', 'currentChange'])
|
||||
// 当前条改变
|
||||
function handleSizeChange(val) {
|
||||
emit('sizeChange', val)
|
||||
}
|
||||
// 当前页改变
|
||||
function handleCurrentChange(val) {
|
||||
emit('currentChange', val)
|
||||
}
|
||||
</script>
|
||||
@@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-table :data="props.list" border style="width: 100%">
|
||||
<el-table-column prop="id" align="center" label="ID" />
|
||||
<el-table-column prop="name" align="center" label="耗材类型名称" />
|
||||
<el-table-column prop="status" align="center" label="状态">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#13ce66"
|
||||
inactive-color="#ff4949" @change="handleStatusChange(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" link icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<!-- <el-button size="small" type="danger" link icon="Delete" style="color: #f89797;"
|
||||
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const emit = defineEmits(['handleDelete', 'handleEdit', 'handleStatusChange'])
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
function handleEdit(row) {
|
||||
emit('handleEdit', row)
|
||||
}
|
||||
function handleDelete(index, row) {
|
||||
emit('handleDelete', row.id)
|
||||
}
|
||||
|
||||
function handleStatusChange(row) {
|
||||
emit('handleStatusChange', row)
|
||||
}
|
||||
</script>
|
||||
53
src/views/inventory/classification/config/add.ts
Normal file
53
src/views/inventory/classification/config/add.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import Api from "@/api/product/cons-group";
|
||||
|
||||
|
||||
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: "请输入耗材类型名称",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
label: "是否启用",
|
||||
prop: "status",
|
||||
attrs: {
|
||||
activeValue: 1,
|
||||
inactiveValue: 0
|
||||
},
|
||||
col: {
|
||||
xs: 24,
|
||||
sm: 12,
|
||||
},
|
||||
initialValue: 0
|
||||
|
||||
},
|
||||
|
||||
],
|
||||
};
|
||||
|
||||
// 如果有异步数据会修改配置的,推荐用reactive包裹,而纯静态配置的可以直接导出
|
||||
export default reactive(modalConfig);
|
||||
48
src/views/inventory/classification/config/config.ts
Normal file
48
src/views/inventory/classification/config/config.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
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 : "";
|
||||
}
|
||||
|
||||
57
src/views/inventory/classification/config/content.ts
Normal file
57
src/views/inventory/classification/config/content.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import Api from "@/api/product/cons-group";
|
||||
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({});
|
||||
},
|
||||
modifyAction: function (data) {
|
||||
return Api.edit(data);
|
||||
},
|
||||
pk: "id",
|
||||
toolbar: ["add"],
|
||||
defaultToolbar: ["refresh", "filter", "search"],
|
||||
cols: [
|
||||
// { type: "selection", width: 50, align: "center" },
|
||||
{
|
||||
label: "ID",
|
||||
align: "center",
|
||||
prop: "id",
|
||||
},
|
||||
{
|
||||
label: "耗材类型名称",
|
||||
align: "center",
|
||||
prop: "name",
|
||||
},
|
||||
|
||||
{
|
||||
label: "状态",
|
||||
align: "center",
|
||||
prop: "status",
|
||||
templet: 'custom',
|
||||
slotName: 'switch'
|
||||
},
|
||||
|
||||
{
|
||||
label: "操作",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 280,
|
||||
templet: "tool",
|
||||
operat: ["edit"],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default contentConfig;
|
||||
53
src/views/inventory/classification/config/edit.ts
Normal file
53
src/views/inventory/classification/config/edit.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import Api from "@/api/product/cons-group";
|
||||
|
||||
|
||||
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: "请输入耗材类型名称",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
label: "是否启用",
|
||||
prop: "status",
|
||||
attrs: {
|
||||
activeValue: 1,
|
||||
inactiveValue: 0
|
||||
},
|
||||
col: {
|
||||
xs: 24,
|
||||
sm: 12,
|
||||
},
|
||||
initialValue: 0
|
||||
|
||||
},
|
||||
|
||||
],
|
||||
};
|
||||
|
||||
// 如果有异步数据会修改配置的,推荐用reactive包裹,而纯静态配置的可以直接导出
|
||||
export default reactive(modalConfig);
|
||||
21
src/views/inventory/classification/config/search.ts
Normal file
21
src/views/inventory/classification/config/search.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { ISearchConfig } from "@/components/CURD/types";
|
||||
|
||||
const searchConfig: ISearchConfig = {
|
||||
pageName: "sys:user",
|
||||
formItems: [
|
||||
{
|
||||
type: "input",
|
||||
label: "版本号",
|
||||
prop: "keywords",
|
||||
attrs: {
|
||||
placeholder: "请输入版本号",
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "200px",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default searchConfig;
|
||||
115
src/views/inventory/classification/index.vue
Normal file
115
src/views/inventory/classification/index.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<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 #status="scope">
|
||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #options="scope">
|
||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||
</template>
|
||||
<template #switch="scope">
|
||||
<el-switch
|
||||
v-model="scope.row[scope.prop]"
|
||||
disabled
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
</template>
|
||||
<template #mobile="scope">
|
||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||
<copy-button
|
||||
v-if="scope.row[scope.prop]"
|
||||
:text="scope.row[scope.prop]"
|
||||
style="margin-left: 2px"
|
||||
/>
|
||||
</template>
|
||||
</page-content>
|
||||
|
||||
<!-- 新增 -->
|
||||
<page-modal
|
||||
ref="addModalRef"
|
||||
:modal-config="addModalConfig"
|
||||
@submit-click="handleSubmitClick"
|
||||
></page-modal>
|
||||
|
||||
<!-- 编辑 -->
|
||||
<page-modal
|
||||
ref="editModalRef"
|
||||
:modal-config="editModalConfig"
|
||||
@submit-click="handleSubmitClick"
|
||||
></page-modal>
|
||||
</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 { returnOptionsLabel } from "./config/config";
|
||||
|
||||
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获取数据进行填充
|
||||
console.log(row);
|
||||
editModalRef.value?.setFormData({ ...row });
|
||||
}
|
||||
1;
|
||||
// 其他工具栏
|
||||
function handleToolbarClick(name: string) {
|
||||
console.log(name);
|
||||
if (name === "custom1") {
|
||||
ElMessage.success("点击了自定义1按钮");
|
||||
}
|
||||
}
|
||||
// 其他操作列
|
||||
async function handleOperatClick(data: IOperatData) {
|
||||
console.log(data);
|
||||
}
|
||||
</script>
|
||||
@@ -1,16 +0,0 @@
|
||||
<template>
|
||||
<div style="padding: 15px;">
|
||||
<!-- 搜索 -->
|
||||
<Search></Search>
|
||||
<!-- 数据统计 -->
|
||||
<DataStatistics></DataStatistics>
|
||||
<!-- 表格 -->
|
||||
<Content></Content>
|
||||
<!-- 其他内容 -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import Search from './consumablesconfig/Search.vue'
|
||||
import DataStatistics from './consumablesconfig/DataStatistics.vue'
|
||||
import Content from './consumablesconfig/Content.vue'
|
||||
</script>
|
||||
197
src/views/inventory/consumables/components/add-haocai copy.vue
Normal file
197
src/views/inventory/consumables/components/add-haocai copy.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<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>
|
||||
177
src/views/inventory/consumables/components/add-haocai.vue
Normal file
177
src/views/inventory/consumables/components/add-haocai.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<!-- 修改和增加 -->
|
||||
<el-dialog :title="dialogtitle" v-model="show" width="800px" @close="reset">
|
||||
<el-form :inline="false" ref="refform" :model="form" :rules="rules" class="demo-form-inline">
|
||||
<el-form-item label="耗材名称" prop="conName">
|
||||
<el-input v-model="form.conName" placeholder="请输入耗材名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="耗材分类" prop="consGroupId">
|
||||
<el-select v-model="form.consGroupId" placeholder="请选择耗材分类" style="width: 200px">
|
||||
<el-option
|
||||
v-for="option in consGroups"
|
||||
:key="option.conTypeId"
|
||||
:label="option.label"
|
||||
:value="option.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="耗材价格" prop="price">
|
||||
<el-input v-model="form.price" placeholder="请输入耗材价格"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="库存">
|
||||
<el-input v-model="form.stockNumber" placeholder="请输入库存值"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="单位" 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="是否检测耗材">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="第二单位" prop="conUnitTwo">
|
||||
<el-input v-model="form.conUnitTwo" placeholder="请输入第二单位"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="第二单位转换数量" prop="conUnitTwoConvert">
|
||||
<el-input-number
|
||||
v-model="form.conUnitTwoConvert"
|
||||
placeholder="第二单位转换数量"
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="默认入库单位" prop="defaultUnit">
|
||||
<el-input v-model="form.defaultUnit" 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 consApi from "@/api/product/cons";
|
||||
import consGroupApi from "@/api/product/cons-group";
|
||||
import { ElMessage } from "element-plus";
|
||||
const consGroups = ref([]);
|
||||
const rules = {
|
||||
conName: [{ required: true, message: "请输入耗材名称", trigger: "blur" }],
|
||||
consGroupId: [{ required: true, message: "请选择耗材类型", trigger: "change" }],
|
||||
price: [{ required: true, message: "请输入耗材价格", trigger: "blur" }],
|
||||
conWarning: [{ required: true, message: "请输入耗材预警值", 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 = {
|
||||
conName: "",
|
||||
consGroupId: "",
|
||||
conUnit: "",
|
||||
price: "",
|
||||
conWarning: "",
|
||||
};
|
||||
const forms = ref([{ ...basicForm }]);
|
||||
const form = reactive({
|
||||
...basicForm,
|
||||
});
|
||||
|
||||
const show = ref(false);
|
||||
let dialogtitle = ref("");
|
||||
function open(item) {
|
||||
dialogtitle.value = item ? "编辑" : "新增";
|
||||
Object.assign(form, item);
|
||||
show.value = true;
|
||||
}
|
||||
function formsAdd(index) {
|
||||
forms.value.push({ ...basicForm });
|
||||
}
|
||||
function close() {
|
||||
show.value = false;
|
||||
}
|
||||
|
||||
const refform = ref();
|
||||
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 });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const emits = defineEmits(["refresh"]);
|
||||
async function submitForm() {
|
||||
refform.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
const res =
|
||||
dialogtitle.value == "新增" ? await consApi.add(this.form) : await consApi.edit(this.form);
|
||||
ElMessage({ type: "success", message: dialogtitle.value + "成功" });
|
||||
emits("refresh");
|
||||
close();
|
||||
}
|
||||
});
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
function reset() {
|
||||
form.value = { ...basicForm };
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close,
|
||||
});
|
||||
</script>
|
||||
240
src/views/inventory/consumables/components/addConsTakin.vue
Normal file
240
src/views/inventory/consumables/components/addConsTakin.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<!-- 耗材列表的新增耗材盘点 -->
|
||||
<template>
|
||||
<el-dialog title="耗材盘点" v-model="dialogVisible" width="80%">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-position="left" inline>
|
||||
<el-form-item label="账存数量">
|
||||
<el-input v-model="form.balance" readonly style="width: 180px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="实际数量">
|
||||
<el-input-number
|
||||
v-model="form.stockNumber"
|
||||
:min="0"
|
||||
:step="1"
|
||||
step-strictly
|
||||
style="width: 180px"
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="盈亏数量">
|
||||
<el-input
|
||||
v-model="profitNumber"
|
||||
readonly
|
||||
:class="{ lose: profitNumber < 0 }"
|
||||
style="width: 180px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="单价">
|
||||
<el-input v-model="form.price" readonly></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="盈亏金额">
|
||||
<el-input
|
||||
v-model="profitPrice"
|
||||
readonly
|
||||
:class="{ lose: profitNumber < 0 }"
|
||||
style="width: 180px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" placeholder="请输入备注" style="width: 300px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="onSubmitHandle">确 定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="head-container">
|
||||
<el-table ref="table" :data="tableData.list" v-loading="tableData.loading" border stripe>
|
||||
<el-table-column label="商品信息" width="150px">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
<el-image :src="scope.row.coverImg" style="width: 30px; height: 30px">
|
||||
<template #error>
|
||||
<div class="img_error">
|
||||
<i class="icon el-icon-document-delete"></i>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<span>{{ scope.row.conName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售价" prop="price">
|
||||
<template v-slot="scope">¥{{ scope.row.price }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="账存数量" prop="stockNumber"></el-table-column>
|
||||
<el-table-column label="盈亏数量" prop="lpNum"></el-table-column>
|
||||
<el-table-column label="盈亏金额" prop="lpAmount">
|
||||
<template v-slot="scope">¥{{ scope.row.lpAmount }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际库存" prop="acStockNumber"></el-table-column>
|
||||
<el-table-column label="盘点时间" prop="createTime"></el-table-column>
|
||||
<el-table-column label="盘点备注" prop="remark"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
:total="tableData.total"
|
||||
:current-page="tableData.page + 1"
|
||||
:page-sizes="[5, 10, 30, 50]"
|
||||
:page-size="tableData.size"
|
||||
@current-change="paginationChange"
|
||||
@size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formatDecimal } from "@/utils/tools.js";
|
||||
import { hasPermission } from "@/utils/limits.js";
|
||||
import stockApi from "@/api/product/stock";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
loading: false,
|
||||
form: {
|
||||
skuId: "", // sku商品必传
|
||||
productId: "", // 必传
|
||||
stocktakinNum: "", // 必传
|
||||
price: "", // 商品价格 非必传 为空盘点价格为商品价格
|
||||
remark: "", // 盘点备注 非必传
|
||||
stockNumber: 0,
|
||||
balance: "",
|
||||
},
|
||||
rules: {
|
||||
stocktakinNum: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入盘点数量",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
resetForm: "",
|
||||
searhForm: {
|
||||
name: "",
|
||||
skuId: "",
|
||||
productId: "",
|
||||
},
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 5,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.form };
|
||||
},
|
||||
computed: {
|
||||
profitNumber() {
|
||||
if (this.form.balance == undefined) {
|
||||
return this.form.stockNumber - 0;
|
||||
} else {
|
||||
return this.form.stockNumber - this.form.balance;
|
||||
}
|
||||
},
|
||||
profitPrice() {
|
||||
return formatDecimal((this.form.stockNumber - this.form.balance) * this.form.price);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSubmitHandle() {
|
||||
this.$refs.form.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.form.lpNum = this.profitNumber;
|
||||
this.form.balance = this.form.stockNumber;
|
||||
this.loading = true;
|
||||
this.form.conInfoId = this.form.id;
|
||||
delete this.form["id"];
|
||||
console.log(this.form);
|
||||
let res = await tbConCheck(this.form);
|
||||
console.log(this.form);
|
||||
this.$emit("success", res);
|
||||
this.dialogVisible = false;
|
||||
this.loading = false;
|
||||
this.$notify({
|
||||
title: "注意",
|
||||
message: `添加成功`,
|
||||
type: "success",
|
||||
});
|
||||
this.getTableData();
|
||||
} catch (error) {
|
||||
this.loading = false;
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
async show(obj) {
|
||||
console.log(obj, 111);
|
||||
let res = await hasPermission("允许耗材盘点");
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
this.form.remark = "";
|
||||
this.form.stocktakinNum = 0;
|
||||
this.form.lpNum = 0;
|
||||
// this.form.stockNumber = 0
|
||||
|
||||
this.form = Object.assign(this.form, obj);
|
||||
this.dialogVisible = true;
|
||||
this.form.conInfoId = obj.consId;
|
||||
this.form.stockNumber = obj.balance < 0 ? 0 : obj.balance;
|
||||
// this.form.balance = obj.stockNumber
|
||||
this.form.balance = obj.balance;
|
||||
this.form.price == null ? 0 : this.form.price;
|
||||
this.searhForm.productId = obj.id;
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页大小改变
|
||||
sizeChange(e) {
|
||||
this.tableData.size = e;
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1;
|
||||
this.getTableData();
|
||||
},
|
||||
// 商品列表
|
||||
async getTableData() {
|
||||
try {
|
||||
this.tableData.loading = true;
|
||||
const res = await stockApi.checkRecord({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
conId: this.searhForm.productId,
|
||||
sort: "id,desc",
|
||||
});
|
||||
this.tableData.list = res.content;
|
||||
this.tableData.total = res.totalElements;
|
||||
setTimeout(() => {
|
||||
this.tableData.loading = false;
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.lose {
|
||||
&::v-deep .el-input__inner {
|
||||
color: rgb(238, 29, 29);
|
||||
}
|
||||
}
|
||||
|
||||
.shop_info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
88
src/views/inventory/consumables/config/add.ts
Normal file
88
src/views/inventory/consumables/config/add.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import Api from "@/api/product/vendor";
|
||||
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: "source",
|
||||
rules: [{ required: true, message: "请选择渠道", trigger: "blur" }],
|
||||
type: "select",
|
||||
attrs: {
|
||||
placeholder: "请选择渠道",
|
||||
},
|
||||
options: [],
|
||||
},
|
||||
{
|
||||
label: "类型",
|
||||
prop: "type",
|
||||
rules: [{ required: true, message: "请选择类型", trigger: "blur" }],
|
||||
type: "select",
|
||||
attrs: {
|
||||
placeholder: "请选择类型",
|
||||
},
|
||||
col: {
|
||||
xs: 24,
|
||||
sm: 12,
|
||||
},
|
||||
options: [],
|
||||
},
|
||||
{
|
||||
type: "input",
|
||||
label: "版本号",
|
||||
prop: "version",
|
||||
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请输入版本号",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "radio",
|
||||
label: "是否强制更新",
|
||||
prop: "isForce",
|
||||
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请输入版本号",
|
||||
},
|
||||
initialValue: 0,
|
||||
options: [],
|
||||
},
|
||||
{
|
||||
type: "textarea",
|
||||
label: "更新提示内容",
|
||||
prop: "message",
|
||||
rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请输入更新提示内容",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "custom",
|
||||
label: "版本文件",
|
||||
prop: "url",
|
||||
rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请上传版本文件",
|
||||
},
|
||||
initialValue: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// 如果有异步数据会修改配置的,推荐用reactive包裹,而纯静态配置的可以直接导出
|
||||
export default reactive(modalConfig);
|
||||
43
src/views/inventory/consumables/config/config.ts
Normal file
43
src/views/inventory/consumables/config/config.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { statusType } from "@/api/order/order";
|
||||
export const options: { [key in optionsType]: options[] } = {
|
||||
|
||||
}
|
||||
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 : "";
|
||||
}
|
||||
|
||||
|
||||
export interface options {
|
||||
label: string;
|
||||
value: string | number;
|
||||
[property: string]: any;
|
||||
}
|
||||
export interface statusOptions extends options {
|
||||
value: statusType;
|
||||
}
|
||||
|
||||
export type payTypeValue =
|
||||
| ""
|
||||
| "cash"
|
||||
| "bank"
|
||||
| "scanCode"
|
||||
| "deposit"
|
||||
| "vipPay"
|
||||
| "arrears"
|
||||
| "virtual"
|
||||
| "arrears";
|
||||
|
||||
export interface payTypeOptions extends options {
|
||||
value: payTypeValue;
|
||||
}
|
||||
94
src/views/inventory/consumables/config/content.ts
Normal file
94
src/views/inventory/consumables/config/content.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import Api from "@/api/product/cons";
|
||||
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: 10,
|
||||
pageSizes: [10, 20, 30, 50],
|
||||
},
|
||||
indexAction: function (params) {
|
||||
return Api.getList(params);
|
||||
},
|
||||
// deleteAction: Api.delete,
|
||||
// modifyAction: function (data) {
|
||||
// // return Api.edit(data);
|
||||
// },
|
||||
pk: "id",
|
||||
toolbar: [
|
||||
"add",
|
||||
{
|
||||
text: "入库",
|
||||
name: 'ruku',
|
||||
auth: 'ruku'
|
||||
},
|
||||
{
|
||||
text: "出库",
|
||||
name: 'chuku',
|
||||
auth: ''
|
||||
},
|
||||
{
|
||||
text: "分类管理",
|
||||
name: 'category',
|
||||
auth: ''
|
||||
},
|
||||
{
|
||||
text: "供应商管理",
|
||||
name: 'gongyinsahng',
|
||||
auth: ''
|
||||
},
|
||||
],
|
||||
defaultToolbar: ["refresh", "filter", "search"],
|
||||
cols: [
|
||||
{ type: "selection", width: 50, align: "center" },
|
||||
// { label: "id", align: "center", prop: "id", width: 100, show: true },
|
||||
{
|
||||
label: "耗材名称",
|
||||
align: "center",
|
||||
prop: "conName",
|
||||
},
|
||||
{
|
||||
label: "单位",
|
||||
align: "center",
|
||||
prop: "conUnit",
|
||||
},
|
||||
{
|
||||
label: "所属商品",
|
||||
align: "center",
|
||||
templet: 'custom',
|
||||
slotName: 'goods'
|
||||
},
|
||||
{
|
||||
label: "库存数量",
|
||||
align: "center",
|
||||
prop: "stockNumber",
|
||||
},
|
||||
{
|
||||
label: "预警值",
|
||||
align: "center",
|
||||
prop: "conWarning",
|
||||
},
|
||||
{
|
||||
label: "是否启用",
|
||||
align: "center",
|
||||
prop: "status",
|
||||
templet: "custom",
|
||||
slotName: "status",
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 150,
|
||||
templet: "custom",
|
||||
slotName: 'operate'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default contentConfig;
|
||||
51
src/views/inventory/consumables/config/edit.ts
Normal file
51
src/views/inventory/consumables/config/edit.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import VersionApi, { type editRequest } from "@/api/system/version";
|
||||
import type { IModalConfig } from "@/components/CURD/types";
|
||||
|
||||
const modalConfig: IModalConfig<editRequest> = {
|
||||
pageName: "sys:user",
|
||||
dialog: {
|
||||
title: "编辑版本",
|
||||
width: 800,
|
||||
draggable: true,
|
||||
},
|
||||
pk: "id",
|
||||
formAction: function (data) {
|
||||
return VersionApi.edit({ ...data, url: typeof data.url === "string" ? data.url : data.url[0] });
|
||||
},
|
||||
beforeSubmit(data) {
|
||||
console.log("提交之前处理", data);
|
||||
},
|
||||
formItems: [
|
||||
{
|
||||
type: "input",
|
||||
label: "版本号",
|
||||
prop: "version",
|
||||
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请输入版本号",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: "textarea",
|
||||
label: "更新提示内容",
|
||||
prop: "message",
|
||||
rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请输入更新提示内容",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "custom",
|
||||
label: "版本文件",
|
||||
prop: "url",
|
||||
rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }],
|
||||
attrs: {
|
||||
placeholder: "请上传版本文件",
|
||||
},
|
||||
initialValue: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default reactive(modalConfig);
|
||||
64
src/views/inventory/consumables/config/search.ts
Normal file
64
src/views/inventory/consumables/config/search.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import type { ISearchConfig } from "@/components/CURD/types";
|
||||
import consGroupApi from '@/api/product/cons-group'
|
||||
import { statusOptions, payTypeOptions } from "./config";
|
||||
const searchConfig: ISearchConfig = {
|
||||
pageName: "sys:user",
|
||||
inline: true,
|
||||
isExpandable: false,
|
||||
formItems: [
|
||||
{
|
||||
type: "select",
|
||||
label: "耗材分类",
|
||||
prop: "consGroupId",
|
||||
attrs: {
|
||||
placeholder: "请选择耗材分类",
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "200px",
|
||||
},
|
||||
},
|
||||
initialValue: "",
|
||||
initFn(formItem) {
|
||||
console.log(formItem);
|
||||
consGroupApi.getAllList({}).then(res => {
|
||||
formItem.options = res.map((item: { name: any; id: any; }) => {
|
||||
return {
|
||||
label: item?.name,
|
||||
value: item?.id
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: "input",
|
||||
label: "耗材名称",
|
||||
prop: "conName",
|
||||
attrs: {
|
||||
placeholder: "请输入耗材名称",
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "200px",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "date-picker",
|
||||
label: "创建时间",
|
||||
prop: "createAt",
|
||||
attrs: {
|
||||
type: "daterange",
|
||||
"range-separator": "~",
|
||||
"start-placeholder": "开始时间",
|
||||
"end-placeholder": "截止时间",
|
||||
"value-format": "YYYY-MM-DD",
|
||||
style: {
|
||||
width: "240px",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default searchConfig;
|
||||
186
src/views/inventory/consumables/index.vue
Normal file
186
src/views/inventory/consumables/index.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<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 #status="scope">
|
||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #goods="scope">
|
||||
<div class="goods_info">
|
||||
<div class="row" v-for="item in scope.row.productList" :key="item.id">
|
||||
<el-image :src="item.productImg" class="cover" lazy></el-image>
|
||||
<div class="info">
|
||||
<div class="name">
|
||||
<span :class="[item.isVip == 1 ? 'colorStyle' : '']">
|
||||
{{ item.productName }}
|
||||
</span>
|
||||
<span class="refund" v-if="item.refundNumber">(退 - {{ item.refundNumber }})</span>
|
||||
</div>
|
||||
<div class="sku">{{ item.productSkuName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #options="scope">
|
||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||
</template>
|
||||
<template #state="scope">
|
||||
<el-tag :type="returnStateType(scope.row[scope.prop])">
|
||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #mobile="scope">
|
||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||
<copy-button
|
||||
v-if="scope.row[scope.prop]"
|
||||
:text="scope.row[scope.prop]"
|
||||
style="margin-left: 2px"
|
||||
/>
|
||||
</template>
|
||||
<template #operate="scope">
|
||||
<div>
|
||||
<el-button @click="refAddHaocaiOpen(scope.row)" type="primary" link>编辑</el-button>
|
||||
<el-button @click="refAddHaocaiTakinShow(scope.row)" link type="primary">
|
||||
耗材盘点
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</page-content>
|
||||
<!-- 耗材添加编辑 -->
|
||||
<add-haocai ref="refAddHaocai" @refresh="refresh"></add-haocai>
|
||||
<!-- 耗材盘点 -->
|
||||
<addConsTakin ref="refAddHaocaiTakin" @refresh="refresh"></addConsTakin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import addHaocai from "./components/add-haocai.vue";
|
||||
import addConsTakin from "./components/addConsTakin.vue";
|
||||
import orderApi, { type getListResponse, OrderInfoVo } from "@/api/order/order";
|
||||
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||
import usePage from "@/components/CURD/usePage";
|
||||
import contentConfig from "./config/content";
|
||||
import editModalConfig from "./config/edit";
|
||||
import searchConfig from "./config/search";
|
||||
import { returnOptionsLabel } from "./config/config";
|
||||
|
||||
const router = useRouter();
|
||||
const {
|
||||
searchRef,
|
||||
contentRef,
|
||||
editModalRef,
|
||||
handleQueryClick,
|
||||
handleResetClick,
|
||||
handleSubmitClick,
|
||||
handleExportClick,
|
||||
handleSearchClick,
|
||||
handleFilterChange,
|
||||
} = usePage();
|
||||
|
||||
//耗材盘点
|
||||
const refAddHaocaiTakin = ref();
|
||||
function refAddHaocaiTakinShow(item: any) {
|
||||
refAddHaocaiTakin.value.show(item);
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
console.log("refresh");
|
||||
contentRef.value?.fetchPageData();
|
||||
}
|
||||
const refAddHaocai = ref();
|
||||
function refAddHaocaiOpen(item) {
|
||||
refAddHaocai.value.open(item);
|
||||
}
|
||||
// 新增
|
||||
async function handleAddClick() {
|
||||
refAddHaocaiOpen();
|
||||
}
|
||||
// 编辑
|
||||
async function handleEditClick(row: IObject) {
|
||||
editModalRef.value?.handleDisabled(false);
|
||||
editModalRef.value?.setModalVisible();
|
||||
console.log({ ...row });
|
||||
editModalRef.value?.setFormData({ ...row, url: [row.url] });
|
||||
}
|
||||
1;
|
||||
// 其他工具栏
|
||||
function handleToolbarClick(name: string) {
|
||||
console.log(name);
|
||||
if (name === "category") {
|
||||
router.push({ path: "/inventory/classification" });
|
||||
return;
|
||||
}
|
||||
if (name == "gongyinsahng") {
|
||||
router.push({ path: "/inventory/supplier" });
|
||||
return;
|
||||
}
|
||||
if (name == "ruku") {
|
||||
router.push({ path: "/inventory/operation_in" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 其他操作列
|
||||
async function handleOperatClick(data: IOperatData) {
|
||||
console.log(data);
|
||||
if (data.name === "detail") {
|
||||
return;
|
||||
}
|
||||
if (data.name === "printer") {
|
||||
}
|
||||
}
|
||||
|
||||
function returnStateType(status: string) {
|
||||
if (status === "unpaid") {
|
||||
return "warning";
|
||||
}
|
||||
if (status === "done") {
|
||||
return "primary";
|
||||
}
|
||||
if (status === "cancelled") {
|
||||
return "info";
|
||||
}
|
||||
if (status === "refund") {
|
||||
return "danger";
|
||||
}
|
||||
}
|
||||
|
||||
const route = useRouter();
|
||||
// 结账
|
||||
function toPayOrder(order: getListResponse) {
|
||||
route.push({
|
||||
path: "/tool/index",
|
||||
query: {
|
||||
id: order.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
//详情
|
||||
const refDetail = ref();
|
||||
function showdetail(row: OrderInfoVo) {
|
||||
refDetail.value.show(row);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div class="Table">
|
||||
<!-- 按钮 -->
|
||||
<AddButton></AddButton>
|
||||
<!-- 表格 -->
|
||||
<Table></Table>
|
||||
<!-- 分页 -->
|
||||
<Paging></Paging>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import AddButton from './component/AddButton.vue'
|
||||
import Table from './component/Table.vue'
|
||||
import Paging from './component/Paging.vue'
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.Table {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
margin-top: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<div class="DataStatistics">
|
||||
<div style="width: 200px;">
|
||||
<el-icon class="iconStyle">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<span>耗材种数</span>
|
||||
<span>{{ datas.totalRow }}</span>
|
||||
</div>
|
||||
<div style="width: 300px;">
|
||||
<el-icon class="iconStyle">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<div>
|
||||
<div><span>增加数量:</span><span>0</span></div>
|
||||
<div style="display: flex;">
|
||||
<div>
|
||||
<span>手动增加:</span><span>0</span>
|
||||
</div>
|
||||
<span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>入库:</span><span>0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 500px;">
|
||||
<el-icon class="iconStyle">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<div>
|
||||
<div><span>减少数量:</span><span>0</span></div>
|
||||
<div style="display: flex;">
|
||||
<div>
|
||||
<span>手动减少:</span><span>0</span>
|
||||
</div>
|
||||
<span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>消耗:</span><span>0</span>
|
||||
</div>
|
||||
<span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>报损:</span><span>0</span>
|
||||
</div><span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>出库:</span><span>0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import API from "@/api/product/index";
|
||||
import { onMounted, reactive } from "vue";
|
||||
onMounted(() => {
|
||||
getPage();
|
||||
})
|
||||
let datas = reactive({
|
||||
totalRow: 0
|
||||
})
|
||||
async function getPage() {
|
||||
let res = await API.getPage();
|
||||
datas.totalRow = res.totalRow
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.DataStatistics {
|
||||
border: 1px solid #e4e7ed;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
>div {
|
||||
height: 80px;
|
||||
background-color: #f4f9ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
padding: 20px;
|
||||
|
||||
.iconStyle {
|
||||
background-color: #d4e9fe;
|
||||
border-radius: 50%;
|
||||
padding: 6px;
|
||||
font-size: 36px;
|
||||
color: #3f9eff;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div class="Search">
|
||||
<el-form :inline="true" :model="formInline" class="demo-form-inline">
|
||||
<el-form-item label="耗材分类">
|
||||
<el-select v-model="formInline.region" placeholder="请选择耗材分类" clearable>
|
||||
<el-option label="Zone one" value="shanghai" />
|
||||
<el-option label="Zone two" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="耗材名称">
|
||||
<el-input v-model="formInline.user" placeholder="请输入耗材名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker v-model="formInline.value1" type="daterange" range-separator="-" start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排列方式">
|
||||
<el-select v-model="formInline.region" placeholder="请选择排列方式" clearable>
|
||||
<el-option label="创建时间" value="shanghai" />
|
||||
<el-option label="数量由低到高" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="onSubmit">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="onSubmit">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const formInline = reactive({
|
||||
user: '',
|
||||
region: '',
|
||||
date: '',
|
||||
value1: ""
|
||||
})
|
||||
|
||||
const onSubmit = () => {
|
||||
console.log('submit!')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.Search {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-input {
|
||||
--el-input-width: 220px;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-select {
|
||||
--el-select-width: 220px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<el-button type="success" icon="Plus">新增</el-button>
|
||||
<el-button>入库</el-button>
|
||||
<el-button>出库</el-button>
|
||||
<el-button @click="toUrl('classification')">分类管理</el-button>
|
||||
<el-button @click="toUrl('supplier')">供应商管理</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
function toUrl(name) {
|
||||
router.push({ name });
|
||||
}
|
||||
</script>
|
||||
@@ -1,22 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-pagination background :page-size="20" :page-sizes="[10, 20, 30, 40]" layout="prev,pager,next,jumper,total,sizes"
|
||||
v-model:current-page="datas.currentPage" :total="datas.total" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
let datas = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
total: 20,
|
||||
})
|
||||
// 当前条改变
|
||||
function handleSizeChange(val) {
|
||||
console.log(`每页 ${val} 条`);
|
||||
}
|
||||
// 当前页改变
|
||||
function handleCurrentChange(val) {
|
||||
console.log(`当前页: ${val}`);
|
||||
}
|
||||
</script>
|
||||
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-table :data="tableData" border style="width: 100%">
|
||||
<el-table-column prop="date" label="Date" width="180" />
|
||||
<el-table-column prop="name" label="Name" width="180" />
|
||||
<el-table-column prop="address" label="Address" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
207
src/views/inventory/operation_in/components/consumableList.vue
Normal file
207
src/views/inventory/operation_in/components/consumableList.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<!-- 耗材列表 -->
|
||||
<template>
|
||||
<el-dialog title="选择耗材" v-model="dialogVisible">
|
||||
<el-form :model="searchForm" inline>
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="searchForm.conTypeName"
|
||||
placeholder="耗材类型名称"
|
||||
@input="onInput"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input v-model="searchForm.conName" placeholder="耗材名称" @input="onInput"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="head-container">
|
||||
<el-table
|
||||
ref="table"
|
||||
:data="tableData.list"
|
||||
v-loading="tableData.loading"
|
||||
@select="firstSelectChange"
|
||||
:row-key="getRowKey"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<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">
|
||||
<template v-slot="scope">
|
||||
{{ formatDecimal(scope.row.stockNumber, 2, true) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="操作" fixed="right">
|
||||
<template v-slot="scope">
|
||||
<el-button type="primary" size="mini" @click="confirmHandle(scope.row)">选择</el-button>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
:total="tableData.total"
|
||||
:current-page="tableData.page + 1"
|
||||
:page-size="tableData.size"
|
||||
@current-change="paginationChange"
|
||||
@size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmHandle">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import consApi from "@/api/product/cons";
|
||||
|
||||
import { formatDecimal } from "@/utils/tools.js";
|
||||
import _ from "lodash";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
formatDecimal,
|
||||
dialogVisible: false,
|
||||
searchForm: {
|
||||
conTypeId: "",
|
||||
conTypeName: "",
|
||||
conCode: "",
|
||||
conName: "",
|
||||
},
|
||||
resetSearchForm: "",
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: [],
|
||||
},
|
||||
goods: [],
|
||||
stayselection: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.resetSearchForm = { ...this.searchForm };
|
||||
},
|
||||
methods: {
|
||||
reset() {
|
||||
this.$refs.table.clearSelection();
|
||||
},
|
||||
onInput: _.debounce(function (event) {
|
||||
//防抖请求
|
||||
this.getTableData();
|
||||
}, 500),
|
||||
onSelectionChange(selection) {
|
||||
this.stayselection = selection;
|
||||
},
|
||||
getRowKey(row) {
|
||||
return row.id;
|
||||
},
|
||||
firstSelectChange() {
|
||||
// console.log(selection)
|
||||
let selection = this.$refs.table.selection || [];
|
||||
if (selection.length > 1 && this.isselect) {
|
||||
const del_row = selection.shift();
|
||||
this.$refs.table.toggleRowSelection(del_row, false);
|
||||
}
|
||||
},
|
||||
|
||||
// 确定选商品
|
||||
confirmHandle() {
|
||||
// let res = this.$refs.table.selection
|
||||
// let res = this.stayselection
|
||||
// this.$emit('success', res)
|
||||
var uniqueArray = this.stayselection.filter(
|
||||
(item1) => !this.goods.some((item2) => item2.productId == item1.id)
|
||||
);
|
||||
this.$emit("success", uniqueArray);
|
||||
this.close();
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.searchForm = { ...this.resetSearchForm };
|
||||
this.tableData.page = 0;
|
||||
this.tableData.size = 10;
|
||||
this.tableData.list = [];
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页大小改变
|
||||
sizeChange(e) {
|
||||
this.tableData.size = e;
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1;
|
||||
this.getTableData();
|
||||
},
|
||||
// 耗材列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true;
|
||||
try {
|
||||
const res = await consApi.getList({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
...this.searchForm,
|
||||
});
|
||||
this.tableData.list = res.records;
|
||||
this.tableData.total = res.totalRow;
|
||||
|
||||
if (this.goods.length) {
|
||||
this.$nextTick(() => {
|
||||
this.selection();
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.tableData.loading = false;
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
show(goods) {
|
||||
this.dialogVisible = true;
|
||||
if (goods && goods.length) {
|
||||
this.goods = goods;
|
||||
} else {
|
||||
this.goods = [];
|
||||
}
|
||||
this.resetHandle();
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
selection() {
|
||||
this.goods.forEach((row) => {
|
||||
this.tableData.list.forEach((item, index) => {
|
||||
if (row.id == item.id) {
|
||||
this.$refs.table.toggleRowSelection(this.tableData.list[index]);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shop_info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
250
src/views/inventory/operation_in/components/shopList.vue
Normal file
250
src/views/inventory/operation_in/components/shopList.vue
Normal file
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<el-dialog title="选择商品" v-model="dialogVisible" @close="reset" top="5vh">
|
||||
<el-form :model="searhForm" inline>
|
||||
<el-form-item>
|
||||
<el-input v-model="searhForm.name" placeholder="商品名称" @input="onInput"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="searhForm.category" placeholder="商品分类">
|
||||
<el-option
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in categoryList"
|
||||
:key="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||
<el-button @click="resetHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="head-container">
|
||||
<el-table
|
||||
ref="table"
|
||||
:data="tableData.list"
|
||||
@select="firstSelectChange"
|
||||
v-loading="tableData.loading"
|
||||
:row-key="getRowKey"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="55"
|
||||
align="center"
|
||||
:reserve-selection="true"
|
||||
></el-table-column>
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
<el-image :src="scope.row.coverImg" style="width: 30px; height: 30px">
|
||||
<div class="img_error" slot="error">
|
||||
<i class="icon el-icon-document-delete"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.typeEnum }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否售罄">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.isPauseSale == 1 ? "是" : "否" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否分销">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.isDistribute == 1 ? "是" : "否" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="售价">
|
||||
<template v-slot="scope">¥{{ scope.row.lowPrice }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="销量/库存">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.realSalesNumber }}/{{ scope.row.stockNumber }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分类名称" prop="categoryName"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
:total="tableData.total"
|
||||
:current-page="tableData.page + 1"
|
||||
:page-size="tableData.size"
|
||||
@current-change="paginationChange"
|
||||
@size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmHandle">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
import consApi from "@/api/product/cons";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
searhForm: {
|
||||
name: "",
|
||||
category: "",
|
||||
},
|
||||
categoryList: [],
|
||||
tableData: {
|
||||
page: 0,
|
||||
size: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
list: [],
|
||||
},
|
||||
goods: [],
|
||||
// 是否单选
|
||||
isselect: false,
|
||||
stayselection: [], //待确认
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
reset() {
|
||||
this.$refs.table.clearSelection();
|
||||
},
|
||||
onInput: _.debounce(function (event) {
|
||||
//防抖请求
|
||||
this.getTableData();
|
||||
}, 500),
|
||||
onSelectionChange(selection) {
|
||||
this.stayselection = selection;
|
||||
},
|
||||
getRowKey(row) {
|
||||
return row.id;
|
||||
},
|
||||
firstSelectChange() {
|
||||
let selection = this.$refs.table.selection;
|
||||
if (selection.length > 1 && this.isselect) {
|
||||
const del_row = selection.shift();
|
||||
this.$refs.table.toggleRowSelection(del_row, false);
|
||||
}
|
||||
},
|
||||
// 确定选商品
|
||||
confirmHandle() {
|
||||
// let res = this.$refs.table.selection
|
||||
var uniqueArray = this.stayselection.filter(
|
||||
(item1) => !this.goods.some((item2) => item2.productId == item1.id)
|
||||
);
|
||||
this.$emit("success", uniqueArray);
|
||||
this.close();
|
||||
},
|
||||
// 是否单选
|
||||
isselectEvent() {
|
||||
this.isselect = true;
|
||||
},
|
||||
// 重置查询
|
||||
resetHandle() {
|
||||
this.searhForm.name = "";
|
||||
this.searhForm.category = "";
|
||||
this.tableData.page = 0;
|
||||
this.tableData.size = 10;
|
||||
this.tableData.list = [];
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页大小改变
|
||||
sizeChange(e) {
|
||||
this.tableData.size = e;
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页回调
|
||||
paginationChange(e) {
|
||||
this.tableData.page = e - 1;
|
||||
this.getTableData();
|
||||
},
|
||||
// 商品列表
|
||||
async getTableData() {
|
||||
this.tableData.loading = true;
|
||||
try {
|
||||
const res = await consApi.getpage({
|
||||
page: this.tableData.page,
|
||||
size: this.tableData.size,
|
||||
name: this.searhForm.name,
|
||||
categoryId: this.searhForm.category,
|
||||
sort: "id",
|
||||
});
|
||||
this.tableData.list = res.content;
|
||||
this.tableData.total = res.totalElements;
|
||||
|
||||
if (this.goods.length) {
|
||||
this.$nextTick(() => {
|
||||
this.selection();
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.tableData.loading = false;
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 商品分类
|
||||
async tbShopCategoryGet() {
|
||||
try {
|
||||
const res = await tbShopCategoryGet({
|
||||
page: 0,
|
||||
size: 100,
|
||||
sort: "id",
|
||||
shopId: localStorage.getItem("shopId"),
|
||||
});
|
||||
this.categoryList = res.content;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
show(goods) {
|
||||
this.dialogVisible = true;
|
||||
if (goods && goods.length) {
|
||||
this.goods = goods;
|
||||
} else {
|
||||
this.goods = [];
|
||||
}
|
||||
this.tbShopCategoryGet();
|
||||
this.resetHandle();
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
selection() {
|
||||
this.goods.forEach((row) => {
|
||||
this.tableData.list.forEach((item, index) => {
|
||||
if (row.id == item.id) {
|
||||
this.$refs.table.toggleRowSelection(this.tableData.list[index]);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.head-container {
|
||||
max-height: 60vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.shop_info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
687
src/views/inventory/operation_in/index.vue
Normal file
687
src/views/inventory/operation_in/index.vue
Normal file
@@ -0,0 +1,687 @@
|
||||
<template>
|
||||
<div class="app-container bg-fff u-m-20">
|
||||
<div class="head-container">
|
||||
<el-form
|
||||
ref="queryForm"
|
||||
:model="queryForm"
|
||||
:rules="queryRules"
|
||||
label-position="left"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="供应商">
|
||||
<el-select
|
||||
v-model="queryForm.purveyorId"
|
||||
placeholder="请选择供应商"
|
||||
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>
|
||||
{{ queryForm.waitAmount }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入库时间" prop="time">
|
||||
<el-date-picker
|
||||
v-model="queryForm.time"
|
||||
type="date"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择日期"
|
||||
style="width: 220px"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="应付金额">
|
||||
<el-input
|
||||
v-model="queryForm.totalAmount"
|
||||
placeholder="请输入应收金额"
|
||||
style="width: 220px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="实付金额">
|
||||
<el-input
|
||||
v-model="queryForm.paidAmount"
|
||||
placeholder="请输入实收金额"
|
||||
style="width: 220px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款时间">
|
||||
<el-date-picker
|
||||
v-model="queryForm.paidAt"
|
||||
type="date"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择日期"
|
||||
style="width: 220px"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="批号">
|
||||
<el-input
|
||||
v-model="queryForm.batchNumber"
|
||||
placeholder="请输入批号"
|
||||
style="width: 220px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="queryForm.remark"
|
||||
placeholder="请输入备注"
|
||||
style="width: 220px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="showHaocai" v-if="inTabValue == 'consumable'">
|
||||
选择耗材
|
||||
</el-button>
|
||||
<el-button type="primary" @click="$refs.shopList.show(tableData.list)" v-else>
|
||||
选择商品
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-autocomplete
|
||||
v-model="autocompletename"
|
||||
:fetch-suggestions="querySearchAsync"
|
||||
:value-key="inTabValue == 'goods' ? 'name' : 'conName'"
|
||||
:placeholder="inTabValue == 'goods' ? '商品搜索' : '耗材搜索'"
|
||||
@select="handleSelect"
|
||||
style="width: 500px"
|
||||
></el-autocomplete>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-button type="primary" plain v-if="inTabValue == 'consumable'">
|
||||
共{{ tableData.list.length }}种耗材,金额合计
|
||||
<span style="color: red">¥{{ queryForm.totalAmount }}</span>
|
||||
</el-button>
|
||||
<el-button type="primary" plain v-else>
|
||||
共{{ tableData.list.length }}种商品,金额合计
|
||||
<span style="color: red">¥{{ queryForm.totalAmount }}</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table :data="tableData.list" v-if="inTabValue == 'consumable'">
|
||||
<el-table-column label="耗材名称" prop="conName">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.conName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进价">
|
||||
<template v-slot="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.price"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
@change="consCountTotal($event, scope.row, 'price')"
|
||||
></el-input-number>
|
||||
<div class="tips" style="font-size: 16px">
|
||||
原价¥
|
||||
<!-- {{ scope.row.costPrice }}/{{ scope.row.conUnit }} -->
|
||||
|
||||
{{
|
||||
!scope.row.unit
|
||||
? scope.row.defaultUnit
|
||||
? scope.row.defaultUnit == scope.row.conUnitTwo
|
||||
? (scope.row.costPrice * scope.row.conUnitTwoConvert).toFixed(2)
|
||||
: scope.row.costPrice
|
||||
: scope.row.costPrice
|
||||
: scope.row.unit == scope.row.conUnitTwo
|
||||
? (scope.row.costPrice * scope.row.conUnitTwoConvert).toFixed(2)
|
||||
: scope.row.costPrice
|
||||
}}
|
||||
/
|
||||
{{
|
||||
!scope.row.unit
|
||||
? scope.row.defaultUnit
|
||||
? scope.row.defaultUnit
|
||||
: scope.row.conUnit
|
||||
: scope.row.unit
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位">
|
||||
<template v-slot="scope">
|
||||
<el-select
|
||||
@change="consCountTotal($event, scope.row, 'unit')"
|
||||
v-model="scope.row.unit"
|
||||
:placeholder="scope.row.defaultUnit ? scope.row.defaultUnit : scope.row.conUnit"
|
||||
>
|
||||
<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>
|
||||
<div class="tips"> </div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量">
|
||||
<template v-slot="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.stockNumber"
|
||||
:min="0"
|
||||
:step="1"
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
@change="consCountTotal($event, scope.row, 'stockNumber')"
|
||||
></el-input-number>
|
||||
<div class="tips" style="font-size: 16px">入库前:</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="小计">
|
||||
<template v-slot="scope">
|
||||
<!-- <el-input-number v-model="scope.row.totalAmount" :min="0" scope.row.price , scope.row.stockNumber
|
||||
controls-position="right"></el-input-number> -->
|
||||
<el-input :value="formatDecimal(testform(scope.row))" readonly style="width: 100px" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="变动后剩余库存">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.conUnit }}
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<el-button link @click="tableData.list.splice(scope.$index, 1), spliceclick()">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table :data="tableData.list" v-else>
|
||||
<el-table-column type="index" width="50"></el-table-column>
|
||||
<el-table-column label="商品名称" prop="name">
|
||||
<template v-slot="scope">
|
||||
<div class="name_wrap">
|
||||
<span class="name">{{ scope.row.name }}</span>
|
||||
<span v-if="scope.row.specSnap">({{ scope.row.specSnap }})</span>
|
||||
<!-- <el-tag type="info" v-if="scope.row.specSnap" size="mini">{{ scope.row.specSnap }}</el-tag> -->
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进价">
|
||||
<template v-slot="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.costPrice"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
@change="modifyPrice($event, scope.row, 'costPrice')"
|
||||
></el-input-number>
|
||||
<div class="tips">成本价¥{{ scope.row.costPrice }}/{{ scope.row.unitName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量">
|
||||
<template v-slot="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.number"
|
||||
:min="0"
|
||||
:step="1"
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
@change="modifyPrice($event, scope.row, 'number', 'totalAmount')"
|
||||
></el-input-number>
|
||||
<div class="tips" style="font-size: 16px">
|
||||
入库前:
|
||||
|
||||
{{
|
||||
!scope.row.unit
|
||||
? scope.row.defaultUnit
|
||||
? scope.row.defaultUnit == scope.row.conUnitTwo
|
||||
? scope.row.number / scope.row.conUnitTwoConvert
|
||||
: scope.row.number
|
||||
: scope.row.number
|
||||
: scope.row.unit == scope.row.conUnitTwo
|
||||
? scope.row.number / scope.row.conUnitTwoConvert
|
||||
: scope.row.number
|
||||
}}
|
||||
|
||||
{{
|
||||
!scope.row.unit
|
||||
? scope.row.defaultUnit
|
||||
? scope.row.defaultUnit
|
||||
: scope.row.conUnit
|
||||
: scope.row.unit
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="小计">
|
||||
<template v-slot="scope">
|
||||
<!-- <el-input-number v-model="scope.row.totalAmount" :min="0"
|
||||
controls-position="right"></el-input-number> -->
|
||||
<el-input
|
||||
:value="scope.row.costPrice * scope.row.number"
|
||||
readonly
|
||||
style="width: 100px"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="变动后剩余库存">
|
||||
<template v-slot="scope">
|
||||
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.unitName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template v-slot="scope">
|
||||
<el-button type="text" @click="tableData.list.splice(scope.$index, 1), spliceclick()">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" @click="submitHandle" :loading="queryFormLoading">确定</el-button>
|
||||
</div>
|
||||
<!-- 选择商品 -->
|
||||
<shopList ref="shopList" @success="selectShop" />
|
||||
<!-- 选择耗材 -->
|
||||
<ConsumableList ref="ConsumableList" @success="selectConsumable" />
|
||||
<el-dialog
|
||||
v-model="showResult"
|
||||
: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>
|
||||
<el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button>
|
||||
<router-link to="/invoicing/operating_record">
|
||||
<el-button size="medium">历史提交</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</template>
|
||||
</el-result>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vendorApi from "@/api/product/vendor";
|
||||
import stockApi from "@/api/product/stock";
|
||||
import dayjs from "dayjs";
|
||||
import shopList from "./components/shopList.vue";
|
||||
import ConsumableList from "./components/consumableList.vue";
|
||||
import { formatDecimal } from "@/utils/tools.js";
|
||||
export default {
|
||||
name: "operation_in",
|
||||
components: {
|
||||
shopList,
|
||||
ConsumableList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formatDecimal,
|
||||
inTabValue: "consumable",
|
||||
inTabs: [
|
||||
{
|
||||
label: "商品入库",
|
||||
value: "goods",
|
||||
type: "purveyor",
|
||||
},
|
||||
{
|
||||
label: "耗材入库",
|
||||
value: "consumable",
|
||||
type: "in",
|
||||
},
|
||||
],
|
||||
shopTypesActive: 0,
|
||||
shopTypes: [
|
||||
{
|
||||
label: "供应商入库",
|
||||
value: "purveyor",
|
||||
},
|
||||
{
|
||||
label: "其他入库",
|
||||
value: "purchase",
|
||||
},
|
||||
],
|
||||
shopTypes2: [
|
||||
{
|
||||
label: "供应商入库",
|
||||
value: "purveyor",
|
||||
},
|
||||
],
|
||||
resetForm: "",
|
||||
queryFormLoading: false,
|
||||
queryForm: {
|
||||
batchNumber: "",
|
||||
list: [],
|
||||
paidAmount: 0,
|
||||
paidAt: "",
|
||||
purveyorId: "",
|
||||
purveyorName: "",
|
||||
remark: "",
|
||||
time: dayjs().format("YYYY-MM-DD"),
|
||||
totalAmount: 0,
|
||||
type: "in",
|
||||
shopId: localStorage.getItem("shopId"),
|
||||
},
|
||||
queryRules: {
|
||||
purveyorId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择供应商",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
time: [
|
||||
{
|
||||
required: true,
|
||||
message: " ",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
},
|
||||
purveyorList: [],
|
||||
tableData: {
|
||||
list: [],
|
||||
},
|
||||
showResult: false,
|
||||
autocompletename: "",
|
||||
restaurants: [],
|
||||
timeout: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.resetForm = { ...this.queryForm };
|
||||
this.tbShopPurveyorGet();
|
||||
},
|
||||
methods: {
|
||||
showHaocai() {
|
||||
this.$refs.ConsumableList.show(this.tableData.list);
|
||||
},
|
||||
async querySearchAsync(queryString, cb) {
|
||||
//快捷搜索
|
||||
let res = null;
|
||||
if (this.inTabValue == "goods") {
|
||||
res = await tbProductlist({
|
||||
page: 0,
|
||||
size: 20,
|
||||
name: queryString ? queryString : "",
|
||||
shopId: localStorage.getItem("shopId"),
|
||||
sort: "id",
|
||||
});
|
||||
} else {
|
||||
res = await tbConsInfoGet({
|
||||
page: 0,
|
||||
size: 20,
|
||||
shopId: localStorage.getItem("shopId"),
|
||||
conName: queryString ? queryString : "",
|
||||
});
|
||||
}
|
||||
this.restaurants = res.content;
|
||||
if (res.content.length == 0) {
|
||||
//给个提示没有搜到
|
||||
this.$message("无此商品");
|
||||
return false;
|
||||
}
|
||||
var uniqueArray = this.restaurants.filter(
|
||||
(item1) => !this.tableData.list.some((item2) => item2.productId == item1.id)
|
||||
);
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
cb(uniqueArray);
|
||||
}, 1000 * Math.random());
|
||||
},
|
||||
testform(d) {
|
||||
let p = 1;
|
||||
if (d.unit && d.unit == d.conUnitTwo) {
|
||||
p = d.conUnitTwoConvert;
|
||||
}
|
||||
return d.price * d.stockNumber * p;
|
||||
},
|
||||
handleSelect(item) {
|
||||
//选定后清空
|
||||
this.autocompletename = "";
|
||||
if (this.inTabValue == "goods") {
|
||||
this.selectShop([item]);
|
||||
} else {
|
||||
this.selectConsumable([item]);
|
||||
}
|
||||
},
|
||||
//删除计算
|
||||
spliceclick() {
|
||||
var zong = 0;
|
||||
if (this.inTabValue == "goods") {
|
||||
this.tableData.list.forEach((ele) => {
|
||||
zong += ele.costPrice * ele.number;
|
||||
});
|
||||
} else {
|
||||
this.tableData.list.forEach((ele) => {
|
||||
let p = 1;
|
||||
if (ele.unit && ele.conUnitTwo == ele.unit) {
|
||||
p = ele.conUnitTwoConvert;
|
||||
}
|
||||
zong += ele.price * ele.stockNumber * p;
|
||||
});
|
||||
}
|
||||
this.queryForm.totalAmount = formatDecimal(zong);
|
||||
},
|
||||
// 选择商品
|
||||
selectShop(res) {
|
||||
let arr = [];
|
||||
res.forEach((item) => {
|
||||
item.skuList.forEach((i) => {
|
||||
arr.push({
|
||||
name: item.name,
|
||||
unitName: item.unitName,
|
||||
productId: item.id,
|
||||
number: 0,
|
||||
totalAmount: "",
|
||||
...i,
|
||||
});
|
||||
});
|
||||
});
|
||||
this.tableData.list = [...this.tableData.list, ...arr];
|
||||
},
|
||||
// 切换入库内容
|
||||
tabChange(value, type) {
|
||||
this.shopTypesActive = type == "in" ? 0 : 1;
|
||||
this.inTabValue = value;
|
||||
this.resetHandle();
|
||||
this.$refs.shopList.reset(); //清除选项
|
||||
this.$refs.ConsumableList.reset(); //清除选项
|
||||
},
|
||||
// 切换类型
|
||||
changeTypeEnum(index) {
|
||||
let filterd = this.purveyorList.filter((ele) => ele.id == index);
|
||||
this.queryForm.waitAmount = filterd[0].waitAmount;
|
||||
|
||||
this.inTabs.forEach((i) => {
|
||||
if (i.value == this.inTabValue) {
|
||||
this.queryForm.type = i.type;
|
||||
}
|
||||
});
|
||||
if (this.inTabValue == "consumable") {
|
||||
return false;
|
||||
}
|
||||
//商品入库是否显示应付实付
|
||||
if (this.queryForm.purveyorId) {
|
||||
this.shopTypesActive = 0;
|
||||
} else {
|
||||
this.shopTypesActive = 1;
|
||||
}
|
||||
},
|
||||
// 计算耗材总价
|
||||
consCountTotal(cvalue, row, key1, key2 = undefined) {
|
||||
if (cvalue == undefined) {
|
||||
setTimeout(() => {
|
||||
row[key1] = 0;
|
||||
|
||||
let zong = 0;
|
||||
this.tableData.list.forEach((ele) => {
|
||||
zong += ele.price * ele.stockNumber;
|
||||
});
|
||||
this.queryForm.totalAmount = formatDecimal(zong);
|
||||
}, 10);
|
||||
} else {
|
||||
row[key1] = cvalue;
|
||||
let zong = 0;
|
||||
this.tableData.list.forEach((ele) => {
|
||||
let p = 1;
|
||||
if (ele.unit && ele.conUnitTwo == ele.unit) {
|
||||
p = ele.conUnitTwoConvert;
|
||||
}
|
||||
zong += ele.price * ele.stockNumber * p;
|
||||
});
|
||||
this.queryForm.totalAmount = formatDecimal(zong);
|
||||
}
|
||||
},
|
||||
// 计算商品总价
|
||||
modifyPrice(cvalue, row, key1, key2 = undefined) {
|
||||
if (cvalue == undefined) {
|
||||
setTimeout(() => {
|
||||
row[key1] = 0;
|
||||
row[key2] = 0;
|
||||
|
||||
let zong = 0;
|
||||
this.tableData.list.forEach((ele) => {
|
||||
zong += ele.costPrice * ele.number;
|
||||
});
|
||||
this.queryForm.totalAmount = formatDecimal(zong);
|
||||
}, 10);
|
||||
} else {
|
||||
row[key1] = cvalue;
|
||||
row[key2] = cvalue;
|
||||
let zong = 0;
|
||||
this.tableData.list.forEach((ele) => {
|
||||
zong += ele.costPrice * ele.number;
|
||||
});
|
||||
this.queryForm.totalAmount = formatDecimal(zong);
|
||||
}
|
||||
},
|
||||
// 提交
|
||||
submitHandle() {
|
||||
if (this.tableData.list.length == 0) {
|
||||
switch (this.inTabValue) {
|
||||
case "goods":
|
||||
this.$message("请先选择商品!");
|
||||
break;
|
||||
case "consumable":
|
||||
this.$message("请先选择耗材!");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
this.$refs.queryForm.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
this.queryFormLoading = true;
|
||||
switch (this.inTabValue) {
|
||||
case "goods":
|
||||
this.queryForm.list = this.tableData.list;
|
||||
await tbProductStockOperateOutAndOn(this.queryForm);
|
||||
break;
|
||||
case "consumable":
|
||||
this.queryForm.accountsPayable = this.queryForm.totalAmount;
|
||||
this.queryForm.actualPayment = this.queryForm.paidAmount;
|
||||
this.queryForm.paymentTime = this.queryForm.paidAt;
|
||||
this.queryForm.supplierId = this.queryForm.purveyorId;
|
||||
this.queryForm.list = this.tableData.list;
|
||||
await stockApi.in(this.queryForm);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.queryFormLoading = false;
|
||||
this.$message({
|
||||
message: "入库提交成功",
|
||||
type: "success",
|
||||
});
|
||||
this.resetHandle(); //初始化
|
||||
// this.showResult = true
|
||||
// this.$refs.shopList.reset()//清除选项
|
||||
// this.$refs.ConsumableList.reset()//清除选项
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.queryFormLoading = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 选择耗材
|
||||
selectConsumable(res) {
|
||||
console.log(res);
|
||||
let arr = res.map((item) => {
|
||||
item.number = formatDecimal(item.stockNumber - item.stockConsume, 2, true);
|
||||
item.stockNumber = 0;
|
||||
item.costPrice = item.price;
|
||||
item.conInfoId = item.id;
|
||||
return item;
|
||||
});
|
||||
this.tableData.list = [...this.tableData.list, ...arr];
|
||||
},
|
||||
|
||||
// 初始化
|
||||
resetHandle() {
|
||||
this.showResult = false;
|
||||
this.queryForm = { ...this.resetForm };
|
||||
if (this.inTabValue == "goods") {
|
||||
this.queryForm.type = "purveyor";
|
||||
} else {
|
||||
this.queryForm.type = this.inTabs.find((item) => item.value == this.inTabValue).type;
|
||||
}
|
||||
this.tableData.list = [];
|
||||
this.$refs.queryForm.resetFields();
|
||||
this.$refs.queryForm.resetFields();
|
||||
},
|
||||
|
||||
// 获取供应商列表
|
||||
async tbShopPurveyorGet() {
|
||||
try {
|
||||
const res = await vendorApi.getList({});
|
||||
this.purveyorList = res.records;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.name_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.app-container {
|
||||
}
|
||||
</style>
|
||||
6
src/views/inventory/payment-record.vue
Normal file
6
src/views/inventory/payment-record.vue
Normal file
@@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<!-- 结款记录 -->
|
||||
<div style="padding: 15px">结款记录</div>
|
||||
</template>
|
||||
<script setup>
|
||||
</script>
|
||||
@@ -1,146 +0,0 @@
|
||||
<template>
|
||||
<div class="Table">
|
||||
<!-- 按钮 -->
|
||||
<AddButton @add="add"></AddButton>
|
||||
<!-- 表格 -->
|
||||
<Table :list="datas.tableData" @handleDelete="handleDelete" @handleEdit="handleEdit"></Table>
|
||||
<!-- 分页 -->
|
||||
<Paging :pagingConfig="datas.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
|
||||
<!-- 其他模板 -->
|
||||
<!-- 新增/编辑 -->
|
||||
<myDialog ref="myDialogRef" :title="datas.title" @confirm="confirm" width="30%">
|
||||
<el-form ref="ruleFormRef" :rules="datas.rules" :model="datas.DialogForm" label-width="80px">
|
||||
<el-form-item label="供应商" prop="name">
|
||||
<el-input v-model="datas.DialogForm.name" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="datas.DialogForm.telephone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="datas.DialogForm.address" placeholder="请输入地址" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="datas.DialogForm.remark" placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</myDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import AddButton from './component/AddButton.vue'
|
||||
import Table from './component/Table.vue'
|
||||
import Paging from './component/Paging.vue'
|
||||
import myDialog from '@/components/mycomponents/myDialog.vue'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import API from './api'
|
||||
|
||||
const datas = reactive({
|
||||
tableData: [], // 表格数据
|
||||
title: '新增数据',
|
||||
pagingConfig: {
|
||||
total: 0, // 总数
|
||||
pageSize: 10, // 每页数据数量
|
||||
pageNumber: 1, // 当前页码
|
||||
},
|
||||
DialogForm: { // 弹窗表单数据
|
||||
name: "",
|
||||
telephone: "",
|
||||
address: "",
|
||||
remark: ""
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '请输入供应商名称', trigger: 'blur' },
|
||||
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
})
|
||||
const myDialogRef = ref(null)
|
||||
const ruleFormRef = ref(null)
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
eventBus.on('search', (res) => {
|
||||
getList(res)
|
||||
})
|
||||
async function getList(data = {}) {
|
||||
const res = await API.getPage({ page: datas.pagingConfig.pageNumber, size: datas.pagingConfig.pageSize, ...data })
|
||||
datas.tableData = res.records
|
||||
datas.pagingConfig.total = res.totalRow
|
||||
datas.pagingConfig.pageSize = res.pageSize
|
||||
datas.pagingConfig.pageNumber = res.pageNumber
|
||||
}
|
||||
function add() {
|
||||
rest()
|
||||
datas.title = '新增数据'
|
||||
myDialogRef.value.open()
|
||||
}
|
||||
async function handleEdit(row) {
|
||||
datas.title = '编辑数据'
|
||||
const res = await API.getinfo(row.id)
|
||||
datas.DialogForm = res
|
||||
myDialogRef.value.open()
|
||||
}
|
||||
async function confirm() {
|
||||
ruleFormRef.value.validate(async valid => {
|
||||
if (valid) {
|
||||
let res = null
|
||||
if (datas.title == '新增数据') {
|
||||
res = await API.add(datas.DialogForm)
|
||||
} else {
|
||||
res = await API.update(datas.DialogForm)
|
||||
}
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '成功',
|
||||
type: 'success',
|
||||
})
|
||||
rest()
|
||||
getList()
|
||||
myDialogRef.value.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 重置
|
||||
function rest() {
|
||||
datas.DialogForm = { sort: "1" }
|
||||
}
|
||||
async function handleDelete(id) {
|
||||
ElMessageBox.confirm("是否删除数据项?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(
|
||||
async () => {
|
||||
let res = await API.deleteByIds(id)
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
})
|
||||
getList()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// 分页
|
||||
function sizeChange(val) {
|
||||
datas.pagingConfig.pageSize = val
|
||||
getList()
|
||||
}
|
||||
function currentChange(val) {
|
||||
datas.pagingConfig.pageNumber = val
|
||||
getList()
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.Table {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
margin-top: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<div class="DataStatistics">
|
||||
<div style="width: 200px;">
|
||||
<el-icon class="iconStyle">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<span>耗材种数</span>
|
||||
<span>{{ datas.totalRow }}</span>
|
||||
</div>
|
||||
<div style="width: 300px;">
|
||||
<el-icon class="iconStyle">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<div>
|
||||
<div><span>增加数量:</span><span>0</span></div>
|
||||
<div style="display: flex;">
|
||||
<div>
|
||||
<span>手动增加:</span><span>0</span>
|
||||
</div>
|
||||
<span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>入库:</span><span>0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 500px;">
|
||||
<el-icon class="iconStyle">
|
||||
<UserFilled />
|
||||
</el-icon>
|
||||
<div>
|
||||
<div><span>减少数量:</span><span>0</span></div>
|
||||
<div style="display: flex;">
|
||||
<div>
|
||||
<span>手动减少:</span><span>0</span>
|
||||
</div>
|
||||
<span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>消耗:</span><span>0</span>
|
||||
</div>
|
||||
<span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>报损:</span><span>0</span>
|
||||
</div><span style="margin: 0 20px;color: #ccc;">|</span>
|
||||
<div>
|
||||
<span>出库:</span><span>0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import API from "@/api/product/index";
|
||||
import { onMounted, reactive } from "vue";
|
||||
onMounted(() => {
|
||||
getPage();
|
||||
})
|
||||
let datas = reactive({
|
||||
totalRow: 0
|
||||
})
|
||||
async function getPage() {
|
||||
let res = await API.getPage();
|
||||
datas.totalRow = res.totalRow
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.DataStatistics {
|
||||
border: 1px solid #e4e7ed;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
>div {
|
||||
height: 80px;
|
||||
background-color: #f4f9ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
padding: 20px;
|
||||
|
||||
.iconStyle {
|
||||
background-color: #d4e9fe;
|
||||
border-radius: 50%;
|
||||
padding: 6px;
|
||||
font-size: 36px;
|
||||
color: #3f9eff;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<div class="Search">
|
||||
<el-form :inline="true" :model="formInline" class="demo-form-inline">
|
||||
<el-form-item label="耗材分类">
|
||||
<el-select v-model="formInline.region" placeholder="请选择耗材分类" clearable>
|
||||
<el-option label="Zone one" value="shanghai" />
|
||||
<el-option label="Zone two" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="耗材名称">
|
||||
<el-input v-model="formInline.user" placeholder="请输入耗材名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker v-model="formInline.value1" type="daterange" range-separator="-" start-placeholder="开始日期"
|
||||
end-placeholder="结束日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排列方式">
|
||||
<el-select v-model="formInline.region" placeholder="请选择排列方式" clearable>
|
||||
<el-option label="创建时间" value="shanghai" />
|
||||
<el-option label="数量由低到高" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="onSubmit">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import eventBus from '@/utils/eventBus'
|
||||
const formInline = reactive({
|
||||
user: '',
|
||||
region: '',
|
||||
date: '',
|
||||
value1: ""
|
||||
})
|
||||
const onSubmit = () => {
|
||||
eventBus.emit('search', formInline)
|
||||
}
|
||||
const reset = () => {
|
||||
formInline.user = ''
|
||||
formInline.region = ''
|
||||
formInline.date = ''
|
||||
formInline.value1 = ''
|
||||
eventBus.emit('search', formInline)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.Search {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-input {
|
||||
--el-input-width: 220px;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-select {
|
||||
--el-select-width: 220px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,60 +0,0 @@
|
||||
import request from "@/utils/request";
|
||||
const baseURL = "/product/admin/prod/group";
|
||||
// XXX-配置
|
||||
const AuthAPI = {
|
||||
// 列表
|
||||
getList(params: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/list`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
},
|
||||
/** 分页*/
|
||||
getPage(params: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/page`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
},
|
||||
// 新增
|
||||
add(data: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}`,
|
||||
method: "post",
|
||||
data: { ...data },
|
||||
});
|
||||
},
|
||||
// 详情
|
||||
getinfo(id: number) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
// 编辑
|
||||
update(data: Object) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}`,
|
||||
method: "put",
|
||||
data,
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteByIds(id: number | String) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
export interface Responseres {
|
||||
code?: number | null;
|
||||
data?: any;
|
||||
msg?: null | string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
export default AuthAPI;
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<el-button type="primary" icon="Plus" @click="addEvent">新增</el-button>
|
||||
<el-button @click="toUrl('supplier')">其他按钮</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter();
|
||||
const emit = defineEmits(['add']);
|
||||
function toUrl(name) {
|
||||
router.push({ name });
|
||||
}
|
||||
function addEvent() {
|
||||
emit('add');
|
||||
}
|
||||
</script>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-pagination background :page-size="props.pagingConfig.pageSize" :page-sizes="[10, 20, 30, 40]"
|
||||
layout="prev,pager,next,jumper,total,sizes" v-model:current-page="props.pagingConfig.pageNumber"
|
||||
:total="props.pagingConfig.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
pagingConfig: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['sizeChange', 'currentChange'])
|
||||
// 当前条改变
|
||||
function handleSizeChange(val) {
|
||||
emit('sizeChange', val)
|
||||
}
|
||||
// 当前页改变
|
||||
function handleCurrentChange(val) {
|
||||
emit('currentChange', val)
|
||||
}
|
||||
</script>
|
||||
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-table :data="props.list" border style="width: 100%">
|
||||
<el-table-column prop="date" label="Date" width="180" />
|
||||
<el-table-column prop="name" label="Name" width="180" />
|
||||
<el-table-column prop="address" label="Address" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" link icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" link icon="Delete" style="color: #f89797;"
|
||||
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const emit = defineEmits(['handleDelete'])
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
function handleEdit(row) {
|
||||
emit('handleEdit', row)
|
||||
}
|
||||
async function handleDelete(index, row) {
|
||||
emit('handleDelete', row.id)
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<!-- 供应商管理模块 -->
|
||||
<div style="padding: 15px;">
|
||||
<!-- 搜索 -->
|
||||
<Search></Search>
|
||||
<!-- 表格 -->
|
||||
<Content></Content>
|
||||
<!-- 其他内容 -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import Search from './supplierconfig/Search.vue'
|
||||
import Content from './supplierconfig/Content.vue'
|
||||
</script>
|
||||
77
src/views/inventory/supplier/config/add.ts
Normal file
77
src/views/inventory/supplier/config/add.ts
Normal 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);
|
||||
48
src/views/inventory/supplier/config/config.ts
Normal file
48
src/views/inventory/supplier/config/config.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
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 : "";
|
||||
}
|
||||
|
||||
79
src/views/inventory/supplier/config/content.ts
Normal file
79
src/views/inventory/supplier/config/content.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import Api from "@/api/product/vendor";
|
||||
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({});
|
||||
},
|
||||
deleteAction: function (id) {
|
||||
return Api.delete(id);
|
||||
},
|
||||
modifyAction: function (data) {
|
||||
return Api.edit(data);
|
||||
},
|
||||
pk: "id",
|
||||
toolbar: ["add"],
|
||||
defaultToolbar: ["refresh", "filter", "search"],
|
||||
cols: [
|
||||
// { type: "selection", width: 50, align: "center" },
|
||||
{
|
||||
label: "供应商",
|
||||
align: "center",
|
||||
prop: "name",
|
||||
},
|
||||
{
|
||||
label: "联系人",
|
||||
align: "center",
|
||||
prop: "contactName",
|
||||
},
|
||||
{
|
||||
label: "联系人电话",
|
||||
align: "center",
|
||||
prop: "telephone",
|
||||
},
|
||||
{
|
||||
label: "地址",
|
||||
align: "center",
|
||||
prop: "address",
|
||||
},
|
||||
{
|
||||
label: "备注",
|
||||
align: "center",
|
||||
prop: "remark",
|
||||
},
|
||||
{
|
||||
label: "创建时间",
|
||||
align: "center",
|
||||
prop: "createTime",
|
||||
},
|
||||
{
|
||||
label: "状态",
|
||||
align: "center",
|
||||
prop: "status",
|
||||
templet: 'custom',
|
||||
slotName: 'switch'
|
||||
},
|
||||
|
||||
{
|
||||
label: "操作",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 280,
|
||||
templet: "tool",
|
||||
operat: ["edit", 'delete'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default contentConfig;
|
||||
77
src/views/inventory/supplier/config/edit.ts
Normal file
77
src/views/inventory/supplier/config/edit.ts
Normal 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.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);
|
||||
21
src/views/inventory/supplier/config/search.ts
Normal file
21
src/views/inventory/supplier/config/search.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { ISearchConfig } from "@/components/CURD/types";
|
||||
|
||||
const searchConfig: ISearchConfig = {
|
||||
pageName: "sys:user",
|
||||
formItems: [
|
||||
{
|
||||
type: "input",
|
||||
label: "版本号",
|
||||
prop: "keywords",
|
||||
attrs: {
|
||||
placeholder: "请输入版本号",
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "200px",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default searchConfig;
|
||||
115
src/views/inventory/supplier/index.vue
Normal file
115
src/views/inventory/supplier/index.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<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 #status="scope">
|
||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #options="scope">
|
||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||
</template>
|
||||
<template #switch="scope">
|
||||
<el-switch
|
||||
v-model="scope.row[scope.prop]"
|
||||
disabled
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
</template>
|
||||
<template #mobile="scope">
|
||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||
<copy-button
|
||||
v-if="scope.row[scope.prop]"
|
||||
:text="scope.row[scope.prop]"
|
||||
style="margin-left: 2px"
|
||||
/>
|
||||
</template>
|
||||
</page-content>
|
||||
|
||||
<!-- 新增 -->
|
||||
<page-modal
|
||||
ref="addModalRef"
|
||||
:modal-config="addModalConfig"
|
||||
@submit-click="handleSubmitClick"
|
||||
></page-modal>
|
||||
|
||||
<!-- 编辑 -->
|
||||
<page-modal
|
||||
ref="editModalRef"
|
||||
:modal-config="editModalConfig"
|
||||
@submit-click="handleSubmitClick"
|
||||
></page-modal>
|
||||
</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 { returnOptionsLabel } from "./config/config";
|
||||
|
||||
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获取数据进行填充
|
||||
console.log(row);
|
||||
editModalRef.value?.setFormData({ ...row });
|
||||
}
|
||||
1;
|
||||
// 其他工具栏
|
||||
function handleToolbarClick(name: string) {
|
||||
console.log(name);
|
||||
if (name === "custom1") {
|
||||
ElMessage.success("点击了自定义1按钮");
|
||||
}
|
||||
}
|
||||
// 其他操作列
|
||||
async function handleOperatClick(data: IOperatData) {
|
||||
console.log(data);
|
||||
}
|
||||
</script>
|
||||
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<div class="Table">
|
||||
<!-- 按钮 -->
|
||||
<AddButton @add="add"></AddButton>
|
||||
<!-- 表格 -->
|
||||
<Table :list="datas.tableData" @handleDelete="handleDelete" @handleEdit="handleEdit"></Table>
|
||||
<!-- 分页 -->
|
||||
<Paging :pagingConfig="datas.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
|
||||
<!-- 其他模板 -->
|
||||
<!-- 新增/编辑 -->
|
||||
<myDialog ref="myDialogRef" :title="datas.title" @confirm="confirm" width="30%">
|
||||
<el-form ref="ruleFormRef" :rules="datas.rules" :model="datas.DialogForm" label-width="80px">
|
||||
<el-form-item label="供应商" prop="name">
|
||||
<el-input v-model="datas.DialogForm.name" placeholder="请输入供应商名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="datas.DialogForm.telephone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="datas.DialogForm.address" placeholder="请输入地址" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="datas.DialogForm.remark" placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</myDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import AddButton from './component/AddButton.vue'
|
||||
import Table from './component/Table.vue'
|
||||
import Paging from './component/Paging.vue'
|
||||
import myDialog from '@/components/mycomponents/myDialog.vue'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import API from './api'
|
||||
|
||||
const datas = reactive({
|
||||
tableData: [], // 表格数据
|
||||
title: '新增数据',
|
||||
pagingConfig: {
|
||||
total: 0, // 总数
|
||||
pageSize: 10, // 每页数据数量
|
||||
pageNumber: 1, // 当前页码
|
||||
},
|
||||
DialogForm: { // 弹窗表单数据
|
||||
name: "",
|
||||
telephone: "",
|
||||
address: "",
|
||||
remark: "",
|
||||
sort: "1",
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '请输入供应商名称', trigger: 'blur' }
|
||||
],
|
||||
}
|
||||
})
|
||||
const myDialogRef = ref(null)
|
||||
const ruleFormRef = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
eventBus.on('search', (res) => {
|
||||
getList(res)
|
||||
})
|
||||
async function getList(data = {}) {
|
||||
const res = await API.getPage({ page: datas.pagingConfig.pageNumber, size: datas.pagingConfig.pageSize, ...data })
|
||||
datas.tableData = res.records
|
||||
datas.pagingConfig.total = res.totalRow
|
||||
datas.pagingConfig.pageSize = res.pageSize
|
||||
datas.pagingConfig.pageNumber = res.pageNumber
|
||||
}
|
||||
function add() {
|
||||
rest()
|
||||
datas.title = '新增数据'
|
||||
myDialogRef.value.open()
|
||||
}
|
||||
async function handleEdit(row) {
|
||||
datas.title = '编辑数据'
|
||||
const res = await API.getinfo(row.id)
|
||||
datas.DialogForm = res
|
||||
myDialogRef.value.open()
|
||||
}
|
||||
async function confirm() {
|
||||
ruleFormRef.value.validate(async valid => {
|
||||
if (valid) {
|
||||
let res = null
|
||||
if (datas.title == '新增数据') {
|
||||
res = await API.add(datas.DialogForm)
|
||||
} else {
|
||||
res = await API.update(datas.DialogForm)
|
||||
}
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '成功',
|
||||
type: 'success',
|
||||
})
|
||||
getList()
|
||||
rest()
|
||||
myDialogRef.value.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 重置
|
||||
function rest() {
|
||||
datas.DialogForm = { sort: "1" }
|
||||
}
|
||||
async function handleDelete(id) {
|
||||
ElMessageBox.confirm("是否删除数据项?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(
|
||||
async () => {
|
||||
let res = await API.deleteByIds(id)
|
||||
if (res.code == 200) {
|
||||
ElMessage({
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
})
|
||||
getList()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// 分页
|
||||
function sizeChange(val) {
|
||||
datas.pagingConfig.pageSize = val
|
||||
getList()
|
||||
}
|
||||
function currentChange(val) {
|
||||
datas.pagingConfig.pageNumber = val
|
||||
getList()
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.Table {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
margin-top: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,52 +0,0 @@
|
||||
<template>
|
||||
<div class="Search">
|
||||
<el-form :inline="true" :model="formInline" class="demo-form-inline">
|
||||
<el-form-item label="供应商:">
|
||||
<el-input v-model="formInline.name" placeholder="请输入供应商" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型:">
|
||||
<el-select v-model="formInline.region" placeholder="请选择类型" clearable>
|
||||
<el-option label="进货" value="shanghai" />
|
||||
<el-option label="退货" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="onSubmit">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import eventBus from '@/utils/eventBus'
|
||||
const formInline = reactive({
|
||||
name: '',
|
||||
region: '',
|
||||
})
|
||||
const onSubmit = () => {
|
||||
eventBus.emit('search', formInline)
|
||||
}
|
||||
const reset = () => {
|
||||
formInline.name = ''
|
||||
formInline.region = ''
|
||||
eventBus.emit('search', formInline)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.Search {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-input {
|
||||
--el-input-width: 220px;
|
||||
}
|
||||
|
||||
.demo-form-inline .el-select {
|
||||
--el-select-width: 220px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,60 +0,0 @@
|
||||
import request from "@/utils/request";
|
||||
const baseURL = "/product/admin/product/vendor";
|
||||
// 供应商管理
|
||||
const AuthAPI = {
|
||||
// 列表
|
||||
getList(params: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/list`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
},
|
||||
/** 分页*/
|
||||
getPage(params: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/page`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
},
|
||||
// 新增
|
||||
add(data: any) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}`,
|
||||
method: "post",
|
||||
data: { ...data },
|
||||
});
|
||||
},
|
||||
// 详情
|
||||
getinfo(id: number) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
// 编辑
|
||||
update(data: Object) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}`,
|
||||
method: "put",
|
||||
data,
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteByIds(id: number | String) {
|
||||
return request<any, Responseres>({
|
||||
url: `${baseURL}/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
export interface Responseres {
|
||||
code?: number | null;
|
||||
data?: any;
|
||||
msg?: null | string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
export default AuthAPI;
|
||||
@@ -1,9 +0,0 @@
|
||||
<template>
|
||||
<el-button type="primary" icon="Plus" @click="addEvent">新增</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
const emit = defineEmits(['add']);
|
||||
function addEvent() {
|
||||
emit('add');
|
||||
}
|
||||
</script>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-pagination background :page-size="props.pagingConfig.pageSize" :page-sizes="[10, 20, 30, 40]"
|
||||
layout="prev,pager,next,jumper,total,sizes" v-model:current-page="props.pagingConfig.pageNumber"
|
||||
:total="props.pagingConfig.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
pagingConfig: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['sizeChange', 'currentChange'])
|
||||
// 当前条改变
|
||||
function handleSizeChange(val) {
|
||||
emit('sizeChange', val)
|
||||
}
|
||||
// 当前页改变
|
||||
function handleCurrentChange(val) {
|
||||
emit('currentChange', val)
|
||||
}
|
||||
</script>
|
||||
@@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<div style="margin-top: 10px;">
|
||||
<el-table :data="props.list" border style="width: 100%">
|
||||
<el-table-column prop="name" label="供应商" />
|
||||
<el-table-column prop="telephone" label="联系电话" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
<el-table-column prop="remark" label="备注" />
|
||||
|
||||
<el-table-column prop="date" label="剩余付款金额" />
|
||||
<el-table-column prop="date" label="待付款笔数" />
|
||||
<el-table-column prop="date" label="状态" />
|
||||
|
||||
<el-table-column prop="lastTransactTime" label="上笔进货日期" />
|
||||
<el-table-column label="操作" width="250">
|
||||
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" link icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" link icon="Delete" style="color: #f89797;"
|
||||
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button>
|
||||
<el-button size="small" type="primary" link @click="PaymentRecord()">结款记录</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
const router = useRouter()
|
||||
const emit = defineEmits(['handleDelete'])
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
function handleEdit(row) {
|
||||
emit('handleEdit', row)
|
||||
}
|
||||
async function handleDelete(index, row) {
|
||||
emit('handleDelete', row.id)
|
||||
}
|
||||
function PaymentRecord() {
|
||||
router.push({ name: 'paymentRecord' });
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -192,6 +192,7 @@ function handleLogin() {
|
||||
.login(user)
|
||||
.then(async (res) => {
|
||||
await userStore.getUserInfo();
|
||||
await $douyin_checkIn();
|
||||
|
||||
const { path, queryParams } = parseRedirect();
|
||||
console.log(res, "Denglv返回");
|
||||
|
||||
@@ -296,6 +296,7 @@ export default {
|
||||
reset() {
|
||||
this.user = "";
|
||||
this.allSelected = false;
|
||||
this.$emit("close");
|
||||
},
|
||||
returnPayType(payType) {
|
||||
if (!payType) {
|
||||
@@ -375,7 +376,7 @@ export default {
|
||||
if (item === "all") {
|
||||
for (let i in this.detail.detailMap) {
|
||||
this.detail.detailMap[i].map((v) => {
|
||||
if (v.checked) {
|
||||
if (v.checked && v.selNumber) {
|
||||
arr.push(v);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
</template>
|
||||
</page-modal>
|
||||
|
||||
<orderDetail ref="refDetail"></orderDetail>
|
||||
<orderDetail ref="refDetail" @close="refresh"></orderDetail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -135,6 +135,11 @@ const {
|
||||
handleFilterChange,
|
||||
} = usePage();
|
||||
|
||||
function refresh() {
|
||||
console.log("refresh");
|
||||
contentRef.value?.fetchPageData();
|
||||
}
|
||||
|
||||
//计算订单原金额
|
||||
function returnOriginAmount(order: OrderInfoVo) {
|
||||
let amount = 0;
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
<el-input v-model="form.alipayAppToken" placeholder="请输入支付宝商户密钥"></el-input>
|
||||
</el-form-item> -->
|
||||
|
||||
<el-form-item label="状态">
|
||||
<!-- <el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :value="1">启用</el-radio>
|
||||
<el-radio :value="-1">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
@@ -757,7 +757,7 @@ $pl: 30px;
|
||||
display: flex;
|
||||
max-height: calc(100vh - 256px);
|
||||
.left {
|
||||
width: 1;
|
||||
flex: 1;
|
||||
padding-right: 14px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
@@ -770,7 +770,7 @@ $pl: 30px;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 3;
|
||||
flex: 4;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
&::-webkit-scrollbar {
|
||||
|
||||
Reference in New Issue
Block a user