uni-app + .NET 7 implementa el envío de mensajes de suscripción al subprograma WeChat

El mensaje de suscripción del Mini Programa WeChat es una de las capacidades importantes del Mini Programa, que brinda una mejor experiencia para realizar el servicio de circuito cerrado. A menudo deberíamos ver mensajes de suscripción, por ejemplo, después de que el pedido se haya realizado correctamente y 服务通知el pago sea exitoso 支付成功通知, todos pertenecen al mensaje de suscripción del applet.

Este artículo solo implementa 一次性订阅las funciones, como para 长期订阅y 设备订阅, si tiene la oportunidad de reunirse y luego realizar una investigación.

Antes de comenzar, echemos un vistazo a la introducción del mensaje de suscripción del subprograma WeChat:

Características

La capacidad de mensajes es una parte importante de la capacidad del applet. Brindamos a los desarrolladores la capacidad de suscribirse a los mensajes para lograr un servicio de circuito cerrado y una mejor experiencia.

  • Ubicación de inserción del mensaje de suscripción: notificación de servicio
  • Condiciones para el envío de mensajes de suscripción: autosuscripción del usuario
  • Capacidad de salto de la tarjeta de mensaje de suscripción: haga clic para ver los detalles para saltar a la página del applet

inserte la descripción de la imagen aquí

Tipo de mensaje

1. Suscripción única a las noticias

El mensaje de suscripción única se usa para resolver el problema de notificación del enlace del servicio de seguimiento después de que el usuario usa el Mini Programa. Después de que el usuario se suscriba de forma independiente, el desarrollador puede enviar un mensaje de servicio correspondiente por un tiempo ilimitado; cada mensaje se puede suscribir o cancelar por separado.

2. Noticias de suscripción a largo plazo

La suscripción única a los mensajes puede satisfacer las necesidades de la mayoría de los escenarios de servicio de los miniprogramas, pero hay escenarios en el campo de los servicios públicos fuera de línea que no se pueden satisfacer con una suscripción única, como retrasos en los vuelos, y es necesario enviar múltiples notificaciones. enviado de acuerdo con el estado en tiempo real del vuelo. Para facilitar el servicio, proporcionamos mensajes de suscripción a largo plazo. Después de que el usuario se suscriba una vez, el desarrollador puede enviar varios mensajes durante mucho tiempo.

目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。

Por lo tanto, para nuestros applets ordinarios, después de un registro exitoso, la selección de plantillas de noticias de suscripción solo tiene la opción de suscripción única y no hay opción de suscripción a largo plazo.
inserte la descripción de la imagen aquí

3. Mensaje de suscripción del dispositivo

El mensaje de suscripción del dispositivo es un tipo especial de mensaje de suscripción, que pertenece al tipo de mensaje de suscripción a largo plazo y debe completar el "acceso al dispositivo" antes de que pueda usarse.

Después de saber cómo suscribirse a las noticias del applet, ¡manos a la obra!

proceso basico

Precauciones

Dado que el siguiente artículo aún es muy largo, las precauciones se emiten primero y es posible que vea que su problema se ha resuelto aquí.

  • La ID de plantilla única y la ID de plantilla permanente no se pueden usar al mismo tiempo.
  • La biblioteca básica de la versión inferior 2.4.4~2.8.3 ya admite la llamada de interfaz de mensajes de suscripción y solo admite el paso de un tmplId/tmplId permanente de una sola vez.
  • A partir de la versión 2.8.2, la interfaz de mensajes de suscripción solo se puede invocar después de que el usuario haga clic o inicie una devolución de llamada de pago.
  • A partir de la versión 2.10.0, la versión de desarrollo y la versión de prueba del applet prohibirán el uso del formulario de mensaje de plantilla.
  • En una llamada de autorización, los títulos de las plantillas correspondientes a cada tmplId no pueden existir iguales, si los hay, solo se mantendrá uno.
  • A partir de la versión 2.10.0, admite la suscripción a recordatorios de mensajes de voz.

Preste especial atención al tercer elemento. Cuando la biblioteca de versiones es 2.8.2 o superior, la interfaz de mensajes de suscripción debe invocarse después de una acción de clic o se inicia una devolución de llamada de pago. No hay requisitos especiales para este comportamiento de clic. Por ejemplo, para un formulario, después de hacer clic en el botón Enviar, también se puede invocar la interfaz de mensajes de suscripción. No es necesario hacer clic en la devolución de llamada después del pago, y también se puede invocar la interfaz de mensajes de suscripción.

Obtener ID de plantilla

Inicie sesión en el mini programa en la plataforma pública de WeChat, en la función de mensaje de suscripción, ingrese Mi plantilla, busque la plantilla y copie la identificación de la plantilla. Si no hay una plantilla, primero debe agregar la plantilla y luego obtener la identificación de la plantilla
inserte la descripción de la imagen aquí

Para agregar una nueva plantilla, haga clic en 选用el botón, seleccione la plantilla deseada en la biblioteca pública de plantillas y agréguela.
inserte la descripción de la imagen aquí

Hay muchos artículos que dicen que si no hay una plantilla adecuada, puedes crear una plantilla personalizada . Pero si realmente desea crear una plantilla personalizada, encontrará que no hay ningún lugar donde encontrarla.
Si desea crear una plantilla personalizada, puede hacerlo de las siguientes maneras.
1. Haga clic en 选用el botón para ir a la biblioteca pública de plantillas. (Las plantillas en la biblioteca pública de plantillas están relacionadas con la categoría de servicio de su Mini Programa)
2. En el cuadro de búsqueda, ingrese una palabra clave relativamente larga.
3. Haga clic en Buscar, si aún se puede hacer coincidir la plantilla, luego vuelva a ajustar las palabras clave hasta que no haya ningún resultado de búsqueda.
4. Haga clic en la página 帮忙我们完善模板库para configurar la plantilla personalizada.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Al crear una plantilla personalizada, asegúrese de leer detenidamente el proceso de solicitud de una plantilla, especialmente el Artículo 1. Simplemente lo saqué y lo resalté, porque no leí el Artículo 1 detenidamente, y esperé varios días por las primeras plantillas para la primera aplicación.
El título de la plantilla debe reflejar escenarios de servicio específicos, 要求以“通知”或“提醒”结尾como: notificación de llegada de logística, recordatorio de transacción.

Al ver esto, encontrará que la mayoría de los anteriores no son diferentes de los artículos en Internet. No se preocupe, ¡el texto principal está aquí!

código uni-aplicación

La implementación de front-end es hacer clic en el botón Enviar, guardar el formulario y enviar un mensaje de suscripción después de que el guardado se haya realizado correctamente. Escriba el siguiente código pages/index/index.vuea continuación :

<template>
	<view>
		<view class="setp">
			<publishStep :list="setpList" :current="0" mode="number" active-color="#eb3572"></publishStep>
		</view>
		<view class="container">
			<u-form :model="form" ref="uForm" :rules="rules" :error-type="errorType">
				<u-form-item label="姓名" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}" prop="realName">
					<u-input v-model="form.realName" placeholder="" input-align="right" />
				</u-form-item>
				
				<u-form-item label="服务时间" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}"
				 right-icon="arrow-right" prop="serviceTime">
					<u-input v-model="form.serviceTime" placeholder="请选择服务时间" :disabled="true" input-align="right" @click="timeShow=true" />
				</u-form-item>
				
				<u-form-item label="服务地址" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}" prop="serviceAddress">
					<u-input v-model="form.serviceAddress" placeholder="" input-align="right" @click="selectAddress" />
				</u-form-item>
				<u-form-item label="联系电话" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}"
				 prop="lxtel">
					<u-input v-model="form.lxtel" type="number" placeholder="请输入联系电话" input-align="right" :clearable="false" />
				</u-form-item>
				<u-form-item label="需求描述" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}"
				 prop="remarks">
					<u-input v-model="form.remarks" type="text" placeholder="请输入您的需求" input-align="right" :clearable="false" />
				</u-form-item>
			</u-form>
		</view>
		<view style="height: 160rpx;"></view>
		<view class="bottom_nav">
			<view class="buttom_box padding-horizontal-20 padding-vertical-10">
				<u-button type="error" @click="submitForm" :loading="submit_loading" style="height: 100rpx; font-weight: bold; font-size: 36rpx;">确认提交</u-button>
			</view>
		</view>
		<u-picker mode="time" v-model="timeShow" :params="timeParams" @confirm="timeConfirm"></u-picker>
	</view>
</template>
<script>
	export default {
      
      
		data() {
      
      
			return {
      
      
				
				form:{
      
      
					realName:"",
					serviceTime:'',
					serviceAddress:"",
					lxtel:"",
					remarks:""
					
				},
				rules:{
      
      
					realName: [{
      
      
						required: true,
						message: "请填写您的姓名",
						trigger: 'change'
					}],
					
					serviceTime: [{
      
      
						required: true,
						message: "请选择服务时间",
						trigger: 'change'
					}],
					
					lxtel: [{
      
      
						required: true,
						message: "请输入联系电话",
						trigger: 'change'
					}],
				},
				errorType: ['toast'],
				
				timeShow:false,
				timeParams:{
      
      
					year: true,
					month: true,
					day: true,
					hour: false,
					minute: false,
					second: false
				},
				submit_loading:false,
			}
		},
		
		
		onReady() {
      
      
			this.$refs.uForm.setRules(this.rules);
		},
		
		onLoad(params) {
      
      
			let that = this;
		},
		methods: {
      
      
			
			timeConfirm(e){
      
      
				let that = this;
				that.form.serviceTime = e.year +"-"+e.month+"-"+e.day
			},
			gotoOrder(){
      
      
			    uni.redirectTo({
      
      
					url:"/pages/order/order"
			    })
			},
			submitForm(){
      
      
				 let that = this;
				this.$refs.uForm.validate(valid=>{
      
      
					if (valid){
      
      
						that.$u.api.submit_order(that.form).then(res => {
      
      
							if (res.success) {
      
      
								let data = res.data;
								uni.showToast({
      
      
									title: '提交成功',
									icon: 'success'
								})
								// #ifdef MP-WEIXIN
								uni.requestSubscribeMessage({
      
      
									tmplIds:['XXXXXXXXXXX'], //这里填写tempid
									success:function(subscribeMessageRes){
      
      
										if(subscribeMessageRes.errMsg=="requestSubscribeMessage:ok"){
      
      
											if(subscribeMessageRes.XXXXXXXXXXX=="accept"){
      
      
												uni.login({
      
      
													provider: 'weixin',
													success:function(loginRes){
      
      
														if(loginRes.errMsg=="login:ok"){
      
      
															const code = loginRes.code;
															that.$u.api.sendSubscribeMessage({
      
      
																"code":code,
																"orderId":data.orderId
															}).then(res=>{
      
      
																that.gotoOrder()
															})
														}else{
      
      
															that.gotoOrder()
														}
													},
													fail() {
      
      
														that.gotoOrder()
													}
												})
											}else{
      
      
												that.gotoOrder()
											}
										}else{
      
      
											that.gotoOrder()
										}
										
									},
									fail:function(){
      
      
										that.gotoOrder()
									}
								})
								// #endif
								
							} else {
      
      
								uni.$u.toast(res.message);
							}
						});
					}
				})
				
			}
		}
	}
</script>

<style>
	.setp{
      
       padding: 40rpx 0;}
	.bottom_nav {
      
      
		position: fixed;
		width: 100%;
		height: 100rpx;
		left: 0;
		bottom: 0;
		z-index: 9999;
		background: #FFFFFF;
		border-top: 1rpx #f3f3f3 solid;
	}
</style>

El proceso aquí se divide en 3 pasos:
1. Envíe el formulario y el servidor devolverá el número de pedido (orderId)
2. Use uni.requestSubscribeMessage, abra el cuadro de autorización e ingrese el tercer paso después de hacer clic en Acepto. Después de invocar la autorización, si el usuario está de acuerdo, los parámetros de la función de devolución de llamada subscribeMessageRestienen dos objetos: errMsgy XXXXXXXXXXX, errMsg No hace falta decirlo. Principalmente lo que es este XXXXXXXXXX. XXXXXXXXXXXX se genera mediante autorización, que es el ID de plantilla mediante inspección visual.
3. Utilizar uni.login, obtener code.
4. Enviar codey orderIdenviar al servidor, el servidor codelo obtiene openIdy luego orderIdobtiene los datos específicos del pedido de acuerdo con la adquisición.
5. Enviar mensaje de plantilla.

Si no sucede nada inesperado, después de que el envío sea exitoso, aparecerá el siguiente cuadro de autorización
inserte la descripción de la imagen aquí

código del servidor

Se usa el ORM del lado del servidor SqlSugary la interfaz del subprograma WeChat usa SKIT.FlurlHttpClient.Wechatla biblioteca.

Generar pedidos

Envíe el pedido , aquí hay solo una demostración, ¡usted mismo puede realizar el código específico!

[HttpPost]
public async Task<AjaxResult> SubmitOrder(order model)
{
    
    
//生成订单号
    model.order_no = DateTime.Now.ToString("yyyyMMddHHssfffff");
    model.addtime = DateTime.Now;
    //ExecuteReturnIdentity方法会返回自增id
    var id = await db.Insertable(model).ExecuteReturnIdentity();
    return new AjaxResult(){
    
    
     success=true,
     data = id
    };
}

AjaxResult.cs

public class AjaxResult
{
    
    
/// <summary>
/// 是否成功
/// </summary>
public bool success {
    
     get; set; } = true;

/// <summary>
/// 错误代码
/// </summary>
public int code {
    
     get; set; } = 0;

/// <summary>
/// 返回消息
/// </summary>
public string message {
    
     get; set; }
/// <summary>
/// 返回数据
/// </summary>
public object data{
    
     get; set;}

}

orden.cs

[SugarTable("order")]
public class order
{
    
    
     /// <summary>
     /// 主键,自增Id
     /// </summary>
    [SugarColumn(IsPrimaryKey = true)]
    public int id {
    
     get; set; }
     /// <summary>
     /// 订单编号
     /// </summary>
    public string order_no {
    
     get; set; }
    /// <summary>
    /// 姓名
    /// </summary>
    public string realName {
    
     get; set; }
    /// <summary>
    /// 时间
    /// </summary>
	public DateTime serviceTime {
    
     get; set; }
	/// <summary>
    /// 地址
    /// </summary>
	public string serviceAddress {
    
     get; set; }
	/// <summary>
    /// 联系电话
    /// </summary>
	public string lxtel {
    
     get; set; }
	/// <summary>
    /// 备注
    /// </summary>
	public string remarks {
    
     get; set; }
	/// <summary>
    /// 创建时间
    /// </summary>
	public DateTime addtime {
    
     get; set; }
}

enviar mensaje de plantilla

codeEnvíe un mensaje de plantilla para una suscripción única y el front- end obtendrá los parámetros pasados orderId. Obtenga la información del pedido de acuerdo con el número de pedido, para configurar la información del subprograma y abrir la ruta en el mensaje de suscripción. codeSe utiliza para conseguir usuarios openId.

[HttpPost]
public async Task<AjaxResult> SendSubscribeMessage(string code,string orderId)
{
    
    
    AjaxResult result = new AjaxResult();
    if (string.IsNullOrEmpty(code) || string.IsNullOrEmpty(orderId))
    {
    
    
        result.success = false;
        result.message = "参数错误";
        return result;
    }
    var order_model = await db.Queryable<order>().InSingleAsync(orderId);
    if(order_model is null)
    {
    
    
        result.success = false;
        result.message = "参数错误";
        return result;
    }
    //初始化WechatApiClient
    var options = new WechatApiClientOptions()
    {
    
    
        AppId = "appId",
        AppSecret = "appSecret "
    };
    var client = new WechatApiClient(options);
    //获取openId
    var request = new SnsJsCode2SessionRequest();
    request.JsCode = code;
    var response = await client.ExecuteSnsJsCode2SessionAsync(request);
    string openId = response.OpenId;
    //获取token
    var tokenRequest = new CgibinTokenRequest();
    var tokenResponse = await client.ExecuteCgibinTokenAsync(tokenRequest);
    var token = tokenResponse.AccessToken;
    //发送模板消息
    var messageRequest = new CgibinMessageSubscribeSendRequest();
    IDictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem> messageData = new Dictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem>
            {
    
    
                {
    
    
                    "params1",
                     new CgibinMessageSubscribeSendRequest.Types.DataItem() {
    
    Value=order_model.order_no}
                },
                {
    
    
                    "params1",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.userNmae}
                },
                {
    
    
                    "params3",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.serviceTime}
                },
                {
    
    
                    "params4",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.serviceAddress}
                },
                {
    
    
                    "params5",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.addtime.ToString("yyyy-MM-dd HH:ss")}
                }
            };
     messageRequest.AccessToken = token;
     messageRequest.ToUserOpenId = openId;
     messageRequest.TemplateId = "XXXXXXXXXXX"; 
     messageRequest.MiniProgramState = "developer";
     //微信小程序要跳转的地址。可以加参数
     messageRequest.MiniProgramPagePath = "/pages/order/order_details?id=" + order_model.id;
     messageRequest.Data = messageData;
     var messageResponse = await client.ExecuteCgibinMessageSubscribeSendAsync(messageRequest);
     if(messageResponse.ErrorCode==0)
     {
    
    
         result.success=true;
         result.message = "ok";
         return result;
     }
     result.success = false;
     result.message = "error";
     return result;
}

Cuando construya un mensaje de plantilla, use IDictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem> messageData = new Dictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem>para construir,
asumiendo que el contenido detallado de un mensaje de plantilla es el siguiente:
inserte la descripción de la imagen aquí

  • Luego, params1 en el código anterior es character_string22, y params2 es thing7 de la misma manera. Eso es. La clave de IDictionary es .DATAel contenido anterior en la plantilla.
  • messageRequest.TemplateId, que debe ser coherente con el Id. de plantilla del front-end.
  • messageRequest.MiniProgramStateIndica el tipo de applet de WeChat redirigido. El valor predeterminado es la versión oficial.
    • desarrollador es la versión de desarrollo;
    • juicio es la versión de prueba;
    • formal es la versión oficial;

Por lo menos, su WeChat recibirá una notificación de servicio. ¡Después de hacer clic en la tarjeta, ingrese a la página de detalles del pedido del mini programa!

Resumir

1. De hecho, es relativamente fácil solicitar el mensaje de suscripción del applet de WeChat y la plantilla de mensaje de suscripción de la cuenta oficial. Si no puede encontrar una plantilla adecuada para usted en la categoría de plantillas y plantillas de historial, solicite una plantilla usted mismo. Si se revisa, puede recibir una notificación dentro de 2-3 días.
需要注意的是,申请模板的时候,最好把各项在本地保留一份。因为一旦提交申请,在公众号或小程序后台,你就找不到了。玩意审核没通过,再申请的时候,前面写的啥内容,已经忘的差不多了!

2. Gracias SqlSugarpor proporcionar un ORM tan potente para los desarrolladores de .Net. Es realmente conveniente.
3. Gracias SKIT.FlurlHttpClient.Wechatpor brindar una herramienta tan conveniente para los desarrolladores de .Net.
4. Para expresar rápidamente el significado con claridad, los códigos anteriores de front-end y del lado del servidor están todos simplificados y no deben usarse directamente. ,

¡Haz clic en la tarjeta de cuenta oficial a continuación para seguirme! ¡Aprender juntos y progresar juntos!

Supongo que te gusta

Origin blog.csdn.net/sd2208464/article/details/128857921
Recomendado
Clasificación