增加店铺列表页面,增加vue-amap,修改登录相关接口类型
This commit is contained in:
parent
a599adc63e
commit
81d6ef44ef
|
|
@ -84,6 +84,7 @@
|
||||||
"@typescript-eslint/eslint-plugin": "^8.23.0",
|
"@typescript-eslint/eslint-plugin": "^8.23.0",
|
||||||
"@typescript-eslint/parser": "^8.23.0",
|
"@typescript-eslint/parser": "^8.23.0",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
"@vuemap/unplugin-resolver": "^1.0.4",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"commitizen": "^4.3.1",
|
"commitizen": "^4.3.1",
|
||||||
"cz-git": "^1.11.0",
|
"cz-git": "^1.11.0",
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ const baseURL = "account/admin/";
|
||||||
|
|
||||||
const AuthAPI = {
|
const AuthAPI = {
|
||||||
/** 登录接口*/
|
/** 登录接口*/
|
||||||
login(data: LoginFormData) {
|
login(data: loginRequest) {
|
||||||
return request<any, LoginResult>({
|
return request<any, loginResponse>({
|
||||||
url: `${baseURL}auth/login`,
|
url: `${baseURL}auth/login`,
|
||||||
method: "post",
|
method: "post",
|
||||||
data: data,
|
data: data,
|
||||||
|
|
@ -13,14 +13,14 @@ const AuthAPI = {
|
||||||
|
|
||||||
/** 获取验证码接口*/
|
/** 获取验证码接口*/
|
||||||
getCaptcha() {
|
getCaptcha() {
|
||||||
return request<any, CaptchaInfo>({
|
return request<any, codeResponse>({
|
||||||
url: `${baseURL}auth/captcha`,
|
url: `${baseURL}auth/captcha`,
|
||||||
method: "get",
|
method: "get",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**getPermission */
|
/**getPermission */
|
||||||
getPermission() {
|
getPermission() {
|
||||||
return request<any, CaptchaInfo>({
|
return request<any, codeResponse>({
|
||||||
url: `${baseURL}auth/permission`,
|
url: `${baseURL}auth/permission`,
|
||||||
method: "get",
|
method: "get",
|
||||||
});
|
});
|
||||||
|
|
@ -28,34 +28,327 @@ const AuthAPI = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AuthAPI;
|
export default AuthAPI;
|
||||||
|
/**
|
||||||
/** 登录表单数据 */
|
* 验证码信息
|
||||||
export interface LoginFormData {
|
*
|
||||||
/** 用户名 */
|
* CzgResult«?»
|
||||||
username: string;
|
|
||||||
/** 密码 */
|
|
||||||
password: string;
|
|
||||||
/** 验证码缓存uuid */
|
|
||||||
uuid: string;
|
|
||||||
/** 验证码 */
|
|
||||||
code: string;
|
|
||||||
/** 登录类型
|
|
||||||
* 0:商户登录
|
|
||||||
* 1:员工登录
|
|
||||||
*/
|
*/
|
||||||
loginType: number;
|
export interface codeResponse {
|
||||||
|
code?: number | null;
|
||||||
|
data?: null;
|
||||||
|
msg?: null | string;
|
||||||
|
[property: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 登录响应 */
|
/**
|
||||||
export interface LoginResult {
|
* 登录参数
|
||||||
/** 访问令牌 */
|
*
|
||||||
token: string;
|
* SysLoginDTO
|
||||||
|
*/
|
||||||
|
export interface loginRequest {
|
||||||
|
/**
|
||||||
|
* 验证码
|
||||||
|
*/
|
||||||
|
code: null | string;
|
||||||
|
/**
|
||||||
|
* 登录类型 0:商户登录 1:员工登录
|
||||||
|
*/
|
||||||
|
loginType: number | null;
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
password: null | string;
|
||||||
|
/**
|
||||||
|
* 用户名
|
||||||
|
*/
|
||||||
|
username: null | string;
|
||||||
|
/**
|
||||||
|
* 验证码uid
|
||||||
|
*/
|
||||||
|
uuid: null | string;
|
||||||
|
[property: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 验证码信息 */
|
/**
|
||||||
export interface CaptchaInfo {
|
* token信息
|
||||||
/** 验证码缓存uuid */
|
*
|
||||||
uuid: string;
|
* CzgResult«LoginVO»
|
||||||
/** 验证码图片Base64字符串 */
|
*/
|
||||||
code: string;
|
export interface loginResponse {
|
||||||
|
code?: number | null;
|
||||||
|
data?: LoginVO;
|
||||||
|
msg?: null | string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LoginVO
|
||||||
|
*/
|
||||||
|
export interface LoginVO {
|
||||||
|
/**
|
||||||
|
* 登录类型,0商户 1员工
|
||||||
|
*/
|
||||||
|
loginType?: number | null;
|
||||||
|
/**
|
||||||
|
* 接口权限集
|
||||||
|
*/
|
||||||
|
promissionList?: string[] | null;
|
||||||
|
/**
|
||||||
|
* 店铺信息
|
||||||
|
*/
|
||||||
|
shopInfo?: TbShopInfo;
|
||||||
|
/**
|
||||||
|
* token信息
|
||||||
|
*/
|
||||||
|
tokenInfo?: SaTokenInfo;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 店铺信息
|
||||||
|
*
|
||||||
|
* TbShopInfo
|
||||||
|
*/
|
||||||
|
export interface TbShopInfo {
|
||||||
|
/**
|
||||||
|
* 详细地址
|
||||||
|
*/
|
||||||
|
address?: null | string;
|
||||||
|
/**
|
||||||
|
* 项目分类
|
||||||
|
*/
|
||||||
|
article?: null | string;
|
||||||
|
/**
|
||||||
|
* 背景图
|
||||||
|
*/
|
||||||
|
backImg?: null | string;
|
||||||
|
/**
|
||||||
|
* 开票系统账号
|
||||||
|
*/
|
||||||
|
bindAccount?: null | string;
|
||||||
|
/**
|
||||||
|
* 台桌预订短信
|
||||||
|
*/
|
||||||
|
bookingSms?: null | string;
|
||||||
|
/**
|
||||||
|
* 营业时间(周结束)
|
||||||
|
*/
|
||||||
|
businessEndDay?: null | string;
|
||||||
|
/**
|
||||||
|
* 营业时间(周开始)
|
||||||
|
*/
|
||||||
|
businessStartDay?: null | string;
|
||||||
|
/**
|
||||||
|
* 营业时间
|
||||||
|
*/
|
||||||
|
businessTime?: null | string;
|
||||||
|
/**
|
||||||
|
* 连锁店扩展店名
|
||||||
|
*/
|
||||||
|
chainName?: null | string;
|
||||||
|
/**
|
||||||
|
* 市
|
||||||
|
*/
|
||||||
|
cities?: null | string;
|
||||||
|
/**
|
||||||
|
* 积分群体 all-所有 vip-仅针对会员
|
||||||
|
*/
|
||||||
|
consumeColony?: null | string;
|
||||||
|
/**
|
||||||
|
* 联系人姓名
|
||||||
|
*/
|
||||||
|
contactName?: null | string;
|
||||||
|
/**
|
||||||
|
* 封面图
|
||||||
|
*/
|
||||||
|
coverImg?: null | string;
|
||||||
|
createTime?: null | string;
|
||||||
|
/**
|
||||||
|
* 店铺简介
|
||||||
|
*/
|
||||||
|
detail?: null | string;
|
||||||
|
/**
|
||||||
|
* 区/县
|
||||||
|
*/
|
||||||
|
districts?: null | string;
|
||||||
|
/**
|
||||||
|
* 就餐模式 堂食 dine-in 外带 take-out
|
||||||
|
*/
|
||||||
|
eatModel?: null | string;
|
||||||
|
/**
|
||||||
|
* 到期时间
|
||||||
|
*/
|
||||||
|
expireTime?: null | string;
|
||||||
|
/**
|
||||||
|
* 门头照
|
||||||
|
*/
|
||||||
|
frontImg?: null | string;
|
||||||
|
/**
|
||||||
|
* 使用系统用户 sys_user id
|
||||||
|
*/
|
||||||
|
id?: number | null;
|
||||||
|
/**
|
||||||
|
* 是否允许会员自定义金额 1 允许 0 不允许
|
||||||
|
*/
|
||||||
|
isCustomAmount?: number | null;
|
||||||
|
/**
|
||||||
|
* 是否开启会员充值密码 1 启用 0 禁用
|
||||||
|
*/
|
||||||
|
isMemberInPwd?: number | null;
|
||||||
|
/**
|
||||||
|
* 是否启用会员价 0否1是
|
||||||
|
*/
|
||||||
|
isMemberPrice?: number | null;
|
||||||
|
/**
|
||||||
|
* 是否开启会员退款密码 1 启用 0 禁用
|
||||||
|
*/
|
||||||
|
isMemberReturnPwd?: number | null;
|
||||||
|
/**
|
||||||
|
* 是否开启退款密码 1 启用 0 禁用
|
||||||
|
*/
|
||||||
|
isReturnPwd?: number | null;
|
||||||
|
/**
|
||||||
|
* 是否免除桌位费 0否1是
|
||||||
|
*/
|
||||||
|
isTableFee?: number | null;
|
||||||
|
/**
|
||||||
|
* 经纬度
|
||||||
|
*/
|
||||||
|
lat?: null | string;
|
||||||
|
/**
|
||||||
|
* 经纬度
|
||||||
|
*/
|
||||||
|
lng?: null | string;
|
||||||
|
/**
|
||||||
|
* 店铺logo
|
||||||
|
*/
|
||||||
|
logo?: null | string;
|
||||||
|
/**
|
||||||
|
* 主店id
|
||||||
|
*/
|
||||||
|
mainId?: number | null;
|
||||||
|
/**
|
||||||
|
* 0停业 1,正常营业 2,网上售卖
|
||||||
|
*/
|
||||||
|
onSale?: number | null;
|
||||||
|
/**
|
||||||
|
* 操作密码
|
||||||
|
*/
|
||||||
|
operationPwd?: null | string;
|
||||||
|
/**
|
||||||
|
* 店铺收款码
|
||||||
|
*/
|
||||||
|
paymentQrcode?: null | string;
|
||||||
|
/**
|
||||||
|
* 联系电话
|
||||||
|
*/
|
||||||
|
phone?: null | string;
|
||||||
|
/**
|
||||||
|
* trial试用版,release正式
|
||||||
|
*/
|
||||||
|
profiles?: null | string;
|
||||||
|
/**
|
||||||
|
* 省
|
||||||
|
*/
|
||||||
|
provinces?: null | string;
|
||||||
|
registerType?: null | string;
|
||||||
|
/**
|
||||||
|
* 数电发票类型
|
||||||
|
*/
|
||||||
|
sdType?: null | string;
|
||||||
|
/**
|
||||||
|
* 店铺名称
|
||||||
|
*/
|
||||||
|
shopName?: null | string;
|
||||||
|
/**
|
||||||
|
* 商家二维码
|
||||||
|
*/
|
||||||
|
shopQrcode?: null | string;
|
||||||
|
/**
|
||||||
|
* 店铺类型 单店--only 连锁店--chain--加盟店join (对应原来 type)
|
||||||
|
*/
|
||||||
|
shopType?: null | string;
|
||||||
|
/**
|
||||||
|
* 小程序码(零点八零首页)
|
||||||
|
*/
|
||||||
|
smallQrcode?: null | string;
|
||||||
|
/**
|
||||||
|
* -1 平台禁用 0-过期,1正式营业,
|
||||||
|
*/
|
||||||
|
status?: number | null;
|
||||||
|
/**
|
||||||
|
* 店铺口号
|
||||||
|
*/
|
||||||
|
subTitle?: null | string;
|
||||||
|
/**
|
||||||
|
* 桌位费
|
||||||
|
*/
|
||||||
|
tableFee?: number | null;
|
||||||
|
/**
|
||||||
|
* 商家标签
|
||||||
|
*/
|
||||||
|
tag?: null | string;
|
||||||
|
/**
|
||||||
|
* 税率
|
||||||
|
*/
|
||||||
|
taxAmount?: null | string;
|
||||||
|
/**
|
||||||
|
* 管理 0否 1是, 1 为直接管理 可切换店铺 0 不可以切换
|
||||||
|
*/
|
||||||
|
tubeType?: number | null;
|
||||||
|
updateTime?: null | string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token信息
|
||||||
|
*
|
||||||
|
* SaTokenInfo
|
||||||
|
*/
|
||||||
|
export interface SaTokenInfo {
|
||||||
|
/**
|
||||||
|
* 此 token 是否已经登录
|
||||||
|
*/
|
||||||
|
isLogin?: boolean | null;
|
||||||
|
/**
|
||||||
|
* 登录设备类型
|
||||||
|
*/
|
||||||
|
loginDevice?: null | string;
|
||||||
|
/**
|
||||||
|
* 此 token 对应的 LoginId,未登录时为 null
|
||||||
|
*/
|
||||||
|
loginId?: { [key: string]: any };
|
||||||
|
/**
|
||||||
|
* 多账号体系下的账号类型
|
||||||
|
*/
|
||||||
|
loginType?: null | string;
|
||||||
|
/**
|
||||||
|
* Account-Session 剩余有效时间(单位: 秒)
|
||||||
|
*/
|
||||||
|
sessionTimeout?: number | null;
|
||||||
|
/**
|
||||||
|
* 自定义数据(暂无意义,留作扩展)
|
||||||
|
*/
|
||||||
|
tag?: null | string;
|
||||||
|
/**
|
||||||
|
* token 距离被冻结还剩多少时间(单位: 秒)
|
||||||
|
*/
|
||||||
|
tokenActiveTimeout?: number | null;
|
||||||
|
/**
|
||||||
|
* token 名称
|
||||||
|
*/
|
||||||
|
tokenName?: null | string;
|
||||||
|
/**
|
||||||
|
* Token-Session 剩余有效时间(单位: 秒)
|
||||||
|
*/
|
||||||
|
tokenSessionTimeout?: number | null;
|
||||||
|
/**
|
||||||
|
* token 剩余有效期(单位: 秒)
|
||||||
|
*/
|
||||||
|
tokenTimeout?: number | null;
|
||||||
|
/**
|
||||||
|
* token 值
|
||||||
|
*/
|
||||||
|
tokenValue?: null | string;
|
||||||
|
[property: string]: any;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import request from "@/utils/request";
|
||||||
|
const baseURL = "account/admin/";
|
||||||
|
|
||||||
|
const MenuApi = {
|
||||||
|
/** 获取当前用户菜单列表*/
|
||||||
|
getRoutes() {
|
||||||
|
return request<any, RouteVO>({
|
||||||
|
url: `${baseURL}menus`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MenuApi;
|
||||||
|
|
||||||
|
/** RouteVO,路由对象 */
|
||||||
|
export interface RouteVO {
|
||||||
|
/** 子路由列表 */
|
||||||
|
children: RouteVO[];
|
||||||
|
/** 组件路径 */
|
||||||
|
component?: string;
|
||||||
|
/** 路由属性 */
|
||||||
|
meta?: Meta;
|
||||||
|
/** 路由名称 */
|
||||||
|
name?: string;
|
||||||
|
/** 路由路径 */
|
||||||
|
path?: string;
|
||||||
|
/** 跳转链接 */
|
||||||
|
redirect?: string;
|
||||||
|
}
|
||||||
|
/** Meta,路由属性 */
|
||||||
|
export interface Meta {
|
||||||
|
/** 【目录】只有一个子路由是否始终显示 */
|
||||||
|
alwaysShow?: boolean;
|
||||||
|
/** 是否隐藏(true-是 false-否) */
|
||||||
|
hidden?: boolean;
|
||||||
|
/** ICON */
|
||||||
|
icon?: string;
|
||||||
|
/** 【菜单】是否开启页面缓存 */
|
||||||
|
keepAlive?: boolean;
|
||||||
|
/** 路由title */
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import request from "@/utils/request";
|
||||||
|
const baseURL = "account/admin/shopInfo";
|
||||||
|
|
||||||
|
const ShopApi = {
|
||||||
|
/** 获取店铺列表*/
|
||||||
|
getList(params: PageQuery) {
|
||||||
|
return request<any, ShopInfoEditDTO[]>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "get",
|
||||||
|
params: params,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
add(data: ShopInfoEditDTO) {
|
||||||
|
return request<any, ShopInfoEditDTO>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
edit(data: ShopInfoEditDTO) {
|
||||||
|
return request<any, ShopInfoEditDTO>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "put",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShopApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShopInfoEditDTO
|
||||||
|
*/
|
||||||
|
export interface ShopInfoEditDTO {
|
||||||
|
accountName?: null | string;
|
||||||
|
accountPwd?: null | string;
|
||||||
|
activateCode?: null | string;
|
||||||
|
address?: null | string;
|
||||||
|
chainName?: null | string;
|
||||||
|
detail?: null | string;
|
||||||
|
frontImg?: null | string;
|
||||||
|
id: number | null;
|
||||||
|
lat?: null | string;
|
||||||
|
lng?: null | string;
|
||||||
|
logo?: null | string;
|
||||||
|
phone?: null | string;
|
||||||
|
profiles?: null | string;
|
||||||
|
roleId?: number | null;
|
||||||
|
shopName?: null | string;
|
||||||
|
shopType?: null | string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageQuery {
|
||||||
|
page: number;
|
||||||
|
shopName?: string;
|
||||||
|
size: number;
|
||||||
|
status?: number;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/** 店铺类型*/
|
||||||
|
export const $ShopType: ShopType[] = [
|
||||||
|
{
|
||||||
|
label: "单店",
|
||||||
|
value: "only",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "连锁店",
|
||||||
|
value: "chain",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "加盟店",
|
||||||
|
value: "join",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export interface ShopType {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ export const enum ResultEnum {
|
||||||
/**
|
/**
|
||||||
* 成功
|
* 成功
|
||||||
*/
|
*/
|
||||||
SUCCESS = "00000",
|
SUCCESS = "200",
|
||||||
/**
|
/**
|
||||||
* 错误
|
* 错误
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { createApp } from "vue";
|
import { createApp } from "vue";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import setupPlugins from "@/plugins";
|
import setupPlugins from "@/plugins";
|
||||||
|
|
||||||
// 本地SVG图标
|
// 本地SVG图标
|
||||||
import "virtual:svg-icons-register";
|
import "virtual:svg-icons-register";
|
||||||
// 暗黑主题样式
|
// 暗黑主题样式
|
||||||
|
|
@ -13,6 +12,13 @@ import "uno.css";
|
||||||
// 自动为某些默认事件(如 touchstart、wheel 等)添加 { passive: true },提升滚动性能并消除控制台的非被动事件监听警告
|
// 自动为某些默认事件(如 touchstart、wheel 等)添加 { passive: true },提升滚动性能并消除控制台的非被动事件监听警告
|
||||||
import "default-passive-events";
|
import "default-passive-events";
|
||||||
|
|
||||||
|
// vue-amp初始化
|
||||||
|
import { initAMapApiLoader } from "@vuemap/vue-amap";
|
||||||
|
import "@vuemap/vue-amap/dist/style.css";
|
||||||
|
initAMapApiLoader({
|
||||||
|
key: "6033c97e67bf2e9ceac306e1a3fa35f8",
|
||||||
|
});
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
// 注册插件
|
// 注册插件
|
||||||
app.use(setupPlugins);
|
app.use(setupPlugins);
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,16 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "list",
|
||||||
|
component: () => import("@/views/shop/list/index.vue"),
|
||||||
|
name: "shopList",
|
||||||
|
meta: {
|
||||||
|
title: "店铺列表",
|
||||||
|
affix: false,
|
||||||
|
keepAlive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "role",
|
path: "role",
|
||||||
component: () => import("@/views/shop/role.vue"),
|
component: () => import("@/views/shop/role.vue"),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { constantRoutes } from "@/router";
|
||||||
import { store } from "@/store";
|
import { store } from "@/store";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
|
||||||
import MenuAPI, { type RouteVO } from "@/api/system/menu";
|
import MenuAPI, { type RouteVO } from "@/api/account/menu";
|
||||||
const modules = import.meta.glob("../../views/**/**.vue");
|
const modules = import.meta.glob("../../views/**/**.vue");
|
||||||
const Layout = () => import("@/layout/index.vue");
|
const Layout = () => import("@/layout/index.vue");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ 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) => {
|
||||||
Object.assign(userInfo.value, { ...data });
|
Object.assign(userInfo.value, { ...data.shopInfo });
|
||||||
const { token } = data;
|
const token = data.tokenInfo.tokenValue;
|
||||||
setToken(token); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
|
setToken(token); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
|
||||||
setRefreshToken(token);
|
setRefreshToken(token);
|
||||||
resolve();
|
resolve();
|
||||||
|
|
@ -61,14 +61,16 @@ export const useUserStore = defineStore("user", () => {
|
||||||
*/
|
*/
|
||||||
function logout() {
|
function logout() {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
AuthAPI.logout()
|
|
||||||
.then(() => {
|
|
||||||
clearUserData();
|
clearUserData();
|
||||||
resolve();
|
resolve();
|
||||||
})
|
// AuthAPI.logout()
|
||||||
.catch((error) => {
|
// .then(() => {
|
||||||
reject(error);
|
// clearUserData();
|
||||||
});
|
// resolve();
|
||||||
|
// })
|
||||||
|
// .catch((error) => {
|
||||||
|
// reject(error);
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,17 +80,17 @@ export const useUserStore = defineStore("user", () => {
|
||||||
function refreshToken() {
|
function refreshToken() {
|
||||||
const refreshToken = getRefreshToken();
|
const refreshToken = getRefreshToken();
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
AuthAPI.refreshToken(refreshToken)
|
// AuthAPI.refreshToken(refreshToken)
|
||||||
.then((data) => {
|
// .then((data) => {
|
||||||
const { token } = data;
|
// const { token } = data;
|
||||||
setToken(token);
|
// setToken(token);
|
||||||
setRefreshToken(refreshToken);
|
// setRefreshToken(refreshToken);
|
||||||
resolve();
|
// resolve();
|
||||||
})
|
// })
|
||||||
.catch((error) => {
|
// .catch((error) => {
|
||||||
console.log(" refreshToken 刷新失败", error);
|
// console.log(" refreshToken 刷新失败", error);
|
||||||
reject(error);
|
// reject(error);
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ service.interceptors.response.use(
|
||||||
}
|
}
|
||||||
|
|
||||||
const { code, data, msg } = response.data;
|
const { code, data, msg } = response.data;
|
||||||
if (code === ResultEnum.SUCCESS || code === undefined || code === null || code === 200) {
|
if (code === ResultEnum.SUCCESS || code === undefined || code === null) {
|
||||||
return data ? data : response.data;
|
return data ? data : response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
<h3 class="title">银收客后台管理</h3>
|
<h3 class="title">银收客后台管理</h3>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-radio-group v-model="state.loginForm.loginType">
|
<el-radio-group v-model="state.loginForm.loginType">
|
||||||
<el-radio-button value="merchant">商户</el-radio-button>
|
<el-radio-button :value="0">商户</el-radio-button>
|
||||||
<el-radio-button value="staff">员工</el-radio-button>
|
<el-radio-button :value="1">员工</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="merchantName" v-if="state.loginForm.loginType == 'staff'">
|
<el-form-item prop="merchantName" v-if="state.loginForm.loginType == 'staff'">
|
||||||
|
|
@ -94,11 +94,11 @@ const state = reactive({
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
rememberMe: false,
|
// rememberMe: false,
|
||||||
code: "",
|
code: "",
|
||||||
uuid: "",
|
uuid: "",
|
||||||
merchantName: "",
|
merchantName: "",
|
||||||
loginType: "merchant",
|
loginType: 0,
|
||||||
},
|
},
|
||||||
loginRules: {
|
loginRules: {
|
||||||
username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
|
username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
|
||||||
|
|
@ -176,12 +176,12 @@ function handleLogin() {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
const user = { ...state.loginForm };
|
const user = { ...state.loginForm };
|
||||||
user.password = encrypt(user.password);
|
// user.password = encrypt(user.password);
|
||||||
console.log(user);
|
console.log(user);
|
||||||
userStore
|
userStore
|
||||||
.login(user)
|
.login(user)
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await userStore.getUserInfo();
|
// await userStore.getUserInfo();
|
||||||
const { path, queryParams } = parseRedirect();
|
const { path, queryParams } = parseRedirect();
|
||||||
router.push({ path: path, query: queryParams });
|
router.push({ path: path, query: queryParams });
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,523 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:title="state.form.id ? '编辑店铺' : '添加店铺'"
|
||||||
|
v-model="state.dialogVisible"
|
||||||
|
@close="reset"
|
||||||
|
>
|
||||||
|
<div style="height: 50vh; overflow-y: auto">
|
||||||
|
<el-form
|
||||||
|
ref="form"
|
||||||
|
:model="state.form"
|
||||||
|
:rules="state.rules"
|
||||||
|
label-width="120px"
|
||||||
|
label-position="left"
|
||||||
|
>
|
||||||
|
<el-form-item label="店铺名称" prop="shopName">
|
||||||
|
<el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺类型">
|
||||||
|
<el-radio-group v-model="state.form.type">
|
||||||
|
<el-radio-button value="only">单店</el-radio-button>
|
||||||
|
<el-radio-button value="chain">连锁店</el-radio-button>
|
||||||
|
<el-radio-button value="join">加盟店</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<div class="tips">请谨慎修改!!!</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="主店账号" prop="mainId" v-if="state.form.type != 'only'">
|
||||||
|
<el-select
|
||||||
|
v-model="state.form.mainId"
|
||||||
|
placeholder="请选择主店铺"
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
reserve-keyword
|
||||||
|
:remote-method="getTableData"
|
||||||
|
:loading="state.shopListLoading"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in state.shopList"
|
||||||
|
:label="`ID:${item.id} - 名称:${item.shopName}`"
|
||||||
|
:value="item.id"
|
||||||
|
:key="item.id"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="连锁店扩展店名">
|
||||||
|
<el-input v-model="state.form.chainName" placeholder="请输入连锁店扩展店名"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="门店logo" prop="logo">
|
||||||
|
<el-image
|
||||||
|
:src="state.form.logo || uploadImg"
|
||||||
|
fit="contain"
|
||||||
|
style="width: 80px; height: 80px"
|
||||||
|
@click="
|
||||||
|
state.showUpload = true;
|
||||||
|
state.uploadIndex = 1;
|
||||||
|
"
|
||||||
|
></el-image>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="门店照片">
|
||||||
|
<el-image
|
||||||
|
:src="state.form.coverImg || uploadImg"
|
||||||
|
fit="contain"
|
||||||
|
style="width: 80px; height: 80px"
|
||||||
|
@click="
|
||||||
|
state.showUpload = true;
|
||||||
|
state.uploadIndex = 2;
|
||||||
|
"
|
||||||
|
></el-image>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="经营模式">
|
||||||
|
<el-radio-group v-model="state.form.registerType">
|
||||||
|
<el-radio-button value="munchies">快餐版</el-radio-button>
|
||||||
|
<el-radio-button value="restaurant">餐饮版</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<div class="tips">请谨慎修改!!!</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="管理方式" v-if="state.form.type != 'only'">
|
||||||
|
<el-radio-group v-model="state.form.tube_type">
|
||||||
|
<el-radio-button value="0">不可直接管理</el-radio-button>
|
||||||
|
<el-radio-button value="1">直接管理</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<div class="tips">请谨慎修改!!!</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="试用/正式">
|
||||||
|
<el-radio-group v-model="state.form.profiles">
|
||||||
|
<el-radio-button value="probation">试用</el-radio-button>
|
||||||
|
<el-radio-button value="release">正式</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="激活码">
|
||||||
|
<el-input v-model="state.form.registerCode" placeholder="请输入激活码"></el-input>
|
||||||
|
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="登录账号" prop="account">
|
||||||
|
<el-input v-model="state.form.account" placeholder="请输入登录账号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="登录密码" prop="password" v-if="!state.form.id">
|
||||||
|
<el-input
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
v-model="state.form.password"
|
||||||
|
placeholder="请输入登录密码"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="联系电话">
|
||||||
|
<el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备数量">
|
||||||
|
<el-input-number
|
||||||
|
v-model="state.form.supportDeviceNumber"
|
||||||
|
controls-position="right"
|
||||||
|
:min="1"
|
||||||
|
:step="1"
|
||||||
|
step-strictly
|
||||||
|
></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="外卖起送金额">
|
||||||
|
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
||||||
|
:min="0"></el-input-number>
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="店铺经度" prop="provinces">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="9" v-if="state.form.provinces">
|
||||||
|
<el-input
|
||||||
|
:value="`${state.form.provinces}-${state.form.cities}-${state.form.districts}`"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4" v-if="state.form.lng">
|
||||||
|
<el-input v-model="state.form.lng" placeholder="经度" disabled></el-input>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4" v-if="state.form.lng">
|
||||||
|
<el-input v-model="state.form.lat" placeholder="纬度" disabled></el-input>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-place"
|
||||||
|
@click="state.showLocation = true"
|
||||||
|
>
|
||||||
|
选择坐标
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺详细地址">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="state.form.address"
|
||||||
|
placeholder="请输入门店详细地址"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺简介">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="state.form.detail"
|
||||||
|
placeholder="请输入店铺简介"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-radio-group v-model="state.form.status">
|
||||||
|
<el-radio :value="1">开启</el-radio>
|
||||||
|
<el-radio :value="0">关闭</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<el-dialog
|
||||||
|
title="选择地址"
|
||||||
|
v-model="state.showLocation"
|
||||||
|
:modal="false"
|
||||||
|
:modal-append-to-body="false"
|
||||||
|
>
|
||||||
|
<div class="map_box">
|
||||||
|
<div class="map">
|
||||||
|
<el-amap ref="map" :center="state.amapOptions.center">
|
||||||
|
<el-amap-marker :position="state.amapOptions.center"></el-amap-marker>
|
||||||
|
<el-amap-search-box
|
||||||
|
:visible="true"
|
||||||
|
@select="onSearchResult"
|
||||||
|
@choose="onSearchResult"
|
||||||
|
></el-amap-search-box>
|
||||||
|
</el-amap>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="search_box">
|
||||||
|
<el-amap-search-box
|
||||||
|
:search-option="searchOption"
|
||||||
|
:on-search-result="onSearchResult"
|
||||||
|
></el-amap-search-box>
|
||||||
|
</div> -->
|
||||||
|
<div class="search_wrap">
|
||||||
|
<div class="item" v-for="item in state.locationSearchList" :key="item.id">
|
||||||
|
<div class="left">
|
||||||
|
<div class="name">{{ item.name }}-{{ item.address }}</div>
|
||||||
|
<div class="location">经纬度:{{ item.lng }},{{ item.lat }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="btn">
|
||||||
|
<el-button type="primary" @click="selectLocationHandle(item)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
<el-dialog
|
||||||
|
v-model="state.showUpload"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
append-to-body
|
||||||
|
width="500px"
|
||||||
|
@close="state.showUpload = false"
|
||||||
|
>
|
||||||
|
<el-upload
|
||||||
|
:before-remove="handleBeforeRemove"
|
||||||
|
:on-success="handleSuccess"
|
||||||
|
:on-error="handleError"
|
||||||
|
:file-list="state.fileList"
|
||||||
|
:headers="headers"
|
||||||
|
:action="qiNiuUploadApi"
|
||||||
|
class="upload-demo"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
|
<template #tip>
|
||||||
|
<div style="display: block" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="doSubmit">确认</el-button>
|
||||||
|
<el-button @click="uploadClose">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitHandle" :loading="state.formLoading">
|
||||||
|
<span v-if="!state.formLoading">保存</span>
|
||||||
|
<span v-else>保存中...</span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { getToken } from "@/utils/auth";
|
||||||
|
import uploadImg from "@/assets/images/upload.png";
|
||||||
|
// { geocode, ShopApi.getList }
|
||||||
|
import ShopApi from "@/api/account/shop";
|
||||||
|
const validateLogo = (rule, value, callback) => {
|
||||||
|
if (!this.form.logo) {
|
||||||
|
callback(new Error("请上传门店logo"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
uploadImg: uploadImg,
|
||||||
|
dialogVisible: false,
|
||||||
|
showLocation: false,
|
||||||
|
showUpload: false,
|
||||||
|
uploadIndex: 1,
|
||||||
|
startTime: "",
|
||||||
|
endTime: "",
|
||||||
|
formLoading: false,
|
||||||
|
form: {
|
||||||
|
id: "",
|
||||||
|
shopName: "",
|
||||||
|
mainId: "",
|
||||||
|
type: "only",
|
||||||
|
tube_type: "0",
|
||||||
|
registerType: "restaurant",
|
||||||
|
profiles: "release",
|
||||||
|
registerCode: "",
|
||||||
|
account: "",
|
||||||
|
password: "",
|
||||||
|
phone: "",
|
||||||
|
supportDeviceNumber: 1,
|
||||||
|
lat: "",
|
||||||
|
lng: "",
|
||||||
|
address: "",
|
||||||
|
detail: "",
|
||||||
|
status: 1,
|
||||||
|
logo: "",
|
||||||
|
coverImg: "",
|
||||||
|
provinces: "",
|
||||||
|
cities: "",
|
||||||
|
districts: "",
|
||||||
|
chainName: "",
|
||||||
|
},
|
||||||
|
resetForm: "",
|
||||||
|
rules: {
|
||||||
|
shopName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: " ",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
mainId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: " ",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
provinces: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请选择坐标",
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
logo: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: validateLogo,
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
account: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: " ",
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: " ",
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
fileList: [],
|
||||||
|
files: [],
|
||||||
|
headers: {
|
||||||
|
Authorization: getToken(),
|
||||||
|
},
|
||||||
|
searchOption: {
|
||||||
|
city: "西安",
|
||||||
|
citylimit: false,
|
||||||
|
},
|
||||||
|
locationSearchList: [],
|
||||||
|
amapOptions: {
|
||||||
|
center: [108.946465, 34.347984],
|
||||||
|
position: [],
|
||||||
|
},
|
||||||
|
shopListLoading: false,
|
||||||
|
shopList: [],
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
state.resetForm = { ...state.form };
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取商家列表
|
||||||
|
async function getTableData(query = "") {
|
||||||
|
state.shopListLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await ShopApi.getList({
|
||||||
|
page: 1,
|
||||||
|
size: 100,
|
||||||
|
shopName: query,
|
||||||
|
type: "only",
|
||||||
|
});
|
||||||
|
state.shopListLoading = false;
|
||||||
|
state.shopList = res.content;
|
||||||
|
} catch (error) {
|
||||||
|
state.shopListLoading = false;
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function onSearchResult(res) {
|
||||||
|
console.log("res");
|
||||||
|
console.log(res);
|
||||||
|
state.locationSearchList = res;
|
||||||
|
state.amapOptions.center = [res[0].lng, res[0].lat];
|
||||||
|
}
|
||||||
|
// 确认地址选择
|
||||||
|
async function selectLocationHandle(item) {
|
||||||
|
console.log(item);
|
||||||
|
state.form.lng = item.lng;
|
||||||
|
state.form.lat = item.lat;
|
||||||
|
state.form.address = item.address;
|
||||||
|
state.showLocation = false;
|
||||||
|
|
||||||
|
const position = `${item.lng},${item.lat}`;
|
||||||
|
const res = JSON.parse(await geocode({ location: position }));
|
||||||
|
console.log(res);
|
||||||
|
|
||||||
|
state.form.provinces = res.addressComponent.province;
|
||||||
|
state.form.cities = res.addressComponent.city;
|
||||||
|
state.form.districts = res.addressComponent.district;
|
||||||
|
}
|
||||||
|
const emits = defineEmits(["close", "success"]);
|
||||||
|
// 保存
|
||||||
|
function submitHandle() {
|
||||||
|
state.$refs.form.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
state.formLoading = true;
|
||||||
|
try {
|
||||||
|
await ShopApi.getListPost(state.form, state.form.id ? "put" : "post");
|
||||||
|
emits("success");
|
||||||
|
state.formLoading = false;
|
||||||
|
$notify({
|
||||||
|
title: "成功",
|
||||||
|
message: `${this.form.id ? "编辑" : "添加"}成功`,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
close();
|
||||||
|
} catch (error) {
|
||||||
|
state.formLoading = false;
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function handleSuccess(response, file, fileList) {
|
||||||
|
// const uid = file.uid
|
||||||
|
// const id = response.id
|
||||||
|
// this.files.push({ uid, id })
|
||||||
|
console.log("上传成功", response);
|
||||||
|
state.files = response.data;
|
||||||
|
}
|
||||||
|
function handleBeforeRemove(file, fileList) {
|
||||||
|
for (let i = 0; i < state.files.length; i++) {
|
||||||
|
if (this.files[i].uid === file.uid) {
|
||||||
|
crudQiNiu.del([state.files[i].id]).then((res) => {});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handlePictureCardPreview(file) {
|
||||||
|
state.dialogImageUrl = file.url;
|
||||||
|
state.dialogVisible = true;
|
||||||
|
}
|
||||||
|
// 监听上传失败
|
||||||
|
function handleError(e, file, fileList) {
|
||||||
|
const msg = JSON.parse(e.message);
|
||||||
|
state.crud.notify(msg.message, CRUD.NOTIFICATION_TYPE.ERROR);
|
||||||
|
}
|
||||||
|
// 刷新列表数据
|
||||||
|
function doSubmit() {
|
||||||
|
state.fileList = [];
|
||||||
|
state.showUpload = false;
|
||||||
|
switch (state.uploadIndex) {
|
||||||
|
case 1:
|
||||||
|
state.form.logo = state.files[0];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
state.form.coverImg = state.files[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function show(obj) {
|
||||||
|
getTableData();
|
||||||
|
state.dialogVisible = true;
|
||||||
|
if (obj && obj.id) {
|
||||||
|
console.log(obj);
|
||||||
|
state.form = { ...obj };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
state.dialogVisible = false;
|
||||||
|
}
|
||||||
|
function uploadClose() {
|
||||||
|
state.showUpload = false;
|
||||||
|
}
|
||||||
|
function reset() {
|
||||||
|
state.form = { ...this.resetForm };
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
close,
|
||||||
|
reset,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.map_box {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.map {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_box {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_wrap {
|
||||||
|
padding: 6px 0;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
padding: 12px 0;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-right: 20px;
|
||||||
|
|
||||||
|
.location {
|
||||||
|
color: #999;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.amap-sug-result {
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" :show-close="false" @close="reset">
|
||||||
|
<el-tabs v-model="activeName">
|
||||||
|
<el-tab-pane label="聚合支付" name="pay">
|
||||||
|
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
||||||
|
<el-form-item label="商户号">
|
||||||
|
<el-input v-model="form.appId" placeholder="请输入商户号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商户密钥">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="form.appToken"
|
||||||
|
placeholder="请输入商户密钥"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="支付密码">
|
||||||
|
<el-input v-model="form.payPassword" placeholder="请输入支付密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="微信appid">
|
||||||
|
<el-input v-model="form.smallAppid" placeholder="请输入微信小程序appid"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="支付宝appid">
|
||||||
|
<el-input
|
||||||
|
v-model="form.alipaySmallAppid"
|
||||||
|
placeholder="请输入支付宝小程序appid"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="支付宝商户号">
|
||||||
|
<el-input v-model="form.alipayAppId" placeholder="请输入支付宝商户号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="支付宝商户密钥">
|
||||||
|
<el-input v-model="form.alipayAppToken" placeholder="请输入支付宝商户密钥"></el-input>
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="店铺id">
|
||||||
|
<el-input v-model="form.storeId" placeholder="请输入店铺id"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-radio-group v-model="form.status">
|
||||||
|
<el-radio :label="1">启用</el-radio>
|
||||||
|
<el-radio :label="-1">禁用</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||||
|
<span v-if="!formLoading">保存</span>
|
||||||
|
<span v-else>保存中...</span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import { tbMerchantThirdApply, tbMerchantThirdApplyPut } from "@/api/shop";
|
||||||
|
import ShopApi from "@/api/account/shop";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
activeName: "pay",
|
||||||
|
formLoading: false,
|
||||||
|
form: {
|
||||||
|
appToken: "",
|
||||||
|
id: "",
|
||||||
|
payPassword: "",
|
||||||
|
status: 1,
|
||||||
|
appId: "",
|
||||||
|
smallAppid: "",
|
||||||
|
storeId: "",
|
||||||
|
alipaySmallAppid: "",
|
||||||
|
alipayAppToken: "",
|
||||||
|
alipayAppId: "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 保存
|
||||||
|
async submitHandle() {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
await tbMerchantThirdApplyPut(this.form);
|
||||||
|
this.$emit("success");
|
||||||
|
this.formLoading = false;
|
||||||
|
this.$notify({
|
||||||
|
title: "成功",
|
||||||
|
message: `提交成功`,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
this.close();
|
||||||
|
} catch (error) {
|
||||||
|
this.formLoading = false;
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.dialogVisible = false;
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
this.form.appToken = "";
|
||||||
|
this.form.id = "";
|
||||||
|
this.form.payPassword = "";
|
||||||
|
this.form.status = 1;
|
||||||
|
this.form.appId = "";
|
||||||
|
},
|
||||||
|
// 详情(配置三方支付)
|
||||||
|
async getDetail(id) {
|
||||||
|
try {
|
||||||
|
const res = await tbMerchantThirdApply(id);
|
||||||
|
this.form.appToken = res.appToken;
|
||||||
|
this.form.payPassword = res.payPassword;
|
||||||
|
this.form.status = res.status;
|
||||||
|
this.form.appId = res.appId;
|
||||||
|
this.form.smallAppid = res.smallAppid;
|
||||||
|
this.form.alipaySmallAppid = res.alipaySmallAppid;
|
||||||
|
//this.form.alipayAppToken = res.alipayAppToken
|
||||||
|
//this.form.alipayAppId = res.alipayAppId
|
||||||
|
this.form.storeId = res.storeId;
|
||||||
|
this.dialogVisible = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show(obj) {
|
||||||
|
if (obj && obj.id) {
|
||||||
|
this.form.id = obj.merchantId;
|
||||||
|
this.getDetail(obj.merchantId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
::v-deep(.el-dialog__header) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,232 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<div class="head-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-input
|
||||||
|
v-model="query.name"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入店铺名称"
|
||||||
|
style="width: 100%"
|
||||||
|
class="filter-item"
|
||||||
|
@keyup.enter="getTableData"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-input
|
||||||
|
v-model="query.account"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入商户号"
|
||||||
|
style="width: 100%"
|
||||||
|
class="filter-item"
|
||||||
|
@keyup.enter="getTableData"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-select v-model="query.status" placeholder="请选择店铺状态" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.type"
|
||||||
|
v-for="item in status"
|
||||||
|
:key="item.type"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||||
|
<el-button @click="resetHandle">重置</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<div class="head-container">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" @click="$refs.addShop.show()">
|
||||||
|
添加店铺
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="head-container">
|
||||||
|
<el-table :data="tableData.list" v-loading="tableData.loading">
|
||||||
|
<el-table-column label="店铺信息" width="200">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<div class="shop_info">
|
||||||
|
<el-image
|
||||||
|
:src="scope.row.logo"
|
||||||
|
style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef"
|
||||||
|
>
|
||||||
|
<div class="img_error" slot="error">
|
||||||
|
<i class="icon el-icon-document-delete"></i>
|
||||||
|
</div>
|
||||||
|
</el-image>
|
||||||
|
<div class="info">
|
||||||
|
<span>{{ scope.row.shopName }}</span>
|
||||||
|
<div class="tag_wrap">
|
||||||
|
<el-tag type="info" effect="dark" v-if="scope.row.profiles == 'no'">
|
||||||
|
未激活
|
||||||
|
</el-tag>
|
||||||
|
<el-tag type="warning" effect="dark" v-if="scope.row.profiles == 'probation'">
|
||||||
|
试用
|
||||||
|
</el-tag>
|
||||||
|
<el-tag type="success" effect="dark" v-if="scope.row.profiles == 'release'">
|
||||||
|
正式
|
||||||
|
</el-tag>
|
||||||
|
<el-tag type="primary" effect="dark" v-if="scope.row.isWxMaIndependent">
|
||||||
|
独立小程序
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="registerType" label="类型">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span v-if="scope.row.registerType == 'munchies'">快餐版</span>
|
||||||
|
<span v-if="scope.row.registerType == 'restaurant'">餐饮版</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="address" label="商户号"></el-table-column>
|
||||||
|
<el-table-column prop="lowPrice" label="来源"></el-table-column>
|
||||||
|
<el-table-column prop="lowPrice" label="认证状态">-</el-table-column>
|
||||||
|
<el-table-column prop="status" label="店铺状态">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.status"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
disabled
|
||||||
|
></el-switch>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createdAt" label="到期时间">
|
||||||
|
<template v-slot="scope">
|
||||||
|
{{ dayjs(scope.row.expireAt).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="150">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-link icon="edit" @click="$refs.addShop.show(scope.row)">编辑</el-link>
|
||||||
|
<el-dropdown @command="dropdownClick">
|
||||||
|
<el-link icon="arrow-down">更多</el-link>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-item :command="{ row: scope.row, command: 1 }">
|
||||||
|
三方配置
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="2">续费记录</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="3">前往店铺</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="4">重置密码</el-dropdown-item>
|
||||||
|
<el-dropdown-item divided :command="5">删除</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="head-container">
|
||||||
|
<el-pagination
|
||||||
|
:total="tableData.total"
|
||||||
|
v-model:current-page="tableData.page"
|
||||||
|
:page-size="tableData.size"
|
||||||
|
@current-change="paginationChange"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
></el-pagination>
|
||||||
|
</div>
|
||||||
|
<addShop ref="addShop" @success="getTableData" />
|
||||||
|
<detailModal ref="detailModal" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import ShopApi from "@/api/account/shop";
|
||||||
|
|
||||||
|
import addShop from "./components/addShop.vue";
|
||||||
|
import detailModal from "./components/detailModal.vue";
|
||||||
|
export default {
|
||||||
|
components: { addShop, detailModal },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dayjs,
|
||||||
|
query: {
|
||||||
|
name: "",
|
||||||
|
account: "",
|
||||||
|
status: "",
|
||||||
|
},
|
||||||
|
status: [
|
||||||
|
{
|
||||||
|
type: 1,
|
||||||
|
label: "开启",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 0,
|
||||||
|
label: "关闭",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tableData: {
|
||||||
|
list: [],
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
loading: false,
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
dropdownClick(e) {
|
||||||
|
switch (e.command) {
|
||||||
|
case 1:
|
||||||
|
this.$refs.detailModal.show(e.row);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 重置查询
|
||||||
|
resetHandle() {
|
||||||
|
this.query.name = "";
|
||||||
|
this.query.account = "";
|
||||||
|
this.query.status = "";
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
// 分页回调
|
||||||
|
paginationChange(e) {
|
||||||
|
this.tableData.page = e;
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
// 获取商家列表
|
||||||
|
async getTableData() {
|
||||||
|
this.tableData.loading = true;
|
||||||
|
try {
|
||||||
|
const res = await ShopApi.getList({
|
||||||
|
page: this.tableData.page,
|
||||||
|
size: this.tableData.size,
|
||||||
|
shopName: this.query.name,
|
||||||
|
account: this.query.account,
|
||||||
|
status: this.query.status,
|
||||||
|
});
|
||||||
|
this.tableData.loading = false;
|
||||||
|
this.tableData.list = res.records;
|
||||||
|
this.tableData.total = res.totalRow;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.head-container {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.shop_info {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
|
||||||
// 类型声明相关配置
|
// 类型声明相关配置
|
||||||
"types": ["node", "vite/client", "element-plus/global"]
|
"types": ["node", "vite/client", "element-plus/global", "vuemap"]
|
||||||
},
|
},
|
||||||
|
|
||||||
"include": ["mock/**/*.ts", "src/**/*.ts", "src/**/*.vue", "vite.config.ts"],
|
"include": ["mock/**/*.ts", "src/**/*.ts", "src/**/*.vue", "vite.config.ts"],
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { type UserConfig, type ConfigEnv, loadEnv, defineConfig } from "vite";
|
||||||
|
|
||||||
import AutoImport from "unplugin-auto-import/vite";
|
import AutoImport from "unplugin-auto-import/vite";
|
||||||
import Components from "unplugin-vue-components/vite";
|
import Components from "unplugin-vue-components/vite";
|
||||||
|
import { VueAmapResolver } from "@vuemap/unplugin-resolver";
|
||||||
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||||
|
|
||||||
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
|
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
|
||||||
|
|
@ -65,7 +66,10 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
||||||
imports: ["vue", "@vueuse/core", "pinia", "vue-router", "vue-i18n"],
|
imports: ["vue", "@vueuse/core", "pinia", "vue-router", "vue-i18n"],
|
||||||
resolvers: [
|
resolvers: [
|
||||||
// 导入 Element Plus函数,如:ElMessage, ElMessageBox 等
|
// 导入 Element Plus函数,如:ElMessage, ElMessageBox 等
|
||||||
ElementPlusResolver(),
|
ElementPlusResolver({
|
||||||
|
exclude: /^ElAmap[A-Z]*/,
|
||||||
|
}),
|
||||||
|
VueAmapResolver(),
|
||||||
],
|
],
|
||||||
eslintrc: {
|
eslintrc: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
@ -80,7 +84,10 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
||||||
Components({
|
Components({
|
||||||
resolvers: [
|
resolvers: [
|
||||||
// 导入 Element Plus 组件
|
// 导入 Element Plus 组件
|
||||||
ElementPlusResolver(),
|
ElementPlusResolver({
|
||||||
|
exclude: /^ElAmap[A-Z]*/,
|
||||||
|
}),
|
||||||
|
VueAmapResolver(),
|
||||||
],
|
],
|
||||||
// 指定自定义组件位置(默认:src/components)
|
// 指定自定义组件位置(默认:src/components)
|
||||||
dirs: ["src/components", "src/**/components"],
|
dirs: ["src/components", "src/**/components"],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue