This commit is contained in:
parent
6a86e5fa99
commit
0181a84b01
|
@ -3,8 +3,8 @@ VITE_NOW_TYPE = 'dist'
|
||||||
# Base API
|
# Base API
|
||||||
# VITE_APP_BASE_URL='http://192.168.1.13:8546'
|
# VITE_APP_BASE_URL='http://192.168.1.13:8546'
|
||||||
|
|
||||||
# VITE_PUSH_URL = 'ws://192.168.1.22:8787'
|
VITE_PUSH_URL = 'ws://192.168.1.22:8787'
|
||||||
# VITE_APP_BASE_URL = 'http://192.168.1.22:8546'
|
VITE_APP_BASE_URL = 'http://192.168.1.22:8546'
|
||||||
|
|
||||||
VITE_PUSH_URL ='wss://erp.lihaink.cn/pull'
|
# VITE_PUSH_URL ='wss://erp.lihaink.cn/pull'
|
||||||
VITE_APP_BASE_URL='https://erp.lihaink.cn'
|
# VITE_APP_BASE_URL='https://erp.lihaink.cn'
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 供应商报价日期列表
|
||||||
|
*/
|
||||||
|
export function opurchaseGoodsOfferDateListsApi(params: any) {
|
||||||
|
return request.get({ url: "/operation/OpurchaseGoodsOffer/date_lists", params });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 供应商报价列表
|
||||||
|
*/
|
||||||
|
export function opurchaseGoodsOfferListsApi(params: any) {
|
||||||
|
return request.get({ url: "/operation/OpurchaseGoodsOffer/lists", params });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 提交报价
|
||||||
|
*/
|
||||||
|
export function opurchaseGoodsOfferOfferApi(params: any) {
|
||||||
|
return request.post({ url: "/operation/OpurchaseGoodsOffer/offer", params });
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
export enum PageEnum {
|
export enum PageEnum {
|
||||||
//登录页面
|
//登录页面
|
||||||
LOGIN = '/login',
|
LOGIN = '/login',
|
||||||
|
ADMIN_LOGIN = '/admin_login',
|
||||||
//无权限页面
|
//无权限页面
|
||||||
ERROR_403 = '/403',
|
ERROR_403 = '/403',
|
||||||
INDEX = '/'
|
INDEX = '/'
|
||||||
|
|
|
@ -13,6 +13,7 @@ export enum RequestMethodsEnum {
|
||||||
export enum RequestCodeEnum {
|
export enum RequestCodeEnum {
|
||||||
SUCCESS = 1,
|
SUCCESS = 1,
|
||||||
FAIL = 0,
|
FAIL = 0,
|
||||||
|
SERVER_ERROR = 500,
|
||||||
LOGIN_FAILURE = -1,
|
LOGIN_FAILURE = -1,
|
||||||
OPEN_NEW_PAGE = 2
|
OPEN_NEW_PAGE = 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import LayoutMain from './components/main.vue'
|
||||||
import LayoutSidebar from './components/sidebar/index.vue'
|
import LayoutSidebar from './components/sidebar/index.vue'
|
||||||
import LayoutHeader from './components/header/index.vue'
|
import LayoutHeader from './components/header/index.vue'
|
||||||
import { Push } from "@/common/push.js";
|
import { Push } from "@/common/push.js";
|
||||||
|
import { print } from "@/utils/print";
|
||||||
|
|
||||||
const connection = new Push({
|
const connection = new Push({
|
||||||
url: import.meta.env.VITE_PUSH_URL, // websocket地址
|
url: import.meta.env.VITE_PUSH_URL, // websocket地址
|
||||||
|
@ -30,11 +31,63 @@ const connection = new Push({
|
||||||
const user_channel = connection.subscribe(`platform_1`);
|
const user_channel = connection.subscribe(`platform_1`);
|
||||||
// const user_channel = connection.subscribe(`store_merchant_${1}`);
|
// const user_channel = connection.subscribe(`store_merchant_${1}`);
|
||||||
|
|
||||||
|
// setTimeout(()=>{
|
||||||
|
|
||||||
|
// print(
|
||||||
|
// {
|
||||||
|
// id: 405,
|
||||||
|
// merchant: 501,
|
||||||
|
// real_name: '阿哈',
|
||||||
|
// user_phone: '19330904744',
|
||||||
|
// user_address: '里海三楼',
|
||||||
|
// uid: '9',
|
||||||
|
// number: 'PF171617436315965155',
|
||||||
|
// total: '0.02',
|
||||||
|
// actual: '0.02',
|
||||||
|
// create_time: '2024-05-20 11:06:03',
|
||||||
|
// mer_name: '莲花农贸市场',
|
||||||
|
// mer_phone: '15566669999',
|
||||||
|
// mer_nickname: '小明',
|
||||||
|
// mer_user_mobile: '',
|
||||||
|
// nickname: '用户1532345',
|
||||||
|
// user_moblie: '19330904747',
|
||||||
|
// info: [
|
||||||
|
// {
|
||||||
|
// goods: 317,
|
||||||
|
// nums: '1.00',
|
||||||
|
// price: '0.02',
|
||||||
|
// total: '0.02',
|
||||||
|
// unit_name: '斤',
|
||||||
|
// goods_name: '西瓜'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// goods: 317,
|
||||||
|
// nums: '1.56',
|
||||||
|
// price: '1.98',
|
||||||
|
// total: '3.09',
|
||||||
|
// unit_name: '斤',
|
||||||
|
// goods_name: '苹果'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// goods: 317,
|
||||||
|
// nums: '2.58',
|
||||||
|
// price: '3.68',
|
||||||
|
// total: '9.49',
|
||||||
|
// unit_name: '斤',
|
||||||
|
// goods_name: '香蕉'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }, 1000)
|
||||||
|
|
||||||
// 当user-2频道有message事件的消息时
|
// 当user-2频道有message事件的消息时
|
||||||
user_channel.on('message', function (data) {
|
user_channel.on('message', function (data: any) {
|
||||||
console.log("收到消息--",data);
|
console.log("收到消息--",data);
|
||||||
if(data.event=='platform_print'){
|
if(data.event=='platform_print'){
|
||||||
console.log('收到打印消息');
|
console.log('收到打印消息');
|
||||||
|
if(typeof data.data != 'object' || !data.data?.info?.length) return ElMessage.error('收到订单,但打印数据不合法,请联系管理员');
|
||||||
|
else print(data.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 断线事件
|
// 断线事件
|
||||||
|
|
|
@ -12,20 +12,24 @@ import { PageEnum } from './enums/pageEnum'
|
||||||
import useTabsStore from './stores/modules/multipleTabs'
|
import useTabsStore from './stores/modules/multipleTabs'
|
||||||
import { clearAuthInfo } from './utils/auth'
|
import { clearAuthInfo } from './utils/auth'
|
||||||
import config from './config'
|
import config from './config'
|
||||||
|
import cache from '@/utils/cache'
|
||||||
|
|
||||||
// NProgress配置
|
// NProgress配置
|
||||||
NProgress.configure({ showSpinner: false })
|
NProgress.configure({ showSpinner: false })
|
||||||
|
|
||||||
const loginPath = PageEnum.LOGIN
|
const loginPath = PageEnum.LOGIN
|
||||||
|
const adminLoginPath = PageEnum.ADMIN_LOGIN
|
||||||
const defaultPath = PageEnum.INDEX
|
const defaultPath = PageEnum.INDEX
|
||||||
// 免登录白名单
|
// 免登录白名单
|
||||||
const whiteList: string[] = [PageEnum.LOGIN, PageEnum.ERROR_403]
|
const whiteList: string[] = [PageEnum.LOGIN, PageEnum.ERROR_403, PageEnum.ADMIN_LOGIN]
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
// 开始 Progress Bar
|
// 开始 Progress Bar
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
document.title = to.meta.title ?? config.title
|
document.title = to.meta.title ?? config.title
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const tabsStore = useTabsStore()
|
const tabsStore = useTabsStore()
|
||||||
|
const is_admin = cache.get('is_admin')
|
||||||
|
|
||||||
if (whiteList.includes(to.path)) {
|
if (whiteList.includes(to.path)) {
|
||||||
// 在免登录白名单,直接进入
|
// 在免登录白名单,直接进入
|
||||||
next()
|
next()
|
||||||
|
@ -33,7 +37,7 @@ router.beforeEach(async (to, from, next) => {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
const hasGetUserInfo = Object.keys(userStore.userInfo).length !== 0
|
const hasGetUserInfo = Object.keys(userStore.userInfo).length !== 0
|
||||||
if (hasGetUserInfo) {
|
if (hasGetUserInfo) {
|
||||||
if (to.path === loginPath) {
|
if (to.path === loginPath || to.path === adminLoginPath) {
|
||||||
next({ path: defaultPath })
|
next({ path: defaultPath })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
|
@ -70,11 +74,15 @@ router.beforeEach(async (to, from, next) => {
|
||||||
next({ ...to, replace: true })
|
next({ ...to, replace: true })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
clearAuthInfo()
|
clearAuthInfo()
|
||||||
next({ path: loginPath, query: { redirect: to.fullPath } })
|
if (is_admin==1) {
|
||||||
|
next({ path: adminLoginPath, query: { redirect: to.fullPath } })
|
||||||
|
} else next({ path: loginPath, query: { redirect: to.fullPath } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
next({ path: loginPath, query: { redirect: to.fullPath } })
|
if (is_admin==1) {
|
||||||
|
next({ path: adminLoginPath, query: { redirect: to.fullPath } })
|
||||||
|
} else next({ path: loginPath, query: { redirect: to.fullPath } })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ export const constantRoutes: Array<RouteRecordRaw> = [
|
||||||
path: PageEnum.LOGIN,
|
path: PageEnum.LOGIN,
|
||||||
component: () => import('@/views/account/login.vue')
|
component: () => import('@/views/account/login.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: PageEnum.ADMIN_LOGIN,
|
||||||
|
component: () => import('@/views/account/admin_login.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/user',
|
path: '/user',
|
||||||
component: LAYOUT,
|
component: LAYOUT,
|
||||||
|
|
|
@ -32,15 +32,17 @@ const useUserStore = defineStore({
|
||||||
this.perms = []
|
this.perms = []
|
||||||
},
|
},
|
||||||
login(playload: any) {
|
login(playload: any) {
|
||||||
const { account, password } = playload
|
const { account, password, is_admin } = playload
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login({
|
login({
|
||||||
account: account.trim(),
|
account: account.trim(),
|
||||||
password: password
|
password: password,
|
||||||
|
is_admin: is_admin
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.token = data.token
|
this.token = data.token
|
||||||
cache.set(TOKEN_KEY, data.token)
|
cache.set(TOKEN_KEY, data.token)
|
||||||
|
cache.set('is_admin', is_admin)
|
||||||
resolve(data)
|
resolve(data)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
@ -53,7 +55,8 @@ const useUserStore = defineStore({
|
||||||
logout()
|
logout()
|
||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
this.token = ''
|
this.token = ''
|
||||||
await router.push(PageEnum.LOGIN)
|
const is_admin = cache.get('is_admin')
|
||||||
|
await router.push(is_admin==1 ? PageEnum.ADMIN_LOGIN : PageEnum.LOGIN)
|
||||||
clearAuthInfo()
|
clearAuthInfo()
|
||||||
resolve(data)
|
resolve(data)
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,50 +16,188 @@ export const print = (data: any) => {
|
||||||
const list = hiprint.hiwebSocket.getPrinterList();
|
const list = hiprint.hiwebSocket.getPrinterList();
|
||||||
console.log(list);
|
console.log(list);
|
||||||
|
|
||||||
|
let nowHeight = 0;
|
||||||
|
let textHeight = 10;
|
||||||
|
|
||||||
// 下列方法都是没有拖拽设计页面的, 相当于代码模式, 使用代码设计页面
|
// 下列方法都是没有拖拽设计页面的, 相当于代码模式, 使用代码设计页面
|
||||||
// 想要实现拖拽设计页面,请往下看 '自定义设计'
|
// 想要实现拖拽设计页面,请往下看 '自定义设计'
|
||||||
var hiprintTemplate = new hiprint.PrintTemplate();
|
var hiprintTemplate = new hiprint.PrintTemplate();
|
||||||
|
|
||||||
|
// 纸张高度 固定为 130 pt + 商品数量高度
|
||||||
|
let oneHeight = 120 + Math.ceil((data.info.length * 2 * 10) / 2.84);
|
||||||
|
|
||||||
// 模板宽度单位是mm ( 1mm ~= 2.84pt ) 其他的宽高单位是pt
|
// 模板宽度单位是mm ( 1mm ~= 2.84pt ) 其他的宽高单位是pt
|
||||||
var panel = hiprintTemplate.addPrintPanel({
|
var panel = hiprintTemplate.addPrintPanel({
|
||||||
width: WIDTH, // 58mm = 164pt
|
width: 58, // 58mm = 164pt
|
||||||
height: 58,
|
height: oneHeight,
|
||||||
paperNumberDisabled: true,
|
paperNumberDisabled: true,
|
||||||
topOffset: -1,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//文本
|
let options = (e: any) => {
|
||||||
panel.addPrintText({
|
nowHeight += textHeight;
|
||||||
options: {
|
let opt = {
|
||||||
width: T_WIDTH,
|
width: T_WIDTH,
|
||||||
height: 10,
|
height: textHeight,
|
||||||
top: 10,
|
top: nowHeight,
|
||||||
left: T_LEFT,
|
left: T_LEFT,
|
||||||
title: "hiprint插件手动添加text",
|
title: "",
|
||||||
|
};
|
||||||
|
if (typeof e === "string") opt.title = e;
|
||||||
|
else opt = Object.assign(opt, e);
|
||||||
|
return {
|
||||||
|
options: opt,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let lineTitle = () => {
|
||||||
|
nowHeight += textHeight;
|
||||||
|
let left = Math.floor(T_WIDTH / 3);
|
||||||
|
panel.addPrintText({
|
||||||
|
options: {
|
||||||
|
width: left,
|
||||||
|
height: 10,
|
||||||
|
top: nowHeight,
|
||||||
|
left: 0,
|
||||||
|
title: "单价",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
panel.addPrintText({
|
||||||
|
options: {
|
||||||
|
width: left,
|
||||||
|
height: textHeight,
|
||||||
|
top: nowHeight,
|
||||||
|
left: left,
|
||||||
|
title: "数量",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
panel.addPrintText({
|
||||||
|
options: {
|
||||||
|
width: left,
|
||||||
|
height: textHeight,
|
||||||
|
top: nowHeight,
|
||||||
|
left: left * 2,
|
||||||
|
title: "小计",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let lineOptions = (text1: any, text2: any, text3: any) => {
|
||||||
|
nowHeight += textHeight;
|
||||||
|
let left = Math.floor(T_WIDTH / 3);
|
||||||
|
panel.addPrintText({
|
||||||
|
options: {
|
||||||
|
width: left,
|
||||||
|
height: 10,
|
||||||
|
top: nowHeight,
|
||||||
|
left: 0,
|
||||||
|
title: text1 + "",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
panel.addPrintText({
|
||||||
|
options: {
|
||||||
|
width: left,
|
||||||
|
height: textHeight,
|
||||||
|
top: nowHeight,
|
||||||
|
left: left,
|
||||||
|
title: text2 + "",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
panel.addPrintText({
|
||||||
|
options: {
|
||||||
|
width: left,
|
||||||
|
height: textHeight,
|
||||||
|
top: nowHeight,
|
||||||
|
left: left * 2,
|
||||||
|
title: text3 + "",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//文本 *1
|
||||||
|
panel.addPrintText(
|
||||||
|
options({
|
||||||
|
title: "泸优采-采购单",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
//文本 *6
|
||||||
|
panel.addPrintText(options("单号: " + data.number));
|
||||||
|
panel.addPrintText(options("配送时间: " + data.create_time));
|
||||||
|
panel.addPrintText(options("配送员: " + data.mer_nickname));
|
||||||
|
panel.addPrintText(options("配送电话: " + data.mer_phone));
|
||||||
|
panel.addPrintText(options("======================"));
|
||||||
|
panel.addPrintText(options("商品信息: "));
|
||||||
|
|
||||||
|
//格式化 *1 + x * y
|
||||||
|
lineTitle();
|
||||||
|
data.info.forEach((item: any) => {
|
||||||
|
panel.addPrintText(options(item.goods_name));
|
||||||
|
if(item.nums==Math.floor(+item.nums)) item.nums = Number(item.nums).toFixed(0);
|
||||||
|
lineOptions(
|
||||||
|
`${item.price}元`,
|
||||||
|
`${item.nums}${item.unit_name}`,
|
||||||
|
`${item.total}元`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
//长文本
|
|
||||||
panel.addPrintLongText({
|
//文本 *5
|
||||||
|
panel.addPrintText(options("======================"));
|
||||||
|
panel.addPrintText(options(`合计: ${data.total}元`));
|
||||||
|
panel.addPrintText(options("提货点: " + data.mer_name));
|
||||||
|
panel.addPrintText(options("提货点电话: " + data.mer_phone));
|
||||||
|
panel.addPrintText(options("提货点负责人签字:"));
|
||||||
|
// https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png //无字
|
||||||
|
// https://lihai001.oss-cn-chengdu.aliyuncs.com/def/54705202405221504133485.png //有字
|
||||||
|
// panel.addPrintRect({ options: { width: T_WIDTH, height:30,top: nowHeight + 15, left: T_LEFT,borderColor:'',borderWidth:0.75 } });
|
||||||
|
// nowHeight+=40;
|
||||||
|
|
||||||
|
// 文本 *6
|
||||||
|
panel.addPrintImage({
|
||||||
options: {
|
options: {
|
||||||
width: T_WIDTH,
|
width: T_WIDTH,
|
||||||
height: 35,
|
height: 50,
|
||||||
top: 30,
|
top: nowHeight + 15,
|
||||||
left: T_LEFT,
|
left: T_LEFT,
|
||||||
title: "长文本:hiprint是一个很好的webjs打印,浏览器在的地方他都可以运行",
|
title: "",
|
||||||
|
src: "https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
//长文本
|
nowHeight += 60;
|
||||||
panel.addPrintLongText({
|
// 文本 *4
|
||||||
|
panel.addPrintText(options("收货人: " + data.real_name));
|
||||||
|
panel.addPrintText(options("收货地址: " + data.user_address));
|
||||||
|
panel.addPrintText(options("联系电话: " + data.user_phone));
|
||||||
|
panel.addPrintText(options("收货人签字:"));
|
||||||
|
// panel.addPrintRect({ options: { width: T_WIDTH, height:30,top: nowHeight+15, left: T_LEFT,borderColor:'',borderWidth:0.75 } });
|
||||||
|
|
||||||
|
// 文本 *6
|
||||||
|
panel.addPrintImage({
|
||||||
options: {
|
options: {
|
||||||
width: T_WIDTH,
|
width: T_WIDTH,
|
||||||
height: 35,
|
height: 50,
|
||||||
top: 80,
|
top: nowHeight + 15,
|
||||||
left: T_LEFT,
|
left: T_LEFT,
|
||||||
title:
|
title: "",
|
||||||
"长文本:直接打印,需要安装客户端, 直接打印,需要安装客户端, 直接打印,需要安装客户端, 直接打印,需要安装客户端",
|
src: "https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
nowHeight += 60;
|
||||||
|
|
||||||
|
// 文本 *4
|
||||||
|
panel.addPrintText(options(""));
|
||||||
|
panel.addPrintText(options(""));
|
||||||
|
panel.addPrintText(options(""));
|
||||||
|
panel.addPrintText(options("======================"));
|
||||||
|
|
||||||
|
// 合计高度 23 + length * 2
|
||||||
|
|
||||||
//打印
|
//打印
|
||||||
hiprintTemplate.print({});
|
hiprintTemplate.print({});
|
||||||
//直接打印,需要安装客户端
|
//直接打印,需要安装客户端
|
||||||
|
@ -94,25 +232,25 @@ export const testPrint = () => {
|
||||||
paperNumberDisabled: true,
|
paperNumberDisabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let options = (e: any)=>{
|
let options = (e: any) => {
|
||||||
nowHeight+=textHeight;
|
nowHeight += textHeight;
|
||||||
let opt = {
|
let opt = {
|
||||||
width: T_WIDTH,
|
width: T_WIDTH,
|
||||||
height: textHeight,
|
height: textHeight,
|
||||||
top: nowHeight,
|
top: nowHeight,
|
||||||
left: T_LEFT,
|
left: T_LEFT,
|
||||||
title: '',
|
title: "",
|
||||||
}
|
};
|
||||||
if(typeof e === 'string') opt.title = e;
|
if (typeof e === "string") opt.title = e;
|
||||||
else opt = Object.assign(opt, e);
|
else opt = Object.assign(opt, e);
|
||||||
return {
|
return {
|
||||||
options: opt
|
options: opt,
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
let lineTitle = ()=>{
|
let lineTitle = () => {
|
||||||
nowHeight+=textHeight;
|
nowHeight += textHeight;
|
||||||
let left = Math.floor(T_WIDTH/3) ;
|
let left = Math.floor(T_WIDTH / 3);
|
||||||
panel.addPrintText({
|
panel.addPrintText({
|
||||||
options: {
|
options: {
|
||||||
width: left,
|
width: left,
|
||||||
|
@ -143,18 +281,18 @@ export const testPrint = () => {
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
let lineOptions = (text1: any, text2: any, text3: any)=>{
|
let lineOptions = (text1: any, text2: any, text3: any) => {
|
||||||
nowHeight+=textHeight;
|
nowHeight += textHeight;
|
||||||
let left = Math.floor(T_WIDTH/3) ;
|
let left = Math.floor(T_WIDTH / 3);
|
||||||
panel.addPrintText({
|
panel.addPrintText({
|
||||||
options: {
|
options: {
|
||||||
width: left,
|
width: left,
|
||||||
height: 10,
|
height: 10,
|
||||||
top: nowHeight,
|
top: nowHeight,
|
||||||
left: 0,
|
left: 0,
|
||||||
title: text1+"",
|
title: text1 + "",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -164,7 +302,7 @@ export const testPrint = () => {
|
||||||
height: textHeight,
|
height: textHeight,
|
||||||
top: nowHeight,
|
top: nowHeight,
|
||||||
left: left,
|
left: left,
|
||||||
title: text2+"",
|
title: text2 + "",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -174,17 +312,19 @@ export const testPrint = () => {
|
||||||
height: textHeight,
|
height: textHeight,
|
||||||
top: nowHeight,
|
top: nowHeight,
|
||||||
left: left * 2,
|
left: left * 2,
|
||||||
title: text3+"",
|
title: text3 + "",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//文本 *1
|
//文本 *1
|
||||||
panel.addPrintText(options({
|
panel.addPrintText(
|
||||||
title: '泸优采-小票0',
|
options({
|
||||||
textAlign: "center",
|
title: "泸优采-小票0",
|
||||||
}));
|
textAlign: "center",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
//文本 *6
|
//文本 *6
|
||||||
panel.addPrintText(options("单号: PF171617436315965155"));
|
panel.addPrintText(options("单号: PF171617436315965155"));
|
||||||
|
@ -205,11 +345,11 @@ export const testPrint = () => {
|
||||||
|
|
||||||
//文本 *13
|
//文本 *13
|
||||||
panel.addPrintText(options("======================"));
|
panel.addPrintText(options("======================"));
|
||||||
panel.addPrintText(options('合计: 0.75元'));
|
panel.addPrintText(options("合计: 0.75元"));
|
||||||
|
|
||||||
panel.addPrintText(options('提货点: 莲花农贸市场'));
|
panel.addPrintText(options("提货点: 莲花农贸市场"));
|
||||||
panel.addPrintText(options('提货点电话: 19330904744'));
|
panel.addPrintText(options("提货点电话: 19330904744"));
|
||||||
panel.addPrintText(options('提货点负责人签字:'));
|
panel.addPrintText(options("提货点负责人签字:"));
|
||||||
// https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png //无字
|
// https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png //无字
|
||||||
// https://lihai001.oss-cn-chengdu.aliyuncs.com/def/54705202405221504133485.png //有字
|
// https://lihai001.oss-cn-chengdu.aliyuncs.com/def/54705202405221504133485.png //有字
|
||||||
// panel.addPrintRect({ options: { width: T_WIDTH, height:30,top: nowHeight + 15, left: T_LEFT,borderColor:'',borderWidth:0.75 } });
|
// panel.addPrintRect({ options: { width: T_WIDTH, height:30,top: nowHeight + 15, left: T_LEFT,borderColor:'',borderWidth:0.75 } });
|
||||||
|
@ -217,38 +357,37 @@ export const testPrint = () => {
|
||||||
panel.addPrintImage({
|
panel.addPrintImage({
|
||||||
options: {
|
options: {
|
||||||
width: T_WIDTH,
|
width: T_WIDTH,
|
||||||
height:50,
|
height: 50,
|
||||||
top: nowHeight + 15,
|
top: nowHeight + 15,
|
||||||
left: T_LEFT,
|
left: T_LEFT,
|
||||||
title: '',
|
title: "",
|
||||||
src: 'https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png'
|
src: "https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png",
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
nowHeight+=60;
|
nowHeight += 60;
|
||||||
panel.addPrintText(options('收货人: 阿哈'));
|
panel.addPrintText(options("收货人: 阿哈"));
|
||||||
panel.addPrintText(options('收货地址: 里海科技'));
|
panel.addPrintText(options("收货地址: 里海科技"));
|
||||||
panel.addPrintText(options('联系电话: 17685151643'));
|
panel.addPrintText(options("联系电话: 17685151643"));
|
||||||
panel.addPrintText(options('收货人签字:'));
|
panel.addPrintText(options("收货人签字:"));
|
||||||
// panel.addPrintRect({ options: { width: T_WIDTH, height:30,top: nowHeight+15, left: T_LEFT,borderColor:'',borderWidth:0.75 } });
|
// panel.addPrintRect({ options: { width: T_WIDTH, height:30,top: nowHeight+15, left: T_LEFT,borderColor:'',borderWidth:0.75 } });
|
||||||
panel.addPrintImage({
|
panel.addPrintImage({
|
||||||
options: {
|
options: {
|
||||||
width: T_WIDTH,
|
width: T_WIDTH,
|
||||||
height: 50,
|
height: 50,
|
||||||
top: nowHeight + 15,
|
top: nowHeight + 15,
|
||||||
left: T_LEFT,
|
left: T_LEFT,
|
||||||
title: '',
|
title: "",
|
||||||
src: 'https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png'
|
src: "https://lihai001.oss-cn-chengdu.aliyuncs.com/def/db264202405221455038529.png",
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
nowHeight+=60;
|
nowHeight += 60;
|
||||||
|
|
||||||
panel.addPrintText(options(""));
|
panel.addPrintText(options(""));
|
||||||
panel.addPrintText(options(""));
|
panel.addPrintText(options(""));
|
||||||
panel.addPrintText(options(""));
|
panel.addPrintText(options(""));
|
||||||
panel.addPrintText(options("======================"));
|
panel.addPrintText(options("======================"));
|
||||||
|
|
||||||
// 合计高度 23 + length * 2
|
// 合计高度 23 + length * 2
|
||||||
|
|
||||||
|
|
||||||
//打印
|
//打印
|
||||||
// hiprintTemplate.print({});
|
// hiprintTemplate.print({});
|
||||||
|
@ -258,22 +397,24 @@ export const testPrint = () => {
|
||||||
// 发送任务到打印机成功
|
// 发送任务到打印机成功
|
||||||
hiprintTemplate.on("printSuccess", (e: any) => {
|
hiprintTemplate.on("printSuccess", (e: any) => {
|
||||||
console.log("printSuccess", e);
|
console.log("printSuccess", e);
|
||||||
|
ElMessage.success('订单已加入打印队列');
|
||||||
});
|
});
|
||||||
// 发送任务到打印机失败
|
// 发送任务到打印机失败
|
||||||
hiprintTemplate.on("printError", (e: any) => {
|
hiprintTemplate.on("printError", (e: any) => {
|
||||||
console.log("printError", e);
|
console.log("printError", e);
|
||||||
|
ElMessage.error('打印失败,请检查是否正确连接打印机!');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const printerList = ()=>{
|
export const printerList = () => {
|
||||||
try{
|
try {
|
||||||
const list = hiprint.hiwebSocket.getPrinterList();
|
const list = hiprint.hiwebSocket.getPrinterList();
|
||||||
return list;
|
return list;
|
||||||
}catch{
|
} catch {
|
||||||
ElMessage.error("请先安装打印机客户端")
|
ElMessage.error("请先安装打印机客户端");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 计算字符串长度
|
// 计算字符串长度
|
||||||
function calculateStringLength(str: string) {
|
function calculateStringLength(str: string) {
|
||||||
|
|
|
@ -1,123 +1,133 @@
|
||||||
import { merge } from 'lodash'
|
import { merge } from "lodash";
|
||||||
import configs from '@/config'
|
import configs from "@/config";
|
||||||
import { Axios } from './axios'
|
import { Axios } from "./axios";
|
||||||
import { ContentTypeEnum, RequestCodeEnum, RequestMethodsEnum } from '@/enums/requestEnums'
|
import {
|
||||||
import type { AxiosHooks } from './type'
|
ContentTypeEnum,
|
||||||
import { clearAuthInfo, getToken } from '../auth'
|
RequestCodeEnum,
|
||||||
import feedback from '../feedback'
|
RequestMethodsEnum,
|
||||||
import NProgress from 'nprogress'
|
} from "@/enums/requestEnums";
|
||||||
import { AxiosError, type AxiosRequestConfig } from 'axios'
|
import type { AxiosHooks } from "./type";
|
||||||
import router from '@/router'
|
import { clearAuthInfo, getToken } from "../auth";
|
||||||
import { PageEnum } from '@/enums/pageEnum'
|
import feedback from "../feedback";
|
||||||
|
import NProgress from "nprogress";
|
||||||
|
import { AxiosError, type AxiosRequestConfig } from "axios";
|
||||||
|
import router from "@/router";
|
||||||
|
import { PageEnum } from "@/enums/pageEnum";
|
||||||
|
|
||||||
// 处理axios的钩子函数
|
// 处理axios的钩子函数
|
||||||
const axiosHooks: AxiosHooks = {
|
const axiosHooks: AxiosHooks = {
|
||||||
requestInterceptorsHook(config) {
|
requestInterceptorsHook(config) {
|
||||||
NProgress.start()
|
NProgress.start();
|
||||||
const { withToken, isParamsToData } = config.requestOptions
|
const { withToken, isParamsToData } = config.requestOptions;
|
||||||
const params = config.params || {}
|
const params = config.params || {};
|
||||||
const headers = config.headers || {}
|
const headers = config.headers || {};
|
||||||
|
|
||||||
// 添加token
|
// 添加token
|
||||||
if (withToken) {
|
if (withToken) {
|
||||||
const token = getToken()
|
const token = getToken();
|
||||||
headers.token = token
|
headers.token = token;
|
||||||
}
|
|
||||||
// POST请求下如果无data,则将params视为data
|
|
||||||
if (
|
|
||||||
isParamsToData &&
|
|
||||||
!Reflect.has(config, 'data') &&
|
|
||||||
config.method?.toUpperCase() === RequestMethodsEnum.POST
|
|
||||||
) {
|
|
||||||
config.data = params
|
|
||||||
config.params = {}
|
|
||||||
}
|
|
||||||
config.headers = headers
|
|
||||||
return config
|
|
||||||
},
|
|
||||||
requestInterceptorsCatchHook(err) {
|
|
||||||
NProgress.done()
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
async responseInterceptorsHook(response) {
|
|
||||||
NProgress.done()
|
|
||||||
const { isTransformResponse, isReturnDefaultResponse } = response.config.requestOptions
|
|
||||||
|
|
||||||
//返回默认响应,当需要获取响应头及其他数据时可使用
|
|
||||||
if (isReturnDefaultResponse) {
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
// 是否需要对数据进行处理
|
|
||||||
if (!isTransformResponse) {
|
|
||||||
return response.data
|
|
||||||
}
|
|
||||||
const { code, data, show, msg } = response.data
|
|
||||||
switch (code) {
|
|
||||||
case RequestCodeEnum.SUCCESS:
|
|
||||||
if (show) {
|
|
||||||
msg && feedback.msgSuccess(msg)
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
case RequestCodeEnum.FAIL:
|
|
||||||
if (show) {
|
|
||||||
msg && feedback.msgError(msg)
|
|
||||||
}
|
|
||||||
return Promise.reject(data)
|
|
||||||
case RequestCodeEnum.LOGIN_FAILURE:
|
|
||||||
clearAuthInfo()
|
|
||||||
router.push(PageEnum.LOGIN)
|
|
||||||
return Promise.reject()
|
|
||||||
case RequestCodeEnum.OPEN_NEW_PAGE:
|
|
||||||
window.location.href = data.url
|
|
||||||
return data
|
|
||||||
default:
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
},
|
|
||||||
responseInterceptorsCatchHook(error) {
|
|
||||||
NProgress.done()
|
|
||||||
if (error.code !== AxiosError.ERR_CANCELED) {
|
|
||||||
error.message && feedback.msgError(error.message)
|
|
||||||
}
|
|
||||||
return Promise.reject(error)
|
|
||||||
}
|
}
|
||||||
}
|
// POST请求下如果无data,则将params视为data
|
||||||
|
if (
|
||||||
|
isParamsToData &&
|
||||||
|
!Reflect.has(config, "data") &&
|
||||||
|
config.method?.toUpperCase() === RequestMethodsEnum.POST
|
||||||
|
) {
|
||||||
|
config.data = params;
|
||||||
|
config.params = {};
|
||||||
|
}
|
||||||
|
config.headers = headers;
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
requestInterceptorsCatchHook(err) {
|
||||||
|
NProgress.done();
|
||||||
|
return err;
|
||||||
|
},
|
||||||
|
async responseInterceptorsHook(response) {
|
||||||
|
NProgress.done();
|
||||||
|
const { isTransformResponse, isReturnDefaultResponse } =
|
||||||
|
response.config.requestOptions;
|
||||||
|
|
||||||
|
//返回默认响应,当需要获取响应头及其他数据时可使用
|
||||||
|
if (isReturnDefaultResponse) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
// 是否需要对数据进行处理
|
||||||
|
if (!isTransformResponse) {
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
const { code, data, show, msg } = response.data;
|
||||||
|
switch (code) {
|
||||||
|
case RequestCodeEnum.SUCCESS:
|
||||||
|
if (show) {
|
||||||
|
msg && feedback.msgSuccess(msg);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
case RequestCodeEnum.FAIL:
|
||||||
|
if (show) {
|
||||||
|
msg && feedback.msgError(msg);
|
||||||
|
}
|
||||||
|
return Promise.reject(data);
|
||||||
|
case RequestCodeEnum.SERVER_ERROR:
|
||||||
|
if (show) {
|
||||||
|
msg && feedback.msgError(msg);
|
||||||
|
}
|
||||||
|
return Promise.reject(data);
|
||||||
|
case RequestCodeEnum.LOGIN_FAILURE:
|
||||||
|
clearAuthInfo();
|
||||||
|
router.push(PageEnum.LOGIN);
|
||||||
|
return Promise.reject();
|
||||||
|
case RequestCodeEnum.OPEN_NEW_PAGE:
|
||||||
|
window.location.href = data.url;
|
||||||
|
return data;
|
||||||
|
default:
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
responseInterceptorsCatchHook(error) {
|
||||||
|
NProgress.done();
|
||||||
|
if (error.code !== AxiosError.ERR_CANCELED) {
|
||||||
|
error.message && feedback.msgError(error.message);
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const defaultOptions: AxiosRequestConfig = {
|
const defaultOptions: AxiosRequestConfig = {
|
||||||
//接口超时时间
|
//接口超时时间
|
||||||
timeout: configs.timeout,
|
timeout: configs.timeout,
|
||||||
// 基础接口地址
|
// 基础接口地址
|
||||||
baseURL: configs.baseUrl,
|
baseURL: configs.baseUrl,
|
||||||
//请求头
|
//请求头
|
||||||
headers: { 'Content-Type': ContentTypeEnum.JSON, version: configs.version },
|
headers: { "Content-Type": ContentTypeEnum.JSON, version: configs.version },
|
||||||
// 处理 axios的钩子函数
|
// 处理 axios的钩子函数
|
||||||
axiosHooks: axiosHooks,
|
axiosHooks: axiosHooks,
|
||||||
// 每个接口可以单独配置
|
// 每个接口可以单独配置
|
||||||
requestOptions: {
|
requestOptions: {
|
||||||
// 是否将params视为data参数,仅限post请求
|
// 是否将params视为data参数,仅限post请求
|
||||||
isParamsToData: true,
|
isParamsToData: true,
|
||||||
//是否返回默认的响应
|
//是否返回默认的响应
|
||||||
isReturnDefaultResponse: false,
|
isReturnDefaultResponse: false,
|
||||||
// 需要对返回数据进行处理
|
// 需要对返回数据进行处理
|
||||||
isTransformResponse: true,
|
isTransformResponse: true,
|
||||||
// 接口拼接地址
|
// 接口拼接地址
|
||||||
urlPrefix: configs.urlPrefix,
|
urlPrefix: configs.urlPrefix,
|
||||||
// 忽略重复请求
|
// 忽略重复请求
|
||||||
ignoreCancelToken: false,
|
ignoreCancelToken: false,
|
||||||
// 是否携带token
|
// 是否携带token
|
||||||
withToken: true,
|
withToken: true,
|
||||||
// 开启请求超时重新发起请求请求机制
|
// 开启请求超时重新发起请求请求机制
|
||||||
isOpenRetry: true,
|
isOpenRetry: true,
|
||||||
// 重新请求次数
|
// 重新请求次数
|
||||||
retryCount: 2
|
retryCount: 2,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
function createAxios(opt?: Partial<AxiosRequestConfig>) {
|
function createAxios(opt?: Partial<AxiosRequestConfig>) {
|
||||||
return new Axios(
|
return new Axios(
|
||||||
// 深度合并
|
// 深度合并
|
||||||
merge(defaultOptions, opt || {})
|
merge(defaultOptions, opt || {})
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
const request = createAxios()
|
const request = createAxios();
|
||||||
export default request
|
export default request;
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
<template>
|
||||||
|
<div class="login flex flex-col">
|
||||||
|
<div class="flex-1 flex items-center justify-center">
|
||||||
|
<div class="login-card flex rounded-md">
|
||||||
|
<div class="flex-1 h-full hidden md:inline-block">
|
||||||
|
<image-contain :src="config.login_image" :width="400" height="100%" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[400px] w-[375px] flex-none mx-auto"
|
||||||
|
>
|
||||||
|
<div class="text-center text-3xl font-medium mb-8">{{ '里海ERP后台管理系统' || config.web_name }}</div>
|
||||||
|
<el-form ref="formRef" :model="formData" size="large" :rules="rules">
|
||||||
|
<el-form-item prop="account">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.account"
|
||||||
|
placeholder="请输入账号"
|
||||||
|
@keyup.enter="handleEnter"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<icon name="el-icon-User" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input
|
||||||
|
ref="passwordRef"
|
||||||
|
v-model="formData.password"
|
||||||
|
show-password
|
||||||
|
placeholder="请输入密码"
|
||||||
|
@keyup.enter="handleLogin"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<icon name="el-icon-Lock" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="mb-5">
|
||||||
|
<el-checkbox v-model="remAccount" label="记住账号"></el-checkbox>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" size="large" :loading="isLock" @click="lockLogin">
|
||||||
|
登录
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<layout-footer />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, onMounted, reactive, ref, shallowRef } from 'vue'
|
||||||
|
import type { InputInstance, FormInstance } from 'element-plus'
|
||||||
|
import LayoutFooter from '@/layout/components/footer.vue'
|
||||||
|
import useAppStore from '@/stores/modules/app'
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
import cache from '@/utils/cache'
|
||||||
|
import { ACCOUNT_KEY } from '@/enums/cacheEnums'
|
||||||
|
import { PageEnum } from '@/enums/pageEnum'
|
||||||
|
import { useLockFn } from '@/hooks/useLockFn'
|
||||||
|
const passwordRef = shallowRef<InputInstance>()
|
||||||
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const remAccount = ref(false)
|
||||||
|
const config = computed(() => appStore.config)
|
||||||
|
const formData = reactive({
|
||||||
|
account: '',
|
||||||
|
password: '',
|
||||||
|
is_admin: 1 //1管理员, 0是供应链
|
||||||
|
})
|
||||||
|
const rules = {
|
||||||
|
account: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入账号',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
// 回车按键监听
|
||||||
|
const handleEnter = () => {
|
||||||
|
if (!formData.password) {
|
||||||
|
return passwordRef.value?.focus()
|
||||||
|
}
|
||||||
|
handleLogin()
|
||||||
|
}
|
||||||
|
// 登录处理
|
||||||
|
const handleLogin = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
// 记住账号,缓存
|
||||||
|
cache.set(ACCOUNT_KEY, {
|
||||||
|
remember: remAccount.value,
|
||||||
|
account: remAccount.value ? formData.account : ''
|
||||||
|
})
|
||||||
|
await userStore.login(formData)
|
||||||
|
const {
|
||||||
|
query: { redirect }
|
||||||
|
} = route
|
||||||
|
const path = typeof redirect === 'string' ? redirect : PageEnum.INDEX
|
||||||
|
router.push(path)
|
||||||
|
}
|
||||||
|
const { isLock, lockFn: lockLogin } = useLockFn(handleLogin)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const value = cache.get(ACCOUNT_KEY)
|
||||||
|
if (value?.remember) {
|
||||||
|
remAccount.value = value.remember
|
||||||
|
formData.account = value.account
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.login {
|
||||||
|
background-image: url('./images/login_bg.png');
|
||||||
|
@apply min-h-screen bg-no-repeat bg-center bg-cover;
|
||||||
|
.login-card {
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -68,7 +68,8 @@ const remAccount = ref(false)
|
||||||
const config = computed(() => appStore.config)
|
const config = computed(() => appStore.config)
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
account: '',
|
account: '',
|
||||||
password: ''
|
password: '',
|
||||||
|
is_admin: 0 //1管理员, 0是供应链
|
||||||
})
|
})
|
||||||
const rules = {
|
const rules = {
|
||||||
account: [
|
account: [
|
||||||
|
|
|
@ -281,7 +281,7 @@
|
||||||
审核
|
审核
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-else-if="!row.status"
|
v-else-if="!row.status && !row.mark"
|
||||||
link
|
link
|
||||||
type="warning"
|
type="warning"
|
||||||
@click="handleDetail(row)"
|
@click="handleDetail(row)"
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
<el-button v-if="!row.status && (row.mark=='' || row.mark==null)" link type="primary" @click="handleDetail(row)">
|
<el-button v-if="!row.status && (row.mark=='' || row.mark==null)" link type="primary" @click="handleDetail(row)">
|
||||||
审核
|
审核
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-else-if="!row.status" link type="warning" @click="handleDetail(row)">
|
<el-button v-else-if="!row.status && !row.mark" link type="warning" @click="handleDetail(row)">
|
||||||
重新审核
|
重新审核
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,23 +5,43 @@
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="供应商分类" prop="category_id">
|
<el-form-item label="供应商分类" prop="category_id">
|
||||||
<el-select v-model="queryParams.category_id" clearable placeholder="请选择供应商类型">
|
<el-select
|
||||||
<el-option v-for="(item, index) in dictData.mer_category_type" :key="index" :label="item.name"
|
v-model="queryParams.category_id"
|
||||||
:value="parseInt(item.value)" />
|
clearable
|
||||||
|
placeholder="请选择供应商类型"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in dictData.mer_category_type"
|
||||||
|
:key="index"
|
||||||
|
:label="item.name"
|
||||||
|
:value="parseInt(item.value)"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="供应商类型" prop="type_id">
|
<el-form-item label="供应商类型" prop="type_id">
|
||||||
<el-select v-model="queryParams.type_id" clearable placeholder="请选择供应商类型">
|
<el-select
|
||||||
<el-option v-for="(item, index) in dictData.merchat_type" :key="index" :label="item.name"
|
v-model="queryParams.type_id"
|
||||||
:value="parseInt(item.value)" />
|
clearable
|
||||||
|
placeholder="请选择供应商类型"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in dictData.merchat_type"
|
||||||
|
:key="index"
|
||||||
|
:label="item.name"
|
||||||
|
:value="parseInt(item.value)"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="供应商名称" prop="mer_name">
|
<el-form-item label="供应商名称" prop="mer_name">
|
||||||
<el-input v-model="queryParams.mer_name" clearable placeholder="请输入供应商名称" />
|
<el-input
|
||||||
|
v-model="queryParams.mer_name"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入供应商名称"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
|
@ -34,13 +54,21 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
||||||
<el-button v-perms="['supplier.supplier/add']" type="primary" @click="handleAdd">
|
<el-button
|
||||||
|
v-perms="['supplier.supplier/add']"
|
||||||
|
type="primary"
|
||||||
|
@click="handleAdd"
|
||||||
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon name="el-icon-Plus" />
|
<icon name="el-icon-Plus" />
|
||||||
</template>
|
</template>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-perms="['supplier.supplier/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
|
<el-button
|
||||||
|
v-perms="['supplier.supplier/delete']"
|
||||||
|
:disabled="!selectData.length"
|
||||||
|
@click="handleDelete(selectData)"
|
||||||
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
|
@ -59,14 +87,33 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column> -->
|
</el-table-column> -->
|
||||||
<el-table-column label="供应商类型" prop="type_id" show-overflow-tooltip>
|
<el-table-column
|
||||||
|
label="供应商类型"
|
||||||
|
prop="type_id"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<dict-value :options="dictData.merchat_type" :value="row.type_id" />
|
<dict-value
|
||||||
|
:options="dictData.merchat_type"
|
||||||
|
:value="row.type_id"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="供应商名称" prop="mer_name" show-overflow-tooltip />
|
<el-table-column
|
||||||
<el-table-column label="结算周期(天)" prop="settle_cycle" show-overflow-tooltip />
|
label="供应商名称"
|
||||||
<el-table-column label="利率" prop="interest_rate" show-overflow-tooltip />
|
prop="mer_name"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="结算周期(天)"
|
||||||
|
prop="settle_cycle"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="利率"
|
||||||
|
prop="interest_rate"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
<!-- <el-table-column
|
<!-- <el-table-column
|
||||||
label="标签"
|
label="标签"
|
||||||
prop="sys_labels_arr"
|
prop="sys_labels_arr"
|
||||||
|
@ -78,14 +125,26 @@
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column> -->
|
</el-table-column> -->
|
||||||
<el-table-column label="供应商地址" prop="mer_address" show-overflow-tooltip />
|
<el-table-column
|
||||||
|
label="供应商地址"
|
||||||
|
prop="mer_address"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
<el-table-column label="供应商是否禁用" prop="status">
|
<el-table-column label="供应商是否禁用" prop="status">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<dict-value :options="dictData.show_status" :value="row.status" />
|
<dict-value :options="dictData.show_status" :value="row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="提成比例" prop="commission_rate" show-overflow-tooltip />
|
<el-table-column
|
||||||
<el-table-column label="供应商手续费单独设置" width="200" prop="commission_switch">
|
label="提成比例"
|
||||||
|
prop="commission_rate"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="供应商手续费单独设置"
|
||||||
|
width="200"
|
||||||
|
prop="commission_switch"
|
||||||
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<!-- <dict-value :options="dictData.show_status" :value="row.commission_switch" /> -->
|
<!-- <dict-value :options="dictData.show_status" :value="row.commission_switch" /> -->
|
||||||
{{ row.commission_switch ? "开启" : "关闭" }}
|
{{ row.commission_switch ? "开启" : "关闭" }}
|
||||||
|
@ -98,22 +157,42 @@
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" width="200" fixed="right">
|
<el-table-column label="操作" width="200" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button v-perms="['supplier.supplier/edit']" type="primary" link @click="handleEdit(row)">
|
<el-button
|
||||||
|
v-perms="['supplier.supplier/edit']"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="handleEdit(row)"
|
||||||
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-perms="['supplier.supplier/delete']" type="danger" link @click="handleDelete(row.id)">
|
<el-button
|
||||||
|
v-perms="['supplier.supplier/delete']"
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
@click="handleDelete(row.id)"
|
||||||
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button link @click="handleDetail(row.id)"> 详情 </el-button>
|
<el-button link @click="handleDetail(row.id)"> 详情 </el-button>
|
||||||
<router-link :to="{
|
|
||||||
path: 'bindGoods',
|
<el-button link type="primary">
|
||||||
query: {
|
<router-link
|
||||||
id: row.id,
|
:to="{
|
||||||
},
|
path: 'bindGoods',
|
||||||
}">
|
query: {
|
||||||
<el-button link type="primary"> 商品绑定 </el-button>
|
id: row.id,
|
||||||
</router-link>
|
},
|
||||||
<el-button v-if="!row.uid" link @click="bindUser(row)" type="primary">
|
}"
|
||||||
|
>
|
||||||
|
商品绑定
|
||||||
|
</router-link>
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="!row.uid"
|
||||||
|
link
|
||||||
|
@click="bindUser(row)"
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
绑定用户
|
绑定用户
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button link @click="setBalance(row.id)"> 设置余额 </el-button>
|
<el-button link @click="setBalance(row.id)"> 设置余额 </el-button>
|
||||||
|
@ -151,15 +230,17 @@
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="金额" :label-width="100">
|
<el-form-item label="金额" :label-width="100">
|
||||||
<el-input v-model="balanceInfo.set_money" type="number" placeholder="请输入金额" />
|
<el-input
|
||||||
|
v-model="balanceInfo.set_money"
|
||||||
|
type="number"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="showBalance = false">取消</el-button>
|
<el-button @click="showBalance = false">取消</el-button>
|
||||||
<el-button type="primary" @click="submitBalance">
|
<el-button type="primary" @click="submitBalance"> 确认 </el-button>
|
||||||
确认
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
@ -174,7 +255,7 @@ import {
|
||||||
apiSupplierDelete,
|
apiSupplierDelete,
|
||||||
apiSupplierDetail,
|
apiSupplierDetail,
|
||||||
apiSupplierSetBalance,
|
apiSupplierSetBalance,
|
||||||
apiSupplierBindUser
|
apiSupplierBindUser,
|
||||||
} from "@/api/supplier";
|
} from "@/api/supplier";
|
||||||
import { timeFormat } from "@/utils/util";
|
import { timeFormat } from "@/utils/util";
|
||||||
import feedback from "@/utils/feedback";
|
import feedback from "@/utils/feedback";
|
||||||
|
@ -246,7 +327,7 @@ const handleDetail = async (id: any) => {
|
||||||
|
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false);
|
||||||
const bindData = ref({
|
const bindData = ref({
|
||||||
id: ""
|
id: "",
|
||||||
});
|
});
|
||||||
// 绑定用户
|
// 绑定用户
|
||||||
const bindUser = (data: any) => {
|
const bindUser = (data: any) => {
|
||||||
|
@ -261,7 +342,6 @@ const onBind = (data: any) => {
|
||||||
showDialog.value = false;
|
showDialog.value = false;
|
||||||
getLists();
|
getLists();
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const balanceInfo = ref({
|
const balanceInfo = ref({
|
||||||
|
@ -277,8 +357,9 @@ const setBalance = (id: any) => {
|
||||||
balanceInfo.value.type = 1;
|
balanceInfo.value.type = 1;
|
||||||
showBalance.value = true;
|
showBalance.value = true;
|
||||||
};
|
};
|
||||||
const submitBalance = ()=>{
|
const submitBalance = () => {
|
||||||
if(+balanceInfo.value.set_money <=0 || balanceInfo.value.set_money == '') return ElMessage.error('请输入正确的金额');
|
if (+balanceInfo.value.set_money <= 0 || balanceInfo.value.set_money == "")
|
||||||
|
return ElMessage.error("请输入正确的金额");
|
||||||
apiSupplierSetBalance({
|
apiSupplierSetBalance({
|
||||||
set_money: +balanceInfo.value.set_money,
|
set_money: +balanceInfo.value.set_money,
|
||||||
id: balanceInfo.value.id,
|
id: balanceInfo.value.id,
|
||||||
|
@ -287,7 +368,7 @@ const submitBalance = ()=>{
|
||||||
showBalance.value = false;
|
showBalance.value = false;
|
||||||
getLists();
|
getLists();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
getLists();
|
getLists();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
<template>
|
||||||
|
<div class="edit-popup">
|
||||||
|
<popup ref="popupRef" :async="true" width="550px" @close="handleClose" :bottom-btn="false">
|
||||||
|
<el-descriptions class="margin-top" :title="popupTitle" :column="1" border>
|
||||||
|
<el-descriptions-item label="条码名称">
|
||||||
|
{{ formData.name }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="条码内容">
|
||||||
|
{{ formData.code }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="条码类型">
|
||||||
|
<dict-value :options="dictData.code_type" :value="formData.type" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="备注信息">
|
||||||
|
{{ formData.data }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="扩展信息">
|
||||||
|
{{ formData.more }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="排序">
|
||||||
|
{{ formData.sort }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="brandEdit">
|
||||||
|
import Popup from '@/components/popup/index.vue'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
defineProps({
|
||||||
|
dictData: {
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['success', 'close'])
|
||||||
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
|
const mode = ref('add')
|
||||||
|
|
||||||
|
|
||||||
|
// 弹窗标题
|
||||||
|
const popupTitle = computed(() => {
|
||||||
|
return '品牌详情'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive({
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
py: '',
|
||||||
|
code: '',
|
||||||
|
type: '',
|
||||||
|
data: '',
|
||||||
|
more: '',
|
||||||
|
sort: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证
|
||||||
|
const formRules = reactive<any>({
|
||||||
|
name: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入品牌名称',
|
||||||
|
trigger: ['blur']
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 获取详情
|
||||||
|
const setFormData = async (data: Record<any, any>) => {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (data[key] != null && data[key] != undefined) {
|
||||||
|
//@ts-ignore
|
||||||
|
formData[key] = data[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
// const handleSubmit = async () => {
|
||||||
|
// await formRef.value?.validate()
|
||||||
|
// const data = { ...formData, }
|
||||||
|
// mode.value == 'edit'
|
||||||
|
// ? await apiBrandEdit(data)
|
||||||
|
// : await apiBrandAdd(data)
|
||||||
|
// popupRef.value?.close()
|
||||||
|
// emit('success')
|
||||||
|
// }
|
||||||
|
|
||||||
|
//打开弹窗
|
||||||
|
const open = (type = 'add') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭回调
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setFormData,
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,144 @@
|
||||||
|
<template>
|
||||||
|
<div class="edit-popup">
|
||||||
|
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
|
||||||
|
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||||||
|
<el-form-item label="条码名称" prop="name">
|
||||||
|
<el-input v-model="formData.name" clearable placeholder="请输入条码名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="拼音信息" prop="py">
|
||||||
|
<el-input v-model="formData.py" clearable placeholder="请输入拼音信息" />
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="条码内容" prop="code">
|
||||||
|
<el-input v-model="formData.code" clearable placeholder="请输入条码内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="条码类型" prop="type">
|
||||||
|
<el-select class="flex-1" v-model="formData.type" clearable placeholder="请选择条码类型">
|
||||||
|
<el-option v-for="(item, index) in dictData.code_type" :key="index" :label="item.name"
|
||||||
|
:value="parseInt(item.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注信息" prop="data">
|
||||||
|
<el-input v-model="formData.data" type="textarea" clearable placeholder="请输入备注信息" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="扩展信息" prop="more">
|
||||||
|
<el-input v-model="formData.more" type="textarea" clearable placeholder="请输入扩展信息" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input v-model="formData.sort" clearable placeholder="请输入排序" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="codeEdit">
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import Popup from '@/components/popup/index.vue'
|
||||||
|
import { apiCodeAdd, apiCodeEdit, apiCodeDetail } from '@/api/code'
|
||||||
|
import { timeFormat } from '@/utils/util'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
defineProps({
|
||||||
|
dictData: {
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['success', 'close'])
|
||||||
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
|
const mode = ref('add')
|
||||||
|
|
||||||
|
|
||||||
|
// 弹窗标题
|
||||||
|
const popupTitle = computed(() => {
|
||||||
|
return mode.value == 'edit' ? '编辑条码表' : '新增条码表'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive({
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
py: '',
|
||||||
|
code: '',
|
||||||
|
type: '',
|
||||||
|
data: '',
|
||||||
|
more: '',
|
||||||
|
sort: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 表单验证
|
||||||
|
const formRules = reactive<any>({
|
||||||
|
name: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入条码名称',
|
||||||
|
trigger: ['blur']
|
||||||
|
}],
|
||||||
|
py: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入拼音信息',
|
||||||
|
trigger: ['blur']
|
||||||
|
}],
|
||||||
|
code: [{
|
||||||
|
required: true,
|
||||||
|
message: '请输入条码内容',
|
||||||
|
trigger: ['blur']
|
||||||
|
}],
|
||||||
|
type: [{
|
||||||
|
required: true,
|
||||||
|
message: '请选择条码类型0:条形码 | 1:二维码',
|
||||||
|
trigger: ['blur']
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 获取详情
|
||||||
|
const setFormData = async (data: Record<any, any>) => {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (data[key] != null && data[key] != undefined) {
|
||||||
|
//@ts-ignore
|
||||||
|
formData[key] = data[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDetail = async (row: Record<string, any>) => {
|
||||||
|
const data = await apiCodeDetail({
|
||||||
|
id: row.id
|
||||||
|
})
|
||||||
|
setFormData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
const data = { ...formData, }
|
||||||
|
mode.value == 'edit'
|
||||||
|
? await apiCodeEdit(data)
|
||||||
|
: await apiCodeAdd(data)
|
||||||
|
popupRef.value?.close()
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
//打开弹窗
|
||||||
|
const open = (type = 'add') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭回调
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setFormData,
|
||||||
|
getDetail
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,76 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-card class="!border-none mb-4" shadow="never">
|
||||||
|
<el-form class="mb-[-16px]" :model="queryParams" inline>
|
||||||
|
<el-form-item label="条码名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
class="w-[280px]"
|
||||||
|
v-model="queryParams.name"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入条码名称"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
|
<el-button @click="resetParams">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
||||||
|
<div class="mt-4">
|
||||||
|
<el-table :data="pager.lists">
|
||||||
|
<el-table-column label="ID" prop="id" width="55" />
|
||||||
|
<el-table-column label="名称" prop="name" show-overflow-tooltip />
|
||||||
|
<el-table-column label="商品款数" prop="nums" show-overflow-tooltip />
|
||||||
|
<el-table-column label="状态" prop="status" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span v-if="row.status == 1">已报价</span>
|
||||||
|
<span v-if="row.status == 0" style="color: #f56c6c">待报价</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="170" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button link @click="handleDetail(row.id)" type="primary">
|
||||||
|
<router-link
|
||||||
|
:to="{
|
||||||
|
path: 'quoteOffer',
|
||||||
|
query: {
|
||||||
|
id: row.id,
|
||||||
|
date: row.name.substring(0, 10)
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
立即报价
|
||||||
|
</router-link>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="flex mt-4 justify-end">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="codeLists">
|
||||||
|
import { usePaging } from "@/hooks/usePaging";
|
||||||
|
import { useDictData } from "@/hooks/useDictOptions";
|
||||||
|
import { opurchaseGoodsOfferDateListsApi } from "@/api/quote";
|
||||||
|
import feedback from "@/utils/feedback";
|
||||||
|
|
||||||
|
// 查询条件
|
||||||
|
const queryParams = reactive({});
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: opurchaseGoodsOfferDateListsApi,
|
||||||
|
params: queryParams,
|
||||||
|
});
|
||||||
|
|
||||||
|
getLists();
|
||||||
|
|
||||||
|
const handleDetail = (e) => {};
|
||||||
|
</script>
|
|
@ -0,0 +1,244 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-card class="!border-none mb-4" shadow="never">
|
||||||
|
<el-tabs v-model="activeName" class="demo-tabs" @tab-change="tabChange">
|
||||||
|
<el-tab-pane label="待报价" name="tobe">
|
||||||
|
<div class="flex mb-4">
|
||||||
|
<el-button type="primary" @click="submit">提交报价</el-button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="quote-list"
|
||||||
|
v-infinite-scroll="getLists(1)"
|
||||||
|
:infinite-scroll-distance="1000"
|
||||||
|
:infinite-scroll-delay="500"
|
||||||
|
:infinite-scroll-immediate="false"
|
||||||
|
style="overflow: auto"
|
||||||
|
>
|
||||||
|
<el-row :gutter="20" style="width: 100%">
|
||||||
|
<el-col :span="8" v-for="(item, index) in list1" :key="index">
|
||||||
|
<el-card>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div>名称: {{ item.goods_name }}</div>
|
||||||
|
<div>
|
||||||
|
需求量:
|
||||||
|
<span style="color: #f56c6c">{{ item.need_num }}</span>
|
||||||
|
{{ item.unit_name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between mt-4">
|
||||||
|
<div class="flex" style="align-items: center">
|
||||||
|
<span class="mr-2">提供数量: </span>
|
||||||
|
<el-input
|
||||||
|
v-model="item.nums"
|
||||||
|
placeholder="请输入可提供数量"
|
||||||
|
style="flex: 1"
|
||||||
|
></el-input>
|
||||||
|
</div>
|
||||||
|
<div class="flex" style="align-items: center">
|
||||||
|
<span class="mr-2">产品报价: </span>
|
||||||
|
<el-input
|
||||||
|
v-model="item.price"
|
||||||
|
placeholder="请输入产品报价"
|
||||||
|
style="flex: 1"
|
||||||
|
></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end mt-4">
|
||||||
|
<div>
|
||||||
|
共 {{ item.nums }} {{ item.unit_name }} 合计
|
||||||
|
<span class="mx-1" style="color: #f56c6c">{{
|
||||||
|
(item.nums * item.price).toFixed(2)
|
||||||
|
}}</span>
|
||||||
|
元
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="报价记录" name="yet">
|
||||||
|
<div
|
||||||
|
class="quote-list not-btn"
|
||||||
|
v-infinite-scroll="getLists(1)"
|
||||||
|
:infinite-scroll-distance="1000"
|
||||||
|
:infinite-scroll-delay="500"
|
||||||
|
:infinite-scroll-immediate="false"
|
||||||
|
style="overflow: auto"
|
||||||
|
>
|
||||||
|
<el-row :gutter="20" style="width: 100%;">
|
||||||
|
<el-col :span="8" v-for="(item, index) in list2" :key="index">
|
||||||
|
<el-card>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div>名称: {{ item.goods_name }}</div>
|
||||||
|
<div>
|
||||||
|
需求量:
|
||||||
|
<span style="color: #f56c6c">{{ item.need_num }}</span>
|
||||||
|
{{ item.unit_name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between mt-4">
|
||||||
|
<div
|
||||||
|
class="flex"
|
||||||
|
style="align-items: center; position: relative"
|
||||||
|
>
|
||||||
|
<span class="mr-2">提供数量: </span>
|
||||||
|
<el-input
|
||||||
|
v-model="item.nums"
|
||||||
|
placeholder="请输入可提供数量"
|
||||||
|
style="flex: 1"
|
||||||
|
readonly
|
||||||
|
></el-input>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-image
|
||||||
|
v-if="item.is_adopt == 1"
|
||||||
|
src="https://lihai001.oss-cn-chengdu.aliyuncs.com/attach/274ad202405111523222891.png"
|
||||||
|
></el-image>
|
||||||
|
<el-image
|
||||||
|
v-else-if="item.is_adopt == 2"
|
||||||
|
src="https://lihai001.oss-cn-chengdu.aliyuncs.com/attach/739c3202405071458553459.png"
|
||||||
|
></el-image>
|
||||||
|
<el-image
|
||||||
|
v-else
|
||||||
|
src="https://lihai001.oss-cn-chengdu.aliyuncs.com/attach/04c2c202405071501462462.png"
|
||||||
|
></el-image>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex" style="align-items: center">
|
||||||
|
<span class="mr-2">产品报价: </span>
|
||||||
|
<el-input
|
||||||
|
v-model="item.price"
|
||||||
|
placeholder="请输入产品报价"
|
||||||
|
style="flex: 1"
|
||||||
|
readonly
|
||||||
|
></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end mt-4">
|
||||||
|
<div>
|
||||||
|
共 {{ item.nums }} {{ item.unit_name }} 合计
|
||||||
|
<span class="mx-1" style="color: #f56c6c">{{
|
||||||
|
(item.nums * item.price).toFixed(2)
|
||||||
|
}}</span>
|
||||||
|
元
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="quoteOffer">
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import {
|
||||||
|
opurchaseGoodsOfferListsApi,
|
||||||
|
opurchaseGoodsOfferOfferApi,
|
||||||
|
} from "@/api/quote";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const form = ref({});
|
||||||
|
|
||||||
|
const activeName = ref("tobe");
|
||||||
|
const activeMap = ref(
|
||||||
|
new Map([
|
||||||
|
["detail", true],
|
||||||
|
["yet", false],
|
||||||
|
])
|
||||||
|
);
|
||||||
|
const tabChange = (type: any) => {
|
||||||
|
if (type == "yet") {
|
||||||
|
list2.value = [];
|
||||||
|
getLists(2);
|
||||||
|
} else {
|
||||||
|
list1.value = [];
|
||||||
|
getLists(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const list1 = ref([]);
|
||||||
|
const list2 = ref([]);
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
date: route.query.date,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getLists = (e = 1) => {
|
||||||
|
opurchaseGoodsOfferListsApi({
|
||||||
|
type: e,
|
||||||
|
...queryParams,
|
||||||
|
}).then((res) => {
|
||||||
|
if (e == 1) {
|
||||||
|
list1.value = [...list1.value, ...res.lists];
|
||||||
|
} else {
|
||||||
|
list2.value = [...list2.value, ...res.lists];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getLists();
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
let data = list1.value
|
||||||
|
.filter((item) => {
|
||||||
|
return +item.price && +item.nums;
|
||||||
|
})
|
||||||
|
.map((item: any) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
nums: item.nums,
|
||||||
|
price: item.price,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (!data.length) return ElMessage.error("请先填写产品报价");
|
||||||
|
opurchaseGoodsOfferOfferApi({
|
||||||
|
data: data,
|
||||||
|
}).then((res) => {
|
||||||
|
getLists();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.quote-list {
|
||||||
|
height: calc(100vh - 300px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.not-btn{
|
||||||
|
height: calc(100vh - 252px);
|
||||||
|
}
|
||||||
|
/* 修改滚动条的样式 */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0.315rem; /* 设置滚动条的宽度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条的轨道样式 */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background-color: #f1f1f1; /* 设置轨道的背景色 */
|
||||||
|
margin: 1.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条的滑块样式 */
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #ccc; /* 设置滑块的背景色 */
|
||||||
|
border-radius: 0.315rem; /* 设置滑块的圆角 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条鼠标悬停时的滑块样式 */
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: #999; /* 设置鼠标悬停时滑块的背景色 */
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -46,7 +46,7 @@
|
||||||
</template>
|
</template>
|
||||||
提交今日商户采购订单
|
提交今日商户采购订单
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<!-- <el-button
|
||||||
v-perms="['operation.opurchaseclass/add']"
|
v-perms="['operation.opurchaseclass/add']"
|
||||||
type="success"
|
type="success"
|
||||||
@click="onPrintOrder"
|
@click="onPrintOrder"
|
||||||
|
@ -55,10 +55,10 @@
|
||||||
<icon name="el-icon-Printer" />
|
<icon name="el-icon-Printer" />
|
||||||
</template>
|
</template>
|
||||||
打印
|
打印
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" />
|
<!-- <el-table-column type="selection" width="55" /> -->
|
||||||
<el-table-column label="ID" prop="id" show-overflow-tooltip />
|
<el-table-column label="ID" prop="id" show-overflow-tooltip />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="所属商户"
|
label="所属商户"
|
||||||
|
@ -114,6 +114,9 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="120" fixed="right">
|
<el-table-column label="操作" width="120" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<!-- <el-button type="primary" link @click="onPrintOrder(row)">
|
||||||
|
打印
|
||||||
|
</el-button> -->
|
||||||
<el-button type="primary" link @click="handleDetail(row)">
|
<el-button type="primary" link @click="handleDetail(row)">
|
||||||
详情
|
详情
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -166,10 +169,12 @@ import { useRouter } from "vue-router";
|
||||||
import { print, testPrint } from "@/utils/print";
|
import { print, testPrint } from "@/utils/print";
|
||||||
|
|
||||||
// 下列方法都是没有拖拽设计页面的, 相当于代码模式, 使用代码设计页面
|
// 下列方法都是没有拖拽设计页面的, 相当于代码模式, 使用代码设计页面
|
||||||
const onPrintOrder = () => {
|
const onPrintOrder = (row: any) => {
|
||||||
testPrint({
|
console.log(row);
|
||||||
name: 'test'
|
|
||||||
})
|
// testPrint({
|
||||||
|
// name: 'test'
|
||||||
|
// })
|
||||||
};
|
};
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<el-form-item label="名称" prop="name">
|
<el-form-item label="名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入名称" clearable />
|
<el-input v-model="formData.name" placeholder="请输入名称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="归属部门" prop="dept_id">
|
<!-- <el-form-item label="归属部门" prop="dept_id">
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
v-model="formData.dept_id"
|
v-model="formData.dept_id"
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
:default-expand-all="true"
|
:default-expand-all="true"
|
||||||
placeholder="请选择上级部门"
|
placeholder="请选择上级部门"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<el-form-item label="岗位" prop="jobs_id">
|
<el-form-item label="岗位" prop="jobs_id">
|
||||||
<el-select
|
<el-select
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
</el-button> -->
|
</el-button> -->
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" />
|
<!-- <el-table-column type="selection" width="55" /> -->
|
||||||
<el-table-column label="ID" prop="id" show-overflow-tooltip />
|
<el-table-column label="ID" prop="id" show-overflow-tooltip />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="所属商户"
|
label="所属商户"
|
||||||
|
|
Loading…
Reference in New Issue