新增企业微信登录
This commit is contained in:
parent
7835ed46af
commit
9e15542d82
|
@ -29,8 +29,9 @@ onMounted(() => {
|
||||||
console.log('urlParams', urlParams);
|
console.log('urlParams', urlParams);
|
||||||
const code = urlParams.get('code') || undefined;
|
const code = urlParams.get('code') || undefined;
|
||||||
const state = urlParams.get('state') || undefined;
|
const state = urlParams.get('state') || undefined;
|
||||||
|
const corpid = urlParams.get('corpid') || undefined;
|
||||||
if (code || state) {
|
if (code || state) {
|
||||||
wxStore.handleWxCallback({ code, state })
|
wxStore.handleWxCallback({ corpid, code, state })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { request } from "@/http/axios"
|
import { request } from "@/http/axios"
|
||||||
import { GetOrdersByOpenIdDTO, ShopGoodsResponseData, SubmitOrderRequestData, SubmitOrderResponseData } from './type'
|
import { GetBalanceResponse, GetOrdersByOpenIdDTO, QyLoginDTO, QyLoginRequestParams, ShopGoodsResponseData, SubmitOrderRequestData, SubmitOrderResponseData } from './type'
|
||||||
import { GetOpenIdRequestParams } from './type'
|
import { GetOpenIdRequestParams } from './type'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** 获取当前登录用户详情 */
|
/** 获取当前登录用户详情 */
|
||||||
export function getShopGoodsApi() {
|
export function getShopGoodsApi() {
|
||||||
return request<ShopGoodsResponseData>({
|
return request<ShopGoodsResponseData>({
|
||||||
|
@ -28,6 +29,14 @@ export function getOpenIdApi(params: GetOpenIdRequestParams) {
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
/** 企业微信登录 */
|
||||||
|
export function qyLogin(params: QyLoginRequestParams) {
|
||||||
|
return request<ApiResponseData<QyLoginDTO>>({
|
||||||
|
url: "common/login/qy",
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/** 根据openid获取用户订单信息 */
|
/** 根据openid获取用户订单信息 */
|
||||||
export function getOrdersByOpenIdApi(openid: string) {
|
export function getOrdersByOpenIdApi(openid: string) {
|
||||||
|
@ -43,4 +52,20 @@ export function openCabinetApi(orderId: number, orderGoodsId: number) {
|
||||||
url: `order/openCabinet/${orderId}/${orderGoodsId}`,
|
url: `order/openCabinet/${orderId}/${orderGoodsId}`,
|
||||||
method: "post"
|
method: "post"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获取用户余额接口 */
|
||||||
|
export function getBalanceApi(openid: string) {
|
||||||
|
return request<ApiResponseData<GetBalanceResponse>>({
|
||||||
|
url: "payment/getBalance",
|
||||||
|
method: "get",
|
||||||
|
params: { openid }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getBalanceByQyUserid(corpid: string, userid: string) {
|
||||||
|
return request<ApiResponseData<GetBalanceResponse>>({
|
||||||
|
url: "payment/getBalanceByQyUserid",
|
||||||
|
method: "get",
|
||||||
|
params: { corpid, userid }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,10 @@ export type category = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubmitOrderRequestData {
|
export interface SubmitOrderRequestData {
|
||||||
openid: string
|
openid: string;
|
||||||
|
userid: string;
|
||||||
|
corpid: string;
|
||||||
|
paymentType: 'wechat' | 'balance';
|
||||||
goodsList: Array<{
|
goodsList: Array<{
|
||||||
goodsId: number
|
goodsId: number
|
||||||
quantity: number
|
quantity: number
|
||||||
|
@ -26,6 +29,7 @@ export interface SubmitOrderRequestData {
|
||||||
export type SubmitOrderResponseData = ApiResponseMsgData<{
|
export type SubmitOrderResponseData = ApiResponseMsgData<{
|
||||||
orderId: number
|
orderId: number
|
||||||
totalAmount: number
|
totalAmount: number
|
||||||
|
newBalance: number
|
||||||
paymentInfo: WxJsApiPreCreateResponse
|
paymentInfo: WxJsApiPreCreateResponse
|
||||||
}>
|
}>
|
||||||
|
|
||||||
|
@ -46,6 +50,11 @@ export interface WxJsApiPreCreateResponse {
|
||||||
export interface GetOpenIdRequestParams {
|
export interface GetOpenIdRequestParams {
|
||||||
code: string
|
code: string
|
||||||
}
|
}
|
||||||
|
export interface QyLoginRequestParams {
|
||||||
|
corpid: string
|
||||||
|
code: string
|
||||||
|
state?: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShopOrderEntity {
|
export interface ShopOrderEntity {
|
||||||
orderId: number
|
orderId: number
|
||||||
|
@ -72,3 +81,15 @@ export interface GetOrdersByOpenIdDTO {
|
||||||
orderGoods: ShopOrderGoodsEntity[]
|
orderGoods: ShopOrderGoodsEntity[]
|
||||||
goods: Goods[]
|
goods: Goods[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GetBalanceResponse {
|
||||||
|
userid: string
|
||||||
|
corpid: string
|
||||||
|
balance: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QyLoginDTO {
|
||||||
|
userid: string
|
||||||
|
openid: string
|
||||||
|
isCabinetAdmin: number
|
||||||
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useWxStore } from '@/pinia/stores/wx'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const wxStore = useWxStore()
|
||||||
|
const balance = computed(() => wxStore.balance)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -31,10 +36,10 @@ const router = useRouter()
|
||||||
<van-grid :column-num="4" :gutter="12" class="func-buttons un-mt-20px">
|
<van-grid :column-num="4" :gutter="12" class="func-buttons un-mt-20px">
|
||||||
<van-grid-item
|
<van-grid-item
|
||||||
v-for="(item, index) in [
|
v-for="(item, index) in [
|
||||||
{ icon: 'idcard', text: '身份证', color: 'linear-gradient(to right, #ff6034, #ee0a24)' },
|
{ icon: 'idcard', text: '身份证', color: 'transparent' },
|
||||||
{ icon: 'phone-o', text: '手机号', color: 'linear-gradient(to right, #3f87ff, #1989fa)' },
|
{ icon: 'phone-o', text: '手机号', color: 'transparent' },
|
||||||
{ icon: 'wechat', text: '微信', color: 'linear-gradient(to right, #07c160, #4b0)' },
|
{ icon: 'wechat', text: '微信', color: 'transparent' },
|
||||||
{ icon: 'card', text: '银行卡', color: 'linear-gradient(to right, #ffd700, #ffb300)' }
|
{ icon: 'card', text: '银行卡', color: 'transparent' }
|
||||||
]"
|
]"
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
|
@ -51,7 +56,7 @@ const router = useRouter()
|
||||||
<!-- 余额区域 -->
|
<!-- 余额区域 -->
|
||||||
<van-cell
|
<van-cell
|
||||||
title="账户余额"
|
title="账户余额"
|
||||||
:value="`¥${0}`"
|
:value="`¥${balance}`"
|
||||||
class="un-mt-16px! un-rounded-8px!"
|
class="un-mt-16px! un-rounded-8px!"
|
||||||
title-class="un-text-14px! un-color-hex-333!"
|
title-class="un-text-14px! un-color-hex-333!"
|
||||||
value-class="un-text-16px! un-fw-600! un-color-primary!"
|
value-class="un-text-16px! un-fw-600! un-color-primary!"
|
||||||
|
|
|
@ -101,6 +101,7 @@ watch(() => orderId.value, async (newVal) => {
|
||||||
type="default"
|
type="default"
|
||||||
block
|
block
|
||||||
class="detail-button"
|
class="detail-button"
|
||||||
|
@click="router.push('/order/' + orderId)"
|
||||||
>
|
>
|
||||||
查看订单详情
|
查看订单详情
|
||||||
</van-button>
|
</van-button>
|
||||||
|
|
|
@ -67,7 +67,7 @@ const throttledUpdate = throttle(() => {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activeCategory.value = activeIndex
|
// activeCategory.value = activeIndex
|
||||||
}, 100)
|
}, 100)
|
||||||
|
|
||||||
// 节流的头部高度计算(实现顶部图片缩放效果)
|
// 节流的头部高度计算(实现顶部图片缩放效果)
|
||||||
|
@ -134,9 +134,6 @@ function handleCheckout() {
|
||||||
<!-- 右侧商品列表 -->
|
<!-- 右侧商品列表 -->
|
||||||
<div ref="scrollContainer" class="product-list">
|
<div ref="scrollContainer" class="product-list">
|
||||||
<div :ref="el => categoryRefs[0] = el as HTMLElement" class="category-section">
|
<div :ref="el => categoryRefs[0] = el as HTMLElement" class="category-section">
|
||||||
<h3 class="category-title">
|
|
||||||
{{ labels[activeCategory].name }}
|
|
||||||
</h3>
|
|
||||||
<van-cell v-for="product in currentProducts" :key="product.id" class="product-item">
|
<van-cell v-for="product in currentProducts" :key="product.id" class="product-item">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<van-image :src="product.image" width="80" height="80" @click.stop="showProductDetail(product.id)"
|
<van-image :src="product.image" width="80" height="80" @click.stop="showProductDetail(product.id)"
|
||||||
|
|
|
@ -13,8 +13,9 @@ const cartStore = useCartStore()
|
||||||
const { cartItems, totalPrice } = storeToRefs(cartStore)
|
const { cartItems, totalPrice } = storeToRefs(cartStore)
|
||||||
|
|
||||||
const wxStore = useWxStore()
|
const wxStore = useWxStore()
|
||||||
const { openid } = storeToRefs(wxStore)
|
const { openid, balance } = storeToRefs(wxStore)
|
||||||
|
|
||||||
|
const selectedPayment = ref<'wechat' | 'balance'>('wechat')
|
||||||
const contact = ref("")
|
const contact = ref("")
|
||||||
const remark = ref("")
|
const remark = ref("")
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
|
@ -28,8 +29,8 @@ function callWxJsApi(paymentInfo: WxJsApiPreCreateResponse) {
|
||||||
appId: paymentInfo.appId,
|
appId: paymentInfo.appId,
|
||||||
timeStamp: paymentInfo.timeStamp,
|
timeStamp: paymentInfo.timeStamp,
|
||||||
nonceStr: paymentInfo.nonceStr,
|
nonceStr: paymentInfo.nonceStr,
|
||||||
package: paymentInfo.package.startsWith('prepay_id=')
|
package: paymentInfo.package.startsWith('prepay_id=')
|
||||||
? paymentInfo.package
|
? paymentInfo.package
|
||||||
: `prepay_id=${paymentInfo.package}`,
|
: `prepay_id=${paymentInfo.package}`,
|
||||||
signType: paymentInfo.signType,
|
signType: paymentInfo.signType,
|
||||||
paySign: paymentInfo.paySign
|
paySign: paymentInfo.paySign
|
||||||
|
@ -67,46 +68,50 @@ async function handleSubmit() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 移除原有的支付方式选择弹窗代码
|
||||||
|
|
||||||
submitting.value = true
|
submitting.value = true
|
||||||
try {
|
try {
|
||||||
// 构造请求参数
|
|
||||||
const requestData: SubmitOrderRequestData = {
|
const requestData: SubmitOrderRequestData = {
|
||||||
openid: openid.value, // 假设联系方式即为openid,根据实际情况调整
|
openid: openid.value,
|
||||||
|
userid: wxStore.userid,
|
||||||
|
corpid: wxStore.corpid,
|
||||||
goodsList: cartItems.value.map(item => ({
|
goodsList: cartItems.value.map(item => ({
|
||||||
goodsId: item.product.id,
|
goodsId: item.product.id,
|
||||||
quantity: item.quantity
|
quantity: item.quantity
|
||||||
}))
|
})),
|
||||||
|
paymentType: selectedPayment.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用提交订单接口
|
const { code, data } = await submitOrderApi(requestData)
|
||||||
const { data } = await submitOrderApi(requestData)
|
|
||||||
|
|
||||||
// await showConfirmDialog({
|
if (code !== 0) {
|
||||||
// title: "提交成功",
|
throw new Error("订单提交失败")
|
||||||
// message: `订单号:${data.orderId},正在跳转支付...`
|
}
|
||||||
// })
|
|
||||||
|
|
||||||
// 调用微信支付
|
if (selectedPayment.value === 'wechat') {
|
||||||
if (data.paymentInfo) {
|
if (data.paymentInfo) {
|
||||||
await callWxJsApi(data.paymentInfo);
|
await callWxJsApi(data.paymentInfo);
|
||||||
// 支付成功后跳转
|
}
|
||||||
router.push({
|
|
||||||
path: '/order-success',
|
|
||||||
query: {
|
|
||||||
orderId: data.orderId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('无法获取支付信息');
|
// 余额支付成功处理
|
||||||
|
wxStore.setBalance(data.newBalance || 0);
|
||||||
|
try {
|
||||||
|
await showConfirmDialog({
|
||||||
|
title: "支付成功",
|
||||||
|
message: `余额支付成功,剩余余额:¥${data.newBalance?.toFixed(2)}`
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空购物车
|
router.push({
|
||||||
|
path: '/order-success',
|
||||||
|
query: { orderId: data.orderId }
|
||||||
|
});
|
||||||
cartStore.clearCart()
|
cartStore.clearCart()
|
||||||
|
|
||||||
// 这里添加支付跳转逻辑(根据paymentInfo处理)
|
|
||||||
// 例如:调用微信JSAPI支付等
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if(error !== 'user_cancel') {
|
if (error !== 'user_cancel') {
|
||||||
showConfirmDialog({
|
showConfirmDialog({
|
||||||
title: "支付失败",
|
title: "支付失败",
|
||||||
message: error instanceof Error ? error.message : "支付流程中断"
|
message: error instanceof Error ? error.message : "支付流程中断"
|
||||||
|
@ -146,13 +151,21 @@ async function handleSubmit() {
|
||||||
</van-cell>
|
</van-cell>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
<!-- 联系方式与备注 -->
|
|
||||||
<van-cell-group class="contact-form">
|
<van-cell-group class="contact-form">
|
||||||
<!-- <van-field v-model="contact" label="联系方式" placeholder="请输入手机号" :rules="[
|
<van-field label="支付方式" :model-value="selectedPayment" readonly>
|
||||||
{ required: true, message: '请填写联系方式' },
|
<template #input>
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确' },
|
<van-radio-group v-model="selectedPayment" direction="horizontal">
|
||||||
]" />
|
<van-radio name="wechat">
|
||||||
<van-field v-model="remark" label="备注" type="textarea" placeholder="选填,可备注特殊需求" rows="2" autosize /> -->
|
<van-icon name="wechat" class="method-icon" />
|
||||||
|
微信支付
|
||||||
|
</van-radio>
|
||||||
|
<van-radio name="balance" :disabled="balance < totalPrice">
|
||||||
|
<van-icon name="balance-o" class="method-icon" />
|
||||||
|
余额支付(当前:¥{{ balance.toFixed(2) }})
|
||||||
|
</van-radio>
|
||||||
|
</van-radio-group>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
<!-- 提交订单栏 -->
|
<!-- 提交订单栏 -->
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { pinia } from "@/pinia"
|
import { pinia } from "@/pinia"
|
||||||
import { getOpenIdApi } from "@/common/apis/shop"
|
import { getOpenIdApi, getBalanceApi, qyLogin, getBalanceByQyUserid } from "@/common/apis/shop"
|
||||||
|
|
||||||
|
|
||||||
export const useWxStore = defineStore("wx", () => {
|
export const useWxStore = defineStore("wx", () => {
|
||||||
|
@ -9,34 +9,76 @@ export const useWxStore = defineStore("wx", () => {
|
||||||
const state = ref<string>("")
|
const state = ref<string>("")
|
||||||
// 用户 openid
|
// 用户 openid
|
||||||
const openid = ref<string>("")
|
const openid = ref<string>("")
|
||||||
|
// 用户 userid
|
||||||
|
const userid = ref<string>("");
|
||||||
|
// 用户余额
|
||||||
|
const balance = ref<number>(0);
|
||||||
|
// 企业id
|
||||||
|
const corpid = ref<string>("");
|
||||||
|
// 是否是柜子管理员
|
||||||
|
const isCabinetAdmin = ref<boolean>(false);
|
||||||
|
|
||||||
// 设置 openid
|
// 设置 openid
|
||||||
const setOpenid = (id: string) => {
|
const setOpenid = (id: string) => {
|
||||||
openid.value = id
|
openid.value = id
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleWxCallback = async (params: { code?: string; state?: string }) => {
|
const setBalance = (amount: number) => {
|
||||||
|
balance.value = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleWxCallback = async (params: { corpid?: string; code?: string; state?: string }) => {
|
||||||
console.log('handleWxCallback:', params)
|
console.log('handleWxCallback:', params)
|
||||||
if (params.code) {
|
if (params.code) {
|
||||||
code.value = params.code
|
code.value = params.code
|
||||||
state.value = params.state || state.value
|
state.value = params.state || state.value
|
||||||
|
corpid.value = params.corpid || corpid.value
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 调用获取 openid 的接口
|
if (!corpid.value) {
|
||||||
const res = await getOpenIdApi({ code: params.code })
|
// 调用获取 openid 的接口
|
||||||
console.log('获取 openid 成功:', res)
|
const res = await getOpenIdApi({ code: params.code });
|
||||||
if (res && res.code == 0) {
|
if (res && res.code == 0) {
|
||||||
openid.value = res.data
|
openid.value = res.data
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 企业微信登录
|
||||||
|
const res = await qyLogin({ corpid: corpid.value, code: params.code, state: params.state})
|
||||||
|
if (res && res.code == 0) {
|
||||||
|
userid.value = res.data.userid;
|
||||||
|
openid.value = res.data.openid;
|
||||||
|
isCabinetAdmin.value = res.data.isCabinetAdmin === 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openid.value) {
|
||||||
|
// 获取用户余额
|
||||||
|
let balanceRes = null;
|
||||||
|
|
||||||
|
if(corpid.value) {
|
||||||
|
balanceRes = await getBalanceByQyUserid(corpid.value, userid.value);
|
||||||
|
} else {
|
||||||
|
balanceRes = await getBalanceApi(openid.value)
|
||||||
|
}
|
||||||
|
console.log('获取余额成功:', balanceRes)
|
||||||
|
if (balanceRes && balanceRes.code == 0) {
|
||||||
|
balance.value = balanceRes.data.balance
|
||||||
|
if (!userid.value) {
|
||||||
|
userid.value = balanceRes.data.userid;
|
||||||
|
}
|
||||||
|
if (!corpid.value) {
|
||||||
|
corpid.value = balanceRes.data.corpid;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('获取 openid 失败:', err)
|
console.error('获取 openid 失败:', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(window as any).testWxSetOpenid = setOpenid
|
return { code, state, openid, corpid, userid, balance, setOpenid, setBalance, handleWxCallback }
|
||||||
|
|
||||||
return { code, state, openid, setOpenid, handleWxCallback }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,12 +16,15 @@ declare module 'vue' {
|
||||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||||
VanDivider: typeof import('vant/es')['Divider']
|
VanDivider: typeof import('vant/es')['Divider']
|
||||||
|
VanField: typeof import('vant/es')['Field']
|
||||||
VanGrid: typeof import('vant/es')['Grid']
|
VanGrid: typeof import('vant/es')['Grid']
|
||||||
VanGridItem: typeof import('vant/es')['GridItem']
|
VanGridItem: typeof import('vant/es')['GridItem']
|
||||||
VanIcon: typeof import('vant/es')['Icon']
|
VanIcon: typeof import('vant/es')['Icon']
|
||||||
VanImage: typeof import('vant/es')['Image']
|
VanImage: typeof import('vant/es')['Image']
|
||||||
VanLoading: typeof import('vant/es')['Loading']
|
VanLoading: typeof import('vant/es')['Loading']
|
||||||
VanNavBar: typeof import('vant/es')['NavBar']
|
VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
|
VanRadio: typeof import('vant/es')['Radio']
|
||||||
|
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
||||||
VanSidebar: typeof import('vant/es')['Sidebar']
|
VanSidebar: typeof import('vant/es')['Sidebar']
|
||||||
VanSidebarItem: typeof import('vant/es')['SidebarItem']
|
VanSidebarItem: typeof import('vant/es')['SidebarItem']
|
||||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||||
|
|
Loading…
Reference in New Issue