Bladeren bron

mp:menu 前端接入菜单的保存、清空操作

YunaiV 2 jaren geleden
bovenliggende
commit
2173cf0364
13 gewijzigde bestanden met toevoegingen van 191 en 140 verwijderingen
  1. 2 1
      yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java
  2. 16 5
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.http
  3. 6 15
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.java
  4. 0 18
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java
  5. 20 4
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java
  6. 22 9
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java
  7. 11 3
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/menu/MpMenuConvert.java
  8. 0 4
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/menu/MpMenuDO.java
  9. 4 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/menu/MpMenuMapper.java
  10. 4 13
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/menu/MpMenuService.java
  11. 55 26
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/menu/MpMenuServiceImpl.java
  12. 20 0
      yudao-ui-admin/src/api/mp/menu.js
  13. 31 42
      yudao-ui-admin/src/views/mp/menu/index.vue

+ 2 - 1
yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java

@@ -52,6 +52,7 @@ public interface ErrorCodeConstants {
     ErrorCode DRAFT_DELETE_FAIL = new ErrorCode(1006007002, "删除草稿失败,原因:{}");
 
     // ========== 公众号菜单 1006008000============
-    ErrorCode MENU_NOT_EXISTS = new ErrorCode(1006008000, "菜单不存在");
+    ErrorCode MENU_SAVE_FAIL = new ErrorCode(1006008000, "创建菜单失败,原因:{}");
+    ErrorCode MENU_DELETE_FAIL = new ErrorCode(1006008001, "删除菜单失败,原因:{}");
 
 }

+ 16 - 5
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.http

@@ -6,24 +6,24 @@ tenant-id: {{adminTenentId}}
 
 {
   "accountId": "1",
-  "buttons": [
+  "menus": [
     {
       "type":"click",
       "name":"今日歌曲",
-      "key":"V1001_TODAY_MUSIC"
+      "menuKey":"V1001_TODAY_MUSIC"
     },
     {
       "name":"搜索",
       "type":"view",
-      "url":"http://www.soso.com/"
+      "url":"https://www.soso.com/"
     },
     {
       "name": "父按钮",
-      "subButtons": [
+      "children": [
         {
           "type":"click",
           "name":"归去来兮",
-          "key":"MUSIC"
+          "menuKey":"MUSIC"
         },
         {
           "name":"不说",
@@ -33,6 +33,17 @@ tenant-id: {{adminTenentId}}
     }]
 }
 
+### 请求 /mp/menu/save 接口 => 成功(清空)
+POST {{baseUrl}}/mp/menu/save
+Content-Type: application/json
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+
+{
+  "accountId": "1",
+  "menus": []
+}
+
 ### 请求 /mp/menu/list 接口 => 成功
 GET {{baseUrl}}/mp/menu/list?accountId=1
 Authorization: Bearer {{token}}

+ 6 - 15
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.java

@@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -32,28 +31,20 @@ public class MpMenuController {
     @PostMapping("/save")
     @ApiOperation("保存公众号菜单")
     @PreAuthorize("@ss.hasPermission('mp:menu:save')")
-    public CommonResult<Long> saveMenu(@Valid @RequestBody MpMenuSaveReqVO createReqVO) {
-        return success(mpMenuService.saveMenu(createReqVO));
+    public CommonResult<Boolean> saveMenu(@Valid @RequestBody MpMenuSaveReqVO createReqVO) {
+        mpMenuService.saveMenu(createReqVO);
+        return success(true);
     }
 
     @DeleteMapping("/delete")
     @ApiOperation("删除公众号菜单")
-    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+    @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, example = "10", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('mp:menu:delete')")
-    public CommonResult<Boolean> deleteMenu(@RequestParam("id") Long id) {
-        mpMenuService.deleteMenu(id);
+    public CommonResult<Boolean> deleteMenu(@RequestParam("accountId") Long accountId) {
+        mpMenuService.deleteMenuByAccountId(accountId);
         return success(true);
     }
 
-    @GetMapping("/get")
-    @ApiOperation("获得公众号菜单")
-    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
-    @PreAuthorize("@ss.hasPermission('mp:menu:query')")
-    public CommonResult<MpMenuRespVO> getMenu(@RequestParam("id") Long id) {
-        MpMenuDO menu = mpMenuService.getMenu(id);
-        return success(MpMenuConvert.INSTANCE.convert(menu));
-    }
-
     @GetMapping("/list")
     @ApiOperation("获得公众号菜单列表")
     @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, example = "10", dataTypeClass = Long.class)

+ 0 - 18
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java

@@ -1,12 +1,9 @@
 package cn.iocoder.yudao.module.mp.controller.admin.menu.vo;
 
-import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO;
-import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import me.chanjar.weixin.common.api.WxConsts;
 
-import javax.validation.constraints.NotNull;
 import java.util.List;
 
 // TODO 芋艿:完善 swagger 注解
@@ -17,17 +14,6 @@ import java.util.List;
 @Data
 public class MpMenuBaseVO {
 
-    @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048")
-    @NotNull(message = "公众号账号的编号不能为空")
-    private Long accountId;
-
-    /**
-     * 微信公众号 appid
-     *
-     * 冗余 {@link MpAccountDO#getAppId()}
-     */
-    private String appId;
-
     /**
      * 菜单名称
      */
@@ -42,10 +28,6 @@ public class MpMenuBaseVO {
      * 父菜单编号
      */
     private Long parentId;
-    /**
-     * 排序
-     */
-    private Integer sort;
 
     // ========== 按钮操作 ==========
 

+ 20 - 4
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java

@@ -1,11 +1,16 @@
 package cn.iocoder.yudao.module.mp.controller.admin.menu.vo;
 
-import lombok.*;
+import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 
-import java.util.*;
-
-import io.swagger.annotations.*;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
 
+// TODO swagger 文档
 @ApiModel("管理后台 - 微信菜单 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -15,6 +20,17 @@ public class MpMenuRespVO extends MpMenuBaseVO {
     @ApiModelProperty(value = "主键", required = true)
     private Long id;
 
+    @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048")
+    @NotNull(message = "公众号账号的编号不能为空")
+    private Long accountId;
+
+    /**
+     * 微信公众号 appid
+     *
+     * 冗余 {@link MpAccountDO#getAppId()}
+     */
+    private String appId;
+
     @ApiModelProperty(value = "创建时间", required = true)
     private Date createTime;
 

+ 22 - 9
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java

@@ -1,19 +1,32 @@
 package cn.iocoder.yudao.module.mp.controller.admin.menu.vo;
 
-import lombok.*;
-import io.swagger.annotations.*;
-import me.chanjar.weixin.common.bean.menu.WxMenuButton;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 import java.util.List;
 
-@ApiModel("管理后台 - 微信菜单保存 Request VO")
+// TODO 芋艿:swagger 文档
+@ApiModel("管理后台 - 公众号菜单保存 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class MpMenuSaveReqVO extends MpMenuBaseVO {
+public class MpMenuSaveReqVO {
 
-    @NotNull(message = "按钮不能为空")
-    private List<WxMenuButton> buttons;
+    @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048")
+    @NotNull(message = "公众号账号的编号不能为空")
+    private Long accountId;
+
+    @NotEmpty(message = "菜单不能为空")
+    @Valid
+    private List<Menu> menus;
+
+    @Data
+    public static class Menu extends MpMenuBaseVO {
+
+        private List<Menu> children;
+
+    }
 
 }

+ 11 - 3
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/menu/MpMenuConvert.java

@@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.mp.controller.admin.menu.vo.MpMenuRespVO;
 import cn.iocoder.yudao.module.mp.controller.admin.menu.vo.MpMenuSaveReqVO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.menu.MpMenuDO;
 import cn.iocoder.yudao.module.mp.service.message.bo.MpMessageSendOutReqBO;
+import me.chanjar.weixin.common.bean.menu.WxMenuButton;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Mappings;
@@ -16,8 +17,6 @@ public interface MpMenuConvert {
 
     MpMenuConvert INSTANCE = Mappers.getMapper(MpMenuConvert.class);
 
-    MpMenuDO convert(MpMenuSaveReqVO bean);
-
     MpMenuRespVO convert(MpMenuDO bean);
 
     List<MpMenuRespVO> convertList(List<MpMenuDO> list);
@@ -27,11 +26,20 @@ public interface MpMenuConvert {
             @Mapping(source = "menu.replyMessageType", target = "type"),
             @Mapping(source = "menu.replyContent", target = "content"),
             @Mapping(source = "menu.replyMediaId", target = "mediaId"),
-            @Mapping(source = "menu.replyMediaUrl", target = "mediaUrl"),
             @Mapping(source = "menu.replyTitle", target = "title"),
             @Mapping(source = "menu.replyDescription", target = "description"),
             @Mapping(source = "menu.replyArticles", target = "articles"),
     })
     MpMessageSendOutReqBO convert(String openid, MpMenuDO menu);
 
+    List<WxMenuButton> convert(List<MpMenuSaveReqVO.Menu> list);
+
+    @Mappings({
+            @Mapping(source = "menuKey", target = "key"),
+            @Mapping(source = "children", target = "subButtons"),
+    })
+    WxMenuButton convert(MpMenuSaveReqVO.Menu bean);
+
+    MpMenuDO convert02(MpMenuSaveReqVO.Menu menu);
+
 }

+ 0 - 4
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/menu/MpMenuDO.java

@@ -64,10 +64,6 @@ public class MpMenuDO extends BaseDO {
      * 父菜单编号
      */
     private Long parentId;
-    /**
-     * 排序
-     */
-    private Integer sort;
 
     // ========== 按钮操作 ==========
 

+ 4 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/menu/MpMenuMapper.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.mp.dal.mysql.menu;
 
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mp.dal.dataobject.menu.MpMenuDO;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -18,4 +19,7 @@ public interface MpMenuMapper extends BaseMapperX<MpMenuDO> {
         return selectList(MpMenuDO::getAccountId, accountId);
     }
 
+    default void deleteByAccountId(Long accountId) {
+        delete(new LambdaQueryWrapperX<MpMenuDO>().eq(MpMenuDO::getAccountId, accountId));
+    }
 }

+ 4 - 13
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/menu/MpMenuService.java

@@ -18,24 +18,15 @@ public interface MpMenuService {
      * 保存公众号菜单
      *
      * @param createReqVO 创建信息
-     * @return 编号
      */
-    Long saveMenu(@Valid MpMenuSaveReqVO createReqVO);
+    void saveMenu(@Valid MpMenuSaveReqVO createReqVO);
 
     /**
      * 删除公众号菜单
      *
-     * @param id 编号
+     * @param accountId 公众号账号的编号
      */
-    void deleteMenu(Long id);
-
-    /**
-     * 获得公众号菜单
-     *
-     * @param id 编号
-     * @return 公众号菜单
-     */
-    MpMenuDO getMenu(Long id);
+    void deleteMenuByAccountId(Long accountId);
 
     /**
      * 用户点击菜单按钮时,回复对应的消息
@@ -50,7 +41,7 @@ public interface MpMenuService {
     /**
      * 获得公众号菜单列表
      *
-     * @param accountId 公众号编号
+     * @param accountId 公众号账号的编号
      * @return 公众号菜单列表
      */
     List<MpMenuDO> getMenuListByAccountId(Long accountId);

+ 55 - 26
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/menu/MpMenuServiceImpl.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.module.mp.service.menu;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.module.mp.controller.admin.menu.vo.MpMenuSaveReqVO;
 import cn.iocoder.yudao.module.mp.convert.menu.MpMenuConvert;
+import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.menu.MpMenuDO;
 import cn.iocoder.yudao.module.mp.dal.mysql.menu.MpMenuMapper;
 import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory;
+import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
 import cn.iocoder.yudao.module.mp.service.message.MpMessageService;
 import cn.iocoder.yudao.module.mp.service.message.bo.MpMessageSendOutReqBO;
 import lombok.extern.slf4j.Slf4j;
@@ -15,13 +18,15 @@ import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.MENU_NOT_EXISTS;
+import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.MENU_DELETE_FAIL;
+import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.MENU_SAVE_FAIL;
 
 /**
  * 公众号菜单 Service 实现类
@@ -35,6 +40,9 @@ public class MpMenuServiceImpl implements MpMenuService {
 
     @Resource
     private MpMessageService mpMessageService;
+    @Resource
+    @Lazy // 延迟加载,避免循环引用报错
+    private MpAccountService mpAccountService;
 
     @Resource
     @Lazy // 延迟加载,避免循环引用报错
@@ -44,43 +52,64 @@ public class MpMenuServiceImpl implements MpMenuService {
     private MpMenuMapper mpMenuMapper;
 
     @Override
-    public Long saveMenu(MpMenuSaveReqVO createReqVO) {
-        String appId = "wx5b23ba7a5589ecbb";
-        // 插入
-        MpMenuDO menu = MpMenuConvert.INSTANCE.convert(createReqVO);
-//        mpMenuMapper.insert(menu);
-
-        // TODO 同步菜单
-        WxMpService mpService = mpServiceFactory.getRequiredMpService(appId);
+    @Transactional(rollbackFor = Exception.class)
+    public void saveMenu(MpMenuSaveReqVO createReqVO) {
+        MpAccountDO account = mpAccountService.getRequiredAccount(createReqVO.getAccountId());
+        WxMpService mpService = mpServiceFactory.getRequiredMpService(createReqVO.getAccountId());
+
+        // 第一步,同步公众号
         WxMenu wxMenu = new WxMenu();
-        wxMenu.setButtons(createReqVO.getButtons());
+        wxMenu.setButtons(MpMenuConvert.INSTANCE.convert(createReqVO.getMenus()));
         try {
             mpService.getMenuService().menuCreate(wxMenu);
         } catch (WxErrorException e) {
-            throw new RuntimeException(e);
+            throw exception(MENU_SAVE_FAIL, e.getError().getErrorMsg());
         }
 
-        // 返回
-        return menu.getId();
+        // 第二步,存储到数据库
+        mpMenuMapper.deleteByAccountId(createReqVO.getAccountId());
+        createReqVO.getMenus().forEach(menu -> {
+            // 先保存顶级菜单
+            MpMenuDO menuDO = createMenu(menu, null, account);
+            // 再保存子菜单
+            if (CollUtil.isEmpty(menu.getChildren())) {
+                return;
+            }
+            menu.getChildren().forEach(childMenu -> createMenu(childMenu, menuDO, account));
+        });
     }
 
     @Override
-    public void deleteMenu(Long id) {
-        // 校验存在
-        validateMenuExists(id);
-        // 删除
-        mpMenuMapper.deleteById(id);
-    }
-
-    private void validateMenuExists(Long id) {
-        if (mpMenuMapper.selectById(id) == null) {
-            throw exception(MENU_NOT_EXISTS);
+    public void deleteMenuByAccountId(Long accountId) {
+        WxMpService mpService = mpServiceFactory.getRequiredMpService(accountId);
+        // 第一步,同步公众号
+        try {
+            mpService.getMenuService().menuDelete();
+        } catch (WxErrorException e) {
+            throw exception(MENU_DELETE_FAIL, e.getError().getErrorMsg());
         }
+
+        // 第二步,存储到数据库
+        mpMenuMapper.deleteByAccountId(accountId);
     }
 
-    @Override
-    public MpMenuDO getMenu(Long id) {
-        return mpMenuMapper.selectById(id);
+    private MpMenuDO createMenu(MpMenuSaveReqVO.Menu wxMenu, MpMenuDO parentMenu, MpAccountDO account) {
+        MpMenuDO menu = CollUtil.isNotEmpty(wxMenu.getChildren())
+                ? new MpMenuDO().setName(wxMenu.getName())
+                : MpMenuConvert.INSTANCE.convert02(wxMenu);
+        if (account != null) {
+            menu.setAccountId(account.getId()).setAppId(account.getAppId());
+        }
+        if (parentMenu != null) {
+            menu.setParentId(parentMenu.getId());
+        } else {
+            menu.setParentId(MpMenuDO.ID_ROOT);
+        }
+        if (StrUtil.isNotEmpty(wxMenu.getReplyMediaId())) {
+            throw new IllegalArgumentException("未实现");
+        }
+        mpMenuMapper.insert(menu);
+        return menu;
     }
 
     @Override

+ 20 - 0
yudao-ui-admin/src/api/mp/menu.js

@@ -7,3 +7,23 @@ export function getMenuList(accountId) {
     method: 'get',
   })
 }
+
+// 保存公众号菜单
+export function saveMenu(accountId, menus) {
+  return request({
+    url: '/mp/menu/save',
+    method: 'post',
+    data: {
+      accountId,
+      menus
+    }
+  })
+}
+
+// 删除公众号菜单
+export function deleteMenu(accountId) {
+  return request({
+    url: '/mp/menu/delete?accountId=' + accountId,
+    method: 'delete',
+  })
+}

+ 31 - 42
yudao-ui-admin/src/views/mp/menu/index.vue

@@ -63,8 +63,8 @@ SOFTWARE.
           <div class="menu_bottom menu_addicon" v-if="this.menuList.length < 3" @click="addMenu"><i class="el-icon-plus"></i></div>
         </div>
         <div class="save_div">
-            <!--<el-button class="save_btn" type="warning" size="small" @click="saveFun">保存菜单</el-button>-->
-            <el-button class="save_btn" type="success" size="small" @click="handleSaveAndReleaseFun">保存并发布菜单</el-button>
+            <el-button class="save_btn" type="success" size="small" @click="handleSave">保存并发布菜单</el-button>
+            <el-button class="save_btn" type="danger" size="small" @click="handleDelete">清空菜单</el-button>
         </div>
       </div>
       <!--右边配置-->
@@ -141,7 +141,7 @@ SOFTWARE.
 import WxReplySelect from '@/views/mp/components/wx-news/main.vue'
 import WxNews from '@/views/mp/components/wx-news/main.vue';
 import WxMaterialSelect from '@/views/mp/components/wx-news/main.vue'
-import { getMenuList } from "@/api/mp/menu";
+import {deleteMenu, getMenuList, saveMenu} from "@/api/mp/menu";
 import { getSimpleAccounts } from "@/api/mp/account";
 
 export default {
@@ -164,11 +164,6 @@ export default {
         children: [],
       },
 
-      menu:{ // 横向菜单
-          button:[
-          ]
-      },
-
       // ======================== 菜单操作 ========================
       isActive: -1,// 一级菜单点中样式
       isSubMenuActive: -1, // 一级菜单点中样式
@@ -178,7 +173,7 @@ export default {
       showRightFlag: false, // 右边配置显示默认详情还是配置详情
       nameMaxLength: 0, // 菜单名称最大长度;1 级是 4 字符;2 级是 7 字符;
       showConfigureContent: true, // 是否展示配置内容;如果有子菜单,就不显示配置内容
-
+      hackResetWxReplySelect: false, // 重置 WxReplySelect 组件
 
       tempObj:{}, // 右边临时变量,作为中间值牵引关系
       tempSelfObj: { // 一些临时值放在这里进行判断,如果放在 tempObj,由于引用关系,menu 也会多了多余的参数
@@ -218,7 +213,6 @@ export default {
           label: '选择地理位置'
       }],
       dialogNewsVisible: false,
-      hackResetWxReplySelect: false,
 
       // 公众号账号列表
       accounts: [],
@@ -246,7 +240,6 @@ export default {
       this.loading = false;
       getMenuList(this.accountId).then(response => {
         this.menuList = this.handleTree(response.data, "id");
-        console.log(this.menuList)
       }).finally(() => {
         this.loading = false;
       })
@@ -354,31 +347,16 @@ export default {
     },
 
     // ======================== 菜单编辑 ========================
-    handleSaveAndReleaseFun(){
-      this.$confirm('确定要保证并发布该菜单吗?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
+    handleSave() {
+      this.$modal.confirm('确定要保证并发布该菜单吗?').then(() => {
         this.loading = true
-        saveAndRelease({
-          strWxMenu:this.menu
-        }).then(response => {
-          this.loading = false
-          if(response.code == 200){
-            this.$message({
-              showClose: true,
-              message: '发布成功',
-              type: 'success'
-            })
-          }else{
-            this.$message.error(response.data.msg)
-          }
-        }).catch(() => {
-          this.loading = false
-        })
-      }).catch(() => {
-      })
+        return saveMenu(this.accountId, this.menuList);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("发布成功");
+      }).catch(() => {}).finally(() => {
+        this.loading = false
+      });
     },
     // 表单 Editor 重置
     resetEditor() {
@@ -387,6 +365,17 @@ export default {
         this.hackResetEditor = true // 重建组件
       })
     },
+    handleDelete() {
+      this.$modal.confirm('确定要清空所有菜单吗?').then(() => {
+        this.loading = true
+        return deleteMenu(this.accountId);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("清空成功");
+      }).catch(() => {}).finally(() => {
+        this.loading = false
+      });
+    },
 
     // TODO 芋艿:未归类
 
@@ -431,7 +420,7 @@ div{
   left:0px;
   width: 300px;
   height:64px;
-  background: transparent url(assets/menu_head.png) no-repeat 0 0;
+  background: transparent url("assets/menu_head.png") no-repeat 0 0;
   background-position: 0 0;
   background-size: 100%
 }
@@ -445,7 +434,7 @@ div{
   left: 0px;
 }
 .weixin-menu{
-  background: transparent url(assets/menu_foot.png) no-repeat 0 0;
+  background: transparent url("assets/menu_foot.png") no-repeat 0 0;
   padding-left: 43px;
   font-size: 12px
 }
@@ -581,26 +570,26 @@ div{
 <!--</style>-->
 <!--素材样式-->
 <style lang="scss" scoped>
-.pagination{
+.pagination {
     text-align: right;
     margin-right: 25px;
 }
-.select-item{
+.select-item {
     width: 280px;
     padding: 10px;
     margin: 0 auto 10px auto;
     border: 1px solid #eaeaea;
 }
-.select-item2{
+.select-item2 {
     padding: 10px;
     margin: 0 auto 10px auto;
     border: 1px solid #eaeaea;
 }
-.ope-row{
+.ope-row {
     padding-top: 10px;
     text-align: center;
 }
-.item-name{
+.item-name {
     font-size: 12px;
     overflow: hidden;
     text-overflow:ellipsis;