Exemple de code pour développer un outil d'édition de menu personnalisé WeChat via asp.net mvc

Y2J
Libérer: 2017-05-20 13:40:18
original
2441 Les gens l'ont consulté

Cet article présente principalement le développement d'outils d'édition de menus personnalisés WeChat utilisant asp.net mvc, boostrap et knockout.js. Il est très bon et a une valeur de référence. Les amis dans le besoin peuvent s'y référer

<.>Avant-propos

L'outil de débogage d'interface de WeChat peut modifier des menus personnalisés, mais il nécessite uniquement de soumettre des données au format json pour créer des menus, ce qui est très peu pratique et sujet aux erreurs. Les outils en ligne ne sont pas faciles à utiliser, j'en ai donc écrit un moi-même.

Texte

Utilisez d'abord

bootstrap pour organiser la page frame et appelez le menu personnalisé L'interface doit utiliser AccessToken, mettre une zone de saisie pour saisir AccessToken. Les utilisateurs qui souhaitent saisir directement l'AppId et l'AppSecret pour obtenir l'AccessToken ne sont pas exclus, ils ont donc également besoin du menu déroulant pour choisir de saisir l'AccessToken ou d'obtenir directement l'AccessToken. Afin de prendre en compte le menu de création d'application de compte d'entreprise WeChat, AgentId, CorpId, le code d'autorisation permanent de la suite, SuiteId, SuiteSecret, SuiteTicket et les zones de saisie des paramètres sont à peu près ceux-ci.

Utilisez knockout pour définir les attributs

de surveillance des observables . Et liez-le à la zone de saisie.

 

Définir l'affichage du menu et le module d'édition du menu La disposition est composée de trois grands menus pour le menu du compte officiel WeChat. être configuré sous cinq sous-menus. L'idée générale est la suivante. La mise en page est de six lignes et trois colonnes. Lorsque les trois grands menus ne sont pas entièrement configurés, le bouton Ajouter un menu

s'affiche sur le côté droit. > les sous-menus de chaque menu parent ne sont pas configurés. Lorsqu'ils sont pleins, un bouton d'ajout de menu s'affiche au-dessus. Lorsque la configuration n'est pas pleine, un p vide sera utilisé pour occuper la place.

Définir une

fonction

pour générer un tableau

de longueur personnalisée

Utiliser knockout pour définir les attributs de surveillance du menu et format Définir les fonctions de menu ajouter, modifier, supprimer

pour

{
 "button": [
  {
   "name": "父级菜单1",
   "sub_button": [
    {
     "type": "view",
     "name": "子菜单1",
     "url": ""
    }
   ]
  },
  {
   "name": "父级菜单1",
   "sub_button": [
    {
     "type": "view",
     "name": "子菜单2",
     "url": ""
    },
    {
     "type": "view",
     "name": "子菜单1",
     "url": ""
    }
   ]
  }
 ]
}
Copier après la connexion
, définir les attributs de surveillance temporaires lors de l'ajout d'un menu d'édition et définir les attributs de surveillance du menu d'édition actuel

indice .

Il n'est pas très pratique d'éditer les menus un par un, il faut donc également définir le mouvement haut, bas, gauche et droite du menu, ainsi que la copie et fonction coller.

Lier les attributs de surveillance et générer la disposition du menu

function MenuFormValidate() {
   $("#MenuForm").validate({
    rules: {
     name: {
      required: true
     },
     value: {
      required: false
     }
    },
    messages: {
     name: {
      required: "请输入名称"
     },
     value: {
      required: $("#txtMenuButtonValue").attr("placeholder")
     }
    }
   });
  }
          MenusReset:function () {
     var menus = JSON.stringify(model.Menus());
     model.Menus(undefined);
     model.Menus(JSON.parse(menus));//刷新菜单对象
     MenuFormValidate();//重新绑定验证方法
    },
MenuIndex: ko.observable(), //父级菜单索引
    isEditMenu: ko.observable(false), //是否是编辑菜单
    BottonIndex: ko.observable(-1), //编辑菜单的父级菜单索引
    SubBottonIndex: ko.observable(-1), //编辑菜单的子菜单索引
    Menu: ko.observable(),//编辑菜单时临时监控属性
    CopyMenu: ko.observable(),//复制的菜单对象
    Copy: function () { //复制
     if (model.Menu() != undefined) {
      var menu = JSON.stringify(model.Menu());
      model.CopyMenu(JSON.parse(menu));
      model.Menu(undefined);
     }
    },
    Paste: function () {//粘贴
     if (model.CopyMenu() != undefined) {
      var menu = JSON.parse(JSON.stringify(model.CopyMenu()));
      if (model.SubBottonIndex() !== -1 && menu.sub_button != undefined || (!model.isEditMenu() && model.MenuIndex() != undefined)) {
       delete menu.sub_button;
      }
      model.Menu(menu);
      MenuFormValidate();
     }
    },
    Up: function () {//向上移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     var newSubBottonIndex = subBottonIndex - 1;
     model.Menus().button[bottonIndex].sub_button[subBottonIndex] = model.Menus().button[bottonIndex].sub_button[newSubBottonIndex];
     model.Menus().button[bottonIndex].sub_button[newSubBottonIndex] = model.Menu();
     model.MenusReset();
     model.SubBottonIndex(newSubBottonIndex);
    },
    Down: function () {//向下移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     var newSubBottonIndex = subBottonIndex + 1;
     model.Menus().button[bottonIndex].sub_button[subBottonIndex] = model.Menus().button[bottonIndex].sub_button[newSubBottonIndex];
     model.Menus().button[bottonIndex].sub_button[newSubBottonIndex] = model.Menu();
     model.MenusReset();
     model.SubBottonIndex(newSubBottonIndex);
    },
    Left: function () {//向左移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     if (subBottonIndex === -1) {
      var newBottonIndex = bottonIndex - 1;
      model.Menus().button[bottonIndex] = model.Menus().button[newBottonIndex];
      model.Menus().button[newBottonIndex] = model.Menu();
      model.MenusReset();
      model.BottonIndex(newBottonIndex);
     }
    },
    Right: function () {//向右移动
     var bottonIndex = model.BottonIndex();
     var subBottonIndex = model.SubBottonIndex();
     if (subBottonIndex === -1) {
      var newBottonIndex = bottonIndex + 1;
      model.Menus().button[bottonIndex] = model.Menus().button[newBottonIndex];
      model.Menus().button[newBottonIndex] = model.Menu();
      model.MenusReset();
      model.BottonIndex(newBottonIndex);
     }
    },
    EditMenu: function (obj, bottonindex, subbottonindex) {//编辑菜单
     model.BottonIndex(bottonindex);
     model.SubBottonIndex(subbottonindex);
     model.isEditMenu(true);
     var data = JSON.stringify(obj);
     model.Menu(JSON.parse(data));
     MenuFormValidate();
    },
    AddMenu: function (index) {//添加菜单
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
     model.isEditMenu(false);
     model.MenuIndex(index);
     var menu = { type: "view", name: "", value: "" };
     model.Menu(menu);
     MenuFormValidate();
    },
    DeleteMenu: function () {//删除菜单
     $(model.Menus().button).each(function (index, item) {
      if (index === model.BottonIndex() && model.SubBottonIndex() === -1) {
       model.Menus().button.splice(index, 1);
      }
      if (item.sub_button instanceof Array) {
       $(item.sub_button).each(function (index1) {
        if (index === model.BottonIndex() && index1 === model.SubBottonIndex()) {
         item.sub_button.splice(index1, 1);
        }
       });
      }
     });
     model.Menu(undefined);
     model.MenuIndex(undefined);
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
     model.MenusReset();
    },
    CancelMenuSave: function () {//取消编辑,重置参数
     model.Menu(undefined);
     model.MenuIndex(undefined);
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
    },
    MenuSave: function () {//保存编辑的菜单
     if (!$("#MenuForm").data("validator").form()) {
      return;
     }
     if (model.isEditMenu()) {
      var menuIndex = model.BottonIndex();
      var subMenuIndex = model.SubBottonIndex();
      if (subMenuIndex === -1) {
       model.Menus().button[menuIndex] = model.Menu();
      } else {
       model.Menus().button[menuIndex].sub_button[subMenuIndex] = model.Menu();
      }
     } else {
      if (model.MenuIndex() != undefined) {
       if (model.Menus().button[model.MenuIndex()].sub_button == undefined) {
        model.Menus().button[model.MenuIndex()].sub_button = new Array();
       }
       model.Menus().button[model.MenuIndex()].sub_button.unshift(model.Menu());
      } else {
       model.Menus().button.push(model.Menu());
      }
     }
     model.Menu(undefined);
     model.MenuIndex(undefined);
     model.BottonIndex(-1);
     model.SubBottonIndex(-1);
     model.MenusReset();
    },
Copier après la connexion

Enfin, ajoutez la fonction

requête
<p class="panel-body" data-bind="with:Menus" id="pMenu" style="display: none;">
  <p style="height: 200px;" data-bind="foreach:newArray(3)">
   <p class="list-group col-xs-4 clearFill bn">
    <!--ko if:($parent.button.length>0 && $parent.button[$index()]!=undefined && $parent.button[$index()].sub_button!=undefined ) -->
    <!--ko foreach:newArray((4-$parent.button[$index()].sub_button.length)) -->
    <p class="list-group-item bn"></p>
    <!--/ko-->
    <!--ko if:$parent.button[$index()].sub_button.length<5 -->
    <p class="list-group-item" data-bind="click:function (){$root.AddMenu($index())}"><i class="fa fa-plus"></i>
    </p>
    <!--/ko-->
    <!--ko foreach:($parent.button[$index()].sub_button) -->
    <p class="list-group-item" data-bind="text:name,attr:{&#39;bottonIndex&#39;:$parent.value,&#39;subbottonIndex&#39;:$index()},click:function (){$root.EditMenu($data,$parent.value,$index())}"></p>
    <!--/ko-->
    <!--/ko -->
    <!--ko if: $parent.button[$index()]!=undefined && $parent.button[$index()].sub_button==undefined -->
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item" data-bind="click:function (){$root.AddMenu($index())}"><i class="fa fa-plus"></i>
    </p>
    <!--/ko-->
    <!--ko if: $parent.button[$index()]==undefined -->
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <p class="list-group-item bn"></p>
    <!--/ko-->
   </p>
  </p>
  <!--ko foreach:button -->
  <p class="col-xs-4 list-group-item list-group-item-danger" data-bind="text:name,attr:{&#39;bottonindex&#39;:$index()},click:function (){$root.EditMenu($data,$index(),-1)}"></p>
  <!--/ko-->
  <!--ko if:button.length < 3 -->
  <p class="col-xs-4 list-group-item" data-bind="click:function (){$root.AddMenu();}"><i class="fa fa-plus"></i>
  </p>
  <!--/ko-->
  <p class="clearfix"></p>
  <p class="col-xs-12" style="border: 1px solid #EEEEEE; padding-top: 15px; margin-top: 15px;" data-bind="with:$root.Menu,visible:($root.Menu()!=undefined)">
   <form id="MenuForm" onsubmit="return false;">
    <p class="form-group col-xs-4">
     <input type="text" class="form-control" name="name" placeholder="请输入名称" data-bind="value:name">
    </p>
    <p class="form-group col-xs-4">
     <select class="form-control" onchange="$(&#39;#txtMenuButtonValue&#39;)
 .attr(&#39;placeholder&#39;, $(this).find(&#39;option:selected&#39;).attr(&#39;pl&#39;))" data-bind="value:type">
      <option value="view" pl="请输入Url">跳转URL</option>
      <option value="click" pl="请输入Key">点击推事件</option>
      <option value="scancode_push" pl="请输入Key">扫码推事件</option>
      <option value="scancode_waitmsg" pl="请输入Key">扫码推事件且弹出“消息接收中”提示框</option>
      <option value="pic_sysphoto" pl="请输入Key">弹出系统拍照发图</option>
      <option value="pic_photo_or_album" pl="请输入Key">弹出拍照或者相册发图</option>
      <option value="pic_weixin" pl="请输入Key"> 弹出微信相册发图器</option>
      <option value="location_select" pl="请输入Key">弹出地理位置选择器</option>
     </select>
    </p>
    <p class="form-group col-xs-8">
     <input type="text" id="txtMenuButtonValue" name="value" class="form-control" placeholder="请输入Url" data-bind="value:value">
    </p>
    <p class="form-group col-xs-12">
     <button type="submit" class="btn btn-primary" data-bind="click:$root.MenuSave">确定</button>
     <button type="submit" class="btn btn-danger" data-bind="visible:$root.isEditMenu,click:$root.DeleteMenu">删除</button>
     <button type="button" class="btn btn-default" title="上移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsUp(),click:$root.Up"><i class="fa fa-chevron-circle-up" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="下移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsDown(),click:$root.Down"><i class="fa fa-chevron-circle-down" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="左移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsLeft(),click:$root.Left"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="右移" data-bind="visible:$root.isEditMenu(),disable:!$root.IsRight(),click:$root.Right"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></button>
     <button type="button" class="btn btn-default" title="复制菜单" data-bind="visible:$root.isEditMenu(),click:$root.Copy">复制</button>
     <button type="button" class="btn btn-default" title="粘贴菜单" data-bind="click:$root.Paste">粘贴</button>
     <button type="submit" class="btn btn-default" data-bind="click:$root.CancelMenuSave">关闭</button>
    </p>
   </form>
  </p>
  <p class="clearfix"></p>
 </p>
Copier après la connexion
et la fonction de publication du menu. Parce qu'il est pratique de modifier les menus, l'objet menu ne correspond pas au format json requis par l'interface de menu personnalisée de WeChat. Par conséquent, lors de l'interrogation des menus existants et de la publication des menus, vous devez apporter certaines modifications de format aux données json. , 🎜>

2. Tutoriel ASP.NET

 EditMenus: function (isQuery) {
     if (isQuery == undefined) {
      var menu = {};
      menu.button = new Array();
      model.Menus(menu);
     } else {
      var appId = model.AppId();
      var appSecret = model.AppSecret();
      var accessToken = model.AccessToken();
      var type = model.Type();
      var tokenType = model.TokenType();
      var corpId = model.CorpId();
      var permanentCode = model.PermanentCode();
      var agentId = model.AgentId();
      var suiteId = model.SuiteId();
      var suiteSecret = model.SuiteSecret();
      var suiteTicket = model.SuiteTicket();
      if (type === "1" && tokenType === "2") {
       if (appId == undefined || $.trim(appId).length === 0) {
        alert("请输入AppId");
        return;
       }
       if (appSecret == undefined || $.trim(appSecret).length === 0) {
        alert("请输入AppSecret");
        return;
       }
      } else if (type === "2" && tokenType === "2") {
       if (corpId == undefined || $.trim(corpId).length === 0) {
        alert("请输入CorpId");
        return;
       }
       if (permanentCode == undefined || $.trim(permanentCode).length === 0) {
        alert("请输入永久授权码");
        return;
       }
       if (agentId == undefined || $.trim(agentId).length === 0) {
        alert("请输入AgentId");
        return;
       }
       if (suiteId == undefined || $.trim(suiteId).length === 0) {
        alert("请输入SuiteId");
        return;
       }
       if (suiteSecret == undefined || $.trim(suiteSecret).length === 0) {
        alert("请输入SuiteSecret");
        return;
       }
       if (suiteTicket == undefined || $.trim(suiteTicket).length === 0) {
        alert("请输入SuiteTicket");
        return;
       }
      } else if (tokenType === "1") {
       if (accessToken == undefined || $.trim(accessToken).length === 0) {
        alert("请输入AccessToken");
        return;
       }
      }
      $("#btnQueryMenu").button("查询中...");
      $.ajax({
       url: "",
       datatype: "JSON",
       type: "POST",
       async: true,
       data: JSON.stringify({
        appId: appId, appSecret: appSecret, accessToken: accessToken, type: type, tokenType: tokenType, corpId: corpId, permanentCode: permanentCode, agentId: agentId,
        suiteId: suiteId, suiteSecret: suiteSecret, suiteTicket: suiteTicket
       }),
       contentType: "application/json; charset=UTF-8",
       success: function (obj) {
        $("#btnQueryMenu").button("reset");
        if (obj.Success) {
         var data = obj.Data;
         var menus = JSON.parse(data).menu;
         $(menus.button).each(function (index, item) {
          if (item.type === "view") {
           item.value = item.url;
           delete item.url;
          } else {
           item.value = item.key;
           delete item.key;
          }
          if (item.type == undefined) {
           item.type = "view";
           item.value = "";
          }
          if (item.sub_button instanceof Array) {
           $(item.sub_button).each(function (index1, item2) {
            if (item2.type === "view") {
             item2.value = item2.url;
             delete item2.url;
            } else {
             item2.value = item2.key;
             delete item2.key;
            }
           });
          }
         });
         model.Menu(undefined);
         model.MenuIndex(undefined);
         model.BottonIndex(-1);
         model.SubBottonIndex(-1);
         model.Menus(undefined);
         model.Menus(menus);
        } else {
         alert(obj.Messages);
        }
       },
       error: function (xmlHttpRequest, textStatus, errorThrown) {
        $("#btnQueryMenu").button("reset");
        console.error(errorThrown);
       }
      });
     }
    },
    SaveMenus: function () {
     var menus = JSON.parse(JSON.stringify(model.Menus()));
     $(menus.button).each(function (index, item) {
      if (item.type === "view") {
       item.url = item.value;
       delete item.value;
      } else {
       item.key = item.value;
       delete item.value;
      }
      if (item.sub_button instanceof Array) {
       $(item.sub_button).each(function (index1, item2) {
        if (item2.type === "view") {
         item2.url = item2.value;
         delete item2.value;
        } else {
         item2.key = item2.value;
         delete item2.value;
        }
       });
       if (item.sub_button.length > 0) {
        delete item.key;
        delete item.url;
        delete item.type;
       } else {
        delete item.sub_button;
       }
      }
     });
     console.log(JSON.stringify(menus));
     var appId = model.AppId();
     var appSecret = model.AppSecret();
     var accessToken = model.AccessToken();
     var type = model.Type();
     var tokenType = model.TokenType();
     var agentId = model.AgentId();
     var suiteId = model.SuiteId();
     var suiteSecret = model.SuiteSecret();
     var suiteTicket = model.SuiteTicket();
     if (type === "1" && tokenType === "2") {
      if (appId == undefined || $.trim(appId).length === 0) {
       alert("请输入AppId");
       return;
      }
      if (appSecret == undefined || $.trim(appSecret).length === 0) {
       alert("请输入AppSecret");
       return;
      }
     } else if (type === "2" && tokenType === "2") {
      if (agentId == undefined || $.trim(agentId).length === 0) {
       alert("请输入AgentId");
       return;
      }
      if (suiteId == undefined || $.trim(suiteId).length === 0) {
       alert("请输入SuiteId");
       return;
      }
      if (suiteSecret == undefined || $.trim(suiteSecret).length === 0) {
       alert("请输入SuiteSecret");
       return;
      }
      if (suiteTicket == undefined || $.trim(suiteTicket).length === 0) {
       alert("请输入SuiteTicket");
       return;
      }
     } else if (tokenType === "1") {
      if (accessToken == undefined || $.trim(accessToken).length === 0) {
       alert("请输入AccessToken");
       return;
      }
     }
     $("#btnSubmitMenu").button("发布中...");
     $.ajax({
      url: "",
      datatype: "JSON",
      type: "POST",
      async: true,
      data: JSON.stringify({
       appId: appId, appSecret: appSecret, accessToken: accessToken, type: type, tokenType: tokenType, agentId: agentId,
       suiteId: suiteId, suiteSecret: suiteSecret, suiteTicket: suiteTicket, menu: JSON.stringify(menus)
      }),
      contentType: "application/json; charset=UTF-8",
      success: function (obj) {
       $("#btnSubmitMenu").button("reset");
       if (obj.Success) {
        alert("发布成功");
       } else {
        alert(obj.Messages);
       }
      },
      error: function (xmlHttpRequest, textStatus, errorThrown) {
       $("#btnSubmitMenu").button("reset");
       console.error(errorThrown);
      }
     });
    }
Copier après la connexion

3

Tutoriel vidéo ASP.NET de la Geek Academy

4.

Qu'est-ce qu'ASP.NET MVC ? Résumé d'ASP.NET MVC

5. Introduction à ASP.NET MVC en détail - contrôleur (contrôleur)

6. en détail. NET MVC--Vue

7 Introduction détaillée à ASP.NET MVC--Routage

8. d'ASP.NET MVC et WebForm La différence

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!