feat(用户绑定): 添加企业微信用户与汇邦云账号绑定功能
- 在ab98接口模块新增BindQyUserCommand类型和bindQyUserApi方法 - 扩展QyLoginDTO接口添加qyUserId和ab98User字段 - 新增ab98UserDTO类型定义用户详细信息 - 在wxStore中添加qyUserId和ab98User状态及相关操作方法 - 在ProductList页面添加绑定弹窗逻辑,当检测到未绑定用户时自动弹出绑定表单
This commit is contained in:
parent
8cfa252d9a
commit
bd0cce7aab
|
@ -1,5 +1,6 @@
|
||||||
import { request } from '@/http/axios'
|
import { request } from '@/http/axios'
|
||||||
import {
|
import {
|
||||||
|
BindQyUserCommand,
|
||||||
GetTokenParams,
|
GetTokenParams,
|
||||||
LoginData,
|
LoginData,
|
||||||
LogoutResponse,
|
LogoutResponse,
|
||||||
|
@ -8,6 +9,7 @@ import {
|
||||||
VerifySmsParams,
|
VerifySmsParams,
|
||||||
WechatQrCodeParams
|
WechatQrCodeParams
|
||||||
} from './type'
|
} from './type'
|
||||||
|
import { ab98UserDTO } from '../shop/type'
|
||||||
|
|
||||||
/** 获取临时令牌 */
|
/** 获取临时令牌 */
|
||||||
export function getTokenApi(appName: string) {
|
export function getTokenApi(appName: string) {
|
||||||
|
@ -61,4 +63,12 @@ export function tokenLogin(token: string, userid: string, openid: string) {
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { token, userid, openid }
|
params: { token, userid, openid }
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bindQyUserApi(data: BindQyUserCommand) {
|
||||||
|
return request<ApiResponseData<ab98UserDTO>>({
|
||||||
|
url: '/wx/login/bindQyUser',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
}
|
}
|
|
@ -58,4 +58,10 @@ export type VerifySmsParams = {
|
||||||
vcode: string
|
vcode: string
|
||||||
userid: string
|
userid: string
|
||||||
openid: string
|
openid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BindQyUserCommand {
|
||||||
|
qyUserId: number;
|
||||||
|
name: string;
|
||||||
|
idNum: string;
|
||||||
}
|
}
|
|
@ -110,10 +110,39 @@ export interface GetBalanceResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QyLoginDTO {
|
export interface QyLoginDTO {
|
||||||
userid: string
|
userid: string;
|
||||||
openid: string
|
openid: string;
|
||||||
isCabinetAdmin: number
|
isCabinetAdmin: number;
|
||||||
name: string
|
qyUserId: number;
|
||||||
|
name: string;
|
||||||
|
ab98User: ab98UserDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ab98UserDTO {
|
||||||
|
/** 主键ID */
|
||||||
|
ab98UserId?: number;
|
||||||
|
/** openid */
|
||||||
|
openid?: string;
|
||||||
|
/** 汇邦云用户唯一ID */
|
||||||
|
userid?: string;
|
||||||
|
/** 真实姓名 */
|
||||||
|
name?: string;
|
||||||
|
/** 手机号码 */
|
||||||
|
tel?: string;
|
||||||
|
/** 身份证号码 */
|
||||||
|
idnum?: string;
|
||||||
|
/** 性别(男 女) */
|
||||||
|
sex?: string;
|
||||||
|
/** 人脸照片地址 */
|
||||||
|
faceImg?: string;
|
||||||
|
/** 身份证正面地址 */
|
||||||
|
idcardFront?: string;
|
||||||
|
/** 身份证背面地址 */
|
||||||
|
idcardBack?: string;
|
||||||
|
/** 身份证登记地址 */
|
||||||
|
address?: string;
|
||||||
|
/** 是否已注册(0未注册 1已注册) */
|
||||||
|
registered?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenCabinetApiData {
|
export interface OpenCabinetApiData {
|
||||||
|
|
|
@ -9,15 +9,19 @@ import { computed, onBeforeUnmount, onMounted, ref } from "vue"
|
||||||
import Cart from "./components/cart.vue"
|
import Cart from "./components/cart.vue"
|
||||||
import Detail from "./components/detail.vue"
|
import Detail from "./components/detail.vue"
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useWxStore } from "@/pinia/stores/wx"
|
||||||
|
import { bindQyUserApi } from "@/common/apis/ab98"
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
// 状态管理
|
// 状态管理
|
||||||
const productStore = useProductStore()
|
const productStore = useProductStore();
|
||||||
const cartStore = useCartStore()
|
const cartStore = useCartStore();
|
||||||
const { cartItems, totalPrice, totalQuantity } = storeToRefs(cartStore) // 新增购物车状态
|
const wxStore = useWxStore();
|
||||||
|
const { cartItems, totalPrice, totalQuantity } = storeToRefs(cartStore); // 新增购物车状态
|
||||||
// 从 store 解构分类标签和商品数据
|
// 从 store 解构分类标签和商品数据
|
||||||
const { labels, categories } = storeToRefs(productStore)
|
const { labels, categories } = storeToRefs(productStore);
|
||||||
|
const { openid, corpidLogin, ab98User, qyUserId } = storeToRefs(wxStore);
|
||||||
|
|
||||||
// 当前选中的分类索引
|
// 当前选中的分类索引
|
||||||
const activeCategory = ref(0)
|
const activeCategory = ref(0)
|
||||||
|
@ -40,7 +44,11 @@ const currentProduct = computed(() =>
|
||||||
// 购物车弹窗控制
|
// 购物车弹窗控制
|
||||||
const showCartPopup = ref(false)
|
const showCartPopup = ref(false)
|
||||||
|
|
||||||
const searchQuery = ref('')
|
const searchQuery = ref('');
|
||||||
|
|
||||||
|
const name = ref('');
|
||||||
|
const idNum = ref('');
|
||||||
|
const showAb98BindPopup = ref(false);
|
||||||
|
|
||||||
// 点击分类导航
|
// 点击分类导航
|
||||||
function handleCategoryClick(index: number) {
|
function handleCategoryClick(index: number) {
|
||||||
|
@ -131,7 +139,38 @@ watch(() => route.path, (newPath) => {
|
||||||
if (newPath === '/') {
|
if (newPath === '/') {
|
||||||
productStore.getGoods()
|
productStore.getGoods()
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
let showAb98BindPopupOnce = false;
|
||||||
|
watch(openid, async () => {
|
||||||
|
if (openid.value && corpidLogin.value && !ab98User.value
|
||||||
|
&& !showAb98BindPopup.value && !showAb98BindPopupOnce) {
|
||||||
|
// 显示绑定弹窗
|
||||||
|
showAb98BindPopup.value = true;
|
||||||
|
showAb98BindPopupOnce = true;
|
||||||
|
}
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
async function handleAb98Bind() {
|
||||||
|
try {
|
||||||
|
const ab98UserData = await bindQyUserApi({
|
||||||
|
qyUserId: qyUserId.value,
|
||||||
|
name: name.value,
|
||||||
|
idNum: idNum.value
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ab98UserData?.code === 0) {
|
||||||
|
wxStore.setAb98User(ab98UserData.data);
|
||||||
|
showAb98BindPopup.value = false;
|
||||||
|
name.value = '';
|
||||||
|
idNum.value = '';
|
||||||
|
} else {
|
||||||
|
console.error('绑定失败:', ab98UserData?.msg);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('绑定失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -217,6 +256,29 @@ watch(() => route.path, (newPath) => {
|
||||||
<VanPopup v-model:show="showCartPopup" position="bottom" :style="{ height: '80%' }" round>
|
<VanPopup v-model:show="showCartPopup" position="bottom" :style="{ height: '80%' }" round>
|
||||||
<Cart class="detail-container" @cart-close="showCartPopup = false" />
|
<Cart class="detail-container" @cart-close="showCartPopup = false" />
|
||||||
</VanPopup>
|
</VanPopup>
|
||||||
|
<VanPopup v-model:show="showAb98BindPopup" position="center" round>
|
||||||
|
<van-form @submit="handleAb98Bind">
|
||||||
|
<van-cell-group inset>
|
||||||
|
<van-field
|
||||||
|
v-model="name"
|
||||||
|
label="姓名"
|
||||||
|
placeholder="请输入真实姓名"
|
||||||
|
:rules="[{ required: true, message: '请填写姓名' }]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="idNum"
|
||||||
|
label="身份证号"
|
||||||
|
placeholder="请输入身份证号码"
|
||||||
|
:rules="[{ required: true, message: '请填写身份证号' }]"
|
||||||
|
/>
|
||||||
|
</van-cell-group>
|
||||||
|
<div style="margin: 16px;">
|
||||||
|
<van-button block type="primary" native-type="submit">
|
||||||
|
立即绑定
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</van-form>
|
||||||
|
</VanPopup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { pinia } from "@/pinia"
|
import { pinia } from "@/pinia"
|
||||||
import { getOpenIdApi, getBalanceApi, qyLogin, getBalanceByQyUserid } from "@/common/apis/shop"
|
import { getOpenIdApi, getBalanceApi, qyLogin, getBalanceByQyUserid } from "@/common/apis/shop"
|
||||||
import { GetBalanceResponse } from "@/common/apis/shop/type"
|
import { ab98UserDTO, GetBalanceResponse } from "@/common/apis/shop/type"
|
||||||
|
import { useAb98UserStore } from "./ab98-user"
|
||||||
|
|
||||||
|
|
||||||
export const useWxStore = defineStore("wx", () => {
|
export const useWxStore = defineStore("wx", () => {
|
||||||
|
@ -26,6 +27,10 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
const isCabinetAdmin = ref<boolean>(false);
|
const isCabinetAdmin = ref<boolean>(false);
|
||||||
// 企业微信用户姓名
|
// 企业微信用户姓名
|
||||||
const name = ref<string>("");
|
const name = ref<string>("");
|
||||||
|
// 企业微信用户id
|
||||||
|
const qyUserId = ref<number>(0);
|
||||||
|
// 汇邦云用户信息
|
||||||
|
const ab98User = ref<ab98UserDTO | null>(null);
|
||||||
|
|
||||||
// 设置 openid
|
// 设置 openid
|
||||||
const setOpenid = (id: string) => {
|
const setOpenid = (id: string) => {
|
||||||
|
@ -39,6 +44,20 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
const setIsCabinetAdmin = (isAdmin: boolean) => {
|
const setIsCabinetAdmin = (isAdmin: boolean) => {
|
||||||
isCabinetAdmin.value = isAdmin;
|
isCabinetAdmin.value = isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setAb98User = (user: ab98UserDTO) => {
|
||||||
|
ab98User.value = user;
|
||||||
|
const ab98UserStore = useAb98UserStore();
|
||||||
|
ab98UserStore.setUserInfo({
|
||||||
|
face_img: ab98User.value.faceImg || "",
|
||||||
|
success: true,
|
||||||
|
sex: ab98User.value.sex || "",
|
||||||
|
name: ab98User.value.name || "",
|
||||||
|
userid: ab98User.value.userid || "",
|
||||||
|
registered: true,
|
||||||
|
tel: ab98User.value.tel || "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const refreshBalance = async () => {
|
const refreshBalance = async () => {
|
||||||
if (corpid.value && userid.value) {
|
if (corpid.value && userid.value) {
|
||||||
|
@ -76,6 +95,8 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
openid.value = res.data.openid;
|
openid.value = res.data.openid;
|
||||||
isCabinetAdmin.value = res.data.isCabinetAdmin === 1;
|
isCabinetAdmin.value = res.data.isCabinetAdmin === 1;
|
||||||
name.value = res.data.name;
|
name.value = res.data.name;
|
||||||
|
qyUserId.value = res.data.qyUserId;
|
||||||
|
setAb98User(res.data.ab98User);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +129,9 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { code, state, openid, corpid, userid, balance, useBalance, balanceLimit, isCabinetAdmin, corpidLogin, name,
|
return { code, state, openid, corpid, userid, balance, useBalance,
|
||||||
setOpenid, setBalance, handleWxCallback, setIsCabinetAdmin, refreshBalance }
|
balanceLimit, isCabinetAdmin, corpidLogin, name, ab98User, qyUserId,
|
||||||
|
setOpenid, setBalance, handleWxCallback, setIsCabinetAdmin, refreshBalance, setAb98User }
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue