7 changed files with 1893 additions and 886 deletions
			
			
		@ -0,0 +1,233 @@ | 
				
			|||
  const cptTypeListTestdata = [ | 
				
			|||
      // 通用组件 | 
				
			|||
      { | 
				
			|||
        functionId: '0', | 
				
			|||
        functionName: '通用组件', | 
				
			|||
        functionType: 1, // 1通用 2功能 | 
				
			|||
        isUnfold: true, | 
				
			|||
        componentList: [ | 
				
			|||
          { | 
				
			|||
            componentId: '7', | 
				
			|||
            componentName: '最新议题', | 
				
			|||
            componentFrontId: 'resi-functionList-hall-latestIssueList', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              num: 3 | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '最新议题的标题。最新议题的标题。最新议题的标题。最新议题的标题。', | 
				
			|||
                  content: '最新议题的内容,最新议题的内容,最新议题的内容。', | 
				
			|||
                  author: '山东路45号-刘女士', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '最新议题的标题。', | 
				
			|||
                  content: '最新议题的内容,最新议题的内容,最新议题的内容。', | 
				
			|||
                  author: '山东路45号-刘女士', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '最新议题的标题。', | 
				
			|||
                  content: '最新议题的内容,最新议题的内容,最新议题的内容。', | 
				
			|||
                  author: '山东路45号-刘女士', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '8', | 
				
			|||
            componentName: '最新发布', | 
				
			|||
            componentFrontId: 'resi-functionList-voice-newsList', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              num: 3 | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  pic: '', | 
				
			|||
                  title: '新型冠状病毒检测重大突破!新型冠状病毒检测重大突破!!!', | 
				
			|||
                  author: '大港路党支部', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  pic: '', | 
				
			|||
                  title: '新型冠状病毒检测重大突破!', | 
				
			|||
                  author: '大港路党支部', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  pic: '', | 
				
			|||
                  title: '新型冠状病毒检测重大突破!', | 
				
			|||
                  author: '大港路党支部', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '9', | 
				
			|||
            componentName: '结案项目', | 
				
			|||
            componentFrontId: 'resi-functionList-hall-closedProjectList', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              num: 3 | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  title: '结案项目的标题。', | 
				
			|||
                  content: '结案项目的内容,结案项目的内容,结案项目的内容。', | 
				
			|||
                  author: '党支部-卫生部门', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  title: '结案项目的标题。', | 
				
			|||
                  content: '结案项目的内容,结案项目的内容,结案项目的内容。', | 
				
			|||
                  author: '党支部-卫生部门', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  title: '结案项目的标题。', | 
				
			|||
                  content: '结案项目的内容,结案项目的内容,结案项目的内容。', | 
				
			|||
                  author: '党支部-卫生部门', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          } | 
				
			|||
        ] | 
				
			|||
      }, | 
				
			|||
      // 功能组件 | 
				
			|||
      { | 
				
			|||
        functionId: '1', | 
				
			|||
        functionName: '议事厅', | 
				
			|||
        functionType: 2, // 1通用 2功能 | 
				
			|||
        isUnfold: false, | 
				
			|||
        componentList: [ | 
				
			|||
          { | 
				
			|||
            componentId: '1', | 
				
			|||
            componentName: '顶部标题', | 
				
			|||
            componentFrontId: 'resi-titleList-home-gridNameTitle', | 
				
			|||
            configuration: { | 
				
			|||
              // content: '' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              ico: '', | 
				
			|||
              avatar: '', | 
				
			|||
              title: '青岛市市北区大港路第二网格' | 
				
			|||
            }, | 
				
			|||
            region: 'titleList', | 
				
			|||
            configurationDescription: '请配置具体内容' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '2', | 
				
			|||
            componentName: '轮播图', | 
				
			|||
            componentFrontId: 'resi-topList-voice-hotNewsSwiper', | 
				
			|||
            configuration: { | 
				
			|||
              // content: '' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              pic: '', | 
				
			|||
              title: '轮播图新闻标题' | 
				
			|||
            }, | 
				
			|||
            region: 'topList', | 
				
			|||
            configurationDescription: '请配置具体内容' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '3', | 
				
			|||
            componentName: '消息通知', | 
				
			|||
            componentFrontId: 'resi-floatingList-mine-newMessageButton', | 
				
			|||
            configuration: { | 
				
			|||
              // content: '' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              ico: '', | 
				
			|||
              text: '有新消息!' | 
				
			|||
            }, | 
				
			|||
            region: 'floatingList', | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '5', | 
				
			|||
            componentName: '功能菜单', | 
				
			|||
            componentFrontId: 'resi-functionList-extend-moreFunctionIcons', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              // bgc: '#eee' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '议事厅' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '社群' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '党建声音' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '更多功能' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '6', | 
				
			|||
            componentName: '热门群', | 
				
			|||
            componentFrontId: 'resi-functionList-group-recommendGroupSlider', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              // bgc: '#fff' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  no: '1', | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '群名称', | 
				
			|||
                  info1: '山东路45号-张三', | 
				
			|||
                  info2: '共240人', | 
				
			|||
                  info3: '党员11人' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  no: '2', | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '群名称', | 
				
			|||
                  info1: '山东路45号-张三', | 
				
			|||
                  info2: '共240人', | 
				
			|||
                  info3: '党员11人' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  no: '3', | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '群名称', | 
				
			|||
                  info1: '山东路45号-张三', | 
				
			|||
                  info2: '共240人', | 
				
			|||
                  info3: '党员11人' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          } | 
				
			|||
        ] | 
				
			|||
      } | 
				
			|||
    ] | 
				
			|||
@ -0,0 +1,680 @@ | 
				
			|||
<template> | 
				
			|||
  <div> | 
				
			|||
    <div class="m-wx_index"> | 
				
			|||
      <el-button v-if="userType==='oper'" | 
				
			|||
                 type="default" | 
				
			|||
                 @click="diaCancel">取消返回</el-button> | 
				
			|||
      <el-button type="info" | 
				
			|||
                 @click="isInPreview = true">预览</el-button> | 
				
			|||
      <el-button type="success" | 
				
			|||
                 @click="save">保存</el-button> | 
				
			|||
      <el-button v-if="showFrom==='customize'" | 
				
			|||
                 type="danger" | 
				
			|||
                 @click="publish">发布</el-button> | 
				
			|||
      <span v-if="showFrom==='customize'" | 
				
			|||
            style="margin-left:20px; color:#aaa; font-size:13px">({{ wxIndex.customerName }} - )</span> | 
				
			|||
      <span style="margin-left:20px; color:#aaa; font-size:13px">({{ wxIndex.clientType===1 ? '工作端' : '居民端' }})</span> | 
				
			|||
 | 
				
			|||
      <el-row class="wrap" | 
				
			|||
              :gutter="20"> | 
				
			|||
        <el-col :span="5"> | 
				
			|||
          <h4>选择组件</h4> | 
				
			|||
          <div class="mw-cpt_type"> | 
				
			|||
            <div class="d-function" | 
				
			|||
                 v-show="item.componentList.length > 0" | 
				
			|||
                 :key="item.functionId" | 
				
			|||
                 v-for="item in cptTypeList"> | 
				
			|||
              <div class="d-info" | 
				
			|||
                   @click="shiftCptTypeItemUnfold(item)"> | 
				
			|||
                <img v-if="item.functionName=='议事厅'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt1.png"> | 
				
			|||
                <img v-else-if="item.functionName=='社群'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt2.png"> | 
				
			|||
                <img v-else-if="item.functionName=='党建声音'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt3.png"> | 
				
			|||
                <img v-else-if="item.functionName=='消息通知'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt4.png"> | 
				
			|||
                <img v-else | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/common-cpt.png"> | 
				
			|||
 | 
				
			|||
                <span class="d-name">{{ item.functionName }}</span> | 
				
			|||
 | 
				
			|||
                <img class="d-arrow" | 
				
			|||
                     :class="{'z-unfold': item.isUnfold}" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/arrow-down.png"> | 
				
			|||
              </div> | 
				
			|||
              <div class="d-list" | 
				
			|||
                   v-show="item.isUnfold"> | 
				
			|||
                <div class="d-item" | 
				
			|||
                     :key="cptItem.componentId" | 
				
			|||
                     v-for="cptItem in item.componentList"> | 
				
			|||
                  <span class="d-item-region">({{ getCptRegionName(checkCptRegion(cptItem)) }})</span> | 
				
			|||
                  <span class="d-item-name">{{ cptItem.componentName }}</span> | 
				
			|||
                  <span class="d-item-btn z-disabled" | 
				
			|||
                        v-if="!checkCptReuse(cptItem) && checkExistCpt(cptItem)">已添加</span> | 
				
			|||
                  <span class="d-item-btn" | 
				
			|||
                        v-else | 
				
			|||
                        @click="beforeAddCpt(cptItem)"> | 
				
			|||
                    <img src="@/assets/img/modules/wx-mini/index-set/add.png"> | 
				
			|||
                    <span>添加</span> | 
				
			|||
                  </span> | 
				
			|||
                </div> | 
				
			|||
              </div> | 
				
			|||
            </div> | 
				
			|||
          </div> | 
				
			|||
        </el-col> | 
				
			|||
 | 
				
			|||
        <el-col :span="13"> | 
				
			|||
          <div class="mw-show" | 
				
			|||
               :class="{'z-preview': isInPreview}"> | 
				
			|||
            <div v-show="isInPreview" | 
				
			|||
                 class="mw-show-close"> | 
				
			|||
              <el-button type="default" | 
				
			|||
                         @click="isInPreview = false" | 
				
			|||
                         icon="el-icon-close" | 
				
			|||
                         circle></el-button> | 
				
			|||
            </div> | 
				
			|||
            <div class="mw-phone"> | 
				
			|||
              <img class="mw-phone-topbar" | 
				
			|||
                   v-show="isInPreview" | 
				
			|||
                   src="@/assets/img/modules/wx-mini/index-set/page/wx-top.png"> | 
				
			|||
 | 
				
			|||
              <div class="mw-phone-top" | 
				
			|||
                   v-show="!isInPreview || topCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-left': topCptList.length>0}">({{ getCptRegionName('top') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt" | 
				
			|||
                          v-for="item in topCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
              <div class="mw-phone-ban" | 
				
			|||
                   v-show="!isInPreview || banCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-left': banCptList.length>0}">({{ getCptRegionName('ban') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt" | 
				
			|||
                          v-for="item in banCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
              <div class="mw-phone-fixed" | 
				
			|||
                   v-show="!isInPreview || fixedCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-down': fixedCptList.length>0}">({{ getCptRegionName('fixed') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt" | 
				
			|||
                          v-for="item in fixedCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
              <div class="mw-phone-cnt" | 
				
			|||
                   v-show="!isInPreview || cntCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-left': cntCptList.length>0}">({{ getCptRegionName('cnt') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt($event, index)" | 
				
			|||
                          v-for="(item, index) in cntCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
            </div> | 
				
			|||
          </div> | 
				
			|||
        </el-col> | 
				
			|||
 | 
				
			|||
        <el-col :span="6"> | 
				
			|||
          <transition v-show="focusedCpt.tempOnlyId" | 
				
			|||
                      name="el-zoom-in-top"> | 
				
			|||
            <div class="mw-set el-zoom-in-top" | 
				
			|||
                 v-if="focusedCpt.tempOnlyId"> | 
				
			|||
              <!-- <div class="d-set-head" | 
				
			|||
                   @click="focusedCpt.demoIsUnfold = !focusedCpt.demoIsUnfold"> | 
				
			|||
                <span class="d-title">演示数据</span> | 
				
			|||
                <img class="d-arrow" | 
				
			|||
                     :class="{'z-unfold': focusedCpt.demoIsUnfold}" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/arrow-down.png"> | 
				
			|||
              </div> | 
				
			|||
              <el-form v-show="focusedCpt.demoIsUnfold" | 
				
			|||
                       ref="form"> | 
				
			|||
                <el-form-item> | 
				
			|||
                  <el-input type="textarea" | 
				
			|||
                            v-model="focusedCpt.demoData"></el-input> | 
				
			|||
                </el-form-item> | 
				
			|||
              </el-form> --> | 
				
			|||
 | 
				
			|||
              <div class="d-set-head" | 
				
			|||
                   @click="focusedCpt.confIsUnfold = !focusedCpt.confIsUnfold"> | 
				
			|||
                <span class="d-title">高级选项--{{focusedCpt.componentName}}</span> | 
				
			|||
                <!-- <img class="d-arrow" | 
				
			|||
                     :class="{'z-unfold': focusedCpt.confIsUnfold}" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/arrow-down.png"> --> | 
				
			|||
              </div> | 
				
			|||
              <!-- <el-form v-show="focusedCpt.confIsUnfold" | 
				
			|||
                       ref="form"> --> | 
				
			|||
              <el-form ref="form"> | 
				
			|||
                <el-form-item> | 
				
			|||
                  <el-input type="textarea" | 
				
			|||
                            v-model="focusedCpt.configuration"></el-input> | 
				
			|||
                </el-form-item> | 
				
			|||
                <div class="d-config-hint" | 
				
			|||
                     v-show="focusedCpt.configurationDescription"> | 
				
			|||
                  <img src="@/assets/img/modules/wx-mini/index-set/info.png"> | 
				
			|||
                  <span>{{ focusedCpt.configurationDescription }}</span> | 
				
			|||
                </div> | 
				
			|||
                <div v-if="focusedCpt.componentFrontId === 'resi-functionList-heart-banner'" | 
				
			|||
                     class="d-set-banners"> | 
				
			|||
                  <span>Banner图</span> | 
				
			|||
                  <el-upload v-if="showFrom==='default'" | 
				
			|||
                             class="upload-demos" | 
				
			|||
                             :show-file-list="false" | 
				
			|||
                             :on-success="handleBannerSuccess" | 
				
			|||
                             :before-upload="beforeBannerUpload" | 
				
			|||
                             :action="uploadUlr"> | 
				
			|||
                    <i class="el-icon-plus avatar-uploader-icon"></i> | 
				
			|||
                  </el-upload> | 
				
			|||
                  <el-upload v-if="showFrom==='customize'" | 
				
			|||
                             class="upload-demos" | 
				
			|||
                             :show-file-list="false" | 
				
			|||
                             :on-success="handleBannerSuccess" | 
				
			|||
                             :before-upload="beforeBannerUpload" | 
				
			|||
                             :action="uploadUlrCustomize" | 
				
			|||
                             :data="{customerId:wxIndex.customerId}"> | 
				
			|||
                    <i class="el-icon-plus avatar-uploader-icon"></i> | 
				
			|||
                  </el-upload> | 
				
			|||
                </div> | 
				
			|||
 | 
				
			|||
              </el-form> | 
				
			|||
 | 
				
			|||
              <div class="d-operate"> | 
				
			|||
                <el-button type="default" | 
				
			|||
                           size="small" | 
				
			|||
                           round | 
				
			|||
                           @click="resetFocusedCptData">重置</el-button> | 
				
			|||
                <el-button type="success" | 
				
			|||
                           size="small" | 
				
			|||
                           round | 
				
			|||
                           @click="saveFocusedCptData">保存</el-button> | 
				
			|||
              </div> | 
				
			|||
            </div> | 
				
			|||
          </transition> | 
				
			|||
        </el-col> | 
				
			|||
      </el-row> | 
				
			|||
    </div> | 
				
			|||
  </div> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<style lang="scss" src="@/assets/scss/modules/wx-mini/index-set.scss"></style> | 
				
			|||
 | 
				
			|||
<script> | 
				
			|||
// import mixinViewModule from '@/mixins/view-module' | 
				
			|||
import componentWxcpt from '@/components/wx-index/cpt-item' | 
				
			|||
import { Loading } from 'element-ui' | 
				
			|||
import nextTick from 'dai-js/tools/nextTick' | 
				
			|||
import getRandomString from 'dai-js/tools/getRandomString' | 
				
			|||
import cloneDeep from 'lodash/cloneDeep' | 
				
			|||
import { requestPost } from "@/js/dai/request"; | 
				
			|||
let loading // 加载动画 | 
				
			|||
 | 
				
			|||
export default { | 
				
			|||
  data () { | 
				
			|||
    return { | 
				
			|||
      showFrom: "default",//来源:default  产品配置    customize  客户定制化 | 
				
			|||
 | 
				
			|||
      allComListUrl: "/oper/customize/customerhometemplate/getcomponentlist", //所有组件列表url | 
				
			|||
      setComListUrl: "/oper/customize/customerhometemplate/gethometemplate", //已配置组件列表url | 
				
			|||
      saveUrl: "/oper/customize/customerhometemplate/savecustomerhometemplate", //保存配置url | 
				
			|||
      publishUrl: "/oper/customize/home/distributehomedesign", //发布配置url | 
				
			|||
 | 
				
			|||
 | 
				
			|||
      wxIndex: { | 
				
			|||
        customerId: '', | 
				
			|||
        customerName: '', | 
				
			|||
        clientType: '' | 
				
			|||
      }, | 
				
			|||
 | 
				
			|||
      // 在预览中状态 | 
				
			|||
      isInPreview: false, | 
				
			|||
 | 
				
			|||
      // 可用列表 | 
				
			|||
      cptTypeList: [], | 
				
			|||
      // 当前应用组件列表 | 
				
			|||
      cptList: [ | 
				
			|||
 | 
				
			|||
      ], | 
				
			|||
      lastSavedCptList: [], | 
				
			|||
      focusedCpt: { | 
				
			|||
        tempOnlyId: '' | 
				
			|||
      }, | 
				
			|||
 | 
				
			|||
      uploadUlr: window.SITE_CONFIG['apiURL'] + '/oss/file/customerlogo/upload',//产品配置上传图片url | 
				
			|||
      uploadUlrCustomize: window.SITE_CONFIG['apiURL'] + '/oss/file/uploadqrcodeV2',//客户定制化上传图片url | 
				
			|||
 | 
				
			|||
      globalIndex: 0 | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  components: { | 
				
			|||
    'cpt-item': componentWxcpt | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  computed: { | 
				
			|||
    userType () { | 
				
			|||
      return localStorage.getItem('userType') | 
				
			|||
    }, | 
				
			|||
    cptTypeListTiled () { | 
				
			|||
      const { cptTypeList } = this | 
				
			|||
      let list = [] | 
				
			|||
      cptTypeList.forEach(item => { | 
				
			|||
        list = [...list, ...item.componentList] | 
				
			|||
      }) | 
				
			|||
      return list | 
				
			|||
    }, | 
				
			|||
    topCptList () { | 
				
			|||
      return this.cptList.filter(item => this.checkCptRegion(item) === 'top') | 
				
			|||
    }, | 
				
			|||
    banCptList () { | 
				
			|||
      return this.cptList.filter(item => this.checkCptRegion(item) === 'ban') | 
				
			|||
    }, | 
				
			|||
    cntCptList () { | 
				
			|||
      let arr = this.cptList.filter(item => this.checkCptRegion(item) === 'cnt') | 
				
			|||
      arr.sort((f, s) => f.displayOrder - s.displayOrder) | 
				
			|||
      return arr | 
				
			|||
    }, | 
				
			|||
    fixedCptList () { | 
				
			|||
      return this.cptList.filter(item => this.checkCptRegion(item) === 'fixed') | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  mounted () { | 
				
			|||
    //判断登录入口:work(工作端pc),oper(运营端),如果是前者,从缓存获取登陆者信息 | 
				
			|||
    const userType = localStorage.getItem('userType') | 
				
			|||
    if (userType === 'work') { | 
				
			|||
      this.startSetWxIndex(localStorage.getItem('customerId'), localStorage.getItem('customerName'), 0) | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  methods: { | 
				
			|||
    // 选择用户开始配置 | 
				
			|||
    async startSetWxIndex (id, name, type, showFrom) { | 
				
			|||
      this.wxIndex.customerId = id | 
				
			|||
      this.wxIndex.customerName = name | 
				
			|||
      this.wxIndex.clientType = type | 
				
			|||
      this.showFrom = showFrom | 
				
			|||
 | 
				
			|||
      if (this.showFrom === 'customize') {//客户定制化 | 
				
			|||
        this.allComListUrl = "/oper/customize/home/getcomponentlistbycustomer" | 
				
			|||
        this.setComListUrl = "/oper/customize/home/gethomedesignbycustomer" | 
				
			|||
        this.saveUrl = "/oper/customize/home/savehomedesign" | 
				
			|||
 | 
				
			|||
      } else {//产品配置 | 
				
			|||
        this.allComListUrl = "/oper/customize/customerhometemplate/getcomponentlist" //所有组件列表url | 
				
			|||
        this.setComListUrl = "/oper/customize/customerhometemplate/gethometemplate" //已配置组件列表url | 
				
			|||
        this.saveUrl = "/oper/customize/customerhometemplate/savecustomerhometemplate" //保存配置url | 
				
			|||
 | 
				
			|||
      } | 
				
			|||
 | 
				
			|||
      this.startLoading() | 
				
			|||
      await this.getAllComList() | 
				
			|||
      await this.getSetComList() | 
				
			|||
 | 
				
			|||
      this.cleanFocusCpt() | 
				
			|||
      this.endLoading() | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    //字符串转化为json | 
				
			|||
    stringToJson (item) { | 
				
			|||
      let demoData = {} | 
				
			|||
      let configuration = {} | 
				
			|||
      const tempOnlyId = getRandomString(20) | 
				
			|||
      try { | 
				
			|||
        demoData = JSON.parse(item.demoData) | 
				
			|||
        configuration = JSON.parse(item.configuration) | 
				
			|||
      } catch (err) { | 
				
			|||
        console.log("错误项", item) | 
				
			|||
        console.log(err) | 
				
			|||
      } | 
				
			|||
      return { tempOnlyId, ...item, demoData, configuration } | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 获取所有可用组件列表 | 
				
			|||
    async getAllComList () { | 
				
			|||
      const { wxIndex: { clientType, customerId } } = this | 
				
			|||
 | 
				
			|||
      const { data, code, msg } = await requestPost(this.allComListUrl, { clientType, customerId }) | 
				
			|||
      if (code === 0) { | 
				
			|||
        if (data) { | 
				
			|||
          let list = [{ | 
				
			|||
            functionId: '0', | 
				
			|||
            functionName: '通用组件', | 
				
			|||
            functionType: 1, // 1通用 2功能 | 
				
			|||
            isUnfold: true, | 
				
			|||
            componentList: data.commonList.map(this.stringToJson) | 
				
			|||
          }, ...data.functionList.map(item => { | 
				
			|||
            return { | 
				
			|||
              functionId: item.functionId, | 
				
			|||
              functionName: item.functionName, | 
				
			|||
              functionType: 2, // 1通用 2功能 | 
				
			|||
              isUnfold: false, | 
				
			|||
              componentList: item.componentList.map(this.stringToJson) | 
				
			|||
            } | 
				
			|||
          })] | 
				
			|||
          this.cptTypeList = list | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
      } else { | 
				
			|||
        this.$message.error(msg) | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 获取用户当前保存的组件列表 | 
				
			|||
    async getSetComList () { | 
				
			|||
      const { wxIndex: { clientType, customerId } } = this | 
				
			|||
 | 
				
			|||
      const { data, code, msg } = await requestPost(this.setComListUrl, { clientType, customerId }) | 
				
			|||
      if (code === 0) { | 
				
			|||
        if (data) { | 
				
			|||
          let list = [ | 
				
			|||
            ...data.titleList, | 
				
			|||
            ...data.topList, | 
				
			|||
            ...data.functionList, | 
				
			|||
            ...data.floatingList | 
				
			|||
          ] | 
				
			|||
          this.cptList = list.map(this.stringToJson) | 
				
			|||
          this.lastSavedCptList = cloneDeep(this.cptList) | 
				
			|||
        } | 
				
			|||
      } else { | 
				
			|||
        this.$message.error(msg) | 
				
			|||
      } | 
				
			|||
 | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 保存配置 | 
				
			|||
    async save () { | 
				
			|||
      const { wxIndex: { clientType, customerId }, cptList } = this | 
				
			|||
      const componentList = cptList.map(item => { | 
				
			|||
        return { | 
				
			|||
          componentId: item.componentId, | 
				
			|||
          region: item.region, | 
				
			|||
          displayOrder: item.displayOrder, | 
				
			|||
          demoData: JSON.stringify(item.demoData), | 
				
			|||
          configuration: JSON.stringify(item.configuration) | 
				
			|||
        } | 
				
			|||
      }) | 
				
			|||
 | 
				
			|||
      const { data, code, msg } = await requestPost(this.saveUrl, { clientType, customerId, componentList }) | 
				
			|||
      if (code === 0) { | 
				
			|||
        this.lastSavedCptList = cloneDeep(this.cptList) | 
				
			|||
        this.$message.success('保存成功') | 
				
			|||
      } else { | 
				
			|||
        this.$message.error(msg) | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 发布配置 | 
				
			|||
    async handelPublish () { | 
				
			|||
      const { cptList } = this | 
				
			|||
      const componentList = cptList.map(item => { | 
				
			|||
        return { | 
				
			|||
          componentId: item.componentId, | 
				
			|||
          region: item.region, | 
				
			|||
          displayOrder: item.displayOrder, | 
				
			|||
          demoData: JSON.stringify(item.demoData), | 
				
			|||
          configuration: JSON.stringify(item.configuration) | 
				
			|||
        } | 
				
			|||
      }) | 
				
			|||
      if (componentList.length === 0) { | 
				
			|||
        return this.$message.error('您尚未选择任何组件,不能发布') | 
				
			|||
      } | 
				
			|||
      return this.$confirm('目前的设置会呈现在所有用户的小程序上,是否继续发布?', '确认发布', { | 
				
			|||
        confirmButtonText: '确定', | 
				
			|||
        cancelButtonText: '取消', | 
				
			|||
        type: 'warning' | 
				
			|||
      }).then(() => { | 
				
			|||
        this.publish(componentList) | 
				
			|||
 | 
				
			|||
      }).catch((err) => { | 
				
			|||
        console.log(err) | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    async publish (componentList) { | 
				
			|||
      const { wxIndex: { clientType, customerId } } = this | 
				
			|||
      const { data, code, msg } = await requestPost(this.publish, { clientType, customerId, componentList }) | 
				
			|||
      if (code === 0) { | 
				
			|||
        this.lastSavedCptList = cloneDeep(this.cptList) | 
				
			|||
        return this.$message.success('发布成功') | 
				
			|||
 | 
				
			|||
      } else { | 
				
			|||
        this.$message.error(msg) | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 判断组件所属区域类别 | 
				
			|||
    checkCptRegion (item) { | 
				
			|||
      const { region } = item | 
				
			|||
      if (region === 'titleList') { | 
				
			|||
        return 'top' | 
				
			|||
      } else if (region === 'topList') { | 
				
			|||
        return 'ban' | 
				
			|||
      } else if (region === 'functionList') { | 
				
			|||
        return 'cnt' | 
				
			|||
      } else if (region === 'floatingList') { | 
				
			|||
        return 'fixed' | 
				
			|||
      } else { | 
				
			|||
        return 'none' | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 判断组件是否可用复用 | 
				
			|||
    checkCptReuse (item) { | 
				
			|||
      const { componentFrontId } = item | 
				
			|||
      const reuseList = this.cptTypeList[0].componentList.map(v => v.componentFrontId) | 
				
			|||
      const fun = name => name === componentFrontId | 
				
			|||
      return reuseList.findIndex(fun) !== -1 | 
				
			|||
    }, | 
				
			|||
    // 根据所属区域简称得到名字 | 
				
			|||
    getCptRegionName (id) { | 
				
			|||
      return { | 
				
			|||
        'top': '标题区', | 
				
			|||
        'ban': '置顶区', | 
				
			|||
        'fixed': '浮窗区', | 
				
			|||
        'cnt': '功能区', | 
				
			|||
        'none': '' | 
				
			|||
      }[id] | 
				
			|||
    }, | 
				
			|||
    // 添加组件到实例-前验证 | 
				
			|||
    beforeAddCpt (item) { | 
				
			|||
      const regionType = this.checkCptRegion(item) | 
				
			|||
      const tempOnlyId = getRandomString(20) | 
				
			|||
      if (regionType === 'top') { | 
				
			|||
        if (this.topCptList.length > 0) { | 
				
			|||
          this.$message('标题区已有组件,请删除后再添加') | 
				
			|||
        } else { | 
				
			|||
          this.addCpt(item, tempOnlyId) | 
				
			|||
        } | 
				
			|||
      } else if (regionType === 'ban') { | 
				
			|||
        if (this.banCptList.length > 0) { | 
				
			|||
          this.$message('置顶区已有组件,请删除后再添加') | 
				
			|||
        } else { | 
				
			|||
          this.addCpt(item, tempOnlyId) | 
				
			|||
        } | 
				
			|||
      } else if (regionType === 'fixed') { | 
				
			|||
        if (this.fixedCptList.length > 0) { | 
				
			|||
          this.$message('浮窗区已有组件,请删除后再添加') | 
				
			|||
        } else { | 
				
			|||
          this.addCpt(item, tempOnlyId) | 
				
			|||
        } | 
				
			|||
      } else if (regionType === 'cnt') { | 
				
			|||
        this.cntCptListResort() | 
				
			|||
        this.addCpt(item, tempOnlyId, (this.cntCptList.length + 1) * 10) | 
				
			|||
      } else { | 
				
			|||
        return false | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 实例内容组件重置displayOrder属性 | 
				
			|||
    cntCptListResort () { | 
				
			|||
      console.log('实例内容组件重置displayOrder属性') | 
				
			|||
      this.cntCptList.forEach((item, index) => { | 
				
			|||
        item.displayOrder = (index + 1) * 10 | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 添加组件到实例 | 
				
			|||
    addCpt (item, tempOnlyId, displayOrder = 0) { | 
				
			|||
      console.log('添加组件到实例') | 
				
			|||
      let trueItem = cloneDeep(item) | 
				
			|||
      trueItem.tempOnlyId = tempOnlyId | 
				
			|||
      trueItem.displayOrder = displayOrder | 
				
			|||
      this.cptList.push(trueItem) | 
				
			|||
    }, | 
				
			|||
    // 改变实例组件显示顺序 | 
				
			|||
    async changeCptDisplayOrder (item, type) { | 
				
			|||
      console.log('改变实例组件显示顺序') | 
				
			|||
      if (type === 'up') { | 
				
			|||
        item.displayOrder -= 11 | 
				
			|||
      } else if (type === 'down') { | 
				
			|||
        item.displayOrder += 11 | 
				
			|||
      } | 
				
			|||
      await nextTick() | 
				
			|||
      this.cntCptListResort() | 
				
			|||
    }, | 
				
			|||
    // 删除组件 | 
				
			|||
    delCpt (item) { | 
				
			|||
      this.cptList = this.cptList.filter(cptItem => item.tempOnlyId !== cptItem.tempOnlyId) | 
				
			|||
      if (this.focusedCpt.tempOnlyId === item.tempOnlyId) { | 
				
			|||
        this.focusedCpt = { tempOnlyId: '' } | 
				
			|||
      } | 
				
			|||
      this.cntCptListResort() | 
				
			|||
    }, | 
				
			|||
    // 检测实例中是否存在某种类型组件 | 
				
			|||
    checkExistCpt (item) { | 
				
			|||
      return this.cptList.some(cptItem => item.componentFrontId === cptItem.componentFrontId) | 
				
			|||
    }, | 
				
			|||
    // 清空聚焦实例组件 | 
				
			|||
    cleanFocusCpt () { | 
				
			|||
      this.focusedCpt = { tempOnlyId: '' } | 
				
			|||
    }, | 
				
			|||
    // 聚焦实例组件 | 
				
			|||
    focusCpt (item, index) { | 
				
			|||
      console.log('聚焦实例组件', item, index) | 
				
			|||
 | 
				
			|||
      this.globalIndex = index | 
				
			|||
      if (this.isInPreview) return | 
				
			|||
      if (this.focusedCpt.tempOnlyId === item.tempOnlyId) { | 
				
			|||
        this.cleanFocusCpt() | 
				
			|||
      } else { | 
				
			|||
        this.focusedCpt = { ...cloneDeep(item), demoData: JSON.stringify(item.demoData), configuration: JSON.stringify(item.configuration), demoIsUnfold: true, confIsUnfold: false } | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 保存聚焦组件数据 | 
				
			|||
    saveFocusedCptData () { | 
				
			|||
      const { focusedCpt } = this | 
				
			|||
      this.cptList.forEach(item => { | 
				
			|||
        if (item.tempOnlyId === focusedCpt.tempOnlyId) { | 
				
			|||
          try { | 
				
			|||
            item.demoData = JSON.parse(focusedCpt.demoData) | 
				
			|||
            item.configuration = JSON.parse(focusedCpt.configuration) | 
				
			|||
          } catch (err) { | 
				
			|||
            this.$alert('json数据格式有误', '无法保存', { | 
				
			|||
              confirmButtonText: '确定' | 
				
			|||
            }) | 
				
			|||
            console.log(err) | 
				
			|||
          } | 
				
			|||
        } | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 重置聚焦组件数据,重置为上次整体保存时的数据 | 
				
			|||
    resetFocusedCptData () { | 
				
			|||
      const { focusedCpt } = this | 
				
			|||
      const fun = item => { | 
				
			|||
        if (item.tempOnlyId === focusedCpt.tempOnlyId) { | 
				
			|||
          focusedCpt.demoData = JSON.stringify(item.demoData) | 
				
			|||
          focusedCpt.configuration = JSON.stringify(item.configuration) | 
				
			|||
          return true | 
				
			|||
        } else { | 
				
			|||
          return false | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
      if (!this.lastSavedCptList.some(fun)) { | 
				
			|||
        this.cptTypeListTiled.forEach(item => { | 
				
			|||
          if (item.componentFrontId === focusedCpt.componentFrontId) { | 
				
			|||
            focusedCpt.demoData = JSON.stringify(item.demoData) | 
				
			|||
            focusedCpt.configuration = JSON.stringify(item.configuration) | 
				
			|||
          } | 
				
			|||
        }) | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 改变可用列表组件展开与收起 | 
				
			|||
    shiftCptTypeItemUnfold (item) { | 
				
			|||
      item.isUnfold = !item.isUnfold | 
				
			|||
    }, | 
				
			|||
    // 上传爱心互助banner图 | 
				
			|||
    beforeBannerUpload (file) { | 
				
			|||
      console.log('file', file.size / 1024) | 
				
			|||
      let testmsg = file.name.substring(file.name.lastIndexOf('.') + 1) | 
				
			|||
      const imgs = ['png', 'PNG'] | 
				
			|||
      const extension = imgs.includes(testmsg) | 
				
			|||
      const isLt2M = file.size / 1024 < 100 | 
				
			|||
 | 
				
			|||
      if (!extension) { | 
				
			|||
        this.$message.error('上传图片只能是png格式!') | 
				
			|||
      } | 
				
			|||
      if (!isLt2M) { | 
				
			|||
        this.$message.error('上传图片大小不能超过 100KB!') | 
				
			|||
      } | 
				
			|||
      return extension && isLt2M | 
				
			|||
    }, | 
				
			|||
    handleBannerSuccess (res, file) { | 
				
			|||
      console.log('res', res) | 
				
			|||
      console.log('files', file) | 
				
			|||
      if (res.code === 0 && res.msg === 'success') { | 
				
			|||
        this.focusedCpt.configuration = { | 
				
			|||
          url: res.data.url | 
				
			|||
        } | 
				
			|||
        this.cntCptList[this.globalIndex].demoData.pic = res.data.url | 
				
			|||
        this.focusedCpt.configuration = JSON.stringify(this.focusedCpt.configuration) | 
				
			|||
        this.focusedCpt.demoData = JSON.stringify(this.cntCptList[this.globalIndex].demoData) | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 开启加载动画 | 
				
			|||
    startLoading () { | 
				
			|||
      loading = Loading.service({ | 
				
			|||
        lock: true, // 是否锁定 | 
				
			|||
        text: '正在加载……', // 加载中需要显示的文字 | 
				
			|||
        background: 'rgba(0,0,0,.7)' // 背景颜色 | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 结束加载动画 | 
				
			|||
    endLoading () { | 
				
			|||
      // clearTimeout(timer); | 
				
			|||
      if (loading) { | 
				
			|||
        loading.close() | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 取消 | 
				
			|||
    diaCancel () { | 
				
			|||
      this.$emit('cancleBack') | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</script> | 
				
			|||
@ -0,0 +1,924 @@ | 
				
			|||
<template> | 
				
			|||
  <div> | 
				
			|||
    <el-card v-show="step==1" | 
				
			|||
             shadow="never" | 
				
			|||
             class="aui-card--fill"> | 
				
			|||
      <el-button type="text" | 
				
			|||
                 size="small" | 
				
			|||
                 @click="startSetWxIndex('', '', 0)">居民端</el-button> | 
				
			|||
      <el-button type="text" | 
				
			|||
                 size="small" | 
				
			|||
                 @click="startSetWxIndex('', '', 1)">工作端</el-button> | 
				
			|||
    </el-card> | 
				
			|||
 | 
				
			|||
    <div class="m-wx_index" | 
				
			|||
         v-show="step==2"> | 
				
			|||
      <el-button type="default" | 
				
			|||
                 @click="toStep(1)">取消返回</el-button> | 
				
			|||
      <el-button type="info" | 
				
			|||
                 @click="isInPreview = true">预览</el-button> | 
				
			|||
      <el-button type="success" | 
				
			|||
                 @click="save">保存</el-button> | 
				
			|||
      <!-- <el-button type="danger" | 
				
			|||
                 @click="publish">发布</el-button> --> | 
				
			|||
      <span style="margin-left:20px; color:#aaa; font-size:13px">({{ wxIndex.clientType===1 ? '工作端' : '居民端' }})</span> | 
				
			|||
 | 
				
			|||
      <el-row class="wrap" | 
				
			|||
              :gutter="20"> | 
				
			|||
        <el-col :span="5"> | 
				
			|||
          <h4>选择组件</h4> | 
				
			|||
          <div class="mw-cpt_type"> | 
				
			|||
            <div class="d-function" | 
				
			|||
                 v-show="item.componentList.length > 0" | 
				
			|||
                 :key="item.functionId" | 
				
			|||
                 v-for="item in cptTypeList"> | 
				
			|||
              <div class="d-info" | 
				
			|||
                   @click="shiftCptTypeItemUnfold(item)"> | 
				
			|||
                <img v-if="item.functionName=='议事厅'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt1.png"> | 
				
			|||
                <img v-else-if="item.functionName=='社群'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt2.png"> | 
				
			|||
                <img v-else-if="item.functionName=='党建声音'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt3.png"> | 
				
			|||
                <img v-else-if="item.functionName=='消息通知'" | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/function-cpt4.png"> | 
				
			|||
                <img v-else | 
				
			|||
                     class="d-ico" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/common-cpt.png"> | 
				
			|||
 | 
				
			|||
                <span class="d-name">{{ item.functionName }}</span> | 
				
			|||
 | 
				
			|||
                <img class="d-arrow" | 
				
			|||
                     :class="{'z-unfold': item.isUnfold}" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/arrow-down.png"> | 
				
			|||
              </div> | 
				
			|||
              <div class="d-list" | 
				
			|||
                   v-show="item.isUnfold"> | 
				
			|||
                <div class="d-item" | 
				
			|||
                     :key="cptItem.componentId" | 
				
			|||
                     v-for="cptItem in item.componentList"> | 
				
			|||
                  <span class="d-item-region">({{ getCptRegionName(checkCptRegion(cptItem)) }})</span> | 
				
			|||
                  <span class="d-item-name">{{ cptItem.componentName }}</span> | 
				
			|||
                  <span class="d-item-btn z-disabled" | 
				
			|||
                        v-if="!checkCptReuse(cptItem) && checkExistCpt(cptItem)">已添加</span> | 
				
			|||
                  <span class="d-item-btn" | 
				
			|||
                        v-else | 
				
			|||
                        @click="beforeAddCpt(cptItem)"> | 
				
			|||
                    <img src="@/assets/img/modules/wx-mini/index-set/add.png"> | 
				
			|||
                    <span>添加</span> | 
				
			|||
                  </span> | 
				
			|||
                </div> | 
				
			|||
              </div> | 
				
			|||
            </div> | 
				
			|||
          </div> | 
				
			|||
        </el-col> | 
				
			|||
        <el-col :span="13"> | 
				
			|||
          <div class="mw-show" | 
				
			|||
               :class="{'z-preview': isInPreview}"> | 
				
			|||
            <div v-show="isInPreview" | 
				
			|||
                 class="mw-show-close"> | 
				
			|||
              <el-button type="default" | 
				
			|||
                         @click="isInPreview = false" | 
				
			|||
                         icon="el-icon-close" | 
				
			|||
                         circle></el-button> | 
				
			|||
            </div> | 
				
			|||
            <div class="mw-phone"> | 
				
			|||
              <img class="mw-phone-topbar" | 
				
			|||
                   v-show="isInPreview" | 
				
			|||
                   src="@/assets/img/modules/wx-mini/index-set/page/wx-top.png"> | 
				
			|||
 | 
				
			|||
              <div class="mw-phone-top" | 
				
			|||
                   v-show="!isInPreview || topCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-left': topCptList.length>0}">({{ getCptRegionName('top') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt" | 
				
			|||
                          v-for="item in topCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
              <div class="mw-phone-ban" | 
				
			|||
                   v-show="!isInPreview || banCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-left': banCptList.length>0}">({{ getCptRegionName('ban') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt" | 
				
			|||
                          v-for="item in banCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
              <div class="mw-phone-fixed" | 
				
			|||
                   v-show="!isInPreview || fixedCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-down': fixedCptList.length>0}">({{ getCptRegionName('fixed') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt" | 
				
			|||
                          v-for="item in fixedCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
              <div class="mw-phone-cnt" | 
				
			|||
                   v-show="!isInPreview || cntCptList.length>0" | 
				
			|||
                   :class="{'z-none': !isInPreview}"> | 
				
			|||
                <div class="mw-phone-hint" | 
				
			|||
                     v-show="!isInPreview" | 
				
			|||
                     :class="{'z-out-left': cntCptList.length>0}">({{ getCptRegionName('cnt') }})</div> | 
				
			|||
                <cpt-item :item="item" | 
				
			|||
                          :key="item.tempOnlyId" | 
				
			|||
                          :is-focused="focusedCpt.tempOnlyId===item.tempOnlyId" | 
				
			|||
                          @del="delCpt" | 
				
			|||
                          @sort="changeCptDisplayOrder" | 
				
			|||
                          @focus="focusCpt($event, index)" | 
				
			|||
                          v-for="(item, index) in cntCptList"></cpt-item> | 
				
			|||
              </div> | 
				
			|||
            </div> | 
				
			|||
          </div> | 
				
			|||
        </el-col> | 
				
			|||
        <el-col :span="6"> | 
				
			|||
          <transition v-show="focusedCpt.tempOnlyId" | 
				
			|||
                      name="el-zoom-in-top"> | 
				
			|||
            <div class="mw-set el-zoom-in-top" | 
				
			|||
                 v-if="focusedCpt.tempOnlyId"> | 
				
			|||
              <!-- <div class="d-set-head" | 
				
			|||
                   @click="focusedCpt.demoIsUnfold = !focusedCpt.demoIsUnfold"> | 
				
			|||
                <span class="d-title">演示数据</span> | 
				
			|||
                <img class="d-arrow" | 
				
			|||
                     :class="{'z-unfold': focusedCpt.demoIsUnfold}" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/arrow-down.png"> | 
				
			|||
              </div> | 
				
			|||
              <el-form v-show="focusedCpt.demoIsUnfold" | 
				
			|||
                       ref="form"> | 
				
			|||
                <el-form-item> | 
				
			|||
                  <el-input type="textarea" | 
				
			|||
                            v-model="focusedCpt.demoData"></el-input> | 
				
			|||
                </el-form-item> | 
				
			|||
              </el-form> --> | 
				
			|||
 | 
				
			|||
              <div class="d-set-head" | 
				
			|||
                   @click="focusedCpt.confIsUnfold = !focusedCpt.confIsUnfold"> | 
				
			|||
                <span class="d-title">高级选项--{{focusedCpt.componentName}}</span> | 
				
			|||
                <!-- <img class="d-arrow" | 
				
			|||
                     :class="{'z-unfold': focusedCpt.confIsUnfold}" | 
				
			|||
                     src="@/assets/img/modules/wx-mini/index-set/arrow-down.png"> --> | 
				
			|||
              </div> | 
				
			|||
              <!-- <el-form v-show="focusedCpt.confIsUnfold" | 
				
			|||
                       ref="form"> --> | 
				
			|||
              <el-form ref="form"> | 
				
			|||
                <el-form-item> | 
				
			|||
                  <el-input type="textarea" | 
				
			|||
                            v-model="focusedCpt.configuration"></el-input> | 
				
			|||
                </el-form-item> | 
				
			|||
                <div class="d-config-hint" | 
				
			|||
                     v-show="focusedCpt.configurationDescription"> | 
				
			|||
                  <img src="@/assets/img/modules/wx-mini/index-set/info.png"> | 
				
			|||
                  <span>{{ focusedCpt.configurationDescription }}</span> | 
				
			|||
                </div> | 
				
			|||
                <div v-if="focusedCpt.componentFrontId === 'resi-functionList-heart-banner'" | 
				
			|||
                     class="d-set-banners"> | 
				
			|||
                  <span>Banner图</span> | 
				
			|||
                  <el-upload class="upload-demos" | 
				
			|||
                             :show-file-list="false" | 
				
			|||
                             :on-success="handleBannerSuccess" | 
				
			|||
                             :before-upload="beforeBannerUpload" | 
				
			|||
                             :action="uploadUlr"> | 
				
			|||
                    <i class="el-icon-plus avatar-uploader-icon"></i> | 
				
			|||
                  </el-upload> | 
				
			|||
                </div> | 
				
			|||
 | 
				
			|||
              </el-form> | 
				
			|||
 | 
				
			|||
              <div class="d-operate"> | 
				
			|||
                <el-button type="default" | 
				
			|||
                           size="small" | 
				
			|||
                           round | 
				
			|||
                           @click="resetFocusedCptData">重置</el-button> | 
				
			|||
                <el-button type="success" | 
				
			|||
                           size="small" | 
				
			|||
                           round | 
				
			|||
                           @click="saveFocusedCptData">保存</el-button> | 
				
			|||
              </div> | 
				
			|||
            </div> | 
				
			|||
          </transition> | 
				
			|||
        </el-col> | 
				
			|||
      </el-row> | 
				
			|||
    </div> | 
				
			|||
  </div> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<style lang="scss" src="@/assets/scss/modules/wx-mini/index-set.scss"></style> | 
				
			|||
 | 
				
			|||
<script> | 
				
			|||
import mixinViewModule from '@/mixins/view-module' | 
				
			|||
import componentWxcpt from '@/components/wx-index/cpt-item' | 
				
			|||
import { Loading } from 'element-ui' | 
				
			|||
import nextTick from 'dai-js/tools/nextTick' | 
				
			|||
import getRandomString from 'dai-js/tools/getRandomString' | 
				
			|||
import cloneDeep from 'lodash/cloneDeep' | 
				
			|||
 | 
				
			|||
// 处理获得mock测试接口地址 | 
				
			|||
const getMockFilterUrl = (url) => { | 
				
			|||
  const usedMockTest = false | 
				
			|||
  const mockBaseUrl = 'https://nei.netease.com/api/apimock/30f0251f1b7dc90a8c38e3c634ef2a8b/api' | 
				
			|||
  if (usedMockTest) { | 
				
			|||
    return mockBaseUrl + url | 
				
			|||
  } else { | 
				
			|||
    return url | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// 当前是否是开发环境 | 
				
			|||
const envIsDev = process.env.VUE_APP_NODE_ENV === 'dev' | 
				
			|||
 | 
				
			|||
export default { | 
				
			|||
  mixins: [mixinViewModule], | 
				
			|||
  data () { | 
				
			|||
    const cptTypeListTestdata = [ | 
				
			|||
      // 通用组件 | 
				
			|||
      { | 
				
			|||
        functionId: '0', | 
				
			|||
        functionName: '通用组件', | 
				
			|||
        functionType: 1, // 1通用 2功能 | 
				
			|||
        isUnfold: true, | 
				
			|||
        componentList: [ | 
				
			|||
          { | 
				
			|||
            componentId: '7', | 
				
			|||
            componentName: '最新议题', | 
				
			|||
            componentFrontId: 'resi-functionList-hall-latestIssueList', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              num: 3 | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '最新议题的标题。最新议题的标题。最新议题的标题。最新议题的标题。', | 
				
			|||
                  content: '最新议题的内容,最新议题的内容,最新议题的内容。', | 
				
			|||
                  author: '山东路45号-刘女士', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '最新议题的标题。', | 
				
			|||
                  content: '最新议题的内容,最新议题的内容,最新议题的内容。', | 
				
			|||
                  author: '山东路45号-刘女士', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '最新议题的标题。', | 
				
			|||
                  content: '最新议题的内容,最新议题的内容,最新议题的内容。', | 
				
			|||
                  author: '山东路45号-刘女士', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '8', | 
				
			|||
            componentName: '最新发布', | 
				
			|||
            componentFrontId: 'resi-functionList-voice-newsList', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              num: 3 | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  pic: '', | 
				
			|||
                  title: '新型冠状病毒检测重大突破!新型冠状病毒检测重大突破!!!', | 
				
			|||
                  author: '大港路党支部', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  pic: '', | 
				
			|||
                  title: '新型冠状病毒检测重大突破!', | 
				
			|||
                  author: '大港路党支部', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  pic: '', | 
				
			|||
                  title: '新型冠状病毒检测重大突破!', | 
				
			|||
                  author: '大港路党支部', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '9', | 
				
			|||
            componentName: '结案项目', | 
				
			|||
            componentFrontId: 'resi-functionList-hall-closedProjectList', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              num: 3 | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  title: '结案项目的标题。', | 
				
			|||
                  content: '结案项目的内容,结案项目的内容,结案项目的内容。', | 
				
			|||
                  author: '党支部-卫生部门', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  title: '结案项目的标题。', | 
				
			|||
                  content: '结案项目的内容,结案项目的内容,结案项目的内容。', | 
				
			|||
                  author: '党支部-卫生部门', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  title: '结案项目的标题。', | 
				
			|||
                  content: '结案项目的内容,结案项目的内容,结案项目的内容。', | 
				
			|||
                  author: '党支部-卫生部门', | 
				
			|||
                  date: '2020-01-02' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          } | 
				
			|||
        ] | 
				
			|||
      }, | 
				
			|||
      // 功能组件 | 
				
			|||
      { | 
				
			|||
        functionId: '1', | 
				
			|||
        functionName: '议事厅', | 
				
			|||
        functionType: 2, // 1通用 2功能 | 
				
			|||
        isUnfold: false, | 
				
			|||
        componentList: [ | 
				
			|||
          { | 
				
			|||
            componentId: '1', | 
				
			|||
            componentName: '顶部标题', | 
				
			|||
            componentFrontId: 'resi-titleList-home-gridNameTitle', | 
				
			|||
            configuration: { | 
				
			|||
              // content: '' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              ico: '', | 
				
			|||
              avatar: '', | 
				
			|||
              title: '青岛市市北区大港路第二网格' | 
				
			|||
            }, | 
				
			|||
            region: 'titleList', | 
				
			|||
            configurationDescription: '请配置具体内容' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '2', | 
				
			|||
            componentName: '轮播图', | 
				
			|||
            componentFrontId: 'resi-topList-voice-hotNewsSwiper', | 
				
			|||
            configuration: { | 
				
			|||
              // content: '' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              pic: '', | 
				
			|||
              title: '轮播图新闻标题' | 
				
			|||
            }, | 
				
			|||
            region: 'topList', | 
				
			|||
            configurationDescription: '请配置具体内容' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '3', | 
				
			|||
            componentName: '消息通知', | 
				
			|||
            componentFrontId: 'resi-floatingList-mine-newMessageButton', | 
				
			|||
            configuration: { | 
				
			|||
              // content: '' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              ico: '', | 
				
			|||
              text: '有新消息!' | 
				
			|||
            }, | 
				
			|||
            region: 'floatingList', | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '5', | 
				
			|||
            componentName: '功能菜单', | 
				
			|||
            componentFrontId: 'resi-functionList-extend-moreFunctionIcons', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              // bgc: '#eee' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '议事厅' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '社群' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '党建声音' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  text: '更多功能' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          }, | 
				
			|||
          { | 
				
			|||
            componentId: '6', | 
				
			|||
            componentName: '热门群', | 
				
			|||
            componentFrontId: 'resi-functionList-group-recommendGroupSlider', | 
				
			|||
            region: 'functionList', | 
				
			|||
            configuration: { | 
				
			|||
              // bgc: '#fff' | 
				
			|||
            }, | 
				
			|||
            demoData: { | 
				
			|||
              list: [ | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  no: '1', | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '群名称', | 
				
			|||
                  info1: '山东路45号-张三', | 
				
			|||
                  info2: '共240人', | 
				
			|||
                  info3: '党员11人' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  no: '2', | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '群名称', | 
				
			|||
                  info1: '山东路45号-张三', | 
				
			|||
                  info2: '共240人', | 
				
			|||
                  info3: '党员11人' | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                  ico: '', | 
				
			|||
                  no: '3', | 
				
			|||
                  avatar: '', | 
				
			|||
                  title: '群名称', | 
				
			|||
                  info1: '山东路45号-张三', | 
				
			|||
                  info2: '共240人', | 
				
			|||
                  info3: '党员11人' | 
				
			|||
                } | 
				
			|||
              ] | 
				
			|||
            }, | 
				
			|||
            configurationDescription: '' | 
				
			|||
          } | 
				
			|||
        ] | 
				
			|||
      } | 
				
			|||
    ] | 
				
			|||
    return { | 
				
			|||
      mixinViewModuleOptions: { | 
				
			|||
        getDataListURL: getMockFilterUrl('/oper/crm/customer/getvalidcustomerlist'), | 
				
			|||
        getDataListIsPage: false | 
				
			|||
      }, | 
				
			|||
 | 
				
			|||
      dataList: !envIsDev ? [] : [ | 
				
			|||
        { | 
				
			|||
          customerName: '测试1', | 
				
			|||
          customerId: '1' | 
				
			|||
        }, | 
				
			|||
        { | 
				
			|||
          customerName: '测试2', | 
				
			|||
          customerId: '2' | 
				
			|||
        } | 
				
			|||
      ], | 
				
			|||
 | 
				
			|||
      // 步骤: 1列表选择 2首页配置 | 
				
			|||
      step: 1, | 
				
			|||
 | 
				
			|||
      wxIndex: { | 
				
			|||
        customerId: '', | 
				
			|||
        customerName: '', | 
				
			|||
        clientType: '' | 
				
			|||
      }, | 
				
			|||
 | 
				
			|||
      // 在预览中状态 | 
				
			|||
      isInPreview: false, | 
				
			|||
 | 
				
			|||
      // 可用列表 | 
				
			|||
      cptTypeList: !envIsDev ? [] : cptTypeListTestdata, | 
				
			|||
      // 当前应用组件列表 | 
				
			|||
      cptList: [ | 
				
			|||
        // { | 
				
			|||
        //   componentId: '1', | 
				
			|||
        //   componentName: '顶部标题', | 
				
			|||
        //   componentFrontId: 'top_title', | 
				
			|||
        //   configuration: { | 
				
			|||
        //     content: '青岛市党委' | 
				
			|||
        //   }, | 
				
			|||
        //   demoData: { | 
				
			|||
        //     content: '我是标题' | 
				
			|||
        //   }, | 
				
			|||
        //   configurationDescription: '请配置具体内容', | 
				
			|||
        //   displayOrder: 1, | 
				
			|||
        //   region: 1 // 区域 1top 2ban 3fixed 4cnt | 
				
			|||
        // } | 
				
			|||
      ], | 
				
			|||
      lastSavedCptList: [], | 
				
			|||
      focusedCpt: { | 
				
			|||
        tempOnlyId: '' | 
				
			|||
      }, | 
				
			|||
      uploadUlr: window.SITE_CONFIG['apiURL'] + '/oss/file/customerlogo/upload', | 
				
			|||
      globalIndex: 0 | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  components: { | 
				
			|||
    'cpt-item': componentWxcpt | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  computed: { | 
				
			|||
    cptTypeListTiled () { | 
				
			|||
      const { cptTypeList } = this | 
				
			|||
      let list = [] | 
				
			|||
      cptTypeList.forEach(item => { | 
				
			|||
        list = [...list, ...item.componentList] | 
				
			|||
      }) | 
				
			|||
      return list | 
				
			|||
    }, | 
				
			|||
    topCptList () { | 
				
			|||
      return this.cptList.filter(item => this.checkCptRegion(item) === 'top') | 
				
			|||
    }, | 
				
			|||
    banCptList () { | 
				
			|||
      return this.cptList.filter(item => this.checkCptRegion(item) === 'ban') | 
				
			|||
    }, | 
				
			|||
    cntCptList () { | 
				
			|||
      let arr = this.cptList.filter(item => this.checkCptRegion(item) === 'cnt') | 
				
			|||
      arr.sort((f, s) => f.displayOrder - s.displayOrder) | 
				
			|||
      return arr | 
				
			|||
    }, | 
				
			|||
    fixedCptList () { | 
				
			|||
      return this.cptList.filter(item => this.checkCptRegion(item) === 'fixed') | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
 | 
				
			|||
  methods: { | 
				
			|||
    // 改变步骤 | 
				
			|||
    toStep (s) { | 
				
			|||
      this.step = s | 
				
			|||
    }, | 
				
			|||
    // 选择用户开始配置 | 
				
			|||
    async startSetWxIndex (id, name, type) { | 
				
			|||
      this.wxIndex.customerId = id | 
				
			|||
      this.wxIndex.customerName = name | 
				
			|||
      this.wxIndex.clientType = type | 
				
			|||
 | 
				
			|||
      let loadingInstance = Loading.service() | 
				
			|||
      await this.getCptTypeList() | 
				
			|||
      await this.getCptList() | 
				
			|||
      this.toStep(2) | 
				
			|||
      this.cleanFocusCpt() | 
				
			|||
      loadingInstance.close() | 
				
			|||
    }, | 
				
			|||
    processBackendCptData (item) { | 
				
			|||
 | 
				
			|||
      let demoData = {} | 
				
			|||
      let configuration = {} | 
				
			|||
      const tempOnlyId = getRandomString(20) | 
				
			|||
      try { | 
				
			|||
        demoData = JSON.parse(item.demoData) | 
				
			|||
        configuration = JSON.parse(item.configuration) | 
				
			|||
      } catch (err) { | 
				
			|||
        console.log(err) | 
				
			|||
      } | 
				
			|||
      return { tempOnlyId, ...item, demoData, configuration } | 
				
			|||
    }, | 
				
			|||
    // 获取用户可用组件列表 | 
				
			|||
    getCptTypeList () { | 
				
			|||
      const url = getMockFilterUrl('/oper/customize/customerhometemplate/getcomponentlist') | 
				
			|||
      const { wxIndex: { clientType, customerId } } = this | 
				
			|||
      return this.$http.post( | 
				
			|||
        url, | 
				
			|||
        { clientType, customerId } | 
				
			|||
      ).then(({ data: res }) => { | 
				
			|||
        if (res.code !== 0) { | 
				
			|||
          return this.$message.error(res.msg) | 
				
			|||
        } else { | 
				
			|||
 | 
				
			|||
          let list = [{ | 
				
			|||
            functionId: '0', | 
				
			|||
            functionName: '通用组件', | 
				
			|||
            functionType: 1, // 1通用 2功能 | 
				
			|||
            isUnfold: true, | 
				
			|||
            componentList: res.data.commonList.map(this.processBackendCptData) | 
				
			|||
          }, ...res.data.functionList.map(item => { | 
				
			|||
            return { | 
				
			|||
              functionId: item.functionId, | 
				
			|||
              functionName: item.functionName, | 
				
			|||
              functionType: 2, // 1通用 2功能 | 
				
			|||
              isUnfold: false, | 
				
			|||
              componentList: item.componentList.map(this.processBackendCptData) | 
				
			|||
            } | 
				
			|||
          })] | 
				
			|||
          this.cptTypeList = list | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
      }).catch((err) => { | 
				
			|||
        console.log(err) | 
				
			|||
        return this.$message.error('网络错误') | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 获取用户当前保存的组件列表 | 
				
			|||
    getCptList () { | 
				
			|||
      const url = getMockFilterUrl('/oper/customize/customerhometemplate/gethometemplate') | 
				
			|||
      const { wxIndex: { clientType, customerId } } = this | 
				
			|||
      return this.$http.post( | 
				
			|||
        url, | 
				
			|||
        { clientType, customerId } | 
				
			|||
      ).then(({ data: res }) => { | 
				
			|||
        if (res.code !== 0) { | 
				
			|||
          return this.$message.error(res.msg) | 
				
			|||
        } else { | 
				
			|||
          let list = [ | 
				
			|||
            ...res.data.titleList, | 
				
			|||
            ...res.data.topList, | 
				
			|||
            ...res.data.functionList, | 
				
			|||
            ...res.data.floatingList | 
				
			|||
          ] | 
				
			|||
          this.cptList = list.map(this.processBackendCptData) | 
				
			|||
          this.lastSavedCptList = cloneDeep(this.cptList) | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
      }).catch((err) => { | 
				
			|||
        console.log(err) | 
				
			|||
        return this.$message.error('网络错误') | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 保存配置 | 
				
			|||
    save () { | 
				
			|||
 | 
				
			|||
      const url = getMockFilterUrl('/oper/customize/customerhometemplate/savecustomerhometemplate') | 
				
			|||
      const { wxIndex: { clientType, customerId }, cptList } = this | 
				
			|||
      const componentList = cptList.map(item => { | 
				
			|||
        return { | 
				
			|||
          componentId: item.componentId, | 
				
			|||
          region: item.region, | 
				
			|||
          displayOrder: item.displayOrder, | 
				
			|||
          demoData: JSON.stringify(item.demoData), | 
				
			|||
          configuration: JSON.stringify(item.configuration) | 
				
			|||
        } | 
				
			|||
      }) | 
				
			|||
      return this.$http.post( | 
				
			|||
        url, | 
				
			|||
        { clientType, customerId, componentList } | 
				
			|||
      ).then(({ data: res }) => { | 
				
			|||
        if (res.code !== 0) { | 
				
			|||
          return this.$message.error(res.msg) | 
				
			|||
        } else { | 
				
			|||
          console.log(res) | 
				
			|||
          this.lastSavedCptList = cloneDeep(this.cptList) | 
				
			|||
          return this.$message.success('保存成功') | 
				
			|||
        } | 
				
			|||
      }).catch((err) => { | 
				
			|||
        console.log(err) | 
				
			|||
        return this.$message.error('网络错误') | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 发布配置 | 
				
			|||
    publish () { | 
				
			|||
      console.log('发布配置') | 
				
			|||
      const url = getMockFilterUrl('/oper/customize/home/distributehomedesign') | 
				
			|||
      const { wxIndex: { clientType, customerId }, cptList } = this | 
				
			|||
      const componentList = cptList.map(item => { | 
				
			|||
        return { | 
				
			|||
          componentId: item.componentId, | 
				
			|||
          region: item.region, | 
				
			|||
          displayOrder: item.displayOrder, | 
				
			|||
          demoData: JSON.stringify(item.demoData), | 
				
			|||
          configuration: JSON.stringify(item.configuration) | 
				
			|||
        } | 
				
			|||
      }) | 
				
			|||
      if (componentList.length === 0) { | 
				
			|||
        return this.$message.error('您尚未选择任何组件,不能发布') | 
				
			|||
      } | 
				
			|||
      return this.$confirm('目前的设置会呈现在所有用户的小程序上,是否继续发布?', '确认发布', { | 
				
			|||
        confirmButtonText: '确定', | 
				
			|||
        cancelButtonText: '取消', | 
				
			|||
        type: 'warning' | 
				
			|||
      }).then(() => { | 
				
			|||
        return this.$http.post( | 
				
			|||
          url, | 
				
			|||
          { clientType, customerId, componentList } | 
				
			|||
        ).then(({ data: res }) => { | 
				
			|||
          if (res.code !== 0) { | 
				
			|||
            return this.$message.error(res.msg) | 
				
			|||
          } else { | 
				
			|||
            console.log(res) | 
				
			|||
            this.lastSavedCptList = cloneDeep(this.cptList) | 
				
			|||
            return this.$message.success('发布成功') | 
				
			|||
          } | 
				
			|||
        }).catch((err) => { | 
				
			|||
          console.log(err) | 
				
			|||
          return this.$message.error('网络错误') | 
				
			|||
        }) | 
				
			|||
      }).catch((err) => { | 
				
			|||
        console.log(err) | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 判断组件所属区域类别 | 
				
			|||
    checkCptRegion (item) { | 
				
			|||
      const { region } = item | 
				
			|||
      if (region === 'titleList') { | 
				
			|||
        return 'top' | 
				
			|||
      } else if (region === 'topList') { | 
				
			|||
        return 'ban' | 
				
			|||
      } else if (region === 'functionList') { | 
				
			|||
        return 'cnt' | 
				
			|||
      } else if (region === 'floatingList') { | 
				
			|||
        return 'fixed' | 
				
			|||
      } else { | 
				
			|||
        return 'none' | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 判断组件是否可用复用 | 
				
			|||
    checkCptReuse (item) { | 
				
			|||
      const { componentFrontId } = item | 
				
			|||
      const reuseList = this.cptTypeList[0].componentList.map(v => v.componentFrontId) | 
				
			|||
      const fun = name => name === componentFrontId | 
				
			|||
      return reuseList.findIndex(fun) !== -1 | 
				
			|||
    }, | 
				
			|||
    // 根据所属区域简称得到名字 | 
				
			|||
    getCptRegionName (id) { | 
				
			|||
      return { | 
				
			|||
        'top': '标题区', | 
				
			|||
        'ban': '置顶区', | 
				
			|||
        'fixed': '浮窗区', | 
				
			|||
        'cnt': '功能区', | 
				
			|||
        'none': '' | 
				
			|||
      }[id] | 
				
			|||
    }, | 
				
			|||
    // 添加组件到实例-前验证 | 
				
			|||
    beforeAddCpt (item) { | 
				
			|||
 | 
				
			|||
      console.log('添加组件到实例-前验证') | 
				
			|||
      const regionType = this.checkCptRegion(item) | 
				
			|||
      const tempOnlyId = getRandomString(20) | 
				
			|||
      if (regionType === 'top') { | 
				
			|||
        if (this.topCptList.length > 0) { | 
				
			|||
          this.$message('标题区已有组件,请删除后再添加') | 
				
			|||
        } else { | 
				
			|||
          this.addCpt(item, tempOnlyId) | 
				
			|||
        } | 
				
			|||
      } else if (regionType === 'ban') { | 
				
			|||
        if (this.banCptList.length > 0) { | 
				
			|||
          this.$message('置顶区已有组件,请删除后再添加') | 
				
			|||
        } else { | 
				
			|||
          this.addCpt(item, tempOnlyId) | 
				
			|||
        } | 
				
			|||
      } else if (regionType === 'fixed') { | 
				
			|||
        if (this.fixedCptList.length > 0) { | 
				
			|||
          this.$message('浮窗区已有组件,请删除后再添加') | 
				
			|||
        } else { | 
				
			|||
          this.addCpt(item, tempOnlyId) | 
				
			|||
        } | 
				
			|||
      } else if (regionType === 'cnt') { | 
				
			|||
        this.cntCptListResort() | 
				
			|||
        this.addCpt(item, tempOnlyId, (this.cntCptList.length + 1) * 10) | 
				
			|||
      } else { | 
				
			|||
        return false | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 实例内容组件重置displayOrder属性 | 
				
			|||
    cntCptListResort () { | 
				
			|||
      console.log('实例内容组件重置displayOrder属性') | 
				
			|||
      this.cntCptList.forEach((item, index) => { | 
				
			|||
        item.displayOrder = (index + 1) * 10 | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 添加组件到实例 | 
				
			|||
    addCpt (item, tempOnlyId, displayOrder = 0) { | 
				
			|||
      console.log('添加组件到实例') | 
				
			|||
      let trueItem = cloneDeep(item) | 
				
			|||
      trueItem.tempOnlyId = tempOnlyId | 
				
			|||
      trueItem.displayOrder = displayOrder | 
				
			|||
      this.cptList.push(trueItem) | 
				
			|||
    }, | 
				
			|||
    // 改变实例组件显示顺序 | 
				
			|||
    async changeCptDisplayOrder (item, type) { | 
				
			|||
      console.log('改变实例组件显示顺序') | 
				
			|||
      if (type === 'up') { | 
				
			|||
        item.displayOrder -= 11 | 
				
			|||
      } else if (type === 'down') { | 
				
			|||
        item.displayOrder += 11 | 
				
			|||
      } | 
				
			|||
      await nextTick() | 
				
			|||
      this.cntCptListResort() | 
				
			|||
    }, | 
				
			|||
    // 删除组件 | 
				
			|||
    delCpt (item) { | 
				
			|||
      this.cptList = this.cptList.filter(cptItem => item.tempOnlyId !== cptItem.tempOnlyId) | 
				
			|||
      if (this.focusedCpt.tempOnlyId === item.tempOnlyId) { | 
				
			|||
        this.focusedCpt = { tempOnlyId: '' } | 
				
			|||
      } | 
				
			|||
      this.cntCptListResort() | 
				
			|||
    }, | 
				
			|||
    // 检测实例中是否存在某种类型组件 | 
				
			|||
    checkExistCpt (item) { | 
				
			|||
      return this.cptList.some(cptItem => item.componentFrontId === cptItem.componentFrontId) | 
				
			|||
    }, | 
				
			|||
    // 清空聚焦实例组件 | 
				
			|||
    cleanFocusCpt () { | 
				
			|||
      this.focusedCpt = { tempOnlyId: '' } | 
				
			|||
    }, | 
				
			|||
    // 聚焦实例组件 | 
				
			|||
    focusCpt (item, index) { | 
				
			|||
      console.log('聚焦实例组件', item, index) | 
				
			|||
 | 
				
			|||
      this.globalIndex = index | 
				
			|||
      if (this.isInPreview) return | 
				
			|||
      if (this.focusedCpt.tempOnlyId === item.tempOnlyId) { | 
				
			|||
        this.cleanFocusCpt() | 
				
			|||
      } else { | 
				
			|||
        this.focusedCpt = { ...cloneDeep(item), demoData: JSON.stringify(item.demoData), configuration: JSON.stringify(item.configuration), demoIsUnfold: true, confIsUnfold: false } | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
    // 保存聚焦组件数据 | 
				
			|||
    saveFocusedCptData () { | 
				
			|||
      const { focusedCpt } = this | 
				
			|||
      this.cptList.forEach(item => { | 
				
			|||
        if (item.tempOnlyId === focusedCpt.tempOnlyId) { | 
				
			|||
          try { | 
				
			|||
            item.demoData = JSON.parse(focusedCpt.demoData) | 
				
			|||
            item.configuration = JSON.parse(focusedCpt.configuration) | 
				
			|||
          } catch (err) { | 
				
			|||
            this.$alert('json数据格式有误', '无法保存', { | 
				
			|||
              confirmButtonText: '确定' | 
				
			|||
            }) | 
				
			|||
            console.log(err) | 
				
			|||
          } | 
				
			|||
        } | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 重置聚焦组件数据,重置为上次整体保存时的数据 | 
				
			|||
    resetFocusedCptData () { | 
				
			|||
      const { focusedCpt } = this | 
				
			|||
      const fun = item => { | 
				
			|||
        if (item.tempOnlyId === focusedCpt.tempOnlyId) { | 
				
			|||
          focusedCpt.demoData = JSON.stringify(item.demoData) | 
				
			|||
          focusedCpt.configuration = JSON.stringify(item.configuration) | 
				
			|||
          return true | 
				
			|||
        } else { | 
				
			|||
          return false | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
      if (!this.lastSavedCptList.some(fun)) { | 
				
			|||
        this.cptTypeListTiled.forEach(item => { | 
				
			|||
          if (item.componentFrontId === focusedCpt.componentFrontId) { | 
				
			|||
            focusedCpt.demoData = JSON.stringify(item.demoData) | 
				
			|||
            focusedCpt.configuration = JSON.stringify(item.configuration) | 
				
			|||
          } | 
				
			|||
        }) | 
				
			|||
      } | 
				
			|||
    }, | 
				
			|||
 | 
				
			|||
    // 改变可用列表组件展开与收起 | 
				
			|||
    shiftCptTypeItemUnfold (item) { | 
				
			|||
      item.isUnfold = !item.isUnfold | 
				
			|||
    }, | 
				
			|||
    // 上传爱心互助banner图 | 
				
			|||
    beforeBannerUpload (file) { | 
				
			|||
      console.log('file', file.size / 1024) | 
				
			|||
      let testmsg = file.name.substring(file.name.lastIndexOf('.') + 1) | 
				
			|||
      const imgs = ['png', 'PNG'] | 
				
			|||
      const extension = imgs.includes(testmsg) | 
				
			|||
      const isLt2M = file.size / 1024 < 100 | 
				
			|||
 | 
				
			|||
      if (!extension) { | 
				
			|||
        this.$message.error('上传图片只能是png格式!') | 
				
			|||
      } | 
				
			|||
      if (!isLt2M) { | 
				
			|||
        this.$message.error('上传图片大小不能超过 100KB!') | 
				
			|||
      } | 
				
			|||
      return extension && isLt2M | 
				
			|||
    }, | 
				
			|||
    handleBannerSuccess (res, file) { | 
				
			|||
      console.log('res', res) | 
				
			|||
      console.log('files', file) | 
				
			|||
      if (res.code === 0 && res.msg === 'success') { | 
				
			|||
        this.focusedCpt.configuration = { | 
				
			|||
          url: res.data.url | 
				
			|||
        } | 
				
			|||
        this.cntCptList[this.globalIndex].demoData.pic = res.data.url | 
				
			|||
        this.focusedCpt.configuration = JSON.stringify(this.focusedCpt.configuration) | 
				
			|||
        this.focusedCpt.demoData = JSON.stringify(this.cntCptList[this.globalIndex].demoData) | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</script> | 
				
			|||
					Loading…
					
					
				
		Reference in new issue