Browse Source

feat(hygl): 添加微信小程序二维码生成功能

- 新增重新生成微信小程序二维码的 API 接口和前端功能
- 在配置页面添加微信小程序二维码相关字段和操作按钮
- 实现微信小程序二维码生成和保存的后端逻辑
- 优化 H5站点二维码生成流程,增加缺失信息提示
master
liutong 1 year ago
parent
commit
8fd549110c
  1. 7
      admin/src/addon/hygl/api/config.ts
  2. 47
      admin/src/addon/hygl/views/config/config.vue
  3. 14
      niucloud/addon/hygl/app/adminapi/controller/config/Config.php
  4. 2
      niucloud/addon/hygl/app/adminapi/route/route.php
  5. 163
      niucloud/addon/hygl/app/service/admin/config/ConfigService.php

7
admin/src/addon/hygl/api/config.ts

@ -55,6 +55,13 @@ export function resetH5SiteQRCode(id: number) {
return request.get(`hygl/config/resetH5SiteQRCode/${id}`);
}
/**
*
* @param id
*/
export function resetMiniAppQRCode(id: number) {
return request.get(`hygl/config/resetMiniAppQRCode/${id}`);
}
// USER_CODE_END -- hygl_config

47
admin/src/addon/hygl/views/config/config.vue

@ -23,7 +23,7 @@
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayMiniappId')">
<el-form-item :label="t('weChatPayMiniappId')" prop="we_chat_pay_miniapp_id">
<el-input v-model="formData.we_chat_pay_miniapp_id" clearable
:placeholder="t('weChatPayMiniappIdPlaceholder')" class="input-width"/>
</el-form-item>
@ -37,12 +37,12 @@
<el-input v-model="formData.we_chat_pay_key" clearable :placeholder="t('weChatPayKeyPlaceholder')"
class="input-width"/>
</el-form-item>
<!--
<el-form-item :label="t('weChatPayMiniappSecret')">
<el-form-item :label="t('weChatPayMiniappSecret')" prop="we_chat_pay_miniapp_secret">
<el-input v-model="formData.we_chat_pay_miniapp_secret" clearable
:placeholder="t('weChatPayMiniappSecretPlaceholder')" class="input-width"/>
</el-form-item>
-->
<el-form-item :label="t('weChatPayNotifyUrl')" prop="we_chat_pay_notify_url">
<el-input disabled="true" v-model="formData.we_chat_pay_notify_url" clearable
:placeholder="t('weChatPayNotifyUrlPlaceholder')" class="input-width"/>
@ -103,7 +103,7 @@
<el-form-item v-if="formData.ol_h5_qrcode_url" :label="t('原始H5站点二维码')" prop="h5_qrcode_url">
<div>
<p style="color: red;">重新生成二维码后->点击"保存"将替换此二维码</p>
<img :src="formData.ol_h5_qrcode_url" alt="">
<img :src="formData.ol_h5_qrcode_url" alt="" style="width:205px;height:205px;">
<a :href="formData.ol_h5_qrcode_url" target="downloadFile" download="h5_qrcode.png">
<el-button type="primary">打开二维码</el-button>
</a>
@ -120,13 +120,13 @@
<el-form-item :label="t('微信小程序二维码')" prop="miniapp_qrcode_url">
<el-input disabled="true" v-model="formData.miniapp_qrcode_url" clearable :placeholder="t('微信小程序二维码')"
class="input-width"/>
<el-button style="margin-left: 15px;" type="primary" @click="resetMiniAppQrCode()">{{ t('重新生成二维码') }}</el-button>
<el-button style="margin-left: 15px;" type="primary" @click="resetMiniAppQRCodeImg()">{{ t('重新生成二维码') }}</el-button>
</el-form-item>
<el-form-item v-if="formData.ol_miniapp_qrcode_url" :label="t('原始微信小程序二维码')" prop="miniapp_qrcode_url">
<div>
<p style="color: red;">重新生成二维码后->点击"保存"将替换此二维码</p>
<img :src="formData.ol_miniapp_qrcode_url" alt="">
<img :src="formData.ol_miniapp_qrcode_url" alt="" style="width:205px;height:205px;">
<a :href="formData.ol_miniapp_qrcode_url" target="downloadFile" download="miniapp_qrcode.png">
<el-button type="primary">打开二维码</el-button>
</a>
@ -151,7 +151,7 @@ import {ref, reactive, computed, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import type {FormInstance} from 'element-plus'
import {getConfigInfo, addConfig, editConfig, getConfigList, resetH5SiteQRCode,} from '@/addon/hygl/api/config';
import {getConfigInfo, addConfig, editConfig, getConfigList, resetH5SiteQRCode,resetMiniAppQRCode} from '@/addon/hygl/api/config';
import {useRoute} from 'vue-router'
import {ElMessage} from 'element-plus'
import {uploadFile} from "@/addon/hygl/api/common";
@ -183,6 +183,10 @@ const initialFormData = {
h5_site_url:'',
h5_qrcode_url:'',
ol_h5_qrcode_url:'',
miniapp_site_url:'',
miniapp_qrcode_url:'',
ol_miniapp_qrcode_url:'',
}
const formData: Record<string, any> = reactive({...initialFormData})
@ -327,7 +331,7 @@ const back = () => {
history.back()
}
//
//H5
const resetQrCode = async () => {
let data = formData
@ -350,6 +354,31 @@ const resetQrCode = async () => {
}
//
const resetMiniAppQRCodeImg = async () => {
let data = formData
if (!data.id || !data.we_chat_pay_miniapp_id || !data.we_chat_pay_miniapp_secret) {
ElMessage({
message: '请先填写必要信息并点击保存后再试',
type: 'warning',
})
return
}
let aa = resetMiniAppQRCode(data.id).then(res => {
if (res.code){
formData.miniapp_qrcode_url = res.data.url
}
// history.back()
}).catch(err => {
console.log(err)
})
}
//()
const handleFileUpload = (event: Event, name: string, path: string) => {
const fileInput = event.target as HTMLInputElement;

14
niucloud/addon/hygl/app/adminapi/controller/config/Config.php

@ -56,6 +56,20 @@ class Config extends BaseAdminController
return success($res);
}
/**
* 重新生成H5站点二维码
* @param int $id
* @return \think\Response
*/
public function resetMiniAppQRCode(int $id){
$qrcode = (new ConfigService())->resetMiniAppQRCode($id);
$res = [
'url'=>$qrcode['url'],
'ol_url'=>$qrcode['ol_url']
];
return success($res);
}
/**
* 添加配置项
* @return \think\Response

2
niucloud/addon/hygl/app/adminapi/route/route.php

@ -90,6 +90,8 @@ Route::group('hygl', function () {
Route::get('config/:id', 'addon\hygl\app\adminapi\controller\config\Config@info');
//配置项-重新生成H5站点二维码
Route::get('config/resetH5SiteQRCode/:id', 'addon\hygl\app\adminapi\controller\config\Config@resetH5SiteQRCode');
//配置项-重新生成微信小程序二维码
Route::get('config/resetMiniAppQRCode/:id', 'addon\hygl\app\adminapi\controller\config\Config@resetMiniAppQRCode');
//添加配置项
Route::post('config', 'addon\hygl\app\adminapi\controller\config\Config@add');
//编辑配置项

163
niucloud/addon/hygl/app/service/admin/config/ConfigService.php

@ -17,6 +17,7 @@ use app\model\dict\Dict;
use core\base\BaseAdminService;
use dh2y\qrcode\QRcode;
use http\Url;
use think\File;
/**
@ -54,7 +55,7 @@ class ConfigService extends BaseAdminService
*/
public function getInfo(int $id)
{
$field = 'id,site_id,h5_qrcode_url,we_chat_pay_appid,we_chat_pay_app_id,we_chat_pay_miniapp_id,we_chat_pay_mch_id,we_chat_pay_key,we_chat_pay_miniapp_secret,we_chat_pay_notify_url,alipay_appId,alipay_rsa_private_key,alipay_public_key,alipay_notify_url,create_time,update_time,delete_time,we_chat_pay_mch_secret_cert,we_chat_pay_mch_public_cert_path,h5_site_url';
$field = 'id,site_id,h5_qrcode_url,we_chat_pay_appid,we_chat_pay_app_id,we_chat_pay_miniapp_id,we_chat_pay_mch_id,we_chat_pay_key,we_chat_pay_miniapp_secret,we_chat_pay_notify_url,alipay_appId,alipay_rsa_private_key,alipay_public_key,alipay_notify_url,create_time,update_time,delete_time,we_chat_pay_mch_secret_cert,we_chat_pay_mch_public_cert_path,h5_site_url,miniapp_site_url,miniapp_qrcode_url';
$info = $this->model->field($field)->where('site_id', '=', $this->site_id)->findOrEmpty()->toArray();
@ -68,18 +69,38 @@ class ConfigService extends BaseAdminService
->value('dictionary');
$h5_site_url = json_decode($dictionary, true)[0]['value'];
$data['h5_site_url'] = "{$h5_site_url}?site_id={$this->site_id}";//h5站点地址
$data['miniapp_site_url'] = "pages/wxPay/index?site_id={$this->site_id}";//微信小程序跳转路径
$we_chat_pay_notify_url = Dict::where('key', 'we_chat_pay_notify_url')
->value('dictionary');//微信支付异步回调根路径
$we_chat_pay_notify_url = json_decode($we_chat_pay_notify_url, true)[0]['value'];
$data['we_chat_pay_notify_url'] = "{$we_chat_pay_notify_url}/{$this->site_id}";//微信异步回调地址
$qRCode = $this->createUrlQRCode($data['h5_site_url']);//生成二维码
$qRCode = $this->createUrlQRCode($data['h5_site_url']);//生成H5二维码
$data['h5_qrcode_url'] =$qRCode['url'];
$this->add($data);
$info = $data;
}
if($info['miniapp_site_url'] && !$info['miniapp_qrcode_url'] && $info['we_chat_pay_miniapp_id'] && $info['we_chat_pay_miniapp_secret']){
$mini_qRCode = $this->createMiniappQrcodeUrl($info['we_chat_pay_miniapp_id'], $info['we_chat_pay_miniapp_secret'], $info['miniapp_site_url']);//生成微信小程序二维码
if($mini_qRCode['url']){
$info['miniapp_qrcode_url'] = $mini_qRCode['url'];
$this->edit([
'miniapp_qrcode_url'=>$mini_qRCode['url']
]);
}
}
$info['ol_miniapp_qrcode_url'] = '';
if (!empty($info['miniapp_qrcode_url'])){
$info['ol_miniapp_qrcode_url'] = get_file_url($info['miniapp_qrcode_url']);
}
$info['ol_h5_qrcode_url'] = '';
if (!empty($info['h5_qrcode_url'])){
$info['ol_h5_qrcode_url'] = get_file_url($info['h5_qrcode_url']);
@ -123,6 +144,144 @@ class ConfigService extends BaseAdminService
];
}
/**
* 重新生成微信小程序二维码
* @param int $id
* @return array
*/
public function resetMiniAppQRCode(int $id)
{
//查询站点
$info = Config::where('id',$id)->field('id,miniapp_site_url,we_chat_pay_miniapp_id,we_chat_pay_miniapp_secret')->find();
if (!$info['miniapp_site_url'] || !$info['we_chat_pay_miniapp_id'] || !$info['we_chat_pay_miniapp_secret']){
return [
'msg'=>'缺少必填参数',
'url' => '',
'ol_url' => ''
];
}
$res = $this->createMiniappQrcodeUrl($info['we_chat_pay_miniapp_id'],$info['we_chat_pay_miniapp_secret'],$info['miniapp_site_url']);
return $res;
}
/**
* 生成微信小程序二维码
* @param string $appid 微信小程序appid
* @param string $secret 微信小程序secret
* @param string $path 例如$path = "pages_tool/login/register?age=18"
* @return string
* @throws \Exception
*/
private function createMiniappQrcodeUrl(string $appid, string $secret, string $path)
{
$accessToken = $this->getMiniAppAccessToken($appid, $secret);
if (empty($accessToken)) {
return [
'msg'=>'无法获取accessToken',
'url' => '',
'ol_url' => ''
];
}
$width = 430; // 二维码宽度,默认430px
$codeUrl = "https://api.weixin.qq.com/wxa/getwxacode?access_token=$accessToken";
$postData = json_encode([
'path' => $path,
'width' => $width,
'is_hyaline' => false // 是否透明底色
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $codeUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 仅用于调试,生产环境不建议
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 仅用于调试,生产环境不建议
$qr_code_response = curl_exec($ch);
if ($qr_code_response === false) {
$curl_error = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [
'url' => '',
'ol_url' => ''
];
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode != 200) {
curl_close($ch);
return [
'url' => '',
'ol_url' => ''
];
}
curl_close($ch);
// 创建临时文件并将二维码内容写入
$tempFilePath = tempnam(sys_get_temp_dir(), 'qr_');
if (file_put_contents($tempFilePath, $qr_code_response) === false) {
return [
'url' => '',
'ol_url' => ''
];
}
// 创建 File 对象
$file = new File($tempFilePath);
// 定义保存路径和文件名
$filename = time() . '_xcxcode.png'; // 使用时间戳确保文件名唯一
$site_id = $this->site_id;
$date = date('Y_m_d');
$save_path = "addon/hygl/upload/config_miniapp_qrcode_url/{$site_id}/{$date}"; // 文件保存的路径
// 确保目标目录存在且可写
if (!is_dir($save_path)) {
if (!mkdir($save_path, 0755, true)) {
return [
'url' => '',
'ol_url' => ''
];
}
}
$info = $file->move($save_path, $filename);
if ($info) {
// 返回保存成功的消息和文件路径
$url = "{$save_path}/$filename";
return [
'url' => $url,
'ol_url' => get_file_url($url)
];
} else {
// 返回失败消息
return [
'url' => '',
'ol_url' => ''
];
}
}
//微信小程序生成access_token
private function getMiniAppAccessToken($appId, $appSecret) {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
$response = file_get_contents($url);
$data = json_decode($response, true);
$access_token = '';
if (isset($data['access_token'])) {
$access_token = $data['access_token'];
}
return $access_token;
}
/**
* 添加配置项
* @param array $data

Loading…
Cancel
Save