feat(用户绑定): 添加企业微信用户与汇邦云账号绑定功能

- 在ab98接口模块新增BindQyUserCommand类型和bindQyUserApi方法
- 扩展QyLoginDTO接口添加qyUserId和ab98User字段
- 新增ab98UserDTO类型定义用户详细信息
- 在wxStore中添加qyUserId和ab98User状态及相关操作方法
- 在ProductList页面添加绑定弹窗逻辑,当检测到未绑定用户时自动弹出绑定表单
This commit is contained in:
dzq 2025-06-04 09:19:05 +08:00
parent 8cfa252d9a
commit bd0cce7aab
5 changed files with 142 additions and 13 deletions

View File

@ -1,5 +1,6 @@
import { request } from '@/http/axios'
import {
BindQyUserCommand,
GetTokenParams,
LoginData,
LogoutResponse,
@ -8,6 +9,7 @@ import {
VerifySmsParams,
WechatQrCodeParams
} from './type'
import { ab98UserDTO } from '../shop/type'
/** 获取临时令牌 */
export function getTokenApi(appName: string) {
@ -62,3 +64,11 @@ export function tokenLogin(token: string, userid: string, openid: string) {
params: { token, userid, openid }
})
}
export function bindQyUserApi(data: BindQyUserCommand) {
return request<ApiResponseData<ab98UserDTO>>({
url: '/wx/login/bindQyUser',
method: 'post',
data
})
}

View File

@ -59,3 +59,9 @@ export type VerifySmsParams = {
userid: string
openid: string
}
export interface BindQyUserCommand {
qyUserId: number;
name: string;
idNum: string;
}

View File

@ -110,10 +110,39 @@ export interface GetBalanceResponse {
}
export interface QyLoginDTO {
userid: string
openid: string
isCabinetAdmin: number
name: string
userid: string;
openid: string;
isCabinetAdmin: number;
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 {

View File

@ -9,15 +9,19 @@ import { computed, onBeforeUnmount, onMounted, ref } from "vue"
import Cart from "./components/cart.vue"
import Detail from "./components/detail.vue"
import { useRoute } from 'vue-router'
import { useWxStore } from "@/pinia/stores/wx"
import { bindQyUserApi } from "@/common/apis/ab98"
const router = useRouter()
const route = useRoute()
//
const productStore = useProductStore()
const cartStore = useCartStore()
const { cartItems, totalPrice, totalQuantity } = storeToRefs(cartStore) //
const productStore = useProductStore();
const cartStore = useCartStore();
const wxStore = useWxStore();
const { cartItems, totalPrice, totalQuantity } = storeToRefs(cartStore); //
// store
const { labels, categories } = storeToRefs(productStore)
const { labels, categories } = storeToRefs(productStore);
const { openid, corpidLogin, ab98User, qyUserId } = storeToRefs(wxStore);
//
const activeCategory = ref(0)
@ -40,7 +44,11 @@ const currentProduct = computed(() =>
//
const showCartPopup = ref(false)
const searchQuery = ref('')
const searchQuery = ref('');
const name = ref('');
const idNum = ref('');
const showAb98BindPopup = ref(false);
//
function handleCategoryClick(index: number) {
@ -131,7 +139,38 @@ watch(() => route.path, (newPath) => {
if (newPath === '/') {
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>
<template>
@ -217,6 +256,29 @@ watch(() => route.path, (newPath) => {
<VanPopup v-model:show="showCartPopup" position="bottom" :style="{ height: '80%' }" round>
<Cart class="detail-container" @cart-close="showCartPopup = false" />
</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>
<style scoped>

View File

@ -1,6 +1,7 @@
import { pinia } from "@/pinia"
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", () => {
@ -26,6 +27,10 @@ export const useWxStore = defineStore("wx", () => {
const isCabinetAdmin = ref<boolean>(false);
// 企业微信用户姓名
const name = ref<string>("");
// 企业微信用户id
const qyUserId = ref<number>(0);
// 汇邦云用户信息
const ab98User = ref<ab98UserDTO | null>(null);
// 设置 openid
const setOpenid = (id: string) => {
@ -40,6 +45,20 @@ export const useWxStore = defineStore("wx", () => {
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 () => {
if (corpid.value && userid.value) {
const res = await getBalanceByQyUserid(corpid.value, userid.value);
@ -76,6 +95,8 @@ export const useWxStore = defineStore("wx", () => {
openid.value = res.data.openid;
isCabinetAdmin.value = res.data.isCabinetAdmin === 1;
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,
setOpenid, setBalance, handleWxCallback, setIsCabinetAdmin, refreshBalance }
return { code, state, openid, corpid, userid, balance, useBalance,
balanceLimit, isCabinetAdmin, corpidLogin, name, ab98User, qyUserId,
setOpenid, setBalance, handleWxCallback, setIsCabinetAdmin, refreshBalance, setAb98User }
})
/**