微信公众号授权网页登录修改
This commit is contained in:
parent
e6b59eb2a1
commit
c7305421d0
|
|
@ -1127,7 +1127,22 @@ async function loginFromWechatEnv(code, env, context, wechatLoginId) {
|
|||
// wechatUser存在直接登录
|
||||
if (wechatUser) {
|
||||
const tokenValue = await setUpTokenAndUser(env, context, 'wechatUser', wechatUser.id, undefined, wechatUser.user);
|
||||
await updateWechatLogin({ userId: wechatUser.userId, wechatUserId: wechatUser.id, successed: true });
|
||||
const wechatUserUpdateData = wechatUserData;
|
||||
if (unionId !== wechatUser.unionId) {
|
||||
Object.assign(wechatUserUpdateData, {
|
||||
unionId,
|
||||
...wechatUserData,
|
||||
});
|
||||
}
|
||||
await context.operate('wechatUser', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: wechatUserUpdateData,
|
||||
filter: {
|
||||
id: wechatUser.id,
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
await updateWechatLogin({ userId: wechatUser.userId, successed: true });
|
||||
return tokenValue;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ function QrCode(props) {
|
|||
</Button>)}
|
||||
{onRefresh && (<Button type="text" onClick={() => {
|
||||
onRefresh();
|
||||
}}>
|
||||
}} size="small">
|
||||
<ReloadOutlined className={`${prefixCls}-qrCodeBox_actions_refreshIcon`}/>
|
||||
</Button>)}
|
||||
</Space>}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
&_refreshIcon {
|
||||
color: var(--oak-color-primary);
|
||||
font-size: 24px;
|
||||
font-size: 16px;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Row, Col, Card, Divider, Input, Form, Space, message, } from 'antd';
|
||||
import { Row, Col, Card, Divider, Input, Form, Space, Select, message, } from 'antd';
|
||||
import Styles from './web.module.less';
|
||||
export default function Web(props) {
|
||||
const { config, setValue } = props;
|
||||
|
|
@ -52,6 +52,40 @@ export default function Web(props) {
|
|||
</Form>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
location
|
||||
</Divider>
|
||||
<Form colon={true} labelAlign="left" layout="vertical" style={{ marginTop: 10 }}>
|
||||
<Form.Item label="协议">
|
||||
<>
|
||||
<Select style={{ width: '100%' }} placeholder="请选择协议" value={config?.location?.protocol} onChange={(value) => {
|
||||
setValue(`location.protocol`, value);
|
||||
}} options={[
|
||||
{
|
||||
label: 'http',
|
||||
value: 'http',
|
||||
},
|
||||
{
|
||||
label: 'https',
|
||||
value: 'https',
|
||||
},
|
||||
]}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="主机">
|
||||
<>
|
||||
<Input placeholder="请输入主机" type="text" value={config?.location?.host} onChange={(e) => setValue(`location.host`, e.target.value)}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="端口">
|
||||
<>
|
||||
<Input placeholder="请输入端口" type="text" value={config?.location?.port} onChange={(e) => setValue(`location.port`, e.target.value || '')}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
{/* <Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
网站-授权方式
|
||||
|
|
|
|||
|
|
@ -39,6 +39,41 @@ export default function WechatPublic(props) {
|
|||
</Form.Item>)}
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
<Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
location
|
||||
</Divider>
|
||||
<Form colon={true} labelAlign="left" layout="vertical" style={{ marginTop: 10 }}>
|
||||
<Form.Item label="协议">
|
||||
<>
|
||||
<Select style={{ width: '100%' }} placeholder="请选择协议" value={config?.location?.protocol} onChange={(value) => {
|
||||
setValue(`location.protocol`, value);
|
||||
}} options={[
|
||||
{
|
||||
label: 'http',
|
||||
value: 'http',
|
||||
},
|
||||
{
|
||||
label: 'https',
|
||||
value: 'https',
|
||||
},
|
||||
]}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="主机">
|
||||
<>
|
||||
<Input placeholder="请输入主机" type="text" value={config?.location?.host} onChange={(e) => setValue(`location.host`, e.target.value)}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="端口">
|
||||
<>
|
||||
<Input placeholder="请输入端口" type="text" value={config?.location?.port} onChange={(e) => setValue(`location.port`, e.target.value || '')}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Col>
|
||||
|
||||
{/* <Col flex="auto">
|
||||
<Divider orientation="left" className={Styles.title}>
|
||||
网站-授权方式
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export default function Render(props) {
|
|||
{Tip}
|
||||
</div>}
|
||||
{loginMode === 'wechatPublicForWeb' && <div className={Style['loginbox-qrcode']}>
|
||||
<WechatLoginQrCodeForPublic type="login" oakPath="$login-wechatLogin/qrCode" oakAutoUnmount={true} url={state} size={200}/>
|
||||
<WechatLoginQrCodeForPublic type="login" oakPath="$login-wechatLogin/qrCode" oakAutoUnmount={true} url={state} size={180}/>
|
||||
{Tip}
|
||||
</div>}
|
||||
{InputMethods}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ export default OakComponent({
|
|||
const userId = wechatLogin?.userId;
|
||||
const type = wechatLogin?.type;
|
||||
const application = features.application.getApplication();
|
||||
const appId = application?.config?.wechat
|
||||
?.appId;
|
||||
const appId = application?.config?.appId;
|
||||
return {
|
||||
type,
|
||||
userId,
|
||||
|
|
@ -42,8 +41,8 @@ export default OakComponent({
|
|||
}
|
||||
else {
|
||||
const { appId } = this.state;
|
||||
const redirectUrl = `${window.location.host}/wechatUser/login?wechatLoginId=${this.props.oakId}`;
|
||||
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&state=${state}&redirect_uri=${redirectUrl}&response_type=code&scope=SCOPE#wechat_redirect`;
|
||||
const redirectUrl = `https%3A%2F%2F${window.location.host}%2FwechatUser%2Flogin%3FwechatLoginId%3D${this.props.oakId}`; //网址转义 `https://${window.location.host}/wechatUser/login?wechatLoginId=${this.props.oakId}`
|
||||
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EntityDict } from '../../../oak-app-domain';
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
type: "login" | "bind";
|
||||
type: "bind" | "login";
|
||||
url: string;
|
||||
size: undefined;
|
||||
}>) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const Interval = 2 * 60 * 1000;
|
||||
const Interval = 5 * 60 * 1000;
|
||||
export default OakComponent({
|
||||
isList: false,
|
||||
lifetimes: {
|
||||
|
|
@ -64,7 +64,7 @@ export default OakComponent({
|
|||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
type: 1, //类型
|
||||
type: 1,
|
||||
ticket: 1,
|
||||
url: 1,
|
||||
buffer: 1,
|
||||
|
|
@ -150,5 +150,14 @@ export default OakComponent({
|
|||
}
|
||||
});
|
||||
},
|
||||
refreshQrCode() {
|
||||
if (this.createTimer) {
|
||||
clearInterval(this.createTimer);
|
||||
}
|
||||
this.createWechatLogin();
|
||||
this.createTimer = setInterval(() => {
|
||||
this.createWechatLogin();
|
||||
}, Interval);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,4 +8,6 @@ export default function Render(props: WebComponentProps<EntityDict, 'wechatLogin
|
|||
successful: boolean;
|
||||
type: EntityDict['wechatLogin']['Schema']['type'];
|
||||
size: number;
|
||||
}, {}>): React.JSX.Element;
|
||||
}, {
|
||||
refreshQrCode: () => void;
|
||||
}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import QrCode from '../../../components/common/qrCode';
|
||||
export default function Render(props) {
|
||||
const { oakFullpath, qrCodeUrl, loading, successful, type, size } = props.data;
|
||||
const { refreshQrCode } = props.methods;
|
||||
return (<div>
|
||||
<QrCode loading={loading} url={qrCodeUrl} disableDownload={true} tips={<div>微信扫一扫</div>} successful={successful} type={type} size={size}/>
|
||||
<QrCode loading={loading} url={qrCodeUrl} disableDownload={true} tips={<div>微信扫一扫</div>} successful={successful} type={type} size={size} onRefresh={() => refreshQrCode()}/>
|
||||
</div>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export default OakComponent({
|
|||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
type: 1, //类型
|
||||
type: 1,
|
||||
ticket: 1,
|
||||
url: 1,
|
||||
expired: 1,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ export default OakComponent({
|
|||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
type: 1, //类型
|
||||
type: 1,
|
||||
ticket: 1,
|
||||
url: 1,
|
||||
buffer: 1,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { composeDomainUrl } from '../utils/domain';
|
|||
import { composeUrl } from 'oak-domain/lib/utils/domain';
|
||||
import { createSession } from '../aspects/session';
|
||||
import { getMaterial } from '../aspects/application';
|
||||
import { composeLocationUrl } from '../utils/application';
|
||||
const X2Js = new x2js();
|
||||
function assertFromWeChat(query, config) {
|
||||
const { signature, nonce, timestamp } = query;
|
||||
|
|
@ -170,7 +171,7 @@ async function setUserSubscribed(openId, eventKey, context) {
|
|||
const application = context.getApplication();
|
||||
const { type, config, systemId } = application;
|
||||
assert(type === 'wechatPublic');
|
||||
const { appId, appSecret } = config;
|
||||
const { appId, appSecret, location } = config;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
|
||||
const { expired } = wechatQrCode;
|
||||
if (expired) {
|
||||
|
|
@ -309,24 +310,40 @@ async function setUserSubscribed(openId, eventKey, context) {
|
|||
// todo 公众号跳小程序 绑定login 后面再实现
|
||||
}
|
||||
else {
|
||||
const [domain] = await context.select('domain', {
|
||||
data: {
|
||||
id: 1,
|
||||
url: 1,
|
||||
apiPath: 1,
|
||||
protocol: 1,
|
||||
port: 1,
|
||||
},
|
||||
filter: {
|
||||
system: {
|
||||
application$system: {
|
||||
id: applicationId,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
assert(domain, `处理wechatLogin时,找不到对应的domain,applicationId是「${applicationId}」`);
|
||||
const url = composeDomainUrl(domain, 'wechatQrCode/scan', {
|
||||
// const [domain] = await context.select(
|
||||
// 'domain',
|
||||
// {
|
||||
// data: {
|
||||
// id: 1,
|
||||
// url: 1,
|
||||
// apiPath: 1,
|
||||
// protocol: 1,
|
||||
// port: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// system: {
|
||||
// application$system: {
|
||||
// id: applicationId,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// { dontCollect: true }
|
||||
// );
|
||||
// assert(
|
||||
// domain,
|
||||
// `处理wechatLogin时,找不到对应的domain,applicationId是「${applicationId}」`
|
||||
// );
|
||||
// const url = composeDomainUrl(
|
||||
// domain as EntityDict['domain']['Schema'],
|
||||
// 'wechatQrCode/scan',
|
||||
// {
|
||||
// scene: sceneStr,
|
||||
// time: `${Date.now()}`,
|
||||
// }
|
||||
// );
|
||||
//从application的config中获取前端访问地址
|
||||
const url = composeLocationUrl(location, 'wechatQrCode/scan', {
|
||||
scene: sceneStr,
|
||||
time: `${Date.now()}`,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ export type WebConfig = {
|
|||
enable?: boolean;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
|
|
@ -51,6 +56,11 @@ export type WechatPublicConfig = {
|
|||
originalId: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type NativeConfig = {
|
||||
type: 'native';
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ export type WebConfig = {
|
|||
enable?: boolean;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: "http" | "https";
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
|
|
@ -66,6 +71,11 @@ export type WechatPublicConfig = {
|
|||
originalId: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: "http" | "https";
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type NativeConfig = {
|
||||
type: "native";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
export type Location = {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
export declare function composeLocationUrl(location: Location, url?: string, props?: Record<string, string>): string;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
export function composeLocationUrl(location, url, props) {
|
||||
const { port, protocol, host } = location;
|
||||
let Url = `${protocol}://${host}`;
|
||||
if (port) {
|
||||
Url += `:${port}`;
|
||||
}
|
||||
if (url) {
|
||||
Url += url.startsWith('/') ? url : `/${url}`;
|
||||
if (props) {
|
||||
const k = Object.keys(props);
|
||||
if (k.length > 0) {
|
||||
for (const k2 of k) {
|
||||
Url += Url.includes('?') ? '&' : '?';
|
||||
Url += `${k2}=${encodeURI(props[k2])}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Url;
|
||||
}
|
||||
|
|
@ -1136,7 +1136,22 @@ async function loginFromWechatEnv(code, env, context, wechatLoginId) {
|
|||
// wechatUser存在直接登录
|
||||
if (wechatUser) {
|
||||
const tokenValue = await setUpTokenAndUser(env, context, 'wechatUser', wechatUser.id, undefined, wechatUser.user);
|
||||
await updateWechatLogin({ userId: wechatUser.userId, wechatUserId: wechatUser.id, successed: true });
|
||||
const wechatUserUpdateData = wechatUserData;
|
||||
if (unionId !== wechatUser.unionId) {
|
||||
Object.assign(wechatUserUpdateData, {
|
||||
unionId,
|
||||
...wechatUserData,
|
||||
});
|
||||
}
|
||||
await context.operate('wechatUser', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: wechatUserUpdateData,
|
||||
filter: {
|
||||
id: wechatUser.id,
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
await updateWechatLogin({ userId: wechatUser.userId, successed: true });
|
||||
return tokenValue;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const domain_1 = require("../utils/domain");
|
|||
const domain_2 = require("oak-domain/lib/utils/domain");
|
||||
const session_1 = require("../aspects/session");
|
||||
const application_1 = require("../aspects/application");
|
||||
const application_2 = require("../utils/application");
|
||||
const X2Js = new x2js_1.default();
|
||||
function assertFromWeChat(query, config) {
|
||||
const { signature, nonce, timestamp } = query;
|
||||
|
|
@ -175,7 +176,7 @@ async function setUserSubscribed(openId, eventKey, context) {
|
|||
const application = context.getApplication();
|
||||
const { type, config, systemId } = application;
|
||||
(0, assert_1.assert)(type === 'wechatPublic');
|
||||
const { appId, appSecret } = config;
|
||||
const { appId, appSecret, location } = config;
|
||||
const wechatInstance = WechatSDK_1.default.getInstance(appId, 'wechatPublic', appSecret);
|
||||
const { expired } = wechatQrCode;
|
||||
if (expired) {
|
||||
|
|
@ -314,24 +315,40 @@ async function setUserSubscribed(openId, eventKey, context) {
|
|||
// todo 公众号跳小程序 绑定login 后面再实现
|
||||
}
|
||||
else {
|
||||
const [domain] = await context.select('domain', {
|
||||
data: {
|
||||
id: 1,
|
||||
url: 1,
|
||||
apiPath: 1,
|
||||
protocol: 1,
|
||||
port: 1,
|
||||
},
|
||||
filter: {
|
||||
system: {
|
||||
application$system: {
|
||||
id: applicationId,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
(0, assert_1.assert)(domain, `处理wechatLogin时,找不到对应的domain,applicationId是「${applicationId}」`);
|
||||
const url = (0, domain_1.composeDomainUrl)(domain, 'wechatQrCode/scan', {
|
||||
// const [domain] = await context.select(
|
||||
// 'domain',
|
||||
// {
|
||||
// data: {
|
||||
// id: 1,
|
||||
// url: 1,
|
||||
// apiPath: 1,
|
||||
// protocol: 1,
|
||||
// port: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// system: {
|
||||
// application$system: {
|
||||
// id: applicationId,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// { dontCollect: true }
|
||||
// );
|
||||
// assert(
|
||||
// domain,
|
||||
// `处理wechatLogin时,找不到对应的domain,applicationId是「${applicationId}」`
|
||||
// );
|
||||
// const url = composeDomainUrl(
|
||||
// domain as EntityDict['domain']['Schema'],
|
||||
// 'wechatQrCode/scan',
|
||||
// {
|
||||
// scene: sceneStr,
|
||||
// time: `${Date.now()}`,
|
||||
// }
|
||||
// );
|
||||
//从application的config中获取前端访问地址
|
||||
const url = (0, application_2.composeLocationUrl)(location, 'wechatQrCode/scan', {
|
||||
scene: sceneStr,
|
||||
time: `${Date.now()}`,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ export type WebConfig = {
|
|||
enable?: boolean;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
|
|
@ -51,6 +56,11 @@ export type WechatPublicConfig = {
|
|||
originalId: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type NativeConfig = {
|
||||
type: 'native';
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ export type WebConfig = {
|
|||
enable?: boolean;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: "http" | "https";
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type WechatPublicTemplateMsgsConfig = Record<string, string>;
|
||||
export type WechatPublicConfig = {
|
||||
|
|
@ -66,6 +71,11 @@ export type WechatPublicConfig = {
|
|||
originalId: string;
|
||||
};
|
||||
passport?: Passport[];
|
||||
location: {
|
||||
protocol: "http" | "https";
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
};
|
||||
export type NativeConfig = {
|
||||
type: "native";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
export type Location = {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
};
|
||||
export declare function composeLocationUrl(location: Location, url?: string, props?: Record<string, string>): string;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.composeLocationUrl = void 0;
|
||||
function composeLocationUrl(location, url, props) {
|
||||
const { port, protocol, host } = location;
|
||||
let Url = `${protocol}://${host}`;
|
||||
if (port) {
|
||||
Url += `:${port}`;
|
||||
}
|
||||
if (url) {
|
||||
Url += url.startsWith('/') ? url : `/${url}`;
|
||||
if (props) {
|
||||
const k = Object.keys(props);
|
||||
if (k.length > 0) {
|
||||
for (const k2 of k) {
|
||||
Url += Url.includes('?') ? '&' : '?';
|
||||
Url += `${k2}=${encodeURI(props[k2])}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Url;
|
||||
}
|
||||
exports.composeLocationUrl = composeLocationUrl;
|
||||
|
|
@ -1546,7 +1546,22 @@ async function loginFromWechatEnv<ED extends EntityDict>(
|
|||
undefined,
|
||||
wechatUser.user!
|
||||
);
|
||||
await updateWechatLogin({ userId: wechatUser.userId, wechatUserId: wechatUser.id, successed: true });
|
||||
const wechatUserUpdateData = wechatUserData;
|
||||
if (unionId !== wechatUser.unionId) {
|
||||
Object.assign(wechatUserUpdateData, {
|
||||
unionId,
|
||||
...wechatUserData,
|
||||
});
|
||||
}
|
||||
await context.operate('wechatUser', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: wechatUserUpdateData,
|
||||
filter: {
|
||||
id: wechatUser.id,
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
await updateWechatLogin({ userId: wechatUser.userId, successed: true });
|
||||
return tokenValue;
|
||||
} else {
|
||||
// 创建user和wechatUser(绑定并登录)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
&_refreshIcon {
|
||||
color: var(--oak-color-primary);
|
||||
font-size: 24px;
|
||||
font-size: 16px;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,11 +87,11 @@ function QrCode(props: IQrCodeProps) {
|
|||
title={
|
||||
type === 'bind'
|
||||
? features.locales.t(
|
||||
'weChat-account-successfully-bound'
|
||||
)
|
||||
'weChat-account-successfully-bound'
|
||||
)
|
||||
: features.locales.t(
|
||||
'weChat-authorization-login-successful'
|
||||
)
|
||||
'weChat-authorization-login-successful'
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -162,6 +162,7 @@ function QrCode(props: IQrCodeProps) {
|
|||
onClick={() => {
|
||||
onRefresh();
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
<ReloadOutlined
|
||||
className={`${prefixCls}-qrCodeBox_actions_refreshIcon`}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ export default function Render(
|
|||
oakPath="$login-wechatLogin/qrCode"
|
||||
oakAutoUnmount={true}
|
||||
url={state}
|
||||
size={200}
|
||||
size={180}
|
||||
/>
|
||||
{Tip}
|
||||
</div>}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { WebConfig } from "../../../oak-app-domain/Application/Schema";
|
||||
|
||||
import { WechatPublicConfig } from "../../../oak-app-domain/Application/Schema";
|
||||
|
||||
export default OakComponent({
|
||||
entity: 'wechatLogin',
|
||||
|
|
@ -19,8 +18,8 @@ export default OakComponent({
|
|||
const userId = wechatLogin?.userId;
|
||||
const type = wechatLogin?.type;
|
||||
const application = features.application.getApplication();
|
||||
const appId = (application?.config as WebConfig)?.wechat
|
||||
?.appId;
|
||||
const appId = (application?.config as WechatPublicConfig)?.appId;
|
||||
|
||||
return {
|
||||
type,
|
||||
userId,
|
||||
|
|
@ -47,8 +46,8 @@ export default OakComponent({
|
|||
}
|
||||
else {
|
||||
const { appId } = this.state;
|
||||
const redirectUrl = `${window.location.host}/wechatUser/login?wechatLoginId=${this.props.oakId}`;
|
||||
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&state=${state}&redirect_uri=${redirectUrl}&response_type=code&scope=SCOPE#wechat_redirect`
|
||||
const redirectUrl = `https%3A%2F%2F${window.location.host}%2FwechatUser%2Flogin%3FwechatLoginId%3D${this.props.oakId}`; //网址转义 `https://${window.location.host}/wechatUser/login?wechatLoginId=${this.props.oakId}`
|
||||
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EntityDict } from '../../../oak-app-domain';
|
||||
|
||||
const Interval = 2 * 60 * 1000;
|
||||
const Interval = 5 * 60 * 1000;
|
||||
|
||||
export default OakComponent({
|
||||
isList: false,
|
||||
|
|
@ -170,5 +170,14 @@ export default OakComponent({
|
|||
}
|
||||
);
|
||||
},
|
||||
refreshQrCode() {
|
||||
if ((this as any).createTimer) {
|
||||
clearInterval((this as any).createTimer);
|
||||
}
|
||||
this.createWechatLogin();
|
||||
(this as any).createTimer = setInterval(() => {
|
||||
this.createWechatLogin();
|
||||
}, Interval);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@ export default function Render(
|
|||
type: EntityDict['wechatLogin']['Schema']['type'];
|
||||
size: number;
|
||||
},
|
||||
{}
|
||||
{
|
||||
refreshQrCode: () => void;
|
||||
}
|
||||
>
|
||||
) {
|
||||
const { oakFullpath, qrCodeUrl, loading, successful, type, size } = props.data;
|
||||
const { refreshQrCode } = props.methods;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
@ -33,6 +36,7 @@ export default function Render(
|
|||
successful={successful}
|
||||
type={type}
|
||||
size={size}
|
||||
onRefresh={() => refreshQrCode()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { composeDomainUrl } from '../utils/domain';
|
|||
import { composeUrl } from 'oak-domain/lib/utils/domain';
|
||||
import { createSession } from '../aspects/session';
|
||||
import { getMaterial } from '../aspects/application';
|
||||
import { composeLocationUrl, Location } from '../utils/application';
|
||||
|
||||
type VerifyQuery = {
|
||||
signature: string;
|
||||
|
|
@ -238,7 +239,7 @@ async function setUserSubscribed(
|
|||
const application = context.getApplication();
|
||||
const { type, config, systemId } = application!;
|
||||
assert(type === 'wechatPublic');
|
||||
const { appId, appSecret } = config as WechatPublicConfig;
|
||||
const { appId, appSecret, location } = config as WechatPublicConfig;
|
||||
|
||||
const wechatInstance = WechatSDK.getInstance(
|
||||
appId,
|
||||
|
|
@ -419,38 +420,49 @@ async function setUserSubscribed(
|
|||
if (qrCodeType === 'wechatPublicForMp') {
|
||||
// todo 公众号跳小程序 绑定login 后面再实现
|
||||
} else {
|
||||
const [domain] = await context.select(
|
||||
'domain',
|
||||
{
|
||||
data: {
|
||||
id: 1,
|
||||
url: 1,
|
||||
apiPath: 1,
|
||||
protocol: 1,
|
||||
port: 1,
|
||||
},
|
||||
filter: {
|
||||
system: {
|
||||
application$system: {
|
||||
id: applicationId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ dontCollect: true }
|
||||
);
|
||||
assert(
|
||||
domain,
|
||||
`处理wechatLogin时,找不到对应的domain,applicationId是「${applicationId}」`
|
||||
);
|
||||
const url = composeDomainUrl(
|
||||
domain as EntityDict['domain']['Schema'],
|
||||
// const [domain] = await context.select(
|
||||
// 'domain',
|
||||
// {
|
||||
// data: {
|
||||
// id: 1,
|
||||
// url: 1,
|
||||
// apiPath: 1,
|
||||
// protocol: 1,
|
||||
// port: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// system: {
|
||||
// application$system: {
|
||||
// id: applicationId,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// { dontCollect: true }
|
||||
// );
|
||||
// assert(
|
||||
// domain,
|
||||
// `处理wechatLogin时,找不到对应的domain,applicationId是「${applicationId}」`
|
||||
// );
|
||||
// const url = composeDomainUrl(
|
||||
// domain as EntityDict['domain']['Schema'],
|
||||
// 'wechatQrCode/scan',
|
||||
// {
|
||||
// scene: sceneStr,
|
||||
// time: `${Date.now()}`,
|
||||
// }
|
||||
// );
|
||||
|
||||
//从application的config中获取前端访问地址
|
||||
const url = composeLocationUrl(
|
||||
location as Location,
|
||||
'wechatQrCode/scan',
|
||||
{
|
||||
scene: sceneStr,
|
||||
time: `${Date.now()}`,
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
const title = type === 'bind' ? '扫码绑定' : '扫码登录';
|
||||
const description =
|
||||
type === 'bind' ? '去绑定' : '去登录';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
export type Location = {
|
||||
protocol: 'http' | 'https';
|
||||
host: string;
|
||||
port: string;
|
||||
}
|
||||
|
||||
export function composeLocationUrl(location: Location, url?: string, props?: Record<string, string>) {
|
||||
const { port, protocol, host } = location;
|
||||
let Url = `${protocol}://${host}`;
|
||||
if (port) {
|
||||
Url += `:${port}`;
|
||||
}
|
||||
if (url) {
|
||||
Url += url.startsWith('/') ? url : `/${url}`;
|
||||
if (props) {
|
||||
const k = Object.keys(props);
|
||||
if (k.length > 0) {
|
||||
for (const k2 of k) {
|
||||
Url += Url.includes('?') ? '&' : '?';
|
||||
Url += `${k2}=${encodeURI(props[k2])}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Url;
|
||||
}
|
||||
Loading…
Reference in New Issue