hyf před 3 roky
rodič
revize
889e98e3c3

+ 1 - 1
src/layout/components/AppMain.vue

@@ -38,7 +38,7 @@ export default {
 $navHeight:65px;
 .app-main {
   /* 50= navbar  50  */
-  min-height: calc(100vh - 65px);
+  min-height: calc(100vh - 75px);
   width: 100%;
   position: relative;
   overflow: hidden;

+ 44 - 30
src/layout/components/Navbar.vue

@@ -2,8 +2,11 @@
   <div class="navbar">
     <div class="hos-name">
       <img :src="logo" alt="logo">
+
       <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+
       <span v-if="userData.ocName" class="tag">{{ userData.ocName }}</span>
+
       <countdown v-if="userData.licExpiredTime" :end-time="userData.licExpiredTime">
         <div
           slot="process"
@@ -122,21 +125,27 @@ export default {
   mounted() {
     this.getUnReadMsg()
     this.initSideMenu()
-    this.initsideTab()
+    this.initSideTab()
   },
   methods: {
+
+    // 未读消息
     getUnReadMsg() {
       getUnReadCounter().then((resp) => {
         this.unReadCount = resp.data
       })
     },
+
+    // 渲染导航
     initSideMenu() {
       const permits = JSON.parse(JSON.stringify(this.permits))
       let sideMenuTabList = JSON.parse(JSON.stringify(this.sideMenuTabList))
       sideMenuTabList = sideMenuTabList.filter(item => permits.includes(item.permit))
       this.sideMenus = sideMenuTabList
     },
-    initsideTab() {
+
+    // 渲染导航
+    initSideTab() {
       let id = this.sideMenuTabId
       if (this.isNotNull(localStorage.getItem('csat_tabId'))) {
         id = parseFloat(localStorage.getItem('csat_tabId'))
@@ -146,24 +155,32 @@ export default {
         path
       })
     },
+
+    // 开关导航
     toggleSideBar() {
       this.$store.dispatch('app/toggleSideBar')
     },
+
+    // 导航到路径
     navToPage(path) {
       this.$emit('initMessage')
     },
+
+    // 退出
     async logout() {
       localStorage.clear()
       await this.$store.dispatch('user/logout')
       this.$router.push(`/login?redirect=${this.$route.fullPath}`)
     },
+
+    // 导航变化
     sideTabChange(id, item) {
       this.sideMenuTabId = id
       this.$router.replace({
         path: item.path
       })
       localStorage.setItem('csat_tabId', id)
-      var permission_routes = localStorage.getItem('csat_permission_routes')
+      let permission_routes = localStorage.getItem('csat_permission_routes')
       if (permission_routes) { permission_routes = JSON.parse(permission_routes) } else {
         permission_routes = this.permission_routes
         localStorage.setItem('csat_permission_routes', JSON.stringify(permission_routes))
@@ -176,10 +193,6 @@ export default {
         return item
       })
       this.$store.state.permission.routes = filterRoutes
-    },
-    isNotNull(value) {
-      if (value !== undefined && value !== 'undefined' && value !== null && value !== '') return true
-      return false
     }
   }
 }
@@ -199,33 +212,34 @@ export default {
   box-sizing: border-box;
   background-color: inherit;
   top: 0;
-.hos-name{
-  height: 100%;
-  display: flex;
-  align-items: center;
-  float: left;
-  padding-left: 10px;
-  color: #fff;
-  flex: 1;
-  img{
+  .hos-name{
+    height: 100%;
+    display: flex;
+    align-items: center;
+    float: left;
+    padding-left: 10px;
+    color: #fff;
+    flex: 1;
+    .logo {
       display: block;
       width: auto;
-      height: 32px;
-  }
-  .tag{
-    font-size: 16px;
-    line-height: 1;
-    font-weight: 600;
-    padding-left: 5px;
-    margin-top: 8px;
-    &.authorization{
-      font-size: 12px;
-      margin-top: 13px;
-      color: #a33e3e;
-      // color: rgba(255, 255, 255, 0.7);
+      height: 42px;
+    }
+
+    .tag{
+      font-size: 16px;
+      line-height: 1;
+      font-weight: 300;
+      padding-left: 5px;
+      margin-top: 3px;
+      &.authorization{
+        font-size: 12px;
+        margin-top: 13px;
+        color: #a33e3e;
+        // color: rgba(255, 255, 255, 0.7);
+      }
     }
   }
-}
   .hamburger-container {
     padding: 3px;
     line-height: var(--navHeight);

+ 0 - 6
src/router/modules/csat.js

@@ -247,12 +247,6 @@ const csatRouter = [
         component: () => import('@/views/system/grid'),
         name: 'hos_grid',
         meta: { title: '网格管理', noCache: true, permit: 'hos_grid' }
-      },
-      {
-        path: 'map',
-        component: () => import('@/views/system/map/index'),
-        name: 'hos_map',
-        meta: { title: '地图配置', noCache: true, permit: 'hos_map' }
       }
     ]
   },

+ 5 - 0
src/styles/element-ui-reset/el-button.scss

@@ -0,0 +1,5 @@
+.el-button--mini {
+  padding: 7px 7px;
+  font-size: 12px;
+  border-radius: 3px;
+}

+ 5 - 5
src/styles/element-ui-reset/el-card.scss

@@ -7,14 +7,14 @@
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
     color: #fff
 }
-  
+
 .el-card__header {
-    padding: 18px 20px;
+    padding: 5px 20px;
     border-bottom: 1px solid rgba(255, 255, 255, 0.1);
     -webkit-box-sizing: border-box;
     box-sizing: border-box
   }
-  
+
 .el-card__body {
-    padding: 20px 
-}
+    padding: 10px 10px 0 10px
+}

+ 33 - 0
src/styles/element-ui-reset/el-switch.scss

@@ -1,3 +1,36 @@
+.el-switch {
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  position: relative;
+  font-size: 12px;
+  line-height: 20px;
+  height: 20px;
+  vertical-align: middle;
+}
+
+.el-switch__label * {
+  line-height: 1;
+  font-size: 12px;
+  display: inline-block;
+}
+
 .el-switch__label,.el-switch__label--left{
   color: #FFF;
+  font-size: 12px;
+}
+
+.el-switch__core {
+  width: 30px !important;
+  height: 16px;
+}
+.el-switch__core::after {
+  width: 14px;
+  height: 14px;
+  margin-top: -1px;
+}
+.el-switch.is-checked .el-switch__core::after{
+  margin-left: -15px;
 }

+ 7 - 7
src/styles/element-ui-reset/el-tree.scss

@@ -5,8 +5,8 @@
 
   .el-tree-node  > .el-tree-node__content,.el-tree-node__content{
     background-color: inherit;
-    height: 40px;
-    line-height: 40px;
+    height: 30px;
+    line-height: 30px;
   }
 
   .el-tree-node.is-current > .el-tree-node__content,.el-tree-node__content:hover {
@@ -25,7 +25,7 @@
     &.node-checked {
       position: relative;
       color: #08A6DC;
-  
+
       &::after {
         position: absolute;
         content: "";
@@ -39,14 +39,14 @@
         transform: rotate(270deg);
       }
     }
-  }     
+  }
 }
 .custom-theme .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
   background-color: #003E51;
-} 
+}
 .el-tree .is-checked>.el-tree-node__content{
   color: #08A6DC;
-} 
+}
 .custom-theme {
    .el-tree{
     &::v-deep .el-tree-node__content:hover {
@@ -54,4 +54,4 @@
       background:#003E51;
     }
    }
-}
+}

+ 1 - 0
src/styles/element-ui-reset/index.scss

@@ -2,6 +2,7 @@
 @import "./ql-editor.scss";
 
 // element-ui
+@import "./el-button.scss";
 @import "./el-dialog.scss";
 @import "./el-table.scss";
 @import "./el-drawer.scss";

+ 1 - 1
src/styles/sidebar.scss

@@ -1,5 +1,5 @@
 #app {
-  --navHeight:65px;
+  --navHeight:75px;
   .main-container {
     // min-height: 100%;
     transition: margin-left .28s;

+ 16 - 0
src/utils/index.js

@@ -793,3 +793,19 @@ export function targetType(val) {
   ]
   return strs[val]
 }
+
+export function isNotNull(value) {
+  if (value !== undefined && value !== 'undefined' && value !== null && value !== '') return true
+  return false
+}
+
+export function generateClientId() {
+  const len = 23
+  const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
+  const maxPos = chars.length
+  let str = ''
+  for (let i = 0; i < len; i++) {
+    str += chars.charAt(Math.floor(Math.random() * maxPos))
+  }
+  return new Date().getTime() + str
+}

+ 4 - 4
src/views/hos/doctor/index.vue

@@ -8,16 +8,16 @@
       </el-col>
 
       <el-col :span="12" class="right">
-        <el-input v-model="conditions.keywords" class="search-input m-right-15" size="mini" placeholder="请输入内容">
-          <el-button slot="append" icon="el-icon-search" size="mini" @click="getData()" />
-        </el-input>
+        <el-input v-model="conditions.keywords" style="width: 200px;" class="filter-item" prefix-icon="el-icon-search" size="mini" placeholder="请输入内容" @keyup.enter.native="getData" />
+        <el-button class="filter-item" style="margin-left: 10px;" type="primary" size="mini" icon="el-icon-search" @click="getData">查询</el-button>
+
         <el-button type="primary" size="mini" icon="el-icon-plus" @click="handleAdd">添加</el-button>
         <el-button type="primary" size="mini" :disabled="!(exportItems&&exportItems.length>0)" @click="downloadQrcode">下载二维码</el-button>
       </el-col>
     </el-row>
 
     <el-row class="content-body">
-      <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 240px)" @selection-change="changeSelection">
+      <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 240px)" size="mini" @selection-change="changeSelection">
         <el-table-column type="selection" />
 
         <el-table-column type="index" label="序号" align="center" header-align="center" width="80" />

+ 4 - 3
src/views/hos/profile/components/Hos.vue

@@ -1,7 +1,7 @@
 <template>
   <el-drawer
     :title="title"
-    :modal-append-to-body="false"
+    :append-to-body="true"
     :modal="false"
     size="70%"
     :visible.sync="dialogVisible"
@@ -94,8 +94,8 @@
           </el-card>
         </el-form>
         <div class="btn-group">
-          <el-button type="primary" @click="submitForm('ruleForm')">确 定</el-button>
-          <el-button class="cancel-btn" @click="dialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
+          <el-button class="cancel-btn" @click="dialogVisible = false">取消</el-button>
         </div>
       </vuescroll>
 
@@ -110,6 +110,7 @@ import { getHosProfile, updateHosProfile } from '@/api/hos/hosProfileApi'
 import Vuescroll from 'vuescroll'
 
 export default {
+  name: 'Hos',
   components: {
     AMapAddressSearchDialog, Vuescroll
   },

+ 1 - 1
src/views/hos/record/components/RecordList.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="content-container">
-    <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 220px)">
+    <el-table v-loading="listLoading" class="page-table" border :data="dataList" size="mini" height="calc(100vh - 220px)">
       <el-table-column type="index" label="序号" header-align="center" align="center" width="80" />
 
       <el-table-column prop="personName" label="评价人员" header-align="center" align="center" width="180">

+ 1 - 0
src/views/hos/record/index.vue

@@ -87,6 +87,7 @@ export default {
   },
   methods: {
 
+    // 分类筛选
     selectItem(iStatus) {
       this.conditions.status = iStatus
       this.loadData()

+ 11 - 12
src/views/system/checklist/index.vue

@@ -8,16 +8,15 @@
       </el-col>
 
       <el-col :span="12" class="right">
-        <el-input v-model="conditions.keywords" class="search-input m-right-15" size="mini" placeholder="请输入内容">
-          <el-button slot="append" icon="el-icon-search" size="mini" @click="getData()" />
-        </el-input>
+        <el-input v-model="conditions.keywords" style="width: 200px;" class="filter-item" prefix-icon="el-icon-search" size="mini" placeholder="请输入内容" @keyup.enter.native="getData" />
+        <el-button class="filter-item" style="margin-left: 10px;" type="primary" size="mini" icon="el-icon-search" @click="getData">查询</el-button>
 
         <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd">添加</el-button>
       </el-col>
     </el-row>
 
     <el-row class="content-body">
-      <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 220px)">
+      <el-table v-loading="listLoading" class="page-table" border :data="dataList" size="mini" height="calc(100vh - 220px)">
         <el-table-column type="index" label="序号" header-align="center" align="center" width="80" />
 
         <el-table-column prop="checklistTitle" label="名称" header-align="left" align="left" width="260">
@@ -65,7 +64,7 @@
       </div>
     </el-row>
 
-    <checklist ref="AddChecklist" title="新增" @formSuccess="AddChecklistSuccess" />
+    <checklist ref="AddChecklist" title="新增" @formSuccess="formSuccess" />
     <checklist-details ref="ChecklistDetails" title="详情" @formSuccess="getData" />
   </div>
 </template>
@@ -103,7 +102,7 @@ export default {
   },
 
   methods: {
-    // fetch data
+    // 请求数据
     getData() {
       this.listLoading = true
       getChecklistByPage(this.conditions).then((resp) => {
@@ -117,12 +116,6 @@ export default {
     },
 
     // 新增
-    AddChecklistSuccess(data) {
-      this.getData()
-      this.handleDetails(data)
-    },
-
-    // 修改
     handleAdd() {
       this.$refs['AddChecklist'].showAddModel()
     },
@@ -151,7 +144,13 @@ export default {
       }).catch(() => {
         this.$message({ type: 'info', message: '已取消删除' })
       })
+    },
+
+    // 更新
+    formSuccess(data) {
+      this.getData()
     }
+
   }
 }
 </script>

+ 2 - 2
src/views/system/customer/wx/index.vue

@@ -12,7 +12,7 @@
     </el-row>
 
     <el-row class="content-body">
-      <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 280px)">
+      <el-table v-loading="listLoading" class="page-table" border :data="dataList" size="mini" height="calc(100vh - 280px)">
         <el-table-column type="index" label="序号" header-align="center" align="center" width="80" />
 
         <el-table-column label="客户名称" width="200" align="center" header-align="center">
@@ -39,7 +39,7 @@
           </template>
         </el-table-column>
 
-        <el-table-column label="操作" width="300" class-name="small-padding fixed-width" align="center" header-align="center">
+        <el-table-column label="操作" class-name="small-padding fixed-width" align="center" header-align="center" width="120">
           <template v-slot="{row}">
             <el-button size="mini" icon="el-icon-delete" type="danger" @click="handleDelete(row)">删除</el-button>
           </template>

+ 8 - 3
src/views/system/grid/components/Grid.vue

@@ -1,7 +1,7 @@
 <template>
   <el-drawer
     :title="title"
-    :modal-append-to-body="false"
+    :append-to-body="true"
     :modal="false"
     :wrapper-closable="false"
     size="30%"
@@ -14,6 +14,10 @@
             <el-input v-model="formData.gridTitle" placeholder="输入网格名称" />
           </el-form-item>
 
+          <el-form-item label="分类" prop="gridCatId">
+            <grid-cat-selector v-model="formData.gridCatId" />
+          </el-form-item>
+
           <el-form-item label="所在部门" prop="groupId">
             <group-selector v-model="formData.groupId" />
           </el-form-item>
@@ -51,8 +55,7 @@
 
 import { ACTION_ADD, ACTION_UPDATE } from '@/utils/actionType'
 import { getGridById, createGrid, updateGrid } from '@/api/system/gridApi'
-import GroupSelector from '@/components/GroupSelector'
-import UserSelector from '@/components/UserSelector'
+import { GridCatSelector, GroupSelector, UserSelector } from '@/components'
 import { mapGetters } from 'vuex'
 import Vuescroll from 'vuescroll'
 
@@ -61,6 +64,7 @@ export default {
   components: {
     Vuescroll,
     GroupSelector,
+    GridCatSelector,
     UserSelector
   },
   props: {
@@ -84,6 +88,7 @@ export default {
         gridId: undefined,
         gridTitle: '',
         gridLevel: 0,
+        gridCatId: undefined,
         gridDesc: '',
         status: 1,
         groupId: undefined, // 所属部门

+ 49 - 129
src/views/system/grid/index.vue

@@ -3,65 +3,68 @@
     <el-row class="tool-bar">
       <el-col :span="12" class="left">
         <div class="content-title">
-          网格管理
+          网格区域管理
         </div>
       </el-col>
       <el-col :span="12" class="right">
-        <el-input v-model="conditions.keywords" class="search-input m-right-15" size="mini" placeholder="请输入内容">
-          <el-button slot="append" icon="el-icon-search" size="mini" @click="getData()" />
-        </el-input>
-
+        <el-input v-model="conditions.keywords" style="width: 200px;" class="filter-item" prefix-icon="el-icon-search" size="mini" placeholder="请输入内容" @keyup.enter.native="getData" />
+        <el-button class="filter-item" style="margin-left: 10px;" type="primary" size="mini" icon="el-icon-search" @click="getData">查询</el-button>
         <el-button type="primary" size="mini" icon="el-icon-plus" @click="handleAdd">添加</el-button>
-
-        <el-button type="primary" size="mini" :disabled="!(exportItems&&exportItems.length>0)" @click="downloadQrcode">下载二维码</el-button>
+        <el-button type="primary" :disabled="!(exportItems&&exportItems.length>0)" size="mini" @click="downloadQrcode">下载二维码</el-button>
       </el-col>
     </el-row>
 
     <el-row class="content-body">
-      <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 240px)" @selection-change="changeSelection">
+      <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 240px)" size="mini" @selection-change="changeSelection">
         <el-table-column type="selection" />
         <el-table-column type="index" label="序号" align="center" header-align="center" width="80" />
 
-        <el-table-column label="网格名称" align="center" header-align="center">
+        <el-table-column label="名称 " align="center" header-align="center">
           <template v-slot="{row}">
             <span>{{ row.gridTitle }}</span>
           </template>
         </el-table-column>
 
-        <el-table-column label="等级" align="center" header-align="center" min-width="100">
+        <el-table-column label="分类" align="center" header-align="center" width="100">
+          <template v-slot="{row}">
+            <el-tag type="primary"><span>{{ row.gridCatTitle }}</span></el-tag>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="等级" align="center" header-align="center" width="80">
           <template v-slot="{row}">
-            <span>{{ row.gridLevel | gridLevelFilter }}</span>
+            <span><el-tag type="warning">{{ row.gridLevel | gridLevelFilter }}</el-tag></span>
           </template>
         </el-table-column>
 
-        <el-table-column label="责任部门" align="center" header-align="center" min-width="150">
+        <el-table-column label="责任部门" align="center" header-align="center" width="150">
           <template v-slot="{row}">
             <span>{{ row.groupName }}</span>
           </template>
         </el-table-column>
 
-        <el-table-column label="责任人" align="center" header-align="center" min-width="120">
+        <el-table-column label="责任人" align="center" header-align="center" width="220">
           <template v-slot="{row}">
             <span><i class="el-icon-user" /> {{ row.accountName }}[{{ row.positionName }}]</span>
           </template>
         </el-table-column>
 
-        <el-table-column label="二维码" header-align="center" align="center" width="70">
+        <el-table-column label="二维码" header-align="center" align="center" width="80">
           <template v-slot="{row}">
-            <span class="icon iconfont icon-erweima" @click="showQrcode(row)" />
+            <span class="icon risk-icon icon-erweima" @click="showQrcode(row)" />
           </template>
         </el-table-column>
 
-        <el-table-column label="小程序" align="center" header-align="center" width="70">
+        <el-table-column label="小程序" align="center" header-align="center" width="80">
           <template v-slot="{row}">
             <el-link>
-              <span v-if="row.miniNum> 0" @click="handleMini(row)"> <i class="el-icon-apple" /> </span>
-              <span v-else @click="handleMini(row)">绑定 </span>
+              <span v-if="row.miniNum > 0" @click="handleMini(row)"> <i class="el-icon-apple" /> </span>
+              <span v-else @click="handleMini(row)">绑定</span>
             </el-link>
           </template>
         </el-table-column>
 
-        <el-table-column label="说明" align="left" header-align="left">
+        <el-table-column label="说明" align="left" header-align="left" width="120">
           <template v-slot="{row}">
             <span>{{ row.gridDesc }}</span>
           </template>
@@ -81,76 +84,51 @@
     </el-row>
     <grid ref="AddGrid" title="添加" @formSuccess="getData" />
     <grid ref="EditGrid" title="编辑" @formSuccess="getData" />
-    <QrCode ref="qrcode" />
-    <div id="qrcode" ref="qrcodeModal" style="position:fixed;top:-9999px;" />
+    <QrCode ref="Qrcode" />
     <MiniProgramTargetConfig ref="MiniTargetConfig" :target-type="targetType" @formSuccess="getData" />
-    <MapLayer ref="MapLayer" />
   </div>
 </template>
 
 <script>
-import QRCode from 'qrcodejs2'
-import html2canvas from 'html2canvas'
-import JSZip from 'jszip'
-import saveAs from 'file-saver'
-
-import Grid from './components/Grid'
+import Grid from './components/Grid.vue'
 import { MiniProgramTargetConfig, QrCode } from '@/components'
-import MapLayer from './components/MapLayer'
-import Pagination from '@/components/Pagination'
+import Pagination from '@/components/Pagination/index.vue'
 import { getGridByPage, deleteGridById } from '@/api/system/gridApi'
-import { getSettingById } from '@/api/system/settingApi'
-import { getUserData } from '@/utils/auth'
 
-let zip = new JSZip()
 export default {
   name: 'GridIndex',
   components: {
     Pagination,
     MiniProgramTargetConfig,
     Grid,
-    MapLayer,
     QrCode
   },
   filters: {
     gridLevelFilter(gridLevel) {
-      const gridLevelMap = ['未设定', '重大', '较大', '一般', '较小']
+      const gridLevelMap = ['默认', '重大', '较大', '一般', '较小']
       return gridLevelMap[gridLevel]
     }
   },
   data() {
     return {
-      dataList: null,
+      dataList: undefined,
       listLoading: false,
       total: 0,
-      targetType: 1,
+      targetType: 2,
       conditions: {
-        page: 2,
+        page: 1,
         limit: 10,
         keywords: ''
       },
-      ocId: undefined,
-      miniUrl: '',
       exportItems: []
     }
   },
 
   mounted() {
-    const userData = getUserData()
-    this.ocId = userData.ocId
-    this.getMiniUrl()
     this.getData()
   },
 
   methods: {
-    // 获取小程序地址
-    async getMiniUrl() {
-      const settingId = 1
-      this.listLoading = true
-      const { data } = await getSettingById(settingId)
-      this.listLoading = false
-      this.miniUrl = data.settingValue
-    },
 
     // 初始化数据
     async getData() {
@@ -165,11 +143,13 @@ export default {
     handleAdd() {
       this.$refs['AddGrid'].showAddModel()
     },
+
     // 修改
     handleEdit(data) {
       const { gridId } = data
       this.$refs['EditGrid'].showEditModel(gridId)
     },
+
     // 删除
     handleDelete(data) {
       const { gridId, gridTitle } = data
@@ -185,103 +165,43 @@ export default {
         this.$message({ type: 'info', message: '已取消删除' })
       })
     },
+
+    // 多选
     changeSelection(selection) {
       var len = selection.length
       this.hanleModal = (len > 0)
       this.exportItems = selection
     },
+
+    // 显示二维码
     showQrcode(row) {
-      const code = this.miniUrl + '?ocId=' + this.ocId + '&code=' + row.gridCode
-      this.$refs.qrcode.draw(code)
+      const code = row.gridCode
+      this.$refs.Qrcode.draw(code)
     },
+
+    // 下载二维码
     downloadQrcode() {
       if (this.exportItems && this.exportItems.length > 0) {
-        var content = JSON.parse(JSON.stringify(this.exportItems))
-        this.downloadMaterial(content)
+        const arrData = []
+        for (let i = 0; i < this.exportItems.length; i++) {
+          const item = this.exportItems[i]
+          arrData.push({ type: 2, code: item.gridCode, title: item.gridTitle })
+        }
+        this.$refs.Qrcode.download(arrData, '网格区域')
       } else { this.$message.error('没有可下载的数据!') }
     },
-    downloadMaterial(content) { // 下载物料
-      this.batch(content, '网格管理')
-    },
-    async batch(arr, fileName) {
-      var self = this
-      window.loading = this.$loading({
-        lock: true,
-        text: '制作二维码中!',
-        spinner: 'el-icon-loading',
-        background: 'rgba(0, 0, 0, 0.7)'
-      })
-
-      zip = new JSZip()
-      for (var i = 0; i < arr.length; i++) {
-        var item = arr[i]
-        const code = this.miniUrl + '?ocId=' + this.ocId + '&code=' + item.gridCode
-        await self.drawQrcode(code).catch(() => {
-          window.loading.close()
-          this.$message.error('导出失败')
-        })
-        await self.packMaterial(item.gridTitle).catch(() => {
-          window.loading.close()
-          this.$message.error('导出失败')
-        })
-      }
-      zip.generateAsync({
-        type: 'blob'
-      }).then((blob) => {
-        saveAs(blob, fileName + '二维码物料.zip')
-        window.loading.close()
-      })
-    },
-    drawQrcode(url, sleep = 300) { // 绘制二维码
-      this.$refs.qrcodeModal.innerHTML = ''
-      return new Promise((resolve, reject) => {
-        new QRCode('qrcode', {
-          width: 400,
-          height: 400,
-          text: url.toString()
-        })
-        setTimeout(function() {
-          resolve()
-        }, sleep)
-      })
-    },
 
-    packMaterial(name) { // 打包处理
-      if (!name) name = 'xxx'
-      return new Promise((resolve, reject) => {
-        html2canvas(document.getElementById('qrcode'), {
-          backgroundColor: null,
-          useCORS: true,
-          dpi: 500,
-          scale: 5
-        }).then((canvas) => {
-          let dataURL = canvas.toDataURL('photo/png')
-          dataURL = dataURL.replace(/^data:image\/(png|jpg);base64,/, '')
-          zip.file(name + '.jpg', dataURL, { base64: true })
-          resolve()
-        }).catch((e) => {
-          reject(e)
-        })
-      })
-    },
-
-    // 显示小程序绑定配置
+    // 显示App绑定配置
     handleMini(data) {
       const { gridId } = data
       this.$refs['MiniTargetConfig'].showModel(gridId)
-    },
-
-    // 设定地图位置
-    handleMapLayer(data) {
-      const { layerId } = data
-      this.$refs['MapLayer'].showModel(layerId)
     }
   }
 }
 </script>
 <style scoped>
-  .content-container {
-    height: calc(100vh - 90px);
-  }
+.content-container {
+  height: calc(100vh - 95px);
+}
 
 </style>

+ 2 - 2
src/views/system/group/group/GroupTree.vue

@@ -152,7 +152,7 @@ export default {
 </script>
 <style lang="scss" scoped>
   .content-container {
-    height:  calc(100vh - 90px);
+    height:  calc(100vh - 95px);
 
     .title-bar {
       position: relative;
@@ -202,7 +202,7 @@ export default {
       .right-icon {
         position: absolute;
         right: 10px;
-        top: 14px;
+        top: 8px;
         background: #5181A2;
         color: #FFFFFF;
         width: 14px;

+ 95 - 0
src/views/system/group/user/BindWx.vue

@@ -0,0 +1,95 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="dialogVisible"
+    width="30%"
+    destroy-on-close
+    :close-on-click-modal="false"
+  >
+    <div class="content-container">
+      <el-row type="flex" justify="center" align="middle">
+        <div id="qrcodetemplate" ref="qrcodetemplate" style="margin: 5px 0;" />
+      </el-row>
+      <el-row type="flex" justify="center">
+        <span>{{ viewData.note }}</span>
+      </el-row>
+    </div>
+  </el-dialog>
+</template>
+<script>
+
+import { serverUrl, devServerUrl } from '@/settings'
+import QRCode from 'qrcodejs2'
+import { mapGetters } from 'vuex'
+import { isNotNull } from '@/utils'
+
+export default {
+  name: 'BindWx',
+  props: {
+    title: {
+      type: String,
+      default: '微信绑定'
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      userId: undefined,
+      code: '',
+      viewData: {
+        note: ''
+      }
+    }
+  },
+  computed: {
+    ...mapGetters([
+      'userData'
+    ])
+  },
+  created() {
+
+  },
+  methods: {
+
+    // 外部调用接口
+    show(userId, objCode) {
+      this.userId = userId
+      if (isNotNull(objCode)) {
+        this.viewData.note = '已有绑定'
+      } else {
+        this.viewData.note = '未绑定微信'
+      }
+      this.dialogVisible = true
+      this.drawQrcode()
+    },
+
+    // 显示绑定二维码
+    drawQrcode() {
+      const ocId = this.userData.ocId
+      const userId = this.userId
+
+      const baseURL = process.env.NODE_ENV === 'development' ? devServerUrl : serverUrl
+      const url = baseURL + '/wx/auth/' + ocId + '/' + userId
+      if (!url) {
+        this.$message.error('没有生产二维码的参数')
+        return
+      }
+      this.$nextTick(() => {
+        this.$refs.qrcodetemplate.innerHTML = ''
+        new QRCode('qrcodetemplate', {
+          width: 200,
+          height: 200,
+          text: url.toString()
+        })
+      })
+    }
+  }
+}
+</script>
+<style lang="scss">
+#qrcodetemplate{
+  width: 200px;
+  height: 200px;
+  margin: 0 auto;
+}
+</style>

+ 70 - 48
src/views/system/group/user/UserList.vue

@@ -7,15 +7,15 @@
         </div>
       </el-col>
       <el-col :span="16" class="right">
-        <el-input v-model="conditions.keywords" class="search-input m-right-15" placeholder="请输入内容">
-          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        <el-input v-model="conditions.keywords" class="search-input m-right-15" size="mini" placeholder="请输入内容">
+          <el-button slot="append" icon="el-icon-search" size="mini" @click="getData()" />
         </el-input>
-        <el-button type="primary" icon="el-icon-plus" @click="handleAddUser">新增</el-button>
+        <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddUser">账号</el-button>
       </el-col>
     </el-row>
 
     <el-row class="content-body">
-      <el-table v-loading="listLoading" class="page-table" :data="dataList" height="calc(100vh - 240px)">
+      <el-table v-loading="listLoading" class="page-table" :data="dataList" size="mini" height="calc(100vh - 240px)">
         <el-table-column type="index" align="center" label="序号" width="70" />
 
         <el-table-column align="center" header-align="center" label="头像" width="50">
@@ -75,27 +75,34 @@
           </template>
         </el-table-column>
 
-        <el-table-column label="操作" header-align="center" align="center" width="240">
+        <el-table-column label="操作" header-align="center" align="center" width="190">
           <template v-slot="{row}">
-            <el-button size="mini" @click="handleEditUser(row)">修改</el-button>
-            <el-button v-if="row.isFixed !== 1" size="mini" type="danger" @click="handleDeleteUser(row)">删除</el-button>
-            <el-dropdown v-if="row.isFixed !== 1" class="el-dropdown-link" @command="(command)=>handlerCommand(command, row)">
-              <el-button size="mini" type="primary">
-                更多<i class="el-icon-arrow-down el-icon--right" />
-              </el-button>
-              <el-dropdown-menu slot="dropdown">
-                <template v-if="row.grantGroupId > 0">
-                  <el-dropdown-item command="editGrantGroup">编辑授权</el-dropdown-item>
-                  <el-dropdown-item command="delGrantGroup">解除授权</el-dropdown-item>
-                </template>
-                <template v-else>
-                  <el-dropdown-item command="addGrantGroup">添加授权</el-dropdown-item>
-                </template>
-                <el-dropdown-item command="resetPwd">重置密码</el-dropdown-item>
-                <el-dropdown-item command="handlePermit">权限配置</el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
+            <div v-if="row.isFixed !== 1">
+              <el-button size="mini" @click="handleEditUser(row)">修改</el-button>
+              <el-button v-if="row.isFixed !== 1" size="mini" type="danger" @click="handleDeleteUser(row)">删除</el-button>
+              <el-dropdown v-if="row.isFixed !== 1" class="el-dropdown-link" @command="(command)=>handlerCommand(command, row)">
+                <el-button size="mini" type="primary">
+                  更多<i class="el-icon-arrow-down el-icon--right" />
+                </el-button>
+                <el-dropdown-menu slot="dropdown">
+                  <template v-if="row.grantGroupId > 0">
+                    <el-dropdown-item command="editGrantGroup">编辑授权</el-dropdown-item>
+                    <el-dropdown-item command="delGrantGroup">解除授权</el-dropdown-item>
+                  </template>
+                  <template v-else>
+                    <el-dropdown-item command="addGrantGroup">添加授权</el-dropdown-item>
+                  </template>
+                  <el-dropdown-item command="resetPwd">重置密码</el-dropdown-item>
+                  <el-dropdown-item command="handlePermit">权限配置</el-dropdown-item>
+                  <el-dropdown-item command="bindWx">微信绑定</el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </div>
+            <div v-else>
+              <span><el-tag type="info">系统锁定</el-tag></span>
+            </div>
           </template>
+
         </el-table-column>
       </el-table>
 
@@ -109,6 +116,7 @@
     <grant-group ref="AddGrantGroup" title="添加授权" @formSuccess="getData" />
     <grant-group ref="EditGrantGroup" title="变更授权" @formSuccess="getData" />
     <account-permit ref="AccountPermit" title="权限配置" />
+    <BindWx ref="BindWx" />
   </div>
 </template>
 
@@ -117,16 +125,17 @@ import Pagination from '@/components/Pagination' // secondary package based on e
 import AccountPermit from '@/views/system/permit/account'
 import GrantGroup from './GrantGroup.vue'
 import User from './User.vue'
+import BindWx from './BindWx.vue'
 import { deleteUserById, getUserByPage, resetPassword, updateUserStatus } from '@/api/system/userApi'
 import { mapGetters } from 'vuex'
 
 export default {
   name: 'UserList',
-  components: { Pagination, User, GrantGroup, AccountPermit },
+  components: { Pagination, User, GrantGroup, AccountPermit, BindWx },
   props: { },
   data() {
     return {
-      title: '用户管理',
+      title: '账号管理',
       dataList: [],
       total: 0,
       listLoading: false,
@@ -151,6 +160,26 @@ export default {
 
   methods: {
 
+    // 加载数据
+    loadData(groupId, groupName) {
+      this.conditions.groupId = groupId
+      this.conditions.groupName = groupName
+      this.getData()
+    },
+
+    // 请求数据
+    getData() {
+      this.listLoading = true
+      getUserByPage(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { data, total } = resp
+        this.total = total
+        this.dataList = data
+      }).catch((error) => {
+        console.log(error)
+      })
+    },
+
     // Change User "Status"
     handlerChangeUserStatus(status, data) {
       updateUserStatus(data.accountId, status).then((resp) => {
@@ -183,44 +212,29 @@ export default {
         case 'handlePermit':
           this.handlePermit(data)
           break
-      }
-    },
 
-    // Load Data
-    loadData(groupId, groupName) {
-      this.conditions.groupId = groupId
-      this.conditions.groupName = groupName
-      this.getData()
-    },
-
-    // Fetch User Data
-    getData() {
-      this.listLoading = true
-      getUserByPage(this.conditions).then((resp) => {
-        this.listLoading = false
-        const { data, total } = resp
-        this.total = total
-        this.dataList = data
-      }).catch((error) => {
-        console.log(error)
-      })
+        case 'bindWx':
+          console.log('bindWx')
+          this.handleWinXin(data)
+          break
+      }
     },
 
-    // Click "Add"
+    // 新增
     handleAddUser() {
       const groupId = this.conditions.groupId
       const groupName = this.conditions.groupName
       this.$refs['AddUser'].showAddModel(groupId, groupName)
     },
 
-    // Click "Edit"
+    // 编辑
     handleEditUser(data) {
       const groupId = data.groupId
       const accountId = data.accountId
       this.$refs['EditUser'].showEditModel(groupId, accountId)
     },
 
-    // Click "Reset Password"
+    // 重置密码
     handleResetPassword(data) {
       this.$confirm('温馨提示:系统默认重置密码为 888888', '提示', {
         confirmButtonText: '确定',
@@ -242,6 +256,14 @@ export default {
       this.$refs['AccountPermit'].showModel(accountId, positionId)
     },
 
+    // 微信绑定
+    handleWinXin(data) {
+      const { accountId, wxCode } = data
+      this.$refs.BindWx.show(accountId, wxCode)
+    },
+
+    handleDelGrantGroup() {},
+
     // Click "Delete" User
     handleDeleteUser(data) {
       this.$confirm('此操作将永久删除该账号, 是否继续?', '提示', {

+ 3 - 2
src/views/system/permit/position/index.vue

@@ -1,11 +1,11 @@
 <template>
   <el-drawer
     :title="title"
-    :modal-append-to-body="false"
+    :append-to-body="true"
     :modal="false"
     :wrapper-closable="false"
     :visible.sync="dialogVisible"
-    size="50%"
+    size="40%"
   >
     <div class="content-container">
       <el-row class="content-body">
@@ -53,6 +53,7 @@ import { getPositionPermitViewByList, createPositionPermit, deletePositionPermit
 import { permitTplId } from '@/settings'
 import { mapGetters } from 'vuex'
 export default {
+  name: 'PositionPermitIndex',
   props: {
     title: {
       type: String,

+ 2 - 1
src/views/system/position/components/Position.vue

@@ -21,7 +21,7 @@
       </el-form>
 
       <div class="btn-group">
-        <el-button type="primary" @click="submitForm('ruleForm')">确定</el-button>
+        <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
         <el-button class="cancel-btn" @click="dialogVisible = false">取消</el-button>
       </div>
     </div>
@@ -32,6 +32,7 @@
 import { ACTION_ADD, ACTION_UPDATE } from '@/utils/actionType'
 import { getPositionById, createPosition, updatePosition } from '@/api/system/positionApi'
 export default {
+  name: 'Position',
   props: {
     title: {
       type: String,

+ 4 - 4
src/views/system/position/index.vue

@@ -5,12 +5,12 @@
         <div class="content-title">岗位管理</div>
       </el-col>
       <el-col :span="12" class="right">
-        <el-input v-model="conditions.keywords" style="width: 200px;" class="filter-item" prefix-icon="el-icon-search" placeholder="请输入内容" @keyup.enter.native="handleFilter" />
-        <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-search" @click="getData">查询</el-button>
-        <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
+        <el-input v-model="conditions.keywords" style="width: 200px;" class="filter-item" prefix-icon="el-icon-search" size="mini" placeholder="请输入内容" @keyup.enter.native="getData" />
+        <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-search" size="mini" @click="getData">查询</el-button>
+        <el-button class="filter-item" type="primary" icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
       </el-col>
     </el-row>
-    <el-table v-loading="listLoading" class="page-table" border :data="dataList" height="calc(100vh - 280px)">
+    <el-table v-loading="listLoading" class="page-table" border :data="dataList" size="mini" height="calc(100vh - 240px)">
       <el-table-column type="index" label="序号" header-align="center" align="center" width="80" />
 
       <el-table-column label="岗位名称" width="200" align="center" header-align="center">

+ 1 - 1
src/views/system/profile/userProfile.vue

@@ -111,7 +111,7 @@
 </template>
 <script>
 import { serverUrl, devServerUrl } from '@/settings'
-import { getUserProfile, updateUserProfile } from '@/api/index'
+import { getUserProfile, updateUserProfile } from '@/api'
 import { updatePassword } from '@/api/system/userApi'
 import { mapGetters } from 'vuex'
 import vuescroll from 'vuescroll'