11111
This commit is contained in:
@@ -594,43 +594,52 @@ const ScenarioList: React.FC = () => {
|
||||
<SpinLoading color="primary" />
|
||||
<div>生成二维码中...</div>
|
||||
</div>
|
||||
) : qrImg ? (
|
||||
<>
|
||||
<img
|
||||
src={qrImg}
|
||||
alt="小程序二维码"
|
||||
className={style["qr-image"]}
|
||||
/>
|
||||
{/* 链接复制区域 */}
|
||||
<div className={style["qr-link-section"]}>
|
||||
<div className={style["link-label"]}>小程序链接</div>
|
||||
<div className={style["link-input-wrapper"]}>
|
||||
<Input
|
||||
value={`https://h5.ckb.quwanzhi.com/#/pages/form/input2?id=${currentTaskId}`}
|
||||
readOnly
|
||||
className={style["link-input"]}
|
||||
placeholder="小程序链接"
|
||||
/>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const link = `https://h5.ckb.quwanzhi.com/#/pages/form/input2?id=${currentTaskId}`;
|
||||
navigator.clipboard.writeText(link);
|
||||
Toast.show({
|
||||
content: "链接已复制到剪贴板",
|
||||
position: "top",
|
||||
});
|
||||
}}
|
||||
className={style["copy-button"]}
|
||||
>
|
||||
<CopyOutlined />
|
||||
复制
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className={style["qr-error"]}>二维码生成失败</div>
|
||||
<>
|
||||
{/* 二维码显示区域 */}
|
||||
{qrImg ? (
|
||||
<img
|
||||
src={qrImg}
|
||||
alt="小程序二维码"
|
||||
className={style["qr-image"]}
|
||||
/>
|
||||
) : (
|
||||
<div className={style["qr-error"]}>
|
||||
<QrcodeOutlined style={{ fontSize: 48, color: "#999", marginBottom: 12 }} />
|
||||
<div>二维码生成失败</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* H5链接展示 - 无论二维码是否成功都要显示 */}
|
||||
{currentTaskId && (
|
||||
<div className={style["qr-link-section"]}>
|
||||
<div className={style["link-label"]}>H5链接</div>
|
||||
<div className={style["link-input-wrapper"]}>
|
||||
<Input
|
||||
value={`https://h5.ckb.quwanzhi.com/#/pages/form/input2?id=${currentTaskId}`}
|
||||
readOnly
|
||||
className={style["link-input"]}
|
||||
placeholder="H5链接"
|
||||
/>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const link = `https://h5.ckb.quwanzhi.com/#/pages/form/input2?id=${currentTaskId}`;
|
||||
navigator.clipboard.writeText(link);
|
||||
Toast.show({
|
||||
content: "链接已复制到剪贴板",
|
||||
position: "top",
|
||||
});
|
||||
}}
|
||||
className={style["copy-button"]}
|
||||
>
|
||||
<CopyOutlined />
|
||||
复制
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
SearchOutlined,
|
||||
DeleteOutlined,
|
||||
QrcodeOutlined,
|
||||
CopyOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Checkbox, Popup } from "antd-mobile";
|
||||
import styles from "./base.module.scss";
|
||||
@@ -60,11 +61,46 @@ const DistributionSettings: React.FC<DistributionSettingsProps> = ({
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
// 生成H5链接(独立生成,不依赖二维码)
|
||||
const generateH5Url = (channelId: string | number, channelCode?: string): string => {
|
||||
// 生成H5链接,参考列表中的实现
|
||||
// 格式: https://h5.ckb.quwanzhi.com/#/pages/form/input2?id={planId}&channelId={channelId}
|
||||
if (planId) {
|
||||
return `https://h5.ckb.quwanzhi.com/#/pages/form/input2?id=${planId}&channelId=${channelId}`;
|
||||
} else if (channelCode) {
|
||||
// 新建状态,使用渠道code
|
||||
return `https://h5.ckb.quwanzhi.com/#/pages/form/input2?channelCode=${channelCode}`;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
// 生成渠道二维码
|
||||
const generateChannelQRCode = async (channelId: string | number, channelCode?: string) => {
|
||||
// 如果已经有二维码,直接返回
|
||||
if (qrCodeMap[channelId]?.qrCode) {
|
||||
return;
|
||||
// 先生成H5链接(无论二维码是否成功都要显示)
|
||||
const h5Url = generateH5Url(channelId, channelCode);
|
||||
|
||||
// 如果已经有二维码数据,只更新H5链接(如果还没有)
|
||||
if (qrCodeMap[channelId]) {
|
||||
if (!qrCodeMap[channelId].url) {
|
||||
setQrCodeMap(prev => ({
|
||||
...prev,
|
||||
[channelId]: { ...prev[channelId], url: h5Url },
|
||||
}));
|
||||
}
|
||||
// 如果已经有二维码,直接返回
|
||||
if (qrCodeMap[channelId].qrCode) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 初始化,先设置H5链接
|
||||
setQrCodeMap(prev => ({
|
||||
...prev,
|
||||
[channelId]: {
|
||||
qrCode: "",
|
||||
url: h5Url,
|
||||
loading: true,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
// 设置加载状态
|
||||
@@ -85,18 +121,20 @@ const DistributionSettings: React.FC<DistributionSettingsProps> = ({
|
||||
}
|
||||
|
||||
// 调用API生成二维码,参考列表中的实现
|
||||
// 接口返回格式: { code: 200, msg: "获取小程序码成功", data: "data:image/png;base64,..." }
|
||||
const response = await request(
|
||||
`/v1/plan/getWxMinAppCode`,
|
||||
params,
|
||||
"GET"
|
||||
);
|
||||
|
||||
if (response && response.qrCode) {
|
||||
// response 已经是 base64 字符串(因为 request 拦截器返回了 res.data.data)
|
||||
if (response && typeof response === 'string' && response.startsWith('data:image')) {
|
||||
setQrCodeMap(prev => ({
|
||||
...prev,
|
||||
[channelId]: {
|
||||
qrCode: response.qrCode,
|
||||
url: response.url || "",
|
||||
qrCode: response, // base64 图片数据
|
||||
url: h5Url, // H5链接(确保即使失败也有)
|
||||
loading: false,
|
||||
},
|
||||
}));
|
||||
@@ -104,13 +142,19 @@ const DistributionSettings: React.FC<DistributionSettingsProps> = ({
|
||||
throw new Error("二维码生成失败");
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 即使二维码生成失败,也要保留H5链接
|
||||
Toast.show({
|
||||
content: error.message || "生成二维码失败",
|
||||
position: "top",
|
||||
});
|
||||
setQrCodeMap(prev => ({
|
||||
...prev,
|
||||
[channelId]: { ...prev[channelId], loading: false },
|
||||
[channelId]: {
|
||||
...prev[channelId],
|
||||
qrCode: "", // 二维码为空
|
||||
url: h5Url, // H5链接保留
|
||||
loading: false,
|
||||
},
|
||||
}));
|
||||
}
|
||||
};
|
||||
@@ -673,63 +717,93 @@ const DistributionSettings: React.FC<DistributionSettingsProps> = ({
|
||||
<SpinLoading color="primary" style={{ fontSize: 32 }} />
|
||||
<div style={{ fontSize: 14, color: "#666" }}>生成二维码中...</div>
|
||||
</div>
|
||||
) : qrCodeMap[currentQrChannel.id]?.qrCode ? (
|
||||
) : (
|
||||
<>
|
||||
<img
|
||||
src={qrCodeMap[currentQrChannel.id].qrCode}
|
||||
alt="渠道二维码"
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
border: "1px solid #e5e6eb",
|
||||
borderRadius: 8,
|
||||
padding: 8,
|
||||
background: "#fff",
|
||||
}}
|
||||
/>
|
||||
{qrCodeMap[currentQrChannel.id].url && (
|
||||
{/* 二维码显示区域 */}
|
||||
{qrCodeMap[currentQrChannel.id]?.qrCode ? (
|
||||
<img
|
||||
src={qrCodeMap[currentQrChannel.id].qrCode}
|
||||
alt="渠道二维码"
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
border: "1px solid #e5e6eb",
|
||||
borderRadius: 8,
|
||||
padding: 8,
|
||||
background: "#fff",
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
padding: "40px 20px",
|
||||
color: "#999",
|
||||
}}>
|
||||
<QrcodeOutlined style={{ fontSize: 48 }} />
|
||||
<div style={{ fontSize: 14 }}>二维码生成失败</div>
|
||||
<Button
|
||||
size="small"
|
||||
color="primary"
|
||||
onClick={() => currentQrChannel && generateChannelQRCode(currentQrChannel.id, currentQrChannel.code)}
|
||||
>
|
||||
重新生成
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* H5链接展示 - 无论二维码是否成功都要显示 */}
|
||||
{qrCodeMap[currentQrChannel.id]?.url && (
|
||||
<div style={{
|
||||
width: "100%",
|
||||
padding: "12px",
|
||||
background: "#f5f5f5",
|
||||
borderRadius: 8,
|
||||
marginTop: 16,
|
||||
}}>
|
||||
<div style={{
|
||||
fontSize: 12,
|
||||
fontSize: 14,
|
||||
color: "#666",
|
||||
marginBottom: 8,
|
||||
fontWeight: 500,
|
||||
}}>
|
||||
链接地址
|
||||
H5链接
|
||||
</div>
|
||||
<div style={{
|
||||
fontSize: 12,
|
||||
color: "#333",
|
||||
wordBreak: "break-all",
|
||||
display: "flex",
|
||||
gap: 8,
|
||||
alignItems: "center",
|
||||
}}>
|
||||
{qrCodeMap[currentQrChannel.id].url}
|
||||
<Input
|
||||
value={qrCodeMap[currentQrChannel.id].url}
|
||||
readOnly
|
||||
style={{
|
||||
flex: 1,
|
||||
fontSize: 12,
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const link = qrCodeMap[currentQrChannel.id].url;
|
||||
navigator.clipboard.writeText(link);
|
||||
Toast.show({
|
||||
content: "链接已复制到剪贴板",
|
||||
position: "top",
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<CopyOutlined />
|
||||
复制
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
padding: "40px 20px",
|
||||
color: "#999",
|
||||
}}>
|
||||
<QrcodeOutlined style={{ fontSize: 48 }} />
|
||||
<div style={{ fontSize: 14 }}>二维码生成失败</div>
|
||||
<Button
|
||||
size="small"
|
||||
color="primary"
|
||||
onClick={() => currentQrChannel && generateChannelQRCode(currentQrChannel.id, currentQrChannel.code)}
|
||||
>
|
||||
重新生成
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -133,7 +133,7 @@ export const markAsPaid = async (
|
||||
return request(`/v1/distribution/withdrawals/${id}/mark-paid`, data, "POST");
|
||||
};
|
||||
|
||||
// 生成二维码
|
||||
// 生成渠道扫码创建二维码
|
||||
export const generateQRCode = async (
|
||||
type: "h5" | "miniprogram",
|
||||
): Promise<{
|
||||
@@ -143,3 +143,18 @@ export const generateQRCode = async (
|
||||
}> => {
|
||||
return request("/v1/distribution/channel/generate-qrcode", { type }, "POST");
|
||||
};
|
||||
|
||||
// 生成渠道登录二维码
|
||||
export const generateLoginQRCode = async (
|
||||
type: "h5" | "miniprogram" = "h5",
|
||||
): Promise<{
|
||||
type: "h5" | "miniprogram";
|
||||
qrCode: string; // base64 或图片URL
|
||||
url: string; // H5 或小程序落地页URL
|
||||
}> => {
|
||||
return request(
|
||||
"/v1/distribution/channel/generate-login-qrcode",
|
||||
{ type },
|
||||
"POST",
|
||||
);
|
||||
};
|
||||
|
||||
@@ -70,23 +70,11 @@ const AddChannelModal: React.FC<AddChannelModalProps> = ({
|
||||
}
|
||||
}, [editData, visible]);
|
||||
|
||||
// 当弹窗打开或切换到扫码创建时,自动生成二维码
|
||||
// 当弹窗打开时,如果是扫码创建模式,自动生成二维码
|
||||
useEffect(() => {
|
||||
// 只有在弹窗可见、非编辑模式、选择扫码方式、没有二维码数据、且不在加载中时才生成
|
||||
if (visible && !isEdit && createMethod === "scan" && !qrCodeData && !qrCodeLoading && !generatingRef.current) {
|
||||
// 使用 setTimeout 确保状态更新完成
|
||||
const timer = setTimeout(() => {
|
||||
handleGenerateQRCode();
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [visible, createMethod]);
|
||||
|
||||
// 当二维码类型变化时,重新生成二维码
|
||||
useEffect(() => {
|
||||
if (visible && !isEdit && createMethod === "scan" && qrCodeData && !qrCodeLoading && !generatingRef.current) {
|
||||
// 重置状态后重新生成
|
||||
// 弹窗打开时,如果是扫码创建模式,无论之前是否有数据都重新生成
|
||||
if (visible && !isEdit && createMethod === "scan" && !qrCodeLoading && !generatingRef.current) {
|
||||
// 重置状态后重新生成(无论之前是否有数据)
|
||||
setQrCodeData(null);
|
||||
setScanning(false);
|
||||
// 使用 setTimeout 确保状态更新完成
|
||||
@@ -96,7 +84,22 @@ const AddChannelModal: React.FC<AddChannelModalProps> = ({
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [qrCodeType]);
|
||||
}, [visible]);
|
||||
|
||||
// 当二维码类型变化时,重新生成二维码(无论之前是否成功或失败都要重新生成)
|
||||
useEffect(() => {
|
||||
if (visible && !isEdit && createMethod === "scan" && !qrCodeLoading && !generatingRef.current) {
|
||||
// 重置状态后重新生成(无论之前是否有数据)
|
||||
setQrCodeData(null);
|
||||
setScanning(false);
|
||||
// 使用 setTimeout 确保状态更新完成
|
||||
const timer = setTimeout(() => {
|
||||
handleGenerateQRCode();
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [qrCodeType, visible, createMethod]);
|
||||
|
||||
// 验证手机号格式
|
||||
const validatePhone = (phone: string): boolean => {
|
||||
@@ -213,20 +216,18 @@ const AddChannelModal: React.FC<AddChannelModalProps> = ({
|
||||
|
||||
// 当切换到扫码创建时,自动生成二维码
|
||||
useEffect(() => {
|
||||
if (visible && createMethod === "scan" && !isEdit && !qrCodeData && !qrCodeLoading) {
|
||||
handleGenerateQRCode();
|
||||
if (visible && createMethod === "scan" && !isEdit && !qrCodeLoading && !generatingRef.current) {
|
||||
// 重置状态后重新生成(无论之前是否有数据)
|
||||
setQrCodeData(null);
|
||||
setScanning(false);
|
||||
const timer = setTimeout(() => {
|
||||
handleGenerateQRCode();
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [createMethod, visible]);
|
||||
|
||||
// 当二维码类型变化时,重新生成二维码
|
||||
useEffect(() => {
|
||||
if (visible && createMethod === "scan" && !isEdit && qrCodeData) {
|
||||
handleGenerateQRCode();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [qrCodeType, visible]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={visible}
|
||||
|
||||
@@ -213,7 +213,8 @@ Route::group('v1/', function () {
|
||||
Route::put(':id', 'app\cunkebao\controller\distribution\ChannelController@update'); // 编辑渠道
|
||||
Route::delete(':id', 'app\cunkebao\controller\distribution\ChannelController@delete'); // 删除渠道
|
||||
Route::post(':id/toggle-status', 'app\cunkebao\controller\distribution\ChannelController@toggleStatus'); // 禁用/启用渠道
|
||||
Route::post('generate-qrcode', 'app\cunkebao\controller\distribution\ChannelController@generateQrCode'); // 生成渠道二维码
|
||||
Route::post('generate-qrcode', 'app\cunkebao\controller\distribution\ChannelController@generateQrCode'); // 生成渠道注册二维码
|
||||
Route::post('generate-login-qrcode', 'app\cunkebao\controller\distribution\ChannelController@generateLoginQrCode'); // 生成渠道登录二维码
|
||||
});
|
||||
// 提现申请管理
|
||||
Route::group('withdrawals', function () {
|
||||
|
||||
@@ -864,7 +864,7 @@ class ChannelController extends BaseController
|
||||
if ($type === 'h5') {
|
||||
// 生成H5二维码
|
||||
// 获取H5页面URL(需要根据实际项目配置)
|
||||
$h5BaseUrl = Env::get('h5.base_url', $this->request->domain());
|
||||
$h5BaseUrl = Env::get('rpc.H5_FORM_URL', 'https://h5.ckb.quwanzhi.com/#');
|
||||
// 确保URL格式正确(去除末尾斜杠)
|
||||
$h5BaseUrl = rtrim($h5BaseUrl, '/');
|
||||
$h5Url = $h5BaseUrl . '/pages/channel/add?token=' . urlencode($token);
|
||||
@@ -970,6 +970,144 @@ class ChannelController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成渠道登录二维码(H5或小程序码)
|
||||
* 通用登录二维码,不绑定特定渠道,用户扫码后输入手机号和密码登录
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function generateLoginQrCode()
|
||||
{
|
||||
try {
|
||||
// 获取参数
|
||||
$type = $this->request->param('type', 'h5'); // h5 或 miniprogram
|
||||
|
||||
$companyId = $this->getUserInfo('companyId');
|
||||
|
||||
// 参数验证
|
||||
if (!in_array($type, ['h5', 'miniprogram'])) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'success' => false,
|
||||
'msg' => '类型参数错误,必须为 h5 或 miniprogram',
|
||||
'data' => null
|
||||
]);
|
||||
}
|
||||
|
||||
// 生成登录token(只包含公司ID,有效期1小时)
|
||||
// 用户扫码后需要自己输入手机号和密码
|
||||
$tokenData = [
|
||||
'companyId' => $companyId,
|
||||
'expireTime' => time() + 3600 // 1小时后过期
|
||||
];
|
||||
$token = base64_encode(json_encode($tokenData));
|
||||
|
||||
if ($type === 'h5') {
|
||||
// 生成H5登录二维码
|
||||
$h5BaseUrl = Env::get('rpc.H5_FORM_URL', 'https://h5.ckb.quwanzhi.com/#');
|
||||
$h5BaseUrl = rtrim($h5BaseUrl, '/');
|
||||
// H5登录页面路径,需要根据实际项目调整
|
||||
$h5Url = $h5BaseUrl . '/pages/channel/login?token=' . urlencode($token);
|
||||
|
||||
// 生成二维码
|
||||
$qrCode = new QrCode($h5Url);
|
||||
$qrCode->setSize(300);
|
||||
$qrCode->setMargin(10);
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->setEncoding('UTF-8');
|
||||
$qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH);
|
||||
|
||||
// 转换为base64
|
||||
$qrCodeBase64 = 'data:image/png;base64,' . base64_encode($qrCode->writeString());
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'success' => true,
|
||||
'msg' => '生成H5登录二维码成功',
|
||||
'data' => [
|
||||
'type' => 'h5',
|
||||
'qrCode' => $qrCodeBase64,
|
||||
'url' => $h5Url
|
||||
]
|
||||
]);
|
||||
|
||||
} else {
|
||||
// 生成小程序登录码
|
||||
try {
|
||||
// 从环境变量获取小程序配置
|
||||
$miniProgramConfig = [
|
||||
'app_id' => Env::get('weChat.appidMiniApp', 'wx789850448e26c91d'),
|
||||
'secret' => Env::get('weChat.secretMiniApp', 'd18f75b3a3623cb40da05648b08365a1'),
|
||||
'response_type' => 'array'
|
||||
];
|
||||
|
||||
$app = Factory::miniProgram($miniProgramConfig);
|
||||
|
||||
// scene参数长度限制为32位,使用token的MD5值
|
||||
$scene = substr(md5($token), 0, 32);
|
||||
|
||||
// 调用接口生成小程序码
|
||||
// 小程序登录页面路径,需要根据实际项目调整
|
||||
$response = $app->app_code->getUnlimit($scene, [
|
||||
'page' => 'pages/channel/login', // 请确保小程序里存在该页面
|
||||
'width' => 430,
|
||||
]);
|
||||
|
||||
// 成功时返回的是 StreamResponse
|
||||
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
|
||||
$img = $response->getBody()->getContents();
|
||||
$imgBase64 = 'data:image/png;base64,' . base64_encode($img);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'success' => true,
|
||||
'msg' => '生成小程序登录码成功',
|
||||
'data' => [
|
||||
'type' => 'miniprogram',
|
||||
'qrCode' => $imgBase64,
|
||||
'scene' => $scene,
|
||||
'token' => $token
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// 如果不是流响应,而是数组(错误信息),则解析错误返回
|
||||
if (is_array($response) && isset($response['errcode']) && $response['errcode'] != 0) {
|
||||
$errMsg = isset($response['errmsg']) ? $response['errmsg'] : '微信接口返回错误';
|
||||
return json([
|
||||
'code' => 500,
|
||||
'success' => false,
|
||||
'msg' => '生成小程序登录码失败:' . $errMsg,
|
||||
'data' => $response
|
||||
]);
|
||||
}
|
||||
|
||||
// 其他未知格式
|
||||
return json([
|
||||
'code' => 500,
|
||||
'success' => false,
|
||||
'msg' => '生成小程序登录码失败:响应格式错误',
|
||||
'data' => $response
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return json([
|
||||
'code' => 500,
|
||||
'success' => false,
|
||||
'msg' => '生成小程序登录码失败:' . $e->getMessage(),
|
||||
'data' => null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
return json([
|
||||
'code' => $e->getCode() ?: 500,
|
||||
'success' => false,
|
||||
'msg' => '生成登录二维码失败:' . $e->getMessage(),
|
||||
'data' => null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码提交渠道信息(H5和小程序共用)
|
||||
* GET请求:返回预填信息
|
||||
|
||||
Reference in New Issue
Block a user