微信分享前端开发全程详解含iOS、安卓、H5、ReactNative以及微信开放标签的适配和使用

微信订阅消息接入 使用开放标签 在 H5网页设置订阅通知组件 背景 “服务号订阅通知灰度测试期自2021年1月27日0:00至4月30日24:00,期间服务号模板消息可正常使用;灰度测试期结束后服务号订阅通知的策略将另行公布,届时以官方信息为准” 参考链接:https://developers.weixin.qq.com/community/develop/doc/000a4e1df800d82acb9b7fb5e5b001?page=4#comment-list 订阅消息开始灰度测试 为了在服务号模板消息发生不可预知的改变之后能迅速切换到订阅消息,最大限度降低对现有 阅读详情

2024年9月,本人在做微信分享前端部分的iOS、安卓和H5的页面和功能时踩了不少坑,于是写了这篇文章,内容包括微信分享在上面三个端的技术点和坑点、解决办法,微信开放标签的相关适配,以及ReactNative的特别处理部分。

原文链接:http://www.kovli.com/2024/12/18/wx-share/

作者:Kovli

重要通知:红宝书第5版2024年12月1日出炉了,感兴趣的可以去看看,https://u.jd.com/8alDI4w

一、前期准备:微信开放平台、微信公众平台注册并审核通过

1、微信开放平台入口
2、微信公众平台入口
3、官网域名,分享用网页的域名(可以是二级域名)部署完成,ICP备案完成。
Tip1:微信开放平台认证一次性的三百。公众平台首次认证三百,认证到期后每年需要再年审三百。平台网页:https://developers.weixin.qq.com/community/develop/doc/000c040991c220d8dcea6324e56000
Tip2:官网域名用于iOS的Universal Links,分享用网页的域名用于放到js接口安全域名里面,凡是在js接口安全域名里的网页在微信里打开都可以使用开放标签和对应的微信js接口。后面会说怎么放。
Tip3:注册和申请这两个平台的同时,移动应用也添加和关联进去,后面要用到APPID,另外移动应用需要开启微信分享功能,详见文档。

二、客户端SDK集成:

1、友盟分享集成 开发文档
2、微信官网自行集成 开发文档
本人用的是友盟分享集成,也可以微信官网自行集成,如果友盟分享已经集成了那至少微信文档里SDK的集成这一步已经完成了。
不要遗漏文档里任何一处,以免后面遇到不该遇到的坑。
注意iOS需要配置Universal Links:参考文档

有个需要服务端或运维小伙伴配合的步骤,就是创建个文件名为apple-app-site-association的文件,没有后缀,里面的内容如下,

根据自己的参数来修改里面appID和paths的内容
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID":"苹果teamID.com.aaa.bbb"
                "paths": ["/app/*"]
            }
        ]
    }
}

然后让后端或者运维小伙伴,把这个文件放在官网的服务器根目录下。

比如服务器地址是: https://www.baidu.com/ ,把文件放在这根目录下后,访问 https://www.baidu.com/apple-app-site-association ,这文件就会被下载下来。
然后根目录新建一个.well-known文件夹,里面也放一份这个文件,这样会先去根目录找,如果没找到还会去.well-known文件夹找

三、微信分享H5页面开发(本人用的是Vue2)

H5开发需要适配两个端:手机浏览器端和微信浏览器端
1、手机浏览器的适配比较简单,跳转APP采用Schema逻辑(iOS和安卓均可)。
H5
// 打开app 目前采用的方法 用于适配非微信端打开的网页跳转app并传参
openApp() {
    const sendInfo = {
        key: value
    }
    const schemaInfo = JSON.stringify(sendInfo)
    const appScheme = 'yourSchema://yourshare域名/pagePath?schemaInfo=' + schemaInfo // 替换为你的 app 的 URL scheme
    const fallbackUrl = '应用宝链接' // 替换为你的 app 在应用商店的链接


    const u = navigator.userAgent
    const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
    if (isiOS) {
        window.location.href = appScheme // ios对应的app协议
        setTimeout(function () {
            let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden || window.document.webkitHidden
            if (typeof hidden === 'undefined' || hidden == false) {
                // App store下载地址
                window.location.href = fallbackUrl
            }
        }, 500)
    } else {
        window.location.href = appScheme // 安卓对应的app协议
        setTimeout(function () {
            let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden || window.document.webkitHidden
            if (typeof hidden === 'undefined' || hidden == false) {
                // 应用宝下载地址
                window.location.href = fallbackUrl
            }
        }, 1500)
    }
},
2、微信浏览器端的适配,需要使用微信的开放标签来处理H5和APP的跳转逻辑
微信开放标签:
1、绑定域名加入JS接口安全域名
登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
2、使用前需将「 JS 接口安全域名绑定的服务号」绑定在「移动应用的微信开放平台账号」下,并确保服务号与此开放平台账号同主体且均已认证。请前往 微信开放平台-管理中心-公众号详情-接口信息 设置域名与所需跳转的移动应用。
具体流程参考这篇说明文档:

https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_H5_Launch_APP.html

3、根据开发文档开发适配微信端网页开放标签,具体流程参考这篇文档:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html

注意:
1、安全角度考虑,下面这段所需的参数从服务器接口获取,不要放前端
wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [], // 必填,需要使用的JS接口列表
  openTagList: [] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
});

2、网页的域名和审核通过的js安全域名Host完全一致 + 第一点里面的config初始化成功 + 要在微信里面打开此网页 = 能显示微信开放标签里的内容且点击能跳转到APP,缺一不可
3、开放标签里放不了本地的图,本地的图可以上传到oss上生成链接的形式展示
<wx-open-launch-app
            v-if="iswx"
            id="launch-btn"
            style="width:100%; position: relative; display: flex; flex-direction: row; align-items: center; justify-content: center;height: 44px; background-color: #F7F8FA"
            :extinfo="getSchemaInfo"
            appid="yourWxAppId"
            @error="handleError"
            @launch="handleLaunch"
        >
            <component is="script" type="text/wxtag-template">
                <div style="position: relative; display: flex; flex-direction: row; align-items: center; justify-content: center; height: 44px"
                     @click="onButtonClick">
                    <div style="font-size: 14px; font-weight: 400; color: #388BFF; line-height: 20px; text-align: center">固定在底部的条条</div>
                    <img style="width: 14px; height: 14px; margin-left: 4px;" src="https://yourResources.oss-cn-hangzhou.aliyuncs.com/yourPic.png" alt="">
                </div>
            </component>
        </wx-open-launch-app>
4、开放标签里不能使用postion为fixed和absolute的样式,无效,如果需要可以在开放标签里设置style,加fixed或absolute

参考5里面的代码

5、一个取巧的办法是开放标签可以是透明的盖住普通浏览器样式的页面组件,实现微信端点击跳转APP且无需适配开放标签里面的样式
<wx-open-launch-app
      v-if="iswx"
      id="launch-btn"
      style="max-width: 100%; height: 68px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #F1F2F4; position: fixed; top: 0; left: 0; right: 0; width: 100%; margin: auto; z-index: 99;"
      @error="handleError"
      @launch="handleLaunch"
      :extinfo="getSchemaInfo"
      appid="yourWxAppId"
  >
    <script type="text/wxtag-template">
      <div style="opacity: 0; width: 100%; height: 68px;"></div>
    </script>
  </wx-open-launch-app>
6 也可以根据网页是否在微信里打开的来进一步适配浏览器和微信的页面

如上的代码里有个iswx

let ua = window.navigator.userAgent.toLowerCase()
// 通过正则表达式匹配ua中是否含有MicroMessenger字符串
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
    this.iswx = true
} else {
    this.iswx = false
}

四、客户端处理跳转逻辑

参考开发文档

1、安卓部分 - 浏览器通过schema跳转
安卓 MainActivity.java文件里
  @Override
  public void onNewIntent(Intent intent){
    super.onNewIntent(intent);
    setIntent(intent);
  }
  
  @Override
  protected void onResume() {
    super.onResume();
    Intent intent = getIntent();

    if (!intentHex.equals("") && intentHex.equals(Integer.toHexString(System.identityHashCode(intent)))) {
      // 获取 scheme 名称 重复的intent 不予处理
    } else {
      intentHex = Integer.toHexString(System.identityHashCode(intent));
      String scheme = intent.getScheme();
      Uri uri = intent.getData();
      if(scheme!= null && uri != null) {
        if (uri.getScheme().equals("yourSchema")) {
          String schemaInfo = uri.getQueryParameter("schemaInfo");
          try {
            // 原生的可以处理跳转逻辑,ReactNative的这里可以发送到RN端
            MainApplication application = (MainApplication) this.getApplicationContext();

            WritableMap map = Arguments.createMap();
            map.putString("schemaInfo", schemaInfo);

            ReactInstanceManager reactInstanceManager = application.getReactNativeHost().getReactInstanceManager();
            ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
            if(reactContext != null) {
              reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("Demo_EmitterKey", map);
            } else {
              reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
                @Override
                public void onReactContextInitialized(ReactContext context) {

                  Handler handler = new Handler();
                  handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                      /**
                       *要执行的操作
                       */

                      context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("Demo_EmitterKey", map);
                    }
                  }, 4000);//4秒后执行Runnable中的run方法

                  reactInstanceManager.removeReactInstanceEventListener(this);

                }
              });
            }

          } catch (SecurityException e) {

            // TODO: Display a yellow box about this
          }

        }
      }
    }


  }
安卓部分 - 微信页面通过开放标签跳转

在WXEntryActivity文件里

/**
     * 从微信启动App
     *
     * @param req
     */
    @Override
    public void onReq(BaseReq req) {
        super.onReq(req);

        //获取开放标签传递的extinfo数据逻辑
        try {
            if (req.getType() == ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX && req instanceof ShowMessageFromWX.Req) {
                ShowMessageFromWX.Req showReq = (ShowMessageFromWX.Req) req;
                WXMediaMessage mediaMsg = showReq.message;
                String extInfo = mediaMsg.messageExt;
                // 原生这里已经可以处理跳转逻辑了
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
2、iOS部分 - 浏览器通过schema跳转

参考这篇帖子

iOS AppDelete.mm文件里
// 支持所有iOS系统
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url sourceApplication:sourceApplication annotation:annotation];
    if (!result) {
         // 其他如支付等SDK的回调
    }


      //开启SDK Log
      [WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
          NSLog(@"WeChatSDK: %@", log);
      }];

      // 在调用WXApi的handle方法前,须先调用registerApp注册。ret为注册结果,若注册失败,请根据sdk的log排查原因
      BOOL ret = [WXApi registerApp:@"微信的AppID" universalLink:@"https://your域名/app/"];

      if ([WXApi handleOpenURL:url delegate:self]) {
          /// handled by OpenSDK
      }
      
      // 上面做了微信开放标签的适配

     

  if ([[url scheme] isEqualToString:@"yourSchema"]) {
    NSString *inputString = [url query];
    // 找到等号的位置
    NSUInteger equalSignIndex = [inputString rangeOfString:@"="].location;
    if (equalSignIndex != NSNotFound) {
        // 提取等号后面的字符串
        NSString *schemaInfo = [inputString substringFromIndex:equalSignIndex + 1];

        NSLog(@"schemaInfo: %@", schemaInfo);

      if (![schemaInfo isEqualToString:@""]) {
        NSDictionary *schemaInfoDic = @{@"schemaInfo":schemaInfo};


        //这里原生的就可以跳转了,ReactNative的则把消息全部转给JS
        NSMutableDictionary *mutableDic = [NSMutableDictionary dictionaryWithDictionary:schemaInfoDic];

        //把消息全部转给JS
        [[NSNotificationCenter defaultCenter] postNotificationName:@"SendSchemaInfoToRN" object:mutableDic?mutableDic:@{}];
      } else {
          NSLog(@"empty schemaInfo");
      }
    } else {
        NSLog(@"No '=' found.");
    }
  }

    return result;
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
    BOOL result = [[UMSocialManager defaultManager]  handleOpenURL:url options:options];
    if (!result) {
        // 其他如支付等SDK的回调
    }

  //开启SDK Log
      [WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
          NSLog(@"WeChatSDK: %@", log);
      }];

      // 在调用WXApi的handle方法前,须先调用registerApp注册。ret为注册结果,若注册失败,请根据sdk的log排查原因
      BOOL ret = [WXApi registerApp:@"微信的Appid" universalLink:@"https://your域名/app/"];

      if ([WXApi handleOpenURL:url delegate:self]) {
          /// handled by OpenSDK
      }


      // 上面做了微信开放标签的适配


  if ([[url scheme] isEqualToString:@"yourSchema"]) {
    NSString *inputString = [url query];
    // 找到等号的位置
    NSUInteger equalSignIndex = [inputString rangeOfString:@"="].location;
    if (equalSignIndex != NSNotFound) {
        // 提取等号后面的字符串
        NSString *schemaInfo = [inputString substringFromIndex:equalSignIndex + 1];

        NSLog(@"schemaInfo: %@", schemaInfo);


      if (![schemaInfo isEqualToString:@""]) {
        NSDictionary *schemaInfoDic = @{@"schemaInfo":schemaInfo};

        //这里原生的就可以跳转了,ReactNative的则把消息全部转给JS
        NSMutableDictionary *mutableDic = [NSMutableDictionary dictionaryWithDictionary:schemaInfoDic];

        //把消息全部转给JS
        [[NSNotificationCenter defaultCenter] postNotificationName:@"SendSchemaInfoToRN" object:mutableDic?mutableDic:@{}];
      } else {
          NSLog(@"empty schemaInfo.");
      }
    } else {
        NSLog(@"No '=' found.");
    }
  }


    return result;
}
iOS部分 - 微信页面通过开放标签跳转

在通过Schema跳转的代码基础上,加上下面这段

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
{
    if (![[UMSocialManager defaultManager] handleUniversalLink:userActivity options:nil]) {
        // 其他SDK的回调
      NSLog ( @"其他SDK的回调11");
    }
    NSLog ( @"其他SDK的回调22");

  //开启SDK Log
      [WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
          NSLog(@"WeChatSDK: %@", log);
      }];

  // 在调用WXApi的handle方法前,须先调用registerApp注册。ret为注册结果,若注册失败,请根据sdk的log排查原因
  BOOL ret = [WXApi registerApp:@"微信的Appid" universalLink:@"https://your域名/app/"];
      if ([WXApi handleOpenUniversalLink:userActivity delegate:self]) {
          /// handled by OpenSDK
      }


  // 触发回调方法
    [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
    NSURL *url = userActivity.webpageURL;
    if (url && [TencentOAuth CanHandleUniversalLink:url]) {
      return [TencentOAuth HandleUniversalLink:url];
    }


    return YES;
}



-(void) onReq:(BaseReq*)req
{
    if([req isKindOfClass:[GetMessageFromWXReq class]])
    {
        // 微信请求App提供内容, 需要app提供内容后使用sendRsp返回
        NSString *strTitle = [NSString stringWithFormat:@"微信请求App提供内容"];
        NSString *strMsg = @"微信请求App提供内容,App要调用sendResp:GetMessageFromWXResp返回给微信";

    }
    else if([req isKindOfClass:[ShowMessageFromWXReq class]])
    {
        ShowMessageFromWXReq* temp = (ShowMessageFromWXReq*)req;
        WXMediaMessage *msg = temp.message;

        //显示微信传过来的内容
        WXAppExtendObject *obj = msg.mediaObject;

        NSString *strTitle = [NSString stringWithFormat:@"微信请求App显示内容"];
        NSString *strMsg = [NSString stringWithFormat:@"标题:%@ \n内容:%@ \n附带信息:%@ \n缩略图:%u bytes\n\n", msg.title, msg.description, obj.extInfo, msg.thumbData.length];

    }
    else if([req isKindOfClass:[LaunchFromWXReq class]])
    {
        //从微信启动App
      LaunchFromWXReq* temp = (LaunchFromWXReq*)req;
      WXMediaMessage *msg = temp.message;


      NSLog ( @"req:%@", msg.messageExt);


      NSDictionary *schemaInfoDic = @{@"schemaInfo":msg.messageExt};


      //把消息全部转给JS
      NSMutableDictionary *mutableDic = [NSMutableDictionary dictionaryWithDictionary:schemaInfoDic];

      NSLog(@"Schema 收到微信回调参数 #####%@",mutableDic);


      //把消息全部转给JS
      [[NSNotificationCenter defaultCenter] postNotificationName:@"SendSchemaInfoToRN" object:mutableDic?mutableDic:@{}];
    }
}
3、ReactNative的特殊处理
ReactNative在获取到浏览器或者微信传来的ScehmaInfo后,发送消息到JS的操作在前面的代码里都写进去了,可以看对应的注释。
安卓由于ReactNative就一个MainActivity,拿到微信传过来的数据后还需要特殊处理。

在WXEntryActivity文件里

/**
     * 从微信启动App
     *
     * @param req
     */
    @Override
    public void onReq(BaseReq req) {
        super.onReq(req);

        //获取开放标签传递的extinfo数据逻辑
        try {
            if (req.getType() == ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX && req instanceof ShowMessageFromWX.Req) {
                ShowMessageFromWX.Req showReq = (ShowMessageFromWX.Req) req;
                WXMediaMessage mediaMsg = showReq.message;
                String extInfo = mediaMsg.messageExt;
                
                // 原生这里已经可以处理跳转逻辑了,ReactNative需要特殊处理下,判断MainActivity是否存在,也就是说APP是否处于杀死状态

                if (ActivityUtils.isActivityExistsInStack(MainActivity.class)) {
                    // 发送到RN端
                    MainApplication application = (MainApplication) this.getApplicationContext();

                    WritableMap map = Arguments.createMap();
                    map.putString("schemaInfo", extInfo);

                    ReactInstanceManager reactInstanceManager = application.getReactNativeHost().getReactInstanceManager();
                    ReactContext reactContext = reactInstanceManager.getCurrentReactContext();

                    if (reactContext != null) {
                        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("Demo_EmitterKey", map);
                    } else {
                        reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
                            @Override
                            public void onReactContextInitialized(ReactContext context) {

                                Handler handler = new Handler();
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        /**
                                         *要执行的操作
                                         */
                                       context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("Demo_EmitterKey", map);
                                    }
                                }, 4000);//4秒后执行Runnable中的run方法
                                 reactInstanceManager.removeReactInstanceEventListener(this);

                            }
                        });
                    }
                } else {
                // 如果APP处于启动状态,则到MainActivity里处理逻辑
                    Intent intent = new Intent(this, MainActivity.class);
                    intent.putExtra("keySendToMainActivity", extInfo);
                    startActivity(intent);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

在MainActivity文件里

@Override
  protected void onCreate(Bundle savedInstanceState) {
    MainApplication.getInstance().setMainActivity(this);
    super.onCreate(null);
    
    ...
    
    // 这里加上这些内容
    if (getIntent().getStringExtra("keySendToMainActivity") != null && !"".equals(getIntent().getStringExtra("keySendToMainActivity"))) {
      // 发送到RN端
      MainApplication application = (MainApplication) this.getApplicationContext();

      WritableMap map = Arguments.createMap();
      map.putString("schemaInfo", getIntent().getStringExtra("keySendToMainActivity"));

      ReactInstanceManager reactInstanceManager = application.getReactNativeHost().getReactInstanceManager();
      ReactContext reactContext = reactInstanceManager.getCurrentReactContext();

      if(reactContext != null) {
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("Demo_EmitterKey", map);
      } else {
        reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
          @Override
          public void onReactContextInitialized(ReactContext context) {

            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
              @Override
              public void run() {
                /**
                 *要执行的操作
                 */

                context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("Demo_EmitterKey", map);
              }
            }, 4000);//4秒后执行Runnable中的run方法
            reactInstanceManager.removeReactInstanceEventListener(this);
          }
        });
      }
    }
  }
iOS分享到微信,配置Universal Links,并从微信打开app,跳转到指定界面 需要替换为你自己的域名)。浏览器打开后,会看到我们刚才配置的apple-app-site-association文件内容,如果不能,则需要查看文件目录是否正确,网络是否支持外网,服务器是否拦截。iOS分享到微信之后,需要从微信浏览器直接打开app,跳转到指定界面,这个时候最主要的就是分以下几步(微信sdk集成就不说了)Associated Domains可以设置多个,格式是:applinks: + 服务器域名(域名即可,例如完整链接是。* 表示通用链接,即只要域名正确,可以直接命中,一般不建议直接使用。 阅读详情

相关推荐

uniApp开发微信公众号H5的时候,使用微信开放标签wx-open-subscribe, 在ios手机端环境的问题

IOS:每次切换路由,SPA的url是不会变的,发起签名请求的url参数必须是当前页面的url(就是最初进入页面时的url)Android:每次切换路由,SPA的url是会变的,发起签名请求的url参数必须是当前页面的url(不是最初进入页面时的)在进入这个页面的时候把uni.navigateTo换成window.location.href。这里需要注意的是,window.location.href里的路径需要用全路径,包含域名的路径。接着想应该是iOS路由的问题,所以就用原生的页面跳转。

qq_38181746的博客 1428

微信开发——开放标签

笔记:微信开发——开放标签

我才是真的李成贤的博客 4471

疫情如何重塑按需移动应用开发范式

按需移动应用是一种实时连接供需、调度资源、完成服务的动态系统,其核心在于低延迟响应、弹性供给与可信交互。技术原理上依赖模块化架构、云原生弹性伸缩与状态驱动调度;技术价值体现在快速验证商业假设、保障高并发下的履约稳定性及构建用户端信任链。典型应用场景覆盖社区团购、即时配送、远程医疗与家政服务等民生领域。本文聚焦疫情这一极端压力场景,深度解析MVP驱动开发、跨平台动态能力封装、基于履约概率的智能调度等一线实战演进,揭示服务可达性、供给弹性和信任穿透力三大刚性需求如何倒逼技术选型与工程实践升级。

weixin_34150830的博客 393

微信开放标签wx-open-launch-app唤起app

微信开放标签wx-open-launch-app唤起app,问题总结,步骤说明,注意事项,平台配置说明

weixin_38771596的博客 2960

三菱JET伺服限位、原点信号通过PLC刷新设置方法

RWw及RWr软元件的初始设定值,可通过 [Pr. PA01.0 控制模式选择] 及 [Pr. PN22.0 默认映射模式选择] 的值进行切换。JET伺服参数用于CC-Link IE现场网络Basic。循环通信的请求报文与响应报文的收发数据被换读为伺服放大器的对象数据 (RWwn、RWrn)。接下来看映射字2D05具体的内容: 也就是2D05操作字的第九位、第十位、第十一位。响应报文的设定值可进行变更。变更初始设定值时,应变更PDO映射。不同的模式,对应不同的刷新映射内容。GXWORKS3程序。

qq_51166033的博客 8040

桑基图实战指南:Excel/Python/R三工具高效绘制方法

桑基图是一种以线条宽度编码流量大小、以节点位置表达流程阶段、以连接关系呈现数据流向的专项可视化技术,其核心原理在于‘宽即量、位即序、连即逻辑’。它并非装饰性图表,而是面向业务诊断的分析前置工具,尤其适用于预算分配、能源损耗、用户转化等存在明确单向流动与显著数值差异的场景。相比传统柱状图或漏斗图,桑基图能天然暴露系统瓶颈与隐性损耗,大幅提升决策效率。本文聚焦工程落地,覆盖Excel插件快速交付、Python Plotly交互开发、R networkD3生态集成三大主流路径,兼顾数据准备铁律、索引映射规范与中文

cuml0912的博客 484

wx-open-launch-app微信开放标签唤醒app方法

wx-open-launch-app微信开放标签唤醒app方法

q4717529的博客 1万+

VBA常见错误 - “错误3706,未找到提供程序,该程序可能未正确安装”解决方法

1、问题描述 在利用VBA编程时,引用其它表格数据,出现以下问题: (1)运行“错误3706,未找到提供程序,该程序可能未正确安装”。 (2)引用数据失败 2、解决方法 下载“Access 2010 数据库引擎”,并安装即可。 https://www.microsoft.com/en-us/download/details.aspx?id=54920 AccessDatabaseEngine 2010 官方安装包,官网下载不了的可以来这里下载。(1)运行“错误3706,未找到提..

Nemuel的博客 3万+

微信开放标签【wx-open-launch-weapp】使用方法,亲测好用

微信wx-open-launch-weapp标签的使用和问题整理

ZhangLei280的博客 5714

Kaggle大神Abhishek的机器学习框架实战:从红酒数据集看交叉检验的坑与解法

本文通过Kaggle竞赛Grandmaster Abhishek Thakur的实战经验,以红酒数据集为例,深入探讨了机器学习中交叉检验的五大陷阱与优化策略。文章详细解析了决策树max_depth调优过程中的过拟合现象,对比了五种主流交叉检验方法的适用场景,并提供了回归问题中的分层技巧和特征工程陷阱的解决方案。最后,总结了交叉检验方案选型决策树,帮助数据科学家在实际项目中提升模型泛化能力。

h6j7k8l9p0的博客 960

硬件工程师提前批真题及答案解析2

我们需要考虑题目可能的简化假设,即输入电阻 Ri​ 可能是 rbe​ 和 βre​ 的组合,但题目可能简化为: Ri​≈rbe​+βre​。由于锗管的正向导通电压较小(0.2 V~0.3 V),而硅管的正向导通电压较大(0.6 V~0.7 V),因此-4.7 V的电压差不符合硅管的特性,而更接近锗管的特性。在三极管电路中,静态电位是指在无信号输入时,三极管各电极的直流电压。re​ 是动态发射极电阻,通常可以近似为 re​=IE​VT​​,但在题目中已经给出了 re​=300Ω,因此可以直接使用这个值。

XU157303764的博客 774

uni-app / vue 使用微信开发标签标签wx-open-subscribe

经过N久得爬坑,终于做出来了,废话不多说,直接上代码,样例为uniapp vue 同理,直接新建一个文件打开即可 ,同时把所有得wx. 换成uni.; 有人会问你这一看就是小程序啊,非也非也,我写得是uni,但是呢,是从小程序逆转过来实现得,也支持微信得写法; 前提: 1.模板id必须有,没有跟运维要跟后端要; 即代码中得‘ templateIds’ 2.如果出现点击不好使得问题 确保id是初始化就加载,隐藏起来不好使,别问为什么,就是那么回事 3.如果电脑上报错 addEventListener

艾米的猫儿的博客 5895

《低功耗方法学》翻译——前言

前言

记录所学,分享知识,结识挚友 1205

微信公众号正确使用开放标签wx-open-launch-weapp

7.2、如果你动态向浏览器url上添加了一些参数,在ios上面可能会出现签名失败的问题,可以在你跳转的方法上,添加参数之后再进行跳转,可解决这个问题(这个问题的原因是,跳转到当前页时,你的参数可能是异步添加的,参数还未添加时,发送给微信的是当前地址,等你异步添加参数后,这时候的地址与发送给微信的地址不一致,就会出现签名错误情况。“安卓系统不会出现该情况”);1)在wx-open-launch-weapp同级添加一个标签,样式写在该标签上,wx-open-launch-weapp标签绝对定位,透明度为0;

qq_42660374的博客 3645

[Dify] 如何在Dify中解析上传的TXT文件内容

在Dify平台上构建智能应用时,解析用户上传的.txt文件是关键步骤。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 2631

微信小程序 - 实现Java微信支付退款功能以及退款流程,微信小程序前端+java后端完整示例源码,微信小程序退款功能详解,小程序订单申请退款和退款回调方法、查询退款等(新版微信支付,详细示例代码)

微信小程序开发-微信支付退款功能以及退款回调方法,微信支付退款API详解,微信小程序支付V3(支付、退款)Java实现微信小程序开发 小程序支付开发-小程序退款功能,微信小程序小程序和公众号 退款功能教程(含申请退款和退款回调,退款回调地址在商户后台配置或者代码自定义)最新版微信小程序支付,退款问题,小程序支付和退款功能详解,小程序申请退款,小程序处理退款,微信小程序支付与退款java,微信小程序退款及回调,JAVA实现微信小程序支付退款功能,退款api调用报错,如何解决退款申请无响应,如何用实现小程序订单

🏆 前端领域优质创作者 4148

H5页面微信wx-open-launch-app组件跳转APP

最近遇到一个跳转手机app的功能,我这边用的是微信H5页面跳转第三方APP,底层逻辑即H5页面引入微信sdk-- 跳转公众号 --微信公众号跳转到app,以下是详细介绍: 微信开放标签是微信公众平台面向网页开发者提供的扩展标签集合。通过使用微信开放标签,网页开发者可安全便捷地使用微信或系统的能力,为微信用户提供更优质的网页体验。需要注意的是,微信开放标签有最低的微信版本要求、最低的系统版本要求,以及最低的JS接口文件版本要求。微信公众号必须为服务号、并且接入了微信的第三方开发平台、在微信公众号管理平台还有

qq_43532275的博客 7842

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

微信开放标签之唤起app

微信开放标签之唤起app

qq_41041244的博客 193

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

微信开放标签-H5跳转小程序

微信开放标签-H5跳转小程序 文章目录微信开放标签-H5跳转小程序原生H5跳转小程序一、准备工作1.配置JS接口安全域名2.引入JS-SDK文件3. 通过config接口注入权限验证配置并申请所需开放标签4.必要的参数二、功能实现1.<wx-open-launch-weapp>标签2.获取签名3.wx.config 生成注入权限申请所需开放标签Vue项目H5跳转小程序一、准备工作1.配置JS接口安全域名2.引入JS-SDK文件3. 通过config接口注入权限验证配置并申请所需开放标签4.必要的

黄烁的个人博客 1647

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

微信开放平台开发——网页微信扫码登录(OAuth2.0)

1、OAuth2.0   OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。   允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相...

weixin_34191845的博客 1万+

web前端-微信小程序开发学习

微信小程序和普通网页开发的区别:关于微信公众号平台如何注册小程序的账号, 如何获取小程序的appid, 如何下载小程序的开发工具, 这里我不做过多叙述。大家自行百度安装开发环境。创建组件:在项目的根目录中,鼠标右键创建components->test文件夹在新建的components -> test文件夹上,鼠标右键,点击新建components输入组件的名称之后回车,会自动生成组件对应的4个文件,后缀名分别为为了保证目录结构的清晰,建议把不同的组件,存放到单独目录中。

yong_19930826的博客 8832

微信小程序学习实录8:H5网页跳转小程序(微信开放标签、wx-open-launch-weapp按钮不显示、noPermissionJsApi)

跳转小程序:wx-open-launch-weapp 用于页面中提供一个可跳转指定小程序的按钮。使用此标签后,用户需在网页内点击标签按钮方可跳转小程序。

挖掘大数据价值,让决策者快速洞悉趋势,让大众读懂数据背后的故事。 5941

微信开放标签使用注意说明

待发布

qq_16683523的博客 1061

uniapp开发h5,引入微信开放标签实现h5跳转小程序功能,全网最全最细踩坑记录

首先需要在项目中引入微信的sdk,具体引入方式详见我写的另一篇文章,里面包含了引入sdk以及配置wx.config的详细教学以及踩坑记录。如果引入完微信sdk的前提下接下来就是根据微信文档提供的demo来引入开放标签debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印appId: '', // 必填,公众号的唯一标识timestamp: , // 必填,生成签名的时间戳。

柑橘乌云_ 4012

微信H5页面点击直接跳转app-微信开放标签

开发微信H5项目时,需要从h5直接跳转至app,绞尽脑汁调研一番后,发现微信开放标签能实现,but环境配置和测试流程真的很复杂,真的配置四小时,开发仅需30分钟,经过不断踩坑终于上线,踩过的坑都给你们总结出来啦,如果能帮助到你,帮忙点赞收藏关注一下吧。微信开放标签https//developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html。把线上地址代理到测试地址。尽量多输出错误log信息判断是哪里出错。.........

weixin_43522687的博客 5941

h5使用微信开放标签wx-open-launch-app直接打开app

需求:h5网页点击“打开APP”能在微信浏览器中直接跳转到APP,而不是跳转到提示页面让用户打开浏览器再进行跳转。 问题:因为微信浏览器的限制,现在h5通用跳转APP的方法无法直接跳转到APP,故需要使用到微信方提供的开放标签wx-open-launch-app。 开放标签wx-open-launch-app相关链接: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html 使用步骤: 第一步: 创建

qq_40205355的博客 1万+
上一篇: ReactNative开发笔记(持续更新...)
下一篇: macOS Monterey(MacOS 12) 系统升级cocoapods踩坑指南
kovlistudio
博客等级 码龄8年 839粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kovlistudio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值