更新路由配置,修改店铺信息展示,登录拦截
This commit is contained in:
parent
16cd74fdd6
commit
6d3a3e7f91
|
|
@ -6,7 +6,9 @@ VITE_APP_BASE_API=/dev-api
|
|||
|
||||
# 接口地址
|
||||
|
||||
VITE_APP_API_URL=https://admintestpapi.sxczgkj.cn/ # 线上
|
||||
# VITE_APP_API_URL=https://admintestpapi.sxczgkj.cn/ # 线上
|
||||
VITE_APP_API_URL=https://cashieradmin.sxczgkj.cn/ # 正式
|
||||
|
||||
# VITE_APP_API_URL=https://api.youlai.tech # 线上
|
||||
# VITE_APP_API_URL=http://localhost:8989 # 本地
|
||||
|
||||
|
|
|
|||
|
|
@ -5,18 +5,10 @@ const AUTH_BASE_URL = "/api/v1/auth";
|
|||
const AuthAPI = {
|
||||
/** 登录接口*/
|
||||
login(data: LoginFormData) {
|
||||
const formData = new FormData();
|
||||
formData.append("username", data.username);
|
||||
formData.append("password", data.password);
|
||||
formData.append("captchaKey", data.captchaKey);
|
||||
formData.append("captchaCode", data.captchaCode);
|
||||
return request<any, LoginResult>({
|
||||
url: `${AUTH_BASE_URL}/login`,
|
||||
url: `auth/login`,
|
||||
method: "post",
|
||||
data: formData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -35,7 +27,7 @@ const AuthAPI = {
|
|||
/** 注销登录接口 */
|
||||
logout() {
|
||||
return request({
|
||||
url: `${AUTH_BASE_URL}/logout`,
|
||||
url: `auth/logout`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
|
@ -66,13 +58,7 @@ export interface LoginFormData {
|
|||
/** 登录响应 */
|
||||
export interface LoginResult {
|
||||
/** 访问令牌 */
|
||||
accessToken: string;
|
||||
/** 刷新令牌 */
|
||||
refreshToken: string;
|
||||
/** 令牌类型 */
|
||||
tokenType: string;
|
||||
/** 过期时间(秒) */
|
||||
expiresIn: number;
|
||||
token: string;
|
||||
}
|
||||
|
||||
/** 验证码信息 */
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const MenuAPI = {
|
|||
*/
|
||||
getRoutes() {
|
||||
return request<any, RouteVO[]>({
|
||||
url: `${MENU_BASE_URL}/routes`,
|
||||
url: `api/menus/build`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ const UserAPI = {
|
|||
*
|
||||
* @returns 登录用户昵称、头像信息,包括角色和权限
|
||||
*/
|
||||
getInfo() {
|
||||
getInfo(id: number) {
|
||||
return request<any, UserInfo>({
|
||||
url: `${USER_BASE_URL}/me`,
|
||||
url: `api/tbShopInfo/` + id,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
|
@ -220,17 +220,23 @@ export interface UserInfo {
|
|||
/** 用户名 */
|
||||
username?: string;
|
||||
|
||||
/** 昵称 */
|
||||
nickname?: string;
|
||||
/** 店铺名称 */
|
||||
shopName?: string;
|
||||
|
||||
/** 头像URL */
|
||||
avatar?: string;
|
||||
coverImg?: string;
|
||||
|
||||
/** 角色 */
|
||||
roles: string[];
|
||||
|
||||
/** 权限 */
|
||||
perms: string[];
|
||||
|
||||
/** 店铺id */
|
||||
shopId: number;
|
||||
|
||||
/** 店铺logo */
|
||||
logo: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<el-dropdown trigger="click">
|
||||
<div class="flex-center h100% p13px">
|
||||
<img :src="userStore.userInfo.avatar" class="rounded-full mr-10px w24px h24px" />
|
||||
<span>{{ userStore.userInfo.username }}</span>
|
||||
<img :src="userStore.userInfo.logo" class="rounded-full mr-10px w40px h40px" />
|
||||
<span class="title">{{ userStore.userInfo.shopName }}</span>
|
||||
<el-icon><CaretBottom /></el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
|
|
@ -58,3 +58,9 @@ function logout() {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped>
|
||||
.title {
|
||||
font-size: 16px;
|
||||
color: #5a5e66;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,10 +2,8 @@
|
|||
<div class="logo">
|
||||
<transition name="el-fade-in-linear" mode="out-in">
|
||||
<router-link :key="+collapse" class="wh-full flex-center" to="/">
|
||||
<img :src="logo" class="w20px h20px" />
|
||||
<span v-if="!collapse" class="title">
|
||||
{{ defaultSettings.title }}
|
||||
</span>
|
||||
<img :src="userStore.userInfo.logo" class="w20px h20px" />
|
||||
<span v-if="!collapse" class="title">{{ userStore.userInfo.shopName }}</span>
|
||||
</router-link>
|
||||
</transition>
|
||||
</div>
|
||||
|
|
@ -13,7 +11,9 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import defaultSettings from "@/settings";
|
||||
import logo from "@/assets/logo.png";
|
||||
import { useUserStore } from "@/store";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
defineProps({
|
||||
collapse: {
|
||||
|
|
@ -32,9 +32,12 @@ defineProps({
|
|||
.title {
|
||||
flex-shrink: 0; /* 防止容器在空间不足时缩小 */
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
color: #5a5e66;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
:background-color="variables['menu-background']"
|
||||
:text-color="variables['menu-text']"
|
||||
:active-text-color="variables['menu-active-text']"
|
||||
:unique-opened="false"
|
||||
:unique-opened="true"
|
||||
:collapse-transition="false"
|
||||
:mode="menuMode"
|
||||
@open="onMenuOpen"
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@ export function setupPermission() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
// // 未登录,判断是否在白名单中
|
||||
// if (whiteList.includes(to.path)) {
|
||||
// } else {
|
||||
// // 不在白名单,重定向到登录页
|
||||
// redirectToLogin(to, next);
|
||||
// NProgress.done();
|
||||
// }
|
||||
// 未登录,判断是否在白名单中
|
||||
if (whiteList.includes(to.path)) {
|
||||
next();
|
||||
} else {
|
||||
// 不在白名单,重定向到登录页
|
||||
redirectToLogin(to, next);
|
||||
NProgress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/data/index.vue"),
|
||||
name: "index",
|
||||
name: "dataStatistics",
|
||||
meta: {
|
||||
title: "数据统计",
|
||||
affix: false,
|
||||
|
|
@ -44,7 +44,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||
},
|
||||
{
|
||||
path: "sales",
|
||||
name: "sales",
|
||||
name: "salesStatistics",
|
||||
component: () => import("@/views/data/sales.vue"),
|
||||
meta: {
|
||||
title: "销售统计",
|
||||
|
|
@ -52,6 +52,36 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "table",
|
||||
name: "tableStatistics",
|
||||
component: () => import("@/views/data/table.vue"),
|
||||
meta: {
|
||||
title: "桌台统计",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "credit",
|
||||
name: "creditStatistics",
|
||||
component: () => import("@/views/data/credit.vue"),
|
||||
meta: {
|
||||
title: "挂账管理",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "work",
|
||||
name: "workStatistics",
|
||||
component: () => import("@/views/data/work.vue"),
|
||||
meta: {
|
||||
title: "交班记录",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "401",
|
||||
component: () => import("@/views/error/401.vue"),
|
||||
|
|
@ -64,6 +94,313 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/shop",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "店铺管理",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/shop/index.vue"),
|
||||
name: "shopConfig",
|
||||
meta: {
|
||||
title: "店铺配置",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "role",
|
||||
component: () => import("@/views/shop/role.vue"),
|
||||
name: "shopRole",
|
||||
meta: {
|
||||
title: "角色管理",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "staff",
|
||||
component: () => import("@/views/shop/staff.vue"),
|
||||
name: "shopStaff",
|
||||
meta: {
|
||||
title: "员工列表",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "log",
|
||||
component: () => import("@/views/shop/log.vue"),
|
||||
name: "shopLog",
|
||||
meta: {
|
||||
title: "操作日志",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/online-shop",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "线上店铺",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/online-shop/index.vue"),
|
||||
name: "shopDecoration",
|
||||
meta: {
|
||||
title: "店铺装修",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "goods-group",
|
||||
component: () => import("@/views/online-shop/goods-group.vue"),
|
||||
name: "goodsGroup",
|
||||
meta: {
|
||||
title: "商品分组",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "pad",
|
||||
component: () => import("@/views/online-shop/pad-setting.vue"),
|
||||
name: "pad",
|
||||
meta: {
|
||||
title: "Pad点单设置",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/system-setting",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "系统设置",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "pay-types",
|
||||
component: () => import("@/views/system-setting/pay-types.vue"),
|
||||
name: "payTypes",
|
||||
meta: {
|
||||
title: "支付方式",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: "/tool",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "经营工具",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/tool/index.vue"),
|
||||
name: "toolIndex",
|
||||
meta: {
|
||||
title: "代客下单",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "table",
|
||||
component: () => import("@/views/tool/table.vue"),
|
||||
name: "table",
|
||||
meta: {
|
||||
title: "台桌管理",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/application",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "应用中心",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "marketing",
|
||||
component: () => import("@/views/application/marketing.vue"),
|
||||
name: "applicationMarketing",
|
||||
meta: {
|
||||
title: "营销中心",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/application/index.vue"),
|
||||
name: "applicationIndex",
|
||||
meta: {
|
||||
title: "列表管理",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/devices",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "设备管理",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "printer",
|
||||
component: () => import("@/views/devices/printer.vue"),
|
||||
name: "devicesPrinter",
|
||||
meta: {
|
||||
title: "打印机",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/product",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "商品管理",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/product/list.vue"),
|
||||
name: "productIndex",
|
||||
meta: {
|
||||
title: "商品列表",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "unit",
|
||||
component: () => import("@/views/product/unit.vue"),
|
||||
name: "productUnit",
|
||||
meta: {
|
||||
title: "常用单位",
|
||||
affix: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "category",
|
||||
component: () => import("@/views/product/category.vue"),
|
||||
name: "productCategory",
|
||||
meta: {
|
||||
title: "商品分类",
|
||||
affix: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "specifications",
|
||||
component: () => import("@/views/product/specifications.vue"),
|
||||
name: "specifications",
|
||||
meta: {
|
||||
title: "商品规格",
|
||||
affix: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/inventory",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "进销存",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "consumables",
|
||||
component: () => import("@/views/inventory/consumables.vue"),
|
||||
name: "consumables",
|
||||
meta: {
|
||||
title: "耗材列表",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/user",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "用户管理",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/user/index.vue"),
|
||||
name: "userIndex",
|
||||
meta: {
|
||||
title: "用户列表",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "active",
|
||||
component: () => import("@/views/user/active.vue"),
|
||||
name: "userActive",
|
||||
meta: {
|
||||
title: "活动管理",
|
||||
affix: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/order",
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: "订单管理",
|
||||
icon: "data_statistics",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "index",
|
||||
component: () => import("@/views/order/index.vue"),
|
||||
name: "orderIndex",
|
||||
meta: {
|
||||
title: "订单列表",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "group-purchase",
|
||||
component: () => import("@/views/order/group-purchase.vue"),
|
||||
name: "orderRefund",
|
||||
meta: {
|
||||
title: "团购订单",
|
||||
affix: false,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -25,10 +25,12 @@ export const usePermissionStore = defineStore("permission", () => {
|
|||
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
|
||||
MenuAPI.getRoutes()
|
||||
.then((data) => {
|
||||
const dynamicRoutes = parseDynamicRoutes(data);
|
||||
routes.value = [...constantRoutes, ...dynamicRoutes];
|
||||
// const dynamicRoutes = parseDynamicRoutes(data);
|
||||
// routes.value = [...constantRoutes, ...dynamicRoutes];
|
||||
// isRoutesLoaded.value = true;
|
||||
// resolve(dynamicRoutes);
|
||||
isRoutesLoaded.value = true;
|
||||
resolve(dynamicRoutes);
|
||||
resolve(constantRoutes);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { setToken, setRefreshToken, getRefreshToken, clearToken } from "@/utils/
|
|||
|
||||
export const useUserStore = defineStore("user", () => {
|
||||
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*
|
||||
|
|
@ -20,9 +19,10 @@ export const useUserStore = defineStore("user", () => {
|
|||
return new Promise<void>((resolve, reject) => {
|
||||
AuthAPI.login(LoginFormData)
|
||||
.then((data) => {
|
||||
const { tokenType, accessToken, refreshToken } = data;
|
||||
setToken(tokenType + " " + accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
|
||||
setRefreshToken(refreshToken);
|
||||
Object.assign(userInfo.value, { ...data });
|
||||
const { token } = data;
|
||||
setToken(token); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
|
||||
setRefreshToken(token);
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
@ -38,7 +38,7 @@ export const useUserStore = defineStore("user", () => {
|
|||
*/
|
||||
function getUserInfo() {
|
||||
return new Promise<UserInfo>((resolve, reject) => {
|
||||
UserAPI.getInfo()
|
||||
UserAPI.getInfo(userInfo.value.shopId)
|
||||
.then((data) => {
|
||||
if (!data) {
|
||||
reject("Verification failed, please Login again.");
|
||||
|
|
@ -77,8 +77,8 @@ export const useUserStore = defineStore("user", () => {
|
|||
return new Promise<void>((resolve, reject) => {
|
||||
AuthAPI.refreshToken(refreshToken)
|
||||
.then((data) => {
|
||||
const { tokenType, accessToken, refreshToken } = data;
|
||||
setToken(tokenType + " " + accessToken);
|
||||
const { token } = data;
|
||||
setToken(token);
|
||||
setRefreshToken(refreshToken);
|
||||
resolve();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -36,26 +36,26 @@ service.interceptors.response.use(
|
|||
return response;
|
||||
}
|
||||
|
||||
const { code, data, msg } = response.data;
|
||||
const { code, data, message } = response.data;
|
||||
if (code === ResultEnum.SUCCESS || code === undefined || code === null) {
|
||||
return data ? data : response.data;
|
||||
}
|
||||
|
||||
ElMessage.error(msg || "系统出错");
|
||||
return Promise.reject(new Error(msg || "Error"));
|
||||
ElMessage.error(message || "系统出错");
|
||||
return Promise.reject(new Error(message || "Error"));
|
||||
},
|
||||
async (error: any) => {
|
||||
// 非 2xx 状态码处理 401、403、500 等
|
||||
const { config, response } = error;
|
||||
if (response) {
|
||||
const { code, msg } = response.data;
|
||||
const { code, message } = response.data;
|
||||
if (code === ResultEnum.ACCESS_TOKEN_INVALID) {
|
||||
// Token 过期,刷新 Token
|
||||
return handleTokenRefresh(config);
|
||||
} else if (code === ResultEnum.REFRESH_TOKEN_INVALID) {
|
||||
return Promise.reject(new Error(msg || "Error"));
|
||||
return Promise.reject(new Error(message || "Error"));
|
||||
} else {
|
||||
ElMessage.error(msg || "系统出错");
|
||||
ElMessage.error(message || "系统出错");
|
||||
}
|
||||
}
|
||||
return Promise.reject(error.message);
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -2,22 +2,22 @@
|
|||
<div class="login" :style="'background-image:url(' + Background + ');'">
|
||||
<el-form
|
||||
ref="loginForm"
|
||||
:model="loginForm"
|
||||
:rules="loginRules"
|
||||
:model="state.loginForm"
|
||||
:rules="state.loginRules"
|
||||
label-position="left"
|
||||
label-width="0px"
|
||||
class="login-form"
|
||||
>
|
||||
<h3 class="title">银收客后台管理</h3>
|
||||
<el-form-item>
|
||||
<el-radio-group v-model="loginForm.loginType">
|
||||
<el-radio-group v-model="state.loginForm.loginType">
|
||||
<el-radio-button value="merchant">商户</el-radio-button>
|
||||
<el-radio-button value="staff">员工</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="merchantName" v-if="loginForm.loginType == 'staff'">
|
||||
<el-form-item prop="merchantName" v-if="state.loginForm.loginType == 'staff'">
|
||||
<el-input
|
||||
v-model="loginForm.merchantName"
|
||||
v-model="state.loginForm.merchantName"
|
||||
type="text"
|
||||
auto-complete="off"
|
||||
placeholder="商户号"
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="loginForm.username"
|
||||
v-model="state.loginForm.username"
|
||||
type="text"
|
||||
auto-complete="off"
|
||||
placeholder="账号"
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="loginForm.password"
|
||||
v-model="state.loginForm.password"
|
||||
type="password"
|
||||
auto-complete="off"
|
||||
placeholder="密码"
|
||||
|
|
@ -43,27 +43,27 @@
|
|||
<el-form-item prop="code">
|
||||
<div class="code_wrap">
|
||||
<el-input
|
||||
v-model="loginForm.code"
|
||||
v-model="state.loginForm.code"
|
||||
auto-complete="off"
|
||||
placeholder="验证码"
|
||||
style="width: 63%"
|
||||
@keyup.enter="handleLogin"
|
||||
></el-input>
|
||||
<div class="login-code">
|
||||
<img :src="codeUrl" @click="getCode" />
|
||||
<img :src="state.codeUrl" @click="getCode" />
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item style="width: 100%">
|
||||
<el-button
|
||||
:loading="loading"
|
||||
:loading="state.loading"
|
||||
size="default"
|
||||
type="primary"
|
||||
style="width: 100%"
|
||||
@click.prevent="handleLogin"
|
||||
>
|
||||
<span v-if="!loading">登 录</span>
|
||||
<span v-if="!state.loading">登 录</span>
|
||||
<span v-else>登 录 中...</span>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
|
@ -76,168 +76,125 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { encrypt } from "@/utils/rsaEncrypt";
|
||||
import { getCodeImg } from "@/api/login";
|
||||
import { $douyin_checkIn } from "@/api/coup/index";
|
||||
import Cookies from "js-cookie";
|
||||
import qs from "qs";
|
||||
import Background from "@/assets/images/background_img.jpg";
|
||||
export default {
|
||||
name: "Login",
|
||||
data() {
|
||||
return {
|
||||
Background: Background,
|
||||
codeUrl: "",
|
||||
cookiePass: "",
|
||||
loginForm: {
|
||||
username: "",
|
||||
password: "",
|
||||
rememberMe: false,
|
||||
code: "",
|
||||
uuid: "",
|
||||
merchantName: "",
|
||||
loginType: "merchant",
|
||||
},
|
||||
loginRules: {
|
||||
username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
|
||||
password: [{ required: true, trigger: "blur", message: "密码不能为空" }],
|
||||
code: [{ required: true, trigger: "change", message: "验证码不能为空" }],
|
||||
merchantName: [{ required: true, trigger: "change", message: "商户号不能为空" }],
|
||||
},
|
||||
loading: false,
|
||||
redirect: undefined,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler: function (route) {
|
||||
const data = route.query;
|
||||
if (data && data.redirect) {
|
||||
this.redirect = data.redirect;
|
||||
delete data.redirect;
|
||||
if (JSON.stringify(data) !== "{}") {
|
||||
this.redirect = this.redirect + "&" + qs.stringify(data, { indices: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// 获取验证码
|
||||
this.getCode();
|
||||
// // 获取用户名密码等Cookie
|
||||
// this.getCookie()
|
||||
// // token 过期提示
|
||||
// this.point()
|
||||
import { useUserStore } from "@/store";
|
||||
import { useRoute } from "vue-router";
|
||||
import router from "@/router";
|
||||
const route = useRoute();
|
||||
|
||||
let getinfo = localStorage.getItem("MerchantId");
|
||||
let info = JSON.parse(getinfo);
|
||||
if (info && info.merchantName) {
|
||||
this.loginForm.merchantName = info.merchantName;
|
||||
this.loginForm.username = info.username;
|
||||
}
|
||||
const state = reactive({
|
||||
Background: Background,
|
||||
codeUrl: "",
|
||||
cookiePass: "",
|
||||
loginForm: {
|
||||
username: "",
|
||||
password: "",
|
||||
rememberMe: false,
|
||||
code: "",
|
||||
uuid: "",
|
||||
merchantName: "",
|
||||
loginType: "merchant",
|
||||
},
|
||||
methods: {
|
||||
getCode() {
|
||||
getCodeImg().then((res) => {
|
||||
console.log(res);
|
||||
this.codeUrl = res.img;
|
||||
this.loginForm.uuid = res.uuid;
|
||||
});
|
||||
},
|
||||
getCookie() {
|
||||
const username = Cookies.get("username");
|
||||
let password = Cookies.get("password");
|
||||
const rememberMe = Cookies.get("rememberMe");
|
||||
// 保存cookie里面的加密后的密码
|
||||
this.cookiePass = password === undefined ? "" : password;
|
||||
password = password === undefined ? this.loginForm.password : password;
|
||||
this.loginForm = {
|
||||
username: username === undefined ? this.loginForm.username : username,
|
||||
password: password,
|
||||
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
|
||||
code: "",
|
||||
merchantName: "",
|
||||
loginType: "merchant",
|
||||
};
|
||||
},
|
||||
handleLogin() {
|
||||
this.$refs.loginForm.validate((valid) => {
|
||||
// const user = {
|
||||
// username: this.loginForm.username,
|
||||
// password: this.loginForm.password,
|
||||
// rememberMe: this.loginForm.rememberMe,
|
||||
// code: this.loginForm.code,
|
||||
// uuid: this.loginForm.uuid,
|
||||
// merchantName: this.loginForm.merchantName,
|
||||
// loginType: this.loginForm.loginType
|
||||
// }
|
||||
// if (user.password !== this.cookiePass) {
|
||||
// user.password = encrypt(user.password)
|
||||
// }
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
// if (user.rememberMe) {
|
||||
// Cookies.set('username', user.username, { expires: Config.passCookieExpires })
|
||||
// Cookies.set('password', user.password, { expires: Config.passCookieExpires })
|
||||
// Cookies.set('rememberMe', user.rememberMe, { expires: Config.passCookieExpires })
|
||||
// } else {
|
||||
// Cookies.remove('username')
|
||||
// Cookies.remove('password')
|
||||
// Cookies.remove('rememberMe')
|
||||
// }
|
||||
// console.log(user);
|
||||
const user = { ...this.loginForm };
|
||||
console.log(user);
|
||||
user.password = encrypt(user.password);
|
||||
this.$store
|
||||
.dispatch("Login", user)
|
||||
.then(() => {
|
||||
if (localStorage.getItem("shopName") != "admin") {
|
||||
$douyin_checkIn({
|
||||
loginName: user.username,
|
||||
});
|
||||
}
|
||||
loginRules: {
|
||||
username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
|
||||
password: [{ required: true, trigger: "blur", message: "密码不能为空" }],
|
||||
code: [{ required: true, trigger: "change", message: "验证码不能为空" }],
|
||||
merchantName: [{ required: true, trigger: "change", message: "商户号不能为空" }],
|
||||
},
|
||||
loading: false,
|
||||
redirect: undefined,
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
// 保存商户号
|
||||
localStorage.setItem(
|
||||
"MerchantId",
|
||||
JSON.stringify({
|
||||
merchantName: this.loginForm.merchantName,
|
||||
username: this.loginForm.username,
|
||||
})
|
||||
);
|
||||
this.$router.push({ path: this.redirect || "/" });
|
||||
// window.location.replace = './'
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
this.loading = false;
|
||||
this.getCode();
|
||||
});
|
||||
} else {
|
||||
console.log("error submit!!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
point() {
|
||||
const point = Cookies.get("point") !== undefined;
|
||||
if (point) {
|
||||
this.$notify({
|
||||
title: "提示",
|
||||
message: "当前登录状态已过期,请重新登录!",
|
||||
type: "warning",
|
||||
duration: 5000,
|
||||
onMounted(() => {
|
||||
// 获取验证码
|
||||
getCode();
|
||||
// // 获取用户名密码等Cookie
|
||||
// this.getCookie()
|
||||
// // token 过期提示
|
||||
// this.point()
|
||||
|
||||
let getinfo = localStorage.getItem("MerchantId");
|
||||
let info = JSON.parse(getinfo);
|
||||
if (info && info.merchantName) {
|
||||
state.loginForm.merchantName = info.merchantName;
|
||||
state.loginForm.username = info.username;
|
||||
}
|
||||
});
|
||||
function getCode() {
|
||||
getCodeImg().then((res) => {
|
||||
console.log(res);
|
||||
state.codeUrl = res.img;
|
||||
state.loginForm.uuid = res.uuid;
|
||||
});
|
||||
}
|
||||
function getCookie() {
|
||||
const username = Cookies.get("username");
|
||||
let password = Cookies.get("password");
|
||||
const rememberMe = Cookies.get("rememberMe");
|
||||
// 保存cookie里面的加密后的密码
|
||||
state.cookiePass = password === undefined ? "" : password;
|
||||
password = password === undefined ? state.loginForm.password : password;
|
||||
state.loginForm = {
|
||||
username: username === undefined ? state.loginForm.username : username,
|
||||
password: password,
|
||||
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
|
||||
code: "",
|
||||
merchantName: "",
|
||||
loginType: "merchant",
|
||||
};
|
||||
}
|
||||
|
||||
const loginForm = ref(null);
|
||||
const userStore = useUserStore();
|
||||
|
||||
/**
|
||||
* 解析 redirect 字符串 为 path 和 queryParams
|
||||
*
|
||||
* @returns { path: string, queryParams: Record<string, string> } 解析后的 path 和 queryParams
|
||||
*/
|
||||
function parseRedirect() {
|
||||
const query = route.query;
|
||||
const redirect = query.redirect ?? "/";
|
||||
|
||||
const url = new URL(redirect, window.location.origin);
|
||||
const path = url.pathname;
|
||||
const queryParams = {};
|
||||
|
||||
url.searchParams.forEach((value, key) => {
|
||||
queryParams[key] = value;
|
||||
});
|
||||
|
||||
return { path, queryParams };
|
||||
}
|
||||
function handleLogin() {
|
||||
loginForm.value.validate((valid) => {
|
||||
if (valid) {
|
||||
state.loading = true;
|
||||
const user = { ...state.loginForm };
|
||||
user.password = encrypt(user.password);
|
||||
console.log(user);
|
||||
userStore
|
||||
.login(user)
|
||||
.then(async (res) => {
|
||||
await userStore.getUserInfo();
|
||||
const { path, queryParams } = parseRedirect();
|
||||
router.push({ path: path, query: queryParams });
|
||||
})
|
||||
.catch(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
Cookies.remove("point");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
} else {
|
||||
console.log("error submit!!");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
@ -287,6 +244,7 @@ export default {
|
|||
.code_wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-code {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<template></template>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
11
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div class="app-container">11</div>
|
||||
</template>
|
||||
Loading…
Reference in New Issue