22 Achegas a9ae0de5b3 ... f94687fff6

Autor SHA1 Mensaxe Data
  unknown f94687fff6 doc:更新文档 %!s(int64=4) %!d(string=hai) anos
  unknown a1861597fe beifen %!s(int64=4) %!d(string=hai) anos
  xzh f1bef54fb8 feat:修改 %!s(int64=4) %!d(string=hai) anos
  徐志豪 581c0ccef9 feat:接入腾讯云音视频 %!s(int64=5) %!d(string=hai) anos
  徐志豪 2a50f5b3a2 fix: 修改合并代码后报错的问题 %!s(int64=5) %!d(string=hai) anos
  徐志豪 7d520f9b52 Merge branch 'haowan' of http://192.168.0.115:3000/xuzhihao/haowanShow into haowan %!s(int64=5) %!d(string=hai) anos
  徐志豪 423f78dd17 feat:增加企业信息填写缓存。修改优化讲解员选择弹窗 %!s(int64=5) %!d(string=hai) anos
  徐志豪 c9b201573d 报表功能 %!s(int64=5) %!d(string=hai) anos
  徐志豪 46d1577361 feat:好玩展1.0.3 %!s(int64=5) %!d(string=hai) anos
  徐志豪 781b94a047 小程序首页改版 %!s(int64=5) %!d(string=hai) anos
  徐志豪 b08d06b1aa 第一版发布 %!s(int64=5) %!d(string=hai) anos
  徐志豪 b89f830b8e feat:提测准备 %!s(int64=5) %!d(string=hai) anos
  bill e61f05e71d 修改删除bug %!s(int64=5) %!d(string=hai) anos
  徐志豪 88fc3aadb4 Merge branch 'haowan' of http://192.168.0.115:3000/xuzhihao/haowanShow into haowan %!s(int64=5) %!d(string=hai) anos
  徐志豪 e06c9742f1 feat:功能基本完成 %!s(int64=5) %!d(string=hai) anos
  bill db95738147 添加讲解员界面 %!s(int64=5) %!d(string=hai) anos
  bill 6eb2ecef2c Merge branch 'haowan' of http://192.168.0.115:3000/xuzhihao/haowanShow into haowan %!s(int64=5) %!d(string=hai) anos
  徐志豪 69ac5b92ec 去掉3101的退出登陆 %!s(int64=5) %!d(string=hai) anos
  bill 0d27b82bda Merge branch 'haowan' of http://192.168.0.115:3000/xuzhihao/haowanShow into haowan %!s(int64=5) %!d(string=hai) anos
  bill 1f64e1c3bf 添加讲解员页面 %!s(int64=5) %!d(string=hai) anos
  徐志豪 65dbd31e42 feat:增加展会编辑的功能,企业信息编辑的功能 %!s(int64=5) %!d(string=hai) anos
  徐志豪 7af0677d03 feat:好玩展 %!s(int64=5) %!d(string=hai) anos
Modificáronse 100 ficheiros con 3402 adicións e 781 borrados
  1. 2 0
      admin/package.json
  2. 0 26
      admin/src/api/agency.js
  3. 52 0
      admin/src/api/company.js
  4. 0 32
      admin/src/api/estate.js
  5. 15 0
      admin/src/api/guide.js
  6. 0 66
      admin/src/api/house.js
  7. 45 33
      admin/src/api/index.js
  8. 1 1
      admin/src/api/qqmap.js
  9. 0 34
      admin/src/api/region.js
  10. 0 26
      admin/src/api/store.js
  11. 2 2
      admin/src/api/upload.js
  12. 31 7
      admin/src/assets/css/global.less
  13. 1 1
      admin/src/components/LoginForm.vue
  14. 12 4
      admin/src/components/Modal/index.vue
  15. 25 8
      admin/src/components/map/index.vue
  16. 252 0
      admin/src/components/quillEditor/index.vue
  17. 5 3
      admin/src/components/tables/handle-btns.vue
  18. 6 6
      admin/src/components/tables/tables.vue
  19. 54 9
      admin/src/components/upload/index.vue
  20. 67 18
      admin/src/components/upload/video.vue
  21. 9 9
      admin/src/config/agency.js
  22. 57 21
      admin/src/layout/index/index.vue
  23. 3 3
      admin/src/layout/login/login.vue
  24. 1 1
      admin/src/libs/request.js
  25. 49 48
      admin/src/router/index.js
  26. 58 23
      admin/src/router/routes.js
  27. 1 1
      admin/src/store/user.js
  28. 90 0
      admin/src/views/activity/activityEdit.vue
  29. 95 0
      admin/src/views/activity/enterpriseList.vue
  30. 183 0
      admin/src/views/activity/homeAdmin.vue
  31. 0 0
      admin/src/views/activity/index.vue
  32. 394 0
      admin/src/views/enterprise/components/baseForm.vue
  33. 53 0
      admin/src/views/enterprise/components/introPicForm.vue
  34. 56 0
      admin/src/views/enterprise/components/videoForm.vue
  35. 196 0
      admin/src/views/enterprise/index.vue
  36. 9 0
      admin/src/views/industry/index.vue
  37. 130 0
      admin/src/views/industry/list.vue
  38. 201 0
      admin/src/views/system/commentator/list.vue
  39. 97 0
      admin/src/views/system/commentator/userList.vue
  40. 32 18
      admin/src/views/system/user/list.vue
  41. 5 5
      admin/vue.config.js
  42. BIN=BIN
      admin/备份/favicon.ico
  43. 1 0
      admin/备份/index.html
  44. 2 0
      admin/备份/static/css/app.002868d7.css
  45. 2 0
      admin/备份/static/css/app.acf3529d.css
  46. 2 0
      admin/备份/static/css/app.df3b1772.css
  47. 1 0
      admin/备份/static/css/chunk-157e109a.83d43db3.css
  48. 1 0
      admin/备份/static/css/chunk-38047187.4962b786.css
  49. 1 0
      admin/备份/static/css/chunk-441a8fbe.0473a37f.css
  50. 1 0
      admin/备份/static/css/chunk-44f6aa56.c53cdc34.css
  51. 1 0
      admin/备份/static/css/chunk-4f2d4116.6d6f7126.css
  52. 20 0
      admin/备份/static/css/chunk-57e8b9f0.5c4367e0.css
  53. 1 0
      admin/备份/static/css/chunk-5bb898a2.5b9c4312.css
  54. 1 0
      admin/备份/static/css/chunk-6cf27db8.2747e27d.css
  55. 1 0
      admin/备份/static/css/chunk-e48941e8.f00269c5.css
  56. 1 0
      admin/备份/static/css/chunk-vendors.2b907f11.css
  57. BIN=BIN
      admin/备份/static/fonts/ionicons.143146fa.woff2
  58. BIN=BIN
      admin/备份/static/fonts/ionicons.99ac3308.woff
  59. BIN=BIN
      admin/备份/static/fonts/ionicons.d535a25a.ttf
  60. BIN=BIN
      admin/备份/static/img/img_kor@2x.9b047e48.png
  61. BIN=BIN
      admin/备份/static/img/img_loginele_points@2x.82fc66fa.png
  62. 870 0
      admin/备份/static/img/ionicons.a2c4a261.svg
  63. 1 0
      admin/备份/static/js/app.18e9d2a1.js
  64. 1 0
      admin/备份/static/js/app.237eb3e7.js
  65. 1 0
      admin/备份/static/js/app.65f02c02.js
  66. 1 0
      admin/备份/static/js/app.df643551.js
  67. 1 0
      admin/备份/static/js/app.e0a0ef0f.js
  68. 1 0
      admin/备份/static/js/app.e20254bb.js
  69. 1 0
      admin/备份/static/js/chunk-157e109a.1723ce77.js
  70. 1 0
      admin/备份/static/js/chunk-157e109a.54549403.js
  71. 1 0
      admin/备份/static/js/chunk-2d0abe1d.8c64ea78.js
  72. 1 0
      admin/备份/static/js/chunk-2d0b3248.e3e48ef5.js
  73. 1 0
      admin/备份/static/js/chunk-38047187.a8445277.js
  74. 1 0
      admin/备份/static/js/chunk-38047187.d5b3a3ac.js
  75. 1 0
      admin/备份/static/js/chunk-441a8fbe.55fdf9a5.js
  76. 1 0
      admin/备份/static/js/chunk-441a8fbe.f37e9609.js
  77. 1 0
      admin/备份/static/js/chunk-44f6aa56.3934cede.js
  78. 1 0
      admin/备份/static/js/chunk-44f6aa56.a33bf786.js
  79. 1 0
      admin/备份/static/js/chunk-44f6aa56.c52cab81.js
  80. 1 0
      admin/备份/static/js/chunk-44f6aa56.d275c919.js
  81. 1 0
      admin/备份/static/js/chunk-44f6aa56.ef22b0ac.js
  82. 1 0
      admin/备份/static/js/chunk-4f2d4116.0b2a2c7b.js
  83. 8 0
      admin/备份/static/js/chunk-57e8b9f0.f0441554.js
  84. 1 0
      admin/备份/static/js/chunk-5bb898a2.df9602a7.js
  85. 1 0
      admin/备份/static/js/chunk-6cf27db8.e0890c98.js
  86. 1 0
      admin/备份/static/js/chunk-e2831abe.3b165715.js
  87. 1 0
      admin/备份/static/js/chunk-e48941e8.c0a9513e.js
  88. 72 0
      admin/备份/static/js/chunk-vendors.f473a602.js
  89. 3 0
      miniprogram/apis/company.js
  90. 6 3
      miniprogram/apis/fetcher/request.js
  91. 4 0
      miniprogram/apis/goods.js
  92. 4 3
      miniprogram/apis/im.js
  93. 11 1
      miniprogram/apis/index.js
  94. 71 32
      miniprogram/app.js
  95. 2 5
      miniprogram/app.json
  96. 1 1
      miniprogram/app.wxss
  97. BIN=BIN
      miniprogram/assets/font/iconfont.eot
  98. 1 0
      miniprogram/assets/font/iconfont.js
  99. 0 331
      miniprogram/assets/font/iconfont.json
  100. 0 0
      miniprogram/assets/font/iconfont.ttf

+ 2 - 0
admin/package.json

@@ -24,9 +24,11 @@
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "path-to-regexp": "2.4.0",
+    "quill-image-extend-module": "^1.1.2",
     "view-design": "^4.2.0",
     "vue": "2.6.10",
     "vue-i18n": "^8.17.7",
+    "vue-quill-editor": "^3.0.6",
     "vue-router": "3.0.6",
     "vuex": "3.1.0"
   },

+ 0 - 26
admin/src/api/agency.js

@@ -1,26 +0,0 @@
-import request from 'libs/request'
-
-/*
-** @decs 获取小区列表
-*/
-export function fetchAgencyList (data) {
-  data.store = data.tools_0 || ''
-  data.keyword = data.searchKey
-  return request.get('agency/queryList', {params: data})
-}
-
-export function createAgency (data) {
-  return request.post('agency/add', data)
-}
-
-export function fetchAgencyDetail (agency_id) {
-  return request.get('agency/detail', { params: { agency_user_id: agency_id } })
-}
-
-export function updateAgency (data) {
-  return request.post('agency/update', data)
-}
-
-export function deleteAgency (strIds) {
-  return request.post('agency/delete', { strIds })
-}

+ 52 - 0
admin/src/api/company.js

@@ -0,0 +1,52 @@
+import request from 'libs/request'
+import { getToken } from 'libs/token'
+
+export function addCompany (data) {
+  return request.post('company/add', data)
+}
+
+export function getCompanyDetail (companyId) {
+  return request.get('company/getCompanyDetail', {params: {companyId}})
+}
+
+export function getCompanyList (params) {
+  const defaultParams = {
+    pageNum: 1,
+    pageSize: 10,
+    key: params.searchKey || '',
+    token: getToken()
+  }
+  return request.get('company/getCompanyList', {params: Object.assign(defaultParams, params)})
+}
+
+export function updateCompany (data) {
+  return request.post('company/update', data)
+}
+
+export function fetchAllScene (data) {
+  const defaultParams = {
+    page_num: 1,
+    page_size: 999,
+    searchKey: '',
+    token: getToken()
+  }
+  return request.post('company/getAllScene', Object.assign(defaultParams, data))
+}
+
+export function getIndustry (params) {
+  const defaultParams = {
+    pageNum: 1,
+    pageSize: 10,
+    keyword: params.searchKey || '',
+    token: getToken()
+  }
+  return request.get('activity/trade/queryOrGetTradeList', {params: Object.assign(defaultParams, params)})
+}
+
+export function createIndustry (data) {
+  return request.post('activity/trade/add', data)
+}
+
+export function updateIndustry (data) {
+  return request.post('activity/trade/update', data)
+}

+ 0 - 32
admin/src/api/estate.js

@@ -1,32 +0,0 @@
-import request from 'libs/request'
-
-/*
-** @decs 获取小区列表
-*/
-export function fetchEstateList (data={}) {
-  const defaultParams = {
-    page_size: 10,
-    page_num: 1,
-    province: '',
-    city: '',
-    district: '',
-    query_name: data.searchKey || ''
-  }
-  return request.get('estate/queryAll', {params: Object.assign(defaultParams, data)})
-}
-
-export function createEstate (data) {
-  return request.post('estate/add', data)
-}
-
-export function fetchEstateDetail (estate_id) {
-  return request.get('estate/detail', { params: {estate_id} })
-}
-
-export function updateEstate (data) {
-  return request.post('estate/update', data)
-}
-
-export function deleteEstate (strIds) {
-  return request.post('estate/delete', { strIds })
-}

+ 15 - 0
admin/src/api/guide.js

@@ -0,0 +1,15 @@
+import request from 'libs/request'
+import { getToken } from 'libs/token'
+
+export function getGuideList (data) {
+  let defaultOpt = {
+    pageSize: 20,
+    pageNum: 1,
+    keyword: ''
+  }
+  return request.get('viewer/queryGuidList', {params: Object.assign(defaultOpt, data)})
+}
+
+export function getGuideById (guideId) {
+  return request.get('viewer/getGuideById', {params: { viewerId: guideId }})
+}

+ 0 - 66
admin/src/api/house.js

@@ -1,66 +0,0 @@
-import request from 'libs/request'
-import { getToken } from 'libs/token'
-/*
-** @decs 获取房源列表
-*/
-export function fetchHouseList (data) {
-  data.estate_name = data.tools_0 || ''
-  data.sale_type = data.tools_1 || ''
-  data.query_name = data.searchKey || ''
-  return request.get('house/queryAll', {params: data})
-}
-
-export function createHouse (data) {
-  return request.post('house/add', data)
-}
-
-export function fetchHouseDetail (house_id) {
-  return request.get('house/house', { params: {house_id} })
-}
-
-export function updateHouse (data) {
-  return request.post('house/update', data)
-}
-
-export function fetchUnAgentHouse (params) {
-  const defaultParams = {
-    sale_type: 1,
-    page_size: 10,
-    page_num: 1,
-    query_name: ''
-  }
-  params = Object.assign(defaultParams, params)
-  return request.get('house/queryHouse', { params })
-}
-
-/*
-** @desc 增加关联经纪人
-** @params agency_user_id 经纪人id
-** @params house_ids Array 房源id集合
-*/
-export function attachAgency (data) {
-  return request.post('house/attachAgency', data)
-}
-
-/*
-** @desc 修改关联经纪人
-** @params agencyUserIdNew 准绑定经纪人id
-** @params agencyUserIdOld 老绑定经纪人id
-** @params house_id String 房源id
-*/
-export function changeAgency (data) {
-  return request.post('house/changeAgency', data)
-}
-export function deleteHouse (strIds) {
-  return request.post('house/delete', { strIds })
-}
-
-export function fetchAllScene (data) {
-  const defaultParams = {
-    page_num: 1,
-    page_size: 10,
-    searchKey: '',
-    token: getToken()
-  }
-  return request.post('house/getAllScene', Object.assign(defaultParams, data))
-}

+ 45 - 33
admin/src/api/index.js

@@ -14,53 +14,65 @@ export function login(data) {
   })
 }
 
-// 注册接口
-export function register(data) {
-  return request({
-    url: 'register',
-    method: 'post',
-    data
-  })
-}
-
-// 获取验证码接口
-export function getCode(data) {
-  data.area_num = '86'
-  return request({
-    url: `getMsgAuthCode`,
-    method: 'get',
-    params: data
-  })
-}
-
-// 修改密码
-export function changePassword (data) {
-  return request({
-    url: `changePassword`,
-    method: 'post',
-    data: data
-  })
-}
 
 // 获取管理员列表
 export function fetchUserList (params= {}) {
   const defaultParams = {
     query_name: params.searchKey,
     page_size: 10,
-    page_num: 1
+    page_num: params.pageNum || 1
   }
   return request.get('listAdmin', {params: Object.assign(defaultParams, params)})
 }
 
-export function fetchRoleList () {
-  return request.get('sysRole/list')
+
+// 获取讲解员列表
+export function fetchViewerList (params= {}) {
+  const defaultParams = {
+    registerType: '2',
+    keyword: params.searchKey,
+    pageSize: 10,
+    pageNum: 1
+  }
+  return request.get('viewer/queryViewerList', {params: Object.assign(defaultParams, params)})
+}
+
+
+// 观众修改为讲解员
+export function updateViewerToGuide (id) {
+  return request.get('viewer/changeToGuide', {params: {viewerId: id}})
 }
-// 获取首页统计信息
-export function getHomeData () {
-  return request.get('home')
+
+
+// 获取讲解员列表
+export function fetchGuidList (params= {}) {
+  const defaultParams = {
+    keyword: params.searchKey,
+    pageSize: 10,
+    pageNum: 1
+  }
+  return request.get('viewer/queryGuidList', {params: Object.assign(defaultParams, params)})
 }
 
 export function updateUser (data) {
   return request.post('changeInfo', data)
 }
 
+// 修改讲解员资料
+export function updateGuide (data) {
+  return request.post('viewer/updateGuide', data)
+}
+
+// 修改首页运营的数据
+export function upadteActivity (data) {
+  return request.post('activity/update', data)
+}
+
+// 获取最新一个展会的详情
+export function getActivityDetail () {
+  return request.get('activity/getLatest')
+}
+
+export function refreshAdminerInfo (adminId) {
+  return request.get('getAdminById', { params: { adminId } })
+}

+ 1 - 1
admin/src/api/qqmap.js

@@ -20,7 +20,7 @@ export function getDistrictList () {
   return request(`district/v1/list`, {})
 }
 
-export function searchPlaceByKeyword ({keyword, boundary}) {
+export function searchPlaceByKeyword ({keyword, boundary=`region(珠海,0)`}) {
   return request('place/v1/search', {keyword, boundary})
 }
 

+ 0 - 34
admin/src/api/region.js

@@ -1,34 +0,0 @@
-import request from 'libs/request'
-
-export function fetchCityList (params) {
-  const defalutParams = {
-    type: '',
-    query_name: params.searchKey || '',
-  }
-  return request.get('region/list', {params: Object.assign(defalutParams, params)})
-}
-
-export function createCity (data) {
-  return request.post('region/save', data)
-}
-
-export function fetchChildCity (parent_id) {
-  return request.get('region/child/list', {params: {parent_id}})
-}
-
-export function delRegion (ids) {
-  return request.post('region/delete', { ids })
-}
-
-export function fetchRegionDetail (region_id) {
-  return request.get(`region/info/${region_id}`)
-}
-
-export function updateRegion (data) {
-  return request.post('region/update', data)
-}
-
-export function deleteRegion (strIds) {
-  return request.post('region/delete', { strIds })
-}
-

+ 0 - 26
admin/src/api/store.js

@@ -1,26 +0,0 @@
-import request from 'libs/request'
-
-export function fetchStoreList (params) {
-  const defaultParams = {
-    keyword: params.searchKey || '',
-    page_size: 10,
-    page_num: 1
-  }
-  return request.get('store/queryList', {params: Object.assign(defaultParams, params)})
-}
-
-export function createStore (data) {
-  return request.post('store/add', data)
-}
-
-export function updateStore (data) {
-  return request.post('store/update', data)
-}
-
-export function fetchAllStore (params) {
-  return request.get('store/all', {params})
-}
-
-export function deleteStore (intIds) {
-  return request.post('store/delete', { intIds })
-}

+ 2 - 2
admin/src/api/upload.js

@@ -1,5 +1,5 @@
 import request from 'libs/request'
-// const UploadUrl = '//127.0.0.1:1935'
+const UploadUrl = '//127.0.0.1:1935'
 export function uploadFile (file, opts) {
   if (!file) return new Promise(resolve => resolve())
   if (file.type === 'image/png' || file.type === 'image/jpeg') {
@@ -31,7 +31,7 @@ export function uploadVideo (file) {
   let formData = new FormData()
 
   formData.append('file', file)
-  return request.post(`house/upLoadVideo`, formData)
+  return request.post(`../node-upload/upLoadVideo`, formData)
 }
 
 export function getVideoFirstImage (object_name) {

+ 31 - 7
admin/src/assets/css/global.less

@@ -17,13 +17,16 @@ body,
     font-size: 14px;
   }
   .ivu-btn {
-    // border-color: #1FE4DC;
-    // background-color: transparent;
-    // color: #1FE4DC;
+    border-color: rgba(255,255,255,0.88);
+    background-color: transparent;
+    color:rgba(255,255,255,0.88);
+    // min-width: 88px;
   }
   .ivu-btn-primary {
+    border-color: #1FE4DC;
     background-color: #1FE4DC;
     color: #fff;
+    // min-width: 116px;
   }
   .ivu-btn-ghost.ivu-btn-primary {
     color: #1FE4DC;
@@ -40,7 +43,6 @@ body,
   }
   .ivu-input-word-count,.ivu-input-group-append {
     background: #161a1a;
-    
   }
   .ivu-input-group-append {
     border-left: none;
@@ -108,6 +110,16 @@ body,
   .ivu-select-large.ivu-select-multiple .ivu-tag {
     background-color: transparent;
   }
+  .ivu-form .ivu-form-item-label {
+    padding: 13px 20px 13px 0;
+    text-align: left;
+  }
+  .ivu-form-item {
+    margin-bottom: 30px;
+  }
+  .ivu-form-item-required .ivu-form-item-label:before {
+    display: none;
+  }
 }
 
 // 覆盖 view-design 默认样式 start
@@ -320,9 +332,9 @@ select:-webkit-autofill {
   line-height: 1;
 }
 
-.upload-box {
-  width: 500px;
-}
+// .upload-box {
+//   width: 500px;
+// }
 .house-upload {
   width: 100px;
   height: 100px;
@@ -332,4 +344,16 @@ select:-webkit-autofill {
   position: fixed;
   left: 99999px;
   top: 99999px;
+}
+
+.min-container {
+  width: 936px;
+  margin: 0 auto;
+}
+
+.header-title {
+  color: rgba(255,255,255,0.8);
+  border-bottom: 1px solid rgba(255,255,255,0.8);
+  padding: 25px 0 18px;
+  font-size: 16px;
 }

+ 1 - 1
admin/src/components/LoginForm.vue

@@ -60,7 +60,7 @@ export default {
       loginModel: {
         type: 'login',
         handle: 'handleLogin',
-        title: '后台登录',
+        title: '登录',
         buttonText: '登录',
         item: [{
           name: '账号',

+ 12 - 4
admin/src/components/Modal/index.vue

@@ -1,11 +1,8 @@
 <template>
-  <Modal :width="width" v-model="show" footer-hide :mask-closable="false">
+  <Modal :width="width" v-model="showStatus" footer-hide >
     <div slot="header" class="modal-header">
       {{ title }}
     </div>
-    <div class="close" slot="close">
-      <Icon custom="iconfont iconform_close" @click="close" />
-    </div>
     <div class="content">
       <slot />
       <div  class="btn-w">
@@ -28,6 +25,16 @@ export default {
       default: '保存'
     }
   },
+  computed: {
+    showStatus: {
+      set (val) {
+        this.$emit('close')
+      },
+      get () {
+        return this.show
+      }
+    }
+  },
   methods: {
     close () {
       this.$emit('close')
@@ -43,6 +50,7 @@ export default {
   line-height: 50px;
   padding-left: 20px;
   font-size: 16px;
+  border-bottom:1px solid rgba(255,255,255,0.05);
 }
 .btn-w {
   text-align: right;

+ 25 - 8
admin/src/components/map/index.vue

@@ -47,6 +47,23 @@ export default {
         this.initMarkerEvent()
       
     },
+    search ({lat, lng}) {
+      this.map.setCenter(new TMap.LatLng(lat,lng))
+      this.marker.remove(["1"])
+        const latLng = {lat, lng}
+        this.markerArr = [{
+          id: '1',
+          styleId: 'marker',
+          position: latLng,
+          properties: {
+            title: '1'
+          }
+        }]
+        this.marker.add(this.markerArr)
+        getLocationByGeocoder(`${latLng.lat},${latLng.lng}`).then(res => {
+          this.$emit('clickMap', {address_component: res.result.address_component,address: res.result.formatted_addresses.recommend, location: res.result.location})
+        })
+    },
     getLocationByIp () {
       if (this.location.location) {
         return
@@ -79,7 +96,7 @@ export default {
       
     },
     initMarkerEvent () {
-      let marker = new TMap.MultiMarker({
+      this.marker = new TMap.MultiMarker({
             id: 'marker-layer',
             map: this.map,
             styles: {
@@ -92,7 +109,7 @@ export default {
             },
             geometries: this.markerArr
         })
-        marker.remove(["1"])
+        this.marker.remove(["1"])
         let latlng = {
               lat: this.latitude,
               lng: this.longitude
@@ -105,9 +122,9 @@ export default {
             title: '1'
           }
         }]
-        marker.add(this.markerArr)
+        this.marker.add(this.markerArr)
         this.map.on('click', (evt) => {
-          marker.remove(["1"])
+          this.marker.remove(["1"])
           const latLng = evt.latLng
           this.markerArr = [{
             id: '1',
@@ -117,7 +134,7 @@ export default {
               title: '1'
             }
           }]
-          marker.add(this.markerArr)
+          this.marker.add(this.markerArr)
           getLocationByGeocoder(`${latLng.lat},${latLng.lng}`).then(res => {
             this.$emit('clickMap', {address_component: res.result.address_component,address: res.result.formatted_addresses.recommend, location: res.result.location})
           })
@@ -131,10 +148,10 @@ export default {
 <style lang="less">
 .qqmap {
   position: relative;
-  width: 800px;
+  width: 100%;
   height: 400px;
   background-color: #28272a;
-  padding-top: 20px;
+  margin-top: 20px;
 }
 .map-tools {
   position: absolute;
@@ -158,7 +175,7 @@ export default {
 }
 .map {
     position: relative;
-    width: 800px;
+    width: 100%;
   height: 400px;
   }
 .map-select {

+ 252 - 0
admin/src/components/quillEditor/index.vue

@@ -0,0 +1,252 @@
+<template>
+  <div class="quillEditor">
+    <div style="min-height: 460px">
+      <quill-editor
+        ref="myQuillEditor"
+        v-model="content"
+        :options="editorOption"
+        @blur="onEditorBlur($event)"
+        @focus="onEditorFocus($event)"
+        @ready="onEditorReady($event)"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import "quill/dist/quill.core.css";
+import "quill/dist/quill.snow.css";
+import "quill/dist/quill.bubble.css";
+import { quillEditor, Quill } from "vue-quill-editor";
+import { uploadPic } from "@/api/upload";
+import { container, ImageExtend, QuillWatch } from "quill-image-extend-module";
+Quill.register('modules/ImageExtend', ImageExtend)
+
+const titleConfig = [
+  { Choice: ".ql-bold", title: "加粗" },
+  { Choice: ".ql-italic", title: "斜体" },
+  { Choice: ".ql-underline", title: "下划线" },
+  { Choice: ".ql-header", title: "段落格式" },
+  { Choice: ".ql-strike", title: "删除线" },
+  { Choice: ".ql-blockquote", title: "块引用" },
+  { Choice: ".ql-code", title: "插入代码" },
+  { Choice: ".ql-code-block", title: "插入代码段" },
+  { Choice: ".ql-font", title: "字体" },
+  { Choice: ".ql-size", title: "字体大小" },
+  { Choice: '.ql-list[value="ordered"]', title: "编号列表" },
+  { Choice: '.ql-list[value="bullet"]', title: "项目列表" },
+  { Choice: ".ql-direction", title: "文本方向" },
+  { Choice: '.ql-header[value="1"]', title: "h1" },
+  { Choice: '.ql-header[value="2"]', title: "h2" },
+  { Choice: ".ql-align", title: "对齐方式" },
+  { Choice: ".ql-color", title: "字体颜色" },
+  { Choice: ".ql-background", title: "背景颜色" },
+  { Choice: ".ql-image", title: "图像" },
+  { Choice: ".ql-video", title: "视频" },
+  { Choice: ".ql-link", title: "添加链接" },
+  { Choice: ".ql-formula", title: "插入公式" },
+  { Choice: ".ql-clean", title: "清除字体格式" },
+  { Choice: '.ql-script[value="sub"]', title: "下标" },
+  { Choice: '.ql-script[value="super"]', title: "上标" },
+  { Choice: '.ql-indent[value="-1"]', title: "向左缩进" },
+  { Choice: '.ql-indent[value="+1"]', title: "向右缩进" },
+  { Choice: ".ql-header .ql-picker-label", title: "标题大小" },
+  { Choice: '.ql-header .ql-picker-item[data-value="1"]', title: "标题一" },
+  { Choice: '.ql-header .ql-picker-item[data-value="2"]', title: "标题二" },
+  { Choice: '.ql-header .ql-picker-item[data-value="3"]', title: "标题三" },
+  { Choice: '.ql-header .ql-picker-item[data-value="4"]', title: "标题四" },
+  { Choice: '.ql-header .ql-picker-item[data-value="5"]', title: "标题五" },
+  { Choice: '.ql-header .ql-picker-item[data-value="6"]', title: "标题六" },
+  { Choice: ".ql-header .ql-picker-item:last-child", title: "标准" },
+  { Choice: '.ql-size .ql-picker-item[data-value="small"]', title: "小号" },
+  { Choice: '.ql-size .ql-picker-item[data-value="large"]', title: "大号" },
+  { Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: "超大号" },
+  { Choice: ".ql-size .ql-picker-item:nth-child(2)", title: "标准" },
+  { Choice: ".ql-align .ql-picker-item:first-child", title: "居左对齐" },
+  {
+    Choice: '.ql-align .ql-picker-item[data-value="center"]',
+    title: "居中对齐"
+  },
+  {
+    Choice: '.ql-align .ql-picker-item[data-value="right"]',
+    title: "居右对齐"
+  },
+  {
+    Choice: '.ql-align .ql-picker-item[data-value="justify"]',
+    title: "两端对齐"
+  }
+];
+
+export default {
+  props: {
+    value: String
+  },
+  model: {
+    prop: "value",
+    event: "input"
+  },
+  data() {
+    return {
+      editorOption: {
+        modules: {
+          ImageExtend: {
+            // 如果不作设置,即{}  则依然开启复制粘贴功能且以base64插入
+            name: "file", // 图片参数名
+            size: 3, // 可选参数 图片大小,单位为M,1M = 1024kb
+            action: "/node-upload/uploadfile", // 服务器地址, 如果action为空,则采用base64插入图片
+            // response 为一个函数用来获取服务器返回的具体图片地址
+            // 例如服务器返回{code: 200; data:{ url: 'baidu.com'}}
+            // 则 return res.data.url
+            response: res => {
+              return res.data.url;
+            },
+            sizeError: () => {}, // 图片超过大小的回调
+            start: () => {}, // 可选参数 自定义开始上传触发事件
+            end: () => {}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
+            error: () => {}, // 可选参数 上传失败触发的事件
+            success: () => {}, // 可选参数  上传成功触发的事件
+            change: (xhr, formData) => {
+              // xhr.setRequestHeader('myHeader','myValue')
+              // formData.append('token', 'myToken')
+            } // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
+          },
+
+          toolbar: {
+            // 如果不上传图片到服务器,此处不必配置
+            container: [
+              ["bold", "italic", "underline", "strike"], // toggled buttons
+              ["blockquote", "code-block"],
+
+              [{ header: 1 }, { header: 2 }], // custom button values
+              [{ list: "ordered" }, { list: "bullet" }],
+              [{ script: "sub" }, { script: "super" }], // superscript/subscript
+              [{ indent: "-1" }, { indent: "+1" }], // outdent/indent
+              [{ direction: "rtl" }], // text direction
+
+              [{ size: ["small", false, "large", "huge"] }], // custom dropdown
+              [{ header: [1, 2, 3, 4, 5, 6, false] }],
+
+              [{ color: [] }, { background: [] }], // dropdown with defaults from theme
+              [{ font: [] }],
+              [{ align: [] }],
+              ["image"] //去除video即可
+            ], // container为工具栏,此次引入了全部工具栏,也可自行配置
+            handlers: {
+              image: function() {
+                // 劫持原来的图片点击按钮事件
+                QuillWatch.emit(this.quill.id);
+              }
+            }
+          }
+        }
+      }
+    };
+  },
+  computed: {
+    content: {
+      set(val) {
+        this.$emit("input", val);
+      },
+      get() {
+        return this.value;
+      }
+    },
+    editor() {
+      return this.$refs.myQuillEditor.quill;
+    }
+  },
+  components: {
+    quillEditor
+  },
+  methods: {
+    // onEditorInput (e) {
+    //   this.$emit('input', e)
+    // },
+    onEditorBlur(quill) {
+      // console.log("editor blur!", quill);
+    },
+    onEditorFocus(quill) {
+      // console.log("editor focus!", quill);
+    },
+    onEditorReady(quill) {
+      // console.log("editor ready!", quill);
+    },
+    onEditorChange({ quill, html, text }) {
+      // console.log("editor change!", quill, html, text);
+      this.content = html;
+    },
+    autotip() {
+      document.getElementsByClassName("ql-editor")[0].dataset.placeholder = "";
+      for (let item of titleConfig) {
+        let tip = document.querySelector(".quill-editor " + item.Choice);
+        if (!tip) continue;
+        tip.setAttribute("title", item.title);
+      }
+    }
+  },
+  mounted() {
+    console.log("this is current quill instance object", this.editor);
+    this.autotip();
+    this.editor.root.addEventListener(
+      "paste",
+      evt => {
+        if (
+          evt.clipboardData &&
+          evt.clipboardData.files &&
+          evt.clipboardData.files.length
+        ) {
+          evt.preventDefault();
+          [].forEach.call(evt.clipboardData.files, file => {
+            if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
+              return;
+            }
+            uploadPic(blob)(file, res => {
+              var range = this.editor.getSelection();
+              if (range) {
+                //  在当前光标位置插入图片
+                this.editor.insertEmbed(
+                  range.index,
+                  "image",
+                  this.$ajax.defaults.baseURL + res.file.path
+                );
+                //  将光标移动到图片后面
+                this.editor.setSelection(range.index + 1);
+              }
+            });
+          });
+        }
+      },
+      false
+    );
+  }
+};
+</script>
+
+<style lang="less">
+.act-edit {
+  padding: 30px;
+  .ql-snow .ql-picker {
+    color: #fff;
+  }
+  .ql-snow .ql-stroke {
+    stroke: #fff;
+  }
+  .ql-snow .ql-fill,
+  .ql-snow .ql-stroke.ql-fill {
+    fill: #fff;
+  }
+  .ql-editor {
+    background: #161a1a;
+    min-height: 460px;
+  }
+  .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {
+    color: #000;
+  }
+  .ql-snow .ql-icon-picker .ql-picker-item svg line {
+    stroke: #444;
+  }
+  .ql-snow .ql-picker-label::before {
+    vertical-align: top;
+  }
+}
+</style>

+ 5 - 3
admin/src/components/tables/handle-btns.vue

@@ -45,11 +45,13 @@ export default {
         view: 'toViewLayout',
         author: 'toAuthorLayout',
         edit: 'toEdit',
-        del: 'toDel'
+        del: 'toDel',
+        check: 'toCheck'
       },
       btn_text: {
         edit: '编辑',
-        del: '删除'
+        del: '删除',
+        check: '查看'
       }
     }
   },
@@ -83,7 +85,7 @@ export default {
 .btn {
   cursor: pointer;
 }
-.btn-edit {
+.btn-edit, .btn-check {
   color: #1FE4DC;
   margin-right: 15px;
   &:last-child {

+ 6 - 6
admin/src/components/tables/tables.vue

@@ -43,7 +43,7 @@
           v-if="pageParam.total > 0"
           :current.sync="pageParam.current"
           :total="pageParam.total"
-          :page-size="pageParam.page_size"
+          :page-size="pageParam.pageSize"
           class-name="tatle-page"
           size="small"
           show-total
@@ -99,7 +99,7 @@ export default {
     },
     placeholder: {
       type: String,
-      default: '房源ID/名称/经纪人'
+      default: '房源ID/名称/讲解员'
     }
   },
   data() {
@@ -111,7 +111,7 @@ export default {
       // 工具按钮组
       toolsBtnGroup: [],
       time: null,
-      pageParam: { page_num: 1, page_size: 10, searchKey: '', total: 0, current: 1, tools_0: '', tools_1: '' }
+      pageParam: { pageNum: 1, pageSize: 10, searchKey: '', total: 0, current: 1, tools_0: '', tools_1: '' }
     }
   },
   computed: {
@@ -122,7 +122,7 @@ export default {
   watch: {
     // 监听搜索框,并在用户在时间间隔内只发送一次请求
     'pageParam.searchKey'() {
-      this.$bebounce(this.handleTableData, { page_num: 1, current: 1 })
+      this.$bebounce(this.handleTableData, { pageNum: 1, current: 1 })
     },
     columns() {
       this.handleTableData()
@@ -230,7 +230,7 @@ export default {
     async handleRowBtn(param) {
       if (param.action === 'toDel') {
         // 获取对应的id字段得值
-        await this.deleteApi([param.row[this.deleteIdKey] || param.row[Object.keys(param.row).find(item => item.indexOf('_id') > -1)]])
+        await this.deleteApi([param.row[this.deleteIdKey] || param.row])
         this.handleTableData()
         return
       }
@@ -238,7 +238,7 @@ export default {
     },
     // 分页
     changePage(page) {
-      this.handleTableData({ page_num: page })
+      this.handleTableData({ pageNum: page })
     }
   }
 }

+ 54 - 9
admin/src/components/upload/index.vue

@@ -9,12 +9,14 @@
       action="#"
       :show-upload-list="false"
       :data="data"
+      v-if="!hideUpload"
     >
       <div class="upload">
         <Icon type="md-add" size="40" style="color: #1FE4DC;" />
-        <p>本地上传</p>
+        <!-- <p>本地上传</p> -->
       </div>
     </Upload>
+    <p class="tips">{{ tips }}</p>
       <div
         v-for="(uploadfiles) in hasUploads"
         :key="uploadfiles.img"
@@ -24,8 +26,9 @@
         <div
           class="close-btn"
           @click="handleCancleClick(uploadfiles, 'hasUploads')"
+          v-if="!hideUpload"
         >
-          <Icon class="close" custom="iconfont iconform_close" />
+          <Icon type="md-close-circle" size="16" class="close" />
         </div>
         <div
           class="tip "
@@ -45,8 +48,9 @@
         <div
           class="close-btn"
           @click="handleCancleClick(uploadfiles, 'preUploads')"
+          v-if="!hideUpload"
         >
-          <Icon class="close" custom="iconfont iconform_close" />
+          <Icon type="md-close-circle" size="16" class="close" />
         </div>
         <div
           class="tip "
@@ -64,15 +68,34 @@
 import { uploadFile } from 'api/upload'
 export default {
   props: {
-    preUploads: Array,
-    hasUploads: Array,
+    hideUpload: Boolean,
+    preUploads: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    hasUploads: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
     cover_image: String,
     limit: Number,
     multiple: {
       type: Boolean,
       default: true
     },
-    data: {}
+    data: {},
+    tips: {
+      type: String,
+      default: ''
+    },
+    maxSize: {
+      type: Number,
+      default: 500
+    }
   },
   data () {
     return {
@@ -85,6 +108,13 @@ export default {
   },
   methods: {
     handleBeforeUpload (file) {
+      const { size } = file
+      if (size > this.maxSize * 1024) {
+        this.$Message.error({
+          content: `图片大小超出限制`
+        })
+        return
+      }
       if (this.limit && this.uploads.length >= this.limit) {
         this.$Message.error({
           content: `只能上传${this.limit}张图片`
@@ -108,8 +138,9 @@ export default {
         this.data = opts
       }
       console.log(opts, 'opts')
-      return Promise.all(this.preUploads.map(item => this.uploadTypeFile(item))).then(() => {
-        return this.cover_image
+      console.log(this.preUploads)
+      return Promise.all(this.preUploads.map(item => this.uploadTypeFile(item))).then((res) => {
+        return res
       })
     },
     uploadTypeFile (file) {
@@ -123,7 +154,7 @@ export default {
         file.img = res.data.url
         this.hasUploads.push(file)
         this.preUploads.splice(this.preUploads.indexOf(file), 1)
-        return res
+        return file.img
       })
     },
     handleClickCover (file) {
@@ -132,3 +163,17 @@ export default {
   }
 }
 </script>
+
+<style lang="less" scoped>
+.upload {
+  padding: 30px 0 !important;
+  
+}
+.tips {
+    position: absolute;
+    bottom: -8px;
+    font-size: 12px;
+    color:rgba(255,255,255,0.38);
+    line-height: 1;
+  }
+</style>

+ 67 - 18
admin/src/components/upload/video.vue

@@ -8,38 +8,49 @@
       :before-upload="handleBeforeUpload"
       action="#"
       :show-upload-list="false"
+      v-if="!hideUpload"
     >
       <div class="upload">
         <Icon type="md-add" size="40" style="color: #1FE4DC;" />
-        <p>本地上传</p>
+        <!-- <p>本地上传</p> -->
       </div>
     </Upload>
       <div
         v-for="(uploadfiles) in hasUploads"
         :key="uploadfiles.img"
         class="file-item"
+        @click="selectedVideo = uploadfiles.url;show=true"
       >
         <img :src="uploadfiles.img" />
         <div
           class="close-btn"
-          @click="handleCancleClick(uploadfiles, 'hasUploads')"
+          @click.stop="handleCancleClick(uploadfiles, 'hasUploads')"
+          v-if="!hideUpload"
         >
-          <Icon class="close" custom="iconfont iconform_close" />
+          <Icon type="md-close-circle"  size="16" />
         </div>
       </div>
       <div
         v-for="(uploadfiles) in preUploads"
         :key="uploadfiles.img"
         class="file-item"
+        @click="selectedVideo = uploadfiles.url;show=true"
       >
         <img :src="uploadfiles.img" />
         <div
           class="close-btn"
-          @click="handleCancleClick(uploadfiles, 'preUploads')"
+          @click.stop="handleCancleClick(uploadfiles, 'preUploads')"
+          v-if="!hideUpload"
         >
-          <Icon class="close" custom="iconfont iconform_close" />
+          <Icon type="md-close-circle"  size="16" />
         </div>
     </div>
+    <p class="tips">{{ tips }}</p>
+    <Modal v-model="show" footer-hide>
+      <div>
+        <video width="488" controls="controls" autoplay :src="selectedVideo"></video>
+      </div>
+    </Modal>
   </div>
 </template>
 
@@ -47,16 +58,27 @@
 import { uploadFile } from 'api/upload'
 export default {
   props: {
+    hideUpload: Boolean,
     limit: Number,
     preUploads: Array,
     hasUploads: Array,
     multiple: {
       type: Boolean,
       default: true
+    },
+    tips: {
+      type: String,
+      default: ''
+    },
+    maxSize: {
+      type: Number,
+      default: 10 * 1024
     }
   },
   data () {
     return {
+      show: false,
+      selectedVideo: ''
     }
   },
   computed: {
@@ -66,6 +88,13 @@ export default {
   },
   methods: {
     handleBeforeUpload (file) {
+      const { size } = file
+      if (size > this.maxSize * 1024) {
+        this.$Message.error({
+          content: '上传视频过大'
+        })
+        return
+      }
       if (this.limit && this.uploads.length >= this.limit) {
         this.$Message.error({
           content: '上传数量已超过限制'
@@ -75,8 +104,9 @@ export default {
       const url = URL.createObjectURL(file)
       this.getVideoBase64(url).then(res => {
         file.img = res
+        file.url = url
         this.preUploads.push(file)
-        URL.revokeObjectURL(url)
+        // URL.revokeObjectURL(url)
       })
       return false
     },
@@ -90,17 +120,16 @@ export default {
           video.setAttribute('height', 100);
           video.setAttribute('autoplay', true);
           video.addEventListener('loadeddata', function () {
-              let canvas = document.createElement("canvas"),
-                  width = video.width, //canvas的尺寸和图片一样
-                  height = video.height;
-              canvas.width = width;
-              canvas.height = height;
-              canvas.getContext("2d").drawImage(video, 0, 0, width, height)
-              canvas.getContext("2d").drawImage(video, 0, 0, width, height); //绘制canvas
-              dataURL = canvas.toDataURL('image/png'); //转换为base64
-              resolve(dataURL);
-          });
-        })
+          let canvas = document.createElement("canvas"),
+          width = video.width, //canvas的尺寸和图片一样
+          height = video.height;
+          canvas.width = width;
+          canvas.height = height;
+          canvas.getContext("2d").drawImage(video, 0, 0, width, height)
+          dataURL = canvas.toDataURL('image/png'); //转换为base64
+          resolve(dataURL);
+        });
+      })
     },
     handleCancleClick (uploadfile, type) {
       this[type].splice(this[type].indexOf(uploadfile), 1)
@@ -112,7 +141,6 @@ export default {
     },
     uploadTypeFile (file) {
       return uploadFile(file).then(res => {
-        console.log(res.data, res.data.image)
         file.video = res.data.video
         file.cover_image = res.data.image
         this.hasUploads.push(file)
@@ -120,6 +148,27 @@ export default {
         return res
       })
     }
+  },
+  beforeDestroy () {
+    this.uploads.forEach(item => {
+      URL.revokeObjectURL(item.url)
+    })
   }
 }
 </script>
+
+<style lang="less" scoped>
+.upload {
+  padding: 30px 0 !important;
+}
+.tips {
+  position: absolute;
+  bottom: -8px;
+  font-size: 12px;
+  color:rgba(255,255,255,0.38);
+  line-height: 1;
+}
+.file-item {
+  cursor: pointer;
+}
+</style>

+ 9 - 9
admin/src/config/agency.js

@@ -1,20 +1,20 @@
 export const agency_type = [
   {
-    label: '钻石经纪人',
-    value: '钻石经纪人'
+    label: '钻石讲解员',
+    value: '钻石讲解员'
   },
   {
-    label: '金牌经纪人',
-    value: '金牌经纪人'
+    label: '金牌讲解员',
+    value: '金牌讲解员'
   },
   {
-    label: '资深经纪人',
-    value: '资深经纪人'
+    label: '资深讲解员',
+    value: '资深讲解员'
   }
 ]
 
 export const agency_icon = {
-  '钻石经纪人': 'http://houseoss.4dkankan.com/4dHouse/admin/icon/diamond.svg',
-  '金牌经纪人': 'http://houseoss.4dkankan.com/4dHouse/admin/icon/gold.svg',
-  '资深经纪人': 'http://houseoss.4dkankan.com/4dHouse/admin/icon/senior.svg',
+  '钻石讲解员': 'http://houseoss.4dkankan.com/4dHouse/admin/icon/diamond.svg',
+  '金牌讲解员': 'http://houseoss.4dkankan.com/4dHouse/admin/icon/gold.svg',
+  '资深讲解员': 'http://houseoss.4dkankan.com/4dHouse/admin/icon/senior.svg',
 }

+ 57 - 21
admin/src/layout/index/index.vue

@@ -4,11 +4,10 @@
     <Sider width="310">
       
       <div class="layout-logo">
-        看房4DKanKan-管理后台
+        好玩展-管理后台
       </div>
       <Menu theme="dark" :active-name="$route.name" width="auto" class="layout-menu">
-        <MenuGroup >
-          <template v-for="(item, index) in menuList[0].children">
+        <template v-for="(item, index) in menuList">
             <MenuItem
               :key="item.name"
               :to="item.path"
@@ -22,41 +21,43 @@
             </MenuItem>
             <Submenu :name="index" v-else>
                 <template slot="title">
-                    <Icon class="menu-icon" :custom="`iconfont icon${item.meta.icon}`" />
+                    <div class="menu-item">
+                      <Icon class="menu-icon" :custom="`iconfont icon${item.meta.icon}`" />
                     {{ item.meta.title }}
+                    </div>
                 </template>
-                <MenuItem :name="`${index}-${childIndex}`" :to="`${item.path}/${child.path}`" v-for="(child, childIndex) in item.children" :key="child.path">{{child.meta.title}}</MenuItem>
+                <MenuItem :name="child.name" :to="`${item.path}/${child.path}`" v-for="(child) in item.children" :key="`${item.path}/${child.path}`">{{child.meta.title}}</MenuItem>
             </Submenu>
           </template>
-        </MenuGroup>
       </Menu>
     </Sider>
     <Layout>
       <Header class="layout-header">
+        <template>
+          <div class="layout-navigation">
+          <Breadcrumb separator="/">
+            <BreadcrumbItem class="bread-navigation" v-for="item in breadcrumb" :key="item">{{ item }}</BreadcrumbItem>
+          </Breadcrumb>
+        </div>
         <div class="header-user">
           <span class="user-name">{{ userName }}</span>
             <span class="user-btn" @click="changeEditShow(true)"><Icon custom="iconfont iconnav_password" /><span>修改密码</span></span>
             <span class="user-btn" @click="logoutModal=true"><Icon custom="iconfont iconnav_exit" /><span>退出登录</span></span>
             <i class="iconfont iconarrow_down" />
         </div>
+        </template>
       </Header>
-      <div class="layout-navigation">
-        <Breadcrumb separator=">">
-          <BreadcrumbItem class="bread-navigation" v-for="item in breadcrumb" :key="item">{{ item }}</BreadcrumbItem>
-        </Breadcrumb>
-      </div>
+      
       <Content class="layout-main">
         <!-- <keep-alive>
           <router-view v-if="!$route.meta.noKeepAlive" />
         </keep-alive>
         <router-view v-if="$route.meta.noKeepAlive" /> -->
-        <router-view />
+        <div class="container">
+          <router-view />
+        </div>
       </Content>
     </Layout>
-    <Modal v-model="show" class="edit-modal" width="420" footer-hide>
-      <div class="modal-header" slot="header">修改密码</div>
-      <editPassword v-if="show" @change="changeEditShow" />
-    </Modal>
     <CModal :show="logoutModal" :width="420" title="提示" @close="logoutModal=false" @submit="handleLogout" submitText="确定">
       <div style="height:60px">确定退出登录吗?</div>
     </CModal>
@@ -67,6 +68,9 @@
 import { mapActions } from 'vuex'
 import editPassword from 'components/editPassword'
 import CModal from 'components/Modal'
+import { authRoutes } from '@/router/routes'
+import { getAdmin } from '@/libs/token'
+
 export default {
   name: 'Index',
   data() {
@@ -77,7 +81,8 @@ export default {
   },
   computed: {
     menuList() {
-      return this.$store.getters.menuList
+      const menuList = getAdmin().menuList ? getAdmin().menuList.map(item => item.name) : []
+      return this.$store.getters.menuList[0].children.filter(item => menuList.indexOf(item.meta.title) > -1 )
     },
     userName() {
       return this.$store.getters.userName
@@ -90,6 +95,9 @@ export default {
     editPassword,
     CModal
   },
+  mounted () {
+    
+  },
   methods: {
     ...mapActions([
       'logout'
@@ -102,7 +110,7 @@ export default {
       })
     },
     changeEditShow (show) {
-      this.show = show
+      window.open('https://4dkankan.com')
     }
   }
 }
@@ -121,11 +129,16 @@ export default {
   }
 
   &-menu {
+    padding-top: 30px;
     .menu-item {
       height: 28px;
       line-height: 28px;
+      font-size: 16px;
+      display: flex;
+      align-items: center;
       .menu-icon {
-        margin-right: 10px;
+        margin-right: 15px;
+        color: #17D2D2;
       }
     }
   }
@@ -133,6 +146,9 @@ export default {
   &-header {
     border-bottom: 1px solid #555a5a;
     height: 64px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
     .header-user {
       float: right;
       // cursor: pointer;
@@ -150,7 +166,13 @@ export default {
       }
     }
   }
-
+  .layout-main {
+    padding: 30px;
+    .container {
+      // min-height: 100%;
+      background: #252828;
+    }
+  }
   &-navigation {
     height: 48px;
     padding: 12px 29px;
@@ -164,7 +186,21 @@ export default {
 
   .ivu-menu-dark.ivu-menu-vertical
     .ivu-menu-item-active:not(.ivu-menu-submenu) {
-    color: #fff;
+  }
+  .ivu-menu-vertical .ivu-menu-submenu-title {
+    font-size: 16px;
+  }
+  .ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu) {
+    background: transparent;
+  }
+  .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu .ivu-menu-item-active {
+    background: transparent !important;
+    color: #1FE4DC;
+  }
+  
+  .layout-navigation {
+    border-left: none;
+    padding: 0;
   }
 }
 .user-btn {

+ 3 - 3
admin/src/layout/login/login.vue

@@ -8,11 +8,11 @@
         <div class="login-banner">
           <div class="login-container-text">
             <div class="login-con-header">
-              <span>在线语音带看  足不出户看实况</span>
+              <span>三维数字化技术助力内循环</span>
             </div>
-            <div class="login-con-desc">
+            <!-- <div class="login-con-desc">
               <span>让你的房产交易更加便捷</span>
-            </div>
+            </div> -->
           </div>
         </div>
         <login-form />

+ 1 - 1
admin/src/libs/request.js

@@ -45,7 +45,7 @@ service.interceptors.response.use(
     // 处理后端响应数据状态码不在预设值得情况下,处理异常,这里预设值为2000
     if (data.code && data.code != 0) {
       // 再进一步判断
-      if (data.code == 3004 || data.code == 3005) {
+      if (data.code == 3111 || data.code == 3005 || data.code == 3004) {
         data.code == 3005 && Message.error({ content: 'token过期,请重新登录' })
         app.$router.push('/login')
         setToken('')

+ 49 - 48
admin/src/router/index.js

@@ -1,9 +1,9 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-// import ViewUI from 'view-design'
-// import store from 'store'
+import ViewUI from 'view-design'
+import store from 'store'
 
-// import { getToken, setToken } from 'libs/token'
+import { getToken, setToken } from 'libs/token'
 // import { turnTo } from 'libs/tools'
 
 import routes from './routes'
@@ -16,58 +16,59 @@ const router = new Router({
 })
 
 // 定义登录页面路由name
-// const LOGIN_PAGE_NAME = 'login'
+const LOGIN_PAGE_NAME = 'login'
 // // 定义首页页面路由name
 // const GUIDE_PAGE_NAME = 'guide'
 
-// const needVerify = true
+const needVerify = true
 
 // 添加路由钩子
-// router.beforeEach((to, form, next) => {
-//   ViewUI.LoadingBar.start()
+router.beforeEach((to, form, next) => {
+  ViewUI.LoadingBar.start()
 
-//   const token = getToken()
-//   next()
-//   if (!needVerify || to.name === 'test') {
-//     next()
-//   } else if (!token && to.name !== LOGIN_PAGE_NAME) {
-//     // 未登录且要跳转的页面不是登录页
-//     next({
-//       name: LOGIN_PAGE_NAME // 跳转到登录页
-//     })
-//   } else if (!token && to.name === LOGIN_PAGE_NAME) {
-//     // 未登录且要跳转登录页,直接跳转
-//     next()
-//   } else if (token && to.name === LOGIN_PAGE_NAME) {
-//     // 已登录且要跳转登录页,此时需要重定向到首页
-//     next({
-//       name: GUIDE_PAGE_NAME
-//     })
-//   } else {
-//     // 这里做鉴权处理
-//     // 从状态管理仓库获取登录用户信息,access必须是一个数组,如:['super_admin'] ['super_admin', 'admin']
-//     if (store.state.user.hasAccess) {
-//       turnTo(to, store.state.user.access, next)
-//     } else {
-//       // 拉取用户信息,通过用户权限和跳转的页面的name来判断是否有权限访问;
-//       store.dispatch('checkRole').then(user => {
-//         turnTo(to, user.access, next)
-//       }).catch(() => {
-//         setToken('')
-//         next({
-//           name: 'login'
-//         })
-//       })
+  const token = getToken()
+  next()
+  if (!needVerify || to.name === 'test') {
+    next()
+  } else if (!token && to.name !== LOGIN_PAGE_NAME) {
+    // 未登录且要跳转的页面不是登录页
+    next({
+      name: LOGIN_PAGE_NAME // 跳转到登录页
+    })
+  } else if (!token && to.name === LOGIN_PAGE_NAME) {
+    // 未登录且要跳转登录页,直接跳转
+    next()
+  } else if (token && to.name === LOGIN_PAGE_NAME) {
+    // 已登录且要跳转登录页,此时需要重定向到首页
+    next({
+      name: GUIDE_PAGE_NAME
+    })
+  } else {
+    next()
+    // 这里做鉴权处理
+    // 从状态管理仓库获取登录用户信息,access必须是一个数组,如:['super_admin'] ['super_admin', 'admin']
+    // if (store.state.user.hasAccess) {
+    //   turnTo(to, store.state.user.access, next)
+    // } else {
+    //   // 拉取用户信息,通过用户权限和跳转的页面的name来判断是否有权限访问;
+    //   store.dispatch('checkRole').then(user => {
+    //     turnTo(to, user.access, next)
+    //   }).catch(() => {
+    //     setToken('')
+    //     next({
+    //       name: 'login'
+    //     })
+    //   })
 
-//       store.dispatch('userGetRole')
-//     }
-//   }
-// })
+    //   store.dispatch('userGetRole')
+    // }
+  }
+})
 
-// router.afterEach(
-//   to => {
-//     ViewUI.LoadingBar.finish()
-//   }
-// )
+router.afterEach(
+  to => {
+    ViewUI.LoadingBar.finish()
+  }
+)
 
 export default router

+ 58 - 23
admin/src/router/routes.js

@@ -30,13 +30,58 @@ export default [
       },
       component: resolve => require(['views/enterprise'], resolve) 
     }, 
-    
+    {
+      path: '/activity',
+      name: 'activity',
+      meta: {
+        title: '展会管理',
+        icon: 'nav_system'
+      },
+      component: resolve => require(['views/industry'], resolve),
+      children: [
+        {
+          path: 'home',
+          name: 'home',
+          meta: {
+            title: '首页管理',
+            noKeepAlive: true
+          },
+          component: resolve => require(['views/activity/homeAdmin'], resolve),
+        },
+        {
+          path: 'edit',
+          name: 'actEdit',
+          meta: {
+            title: '展会概况'
+          },
+          component: resolve => require(['views/activity/activityEdit'], resolve),
+        },
+        {
+          path: 'enterpriseList',
+          name: 'enterpriseList',
+          meta: {
+            title: '展商名录',
+            noKeepAlive: true
+          },
+          component: resolve => require(['views/activity/enterpriseList'], resolve),
+        },
+        {
+          path: 'industry',
+          name: 'industry',
+          meta: {
+            title: '企业行业',
+            noKeepAlive: true
+          },
+          component: resolve => require(['views/industry/list'], resolve),
+        },
+      ]
+    },
     {
       path: '/system',
       name: 'system',
       meta: {
-        title: '系统管理',
-        icon: 'iconnav_sys',
+        title: '用户信息',
+        icon: 'nav_user',
         // 不需要缓存路由组件
         noKeepAlive: true
         // access: ['admin']
@@ -48,39 +93,29 @@ export default [
           path: 'user',
           name: 'system',
           meta: {
-            title: '用户管理',
+            title: '管理员信息',
             noKeepAlive: true
           },
           component: resolve => require(['views/system/user/list'], resolve),
         },
         {
-          path: 'user/create',
-          name: 'system',
-          meta: {
-            title: '添加用户',
-            hideInMenu: true
-          },
-          component: resolve => require(['views/system/user/list'], resolve),
-        },
-        {
-          path: 'address',
-          name: 'system',
+          path: 'commentator',
+          name: 'commentator',
           meta: {
-            title: '地址管理',
+            title: '讲解员信息',
             noKeepAlive: true
           },
-          component: resolve => require(['views/system/address/list'], resolve),
+          component: resolve => require(['views/system/commentator/list'], resolve),
         },
         {
-          path: 'store',
+          path: 'user/create',
           name: 'system',
           meta: {
-            title: '门店管理',
-            noKeepAlive: true
+            title: '添加用户',
+            hideInMenu: true
           },
-          component: resolve => require(['views/system/store/list'], resolve),
-        },
-        
+          component: resolve => require(['views/system/user/list'], resolve),
+        }
       ]
     }
   ]

+ 1 - 1
admin/src/store/user.js

@@ -50,7 +50,7 @@ export default {
           res => {
             const { data } = res
             setToken(data.token)
-            setAdmin(data.admin)
+            setAdmin(data)
             commit('setName', data.admin.name || data.user.userName)
             resolve(res)
           }

+ 90 - 0
admin/src/views/activity/activityEdit.vue

@@ -0,0 +1,90 @@
+<template>
+  <!-- Two-way Data-Binding -->
+  <div class="act-edit">
+    <div class="min-container">
+      <div style="min-height: 460px">
+        <Form :label-width="86">
+          <FormItem label="展会名称">
+            <Input size="large" v-model="form.name" />
+          </FormItem>
+          <FormItem label="展会概况">
+            <quill-editor
+              v-model="form.detailContent"
+            />
+          </FormItem>
+          <FormItem label="联系我们">
+            <quill-editor
+              v-model="form.contactUs"
+            />
+          </FormItem>
+          <FormItem>
+            <Button type="primary" size="large" @click="upadteActivity">提交</Button>
+          </FormItem>
+        </Form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import quillEditor from "@/components/quillEditor";
+import { getActivityDetail, upadteActivity } from '@/api'
+export default {
+  data() {
+    return {
+      form: {
+        contactUs: '',
+        detailContent: ''
+      }
+    };
+  },
+  components: {
+    quillEditor
+  },
+  
+  computed: {
+  },
+  mounted() {
+    console.log("this is current quill instance object", this.editor);
+    this.getActivityDetail()
+  },
+  methods: {
+    upadteActivity () {
+      upadteActivity(this.form).then(() => {
+        this.$Message.success('更新成功')
+      })
+    },
+    getActivityDetail () {
+      getActivityDetail().then(res => {
+        this.form = res.data
+      })
+    }
+  },
+};
+</script>
+
+<style lang="less">
+.act-edit {
+  padding: 30px;
+  .ql-snow .ql-picker {
+    color: #fff;
+  }
+  .ql-snow .ql-stroke {
+    stroke: #fff;
+  }
+  .ql-snow .ql-fill,
+  .ql-snow .ql-stroke.ql-fill {
+    fill: #fff;
+  }
+  .ql-editor {
+    background: #161a1a;
+    min-height: 460px;
+  }
+  .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {
+    color: #000;
+  }
+  .ql-snow .ql-icon-picker .ql-picker-item svg line {
+    stroke: #444;
+  }
+}
+</style>

+ 95 - 0
admin/src/views/activity/enterpriseList.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="enterprise-list">
+    <tables
+      :data-api="getCompanyList"
+      :delete-api="deleteCompany"
+      :columns="columns"
+      @toCheck="check"
+      deleteIdKey="agency_user_id"
+      placeholder="输入公司名称"
+      ref="table"
+    />
+  </div>
+</template>
+
+<script>
+import tables from 'components/tables'
+import { getCompanyList, updateCompany } from '@/api/company'
+export default {
+  data () {
+    return {
+      getCompanyList,
+      columns: [
+        {
+          type: 'index',
+          title: '序号',
+          align: 'center',
+          width: 80
+        },
+        {
+          title: '公司名称',
+          key: 'companyName',
+          align: 'center'
+        },
+        {
+          title: '所属行业',
+          key: 'companyType',
+          align: 'center'
+        },
+        {
+          title: '公司地址',
+          key: 'companyAddress',
+          align: 'center'
+        },
+        {
+          title: '成立时间',
+          key: 'registerDate',
+          align: 'center'
+        },
+        {
+          title: '讲解人员',
+          key: 'name',
+          align: 'center'
+        },
+        {
+          title: '手机号码',
+          key: 'name',
+          align: 'center'
+        },
+        {
+          title: '操作',
+          slot: 'action',
+          tools: ['check', 'del' ],
+          align: 'center'
+        }
+      ],
+    }
+  },
+  components: {
+    tables
+  },
+  methods: {
+    check (item) {
+      this.$router.push({
+        path: '/enterprise',
+        query: {
+          companyId: item.companyId
+        }
+      })
+    },
+    async deleteCompany(row) {
+      row[0].enable = 0
+      await updateCompany(row[0])
+      this.$Message.success({
+        content: '删除成功'
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.enterprise-list {
+  padding: 30px;
+}
+</style>

+ 183 - 0
admin/src/views/activity/homeAdmin.vue

@@ -0,0 +1,183 @@
+<template>
+  <div class="home-admin">
+    <div class="min-container">
+      <div class="header-title">顶部海报</div>
+      <Form :label-width="86" class="form">
+        <FormItem label="上传海报">
+          <picUpload tips="只能上传jpg/png文件,且不超过500kb" ref="post-upload" :limit="1" :multiple="false" :preUploads="postPreUploads" :hasUploads="postHasUploads" />
+        </FormItem>
+      </Form>
+      <div class="header-title">明星企业</div>
+      <Form :label-width="86" class="form">
+        <Row>
+          <i-col :span="12">
+            <FormItem label="上传海报">
+            <picUpload tips="只能上传jpg/png文件,且不超过500kb"  ref="banner1-upload" :limit="1" :multiple="false" :preUploads="banner1PreUploads" :hasUploads="banner1HasUploads" />
+          </FormItem>
+          </i-col>
+          <i-col :span="12">
+            <FormItem label="选择企业">
+              <Select v-model="banner1" filterable size="large" @on-change="changeBanner(1)">
+                <Option v-for="item in companyList" :value="item.vrLink" :key="item.companyId">{{ item.companyName }}</Option>
+              </Select>
+          </FormItem>
+          </i-col>
+        </Row>
+        <Row>
+          <i-col :span="12">
+            <FormItem label="上传海报">
+            <picUpload tips="只能上传jpg/png文件,且不超过500kb"  ref="banner2-upload" :limit="1" :multiple="false" :preUploads="banner2PreUploads" :hasUploads="banner2HasUploads" />
+          </FormItem>
+          </i-col>
+          <i-col :span="12">
+            <FormItem label="选择企业">
+              <Select v-model="banner2" filterable size="large" @on-change="changeBanner(2)">
+                <Option v-for="item in companyList" :value="item.vrLink" :key="item.companyId">{{ item.companyName }}</Option>
+              </Select>
+          </FormItem>
+          </i-col>
+        </Row>
+        <Row>
+          <i-col :span="12">
+            <FormItem label="上传海报">
+            <picUpload tips="只能上传jpg/png文件,且不超过500kb"  ref="banner3-upload" :limit="1" :multiple="false" :preUploads="banner3PreUploads" :hasUploads="banner3HasUploads" />
+          </FormItem>
+          </i-col>
+          <i-col :span="12">
+            <FormItem label="选择企业">
+              <Select v-model="banner3" filterable size="large" @on-change="changeBanner(3)">
+                <Option v-for="item in companyList" :value="item.vrLink" :key="item.companyId">{{ item.companyName }}</Option>
+              </Select>
+            </FormItem>
+          </i-col>
+        </Row>
+      </Form>
+      <div class="actions-w">
+        <Button size="large" type="primary" class="submit-btn" @click="submit">提交</Button>
+        <!-- <Button size="large"  class="cancle-btn">取消</Button> -->
+      </div>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+import picUpload from '@/components/upload'
+import { upadteActivity, getActivityDetail } from '@/api'
+import { getCompanyList } from '@/api/company'
+export default {
+  data () {
+    return {
+      postPreUploads: [],
+      postHasUploads: [],
+      form: {
+        firstPageContent: [{},{},{}]
+      },
+      companyList: [],
+      banner1: '',
+      banner2: '',
+      banner3: '',
+      banner1PreUploads: [],
+      banner1HasUploads: [],
+      banner2PreUploads: [],
+      banner2HasUploads: [],
+      banner3PreUploads: [],
+      banner3HasUploads: [],
+    }
+  },
+  components: {
+    picUpload
+  },
+  watch: {
+    banner1HasUploads (val) {
+      if (!val[0]) {
+        this.form.firstPageContent[0] = {}
+      }
+    },
+    banner2HasUploads (val) {
+      if (!val[0]) {
+        this.form.firstPageContent[1] = {}
+      }
+    },
+    banner3HasUploads (val) {
+      if (!val[0]) {
+        this.form.firstPageContent[2] = {}
+      }
+    },
+  },
+  async mounted () {
+    await this.getCompanyList()
+    this.getActivityDetail()
+  },
+  methods: {
+    upadteActivity () {
+      let form = Object.assign({}, this.form)
+      form.firstPageContent = form.firstPageContent.filter(item => item.img)
+      form.firstPageContent = JSON.stringify(form.firstPageContent)
+      upadteActivity(form).then(() => {
+        this.$Message.success('更新成功')
+      })
+    },
+    getCompanyList () {
+      getCompanyList({pageSize: 9999}).then(res => {
+        this.companyList = res.data.list
+        
+      })
+    },
+    submit () {
+      return Promise.all([this.$refs['post-upload'].uploadfiles(), this.$refs['banner1-upload'].uploadfiles(), this.$refs['banner2-upload'].uploadfiles(), this.$refs['banner3-upload'].uploadfiles()]).then(res => {
+        if (res[0][0]) {
+          this.form.logoUrl = res[0][0]
+        }
+        for (let i = 1; i<res.length; i++) {
+          if (res[i][0]) {
+            if (!this.form.firstPageContent[i-1]) {
+              this.form.firstPageContent[i-1] = {}
+            } 
+            this.form.firstPageContent[i-1].img = res[i][0]
+          }
+        }
+        this.upadteActivity()
+      })
+    },
+    changeBanner (index) {
+      const value = this[`banner${index}`]
+      if (!this.form.firstPageContent[index-1]) {
+              this.form.firstPageContent[index-1] = {}
+            }
+      this.form.firstPageContent[index-1].link = value
+    },
+    getActivityDetail () {
+      getActivityDetail().then(res => {
+        this.form = res.data
+        this.form.firstPageContent = JSON.parse(this.form.firstPageContent)
+        this.postHasUploads = [{img: res.data.logoUrl}]
+        this.form.firstPageContent.forEach((item, index) => {
+          this[`banner${index+1}HasUploads`] = [{ img: item.img }]
+          this[`banner${index+1}`] = item.link
+          console.log(item.link)
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.home-admin {
+  padding: 0 30px 30px;
+}
+.form {
+  padding-top: 30px;
+}
+.actions-w {
+  padding-left: 86px;
+  .submit-btn {
+    width: 116px;
+  }
+  .cancle-btn {
+    width: 88px;
+    margin-left: 15px;
+  }
+}
+</style>

+ 0 - 0
admin/src/views/activity/index.vue


+ 394 - 0
admin/src/views/enterprise/components/baseForm.vue

@@ -0,0 +1,394 @@
+<template>
+  <div class="base-form">
+    <div class="form">
+      <Form :label-width="86" :rules="rules" :model="form" ref="form">
+        <Row :gutter="90">
+          <i-col :span="12" class="">
+            <FormItem label="公司名称" prop="companyName">
+              <Input type="text" size="large" v-model="form.companyName" :disabled="isDetail" />
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="所属行业" prop="tradeName">
+              <i-select size="large" v-model="form.tradeName" @on-change="changeCompanyType" :disabled="isDetail">
+                <i-option v-for="item in industryList" :key="item.id" :value="item.name">{{ item.name }}</i-option>
+              </i-select>
+              <!-- <Input type="text" size="large" v-model="form.companyType" :disabled="isDetail" /> -->
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="企业类型">
+              <Input type="text" size="large" v-model="form.companyType" :disabled="isDetail" />
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="成立时间" prop="registerDate1">
+              <Date-picker v-model="form.registerDate1" type="year" size="large" placeholder=""  :disabled="isDetail" @on-change="changeDate"></Date-picker>
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="员工人数" prop="staffNum">
+              <Input type="text" size="large" v-model="form.staffNum" :disabled="isDetail" />
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="注册资金" prop="registerFund">
+              <Input type="text" size="large" v-model="form.registerFund"  :disabled="isDetail"/>
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="主要产品" prop="mainProduct">
+              <Input type="text" size="large" v-model="form.mainProduct" :disabled="isDetail" />
+            </FormItem>
+          </i-col>
+          <i-col :span="12" class="">
+            <FormItem label="公司网址">
+              <Input type="text" size="large" v-model="form.companyWebsite" :disabled="isDetail" />
+            </FormItem>
+          </i-col>
+          <i-col :span="24" class="">
+            <FormItem label="公司地址">
+              <template>
+                <Input size="large" v-model="form.companyAddress" :disabled="isDetail" />
+                <Button size="large" type="primary" style="margin-left:15px" @click="searchAddress" v-if="!isDetail">查找</Button>
+                <qqMap ref="map" city="珠海" :latitude="form.latitude" :longitude="form.longitude" @clickMap="clickMap" v-if="!isDetail" />
+              </template>
+            </FormItem>
+          </i-col>
+          <i-col :span="24" class="">
+            <FormItem label="公司简介" class="textarea-w">
+              <Input type="textarea" size="large" v-model="form.companyDesc" :disabled="isDetail" maxlength="200" :show-word-limit="!isDetail" />
+            </FormItem>
+          </i-col>
+          <i-col :span="24" class="">
+            <FormItem label="公司logo">
+              <picUpload  ref="logoUpload" tips="只能上传jpg/png文件,且不超过500kb" :multiple="false" :limit="1" :preUploads="preLogoUploads" :hasUploads="hasLogoUploads" :hideUpload="isDetail" />
+              <!-- <img style="width: 100px;height:100px;" :src="form.companyLogo" v-else> -->
+            </FormItem>
+          </i-col>
+          <!-- <i-col :span="12" class="">
+            <FormItem label="资质认证">
+              <picUpload tips="只能上传jpg/png文件,且不超过500kb" :multiple="false" :limit="1" />
+            </FormItem>
+          </i-col> -->
+          <i-col :span="24" class="">
+            <FormItem label="场景地址">
+              <template>
+                <Input type="text" size="large" v-model="vrLink" :disabled="isDetail" />
+                <Button type="primary" size="large" class="input-btn" @click="modalShow=true" v-if="!isDetail">选择场景</Button>
+                <Button type="primary" size="large" :class="`input-btn ${form.sceneNum ? '' : 'not-allow'}`" @click="toEditScene">编辑场景</Button>
+              </template>
+            </FormItem>
+          </i-col>
+          <i-col :span="24" class="">
+            <FormItem label="讲解人员">
+              <template>
+                <div class="guide-info">
+                  <p class="guide-name">{{select_guide.name}}</p>
+                  <p class="guide-id">{{select_guide.viewerId}}</p>
+                  <p class="guide-phone">{{select_guide.phoneNum}}</p>
+                  <img v-if="select_guide.avatar" :src="select_guide.avatar" alt="" class="guide-avatar">
+                </div>
+                <Button type="primary" size="large" @click="guideModalShow=true" v-if="!isDetail">选择/更换</Button>
+              </template>
+            </FormItem>
+          </i-col>
+        </Row>
+      </Form>
+    </div>
+    <cModal :show="modalShow"  class="scene-modal" :width="960" title="添加/选择场景" @close="modalShow=false" @submit="changeScene">
+      <template>
+        <tables 
+          :data-api="fetchAllScene"
+          :columns="tableColumns"
+          placeholder="场景名称"
+        />
+        <div style="height:20px"></div>
+      </template>
+    </cModal>
+    <cModal :show.sync="guideModalShow"  class="scene-modal" :width="960" title="选择讲解员" @hide="guideModalShow=false" @close="guideModalShow=false" @submit="changeGuide">
+      <template>
+        <tables 
+          :data-api="getGuideList"
+          :columns="guideTableColumns"
+          placeholder="讲解员"
+          ref="guideTable"
+        />
+        <div style="height:20px"></div>
+      </template>
+    </cModal>
+  </div>
+</template>
+
+<script>
+import picUpload from '@/components/upload'
+import cModal from '@/components/Modal'
+import tables from 'components/tables'
+import * as CompanyApi from '@/api/company'
+import { getGuideList, getGuideById } from '@/api/guide'
+import { searchPlaceByKeyword } from '@/api/qqmap'
+import qqMap from '@/components/map'
+import { getToken } from '@/libs/token'
+
+export default {
+  props: {
+    form: Object,
+    isDetail: Boolean
+  },
+  data () {
+    return {
+      preLogoUploads: [],
+      hasLogoUploads: [],
+      select_scene_num: '',
+      select_guide_id: '',
+      select_guide: {},
+      rules: {
+        companyName: [{ required: true, message: '请填写公司名', trigger: 'blur' }],
+        tradeName: [{ required: true, message: '请选择所属行业', trigger: 'change'}],
+        registerDate1: [{ required: true, message: '请填写成立时间', trigger: 'blur', type: 'date'}],
+        staffNum: [{ required: true, message: '请填写员工人数', trigger: 'blur' }],
+        registerFund: [{ required: true, message: '请填写注册资金', trigger: 'blur' }],
+        mainProduct: [{ required: true, message: '请填写主要产品描述', trigger: 'blur' }],
+      },
+      tableColumns: [
+        {
+          align: 'center',
+          width: 80,
+          render: (h, params ) => h('Checkbox', {
+            props: {
+              trueValue: params.row.num,
+              falseValue: false,
+              value: params.row.num === this.select_scene_num ? params.row.num : false
+            },
+            on: {
+              'on-change': (val) => {
+                this.select_scene_num = val
+              }
+            }
+          })
+        },
+        {
+          type: 'index',
+          title: '序号',
+          align: 'center',
+          width: 80
+        },
+        {
+          title: '场景名称',
+          key: 'sceneName',
+          align: 'center'
+        },
+        {
+          title: '分类',
+          key: 'title',
+          align: 'center',
+          render: h => h('div', '其它')
+        },
+        {
+          title: '拍摄时间',
+          key: 'createTime',
+          align: 'center'
+        }
+      ],
+      guideTableColumns: [
+        {
+          align: 'center',
+          width: 80,
+          render: (h, params ) => h('Checkbox', {
+            props: {
+              trueValue: params.row.viewerId,
+              falseValue: false,
+              value: params.row.viewerId === this.select_guide_id ? params.row.viewerId : false
+            },
+            on: {
+              'on-change': (val) => {
+                this.select_guide_id = val
+              }
+            }
+          })
+        },
+        {
+          type: 'index',
+          title: '序号',
+          align: 'center',
+          width: 80
+        },
+        {
+          title: '头像',
+          key: 'avatar',
+          align: 'center',
+          render: (h, params) => h('img', {
+            attrs: {
+              style: "width: 40px;height:40px;border-radius: 50%;",
+              src: params.row.avatar
+            }
+          })
+        },
+        {
+          title: '名称',
+          key: 'name',
+          align: 'center'
+        },
+        {
+          title: '联系方式',
+          key: 'phoneNum',
+          align: 'center'
+        }
+      ],
+      industryList: [],
+      getGuideList,
+      modalShow: false,
+      guideModalShow: false,
+      addressList: []
+    }
+  },
+  components: {
+    picUpload,
+    cModal,
+    tables,
+    qqMap
+  },
+  computed: {
+    vrLink: {
+      set (val) {
+        this.form.vrLink = encodeURIComponent(val)
+      },
+      get () {
+        return decodeURIComponent(this.form.vrLink)
+      }
+    }
+  },
+  watch: {
+    guideModalShow (val) {
+      if (val) {
+        this.$refs['guideTable'].handleTableData()
+      }
+    }
+  },
+  async mounted () {
+    await this.getIndustryList()
+    this.$watch('form.companyLogo', function (newVal) {
+      if (this.isDetail && newVal) {
+        this.hasLogoUploads = [{img: newVal}]
+      }
+    }, {
+      immediate: true
+    })
+    this.$watch('form.guideId', async (newVal) => {
+      if (this.isDetail) {
+        let res = await getGuideById(this.form.guideId)
+        this.select_guide = res.data || {}
+      }
+    })
+  },
+  methods: {
+    async validate () {
+      const valid = await this.$refs['form'].validate()
+      if (!valid) {
+        this.$Message.error('请完善表单')
+      }
+      return valid
+    },
+    async submit () {
+      let res = await this.$refs['logoUpload'].uploadfiles()
+      this.form.companyLogo = res[0]
+      this.form.registerDate = new Date(this.form.registerDate).getFullYear()
+    },
+    changeScene () {
+      this.vrLink = this.select_scene_num ? `${process.env.VUE_APP_4DKANKAN_URL}/kanzhan.html?m=${this.select_scene_num}` : ''
+      this.form.vrLink = this.select_scene_num ? encodeURIComponent(`${process.env.VUE_APP_4DKANKAN_URL}/kanzhan.html?m=${this.select_scene_num}`) : ''
+      this.form.sceneNum = this.select_scene_num || ''
+      this.modalShow = false
+    },
+    changeGuide () {
+      this.select_guide = this.$refs['guideTable'].tableData.find(item => item.viewerId === this.select_guide_id) || {}
+      this.form.guideId = this.select_guide.viewerId
+      this.guideModalShow = false
+    },
+    getIndustryList () {
+      CompanyApi.getIndustry({pageSize: 9999}).then(res => {
+        this.industryList = res.data.list
+      })
+    },
+    changeCompanyType (value) {
+      this.form.tradeName = value
+    },
+    searchAddress () {
+      searchPlaceByKeyword({keyword: this.form.companyAddress}).then(res => {
+        this.addressList = res.data
+        if (res.data[0]) {
+          this.$refs['map'].search(res.data[0].location)
+        }
+    
+      })
+    },
+    clickMap (value) {
+      this.form.companyAddress = value.address
+      this.form.latitude = value.location.lat
+      this.form.longitude = value.location.lng
+    },
+    changeDate (date) {
+      this.form.registerDate = date
+    },
+    fetchAllScene (data) {
+      return CompanyApi.fetchAllScene(data).then(res => {
+        return {
+          data: {
+            list: [...res.data.myScene, ...res.data.cooperationScene]
+          }
+        }
+      })
+    },
+    toEditScene () {
+      if (this.form.sceneNum) {
+        let kankan = process.env.ENV === 'production' ? `https://4dkankan.com/epc.html?m=${this.form.sceneNum}` : `https://test.4dkankan.com/epc.html?m=${this.form.sceneNum}`
+        kankan = `${kankan}&token=${getToken()}`
+        window.open(kankan)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.base-form {
+
+  .address-detail {
+    font-size: 12px;
+    color: #909090;
+  }
+  .ivu-select .ivu-select-dropdown {
+    width: 337px;
+    overflow: auto;
+    overflow-x: hidden;
+  }
+}
+.guide-info {
+  width: 380px;
+  padding: 12px 15px 16px;
+  font-size: 14px;
+  background: #161A1A;
+  border:1px solid rgba(255,255,255,0.4);
+  position: relative;
+  line-height: 19px;
+  display: inline-block;
+  margin-right: 15px;
+  min-height: 104px;
+  vertical-align: top;
+  p {
+    margin-bottom: 10px;
+  }
+  .guide-phone {
+    margin-bottom: 0;
+  }
+  .guide-avatar {
+    position: absolute;
+    right: 15px;
+    top: 15px;
+    width: 60px;
+    height: 60px;
+    border-radius: 50%;
+  }
+  
+}
+</style>

+ 53 - 0
admin/src/views/enterprise/components/introPicForm.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="intro-pic-form">
+    <div class="form">
+      <Form :label-width="86">
+        <FormItem label="图片上传" :limit="20">
+          <picUpload :hideUpload="isDetail" ref="info-upload" tips="只能上传jpg/png文件,建议尺寸为960*600,且单张不超过500kb,最多20张" :limit="20" :preUploads="preUploads" :hasUploads="hasUploads" />
+        </FormItem>
+      </Form>
+    </div>
+  </div>
+</template>
+
+<script>
+import picUpload from '@/components/upload'
+export default {
+  props: {
+    isDetail: Boolean,
+    form: Object
+  },
+  data () {
+    return {
+      preUploads: [],
+      hasUploads: []
+    }
+  },
+  components: {
+    picUpload
+  },
+  mounted () {
+    this.$watch('form.introduceImage', function (newVal) {
+      if (this.isDetail) {
+        this.hasUploads = JSON.parse(newVal)
+      }
+    }, {
+      immediate: true
+    })
+  },
+  methods: {
+    async validate () {
+      if (this.hasUploads.length > 0 || this.preUploads.length > 0) {
+        return true
+      }
+      this.$Message.error('请上传介绍图片')
+      return false
+    },
+    async submit () {
+      let res = await this.$refs['info-upload'].uploadfiles()
+
+      this.form.introduceImage = JSON.stringify(this.hasUploads)
+    },
+  }
+}
+</script>

+ 56 - 0
admin/src/views/enterprise/components/videoForm.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="video-form">
+    <div class="form" ref="form">
+      <Form :label-width="86">
+        <FormItem label="视频简介">
+          <Input type="text" size="large" v-model="form.introduceVideoDesc" :disabled="isDetail" />
+        </FormItem>
+        <FormItem label="上传视频">
+          <videoUpload :hideUpload="isDetail" tips="只能上传mp4/mov文件,且不超过10mb" ref="videoUpload" :hasUploads="hasUploads" :preUploads="preUploads" :limit="1" />
+        </FormItem>
+      </Form>
+    </div>
+  </div>
+</template>
+
+<script>
+import videoUpload from '@/components/upload/video'
+
+export default {
+  props: {
+    form: Object,
+    isDetail: Boolean
+  },
+  data () {
+    return {
+      hasUploads: [],
+      preUploads: []
+    }
+  },
+  components: {
+    videoUpload
+  },
+  mounted () {
+    this.$watch('form.introduceVideo', function (newVal) {
+      if (this.isDetail && newVal) {
+        this.hasUploads = [{img: `${newVal}?x-oss-process=video/snapshot,t_7000,f_jpg,w_800,h_600,m_fast`, url: newVal}]
+      }
+    }, {
+      immediate: true
+    })
+  },
+  methods: {
+    async validate () {
+      // const valid = await this.$refs['form'].validate()
+      return true
+    },
+    async submit () {
+      let res = await this.$refs['videoUpload'].uploadfiles()
+      if (res[0]) {
+        this.form.introduceVideo = res[0].data.url
+      }
+      
+    },
+  }
+}
+</script>

+ 196 - 0
admin/src/views/enterprise/index.vue

@@ -0,0 +1,196 @@
+<template>
+  <div class="enterprise min-container">
+    <div class="header-title">公司概况
+      <Button type="primary" size="large" class="fr" @click="isDetail=false" v-if="companyId">修改信息</Button>
+    </div>
+    <baseForm key="base" :form="form" ref="base-form" :isDetail="isDetail" />
+    <div class="header-title">视频介绍</div>
+    <videoForm :form="form" ref="video-form" :isDetail="isDetail" />
+    <div class="header-title">图片介绍</div>
+    <introPicForm :form="form" ref="intro-form" :isDetail="isDetail" />
+    <div class="actions-w">
+      <Button type="primary" size="large" class="submit-btn" @click="handleSubmitClick" v-if="!isDetail">提交</Button>
+      <Button  size="large" @click="cancle" v-if="companyId && !isDetail">取消</Button>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+import * as CompanyApi from '@/api/company'
+import baseForm from './components/baseForm'
+import videoForm from './components/videoForm'
+import introPicForm from './components/introPicForm'
+import { getAdmin, setAdmin } from '@/libs/token'
+import { refreshAdminerInfo } from '@/api/index'
+import { remove } from 'js-cookie'
+
+const cacheKey = 'cacheForm'
+function saveForm (form) {
+  localStorage.setItem(cacheKey, JSON.stringify(form))
+}
+
+function removeForm () {
+  localStorage.removeItem(cacheKey)
+}
+
+function loadForm () {
+  return localStorage.getItem(cacheKey)
+}
+
+export default {
+  data () {
+    return {
+      isDetail: false,
+      form: {
+        companyName: '',
+        companyType: '',
+        sceneNum: '',
+        vrLink: '',
+        registerDate: ''
+      },
+      
+    }
+  },
+  components: {
+    baseForm,
+    videoForm,
+    introPicForm
+  },
+  computed: {
+    companyId () {
+      let admin = getAdmin().admin
+      return this.$route.query.companyId || admin.belongCompanyId
+    },
+    adminId () {
+      return getAdmin().admin.adminId
+    }
+  },
+  async mounted () {
+    await this.getCompanyDetail()
+    if (!this.form.companyId && loadForm()) {
+      this.form = JSON.parse(loadForm())
+    }
+  },
+  methods: {
+    async handleSubmitClick () {
+       return this.validate()
+    },
+    async validate () {
+      saveForm(this.form)
+      let res = await Promise.all([this.$refs['base-form'].validate()])
+      let item = res.find(item => !item)
+      if (item === false) {
+        return
+      } else {
+        this.submit()
+      }
+    },
+    async submit () {
+      await Promise.all([this.$refs['base-form'].submit(), this.$refs['video-form'].submit(), this.$refs['intro-form'].submit()])
+      let api = this.form.companyId ? CompanyApi.updateCompany : CompanyApi.addCompany
+      return api(this.form).then(() => {
+        this.$Message.success(this.form.companyId ? '修改成功' : '新增成功')
+        this.isDetail = true
+        removeForm()
+        setTimeout(() => {
+          this.refreshAdminerInfo()
+        }, 500)
+      }).catch(err => {
+        saveForm(this.form)
+      })
+    },
+    cancle () {
+      window.location.reload()
+    },
+    getCompanyDetail (companyId) {
+      let id = companyId || this.companyId
+      if (!id) return
+      return CompanyApi.getCompanyDetail(id).then(res => {
+        this.isDetail = true
+        res.data.company.registerDate1 = new Date(res.data.company.registerDate)
+        
+        this.form = res.data.company
+      })
+    },
+    refreshAdminerInfo () {
+      return refreshAdminerInfo(this.adminId).then(res => {
+        this.$router.push({
+          path: '/enterprise',
+          query: {
+            companyId: res.data.belongCompanyId
+          }
+        })
+      })
+    }
+  }
+}
+</script>
+<style lang="less">
+.enterprise {
+  color: rgba(255,255,255,0.60);
+  .form {
+    margin-top: 30px;
+  }
+  
+  .ivu-date-picker {
+    width: 100%;
+  }
+  .ivu-date-picker-cells-year .ivu-date-picker-cells-cell-focused, .ivu-date-picker-cells-month .ivu-date-picker-cells-cell-focused, .ivu-date-picker-cells-cell:hover em {
+    background: #17D2D2 !important;
+    color: #fff;
+  }
+  
+  .m-t-30 {
+    margin-top: 30px;
+  }
+  .ivu-input-wrapper {
+    max-width: 337px;
+  }
+  .textarea-w {
+    .ivu-input-wrapper {
+      max-width: 100%;
+      
+    }
+    textarea.ivu-input {
+      height: 104px;
+    }
+  }
+  .input-btn {
+    margin: 0 0 0 15px;
+    position: relative;
+    &.not-allow {
+      &::after {
+        width: calc(100% + 2px);
+        height: calc(100% + 2px);
+        content: '';
+        display: block;
+        background: rgba(0,0,0,0.5);
+        position: absolute;
+        top: -1px;
+        left: -1px;
+        cursor: not-allowed;
+      }
+    }
+  }
+  .actions-w {
+    padding-left: 86px;
+    padding-bottom: 30px;
+    .submit-btn {
+      margin-right: 15px;
+    }
+  }
+  .ivu-input[disabled], .ivu-select-disabled .ivu-select-selection {
+    background: transparent !important;
+    color: #fff !important;
+    border: none;
+    cursor: default;
+    .ivu-icon, .ivu-input-word-count {
+      display: none;
+    }
+  }
+  textarea {
+    resize: none;
+  }
+}
+</style>

+ 9 - 0
admin/src/views/industry/index.vue

@@ -0,0 +1,9 @@
+<template>
+  <router-view />
+</template>
+
+<script>
+export default {
+  
+}
+</script>

+ 130 - 0
admin/src/views/industry/list.vue

@@ -0,0 +1,130 @@
+<template>
+  <div class="industry-list">
+    <tables
+      :buttonList="buttonList"
+      :data-api="getIndustry"
+      :delete-api="updateIndustry"
+      :columns="columns"
+      @create="create"
+      @toEdit="toEdit"
+      placeholder="输入行业名称"
+      ref="table"
+    />
+    <cModal :show="modalShow" :width="526" title="新增行业" @close="modalShow=false" @submit="createIndustry">
+      <div class="form">
+        <Form :label-width="86">
+          <FormItem label="行业名称">
+            <Input size="large" v-model="form.name" />
+          </FormItem>
+        </Form>
+      </div>
+    </cModal>
+  </div>
+</template>
+
+<script>
+import { getIndustry, createIndustry, updateIndustry } from '@/api/company'
+import tables from 'components/tables'
+import cModal from 'components/Modal'
+
+export default {
+  data () {
+    return {
+      getIndustry,
+      // 传递给tables的表格列数据
+      buttonList: [
+        {
+          text: '新增',
+          handle: 'create'
+        }
+      ],
+      dataApi: getIndustry,
+      deleteApi: getIndustry,
+      columns: [
+        {
+          type: 'index',
+          title: '序号',
+          align: 'center',
+          width: 80
+        },
+        {
+          title: '行业名称',
+          key: 'name',
+          align: 'center'
+        },
+        {
+          title: '状态',
+          key: 'isValide',
+          align: 'center',
+          render: (h, params) => {
+            return h('i-switch', {
+              props: {
+                trueValue: 1,
+                falseValue: 0,
+                value: params.row.isValide,
+                // disabled: params.row.roleKey === 'admin'
+              },
+              on: {
+                'on-change': (val) => {
+                  updateIndustry(Object.assign(params.row, {isValide: val}))
+                }
+              }
+            })
+          }
+        },
+        {
+          title: '创建时间',
+          key: 'createTime',
+          align: 'center',
+          render: (h, params) => h('p', params.row.createTime.replace('T', ' '))
+        },
+        {
+          title: '操作',
+          slot: 'action',
+          tools: ['edit', 'del' ],
+          align: 'center'
+        }
+      ],
+      modalShow: false,
+      form: {
+        name: ''
+      }
+    }
+  },
+  components: {
+    tables,
+    cModal
+  },
+  methods: {
+    create () {
+      this.form = {
+        name: ''
+      }
+      this.modalShow = true
+    },
+    toEdit (item) {
+      this.modalShow = true
+      this.form = Object.assign({}, item)
+    },
+    async createIndustry () {
+      let api = this.form.id ? updateIndustry : createIndustry
+      let res = await api(this.form)
+      this.$refs['table'].handleTableData()
+      this.modalShow = false
+    },
+    async updateIndustry(row) {
+      row[0].enable = 0
+      await updateIndustry(row[0])
+      this.$Message.success({
+        content: '删除成功'
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.industry-list {
+  padding: 30px;
+}
+</style>

+ 201 - 0
admin/src/views/system/commentator/list.vue

@@ -0,0 +1,201 @@
+<template>
+  <div class="house-list">
+    <tables
+      :buttonList="buttonList"
+      :data-api="dataApi"
+      :deleteApi="toDel"
+      :columns="columns"
+      @toEdit="toEdit"
+      @create="authShow = true"
+      placeholder="账号名称"
+      ref="table"
+    />
+
+    <CModal :show="show" title="讲解员信息" :width="420" @submit="updateUser" @close="closeModal">
+      <Form :label-width="100">
+        <FormItem label="讲解员ID">
+          <p>{{form.viewerId}}</p>
+        </FormItem>
+        <FormItem label="讲解员名称">
+          <Input size="large" v-model="form.name" />
+        </FormItem>
+        <FormItem label="公司名称">
+          <Input size="large" v-model="form.companyName" />
+        </FormItem>
+        <FormItem label="手机号码">
+          <Input size="large" v-model="form.phoneNum" />
+        </FormItem>
+        <FormItem label="头像">
+          <picUpload  class="pic-upload" tips="只能上传jpg/png文件,且不超过500kb" ref="post-upload" :limit="1" :multiple="false" :preUploads="postPreUploads" :hasUploads="postHasUploads" />
+        </FormItem>
+      </Form>
+    </CModal>
+
+    <CModal :show="authShow" title="新增讲解员" :width="640" @submit="authSubmit" @close="authClose">
+      <UserList @selected="s => selectViews = s" />
+    </CModal>
+
+  </div>
+</template>
+
+<script>
+import picUpload from '@/components/upload'
+import UserList from './userList'
+import tables from 'components/tables'
+import { fetchGuidList, updateGuide, updateViewerToGuide } from 'api/'
+import CModal from 'components/Modal'
+
+const roleMap = {
+  0: '超级管理员',
+  1: '普通管理员',
+  2: '讲解员',
+}
+export default {
+  data() {
+    return {
+      postPreUploads: [],
+      postHasUploads: [],
+      buttonList: [
+        {
+          text: '新增',
+          handle: 'create'
+        }
+      ],
+      authShow: false,
+      show: false,
+      form: {},
+      // 传递给tables的表格列数据
+      dataApi: fetchGuidList,
+      roleList: [],
+      columns: [
+        {
+          type: 'index',
+          title: '序号',
+          align: 'center',
+          width: 80
+        },
+        {
+          title: '头像',
+          key: 'avatar',
+          align: 'center',
+          render: (h, params) => {
+            return h('img', {
+              domProps: {
+                src: params.row.avatar,
+                className: 'avatar'
+              }
+            })
+          }
+        },
+        {
+          title: 'ID',
+          key: 'viewerId',
+          align: 'center'
+        },
+        {
+          title: '讲解员名称',
+          key: 'name',
+          align: 'center'
+        },
+        {
+          title: '公司名称',
+          key: 'companyName',
+          align: 'center'
+        },
+        {
+          title: '手机号码',
+          key: 'phoneNum',
+          align: 'center'
+        },
+        {
+          title: '创建时间',
+          key: 'createTime',
+          align: 'center',
+          render: (h, params) => h('p', params.row.createTime.replace('T', ' '))
+        },
+        {
+          title: '操作',
+          slot: 'action',
+          tools: ['edit', 'del'],
+          align: 'center'
+        }
+      ],
+      selectViews: []
+    }
+  },
+  components: {
+    UserList,
+    picUpload,
+    tables,
+    CModal
+  },
+  mounted () {
+  },
+  methods: {
+    authClose() {
+      this.selectViews = []
+      this.authShow = false
+    },
+    async authSubmit() {
+      this.authShow = false
+      let ps = this.selectViews.map(id => updateViewerToGuide(id))
+
+      await Promise.all(ps)
+      
+      this.$refs['table'].handleTableData()
+    },
+    async changeUser (msg = '修改成功') {
+      if (this.postPreUploads.length) {
+        let fs = await this.$refs['post-upload'].uploadfiles()
+        this.form.avatar = fs[0]
+      }
+      
+      await updateGuide(this.form)
+      this.closeModal()
+      this.$Message.success({
+        content: msg
+      })
+    },
+    async updateUser() {
+      await this.changeUser()
+      setTimeout(() => {
+        this.$refs['table'].handleTableData()
+      }, 200)
+    },
+    toEdit (row) {
+      this.form = JSON.parse(JSON.stringify(row))
+      this.postHasUploads =  [{img: this.form.avatar}]
+      this.show = true
+    },
+    toDel(row) {
+      row[0].enable = 0
+      this.toEdit(row[0])
+      this.show = false
+      this.form.enable = 0
+      this.changeUser('删除成功')
+    },
+    closeModal () {
+      this.show = false
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.house-list {
+  padding: 20px;
+  background: #252828;
+}
+</style>
+
+<style>
+.avatar {
+  width: 38px;
+  height: 38px;
+  border-radius: 50%;
+}
+
+.pic-upload .tips {
+  bottom: auto;
+}
+</style>

+ 97 - 0
admin/src/views/system/commentator/userList.vue

@@ -0,0 +1,97 @@
+<template>
+  <div class="house-list">
+    <tables
+      :data-api="dataApi"
+      :columns="columns"
+      @chooseSelection="chooseSelection"
+      placeholder="输入名称"
+      ref="table"
+    />
+  </div>
+</template>
+
+<script>
+import tables from 'components/tables'
+import { fetchViewerList, updateGuide } from 'api/'
+
+const roleMap = {
+  0: '超级管理员',
+  1: '普通管理员',
+  2: '讲解员',
+}
+export default {
+  data() {
+    return {
+      // 传递给tables的表格列数据
+      dataApi: fetchViewerList,
+      roleList: [],
+      columns: [
+        {
+          type: 'selection',
+          width: 60,
+          align: 'center'
+        },
+        {
+          type: 'index',
+          title: '序号',
+          align: 'center',
+          width: 80
+        },
+        {
+          title: '头像',
+          key: 'avatar',
+          align: 'center',
+          render: (h, params) => {
+            return h('img', {
+              domProps: {
+                src: params.row.avatar,
+                className: 'avatar'
+              }
+            })
+          }
+        },
+        {
+          title: '名称',
+          key: 'name',
+          align: 'center'
+        },
+        {
+          title: '授权时间',
+          key: 'createTime',
+          align: 'center',
+          render: (h, params) => h('p', params.row.createTime.replace('T', ' '))
+        }
+      ],
+      selecteds: []
+    }
+  },
+  components: {
+    tables
+  },
+  methods: {
+    chooseSelection (selection) {
+      this.selecteds = selection.map(item => item.viewerId)
+      this.$emit('selected', this.selecteds)
+    },
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.house-list {
+  padding: 20px;
+  background: #252828;
+}
+</style>
+
+<style>
+.avatar {
+  width: 38px;
+  height: 38px;
+  border-radius: 50%;
+}
+
+.pic-upload .tips {
+  bottom: auto;
+}
+</style>

+ 32 - 18
admin/src/views/system/user/list.vue

@@ -8,19 +8,22 @@
       ref="table"
     />
     <CModal :show="show" title="用户信息" :width="420" @submit="changeUser" @close="closeModal">
-      <Form :label-width="75">
+      <Form :label-width="85">
         <FormItem label="用户名称">
           <Input size="large" v-model="form.name" disabled />
         </FormItem>
         <FormItem label="用户角色">
           <Select v-model="form.type" size="large">
-            <Option :value="-1">未分配</Option>
-            <Option :value="item.roleType" v-for="item in roleList" :key="item.roleId">{{ item.remark }}</Option>
+            <!-- <Option :value="-1">未分配</Option> -->
+            <Option :value="item.roleId" v-for="item in roleList" :key="item.roleId">{{ item.remark }}</Option>
           </Select>
         </FormItem>
         <FormItem label="手机号码">
           <Input size="large" v-model="form.phone" disabled />
         </FormItem>
+        <FormItem label="公司代号">
+          <Input size="large" v-model="form.deptId" placeholder="请填写公司代号" />
+        </FormItem>
       </Form>
     </CModal>
   </div>
@@ -28,22 +31,37 @@
 
 <script>
 import tables from 'components/tables'
-import { fetchUserList, updateUser, fetchRoleList } from 'api/'
+import { fetchUserList, updateUser } from 'api/'
 import CModal from 'components/Modal'
+import { getAdmin } from '@/libs/token'
 
 const roleMap = {
-  0: '超级管理员',
-  1: '普通管理员',
-  2: '经纪人',
+  1: '超级管理员',
+  2: '主账号管理员',
+  3: '二级管理员',
+  4: '游客'
 }
+
+const roleType = getAdmin().admin.type
+
+const accessRole = {
+  1: [2,3,4],
+  2: [3,4],
+  3: [],
+  4: []
+}
+
+console.log(accessRole[roleType])
 export default {
   data() {
     return {
       show: false,
-      form: {},
+      form: {
+        type: 1
+      },
       // 传递给tables的表格列数据
-      dataApi: fetchUserList,
-      roleList: [],
+      dataApi: (roleType == 1 || roleType=== 2) ? fetchUserList : function(){},
+      roleList: accessRole[roleType].map(item => { return { roleId: item, remark: roleMap[item] } }),
       columns: [
         {
           type: 'index',
@@ -53,7 +71,7 @@ export default {
         },
         {
           title: '账号ID',
-          key: 'admin_id',
+          key: 'adminId',
           align: 'center'
         },
         {
@@ -99,7 +117,8 @@ export default {
         {
           title: '创建时间',
           key: 'createTime',
-          align: 'center'
+          align: 'center',
+          render: (h, params) => h('p', params.row.createTime.replace('T', ' '))
         },
         {
           title: '操作',
@@ -115,14 +134,8 @@ export default {
     CModal
   },
   mounted () {
-    this.fetchRoleList()
   },
   methods: {
-    fetchRoleList () {
-      fetchRoleList().then(res => {
-        this.roleList = res.data
-      })
-    },
     async changeUser () {
       await updateUser(this.form)
       this.closeModal()
@@ -133,6 +146,7 @@ export default {
     },
     toEdit (row) {
       this.form = JSON.parse(JSON.stringify(row))
+      console.log(this.form)
       this.show = true
     },
     closeModal () {

+ 5 - 5
admin/vue.config.js

@@ -24,12 +24,12 @@ module.exports = {
     },
     proxy: {
       '/admin': {
-        // target: 'http://120.24.85.77:8087', // 正式环境
-        // target: 'http://192.168.0.83:8085'  // 伟玉本地环境
-        target: 'http://39.108.220.65:8085'    // 测试环境
+        target: 'https://haowan.4dkankan.com', // 正式环境
+        // target: 'http://192.168.0.83:8165'  // 伟玉本地环境
+        // target: 'http://haowantest.4dkankan.com'    // 测试环境
       },
       '/node-upload': {
-        target: 'http://39.108.220.65:1935',
+        target: 'http://haowantest.4dkankan.com',
       },
     }
     // before: require('./mock/mock-server.js')
@@ -37,7 +37,7 @@ module.exports = {
   configureWebpack: {
     // provide the app's title in webpack's name field, so that
     // it can be accessed in index.html to inject the correct title.
-    name: '看房4DKanKan-管理后台',
+    name: '好玩展-管理后台',
     resolve: {
       alias: {
         '@': resolve('src'),

BIN=BIN
admin/备份/favicon.ico


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/index.html


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
admin/备份/static/css/app.002868d7.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
admin/备份/static/css/app.acf3529d.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
admin/备份/static/css/app.df3b1772.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-157e109a.83d43db3.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-38047187.4962b786.css


+ 1 - 0
admin/备份/static/css/chunk-441a8fbe.0473a37f.css

@@ -0,0 +1 @@
+.upload[data-v-f5ffe9c6]{padding:30px 0!important}.tips[data-v-f5ffe9c6]{position:absolute;bottom:-8px;font-size:12px;color:hsla(0,0%,100%,.38);line-height:1}.home-admin[data-v-00d8cb8d]{padding:0 30px 30px}.form[data-v-00d8cb8d]{padding-top:30px}.actions-w[data-v-00d8cb8d]{padding-left:86px}.actions-w .submit-btn[data-v-00d8cb8d]{width:116px}.actions-w .cancle-btn[data-v-00d8cb8d]{width:88px;margin-left:15px}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-44f6aa56.c53cdc34.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-4f2d4116.6d6f7126.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 20 - 0
admin/备份/static/css/chunk-57e8b9f0.5c4367e0.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-5bb898a2.5b9c4312.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-6cf27db8.2747e27d.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-e48941e8.f00269c5.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/css/chunk-vendors.2b907f11.css


BIN=BIN
admin/备份/static/fonts/ionicons.143146fa.woff2


BIN=BIN
admin/备份/static/fonts/ionicons.99ac3308.woff


BIN=BIN
admin/备份/static/fonts/ionicons.d535a25a.ttf


BIN=BIN
admin/备份/static/img/img_kor@2x.9b047e48.png


BIN=BIN
admin/备份/static/img/img_loginele_points@2x.82fc66fa.png


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 870 - 0
admin/备份/static/img/ionicons.a2c4a261.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/app.18e9d2a1.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/app.237eb3e7.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/app.65f02c02.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/app.df643551.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/app.e0a0ef0f.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/app.e20254bb.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-157e109a.1723ce77.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-157e109a.54549403.js


+ 1 - 0
admin/备份/static/js/chunk-2d0abe1d.8c64ea78.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0abe1d"],{"16bd":function(e,n,t){"use strict";t.r(n);var u=function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("router-view")},r=[],c={},l=c,a=t("2877"),o=Object(a["a"])(l,u,r,!1,null,null,null);n["default"]=o.exports}}]);

+ 1 - 0
admin/备份/static/js/chunk-2d0b3248.e3e48ef5.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0b3248"],{"26b0":function(e,n,t){"use strict";t.r(n);var u=function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("router-view")},r=[],c={},l=c,o=t("2877"),s=Object(o["a"])(l,u,r,!1,null,null,null);n["default"]=s.exports}}]);

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-38047187.a8445277.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-38047187.d5b3a3ac.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-441a8fbe.55fdf9a5.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-441a8fbe.f37e9609.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-44f6aa56.3934cede.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-44f6aa56.a33bf786.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-44f6aa56.c52cab81.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-44f6aa56.d275c919.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-44f6aa56.ef22b0ac.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-4f2d4116.0b2a2c7b.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 8 - 0
admin/备份/static/js/chunk-57e8b9f0.f0441554.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-5bb898a2.df9602a7.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-6cf27db8.e0890c98.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-e2831abe.3b165715.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
admin/备份/static/js/chunk-e48941e8.c0a9513e.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 72 - 0
admin/备份/static/js/chunk-vendors.f473a602.js


+ 3 - 0
miniprogram/apis/company.js

@@ -19,5 +19,8 @@ export default {
   },
   getCompanyDetail (companyId) {
     return request.get('company/getCompanyDetail', { companyId })
+  },
+  getCompanyDetailByScene (sceneNum) {
+    return request.get('company/getCompanyByScene', { sceneNum })
   }
 }

+ 6 - 3
miniprogram/apis/fetcher/request.js

@@ -2,7 +2,7 @@ import ERROR_CODE from '../../config/error_code'
 import { API_BASE_URL } from './../../config/config'
 const BASE_URL = `${API_BASE_URL}/app/`
 // 需要登录的错误码
-const needLoginErrorCode = [3004, 3005, 3006]
+const needLoginErrorCode = [3018, 3019]
 
 Promise.prototype.finally = function (callback) {
   var Promise = this.constructor;
@@ -30,11 +30,13 @@ function request (url, options) {
       url: url.indexOf('://') === -1 ? BASE_URL + url : url,
       method: options.method,
       data: options.data,
+      header: options.header || {},
       // header: {
       //   token: app.globalData.token
       // },
       success (res) {
-        if (res.data.code == 0 || res.data.code == 200) {
+        console.log(res.data, '请求成功')
+        if (res.data.code == 0 || res.data.code == 200 || res.data.errno === 0) {
           resolve(res.data)
         } else if (needLoginErrorCode.indexOf(Number(res.data.code)) !== -1) {
           wx.navigateTo({
@@ -46,6 +48,7 @@ function request (url, options) {
         }
       },
       fail (err) {
+        console.log(err, '请求失败')
         reject(err)
       }
     }, options))
@@ -63,7 +66,7 @@ function post (url, data = {}, options = {}) {
   options.method = 'POST'
   // token和user_ID放在url上, 后续后端再做优化
   const app = getApp();
-  url += `?token=${app.globalData.token || ''}&viewerId=${app.globalData.userinfo.user_id}`
+  url += `?token=${getApp().globalData.token || ''}&viewerId=${getApp().globalData.userinfo.viewerId}`
   options.data = Object.assign({
     user_id: app.globalData.userinfo.user_id
   }, data)

+ 4 - 0
miniprogram/apis/goods.js

@@ -63,5 +63,9 @@ export default {
       viewerId: getApp().globalData.userinfo.viewerId
     }
     return request.get('goods/cancelGoodsCollect', data)
+  },
+
+  getShopGoodsDetail (goodsId) {
+    return request.post('https://shop.4dkankan.com/platform-framework/api/goods/detail', {id: Number(goodsId)}, { header: {'Content-Type': 'application/x-www-form-urlencoded'}})
   }
 }

+ 4 - 3
miniprogram/apis/im.js

@@ -8,7 +8,7 @@ export default {
   },
   getContacts () {
     const app = getApp()
-    return request.get(`${API_BASE_URL}/im/getContacts/${app.globalData.userinfo.user_id}`, {user_id: app.globalData.userinfo.user_id})
+    return request.get(`${API_BASE_URL}/im/getContacts/${app.globalData.userinfo.viewerId}`, {user_id: app.globalData.userinfo.viewerId})
   },
   upload () {
     const formData = new FormData()
@@ -16,10 +16,11 @@ export default {
     return request.post(`${API_BASE_URL}/im/upload`, formData)
   },
   addFriend (friend_id) {
-    return request.get(`${API_BASE_URL}/im/addFriend/${friend_id}/${getApp().globalData.userinfo.user_id}`)
+    if (friend_id === getApp().globalData.userinfo.viewerId) return
+    return request.get(`${API_BASE_URL}/im/addFriend/${friend_id}/${getApp().globalData.userinfo.viewerId}`)
   },
 
   getMsgHistory (friend_id, offset=0) {
-    return request.get(`${API_BASE_URL}/im/getMsgHistory/${friend_id}/${getApp().globalData.userinfo.user_id}/${offset}`)
+    return request.get(`${API_BASE_URL}/im/getMsgHistory/${friend_id}/${getApp().globalData.userinfo.viewerId}/${offset}`)
   }
 }

+ 11 - 1
miniprogram/apis/index.js

@@ -4,7 +4,8 @@ export default {
   getCompanyList (data) {
     data = Object.assign({
       pageNum: 1,
-      pageSize: 999
+      pageSize: 999,
+      tradeName: ''
     }, data)
     return request.get('company/getCompanyList', data)
   },
@@ -23,5 +24,14 @@ export default {
   },
   getGoodsDetail (goodsId) {
     return request.get('goods/getGoodsDetail', { goodsId })
+  },
+  postApiData (data) {
+    console.log(data, 'data')
+    let app = getApp()
+    let defaultData = {
+      userId: app.globalData.userinfo ? app.globalData.userinfo.viewerId || '' : '',
+      guideId: ''
+    }
+    return request.get('company/sendData', Object.assign(defaultData, data))
   }
 }

+ 71 - 32
miniprogram/app.js

@@ -5,14 +5,42 @@ import {
 } from './utils/storage'
 
 import ImApi from './apis/im'
+import UserApi from './apis/user'
 import AppIMDelegate from "./delegate/app-im-delegate";
-import { fotmatDate } from './utils/date'
+import {
+  fotmatDate
+} from './utils/date'
 
 var QQMapWX = require('/utils/qqmap-wx-jssdk.min.js')
 var timer = null
 App({
   onLaunch: function (options) {
     //检查是否存在新版本
+    const updateManager = wx.getUpdateManager()
+    updateManager.onCheckForUpdate(function (res) {
+      // 请求完新版本信息的回调
+      if (res.hasUpdate) {
+        updateManager.onUpdateReady(function () {
+          wx.showModal({
+            title: '更新提示',
+            content: '新版本已经准备好,是否重启应用?',
+            success: function (res) {
+              if (res.confirm) {
+                // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
+                updateManager.applyUpdate()
+              }
+            }
+          })
+        })
+        updateManager.onUpdateFailed(function () {
+          // 新的版本下载失败
+          wx.showModal({
+            title: '已经有新版本了哟~',
+            content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
+          })
+        })
+      }
+    })
     this.appIMDelegate = new AppIMDelegate(this);
     this.appIMDelegate.onLaunch(options);
     this.globalData.qqmapsdk = new QQMapWX({
@@ -31,7 +59,12 @@ App({
     setTimeout(() => {
       this.appIMDelegate.onShow()
       wx.getUserInfo({
-        complete: (res) => {console.log(res, 'userinfo')},
+        complete: (res) => {
+          console.log(res, 'userinfo')
+        },
+      })
+      UserApi.getUserInfoById(this.globalData.userinfo.viewerId).then(res => {
+        this.globalData.userinfo = res.data
       })
     }, 1000)
   },
@@ -88,37 +121,41 @@ App({
   getIMHandler() {
     return this.appIMDelegate.getIMHandlerDelegate();
   },
-  async getNewMessage (msg) {
-    const { conversations } = this.globalData
+  async getNewMessage(msg) {
+    const {
+      conversations
+    } = this.globalData
     let item = conversations.find(item => item.id === msg.fromId)
     if (item) {
-        item.latestMsgContent = msg.content
-        item.latestMsgTime = msg.sendTime
-        item.unReadNum ? item.unReadNum++ : item.unReadNum = 1
-        this.globalData.conversations = this.dealConversations(conversations)
+      item.latestMsgContent = msg.content
+      item.latestMsgTime = msg.sendTime
+      item.unReadNum ? item.unReadNum++ : item.unReadNum = 1
+      this.globalData.conversations = this.dealConversations(conversations)
     } else {
-        await this.getContact()
+      await this.getContact()
     }
-},
-getContact(isNewMsg) {
-  return ImApi.getContacts().then(res => {
-    const friends = res.data.friends
-    const {
-      conversations
-    } = this.globalData
-    this.globalData.unViewMsg = 0
-    this.globalData.conversations = this.dealConversations(friends.map(item => {
-      const con = conversations.find(con => con.id === item.id)
-      if (con) {
-        item = Object.assign(con, item)
-      } else if (isNewMsg){
-        item.unReadNum = 1
-      }
-      this.globalData.unViewMsg += item.unReadNum
-      return item
-    }))
-  })
-},
+  },
+  getContact(isNewMsg) {
+    return ImApi.getContacts().then(res => {
+      const friends = res.data.friends
+      const {
+        conversations
+      } = this.globalData
+      this.globalData.unViewMsg = 0
+      this.globalData.conversations = this.dealConversations(friends.map(item => {
+        if (conversations) {
+          const con = conversations.find(con => con.id === item.id)
+          if (con) {
+            item = Object.assign(con, item)
+          } else if (isNewMsg) {
+            item.unReadNum = 1
+          }
+          this.globalData.unViewMsg += item.unReadNum
+        }
+        return item
+      }))
+    })
+  },
   dealConversations(conversations) {
     return conversations.map(item => {
       let content = item.latestMsgContent
@@ -135,12 +172,14 @@ getContact(isNewMsg) {
       } catch (err) {}
       item.latestMsgContent = content
       const now = new Date()
-      if (now.getMonth() === new Date(item.latestMsgTime).getMonth() && now.getDate() === new Date(item.latestMsgTime).getDate()) {
+      if (item.latestMsgTime && now.getMonth() === new Date(item.latestMsgTime).getMonth() && now.getDate() === new Date(item.latestMsgTime).getDate()) {
         item.timeStr = fotmatDate(item.latestMsgTime, 'hh:mm')
-      } else {
+      } else if (item.latestMsgTime) {
         item.timeStr = fotmatDate(item.latestMsgTime, 'MM/dd')
+      } else {
+        item.timeStr = ''
       }
-      
+
       return item
     }).sort((a, b) => new Date(b.latestMsgTime) - new Date(a.latestMsgTime))
   },

+ 2 - 5
miniprogram/app.json

@@ -3,20 +3,17 @@
     "pages/index/index",
     "pages/my/my",
     "pages/chat-list/chat-list",
-    "pages/exhibition-detail/exhibition-detail",
-    "pages/exhibition-register/exhibition-register",
     "pages/exhibition-enterprise/exhibition-enterprise",
     "pages/goods-tabs/goods-tabs",
     "pages/search/search",
     "pages/user-info/user-info",
     "pages/collect-goods/collect-goods",
-    "pages/collect-enterprise/collect-enterprise",
     "pages/business-card/business-card",
     "pages/shared/shared",
     "pages/goods-detail/goods-detail",
     "pages/login/login",
     "pages/find/find",
-    "pages/scene/scene",
+    "pages/web/web",
     "pages/business-card/detail/business-card-detail",
     "pages/logout/logout",
     "pages/business-card/scan/scan",
@@ -28,7 +25,7 @@
     "tab-bar": "components/tab-bar/tab-bar"
   },
   "window": {
-    "navigationBarTitleText": "看展4DKanKan",
+    "navigationBarTitleText": "好玩展",
     "navigationBarBackgroundColor": "#fff",
     "navigationBarTextStyle": "black"
   },

+ 1 - 1
miniprogram/app.wxss

@@ -1,6 +1,6 @@
 /**app.wxss**/
 page{
-  height: 100%;
+  min-height: 100%;
   background: #ffffff;
   -webkit-overflow-scrolling : touch;
 }

BIN=BIN
miniprogram/assets/font/iconfont.eot


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
miniprogram/assets/font/iconfont.js


+ 0 - 331
miniprogram/assets/font/iconfont.json

@@ -1,331 +0,0 @@
-{
-  "id": "1790241",
-  "name": "看房4dkk-经纪人端",
-  "font_family": "iconfont",
-  "css_prefix_text": "icon",
-  "description": "",
-  "glyphs": [
-    {
-      "icon_id": "16030488",
-      "name": "my_set",
-      "font_class": "my_set",
-      "unicode": "e708",
-      "unicode_decimal": 59144
-    },
-    {
-      "icon_id": "15968403",
-      "name": "card_mail",
-      "font_class": "card_mail",
-      "unicode": "e706",
-      "unicode_decimal": 59142
-    },
-    {
-      "icon_id": "15968404",
-      "name": "card_address",
-      "font_class": "card_address",
-      "unicode": "e707",
-      "unicode_decimal": 59143
-    },
-    {
-      "icon_id": "15727298",
-      "name": "my_product",
-      "font_class": "my_product",
-      "unicode": "e6fe",
-      "unicode_decimal": 59134
-    },
-    {
-      "icon_id": "15727299",
-      "name": "my_contacts",
-      "font_class": "my_contacts",
-      "unicode": "e6ff",
-      "unicode_decimal": 59135
-    },
-    {
-      "icon_id": "15727300",
-      "name": "my_enterprise",
-      "font_class": "my_enterprise",
-      "unicode": "e700",
-      "unicode_decimal": 59136
-    },
-    {
-      "icon_id": "15727301",
-      "name": "my_reportform",
-      "font_class": "my_reportform",
-      "unicode": "e701",
-      "unicode_decimal": 59137
-    },
-    {
-      "icon_id": "15602811",
-      "name": "search_clear",
-      "font_class": "search_clear",
-      "unicode": "e6fb",
-      "unicode_decimal": 59131
-    },
-    {
-      "icon_id": "15221670",
-      "name": "cus_edit",
-      "font_class": "cus_edit",
-      "unicode": "e6f7",
-      "unicode_decimal": 59127
-    },
-    {
-      "icon_id": "14817584",
-      "name": "scene_tit_tool",
-      "font_class": "scene_tit_tool",
-      "unicode": "e6f6",
-      "unicode_decimal": 59126
-    },
-    {
-      "icon_id": "14409269",
-      "name": "scene_alllayout",
-      "font_class": "scene_alllayout",
-      "unicode": "e6f5",
-      "unicode_decimal": 59125
-    },
-    {
-      "icon_id": "14409200",
-      "name": "vr_tagging",
-      "font_class": "vr_tagging",
-      "unicode": "e6d2",
-      "unicode_decimal": 59090
-    },
-    {
-      "icon_id": "14409201",
-      "name": "bot_input_more",
-      "font_class": "bot_input_more",
-      "unicode": "e6d3",
-      "unicode_decimal": 59091
-    },
-    {
-      "icon_id": "14409202",
-      "name": "bot_input_voice",
-      "font_class": "bot_input_voice",
-      "unicode": "e6d4",
-      "unicode_decimal": 59092
-    },
-    {
-      "icon_id": "14409203",
-      "name": "atab_msg",
-      "font_class": "atab_msg",
-      "unicode": "e6d5",
-      "unicode_decimal": 59093
-    },
-    {
-      "icon_id": "14409204",
-      "name": "atab_customer",
-      "font_class": "atab_customer",
-      "unicode": "e6d6",
-      "unicode_decimal": 59094
-    },
-    {
-      "icon_id": "14409205",
-      "name": "atab_me",
-      "font_class": "atab_me",
-      "unicode": "e6d7",
-      "unicode_decimal": 59095
-    },
-    {
-      "icon_id": "14409206",
-      "name": "cus_add",
-      "font_class": "cus_add",
-      "unicode": "e6d8",
-      "unicode_decimal": 59096
-    },
-    {
-      "icon_id": "14409207",
-      "name": "cus_call",
-      "font_class": "cus_call",
-      "unicode": "e6d9",
-      "unicode_decimal": 59097
-    },
-    {
-      "icon_id": "14409208",
-      "name": "cus_chose_allow",
-      "font_class": "cus_chose_allow",
-      "unicode": "e6da",
-      "unicode_decimal": 59098
-    },
-    {
-      "icon_id": "14409209",
-      "name": "tab_hose",
-      "font_class": "atab_hose",
-      "unicode": "e6db",
-      "unicode_decimal": 59099
-    },
-    {
-      "icon_id": "14409210",
-      "name": "list_about",
-      "font_class": "list_about",
-      "unicode": "e6dc",
-      "unicode_decimal": 59100
-    },
-    {
-      "icon_id": "14409211",
-      "name": "hose_arrow_active",
-      "font_class": "hose_arrow_active",
-      "unicode": "e6dd",
-      "unicode_decimal": 59101
-    },
-    {
-      "icon_id": "14409212",
-      "name": "cus_star",
-      "font_class": "cus_star",
-      "unicode": "e6de",
-      "unicode_decimal": 59102
-    },
-    {
-      "icon_id": "14409213",
-      "name": "hose_arrow_normal",
-      "font_class": "hose_arrow_normal",
-      "unicode": "e6df",
-      "unicode_decimal": 59103
-    },
-    {
-      "icon_id": "14409214",
-      "name": "minfo_fav_active",
-      "font_class": "minfo_fav_active",
-      "unicode": "e6e0",
-      "unicode_decimal": 59104
-    },
-    {
-      "icon_id": "14409215",
-      "name": "maps_call",
-      "font_class": "maps_call",
-      "unicode": "e6e1",
-      "unicode_decimal": 59105
-    },
-    {
-      "icon_id": "14409216",
-      "name": "maps_msg",
-      "font_class": "maps_msg",
-      "unicode": "e6e2",
-      "unicode_decimal": 59106
-    },
-    {
-      "icon_id": "14409217",
-      "name": "list_hose",
-      "font_class": "list_hose",
-      "unicode": "e6e3",
-      "unicode_decimal": 59107
-    },
-    {
-      "icon_id": "14409218",
-      "name": "scene_feedback",
-      "font_class": "scene_feedback",
-      "unicode": "e6e4",
-      "unicode_decimal": 59108
-    },
-    {
-      "icon_id": "14409219",
-      "name": "cus_msg",
-      "font_class": "cus_msg",
-      "unicode": "e6e5",
-      "unicode_decimal": 59109
-    },
-    {
-      "icon_id": "14409220",
-      "name": "scene_tags_close",
-      "font_class": "scene_tags_close",
-      "unicode": "e6e6",
-      "unicode_decimal": 59110
-    },
-    {
-      "icon_id": "14409221",
-      "name": "minfo_fav_normal",
-      "font_class": "minfo_fav_normal",
-      "unicode": "e6e7",
-      "unicode_decimal": 59111
-    },
-    {
-      "icon_id": "14409222",
-      "name": "scene_rule_normal",
-      "font_class": "scene_rule_normal",
-      "unicode": "e6e8",
-      "unicode_decimal": 59112
-    },
-    {
-      "icon_id": "14409223",
-      "name": "home_search",
-      "font_class": "home_search",
-      "unicode": "e6e9",
-      "unicode_decimal": 59113
-    },
-    {
-      "icon_id": "14409224",
-      "name": "rinfo_ban_ele",
-      "font_class": "rinfo_ban_ele",
-      "unicode": "e6ea",
-      "unicode_decimal": 59114
-    },
-    {
-      "icon_id": "14409225",
-      "name": "scene_tags_normal",
-      "font_class": "scene_tags_normal",
-      "unicode": "e6eb",
-      "unicode_decimal": 59115
-    },
-    {
-      "icon_id": "14409226",
-      "name": "scene_tit_arrow",
-      "font_class": "scene_tit_arrow",
-      "unicode": "e6ec",
-      "unicode_decimal": 59116
-    },
-    {
-      "icon_id": "14409227",
-      "name": "my_list_arrow",
-      "font_class": "my_list_arrow",
-      "unicode": "e6ed",
-      "unicode_decimal": 59117
-    },
-    {
-      "icon_id": "14409228",
-      "name": "scene_tit_share",
-      "font_class": "scene_tit_share",
-      "unicode": "e6ee",
-      "unicode_decimal": 59118
-    },
-    {
-      "icon_id": "14409229",
-      "name": "scene_vrmode",
-      "font_class": "scene_vrmode",
-      "unicode": "e6ef",
-      "unicode_decimal": 59119
-    },
-    {
-      "icon_id": "14409230",
-      "name": "scene_map_3d",
-      "font_class": "scene_map_3d",
-      "unicode": "e6f0",
-      "unicode_decimal": 59120
-    },
-    {
-      "icon_id": "14409231",
-      "name": "case_logo",
-      "font_class": "case_logo",
-      "unicode": "e6f1",
-      "unicode_decimal": 59121
-    },
-    {
-      "icon_id": "14409232",
-      "name": "maps_nav",
-      "font_class": "maps_nav",
-      "unicode": "e6f2",
-      "unicode_decimal": 59122
-    },
-    {
-      "icon_id": "14409233",
-      "name": "scene_rule_close",
-      "font_class": "scene_rule_close",
-      "unicode": "e6f3",
-      "unicode_decimal": 59123
-    },
-    {
-      "icon_id": "14409234",
-      "name": "mode_loading",
-      "font_class": "mode_loading",
-      "unicode": "e6f4",
-      "unicode_decimal": 59124
-    }
-  ]
-}

+ 0 - 0
miniprogram/assets/font/iconfont.ttf


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio