This commit is contained in:
parent
299a1875f0
commit
40b6de6fe8
|
@ -0,0 +1,2 @@
|
|||
# VITE_BASE_URL = 'http://192.168.1.24:8324'
|
||||
VITE_BASE_URL = 'https://crmeb-test.shop.lihaink.cn'
|
|
@ -0,0 +1 @@
|
|||
VITE_BASE_URL = ''
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue + TS</title>
|
||||
<title>里海收银系统</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import request from '@/utils/axios.js'
|
||||
|
||||
/**
|
||||
* @description 商品列表
|
||||
*/
|
||||
export function storeListApi(id, data) {
|
||||
return request.get(`server/${30}/product/lst`, { params: data })
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import request from '@/utils/axios.js'
|
||||
|
||||
/**
|
||||
* @description 验证码
|
||||
*/
|
||||
export function captchaApi() {
|
||||
return request.get(`captcha`)
|
||||
}
|
||||
/**
|
||||
* @description 登录
|
||||
*/
|
||||
export function login(data) {
|
||||
return request.post(`auth/login`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 信息
|
||||
*/
|
||||
export function info(data) {
|
||||
return request.get(`user`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 退出登录
|
||||
*/
|
||||
export function logout() {
|
||||
return request.post(`logout`)
|
||||
}
|
|
@ -1,15 +1,65 @@
|
|||
<script setup>
|
||||
import { useUserStore } from "@/store/user.js";
|
||||
import { ref } from "vue";
|
||||
import { info, logout } from "@/api/user.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const merInfo = ref({});
|
||||
merInfo.value = userStore.userInfo.mer_info;
|
||||
|
||||
const getInfo = () => {
|
||||
info().then((res) => {
|
||||
merInfo.value = res.data;
|
||||
});
|
||||
};
|
||||
|
||||
const router = useRouter();
|
||||
const onLogout = () => {
|
||||
logout().then(() => {
|
||||
userStore.setUserInfo({});
|
||||
userStore.setToken("");
|
||||
router.push("/login");
|
||||
}).catch(() => {
|
||||
ElMessage({
|
||||
message: "退出失败",
|
||||
type: "error",
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// getInfo();
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="my-card">
|
||||
<div class="card-header">
|
||||
<el-image src="https://multi-store.crmeb.net/uploads/attach/store/2024/03/20240314/6cea2e0fd02480fc6fb62a9783a9ac43.png"></el-image>
|
||||
<el-image
|
||||
src="https://multi-store.crmeb.net/uploads/attach/store/2024/03/20240314/6cea2e0fd02480fc6fb62a9783a9ac43.png"
|
||||
></el-image>
|
||||
<div class="card-title">里海收银系统</div>
|
||||
</div>
|
||||
<div class="card-body">我的</div>
|
||||
<div class="card-body">
|
||||
<el-dropdown trigger="hover">
|
||||
<div class="el-dropdown-link">
|
||||
<el-avatar :src="merInfo.mer_avatar" icon="user-filled"/>
|
||||
<div class="info">
|
||||
<div>{{ merInfo.mer_name }}</div>
|
||||
<div>{{ merInfo.service_phone }}</div>
|
||||
</div>
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="onLogout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -27,7 +77,22 @@
|
|||
font-size: 1.6rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.el-dropdown-link{
|
||||
width: auto;
|
||||
display: flex;
|
||||
color: #fff;
|
||||
align-items: center;
|
||||
.info{
|
||||
margin: 0 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.el-dropdown{
|
||||
border: none;
|
||||
}
|
||||
</style>
|
|
@ -6,15 +6,17 @@ import 'element-plus/dist/index.css'
|
|||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
import router from './router'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
|
||||
import { createPinia } from 'pinia'
|
||||
const app = createApp(App)
|
||||
|
||||
// 注册图标
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
const pinia = createPinia();
|
||||
|
||||
app.use(router)
|
||||
app.use(pinia)
|
||||
app.use(ElementPlus, {
|
||||
locale: zhCn,
|
||||
})
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import layout from '@/layout/index.vue';
|
||||
import { useUserStore } from '@/store/user.js';
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
|
@ -14,6 +17,11 @@ const routes = [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
@ -21,4 +29,16 @@ const router = createRouter({
|
|||
routes
|
||||
});
|
||||
|
||||
// 全局前置守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 如果用户访问的不是登录页面,并且未登录,则重定向到登录页面
|
||||
if (to.name !== 'login' && !userStore.Token) {
|
||||
next({ name: 'login' });
|
||||
} else {
|
||||
next(); // 放行
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,24 @@
|
|||
import { defineStore } from "pinia"
|
||||
import { ref } from "vue"
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
const userInfo = ref(JSON.parse(localStorage.getItem('userInfo') || '{}'));
|
||||
|
||||
const Token = ref(localStorage.getItem('Token'));
|
||||
|
||||
const setUserInfo = (e)=>{
|
||||
userInfo.value = e;
|
||||
localStorage.setItem('userInfo',JSON.stringify(e));
|
||||
}
|
||||
const setToken = (e)=>{
|
||||
Token.value = e;
|
||||
localStorage.setItem('Token',e);
|
||||
}
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
Token,
|
||||
setUserInfo,
|
||||
setToken
|
||||
}
|
||||
})
|
|
@ -0,0 +1,39 @@
|
|||
import axios from "axios";
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: import.meta.env.VITE_BASE_URL + '/api',
|
||||
timeout: 5000
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
config => {
|
||||
// 在发送请求之前做些什么,例如添加token、修改请求头等
|
||||
const token = localStorage.getItem('Token');
|
||||
if (token) {
|
||||
config.headers['X-Token'] = 'Bearer ' + token;
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
error => {
|
||||
// 处理请求错误
|
||||
console.error(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
response => {
|
||||
// 对响应数据做些什么,例如解析数据、统一处理错误等
|
||||
return response.data;
|
||||
},
|
||||
error => {
|
||||
// 处理响应错误
|
||||
console.error(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default request;
|
|
@ -1,4 +1,25 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
const list = ref([])
|
||||
|
||||
const clearAll = ()=>{
|
||||
list.value = []
|
||||
}
|
||||
|
||||
const deleteOne = (index)=>{
|
||||
list.value.splice(index,1)
|
||||
}
|
||||
|
||||
const getList = ()=>{
|
||||
list = {
|
||||
num: 1
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getList
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -7,10 +28,24 @@
|
|||
<div class="my-order">
|
||||
<div class="header-nav">
|
||||
<div class="nav-item">已选购 <span>{{ 0 }}</span> 件</div>
|
||||
<div class="nav-item-clear"><el-icon><Delete /></el-icon>清空</div>
|
||||
<div class="nav-item-clear" @click="clearAll"><el-icon><Delete /></el-icon>清空</div>
|
||||
</div>
|
||||
<div class="order-list">
|
||||
订单列表
|
||||
<el-empty v-if="list.length==0" description="请点击右侧添加商品" />
|
||||
<div v-else class="order-item" v-for="(item, index) in list" :key="index">
|
||||
<el-image class="order-item-img" src="https://multi-store.crmeb.net/uploads/attach/2024/03/01/8149b6d6bfc22ad622ec478528310c43.jpg"></el-image>
|
||||
<div class="order-item-info">
|
||||
<div class="order-item-title">
|
||||
<div class="title">很不错的商品名称很不错的商品名称很不错的商品名称很不错的商品名称</div>
|
||||
<div class="delete" @click="deleteOne">删除</div>
|
||||
</div>
|
||||
<div class="order-item-sku">设备规格</div>
|
||||
<div class="order-item-price">
|
||||
<div>¥<span>100</span></div>
|
||||
<div><el-input-number v-model="item.num" :min="1" :step="1" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-footer">
|
||||
<div class="order-total">
|
||||
|
@ -33,8 +68,6 @@
|
|||
height: 100%;
|
||||
background-color: #fff;
|
||||
width: 30rem;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 10rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
|
@ -42,6 +75,7 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1rem;
|
||||
height: 1.5rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
span{
|
||||
|
@ -51,10 +85,52 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.order-list{
|
||||
height: calc(100vh - 100px - 14rem);
|
||||
overflow-y: auto;
|
||||
.order-item{
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
.order-item-img{
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
.order-item-info{
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
&>div{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.order-item-title{
|
||||
.title{
|
||||
width: 18rem;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.delete{
|
||||
color: #1890ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.order-item-sku{
|
||||
font-size: 0.8rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.order-footer{
|
||||
position: absolute;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
|
||||
const show = (e)=>{
|
||||
dialogVisible.value = e;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="商品规格"
|
||||
width="650"
|
||||
>
|
||||
<div class="shop">
|
||||
<div class="shop-info">
|
||||
<div class="shop-info-left">
|
||||
<el-image src="https://multi-store.crmeb.net/uploads/attach/2024/03/01/8149b6d6bfc22ad622ec478528310c43.jpg"></el-image>
|
||||
</div>
|
||||
<div class="shop-info-right">
|
||||
<div class="shop-info-right-top">香奈儿(Chanel)五号香水(经典)50ml(礼盒装)送女 香奈儿(Chanel)五号香水(经典)50ml(礼盒装)送女 香奈儿(Chanel)五号香水(经典)50ml(礼盒装)送女香奈儿(Chanel)五号香水(经典)50ml(礼盒装)送女</div>
|
||||
<div class="shop-info-right-center">库存100</div>
|
||||
<div class="shop-info-right-price">¥<span>{{0.10}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shop-sku">
|
||||
<div class="title">产品</div>
|
||||
<div class="sku">
|
||||
<el-space wrap :size="20">
|
||||
<div class="sku-item sku-item_active">大</div>
|
||||
<div class="sku-item">中</div>
|
||||
<div class="sku-item">小</div>
|
||||
</el-space>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button class="ok-btn" type="primary" @click="dialogVisible = false">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dialog-footer{
|
||||
.ok-btn{
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
border-radius: 2.5rem;
|
||||
}
|
||||
}
|
||||
.shop{
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 1rem;
|
||||
.shop-info{
|
||||
display: flex;
|
||||
.shop-info-left{
|
||||
flex-shrink: 0;
|
||||
margin-right: 0.8rem;
|
||||
height: 8rem;
|
||||
width: 8rem;
|
||||
overflow: hidden;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
.shop-info-right{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.shop-info-right-top{
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 2; /* 限制文本显示为两行 */
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
.shop-info-right-center{
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.shop-info-right-price{
|
||||
color: #ff4a00;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
span{
|
||||
font-size: 1.4rem;
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.shop-sku{
|
||||
min-height: 20rem;
|
||||
.title{
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
padding: 1rem 0 0.5rem 0;
|
||||
}
|
||||
.sku{
|
||||
.sku-item{
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 3rem;
|
||||
&_active{
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,9 +1,25 @@
|
|||
<script setup>
|
||||
import { ref } from "vue";
|
||||
const input = ref("");
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
storeList:{
|
||||
type:Array,
|
||||
default:()=>[]
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['getStoreList'])
|
||||
|
||||
const bar_code = ref('');
|
||||
watch(bar_code, (val) => {
|
||||
emit('getStoreList', {
|
||||
bar_code: val
|
||||
})
|
||||
})
|
||||
|
||||
const loadMore = () => {
|
||||
console.log("loadMore");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -12,7 +28,7 @@ const loadMore = () => {
|
|||
<div class="nav-item-label">搜索</div>
|
||||
<div class="nav-item-input">
|
||||
<el-input
|
||||
v-model="input"
|
||||
v-model="bar_code"
|
||||
placeholder="搜索商品名称/ID/唯一码或点击聚焦扫码"
|
||||
clearable
|
||||
/>
|
||||
|
@ -23,12 +39,22 @@ const loadMore = () => {
|
|||
></el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shop-list" v-infinite-scroll="loadMore" infinite-scroll-distance="100" infinite-scroll-delay="500" style="overflow:auto">
|
||||
<div
|
||||
class="shop-list"
|
||||
v-infinite-scroll="loadMore"
|
||||
infinite-scroll-distance="100"
|
||||
infinite-scroll-delay="500"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<el-space wrap :size="20">
|
||||
<div class="shop-item" v-for="(item, index) in 26" :key="index">
|
||||
<el-image src="https://multi-store.crmeb.net/uploads/attach/2024/03/01/8149b6d6bfc22ad622ec478528310c43.jpg"></el-image>
|
||||
<div class="shop-name">桌面好物, 100cm*60cm*70cm大桌子</div>
|
||||
<div class="shop-price">¥<span>{{0.10}}</span></div>
|
||||
<div class="shop-item" v-for="(item, index) in storeList" :key="index">
|
||||
<el-image
|
||||
:src="item.image"
|
||||
></el-image>
|
||||
<div class="shop-name">{{ item.store_name }}</div>
|
||||
<div class="shop-price">
|
||||
¥<span>{{ item.price }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-space>
|
||||
</div>
|
||||
|
@ -84,17 +110,19 @@ const loadMore = () => {
|
|||
height: calc(100vh - 100px - 3rem);
|
||||
width: auto;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
box-sizing: border-box;
|
||||
padding-top: 20px;
|
||||
|
||||
.shop-item {
|
||||
width: 11rem;
|
||||
height: 16rem;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
border-radius: 1rem;
|
||||
padding: 0.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
|
||||
.el-image {
|
||||
border-radius: 0.5rem;
|
||||
|
@ -112,38 +140,21 @@ const loadMore = () => {
|
|||
|
||||
.shop-price {
|
||||
font-size: 0.8rem;
|
||||
color: #f5222d;
|
||||
span {
|
||||
font-size: 1.2rem;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
.shop-price {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 修改滚动条的样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: 5px; /* 设置滚动条的宽度 */
|
||||
}
|
||||
|
||||
/* 设置滚动条的轨道样式 */
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #f1f1f1; /* 设置轨道的背景色 */
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* 设置滚动条的滑块样式 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc; /* 设置滑块的背景色 */
|
||||
border-radius: 5px; /* 设置滑块的圆角 */
|
||||
}
|
||||
|
||||
/* 设置滚动条鼠标悬停时的滑块样式 */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #999; /* 设置鼠标悬停时滑块的背景色 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,6 +2,34 @@
|
|||
import order from './component/order.vue';
|
||||
import shop from './component/shop.vue';
|
||||
import padding from './component/padding.vue';
|
||||
import pupop from './component/pupop.vue';
|
||||
import { ref, nextTick } from 'vue';
|
||||
import { storeListApi } from "@/api/store.js";
|
||||
import { useUserStore } from "@/store/user.js";
|
||||
|
||||
const pupopRef = ref(null);
|
||||
|
||||
const storeList = ref([]);
|
||||
|
||||
const where = ref({
|
||||
page: 1,
|
||||
limit: 30,
|
||||
})
|
||||
const getStoreList = (data)=>{
|
||||
where.value = {
|
||||
...where.value,
|
||||
...data
|
||||
}
|
||||
storeListApi(where.value).then(res=>{
|
||||
storeList.value = res.data.list;
|
||||
})
|
||||
}
|
||||
getStoreList();
|
||||
|
||||
nextTick(() => {
|
||||
// pupopRef.value.show(true);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
@ -9,12 +37,34 @@ import padding from './component/padding.vue';
|
|||
<div class="my-card">
|
||||
<order />
|
||||
<padding />
|
||||
<shop style="flex: 1" />
|
||||
<shop style="flex: 1" :storeList="storeList" @getStoreList="getStoreList"/>
|
||||
<pupop ref="pupopRef"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss">
|
||||
.my-card{
|
||||
display: flex;
|
||||
}
|
||||
/* 修改滚动条的样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: 5px; /* 设置滚动条的宽度 */
|
||||
}
|
||||
|
||||
/* 设置滚动条的轨道样式 */
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #f1f1f1; /* 设置轨道的背景色 */
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* 设置滚动条的滑块样式 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc; /* 设置滑块的背景色 */
|
||||
border-radius: 5px; /* 设置滑块的圆角 */
|
||||
}
|
||||
|
||||
/* 设置滚动条鼠标悬停时的滑块样式 */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #999; /* 设置鼠标悬停时滑块的背景色 */
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,122 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { captchaApi, login, info } from "@/api/user.js";
|
||||
import { useUserStore } from "@/store/user.js";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
|
||||
const formLogin = ref({
|
||||
account: "",
|
||||
password: "",
|
||||
key: "",
|
||||
captchaVerification: "",
|
||||
code: "",
|
||||
});
|
||||
|
||||
const getCaptchaApi = () => {
|
||||
captchaApi()
|
||||
.then((res) => {
|
||||
formLogin.value.key = res.data.key;
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage({
|
||||
message: err.message,
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onLogin = () => {
|
||||
if (!formLogin.value.account)
|
||||
return ElMessage({
|
||||
message: "请填写账号",
|
||||
type: "error",
|
||||
});
|
||||
if (!formLogin.value.password)
|
||||
return ElMessage({
|
||||
message: "请填写密码",
|
||||
type: "error",
|
||||
});
|
||||
login(formLogin.value)
|
||||
.then((res) => {
|
||||
userStore.setToken(res.data.token);
|
||||
info().then(({data}) => {
|
||||
userStore.setUserInfo(data);
|
||||
router.push("/");
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage({
|
||||
message: err.message,
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// getCaptchaApi();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body">
|
||||
<div class="login">
|
||||
<div class="title">里海收银系统 - 登录</div>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-input v-model="formLogin.account" placeholder="请输入账号">
|
||||
<template #prefix>
|
||||
<el-icon><User /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="formLogin.password"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Lock /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button style="width: 100%" type="primary" @click="onLogin"
|
||||
>登录</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
background-image: url(https://multi-store.crmeb.net/view_cashier/img/bg.b8f6b872.png);
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.login {
|
||||
width: 18rem;
|
||||
/* height: 12rem; */
|
||||
background-color: #fff;
|
||||
border-radius: 2rem;
|
||||
padding: 2rem 3rem;
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 1.3rem;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -4,6 +4,10 @@ import vue from '@vitejs/plugin-vue'
|
|||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
port: '5175',
|
||||
host: '0.0.0.0',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': '/src'
|
||||
|
|
Loading…
Reference in New Issue