更新路由配置,修改店铺信息展示,登录拦截

This commit is contained in:
YeMingfei666 2025-02-08 15:52:52 +08:00
parent 16cd74fdd6
commit 6d3a3e7f91
35 changed files with 551 additions and 225 deletions

View File

@ -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=https://api.youlai.tech # 线上
# VITE_APP_API_URL=http://localhost:8989 # 本地 # VITE_APP_API_URL=http://localhost:8989 # 本地

View File

@ -5,18 +5,10 @@ const AUTH_BASE_URL = "/api/v1/auth";
const AuthAPI = { const AuthAPI = {
/** 登录接口*/ /** 登录接口*/
login(data: LoginFormData) { 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>({ return request<any, LoginResult>({
url: `${AUTH_BASE_URL}/login`, url: `auth/login`,
method: "post", method: "post",
data: formData, data: data,
headers: {
"Content-Type": "multipart/form-data",
},
}); });
}, },
@ -35,7 +27,7 @@ const AuthAPI = {
/** 注销登录接口 */ /** 注销登录接口 */
logout() { logout() {
return request({ return request({
url: `${AUTH_BASE_URL}/logout`, url: `auth/logout`,
method: "delete", method: "delete",
}); });
}, },
@ -66,13 +58,7 @@ export interface LoginFormData {
/** 登录响应 */ /** 登录响应 */
export interface LoginResult { export interface LoginResult {
/** 访问令牌 */ /** 访问令牌 */
accessToken: string; token: string;
/** 刷新令牌 */
refreshToken: string;
/** 令牌类型 */
tokenType: string;
/** 过期时间(秒) */
expiresIn: number;
} }
/** 验证码信息 */ /** 验证码信息 */

View File

@ -12,7 +12,7 @@ const MenuAPI = {
*/ */
getRoutes() { getRoutes() {
return request<any, RouteVO[]>({ return request<any, RouteVO[]>({
url: `${MENU_BASE_URL}/routes`, url: `api/menus/build`,
method: "get", method: "get",
}); });
}, },

View File

@ -8,9 +8,9 @@ const UserAPI = {
* *
* @returns * @returns
*/ */
getInfo() { getInfo(id: number) {
return request<any, UserInfo>({ return request<any, UserInfo>({
url: `${USER_BASE_URL}/me`, url: `api/tbShopInfo/` + id,
method: "get", method: "get",
}); });
}, },
@ -220,17 +220,23 @@ export interface UserInfo {
/** 用户名 */ /** 用户名 */
username?: string; username?: string;
/** 称 */ /** 店铺名称 */
nickname?: string; shopName?: string;
/** 头像URL */ /** 头像URL */
avatar?: string; coverImg?: string;
/** 角色 */ /** 角色 */
roles: string[]; roles: string[];
/** 权限 */ /** 权限 */
perms: string[]; perms: string[];
/** 店铺id */
shopId: number;
/** 店铺logo */
logo: string;
} }
/** /**

View File

@ -1,8 +1,8 @@
<template> <template>
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<div class="flex-center h100% p13px"> <div class="flex-center h100% p13px">
<img :src="userStore.userInfo.avatar" class="rounded-full mr-10px w24px h24px" /> <img :src="userStore.userInfo.logo" class="rounded-full mr-10px w40px h40px" />
<span>{{ userStore.userInfo.username }}</span> <span class="title">{{ userStore.userInfo.shopName }}</span>
<el-icon><CaretBottom /></el-icon> <el-icon><CaretBottom /></el-icon>
</div> </div>
<template #dropdown> <template #dropdown>
@ -58,3 +58,9 @@ function logout() {
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<style scoped>
.title {
font-size: 16px;
color: #5a5e66;
}
</style>

View File

@ -2,10 +2,8 @@
<div class="logo"> <div class="logo">
<transition name="el-fade-in-linear" mode="out-in"> <transition name="el-fade-in-linear" mode="out-in">
<router-link :key="+collapse" class="wh-full flex-center" to="/"> <router-link :key="+collapse" class="wh-full flex-center" to="/">
<img :src="logo" class="w20px h20px" /> <img :src="userStore.userInfo.logo" class="w20px h20px" />
<span v-if="!collapse" class="title"> <span v-if="!collapse" class="title">{{ userStore.userInfo.shopName }}</span>
{{ defaultSettings.title }}
</span>
</router-link> </router-link>
</transition> </transition>
</div> </div>
@ -13,7 +11,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import defaultSettings from "@/settings"; import defaultSettings from "@/settings";
import logo from "@/assets/logo.png"; import { useUserStore } from "@/store";
const userStore = useUserStore();
defineProps({ defineProps({
collapse: { collapse: {
@ -32,9 +32,12 @@ defineProps({
.title { .title {
flex-shrink: 0; /* 防止容器在空间不足时缩小 */ flex-shrink: 0; /* 防止容器在空间不足时缩小 */
margin-left: 10px; margin-left: 10px;
font-size: 14px; font-size: 16px;
font-weight: bold; color: #5a5e66;
color: #333; overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 150px;
} }
} }

View File

@ -7,7 +7,7 @@
:background-color="variables['menu-background']" :background-color="variables['menu-background']"
:text-color="variables['menu-text']" :text-color="variables['menu-text']"
:active-text-color="variables['menu-active-text']" :active-text-color="variables['menu-active-text']"
:unique-opened="false" :unique-opened="true"
:collapse-transition="false" :collapse-transition="false"
:mode="menuMode" :mode="menuMode"
@open="onMenuOpen" @open="onMenuOpen"

View File

@ -47,14 +47,14 @@ export function setupPermission() {
} }
} }
} else { } else {
next(); // 未登录,判断是否在白名单中
// // 未登录,判断是否在白名单中 if (whiteList.includes(to.path)) {
// if (whiteList.includes(to.path)) { next();
// } else { } else {
// // 不在白名单,重定向到登录页 // 不在白名单,重定向到登录页
// redirectToLogin(to, next); redirectToLogin(to, next);
// NProgress.done(); NProgress.done();
// } }
} }
}); });

View File

@ -35,7 +35,7 @@ export const constantRoutes: RouteRecordRaw[] = [
{ {
path: "index", path: "index",
component: () => import("@/views/data/index.vue"), component: () => import("@/views/data/index.vue"),
name: "index", name: "dataStatistics",
meta: { meta: {
title: "数据统计", title: "数据统计",
affix: false, affix: false,
@ -44,7 +44,7 @@ export const constantRoutes: RouteRecordRaw[] = [
}, },
{ {
path: "sales", path: "sales",
name: "sales", name: "salesStatistics",
component: () => import("@/views/data/sales.vue"), component: () => import("@/views/data/sales.vue"),
meta: { meta: {
title: "销售统计", title: "销售统计",
@ -52,6 +52,36 @@ export const constantRoutes: RouteRecordRaw[] = [
keepAlive: true, 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", path: "401",
component: () => import("@/views/error/401.vue"), 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,
},
},
],
},
]; ];
/** /**

View File

@ -25,10 +25,12 @@ export const usePermissionStore = defineStore("permission", () => {
return new Promise<RouteRecordRaw[]>((resolve, reject) => { return new Promise<RouteRecordRaw[]>((resolve, reject) => {
MenuAPI.getRoutes() MenuAPI.getRoutes()
.then((data) => { .then((data) => {
const dynamicRoutes = parseDynamicRoutes(data); // const dynamicRoutes = parseDynamicRoutes(data);
routes.value = [...constantRoutes, ...dynamicRoutes]; // routes.value = [...constantRoutes, ...dynamicRoutes];
// isRoutesLoaded.value = true;
// resolve(dynamicRoutes);
isRoutesLoaded.value = true; isRoutesLoaded.value = true;
resolve(dynamicRoutes); resolve(constantRoutes);
}) })
.catch((error) => { .catch((error) => {
reject(error); reject(error);

View File

@ -9,7 +9,6 @@ import { setToken, setRefreshToken, getRefreshToken, clearToken } from "@/utils/
export const useUserStore = defineStore("user", () => { export const useUserStore = defineStore("user", () => {
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo); const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
/** /**
* *
* *
@ -20,9 +19,10 @@ export const useUserStore = defineStore("user", () => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
AuthAPI.login(LoginFormData) AuthAPI.login(LoginFormData)
.then((data) => { .then((data) => {
const { tokenType, accessToken, refreshToken } = data; Object.assign(userInfo.value, { ...data });
setToken(tokenType + " " + accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx const { token } = data;
setRefreshToken(refreshToken); setToken(token); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
setRefreshToken(token);
resolve(); resolve();
}) })
.catch((error) => { .catch((error) => {
@ -38,7 +38,7 @@ export const useUserStore = defineStore("user", () => {
*/ */
function getUserInfo() { function getUserInfo() {
return new Promise<UserInfo>((resolve, reject) => { return new Promise<UserInfo>((resolve, reject) => {
UserAPI.getInfo() UserAPI.getInfo(userInfo.value.shopId)
.then((data) => { .then((data) => {
if (!data) { if (!data) {
reject("Verification failed, please Login again."); reject("Verification failed, please Login again.");
@ -77,8 +77,8 @@ export const useUserStore = defineStore("user", () => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
AuthAPI.refreshToken(refreshToken) AuthAPI.refreshToken(refreshToken)
.then((data) => { .then((data) => {
const { tokenType, accessToken, refreshToken } = data; const { token } = data;
setToken(tokenType + " " + accessToken); setToken(token);
setRefreshToken(refreshToken); setRefreshToken(refreshToken);
resolve(); resolve();
}) })

View File

@ -36,26 +36,26 @@ service.interceptors.response.use(
return response; return response;
} }
const { code, data, msg } = response.data; const { code, data, message } = response.data;
if (code === ResultEnum.SUCCESS || code === undefined || code === null) { if (code === ResultEnum.SUCCESS || code === undefined || code === null) {
return data ? data : response.data; return data ? data : response.data;
} }
ElMessage.error(msg || "系统出错"); ElMessage.error(message || "系统出错");
return Promise.reject(new Error(msg || "Error")); return Promise.reject(new Error(message || "Error"));
}, },
async (error: any) => { async (error: any) => {
// 非 2xx 状态码处理 401、403、500 等 // 非 2xx 状态码处理 401、403、500 等
const { config, response } = error; const { config, response } = error;
if (response) { if (response) {
const { code, msg } = response.data; const { code, message } = response.data;
if (code === ResultEnum.ACCESS_TOKEN_INVALID) { if (code === ResultEnum.ACCESS_TOKEN_INVALID) {
// Token 过期,刷新 Token // Token 过期,刷新 Token
return handleTokenRefresh(config); return handleTokenRefresh(config);
} else if (code === ResultEnum.REFRESH_TOKEN_INVALID) { } else if (code === ResultEnum.REFRESH_TOKEN_INVALID) {
return Promise.reject(new Error(msg || "Error")); return Promise.reject(new Error(message || "Error"));
} else { } else {
ElMessage.error(msg || "系统出错"); ElMessage.error(message || "系统出错");
} }
} }
return Promise.reject(error.message); return Promise.reject(error.message);

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -2,22 +2,22 @@
<div class="login" :style="'background-image:url(' + Background + ');'"> <div class="login" :style="'background-image:url(' + Background + ');'">
<el-form <el-form
ref="loginForm" ref="loginForm"
:model="loginForm" :model="state.loginForm"
:rules="loginRules" :rules="state.loginRules"
label-position="left" label-position="left"
label-width="0px" label-width="0px"
class="login-form" class="login-form"
> >
<h3 class="title">银收客后台管理</h3> <h3 class="title">银收客后台管理</h3>
<el-form-item> <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="merchant">商户</el-radio-button>
<el-radio-button value="staff">员工</el-radio-button> <el-radio-button value="staff">员工</el-radio-button>
</el-radio-group> </el-radio-group>
</el-form-item> </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 <el-input
v-model="loginForm.merchantName" v-model="state.loginForm.merchantName"
type="text" type="text"
auto-complete="off" auto-complete="off"
placeholder="商户号" placeholder="商户号"
@ -25,7 +25,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input
v-model="loginForm.username" v-model="state.loginForm.username"
type="text" type="text"
auto-complete="off" auto-complete="off"
placeholder="账号" placeholder="账号"
@ -33,7 +33,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input
v-model="loginForm.password" v-model="state.loginForm.password"
type="password" type="password"
auto-complete="off" auto-complete="off"
placeholder="密码" placeholder="密码"
@ -43,27 +43,27 @@
<el-form-item prop="code"> <el-form-item prop="code">
<div class="code_wrap"> <div class="code_wrap">
<el-input <el-input
v-model="loginForm.code" v-model="state.loginForm.code"
auto-complete="off" auto-complete="off"
placeholder="验证码" placeholder="验证码"
style="width: 63%" style="width: 63%"
@keyup.enter="handleLogin" @keyup.enter="handleLogin"
></el-input> ></el-input>
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" @click="getCode" /> <img :src="state.codeUrl" @click="getCode" />
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item style="width: 100%"> <el-form-item style="width: 100%">
<el-button <el-button
:loading="loading" :loading="state.loading"
size="default" size="default"
type="primary" type="primary"
style="width: 100%" style="width: 100%"
@click.prevent="handleLogin" @click.prevent="handleLogin"
> >
<span v-if="!loading"> </span> <span v-if="!state.loading"> </span>
<span v-else> 中...</span> <span v-else> 中...</span>
</el-button> </el-button>
</el-form-item> </el-form-item>
@ -76,168 +76,125 @@
</div> </div>
</template> </template>
<script> <script setup>
import { encrypt } from "@/utils/rsaEncrypt"; import { encrypt } from "@/utils/rsaEncrypt";
import { getCodeImg } from "@/api/login"; import { getCodeImg } from "@/api/login";
import { $douyin_checkIn } from "@/api/coup/index"; import { $douyin_checkIn } from "@/api/coup/index";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import qs from "qs"; import qs from "qs";
import Background from "@/assets/images/background_img.jpg"; import Background from "@/assets/images/background_img.jpg";
export default { import { useUserStore } from "@/store";
name: "Login", import { useRoute } from "vue-router";
data() { import router from "@/router";
return { const route = useRoute();
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()
let getinfo = localStorage.getItem("MerchantId"); const state = reactive({
let info = JSON.parse(getinfo); Background: Background,
if (info && info.merchantName) { codeUrl: "",
this.loginForm.merchantName = info.merchantName; cookiePass: "",
this.loginForm.username = info.username; loginForm: {
} username: "",
password: "",
rememberMe: false,
code: "",
uuid: "",
merchantName: "",
loginType: "merchant",
}, },
methods: { loginRules: {
getCode() { username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
getCodeImg().then((res) => { password: [{ required: true, trigger: "blur", message: "密码不能为空" }],
console.log(res); code: [{ required: true, trigger: "change", message: "验证码不能为空" }],
this.codeUrl = res.img; merchantName: [{ required: true, trigger: "change", message: "商户号不能为空" }],
this.loginForm.uuid = res.uuid; },
}); loading: false,
}, redirect: undefined,
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,
});
}
this.loading = false; onMounted(() => {
// //
localStorage.setItem( getCode();
"MerchantId", // // Cookie
JSON.stringify({ // this.getCookie()
merchantName: this.loginForm.merchantName, // // token
username: this.loginForm.username, // this.point()
})
); let getinfo = localStorage.getItem("MerchantId");
this.$router.push({ path: this.redirect || "/" }); let info = JSON.parse(getinfo);
// window.location.replace = './' if (info && info.merchantName) {
}) state.loginForm.merchantName = info.merchantName;
.catch((err) => { state.loginForm.username = info.username;
console.log(err); }
this.loading = false; });
this.getCode(); function getCode() {
}); getCodeImg().then((res) => {
} else { console.log(res);
console.log("error submit!!"); state.codeUrl = res.img;
return false; state.loginForm.uuid = res.uuid;
} });
}); }
}, function getCookie() {
point() { const username = Cookies.get("username");
const point = Cookies.get("point") !== undefined; let password = Cookies.get("password");
if (point) { const rememberMe = Cookies.get("rememberMe");
this.$notify({ // cookie
title: "提示", state.cookiePass = password === undefined ? "" : password;
message: "当前登录状态已过期,请重新登录!", password = password === undefined ? state.loginForm.password : password;
type: "warning", state.loginForm = {
duration: 5000, 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> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -287,6 +244,7 @@ export default {
.code_wrap { .code_wrap {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
width: 100%;
} }
.login-code { .login-code {

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

1
src/views/shop/index.vue Normal file
View File

@ -0,0 +1 @@
<template></template>

1
src/views/shop/log.vue Normal file
View File

@ -0,0 +1 @@
<template></template>

1
src/views/shop/role.vue Normal file
View File

@ -0,0 +1 @@
<template></template>

1
src/views/shop/staff.vue Normal file
View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

5
src/views/tool/index.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<div class="app-container">
11
</div>
</template>

3
src/views/tool/table.vue Normal file
View File

@ -0,0 +1,3 @@
<template>
<div class="app-container">11</div>
</template>

View File

0
src/views/user/index.vue Normal file
View File