Browse Source

认证通默认模板修改

yuwenjun1997 2 years ago
parent
commit
470776b414
100 changed files with 3376 additions and 556 deletions
  1. BIN
      assets/theme-images/normal/h5/banner-approve.png
  2. BIN
      assets/theme-images/normal/h5/banner-club.png
  3. BIN
      assets/theme-images/normal/h5/banner-device.png
  4. BIN
      assets/theme-images/normal/h5/banner-doc.png
  5. BIN
      assets/theme-images/normal/h5/banner-doctor.png
  6. BIN
      assets/theme-images/normal/h5/banner-feedback.png
  7. BIN
      assets/theme-images/normal/h5/banner-home.png
  8. BIN
      assets/theme-images/normal/h5/banner-record.png
  9. BIN
      assets/theme-images/normal/h5/banner-register.png
  10. BIN
      assets/theme-images/normal/h5/club-info-bg.png
  11. BIN
      assets/theme-images/normal/h5/entry-club-bg.png
  12. BIN
      assets/theme-images/normal/h5/entry-device-bg.png
  13. BIN
      assets/theme-images/normal/h5/entry-doctor-bg.png
  14. BIN
      assets/theme-images/normal/h5/h5-icon-mobile.png
  15. BIN
      assets/theme-images/normal/h5/icon-address.png
  16. BIN
      assets/theme-images/normal/h5/icon-auth-ren.png
  17. BIN
      assets/theme-images/normal/h5/icon-auth-seal-t.png
  18. BIN
      assets/theme-images/normal/h5/icon-auth-seal.png
  19. BIN
      assets/theme-images/normal/h5/icon-auth.png
  20. BIN
      assets/theme-images/normal/h5/icon-auth2.png
  21. BIN
      assets/theme-images/normal/h5/icon-avatar-v.png
  22. BIN
      assets/theme-images/normal/h5/icon-device-list.png
  23. BIN
      assets/theme-images/normal/h5/icon-feedback-submit.png
  24. BIN
      assets/theme-images/normal/h5/icon-home-approve.png
  25. BIN
      assets/theme-images/normal/h5/icon-home-doc.png
  26. BIN
      assets/theme-images/normal/h5/icon-home-edit.png
  27. BIN
      assets/theme-images/normal/h5/icon-home-feedback.png
  28. BIN
      assets/theme-images/normal/h5/icon-navigation.png
  29. BIN
      assets/theme-images/normal/h5/link-entry-doc-active.png
  30. BIN
      assets/theme-images/normal/h5/link-entry-feedback-active.png
  31. BIN
      assets/theme-images/normal/h5/link-entry-register-active.png
  32. BIN
      assets/theme-images/normal/h5/nav-entry-device-active.png
  33. BIN
      assets/theme-images/normal/h5/nav-entry-doctor-active.png
  34. BIN
      assets/theme-images/normal/pc/banner-approve.png
  35. BIN
      assets/theme-images/normal/pc/banner-club.png
  36. BIN
      assets/theme-images/normal/pc/banner-device.png
  37. BIN
      assets/theme-images/normal/pc/banner-doc.png
  38. BIN
      assets/theme-images/normal/pc/banner-doctor.png
  39. BIN
      assets/theme-images/normal/pc/banner-feedback.png
  40. BIN
      assets/theme-images/normal/pc/banner-home.png
  41. BIN
      assets/theme-images/normal/pc/banner-record.png
  42. BIN
      assets/theme-images/normal/pc/banner-register.png
  43. BIN
      assets/theme-images/normal/pc/club-info-bg.png
  44. BIN
      assets/theme-images/normal/pc/entry-club-bg.png
  45. BIN
      assets/theme-images/normal/pc/entry-device-bg.png
  46. BIN
      assets/theme-images/normal/pc/entry-doctor-bg.png
  47. BIN
      assets/theme-images/normal/pc/icon-address.png
  48. BIN
      assets/theme-images/normal/pc/icon-auth-ren.png
  49. BIN
      assets/theme-images/normal/pc/icon-auth-seal-t.png
  50. BIN
      assets/theme-images/normal/pc/icon-auth-seal.png
  51. BIN
      assets/theme-images/normal/pc/icon-auth.png
  52. BIN
      assets/theme-images/normal/pc/icon-auth2.png
  53. BIN
      assets/theme-images/normal/pc/icon-avatar-v.png
  54. BIN
      assets/theme-images/normal/pc/icon-center-item-auth-club.png
  55. BIN
      assets/theme-images/normal/pc/icon-center-item-device.png
  56. BIN
      assets/theme-images/normal/pc/icon-device-list.png
  57. BIN
      assets/theme-images/normal/pc/icon-feedback-submit.png
  58. BIN
      assets/theme-images/normal/pc/icon-mobile.png
  59. BIN
      assets/theme-images/normal/pc/icon-navigation.png
  60. BIN
      assets/theme-images/normal/pc/link-entry-doc-active.png
  61. BIN
      assets/theme-images/normal/pc/link-entry-doc.png
  62. BIN
      assets/theme-images/normal/pc/link-entry-feedback-active.png
  63. BIN
      assets/theme-images/normal/pc/link-entry-feedback.png
  64. BIN
      assets/theme-images/normal/pc/link-entry-register-active.png
  65. BIN
      assets/theme-images/normal/pc/link-entry-register.png
  66. BIN
      assets/theme-images/normal/pc/logo.png
  67. BIN
      assets/theme-images/normal/pc/nav-entry-device-active.png
  68. BIN
      assets/theme-images/normal/pc/nav-entry-device.png
  69. BIN
      assets/theme-images/normal/pc/nav-entry-doctor-active.png
  70. BIN
      assets/theme-images/normal/pc/nav-entry-doctor.png
  71. 3 1
      assets/themes/themeVariable.scss
  72. 1 47
      assets/themes/variables/normal.scss
  73. 52 0
      assets/themes/variables/ph.scss
  74. 127 0
      components/SimpleCenterCover/index.vue
  75. 4 0
      configs/mode-map.js
  76. 627 0
      layouts/app-normal.vue
  77. 1 1
      layouts/app-ph.vue
  78. 2 2
      middleware/intercept.js
  79. 0 1
      mixins/operatDoctorDetail.js
  80. 317 107
      pages/_template/app/approve/club/detail.vue
  81. 272 170
      pages/_template/app/approve/club/star-list.vue
  82. 14 24
      pages/_template/app/approve/device/detail.vue
  83. 23 22
      pages/_template/app/approve/device/index.vue
  84. 2 2
      pages/_template/app/approve/personnel/operate/detail.vue
  85. 31 41
      pages/_template/app/approve/personnel/operate/index.vue
  86. 468 0
      pages/_template/app/center/club-detail.vue
  87. 250 0
      pages/_template/app/center/device/detail.vue
  88. 268 0
      pages/_template/app/center/device/index.vue
  89. 472 0
      pages/_template/app/center/index.vue
  90. 295 0
      pages/_template/app/center/settings/password.vue
  91. 46 0
      pages/_template/app/center/subnav/account.vue
  92. 18 18
      pages/_template/app/docs/_fileId.vue
  93. 1 1
      pages/_template/app/docs/article-detail.vue
  94. 5 9
      pages/_template/app/docs/detail.vue
  95. 17 28
      pages/_template/app/feedback/index.vue
  96. 8 4
      pages/_template/app/form/club-bind.vue
  97. 34 38
      pages/_template/app/form/club-register.vue
  98. 13 31
      pages/_template/app/form/components/form-club-device.vue
  99. 3 3
      pages/_template/app/form/components/form-club-info.vue
  100. 2 6
      pages/_template/app/form/components/form-club-register.vue

BIN
assets/theme-images/normal/h5/banner-approve.png


BIN
assets/theme-images/normal/h5/banner-club.png


BIN
assets/theme-images/normal/h5/banner-device.png


BIN
assets/theme-images/normal/h5/banner-doc.png


BIN
assets/theme-images/normal/h5/banner-doctor.png


BIN
assets/theme-images/normal/h5/banner-feedback.png


BIN
assets/theme-images/normal/h5/banner-home.png


BIN
assets/theme-images/normal/h5/banner-record.png


BIN
assets/theme-images/normal/h5/banner-register.png


BIN
assets/theme-images/normal/h5/club-info-bg.png


BIN
assets/theme-images/normal/h5/entry-club-bg.png


BIN
assets/theme-images/normal/h5/entry-device-bg.png


BIN
assets/theme-images/normal/h5/entry-doctor-bg.png


BIN
assets/theme-images/normal/h5/h5-icon-mobile.png


BIN
assets/theme-images/normal/h5/icon-address.png


BIN
assets/theme-images/normal/h5/icon-auth-ren.png


BIN
assets/theme-images/normal/h5/icon-auth-seal-t.png


BIN
assets/theme-images/normal/h5/icon-auth-seal.png


BIN
assets/theme-images/normal/h5/icon-auth.png


BIN
assets/theme-images/normal/h5/icon-auth2.png


BIN
assets/theme-images/normal/h5/icon-avatar-v.png


BIN
assets/theme-images/normal/h5/icon-device-list.png


BIN
assets/theme-images/normal/h5/icon-feedback-submit.png


BIN
assets/theme-images/normal/h5/icon-home-approve.png


BIN
assets/theme-images/normal/h5/icon-home-doc.png


BIN
assets/theme-images/normal/h5/icon-home-edit.png


BIN
assets/theme-images/normal/h5/icon-home-feedback.png


BIN
assets/theme-images/normal/h5/icon-navigation.png


BIN
assets/theme-images/normal/h5/link-entry-doc-active.png


BIN
assets/theme-images/normal/h5/link-entry-feedback-active.png


BIN
assets/theme-images/normal/h5/link-entry-register-active.png


BIN
assets/theme-images/normal/h5/nav-entry-device-active.png


BIN
assets/theme-images/normal/h5/nav-entry-doctor-active.png


BIN
assets/theme-images/normal/pc/banner-approve.png


BIN
assets/theme-images/normal/pc/banner-club.png


BIN
assets/theme-images/normal/pc/banner-device.png


BIN
assets/theme-images/normal/pc/banner-doc.png


BIN
assets/theme-images/normal/pc/banner-doctor.png


BIN
assets/theme-images/normal/pc/banner-feedback.png


BIN
assets/theme-images/normal/pc/banner-home.png


BIN
assets/theme-images/normal/pc/banner-record.png


BIN
assets/theme-images/normal/pc/banner-register.png


BIN
assets/theme-images/normal/pc/club-info-bg.png


BIN
assets/theme-images/normal/pc/entry-club-bg.png


BIN
assets/theme-images/normal/pc/entry-device-bg.png


BIN
assets/theme-images/normal/pc/entry-doctor-bg.png


BIN
assets/theme-images/normal/pc/icon-address.png


BIN
assets/theme-images/normal/pc/icon-auth-ren.png


BIN
assets/theme-images/normal/pc/icon-auth-seal-t.png


BIN
assets/theme-images/normal/pc/icon-auth-seal.png


BIN
assets/theme-images/normal/pc/icon-auth.png


BIN
assets/theme-images/normal/pc/icon-auth2.png


BIN
assets/theme-images/normal/pc/icon-avatar-v.png


BIN
assets/theme-images/normal/pc/icon-center-item-auth-club.png


BIN
assets/theme-images/normal/pc/icon-center-item-device.png


BIN
assets/theme-images/normal/pc/icon-device-list.png


BIN
assets/theme-images/normal/pc/icon-feedback-submit.png


BIN
assets/theme-images/normal/pc/icon-mobile.png


BIN
assets/theme-images/normal/pc/icon-navigation.png


BIN
assets/theme-images/normal/pc/link-entry-doc-active.png


BIN
assets/theme-images/normal/pc/link-entry-doc.png


BIN
assets/theme-images/normal/pc/link-entry-feedback-active.png


BIN
assets/theme-images/normal/pc/link-entry-feedback.png


BIN
assets/theme-images/normal/pc/link-entry-register-active.png


BIN
assets/theme-images/normal/pc/link-entry-register.png


BIN
assets/theme-images/normal/pc/logo.png


BIN
assets/theme-images/normal/pc/nav-entry-device-active.png


BIN
assets/theme-images/normal/pc/nav-entry-device.png


BIN
assets/theme-images/normal/pc/nav-entry-doctor-active.png


BIN
assets/theme-images/normal/pc/nav-entry-doctor.png


+ 3 - 1
assets/themes/themeVariable.scss

@@ -1,7 +1,9 @@
 @import './variables/normal.scss';
 @import './variables/ross.scss';
+@import './variables/ph.scss';
 
 $themes: (
-  normal: $mormalTuple,
+  normal: $normalTuple,
+  ph: $phTuple,
   ross: $rossTuple,
 );

+ 1 - 47
assets/themes/variables/normal.scss

@@ -1,52 +1,6 @@
-$mormalTuple: (
+$normalTuple: (
   color: #bc1724,
   sub-color: #ffe6e8,
   hover-color: #960915,
   cover-color: linear-gradient(180deg, #ffe6e8 0%, rgba(255, 255, 255, 0) 100%),
-  // pc端
-  pc-banner-home: url(~/assets/theme-images/app/pc-banner-home.png),
-  pc-banner-approve: url(~/assets/theme-images/app/pc-banner-approve.png),
-  pc-banner-club: url(~/assets/theme-images/app/pc-banner-club.png),
-  pc-banner-device: url(~/assets/theme-images/app/pc-banner-device.png),
-  pc-banner-doctor: url(~/assets/theme-images/app/pc-banner-doctor.png),
-  pc-banner-feedback: url(~/assets/theme-images/app/pc-banner-feedback.png),
-  pc-banner-doc: url(~/assets/theme-images/app/pc-banner-doc.png),
-  pc-banner-register: url(~/assets/theme-images/app/pc-banner-home.png),
-  pc-banner-record-club: url(~/assets/theme-images/app/pc-banner-home.png),
-  pc-banner-record-device: url(~/assets/theme-images/app/pc-banner-home.png),
-  pc-entry-club-bg: url(~/assets/theme-images/app/pc-entry-club-bg.png),
-  pc-entry-device-bg: url(~/assets/theme-images/app/pc-entry-device-bg.png),
-  pc-entry-doctor-bg: url(~/assets/theme-images/app/pc-entry-doctor-bg.png),
-  pc-icon-home-approve: url(~/assets/theme-images/app/pc-icon-home-approve.png),
-  pc-icon-home-doc: url(~/assets/theme-images/app/pc-icon-home-doc.png),
-  pc-icon-home-edit: url(~/assets/theme-images/app/pc-icon-home-edit.png),
-  pc-icon-home-feedback:
-    url(~/assets/theme-images/app/pc-icon-home-feedback.png),
-  pc-icon-address: url(~/assets/theme-images/app/pc-icon-address.png),
-  pc-icon-mobile: url(~/assets/theme-images/app/pc-icon-mobile.png),
-  pc-icon-navigation: url(~/assets/theme-images/app/pc-icon-navigation.png),
-  pc-icon-feedback-submit: url(~/assets/theme-images/app/pc-icon-feedback-submit.png),
-  //  h5 端
-  h5-banner-home: url(~/assets/theme-images/app/h5-banner-home.png),
-  h5-banner-approve: url(~/assets/theme-images/app/h5-banner-approve.png),
-  h5-banner-club: url(~/assets/theme-images/app/h5-banner-club.png),
-  h5-banner-device: url(~/assets/theme-images/app/h5-banner-device.png),
-  h5-banner-doctor: url(~/assets/theme-images/app/h5-banner-doctor.png),
-  h5-banner-feedback: url(~/assets/theme-images/app/h5-banner-feedback.png),
-  h5-banner-doc: url(~/assets/theme-images/app/h5-banner-doc.png),
-  h5-banner-register: url(~/assets/theme-images/app/h5-banner-home.png),
-  h5-banner-record-club: url(~/assets/theme-images/app/pc-banner-home.png),
-  h5-banner-record-device: url(~/assets/theme-images/app/pc-banner-home.png),
-  h5-entry-club-bg: url(~/assets/theme-images/app/h5-entry-club-bg.png),
-  h5-entry-device-bg: url(~/assets/theme-images/app/h5-entry-device-bg.png),
-  h5-entry-doctor-bg: url(~/assets/theme-images/app/h5-entry-doctor-bg.png),
-  h5-icon-home-approve: url(~/assets/theme-images/app/h5-icon-home-approve.png),
-  h5-icon-home-doc: url(~/assets/theme-images/app/h5-icon-home-doc.png),
-  h5-icon-home-edit: url(~/assets/theme-images/app/h5-icon-home-edit.png),
-  h5-icon-home-feedback:
-    url(~/assets/theme-images/app/h5-icon-home-feedback.png),
-  h5-icon-address: url(~/assets/theme-images/app/h5-icon-address.png),
-  h5-icon-mobile: url(~/assets/theme-images/app/h5-icon-mobile.png),
-  h5-icon-navigation: url(~/assets/theme-images/app/h5-icon-navigation.png),
-  h5-icon-feedback-submit: url(~/assets/theme-images/app/h5-icon-feedback-submit.png),
 );

+ 52 - 0
assets/themes/variables/ph.scss

@@ -0,0 +1,52 @@
+$phTuple: (
+  color: #bc1724,
+  sub-color: #ffe6e8,
+  hover-color: #960915,
+  cover-color: linear-gradient(180deg, #ffe6e8 0%, rgba(255, 255, 255, 0) 100%),
+  // pc端
+  pc-banner-home: url(~/assets/theme-images/app/pc-banner-home.png),
+  pc-banner-approve: url(~/assets/theme-images/app/pc-banner-approve.png),
+  pc-banner-club: url(~/assets/theme-images/app/pc-banner-club.png),
+  pc-banner-device: url(~/assets/theme-images/app/pc-banner-device.png),
+  pc-banner-doctor: url(~/assets/theme-images/app/pc-banner-doctor.png),
+  pc-banner-feedback: url(~/assets/theme-images/app/pc-banner-feedback.png),
+  pc-banner-doc: url(~/assets/theme-images/app/pc-banner-doc.png),
+  pc-banner-register: url(~/assets/theme-images/app/pc-banner-home.png),
+  pc-banner-record-club: url(~/assets/theme-images/app/pc-banner-home.png),
+  pc-banner-record-device: url(~/assets/theme-images/app/pc-banner-home.png),
+  pc-entry-club-bg: url(~/assets/theme-images/app/pc-entry-club-bg.png),
+  pc-entry-device-bg: url(~/assets/theme-images/app/pc-entry-device-bg.png),
+  pc-entry-doctor-bg: url(~/assets/theme-images/app/pc-entry-doctor-bg.png),
+  pc-icon-home-approve: url(~/assets/theme-images/app/pc-icon-home-approve.png),
+  pc-icon-home-doc: url(~/assets/theme-images/app/pc-icon-home-doc.png),
+  pc-icon-home-edit: url(~/assets/theme-images/app/pc-icon-home-edit.png),
+  pc-icon-home-feedback:
+    url(~/assets/theme-images/app/pc-icon-home-feedback.png),
+  pc-icon-address: url(~/assets/theme-images/app/pc-icon-address.png),
+  pc-icon-mobile: url(~/assets/theme-images/app/pc-icon-mobile.png),
+  pc-icon-navigation: url(~/assets/theme-images/app/pc-icon-navigation.png),
+  pc-icon-feedback-submit: url(~/assets/theme-images/app/pc-icon-feedback-submit.png),
+  //  h5 端
+  h5-banner-home: url(~/assets/theme-images/app/h5-banner-home.png),
+  h5-banner-approve: url(~/assets/theme-images/app/h5-banner-approve.png),
+  h5-banner-club: url(~/assets/theme-images/app/h5-banner-club.png),
+  h5-banner-device: url(~/assets/theme-images/app/h5-banner-device.png),
+  h5-banner-doctor: url(~/assets/theme-images/app/h5-banner-doctor.png),
+  h5-banner-feedback: url(~/assets/theme-images/app/h5-banner-feedback.png),
+  h5-banner-doc: url(~/assets/theme-images/app/h5-banner-doc.png),
+  h5-banner-register: url(~/assets/theme-images/app/h5-banner-home.png),
+  h5-banner-record-club: url(~/assets/theme-images/app/pc-banner-home.png),
+  h5-banner-record-device: url(~/assets/theme-images/app/pc-banner-home.png),
+  h5-entry-club-bg: url(~/assets/theme-images/app/h5-entry-club-bg.png),
+  h5-entry-device-bg: url(~/assets/theme-images/app/h5-entry-device-bg.png),
+  h5-entry-doctor-bg: url(~/assets/theme-images/app/h5-entry-doctor-bg.png),
+  h5-icon-home-approve: url(~/assets/theme-images/app/h5-icon-home-approve.png),
+  h5-icon-home-doc: url(~/assets/theme-images/app/h5-icon-home-doc.png),
+  h5-icon-home-edit: url(~/assets/theme-images/app/h5-icon-home-edit.png),
+  h5-icon-home-feedback:
+    url(~/assets/theme-images/app/h5-icon-home-feedback.png),
+  h5-icon-address: url(~/assets/theme-images/app/h5-icon-address.png),
+  h5-icon-mobile: url(~/assets/theme-images/app/h5-icon-mobile.png),
+  h5-icon-navigation: url(~/assets/theme-images/app/h5-icon-navigation.png),
+  h5-icon-feedback-submit: url(~/assets/theme-images/app/h5-icon-feedback-submit.png),
+);

+ 127 - 0
components/SimpleCenterCover/index.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="area">
+    <ul class="circles">
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+      <li></li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style scoped lang="scss">
+.area {
+  background: #bc1724;
+  background: -webkit-linear-gradient(to left, #d82231, #bc1724);
+  width: 100%;
+  height: 100%;
+}
+
+.circles {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+
+  li {
+    position: absolute;
+    display: block;
+    list-style: none;
+    width: 20px;
+    height: 20px;
+    background: rgba(255, 255, 255, 0.2);
+    animation: animate 25s linear infinite;
+    bottom: -150px;
+  }
+  li:nth-child(1) {
+    left: 25%;
+    width: 80px;
+    height: 80px;
+    animation-delay: 0s;
+  }
+  li:nth-child(2) {
+    left: 10%;
+    width: 20px;
+    height: 20px;
+    animation-delay: 2s;
+    animation-duration: 12s;
+  }
+  li:nth-child(3) {
+    left: 70%;
+    width: 20px;
+    height: 20px;
+    animation-delay: 4s;
+  }
+  li:nth-child(4) {
+    left: 40%;
+    width: 60px;
+    height: 60px;
+    animation-delay: 0s;
+    animation-duration: 18s;
+  }
+  li:nth-child(5) {
+    left: 65%;
+    width: 20px;
+    height: 20px;
+    animation-delay: 0s;
+  }
+  li:nth-child(6) {
+    left: 75%;
+    width: 110px;
+    height: 110px;
+    animation-delay: 3s;
+  }
+  li:nth-child(7) {
+    left: 35%;
+    width: 150px;
+    height: 150px;
+    animation-delay: 7s;
+  }
+  li:nth-child(8) {
+    left: 50%;
+    width: 25px;
+    height: 25px;
+    animation-delay: 15s;
+    animation-duration: 45s;
+  }
+  li:nth-child(9) {
+    left: 20%;
+    width: 15px;
+    height: 15px;
+    animation-delay: 2s;
+    animation-duration: 35s;
+  }
+  li:nth-child(10) {
+    left: 85%;
+    width: 150px;
+    height: 150px;
+    animation-delay: 0s;
+    animation-duration: 11s;
+  }
+}
+
+@keyframes animate {
+  0% {
+    transform: translateY(0) rotate(0deg);
+    opacity: 1;
+    border-radius: 0;
+  }
+  100% {
+    transform: translateY(-1000px) rotate(720deg);
+    opacity: 0;
+    border-radius: 50%;
+  }
+}
+</style>

+ 4 - 0
configs/mode-map.js

@@ -8,4 +8,8 @@ export default [
     authUserId: 12,
     prefix: 'ross',
   },
+  {
+    authUserId: 4,
+    prefix: 'ph',
+  },
 ]

+ 627 - 0
layouts/app-normal.vue

@@ -0,0 +1,627 @@
+<template>
+  <div :class="themeClass" v-if="isMounted">
+    <div class="layout" :style="{ paddingTop: showHeader ? '' : 0 }">
+      <div class="header" v-show="showHeader">
+        <div class="navbar flex justify-between items-center">
+          <div class="logo flex items-center" @click="backHome">
+            <img src="~/assets/theme-images/normal/pc/logo.png" />
+            <span>认证通</span>
+          </div>
+          <div class="flex justify-center items-center">
+            <div class="nav" v-if="isPc">
+              <template v-for="item in list">
+                <div class="link" :key="item.id" @click="onJumpTo(item)">
+                  <span class="icon" :class="item.icon"></span>
+                  <span class="text">{{ item.name }}</span>
+                </div>
+              </template>
+            </div>
+            <div class="user-info">
+              <template v-if="accessToken">
+                <div class="user-center">
+                  <span class="icon el-icon-user-solid"></span>
+                  <span class="icon el-icon-arrow-down"></span>
+                  <div class="drop-down">
+                    <ul class="nav">
+                      <li @click.stop="onUserCenter">个人中心</li>
+                      <li @click.stop="logout">退出登录</li>
+                    </ul>
+                  </div>
+                </div>
+              </template>
+              <template v-else>
+                <div class="login-btn" @click="onLogin">登录</div>
+              </template>
+            </div>
+            <span class="collapse-icon" @click="drawer = true"></span>
+          </div>
+        </div>
+      </div>
+      <div class="content">
+        <nuxt />
+      </div>
+      <div class="footer flex justify-center items-center" v-show="showFooter">
+        - {{ supplierInfo.shopName }} | 由采美网提供技术支持 -
+      </div>
+      <SimpleLogin :type="formType" @click="onLoginClick"></SimpleLogin>
+    </div>
+
+    <template v-if="!isPc">
+      <el-drawer :visible.sync="drawer" size="63%">
+        <div class="nav">
+          <template v-for="item in list">
+            <div class="link" :key="item.id" @click="onJumpTo(item)">
+              <span class="icon" :class="item.icon"></span>
+              <span class="text">{{ item.name }}</span>
+            </div>
+          </template>
+        </div>
+      </el-drawer>
+    </template>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  computed: {
+    ...mapGetters([
+      'userInfo',
+      'accessToken',
+      'authUserId',
+      'appId',
+      'routePrefix',
+      'themeName',
+      'isPc',
+      'showHeader',
+      'showFooter',
+      'supplierInfo',
+    ]),
+    themeClass() {
+      return `theme-${this.themeName}`
+    },
+  },
+  head() {
+    return {
+      meta: [
+        {
+          name: 'viewport',
+          content:
+            'width=device-width,initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0, user-scalable=no',
+        },
+      ],
+    }
+  },
+  data() {
+    return {
+      formType: 'login',
+      drawer: false,
+      isMounted: false,
+      list: [
+        {
+          id: 1,
+          name: '授权申请',
+          path: '/form/club-register',
+          icon: 'icon-register',
+        },
+        {
+          id: 2,
+          name: '产品资料',
+          path: '/docs/0',
+          icon: 'icon-doc',
+        },
+        {
+          id: 3,
+          name: '意见反馈',
+          path: '/feedback',
+          icon: 'icon-feedback',
+        },
+      ],
+    }
+  },
+  mounted() {
+    this.responseWidth()
+    this.initPageData()
+    // this.checkAccountType()
+  },
+  beforeDestroy() {
+    window.removeEventListener('resize', () => {})
+    this.refreshCacheData()
+  },
+  methods: {
+    // 跳转
+    onJumpTo(item) {
+      this.drawer = false
+      const hasLogin = this.$store.getters.accessToken
+      // 保存登录重定向路由
+      this.$setStorage(
+        this.routePrefix,
+        'login_redicret',
+        this.routePrefix + item.path
+      )
+      if (item.id > 2 && !hasLogin) {
+        this.$toast({ message: '请先登录', duration: 1000 })
+        this.formType = 'login'
+        this.$store.commit('app/SHOW_LOGIN')
+        return
+      }
+
+      if (item.id === 0) {
+        const url = this.routePrefix + item.path
+        this.$router.push(url)
+      } else {
+        const url = this.routePrefix + item.path
+        this.$router.push(url)
+      }
+    },
+
+    // 点击登录
+    onLoginClick(type) {
+      this.formType = type
+    },
+
+    // 初始化数据页面公共数据
+    initPageData() {
+      this.$store.commit('app/SET_PAGE_THEME', 'normal')
+      // 获取用户信息
+      let userInfo = this.$getStorage(this.routePrefix, 'userInfo')
+      if (userInfo && userInfo.authUserId === this.authUserId) {
+        this.$store.commit('user/SET_USER_INFO', userInfo)
+      }
+      this.isMounted = true
+    },
+
+    // 校验公众号类型
+    async checkAccountType() {
+      try {
+        // 1订阅号,2服务号
+        if (!this.appId) return
+        const res = await this.$http.api.checkAccountType({ appId: this.appId })
+        this.$store.commit('supplier/SET_ACCOUNT_TYPE', res.data)
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
+    // 登录
+    onLogin() {
+      this.formType = 'login'
+      this.$store.commit('app/SHOW_LOGIN')
+    },
+
+    // 注册
+    onRegister() {
+      this.formType = 'register'
+      this.$store.commit('app/SHOW_LOGIN')
+    },
+
+    // 退出登录
+    logout() {
+      this.$store.dispatch('user/logout')
+      this.$removeStorage(this.routePrefix, 'userInfo')
+      this.backHome()
+    },
+
+    // 回到首页
+    backHome() {
+      // if (this.$route.path === this.routePrefix) return
+      // this.$router.replace(this.routePrefix)
+      window.location.href = window.location.origin + this.routePrefix
+    },
+
+    // 个人中心
+    onUserCenter() {
+      // const path = `${this.routePrefix}/center`
+      window.location.href =
+        window.location.origin + `${this.routePrefix}/center`
+    },
+
+    // 响应页面宽度变化
+    responseWidth() {
+      this.$store.commit('app/SET_SCREEN', window.innerWidth)
+      window.addEventListener('resize', (e) => {
+        this.$store.commit('app/SET_SCREEN', e.target.innerWidth)
+      })
+    },
+
+    // 数据初始化刷新浏览器
+    refreshCacheData() {
+      this.$removeStorage(this.routePrefix, 'club_list_data')
+    },
+  },
+}
+</script>
+
+<style scoped lang="scss">
+@keyframes slide-down {
+  0% {
+    top: 48px;
+    z-index: 9;
+    opacity: 0;
+  }
+  100% {
+    top: 32px;
+    opacity: 1;
+  }
+}
+
+// PC端
+@media screen and (min-width: 768px) {
+  .layout {
+    padding-top: 80px;
+    user-select: none;
+
+    .header {
+      position: fixed;
+      top: 0;
+      left: 0;
+      z-index: 999;
+      width: 100%;
+      height: 80px;
+      box-sizing: border-box;
+      background: linear-gradient(90deg, #101010 0%, #404040 100%);
+
+      .navbar {
+        width: 1200px;
+        margin: 0 auto;
+        height: 100%;
+      }
+
+      .logo {
+        cursor: pointer;
+        img {
+          display: block;
+          width: 44px;
+          height: 44px;
+
+          &.ross {
+            width: 85px;
+            height: 27px;
+            margin-right: 15px;
+            transform: translateY(-2px);
+          }
+        }
+        span {
+          font-size: 24px;
+          color: #fff;
+        }
+      }
+
+      .nav {
+        .link {
+          display: inline;
+          margin-left: 32px;
+          cursor: pointer;
+
+          &:hover {
+            .text {
+              @include themify($themes) {
+                color: themed('color');
+              }
+            }
+
+            .icon {
+              &.icon-register {
+                background-image: url(~assets/theme-images/normal/pc/link-entry-register-active.png);
+              }
+              &.icon-doc {
+                background-image: url(~assets/theme-images/normal/pc/link-entry-doc-active.png);
+              }
+              &.icon-feedback {
+                background-image: url(~assets/theme-images/normal/pc/link-entry-feedback-active.png);
+              }
+            }
+          }
+        }
+
+        .icon {
+          width: 20px;
+          height: 20px;
+          display: inline-block;
+          vertical-align: -4px;
+          margin-right: 4px;
+
+          background-size: 20px;
+          background-repeat: no-repeat;
+          background-position: center;
+
+          &.icon-register {
+            background-image: url(~assets/theme-images/normal/pc/link-entry-register.png);
+          }
+          &.icon-doc {
+            background-image: url(~assets/theme-images/normal/pc/link-entry-doc.png);
+          }
+          &.icon-feedback {
+            background-image: url(~assets/theme-images/normal/pc/link-entry-feedback.png);
+          }
+        }
+        .text {
+          font-size: 16px;
+          color: #fff;
+        }
+      }
+
+      .user-info {
+        color: #fff;
+        font-size: 16px;
+        margin-left: 48px;
+
+        .login-btn {
+          width: 80px;
+          height: 34px;
+          color: #fff;
+          background: rgba(255, 255, 255, 0.39);
+          font-size: 14px;
+          text-align: center;
+          line-height: 34px;
+          cursor: pointer;
+        }
+        .user-center {
+          position: relative;
+
+          .icon {
+            width: 32px;
+            height: 32px;
+            text-align: center;
+            line-height: 32px;
+
+            &.el-icon-user-solid {
+              font-size: 24px;
+              cursor: pointer;
+            }
+
+            &.el-icon-arrow-down {
+              font-size: 22px;
+              transition: all 0.2s;
+            }
+          }
+
+          &:hover {
+            .drop-down {
+              display: block;
+              animation: slide-down 0.4s linear forwards;
+            }
+
+            .el-icon-arrow-down {
+              transform: rotateZ(180deg);
+            }
+          }
+
+          .drop-down {
+            display: none;
+            opacity: 0;
+            // z-index: -1;
+            right: 0;
+
+            position: absolute;
+            background: transparent;
+            box-sizing: border-box;
+            padding-top: 24px;
+
+            .nav {
+              width: 118px;
+              padding: 8px 0;
+              background: #fff;
+              box-shadow: 0px 6px 16px rgba(40, 40, 40, 0.1);
+              border-radius: 4px;
+              li {
+                font-size: 14px;
+                color: #282828;
+                text-align: center;
+                line-height: 40px;
+                transition: all 0.4s;
+                cursor: pointer;
+
+                &:hover {
+                  @include themify($themes) {
+                    color: themed('color');
+                  }
+                }
+              }
+            }
+          }
+        }
+
+        .login,
+        .register,
+        .logout {
+          cursor: pointer;
+
+          &:hover {
+            @include themify($themes) {
+              color: themed('color');
+            }
+          }
+        }
+      }
+    }
+    .content {
+      min-height: calc(100vh - 80px - 80px);
+      background-color: #f7f7f7;
+      overflow: hidden;
+    }
+
+    .footer {
+      height: 80px;
+      background-color: #2c3038;
+      color: #fff;
+      font-size: 14px;
+    }
+  }
+}
+
+// 移动端
+@media screen and (max-width: 768px) {
+  .layout {
+    padding-top: 12.8vw;
+    .header {
+      position: fixed;
+      top: 0;
+      left: 0;
+      z-index: 999;
+      width: 100%;
+      padding: 0 4vw;
+      height: 12.8vw;
+      box-sizing: border-box;
+      background: linear-gradient(90deg, #101010 0%, #404040 100%);
+
+      .navbar {
+        height: 100%;
+      }
+
+      .logo {
+        img {
+          display: block;
+          width: 8vw;
+          height: 8vw;
+
+          &.ross {
+            width: 12.2vw;
+            height: 3.9vw;
+            margin-right: 1.9vw;
+            transform: translateY(-0.6vw);
+          }
+        }
+        span {
+          font-size: 4vw;
+          color: #fff;
+        }
+      }
+
+      .user-info {
+        color: #fff;
+        font-size: 3vw;
+
+        .logout {
+          margin: 0 1.6vw;
+        }
+
+        .login-btn {
+          width: 13.4vw;
+          height: 6.4vw;
+          color: #fff;
+          background: rgba(255, 255, 255, 0.39);
+          font-size: 3.4vw;
+          text-align: center;
+          line-height: 6.4vw;
+          margin-right: 2.4vw;
+        }
+
+        .user-center {
+          position: relative;
+
+          .icon {
+            width: 5.6vw;
+            height: 5.6vw;
+            text-align: center;
+            line-height: 5.6vw;
+            margin-right: 4vw;
+
+            &.el-icon-user-solid {
+              font-size: 24px;
+              cursor: pointer;
+            }
+
+            &.el-icon-arrow-down {
+              display: none;
+            }
+          }
+
+          &:hover {
+            .drop-down {
+              display: block;
+              animation: slide-down 0.4s linear forwards;
+            }
+
+            .el-icon-arrow-down {
+              transform: rotateZ(180deg);
+            }
+          }
+
+          .drop-down {
+            display: none;
+            opacity: 0;
+            right: 0;
+
+            position: absolute;
+            background: transparent;
+            box-sizing: border-box;
+            padding-top: 1.2vw;
+
+            .nav {
+              width: 26vw;
+              padding: 1vw 0;
+              background: #fff;
+              box-shadow: 0px 0.6vw 20vw rgba(40, 40, 40, 0.1);
+              border-radius: 0.4vw;
+              li {
+                font-size: 3.4vw;
+                color: #282828;
+                text-align: center;
+                line-height: 8.6vw;
+                transition: all 0.4s;
+              }
+            }
+          }
+        }
+      }
+
+      .collapse-icon {
+        display: block;
+        width: 5.6vw;
+        height: 5.6vw;
+        background: url(~assets/theme-images/common/h5-icon-collapse.png)
+          no-repeat center;
+        background-size: 5.6vw;
+      }
+    }
+    .content {
+      min-height: calc(100vh - 12.8vw - 12.4vw);
+    }
+
+    .footer {
+      height: 12.4vw;
+      background-color: #2c3038;
+      color: #fff;
+      font-size: 3vw;
+    }
+  }
+
+  .nav {
+    width: 63vw;
+    box-sizing: border-box;
+    padding: 0 6.4vw;
+    .link {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      border-bottom: 0.1vw solid #c2c2c2;
+      padding-bottom: 3vw;
+      padding-top: 6vw;
+      .icon {
+        width: 5.6vw;
+        height: 5.6vw;
+        vertical-align: -1.2vw;
+        margin-right: 2.4vw;
+        background-size: 5.6vw;
+        background-repeat: no-repeat;
+        background-position: center;
+
+        &.icon-register {
+          background-image: url(~assets/theme-images/normal/h5/link-entry-register-active.png);
+        }
+        &.icon-doc {
+          background-image: url(~assets/theme-images/normal/h5/link-entry-doc-active.png);
+        }
+        &.icon-feedback {
+          background-image: url(~assets/theme-images/normal/h5/link-entry-feedback-active.png);
+        }
+      }
+      .text {
+        font-size: 3.4vw;
+        color: #282828;
+      }
+    }
+  }
+}
+</style>

+ 1 - 1
layouts/app.vue → layouts/app-ph.vue

@@ -118,7 +118,7 @@ export default {
 
     // 初始化数据页面公共数据
     initPageData() {
-      // this.$store.commit('app/SET_PAGE_THEME', 'app')
+      this.$store.commit('app/SET_PAGE_THEME', 'ph')
       // 获取用户信息
       let userInfo = this.$getStorage(this.routePrefix, 'userInfo')
       if (userInfo && userInfo.authUserId === this.authUserId) {

+ 2 - 2
middleware/intercept.js

@@ -67,7 +67,7 @@ async function initTemplateEntry(context) {
       return
     }
 
-    if (dev !== 'development') {
+    if (dev !== 'development' || true) {
       // 默认模板
       if (prefix === 'app') {
         if (isFixedTemplate(authUserId)) {
@@ -77,7 +77,7 @@ async function initTemplateEntry(context) {
       }
 
       // 非默认模板
-      if (['ross', 'ldm'].includes(prefix)) {
+      if (['ross', 'ldm', 'ph'].includes(prefix)) {
         // 供应商为指定模板
         if (!isMatchTemplate(authUserId, prefix)) {
           showError(error, { statusCode: 500, message: '模板与供应商不匹配' })

+ 0 - 1
mixins/operatDoctorDetail.js

@@ -1,5 +1,4 @@
 export default {
-  layout: 'app',
   data() {
     return {
       doctorId: '',

+ 317 - 107
pages/_template/app/approve/club/detail.vue

@@ -4,38 +4,48 @@
     <div class="page-top">
       <div class="swiper">
         <SimpleSwiper :imageList="clubInfo.bannerList"></SimpleSwiper>
+        <img
+          class="auth-card"
+          :src="authCardImage"
+          @click="onShowAuthCard"
+          v-if="!showAuthCard"
+        />
       </div>
     </div>
     <div class="page-content">
-      <!-- <div class="auth">
-        <div class="auth-icon"></div>
-        <div class="auth-info">
-          <span class="font-bold">ROS'S</span>
-          <span>授予</span>
-          <span>{{ clubInfo.authParty }}</span>
-          <span>正品拥有</span>
-        </div>
-      </div> -->
-      <div class="club-info">
-        <div class="section flex justify-between items-center">
-          <div class="info">
-            <div class="name" v-text="clubInfo.authParty"></div>
-            <div class="mobile" @click="callMobile(clubInfo.mobile)">
-              {{ clubInfo.mobile | formatEmpty }}
+      <div class="bg-container">
+        <!-- 机构信息 -->
+        <div class="club-info">
+          <div class="section flex justify-between items-center">
+            <div class="info">
+              <div class="name" v-text="clubInfo.authParty"></div>
+              <div class="mobile" @click="callMobile(clubInfo.mobile)">
+                {{ clubInfo.mobile | formatEmpty }}
+              </div>
+              <div class="address" v-text="address"></div>
             </div>
-            <div class="address" v-text="address"></div>
+            <div class="logo"><img :src="clubInfo.logo" /></div>
+          </div>
+          <div class="section flex justify-between items-center mt-6">
+            <div class="navigation" @click="onMapNav">导航</div>
+            <div
+              class="distance"
+              v-if="clubInfo.distance && clubInfo.distance < 99999"
+              v-text="'距你' + clubInfo.distance + 'km'"
+            ></div>
           </div>
-          <div class="logo"><img :src="clubInfo.logo" /></div>
         </div>
-        <div class="section flex justify-between items-center mt-6">
-          <div class="navigation" @click="onMapNav">导航</div>
-          <div
-            class="distance"
-            v-if="clubInfo.distance && clubInfo.distance < 99999"
-            v-text="'距你' + clubInfo.distance + 'km'"
-          ></div>
+        <!-- 机构授权信息 -->
+        <div class="auth">
+          <div class="auth-icon"></div>
+          <div class="auth-info">
+            <span>该机构由</span>
+            <span class="font-bold">{{ supplierInfo.shopName }}</span>
+            <span class="font-bold">官方授权</span>
+          </div>
         </div>
       </div>
+      <!-- 分割 -->
       <div class="divider"></div>
       <div class="device-list">
         <div class="title">已认证设备</div>
@@ -60,19 +70,47 @@
       ></SimpleEmpty>
     </div>
 
-    <SimpleMapNav ref="mapNav" @click="navigation"></SimpleMapNav>
+    <SimpleMapNav
+      ref="mapNav"
+      @click="navigation"
+      color="#BC1724"
+    ></SimpleMapNav>
+
+    <!-- 授权牌弹窗 -->
+    <div class="mask" v-if="showAuthCard" @click="onHideAuthCard"></div>
+    <transition
+      enter-active-class="animate__zoomIn"
+      leave-active-class="animate__zoomOut"
+    >
+      <div class="auth-card-content animate__animated" v-if="showAuthCard">
+        <div class="auth-card-popup">
+          <span class="el-icon-circle-close" @click="onHideAuthCard"></span>
+          <img :src="authCardImage" />
+        </div>
+      </div>
+    </transition>
   </div>
 </template>
 
 <script>
 import clubDetailMixin from '@/mixins/clubDetail'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [clubDetailMixin],
 }
 </script>
 
 <style scoped lang="scss">
+.mask {
+  width: 100vw;
+  height: 100vh;
+  position: fixed;
+  left: 0;
+  top: 0;
+  z-index: 8;
+  background: rgba(0, 0, 0, 0.5);
+}
+
 // pc 端
 @media screen and (min-width: 768px) {
   .page {
@@ -88,6 +126,37 @@ export default {
     padding-right: 0;
   }
 
+  .auth-card-content {
+    width: 100vw;
+    height: 100vh;
+    position: fixed;
+    left: 0;
+    top: 0;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 9;
+    .auth-card-popup {
+      position: relative;
+      width: 622px;
+
+      img {
+        display: block;
+        width: 100%;
+        height: auto;
+      }
+
+      .el-icon-circle-close {
+        position: absolute;
+        top: -50px;
+        right: 0;
+        font-size: 32px;
+        color: #fff;
+        cursor: pointer;
+      }
+    }
+  }
+
   .page-title {
     position: absolute;
     font-size: 24px;
@@ -97,7 +166,9 @@ export default {
   }
 
   .page-top {
+    margin-right: 24px;
     .swiper {
+      position: relative;
       width: 580px;
       height: 580px;
       background: #f7f7f7;
@@ -107,6 +178,17 @@ export default {
           height: 580px;
         }
       }
+
+      .auth-card {
+        position: absolute;
+        width: auto;
+        height: 110px;
+        display: block;
+        bottom: 24px;
+        left: 24px;
+        z-index: 2;
+        cursor: pointer;
+      }
     }
   }
 
@@ -114,18 +196,38 @@ export default {
     width: 580px;
     overflow-y: auto;
 
+    &::-webkit-scrollbar {
+      width: 8px;
+      // background-color: #eeeeee;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      border-radius: 4px;
+      background-color: #eeeeee;
+    }
+
+    .bg-container {
+      background: url(~assets/theme-images/normal/pc/club-info-bg.png) center
+        no-repeat;
+      background-size: 100%;
+      box-sizing: border-box;
+      background-position-y: 20px;
+      background-color: #e03f4c;
+      padding-bottom: 24px;
+    }
+
     .auth {
-      width: 100%;
-      min-height: 114px;
-      @include themify($themes) {
-        background: themed('color');
-      }
+      width: 524px;
       box-sizing: border-box;
-      padding: 24px;
+      background: #fef5e8;
+      margin: 0 auto;
+      margin-top: 8px;
+      padding: 12px 16px;
+      border-radius: 2px;
 
       .auth-icon {
         height: 28px;
-        background: url(~assets/theme-images/ross/pc-icon-auth.png) no-repeat
+        background: url(~assets/theme-images/normal/pc/icon-auth.png) no-repeat
           left center;
         background-size: auto 28px;
       }
@@ -135,59 +237,60 @@ export default {
         margin-top: 10px;
         span {
           font-size: 20px;
-          color: #fff;
+          line-height: 1.6;
+          color: #bc1724;
+
+          &.font-bold {
+            font-weight: bold;
+          }
         }
       }
     }
 
     .club-info {
       padding: 32px 24px;
-      @include themify($themes) {
-        background: themed('cover-color');
-      }
+      width: 564px;
+      min-height: 264px;
 
       .info {
-        width: 320px;
+        width: 360px;
         .name {
           font-size: 24px;
-          color: #101010;
+          color: #fff;
           font-weight: bold;
           margin-bottom: 34px;
         }
         .mobile,
         .address {
           position: relative;
-          padding-left: 24px;
+          padding-left: 28px;
           margin-top: 16px;
           line-height: 24px;
           font-size: 16px;
-          color: #404040;
+          color: #fff;
 
           &::after {
             content: '';
             display: block;
-            width: 16px;
-            height: 16px;
+            width: 24px;
+            height: 24px;
             position: absolute;
             left: 0;
-            top: 4px;
-            background-size: 16px;
+            top: 0;
+            background-size: 20px;
             background-repeat: no-repeat;
+            background-position: center;
           }
         }
         .mobile {
           cursor: pointer;
           &::after {
-            @include themify($themes) {
-              background-image: themed('pc-icon-mobile');
-            }
+            background-image: url(~assets/theme-images/normal/pc/icon-mobile.png);
           }
         }
         .address {
           &::after {
-            @include themify($themes) {
-              background-image: themed('h5-icon-address');
-            }
+            background-image: url(~assets/theme-images/normal/pc/icon-address.png);
           }
         }
       }
@@ -198,6 +301,8 @@ export default {
         height: 114px;
         border-radius: 50% 50% 0 50%;
         overflow: hidden;
+        background: #fff;
+        display: flex;
 
         &::after {
           position: absolute;
@@ -207,7 +312,7 @@ export default {
           display: block;
           width: 23px;
           height: 23px;
-          background: url(~assets/theme-images/common/pc-icon-avatar-v.png)
+          background: url(~assets/theme-images/normal/pc/icon-avatar-v.png)
             no-repeat center;
           background-size: 23px;
         }
@@ -221,11 +326,9 @@ export default {
         border-radius: 4px;
 
         font-size: 16px;
-        @include themify($themes) {
-          color: themed('color');
-          border: 1px solid themed('color');
-          background-color: themed('sub-color');
-        }
+        color: #bc1724;
+        border: 1px solid #fff;
+        background-color: #fff;
         cursor: pointer;
 
         &::after {
@@ -234,25 +337,39 @@ export default {
           width: 16px;
           height: 16px;
           margin-left: 4px;
-          @include themify($themes) {
-            background: themed('pc-icon-navigation') no-repeat center;
-          }
+          background: url(~assets/theme-images/normal/pc/icon-navigation.png)
+            no-repeat center;
           background-size: 16px;
         }
       }
       .distance {
         font-size: 14px;
-        color: #404040;
+        color: #fff;
       }
     }
 
     .device-list {
       .title {
-        padding: 16px;
+        position: relative;
         font-size: 20px;
         font-weight: bold;
-        color: #404040;
-        background-color: #f3f5f6;
+        color: #282828;
+        line-height: 30px;
+        padding-left: 32px;
+        margin-top: 46px;
+        margin-bottom: 24px;
+
+        &::before {
+          content: '';
+          display: block;
+          width: 30px;
+          height: 30px;
+          background: url(~assets/theme-images/normal/pc/icon-device-list.png)
+            no-repeat center;
+          position: absolute;
+          left: 0;
+          top: 0;
+        }
       }
 
       .list {
@@ -260,15 +377,23 @@ export default {
       }
 
       .device {
-        padding: 16px 0;
-        border-bottom: 1px solid #d8d8d8;
+        padding: 20px 16px;
+        box-sizing: border-box;
+        background: #f3f5f6;
+        margin-top: 16px;
+
+        &:first-child {
+          margin-top: 0;
+        }
+
         .info {
+          width: 80%;
           .name {
             font-size: 18px;
-            color: #101010;
+            color: #282828;
           }
           .code {
-            margin-top: 16px;
+            margin-top: 12px;
             font-size: 14px;
             color: #666;
           }
@@ -283,9 +408,7 @@ export default {
           font-size: 14px;
           color: #ffffff;
           cursor: pointer;
-          @include themify($themes) {
-            background: themed('color');
-          }
+          color: #bc1724;
         }
       }
     }
@@ -298,8 +421,40 @@ export default {
     display: none;
   }
 
+  .auth-card-content {
+    width: 100vw;
+    height: 100vh;
+    position: fixed;
+    left: 0;
+    top: 0;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 9;
+    .auth-card-popup {
+      position: relative;
+      width: 86vw;
+
+      img {
+        display: block;
+        width: 100%;
+        height: auto;
+      }
+
+      .el-icon-circle-close {
+        position: absolute;
+        top: -8vw;
+        right: 0;
+        font-size: 7vw;
+        color: #fff;
+        cursor: pointer;
+      }
+    }
+  }
+
   .page-top {
     .swiper {
+      position: relative;
       height: 100vw;
 
       background: #f7f7f7;
@@ -308,25 +463,70 @@ export default {
           height: 100vw;
         }
       }
+
+      .auth-card {
+        position: absolute;
+        width: auto;
+        height: 20.6vw;
+        display: block;
+        bottom: 4vw;
+        left: 4vw;
+        z-index: 2;
+      }
     }
   }
 
   .page-content {
-    .divider {
-      height: 3.2vw;
-      background-color: #f7f7f7;
+    .bg-container {
+      background: url(~assets/theme-images/normal/h5/club-info-bg.png) center
+        no-repeat;
+      background-size: 100vw;
+      box-sizing: border-box;
+      background-position-y: 4vw;
+      background-color: #e03f4c;
+      padding-bottom: 5vw;
+    }
+
+    .auth {
+      width: 92vw;
+      box-sizing: border-box;
+      background: #fef5e8;
+      margin: 0 auto;
+      margin-top: 3.2vw;
+      padding: 4vw 3.5vw;
+      border-radius: 0.8vw;
+
+      .auth-icon {
+        height: 6.2vw;
+        background: url(~assets/theme-images/normal/h5/icon-auth.png) no-repeat
+          left center;
+        background-size: auto 6.2vw;
+      }
+
+      .auth-info {
+        font-size: 0;
+        margin-top: 2.2vw;
+        span {
+          font-size: 3.6vw;
+          line-height: 5.8vw;
+          color: #bc1724;
+
+          &.font-bold {
+            font-weight: bold;
+          }
+        }
+      }
     }
     .club-info {
       padding: 4vw;
-      @include themify($themes) {
-        background: themed('cover-color');
-      }
+      width: 100vw;
+      min-height: 43.4vw;
 
       .info {
         width: 67vw;
         .name {
           font-size: 4.8vw;
-          color: #101010;
+          color: #fff;
           font-weight: bold;
           margin-bottom: 4vw;
         }
@@ -337,32 +537,29 @@ export default {
           margin-top: 1.6vw;
           line-height: 5vw;
           font-size: 3.2vw;
-          color: #404040;
+          color: #fff;
 
           &::after {
             content: '';
             display: block;
             width: 4vw;
-            height: 4vw;
+            height: 5vw;
             position: absolute;
             left: 0;
-            top: 0.5vw;
+            top: 0;
             background-size: 4vw 4vw;
             background-repeat: no-repeat;
+            background-position: center;
           }
         }
         .mobile {
           &::after {
-            @include themify($themes) {
-              background-image: themed('h5-icon-mobile');
-            }
+            background-image: url(~assets/theme-images/normal/pc/icon-mobile.png);
           }
         }
         .address {
           &::after {
-            @include themify($themes) {
-              background-image: themed('h5-icon-address');
-            }
+            background-image: url(~assets/theme-images/normal/pc/icon-address.png);
           }
         }
       }
@@ -373,6 +570,8 @@ export default {
         height: 18vw;
         border-radius: 9vw 9vw 0 9vw;
         overflow: hidden;
+        background: #fff;
+        display: flex;
 
         &::after {
           position: absolute;
@@ -382,7 +581,7 @@ export default {
           display: block;
           width: 3.6vw;
           height: 3.6vw;
-          background: url(~assets/theme-images/common/h5-icon-avatar-v.png)
+          background: url(~assets/theme-images/normal/h5/icon-avatar-v.png)
             no-repeat center;
           background-size: 3.6vw;
         }
@@ -395,11 +594,9 @@ export default {
         height: 6.4vw;
         border-radius: 0.4vw;
         font-size: 3.2vw;
-        @include themify($themes) {
-          color: themed('color');
-          border: 1px solid themed('color');
-          background-color: themed('sub-color');
-        }
+        color: #bc1724;
+        border: 1px solid #fff;
+        background-color: #fff;
 
         &::after {
           content: '';
@@ -407,34 +604,49 @@ export default {
           width: 3.6vw;
           height: 3.6vw;
           margin-left: 0.4vw;
-          @include themify($themes) {
-            background: themed('h5-icon-navigation') no-repeat center;
-            background-size: 3.6vw;
-          }
+          background: url(~assets/theme-images/normal/pc/icon-navigation.png)
+            no-repeat center;
+          background-size: 3.6vw;
         }
       }
       .distance {
         font-size: 3vw;
-        color: #404040;
+        color: #fff;
       }
     }
 
     .device-list {
+      padding: 0 4vw;
       .title {
-        padding: 4vw;
-        padding-bottom: 0;
+        position: relative;
+        padding-left: 6.8vw;
+        margin-top: 9.6vw;
+        margin-bottom: 4vw;
         font-size: 4vw;
         font-weight: bold;
         color: #101010;
+
+        &::before {
+          content: '';
+          display: block;
+          width: 4.4vw;
+          height: 4.4vw;
+          background: url(~assets/theme-images/normal/h5/icon-device-list.png)
+            no-repeat center;
+          position: absolute;
+          left: 0;
+          top: 0;
+        }
       }
       .device {
-        padding: 4vw 0;
-        margin: 0 4vw;
-        border-bottom: 0.4vw solid #d8d8d8;
+        padding: 4.4vw 3.2vw;
+        background: #f3f5f6;
+        margin-bottom: 3.2vw;
         .info {
+          width: 74%;
           .name {
             font-size: 3.6vw;
-            color: #101010;
+            color: #282828;
           }
           .code {
             margin-top: 3.2vw;
@@ -451,9 +663,7 @@ export default {
           border-radius: 0.4vw;
           font-size: 3vw;
           color: #ffffff;
-          @include themify($themes) {
-            background: themed('color');
-          }
+          background: #bc1724;
         }
       }
     }

+ 272 - 170
pages/_template/app/approve/club/star-list.vue

@@ -1,58 +1,54 @@
 <template>
   <div class="page">
-    <van-list
-      v-model="isLoadingMore"
-      :finished="finished"
-      :immediate-check="false"
-      :finished-text="total ? '没有更多了' : ''"
-      @load="onLoadMore"
-    >
-      <div class="page-content">
-        <!-- 标题 -->
-        <div class="title flex justify-between px-4 pt-8 pb-8 md:px-0">
-          <div>明星机构</div>
-          <div>共<span v-text="total"></span>家明星机构</div>
-        </div>
-        <!-- 列表 -->
-        <div class="list">
-          <template v-for="item in list">
-            <div
-              class="section flex justify-between mb-4"
-              :key="item.authId"
-              @click="toDetail(item)"
-            >
-              <img class="cover" :src="item.logo || drawLogo(item.clubName)" />
-              <div class="info">
-                <div class="name" v-text="item.clubName"></div>
-                <div class="mobile">{{ item.mobile || '暂无' }}</div>
-                <div class="address">
-                  {{ formatAddress(item.area, item.address) }}
-                </div>
+    <div class="page-content">
+      <!-- 标题 -->
+      <div class="title flex justify-between px-4 pt-8 pb-6 md:px-0">
+        <div>明星机构</div>
+        <div>共<span v-text="total" class="font-bold"></span>家明星机构</div>
+      </div>
+      <!-- 列表 -->
+      <div class="list">
+        <template v-for="item in list">
+          <div
+            class="section flex justify-between mb-4"
+            :key="item.authId"
+            @click="toDetail(item)"
+          >
+            <img class="cover" :src="item.logo || drawLogo(item.authParty)" />
+            <div class="info">
+              <div class="name" v-text="item.authParty"></div>
+              <div class="mobile">{{ item.mobile || '暂无' }}</div>
+              <div class="address">
+                {{ formatAddress(item.area, item.address) }}
               </div>
             </div>
-          </template>
-          <div class="empty" v-for="i in emptyList" :key="'empty-' + i"></div>
-        </div>
-        <!-- 列表为空 -->
-        <SimpleEmpty
-          v-if="!total && !isRequest"
-          name="icon-empty-club.png"
-          description="敬请期待~"
-        ></SimpleEmpty>
+          </div>
+        </template>
       </div>
-    </van-list>
+    </div>
   </div>
 </template>
 
 <script>
 import clubStarListMixin from '@/mixins/clubStarList'
 export default {
-  layout: 'app-ross',
+  layout: 'app-normal',
   mixins: [clubStarListMixin],
 }
 </script>
 
 <style scoped lang="scss">
+.el-input {
+  ::v-deep {
+    & > {
+      .el-input.is-active .el-input__inner,
+      .el-input__inner:focus {
+        border-color: #bc1724;
+      }
+    }
+  }
+}
+
 // pc 端
 @media screen and (min-width: 768px) {
   .page {
@@ -61,54 +57,109 @@ export default {
     background-color: #fff;
   }
   .page-top {
-    height: 420px;
-    @include themify($themes) {
-      background: themed('pc-banner-club');
-    }
-    background-size: auto 420px;
-
-    .logo {
-      display: block;
-      width: 120px;
-      height: 120px;
-      border-radius: 50%;
-      background: #fff;
-    }
-    .name {
-      font-size: 30px;
-      color: #fff;
-    }
-
-    .logo,
-    .name {
-      transform: translateY(-60px);
-    }
+    height: 530px;
+    background-image: url(~assets/theme-images/normal/pc/banner-club.png);
+    background-size: cover;
+    background-position: center;
   }
   .page-content {
-    width: 1200px;
+    position: relative;
+    width: 1000px;
     margin: 0 auto;
-    .search {
-      position: absolute;
-      left: 50%;
-      top: 260px;
-      transform: translateX(-50%);
-    }
-
-    .city {
-      position: absolute;
-      left: 50%;
-      top: 320px;
-      transform: translateX(-50%);
-      z-index: 9;
-    }
 
     .title {
       font-size: 16px;
       color: #404040;
 
       span {
-        @include themify($themes) {
-          color: themed('color');
+        color: #bc1724;
+      }
+    }
+
+    .filter {
+      padding: 48px 0 105px;
+      .search {
+        width: 640px;
+        margin: 0 auto;
+        .el-input {
+          height: 46px;
+          font-size: 16px;
+          .el-input__icon {
+            font-size: 24px;
+            line-height: 46px;
+            margin-left: 12px;
+          }
+
+          ::v-deep {
+            & > .el-input__inner {
+              height: 46px;
+              padding-left: 55px;
+            }
+          }
+        }
+      }
+    }
+
+    .navbar {
+      position: absolute;
+      top: 240px;
+      right: -168px;
+      width: 120px;
+      border-radius: 16px;
+      background: #fff;
+      box-shadow: 0px 6px 20px rgba(40, 40, 40, 0.1);
+      padding: 24px 0;
+      box-sizing: border-box;
+      z-index: 2;
+      .link {
+        &:hover {
+          .icon {
+            &.icon-device {
+              background: url(~assets/theme-images/normal/pc/nav-entry-device-active.png)
+                  no-repeat center center,
+                linear-gradient(180deg, #ffba63 0%, #bc1724 100%);
+              background-size: 48px, 100%;
+            }
+            &.icon-doctor {
+              background: url(~assets/theme-images/normal/pc/nav-entry-doctor-active.png)
+                  no-repeat center center,
+                linear-gradient(180deg, #ffba63 0%, #bc1724 100%);
+              background-size: 48px, 100%;
+            }
+          }
+          .text {
+            color: #bc1724;
+          }
+        }
+
+        span {
+          display: block;
+        }
+
+        .icon {
+          width: 72px;
+          height: 72px;
+          // background: linear-gradient(180deg, #ffba63 0%, #BC1724 100%);
+          background-color: #f6f6f7;
+          border-radius: 12px;
+
+          &.icon-device {
+            background: url(~assets/theme-images/normal/pc/nav-entry-device.png)
+              no-repeat center center #f6f6f7;
+            background-size: 48px;
+          }
+
+          &.icon-doctor {
+            background: url(~assets/theme-images/normal/pc/nav-entry-doctor.png)
+              no-repeat center center #f6f6f7;
+            background-size: 48px;
+          }
+        }
+
+        .text {
+          font-size: 16px;
+          color: #404040;
+          margin-top: 8px;
         }
       }
     }
@@ -124,12 +175,12 @@ export default {
       }
 
       .section {
-        width: 390px;
-        height: 108px;
+        width: 490px;
+        height: 136px;
         background-color: #f3f5f6;
         border-radius: 4px;
         box-sizing: border-box;
-        padding: 12px;
+        padding: 16px;
         cursor: pointer;
         transition: all 0.4s;
         &:hover {
@@ -138,18 +189,19 @@ export default {
 
         .cover {
           display: block;
-          width: 84px;
-          height: 84px;
+          width: 104px;
+          height: 104px;
         }
         .info {
           position: relative;
           margin-left: 12px;
+          width: 330px;
           .name {
             width: 200px;
-            font-size: 16px;
+            font-size: 18px;
             color: #101010;
             font-weight: bold;
-            margin-bottom: 16px;
+            margin-bottom: 24px;
             text-overflow: ellipsis;
             white-space: nowrap;
             overflow: hidden;
@@ -164,6 +216,7 @@ export default {
             line-height: 24px;
             text-overflow: ellipsis;
             white-space: nowrap;
+            margin-top: 6px;
             overflow: hidden;
             &::after {
               content: '';
@@ -191,7 +244,7 @@ export default {
 
           .distance {
             position: absolute;
-            font-size: 12px;
+            font-size: 14px;
             color: #404040;
             top: 2px;
             right: 0;
@@ -205,11 +258,10 @@ export default {
 // 移动 端
 @media screen and (max-width: 768px) {
   .page-top {
-    height: 46vw;
-    @include themify($themes) {
-      background: themed('h5-banner-club');
-    }
-    background-size: auto 46vw;
+    height: 100vw;
+    background: url(~assets/theme-images/normal/h5/banner-club.png);
+    background-size: 100vw 100vw !important;
+    background-position: center;
 
     .logo {
       display: block;
@@ -225,103 +277,153 @@ export default {
   }
   .page-content {
     position: relative;
-    .search {
-      position: absolute;
-      left: 50%;
-      top: 0;
-      transform: translate(-50%, -50%);
-    }
-
-    .city {
-      position: relative;
-      z-index: 9;
-      padding-top: 12vw;
-    }
 
     .title {
       font-size: 3.4vw;
       color: #404040;
 
       span {
-        @include themify($themes) {
-          color: themed('color');
+        color: #bc1724;
+      }
+    }
+
+    .filter {
+      padding: 6.4vw 3.2vw 12.8vw;
+    }
+
+    .navbar {
+      position: fixed;
+      top: 50% !important;
+      right: 3.2vw;
+      left: unset !important;
+      width: 14vw;
+      border-radius: 1.6vw;
+      background: #fff;
+      box-shadow: 0px 0.6vw 2vw rgba(40, 40, 40, 0.1);
+      padding: 2.8vw 0;
+      box-sizing: border-box;
+      z-index: 2;
+      span {
+        display: block;
+      }
+
+      .icon {
+        position: relative;
+        width: 7.2vw;
+        height: 7.2vw;
+        border-radius: 1.2vw;
+        background: linear-gradient(180deg, #ffba63 0%, #bc1724 100%);
+
+        &.icon-device,
+        &.icon-doctor {
+          &::after {
+            content: '';
+            display: block;
+            width: 4.8vw;
+            height: 4.8vw;
+            position: absolute;
+            left: 50%;
+            top: 50%;
+            transform: translate(-50%, -50%);
+            background-size: 4.8vw !important;
+          }
         }
+
+        &.icon-device {
+          &::after {
+            background: url(~assets/theme-images/normal/pc/nav-entry-device-active.png)
+              no-repeat center;
+          }
+        }
+
+        &.icon-doctor {
+          &::after {
+            background: url(~assets/theme-images/normal/pc/nav-entry-doctor-active.png)
+              no-repeat center;
+          }
+        }
+      }
+
+      .text {
+        font-size: 2.4vw;
+        color: #bc1724;
+        margin-top: 1.2vw;
       }
     }
+  }
 
-    .list {
-      display: flex;
-      align-items: center;
-      flex-direction: column;
+  .list {
+    display: flex;
+    align-items: center;
+    flex-direction: column;
 
-      .section {
-        width: 93.6vw;
-        height: 26vw;
-        background-color: #f3f5f6;
-        border-radius: 4px;
-        box-sizing: border-box;
-        padding: 3.2vw;
+    .section {
+      width: 93.6vw;
+      height: 26vw;
+      background-color: #f3f5f6;
+      border-radius: 4px;
+      box-sizing: border-box;
+      padding: 3.2vw;
 
-        .cover {
-          display: block;
-          width: 19.6vw;
-          height: 19.6vw;
+      .cover {
+        display: block;
+        width: 19.6vw;
+        height: 19.6vw;
+      }
+      .info {
+        position: relative;
+        margin-left: 3.2vw;
+        .name {
+          width: 48vw;
+          font-size: 4vw;
+          color: #101010;
+          font-weight: bold;
+          margin-bottom: 4vw;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          overflow: hidden;
         }
-        .info {
+        .mobile,
+        .address {
+          width: 66vw;
           position: relative;
-          margin-left: 3.2vw;
-          .name {
-            width: 48vw;
-            font-size: 4vw;
-            color: #101010;
-            font-weight: bold;
-            margin-bottom: 4vw;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-            overflow: hidden;
-          }
-          .mobile,
-          .address {
-            width: 66vw;
-            position: relative;
-            font-size: 3vw;
-            color: #404040;
-            padding-left: 5vw;
-            line-height: 5vw;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-            overflow: hidden;
-            &::after {
-              content: '';
-              display: block;
-              width: 4vw;
-              height: 4vw;
-              position: absolute;
-              left: 0;
-              top: 50%;
-              transform: translateY(-50%);
-              background-size: 4vw 4vw;
-              background-repeat: no-repeat;
-            }
+          font-size: 3vw;
+          color: #404040;
+          padding-left: 5vw;
+          line-height: 5vw;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          overflow: hidden;
+          &::after {
+            content: '';
+            display: block;
+            width: 4vw;
+            height: 4vw;
+            position: absolute;
+            left: 0;
+            top: 50%;
+            transform: translateY(-50%);
+            background-size: 4vw 4vw;
+            background-repeat: no-repeat;
           }
-          .mobile {
-            &::after {
-              background-image: url(~assets/theme-images/common/h5-icon-mobile.png);
-            }
+        }
+        .mobile {
+          &::after {
+            background-image: url(~assets/theme-images/common/h5-icon-mobile.png);
           }
-          .address {
-            &::after {
-              background-image: url(~assets/theme-images/common/h5-icon-address.png);
-            }
+        }
+        .address {
+          &::after {
+            background-image: url(~assets/theme-images/common/h5-icon-address.png);
           }
+        }
 
-          .distance {
-            position: absolute;
-            font-size: 3vw;
-            color: #404040;
-            top: 0.8vw;
-            right: 0;
-          }
+        .distance {
+          position: absolute;
+          font-size: 3vw;
+          color: #404040;
+          top: 0.8vw;
+          right: 0;
         }
       }
     }

+ 14 - 24
pages/_template/app/approve/device/detail.vue

@@ -45,10 +45,10 @@
           <div class="auth-icon"></div>
           <template v-for="item in productInfo.clubList">
             <div class="auth-info" :key="item.authId">
+              <span>该设备由</span>
               <span class="font-bold">ROS'S</span>
-              <span>授予</span>
+              <span>官方授权</span>
               <span>{{ item.authParty }}</span>
-              <span>正品拥有</span>
             </div>
           </template>
         </div>
@@ -91,7 +91,7 @@
 <script>
 import deviceDetailMixin from '@/mixins/deviceDetail'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [deviceDetailMixin],
 }
 </script>
@@ -99,16 +99,12 @@ export default {
 <style lang="scss" scoped>
 ::v-deep {
   .swiper-pagination-bullet {
-    @include themify($themes) {
-      background: themed('color') !important;
-    }
+    background: #BC1724 !important;
   }
 
   .simple-swiper {
     .swiper-pagination-bullet-active {
-      @include themify($themes) {
-        background: themed('color') !important;
-      }
+      background: #BC1724;
     }
   }
 }
@@ -192,7 +188,7 @@ export default {
           position: absolute;
           width: 70px;
           height: 70px;
-          background: url(~assets/theme-images/ross/pc-icon-auth-seal.png)
+          background: url(~assets/theme-images/normal/pc/icon-auth-seal.png)
             no-repeat center;
           background-size: 70px;
           right: 24px;
@@ -264,7 +260,7 @@ export default {
             display: block;
             width: 24px;
             height: 24px;
-            background: url(~assets/theme-images/ross/pc-icon-auth-ren.png)
+            background: url(~assets/theme-images/normal/pc/icon-auth-ren.png)
               no-repeat center;
             background-size: 23px;
           }
@@ -331,16 +327,14 @@ export default {
         .auth {
           width: 100%;
           min-height: 114px;
-          @include themify($themes) {
-            background: themed('color') !important;
-          }
+          background: #BC1724;
           margin-top: 56px;
           box-sizing: border-box;
           padding: 24px;
 
           .auth-icon {
             height: 28px;
-            background: url(~assets/theme-images/ross/pc-icon-auth.png)
+            background: url(~assets/theme-images/normal/pc/icon-auth2.png)
               no-repeat left center;
             background-size: auto 28px;
             margin-bottom: 10px;
@@ -377,9 +371,7 @@ export default {
             position: absolute;
             width: 73px;
             height: 2px;
-            @include themify($themes) {
-              background: themed('color') !important;
-            }
+            background: #BC1724;
             left: 0;
             bottom: 0;
           }
@@ -482,7 +474,7 @@ export default {
           position: absolute;
           width: 13.8vw;
           height: 13.8vw;
-          background: url(~assets/theme-images/ross/h5-icon-auth-seal.png)
+          background: url(~assets/theme-images/normal/h5/icon-auth-seal.png)
             no-repeat center;
           background-size: 13.8vw;
           right: 4vw;
@@ -552,7 +544,7 @@ export default {
             display: block;
             width: 3.6vw;
             height: 3.6vw;
-            background: url(~assets/theme-images/ross/h5-icon-auth-ren.png)
+            background: url(~assets/theme-images/normal/h5/icon-auth-ren.png)
               no-repeat center;
             background-size: 3.6vw;
           }
@@ -621,9 +613,7 @@ export default {
           // width: 100%;
           margin: 0 4vw;
           min-height: 20vw;
-          @include themify($themes) {
-            background: themed('color') !important;
-          }
+          background: #BC1724;
           margin-top: 4vw;
           box-sizing: border-box;
           padding: 5.2vw 4vw;
@@ -631,7 +621,7 @@ export default {
 
           .auth-icon {
             height: 4.9vw;
-            background: url(~assets/theme-images/ross/h5-icon-auth.png)
+            background: url(~assets/theme-images/normal/h5/icon-auth2.png)
               no-repeat left center;
             background-size: auto 4.9vw;
             margin-bottom: 1vw;

+ 23 - 22
pages/_template/app/approve/device/index.vue

@@ -1,18 +1,13 @@
 <template>
   <div class="page">
     <van-list
-      v-model="isLoadingMore"
+      v-model="loadingMore"
       :finished="finished"
       :immediate-check="false"
       :finished-text="total ? '没有更多了' : ''"
       @load="onLoadMore"
     >
-      <div class="page-top flex flex-col justify-center items-center">
-        <!-- <img class="logo" :src="supplierInfo.logo" /> -->
-        <div class="mt-2 name">
-          <span v-text="supplierInfo.shopName"></span><span>官方授权设备</span>
-        </div>
-      </div>
+      <div class="page-top"></div>
       <div class="page-content">
         <div class="search-title">设备种类查询:</div>
         <div class="search-container">
@@ -105,7 +100,7 @@
 <script>
 import deviceListMixin from '@/mixins/deviceList'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [deviceListMixin],
 }
 </script>
@@ -119,6 +114,18 @@ export default {
   }
 }
 
+::v-deep {
+  .el-button--warning {
+    background-color: #bc1724;
+    border-color: #bc1724;
+
+    &:hover {
+      background: #cf1b2a;
+      border-color: #cf1b2a;
+    }
+  }
+}
+
 // pc 端
 @media screen and (min-width: 768px) {
   .el-popover {
@@ -126,7 +133,7 @@ export default {
       line-height: 24px;
       cursor: pointer;
       &:hover {
-        color: #f3920d;
+        color: #bc1724;
       }
     }
   }
@@ -138,10 +145,9 @@ export default {
   }
   .page-top {
     height: 420px;
-    @include themify($themes) {
-      background: themed('pc-banner-device');
-    }
+    background: url(~assets/theme-images/normal/pc/banner-device.png);
     background-size: auto 420px;
+    background-position: center;
 
     .logo {
       display: block;
@@ -189,9 +195,7 @@ export default {
       color: #404040;
 
       span {
-        @include themify($themes) {
-          color: themed('color');
-        }
+        color: #bc1724;
       }
     }
 
@@ -262,10 +266,9 @@ export default {
 @media screen and (max-width: 768px) {
   .page-top {
     height: 46vw;
-    @include themify($themes) {
-      background: themed('h5-banner-device');
-      background-size: auto 46vw;
-    }
+    background: url(~assets/theme-images/normal/pc/banner-device.png);
+    background-size: auto 46vw;
+    background-position: center;
 
     .logo {
       display: block;
@@ -316,9 +319,7 @@ export default {
       color: #404040;
 
       span {
-        @include themify($themes) {
-          color: themed('color');
-        }
+        color: #bc1724;
       }
     }
 

+ 2 - 2
pages/_template/app/approve/personnel/operate/detail.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="page md:flex md:justify-between">
-    <div class="page-title">操作师认证</div>
+    <div class="page-title">体疗师认证</div>
     <div class="page-top">
       <div class="swiper">
         <SimpleSwiper :imageList="doctorInfo.bannerList"></SimpleSwiper>
@@ -49,7 +49,7 @@
 <script>
 import operatDoctorDetailMixin from '@/mixins/operatDoctorDetail'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [operatDoctorDetailMixin],
 }
 </script>

+ 31 - 41
pages/_template/app/approve/personnel/operate/index.vue

@@ -7,25 +7,19 @@
       :finished-text="total ? '没有更多了' : ''"
       @load="onLoadMore"
     >
-      <div class="page-top flex flex-col justify-center items-center">
-        <!-- <img class="logo" :src="supplierInfo.logo" /> -->
-        <div class="mt-2 name">
-          <span v-text="supplierInfo.shopName"></span>
-          <span>官方操作师认证</span>
-        </div>
-      </div>
+      <div class="page-top"></div>
       <div class="page-content">
         <!-- 搜索区域 -->
         <div class="search">
           <SimpleSearch
             v-model="listQuery.doctorName"
             @search="onSearch"
-            placeholder="搜索操作师"
+            placeholder="搜索体疗师"
           />
         </div>
         <!-- 标题 -->
         <div class="title px-4 pt-12 pb-6">
-          共<span v-text="total"></span>位体操作
+          共<span v-text="total"></span>位体
         </div>
         <!-- 列表 -->
         <div class="list">
@@ -39,11 +33,14 @@
             <div class="info">
               <div class="name" v-text="item.doctorName"></div>
               <div class="tag">{{ item.tagList.join(' | ') }}</div>
-              <div class="code">资格证编号:{{ item.certificateNo }}</div>
-              <div class="club-name">所在机构:{{ item.clubName }}</div>
+              <div class="code">
+                资格证编号:<span>{{ item.certificateNo }}</span>
+              </div>
+              <div class="club-name">
+                所在机构:<span>{{ item.clubName }}</span>
+              </div>
             </div>
           </div>
-          <div class="empty" v-for="i in emptyList" :key="'empty' + i"></div>
         </div>
 
         <!-- 列表为空 -->
@@ -60,13 +57,8 @@
 <script>
 import operatDoctorListMixin from '@/mixins/operatDoctorList'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [operatDoctorListMixin],
-  computed: {
-    emptyList() {
-      return 3 - (this.list.length % 3)
-    },
-  },
 }
 </script>
 
@@ -80,9 +72,8 @@ export default {
 @media screen and (min-width: 768px) {
   .page-top {
     height: 420px;
-    @include themify($themes) {
-      background: themed('pc-banner-doctor') no-repeat center;
-    }
+    background: url(~assets/theme-images/normal/pc/banner-doctor.png) no-repeat
+      center;
     background-size: auto 420px;
 
     .logo {
@@ -103,7 +94,7 @@ export default {
     }
   }
   .page-content {
-    width: 1200px;
+    width: 1000px;
     margin: 0 auto;
 
     .search {
@@ -118,9 +109,7 @@ export default {
       color: #404040;
 
       span {
-        @include themify($themes) {
-          color: themed('color');
-        }
+        color: #bc1724;
       }
     }
 
@@ -135,11 +124,12 @@ export default {
       }
 
       .section {
-        width: 390px;
+        width: 490px;
+        height: 136px;
         background-color: #f3f5f6;
         border-radius: 4px;
         box-sizing: border-box;
-        padding: 12px;
+        padding: 16px;
 
         cursor: pointer;
         transition: all 0.4s;
@@ -149,20 +139,22 @@ export default {
 
         .cover {
           display: block;
-          width: 84px;
-          height: 84px;
+          width: 104px;
+          height: 104px;
         }
         .info {
-          width: 270px;
+          width: 334px;
           position: relative;
           margin-left: 12px;
           .name {
-            font-size: 16px;
+            font-size: 18px;
             color: #101010;
             font-weight: bold;
             text-overflow: ellipsis;
             white-space: nowrap;
             overflow: hidden;
+            font-weight: bold;
+            margin-bottom: 8px;
           }
           .tag,
           .code,
@@ -170,14 +162,15 @@ export default {
             height: 20px;
             position: relative;
             font-size: 14px;
-            color: #404040;
+            color: #999;
             line-height: 20px;
             text-overflow: ellipsis;
             white-space: nowrap;
             overflow: hidden;
+            margin-top: 4px;
 
             span {
-              color: #6d9eff;
+              color: #333333;
             }
           }
 
@@ -194,9 +187,8 @@ export default {
 @media screen and (max-width: 768px) {
   .page-top {
     height: 46vw;
-    @include themify($themes) {
-      background: themed('h5-banner-doctor') no-repeat center;
-    }
+    background: url(~assets/theme-images/normal/pc/banner-doctor.png) no-repeat
+      center;
     background-size: auto 46vw;
 
     .logo {
@@ -229,9 +221,7 @@ export default {
       color: #404040;
 
       span {
-        @include themify($themes) {
-          color: themed('color');
-        }
+        color: #bc1724;
       }
     }
 
@@ -271,14 +261,14 @@ export default {
             height: 5vw;
             position: relative;
             font-size: 3vw;
-            color: #404040;
+            color: #999;
             line-height: 5vw;
             text-overflow: ellipsis;
             white-space: nowrap;
             overflow: hidden;
 
             span {
-              color: #6d9eff;
+              color: #333;
             }
           }
           .tag {

+ 468 - 0
pages/_template/app/center/club-detail.vue

@@ -0,0 +1,468 @@
+<template>
+  <div class="club-detail page">
+    <div class="page-top"></div>
+    <div class="page-content">
+      <div class="title">机构认证信息</div>
+      <template v-if="!isAuth">
+        <div class="tip">抱歉,您暂未认证机构</div>
+        <div class="btn" @click="toAuth">去认证</div>
+      </template>
+      <template v-else>
+        <div class="row">
+          <div class="col label">机构名称:</div>
+          <div class="col content">{{ clubInfo.authParty }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">联系电话:</div>
+          <div class="col content">{{ clubInfo.mobile }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">运营联系人:</div>
+          <div class="col content">{{ clubInfo.linkMan }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">运营联系人手机号:</div>
+          <div class="col content">{{ clubInfo.linkMobile }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">所在地区:</div>
+          <div class="col content">{{ clubInfo.area }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">详细地址:</div>
+          <div class="col content">{{ clubInfo.address }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">所在位置:</div>
+          <div class="col content">
+            <div class="postion-btn" @click="initMap">查看定位</div>
+          </div>
+        </div>
+        <div class="row block">
+          <div class="col label">logo:</div>
+          <div class="col content">
+            <el-image :src="clubInfo.logo" v-if="clubInfo.logo"></el-image>
+          </div>
+        </div>
+        <div class="row block">
+          <div class="col label">门头照:</div>
+          <div class="col content">
+            <template v-for="(image, index) in clubInfo.bannerList">
+              <el-image :src="image" :key="index"></el-image>
+            </template>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col label">机构类型:</div>
+          <div class="col content">{{ firstClubTypeName }}</div>
+        </div>
+        <div class="row">
+          <div class="col label">医美类型:</div>
+          <div class="col content">{{ secondClubTypeName }}</div>
+        </div>
+        <div class="row block">
+          <div class="col label">医疗许可证:</div>
+          <div class="col content">
+            <el-image
+              :src="clubInfo.medicalLicenseImage"
+              v-if="clubInfo.medicalLicenseImage"
+            ></el-image>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col label">员工人数:</div>
+          <div class="col content">{{ clubInfo.empNum }}</div>
+        </div>
+      </template>
+    </div>
+
+    <div class="position-select" v-if="mapVisiable">
+      <div class="position-select-container">
+        <SimpleAMap ref="aMap" :lnglat="lnglat" />
+        <div class="position-select-footer">
+          <div class="lnglat">当前经纬度:{{ clubInfo.lngAndLat }}</div>
+          <div
+            class="position-confirm postion-control"
+            @click="mapVisiable = false"
+          >
+            确定
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  layout: 'app-normal',
+  data() {
+    return {
+      mapVisiable: false,
+      clubInfo: {},
+    }
+  },
+  computed: {
+    ...mapGetters(['userInfo', 'routePrefix']),
+    isAuth() {
+      return this.clubInfo.auditStatus === 1
+    },
+    firstClubTypeName() {
+      if (!this.clubInfo.firstClubType) return '其他'
+      return ['医美', '生美', '项目公司', '个人', '其他'][
+        this.clubInfo.firstClubType - 1
+      ]
+    },
+    secondClubTypeName() {
+      if (!this.clubInfo.secondClubType) return '其他'
+      return ['诊所', '门诊', '医院', '其他', '美容院', '养生馆', '其他'][
+        this.clubInfo.secondClubType - 1
+      ]
+    },
+    lnglat() {
+      return this.clubInfo.lngAndLat ? this.clubInfo.lngAndLat.split(',') : null
+    },
+  },
+  created() {
+    this.fetchClubDetail()
+  },
+  methods: {
+    // 获取机构详情
+    async fetchClubDetail() {
+      try {
+        const authId = this.userInfo.authId
+        if (!authId) return
+        const res = await this.$http.api.fetchClubAuthInfoData({ authId })
+        this.clubInfo = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 去认证
+    toAuth() {
+      this.$router.push(`${this.routePrefix}/form/club-register`)
+    },
+    // 地图定位
+    initMap() {
+      this.mapVisiable = true
+      this.$nextTick(() => {
+        this.$refs.aMap.init()
+      })
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+@media screen and (min-width: 768px) {
+  .page {
+    display: flex;
+    justify-content: center;
+  }
+
+  .position-select {
+    width: 100vw;
+    height: 100vh;
+    background: rgba(0, 0, 0, 0.39);
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 999;
+
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    .position-select-container {
+      background: #fff;
+      width: 60%;
+      box-sizing: border-box;
+      padding: 24px;
+
+      .position-select-footer {
+        position: relative;
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+        padding-top: 24px;
+
+        .lnglat {
+          position: absolute;
+          font-size: 14px;
+          color: #666;
+
+          left: 0;
+          top: 50%;
+          transform: translateY(-50%);
+        }
+      }
+
+      .postion-control {
+        width: 120px;
+        height: 40px;
+        font-size: 14px;
+        border-radius: 4px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        margin-left: 16px;
+
+        &.position-confirm {
+          background: #f56c6c;
+          color: #fff;
+        }
+
+        &.position-cancel {
+          background: #b1b1b1;
+          color: #fff;
+        }
+      }
+    }
+  }
+
+  .page-content {
+    max-width: 760px;
+    padding-bottom: 167px;
+    .title {
+      font-size: 24px;
+      color: #282828;
+      font-weight: bold;
+      text-align: center;
+      padding: 60px 0;
+    }
+
+    .tip {
+      font-size: 16px;
+      color: #b2b2b2;
+      margin-top: 200px;
+      margin-bottom: 24px;
+      text-align: center;
+    }
+
+    .btn {
+      width: 98px;
+      height: 36px;
+      background: #BC1724;
+      border-radius: 4px;
+      text-align: center;
+      line-height: 36px;
+      color: #fff;
+      font-size: 16px;
+      margin: 0 auto;
+      cursor: pointer;
+    }
+
+    .row {
+      display: flex;
+      align-items: flex-start;
+      margin: 32px 0;
+
+      .col {
+        font-size: 16px;
+      }
+      .label {
+        color: #666666;
+        min-width: 100px;
+      }
+      .content {
+        color: #282828;
+
+        .el-image {
+          width: 106px;
+          height: 106px;
+          border: 1px solid #dcdcdc;
+          margin-right: 4px;
+
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+
+        .postion-btn {
+          height: 28px;
+          line-height: 28px;
+          font-size: 14px;
+          color: #fff;
+          background: #1890ff;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          border-radius: 4px;
+          padding: 0 8px;
+
+          &::before {
+            content: '';
+            display: inline-block;
+            width: 16px;
+            height: 16px;
+            background: url(~assets/theme-images/common/icon-position.png)
+              no-repeat center;
+            background-size: 16px 16px;
+          }
+        }
+      }
+    }
+  }
+}
+
+@media screen and (max-width: 768px) {
+  .page {
+    display: flex;
+    justify-content: center;
+  }
+
+  .position-select {
+    width: 100vw;
+    height: 100vh;
+    background: rgba(0, 0, 0, 0.39);
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 999;
+
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    .position-select-container {
+      background: #fff;
+      width: 80%;
+      box-sizing: border-box;
+      padding: 3.2vw;
+
+      .position-select-footer {
+        padding-top: 10vw;
+        position: relative;
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+
+        .lnglat {
+          position: absolute;
+          font-size: 3.2vw;
+          color: #666;
+
+          left: 0;
+          top: 5vw;
+          transform: translateY(-50%);
+        }
+      }
+
+      .postion-control {
+        width: 16vw;
+        height: 7vw;
+        font-size: 3.4vw;
+        border-radius: 0.4vw;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        margin-left: 3.6vw;
+
+        &.position-confirm {
+          background: #f56c6c;
+          color: #fff;
+        }
+
+        &.position-cancel {
+          background: #b1b1b1;
+          color: #fff;
+        }
+      }
+    }
+  }
+
+  .page-content {
+    padding: 0 4vw;
+    .title {
+      font-size: 4.2vw;
+      color: #282828;
+      font-weight: bold;
+      text-align: center;
+      padding: 8vw 0;
+    }
+
+    .tip {
+      font-size: 3vw;
+      color: #b2b2b2;
+      margin-top: 60vw;
+      margin-bottom: 4.8vw;
+      text-align: center;
+    }
+
+    .btn {
+      width: 36vw;
+      height: 8.8vw;
+      background: #BC1724;
+      border-radius: 0.4vw;
+      text-align: center;
+      line-height: 8.8vw;
+      color: #fff;
+      font-size: 3.4vw;
+      margin: 0 auto;
+    }
+
+    .row {
+      display: flex;
+      align-items: flex-start;
+      margin: 5.6vw 0;
+
+      &.block {
+        display: block;
+        .label {
+          margin-bottom: 2.4vw;
+        }
+      }
+
+      .col {
+        font-size: 3.4vw;
+      }
+      .label {
+        color: #666666;
+        min-width: 20.4vw;
+      }
+      .content {
+        color: #282828;
+
+        .el-image {
+          width: 26vw;
+          height: 26vw;
+          border: 0.1vw solid #dcdcdc;
+          margin-right: 0.6vw;
+
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+
+        .postion-btn {
+          height: 6.8vw;
+          line-height: 6.8vw;
+          font-size: 3.2vw;
+          color: #fff;
+          background: #1890ff;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          border-radius: 0.4vw;
+          padding: 0 1.2vw;
+
+          &::before {
+            content: '';
+            display: inline-block;
+            width: 3.58vw;
+            height: 3.58vw;
+            background: url(~assets/theme-images/common/icon-position.png)
+              no-repeat center;
+            background-size: 3.58vw;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 250 - 0
pages/_template/app/center/device/detail.vue

@@ -0,0 +1,250 @@
+<template>
+  <div class="club-detail page">
+    <div class="page-top"></div>
+    <div class="page-content">
+      <div class="title">设备认证信息</div>
+      <div class="row">
+        <div class="col label">设备名称:</div>
+        <div class="col content">{{ productInfo.productName }}</div>
+      </div>
+      <div class="row block">
+        <div class="col label">设备图片:</div>
+        <div class="col content">
+          <el-image
+            v-if="productInfo.productImage"
+            :src="productInfo.productImage"
+            :preview-src-list="[productInfo.productImage]"
+          ></el-image>
+          <span v-else>暂无图片</span>
+        </div>
+      </div>
+      <div class="row">
+        <div class="col label">所属品牌:</div>
+        <div class="col content">{{ productInfo.brandName }}</div>
+      </div>
+      <div class="row">
+        <div class="col label">购买渠道:</div>
+        <div class="col content">{{ productInfo.purchaseWay || '暂无' }}</div>
+      </div>
+      <div class="row block">
+        <div class="col label">发票:</div>
+        <div class="col content">
+          <el-image
+            v-if="productInfo.invoiceImage"
+            :src="productInfo.invoiceImage"
+            :preview-src-list="[productInfo.invoiceImage]"
+          ></el-image>
+          <span v-else>暂无图片</span>
+        </div>
+      </div>
+      <div class="row">
+        <div class="col label">设备SN码:</div>
+        <div class="col content">{{ productInfo.snCode }}</div>
+      </div>
+      <div class="row">
+        <div class="col label">设备参数:</div>
+        <div class="col content params-list">
+          <div
+            class="param"
+            v-for="param in productInfo.paramList"
+            :key="param.productName"
+          >
+            <div class="param-name">{{ param.paramName }}</div>
+            <div class="param-content">{{ param.paramContent }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  layout: 'app-normal',
+  data() {
+    return {
+      productInfo: {},
+    }
+  },
+  created() {
+    this.initData()
+  },
+  methods: {
+    initData() {
+      this.productId = this.$route.query.id
+      this.relationId = this.$route.query.relationId
+      this.getProductDetails()
+    },
+    // 获取认证机构信息
+    async getProductDetails() {
+      try {
+        const res = await this.$http.api.getProductDetails({
+          productId: this.productId,
+          relationId: this.relationId,
+        })
+        this.productInfo = { ...this.productInfo, ...res.data }
+        console.log('res', this.productInfo)
+      } catch (error) {
+        console.log(error)
+      }
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+@media screen and (min-width: 768px) {
+  .page {
+    display: flex;
+    justify-content: center;
+  }
+
+  .page-content {
+    max-width: 760px;
+    padding-bottom: 167px;
+    .title {
+      font-size: 24px;
+      color: #282828;
+      font-weight: bold;
+      text-align: center;
+      padding: 60px 0;
+    }
+
+    .row {
+      display: flex;
+      align-items: flex-start;
+      margin: 32px 0;
+
+      .col {
+        font-size: 16px;
+      }
+      .label {
+        color: #666666;
+        min-width: 100px;
+      }
+      .content {
+        color: #282828;
+
+        .el-image {
+          width: 106px;
+          height: 106px;
+          border: 1px solid #dcdcdc;
+          margin-right: 4px;
+
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+
+        &.params-list {
+          width: 100%;
+          margin-top: -10px;
+          .param {
+            display: table-row;
+            width: 100%;
+          }
+
+          .param-name,
+          .param-content {
+            display: table-cell;
+            font-size: 16px;
+            padding: 12px 0;
+
+            &:nth-child(2n-1) {
+              color: #999999;
+              white-space: nowrap;
+            }
+
+            &:nth-child(2n) {
+              color: #282828;
+              padding-left: 12px;
+            }
+
+            &:nth-child(3) {
+              padding-left: 100px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+@media screen and (max-width: 768px) {
+  .page-content {
+    padding: 0 7.2vw;
+    .title {
+      font-size: 4.6vw;
+      color: #282828;
+      font-weight: bold;
+      text-align: center;
+      padding: 8vw 0;
+    }
+
+    .row {
+      display: flex;
+      align-items: flex-start;
+      margin-bottom: 5.6vw;
+
+      &.block {
+        display: block;
+        .label {
+          margin-bottom: 2.4vw;
+        }
+      }
+
+      .col {
+        font-size: 3.4vw;
+      }
+      .label {
+        color: #666666;
+        min-width: 20.4vw;
+      }
+      .content {
+        color: #282828;
+
+        .el-image {
+          width: 26vw;
+          height: 26vw;
+          border: 0.1vw solid #dcdcdc;
+          margin-right: 0.6vw;
+
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+
+        &.params-list {
+          width: 100%;
+          margin-top: -1vw;
+          .param {
+            display: table-row;
+            width: 100%;
+          }
+
+          .param-name,
+          .param-content {
+            display: table-cell;
+            font-size: 3.4vw;
+            padding: 1.2vw 0;
+
+            &:nth-child(2n-1) {
+              color: #999999;
+              white-space: nowrap;
+            }
+
+            &:nth-child(2n) {
+              color: #282828;
+              padding-left: 1.2vw;
+            }
+
+            &:nth-child(3) {
+              padding-left: 100px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 268 - 0
pages/_template/app/center/device/index.vue

@@ -0,0 +1,268 @@
+<template>
+  <div class="page">
+    <div class="page-content">
+      <div class="title">设备认证信息</div>
+      <template v-if="!isAuth">
+        <div class="tip">抱歉,您暂未认证设备</div>
+        <div class="btn" @click="toAuth">去认证</div>
+      </template>
+      <div class="device-list" v-else>
+        <div
+          class="device"
+          @click="toDetail(product)"
+          v-for="product in list"
+          :key="product.productId"
+        >
+          <div class="cover">
+            <img :src="product.image" :alt="product.productName" />
+          </div>
+          <div class="content">
+            <div class="name">{{ product.productName }}</div>
+            <div class="sncode">SN码:{{ product.snCode | formatSnCode }}</div>
+          </div>
+        </div>
+      </div>
+      <div class="to-auth-btn" v-if="isAuth && !isPc" @click="toAuth">去认证</div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  layout: 'app-normal',
+  data() {
+    return {
+      list: [],
+      clubInfo: {},
+    }
+  },
+  filters: {
+    formatSnCode(code) {
+      if (!code) return ''
+      return code.replace(/^(\w{2})\w+(\w{4})$/, '$1******$2')
+    },
+  },
+  computed: {
+    ...mapGetters(['routePrefix', 'userInfo', 'authUserId', 'isPc']),
+    isAuth() {
+      return this.clubInfo.auditStatus === 1 && this.list.length > 0
+    },
+  },
+  created() {
+    this.fetchProductList()
+    this.fetchAuthDetail()
+  },
+  methods: {
+    // 产看详情
+    toDetail(row) {
+      const path = `${this.routePrefix}/center/device/detail?productId=${row.productId}&relationId=${row.relationId}`
+      this.$router.push(path)
+    },
+    // 获取机构信息
+    async fetchAuthDetail() {
+      try {
+        if (this.userInfo && !this.userInfo.authId) return
+        const res = await this.$http.api.fetchClubAuthInfoData({
+          authId: this.userInfo.authId,
+        })
+        this.clubInfo = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 获取已认证设备列表
+    async fetchProductList() {
+      try {
+        const authId = this.userInfo.authId
+        if (!authId) return
+        const res = await this.$http.api.fetchClubAuthProductList({
+          authId,
+          authUserId: this.authUserId,
+        })
+        if (res.data) {
+          this.list = res.data
+        }
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 去认证
+    toAuth() {
+      this.$router.push(`${this.routePrefix}/form/club-register`)
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+@mixin ellipsis($line: 1) {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: $line;
+  -webkit-box-orient: vertical;
+}
+
+@media screen and (min-width: 768px) {
+  .page-content {
+    width: 1000px;
+    margin: 0 auto;
+    .title {
+      font-size: 24px;
+      text-align: center;
+      font-weight: bold;
+      padding: 60px 0;
+    }
+
+    .tip {
+      font-size: 16px;
+      color: #b2b2b2;
+      margin-top: 200px;
+      margin-bottom: 24px;
+      text-align: center;
+    }
+
+    .btn {
+      width: 98px;
+      height: 36px;
+      background: #BC1724;
+      border-radius: 4px;
+      text-align: center;
+      line-height: 36px;
+      color: #fff;
+      font-size: 16px;
+      margin: 0 auto;
+      cursor: pointer;
+    }
+
+    .device-list {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      flex-wrap: wrap;
+
+      .device {
+        width: 490px;
+        height: 136px;
+        background: #f3f5f6;
+        border-radius: 8px;
+        display: flex;
+        align-items: center;
+        box-sizing: border-box;
+        padding: 16px;
+        margin-bottom: 20px;
+        cursor: pointer;
+
+        .cover {
+          img {
+            display: block;
+            width: 106px;
+            height: 106px;
+          }
+        }
+        .content {
+          width: 320px;
+          margin-left: 16px;
+          .name {
+            font-size: 18px;
+            color: #282828;
+            font-weight: bold;
+            margin-bottom: 24px;
+            @include ellipsis(1);
+          }
+          .sncode {
+            font-size: 16px;
+            color: #666666;
+          }
+        }
+      }
+    }
+  }
+}
+
+@media screen and (max-width: 768px) {
+  .page-content {
+    .title {
+      font-size: 4.2vw;
+      text-align: center;
+      font-weight: bold;
+      padding: 8vw 0;
+    }
+
+    .to-auth-btn {
+      width: 85.2vw;
+      height: 12vw;
+      background: #BC1724;
+      border-radius: 0.2vw;
+      text-align: center;
+      line-height: 12vw;
+      color: #ffffff;
+      font-size: 3.6vw;
+      position: fixed;
+      bottom: 24vw;
+      left: 50%;
+      transform: translateX(-50%);
+    }
+
+    .tip {
+      font-size: 3vw;
+      color: #b2b2b2;
+      margin-top: 60vw;
+      margin-bottom: 4.8vw;
+      text-align: center;
+    }
+
+    .btn {
+      width: 36vw;
+      height: 8.8vw;
+      background: #BC1724;
+      border-radius: 0.4vw;
+      text-align: center;
+      line-height: 8.8vw;
+      color: #fff;
+      font-size: 3.4vw;
+      margin: 0 auto;
+    }
+
+    .device-list {
+      padding: 0 3.2vw;
+      padding-bottom: 26vw;
+      .device {
+        height: 26vw;
+        background: #f3f5f6;
+        border-radius: 0.8vw;
+        display: flex;
+        align-items: center;
+        box-sizing: border-box;
+        padding: 3.2vw;
+        margin-bottom: 3.2vw;
+        cursor: pointer;
+
+        .cover {
+          img {
+            display: block;
+            width: 19.6vw;
+            height: 19.6vw;
+          }
+        }
+        .content {
+          width: 59vw;
+          margin-left: 3.2vw;
+          .name {
+            font-size: 3.6vw;
+            color: #282828;
+            font-weight: bold;
+            margin-bottom: 3.2vw;
+            @include ellipsis(1);
+          }
+          .sncode {
+            font-size: 3.6vw;
+            color: #666666;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 472 - 0
pages/_template/app/center/index.vue

@@ -0,0 +1,472 @@
+<template>
+  <div class="page">
+    <div class="page-top">
+      <SimpleCenterCover />
+      <div class="club-logo">
+        <img :src="clubInfo.logo" alt="" v-if="isAuth" />
+        <img
+          src="~/assets/theme-images/common/pc-icon-club-logo-default.png"
+          v-else-if="isPc"
+        />
+        <img
+          src="~/assets/theme-images/common/h5-icon-club-logo-default.png"
+          v-else
+        />
+        <div class="club-mobile">{{ userInfo.mobile }}</div>
+        <div class="club-name" v-if="isAuth">
+          机构:{{ clubInfo.authParty }}
+        </div>
+      </div>
+    </div>
+    <div class="page-content">
+      <div class="section-title">我的认证</div>
+      <div class="section-content">
+        <div class="item club" @click="onToClubDetail">
+          <div class="auth-icon" :class="isAuth ? 'auth' : 'un-auth'">
+            {{ isAuth ? '已认证' : '未认证' }}
+          </div>
+          <div class="tip">机构认证</div>
+          <div class="btn">
+            点击查看<span class="icon el-icon-arrow-right"></span>
+          </div>
+        </div>
+        <div class="item device" @click="onToDeviceList">
+          <div class="auth-icon" :class="isAuthDevice ? 'auth' : 'un-auth'">
+            {{ isAuthDevice ? '已认证' : '未认证' }}
+          </div>
+          <div class="tip">设备认证</div>
+          <div class="btn">
+            点击查看<span class="icon el-icon-arrow-right"></span>
+          </div>
+        </div>
+      </div>
+      <div class="line"></div>
+      <template v-if="isPc">
+        <div class="section-title">账户设置</div>
+        <div class="section-content">
+          <div class="reset-pwd" @click="onResetPassword">修改密码</div>
+        </div>
+      </template>
+      <template v-else>
+        <div class="menu-list">
+          <div class="item" @click="toAccountSubNav">
+            <span>账户设置</span>
+            <span class="el-icon-arrow-right"></span>
+          </div>
+        </div>
+      </template>
+      <div v-if="!isPc" class="logout" @click="logout">退出登录</div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  layout: 'app-normal',
+  data() {
+    return {
+      clubInfo: {},
+      list: [],
+    }
+  },
+  computed: {
+    ...mapGetters(['routePrefix', 'isPc', 'userInfo', 'authUserId']),
+    isAuth() {
+      return this.clubInfo.auditStatus === 1
+    },
+    isAuthDevice() {
+      return this.isAuth && this.list.length > 0
+    },
+  },
+  created() {
+    this.initUserInfo()
+  },
+  methods: {
+    // 初始化用户信息
+    async initUserInfo() {
+      try {
+        const res = await this.$http.api.checkTokenResult()
+        this.$store.dispatch('user/login', res.data)
+        this.$setStorage(this.routePrefix, 'userInfo', res.data)
+        this.fetchAuthDetail()
+        this.fetchProductList()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 获取机构信息
+    async fetchAuthDetail() {
+      try {
+        const authId = this.userInfo.authId
+        if (!authId) return
+        const res = await this.$http.api.fetchClubAuthInfoData({
+          authId,
+        })
+        this.clubInfo = res.data
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 获取已认证设备列表
+    async fetchProductList() {
+      try {
+        const authId = this.userInfo.authId
+        if (!authId) return
+        const res = await this.$http.api.fetchClubAuthProductList({
+          authId,
+          authUserId: this.authUserId,
+        })
+        if (res.data) {
+          this.list = res.data
+        }
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 去账户设置菜单列表
+    toAccountSubNav() {
+      this.$router.push(`${this.routePrefix}/center/subnav/account`)
+    },
+    // 机构详情
+    onToClubDetail() {
+      this.$router.push(`${this.routePrefix}/center/club-detail`)
+    },
+    // 设备认证
+    onToDeviceList() {
+      this.$router.push(`${this.routePrefix}/center/device`)
+    },
+    // 修改密码
+    onResetPassword() {
+      this.$router.push(`${this.routePrefix}/center/settings/password`)
+    },
+    // 退出登录
+    logout() {
+      this.$store.dispatch('user/logout')
+      this.$removeStorage(this.routePrefix, 'userInfo')
+      this.backHome()
+    },
+    // 回到首页
+    backHome() {
+      if (this.$route.path === this.routePrefix) return
+      this.$router.replace(this.routePrefix)
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+@media screen and (min-width: 768px) {
+  .page {
+    position: relative;
+    min-height: calc(100vh - 80px - 80px);
+    background-color: #fff;
+    overflow: hidden;
+  }
+  .page-top {
+    position: relative;
+    height: 360px;
+    // background-image: url(~assets/theme-images/normal/pc/banner-doc.png);
+
+    .club-logo {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      text-align: center;
+
+      img {
+        display: inline-block;
+        width: 90px;
+        height: 90px;
+        border-radius: 50%;
+      }
+
+      .club-mobile {
+        margin: 8px 0;
+      }
+
+      .club-mobile,
+      .club-name {
+        font-size: 18px;
+        color: #fff;
+      }
+    }
+  }
+
+  .page-content {
+    width: 704px;
+    margin: 8px auto 60px;
+
+    .section-title {
+      font-size: 24px;
+      color: #666666;
+      padding: 16px 0;
+    }
+    .section-content {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      .item {
+        position: relative;
+        width: 340px;
+        height: 230px;
+        background: #eee;
+        box-sizing: border-box;
+        padding-left: 24px;
+        cursor: pointer;
+
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+        justify-content: center;
+        background-size: 340px 230px;
+        background-position: center center;
+        background-repeat: no-repeat;
+
+        &.club {
+          background-image: url(~assets/theme-images/normal/pc/icon-center-item-auth-club.png);
+          .icon {
+            color: #bc1724;
+          }
+        }
+
+        &.device {
+          background-image: url(~assets/theme-images/normal/pc/icon-center-item-device.png);
+
+          .icon {
+            color: #0a6eb1;
+          }
+        }
+
+        .auth-icon {
+          position: absolute;
+          right: 16px;
+          top: 16px;
+          width: 72px;
+          height: 32px;
+          line-height: 32px;
+          text-align: center;
+          font-size: 16px;
+          color: #fff;
+          border-radius: 4px;
+
+          &.auth {
+            background: #1890ff;
+          }
+
+          &.un-auth {
+            background: #f94b4b;
+          }
+        }
+        .tip {
+          font-size: 24px;
+          color: #fff;
+          margin-bottom: 8px;
+        }
+        .btn {
+          font-size: 16px;
+          color: #fff;
+
+          .icon {
+            display: inline-block;
+            width: 18px;
+            height: 18px;
+            border-radius: 50%;
+            background: #fff;
+            // background: #0A6EB1;
+            font-size: 12px;
+            text-align: center;
+            line-height: 18px;
+            margin-left: 9px;
+            font-weight: bold;
+            vertical-align: 1px;
+          }
+        }
+      }
+
+      .reset-pwd {
+        width: 98px;
+        height: 36px;
+        background: #bc1724;
+        opacity: 1;
+        border-radius: 4px;
+        font-size: 16px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #ffffff;
+        text-align: center;
+        cursor: pointer;
+      }
+    }
+
+    .line {
+      height: 1px;
+      background: #c2c2c2;
+      margin: 32px 0;
+    }
+  }
+}
+
+@media screen and (max-width: 768px) {
+  .page-top {
+    height: 36vw;
+    position: relative;
+
+    .club-logo {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      text-align: center;
+
+      img {
+        display: inline-block;
+        width: 12.8vw;
+        height: 12.8vw;
+        border-radius: 50%;
+      }
+
+      .club-mobile {
+        margin: 0.8vw 0;
+      }
+
+      .club-mobile,
+      .club-name {
+        font-size: 3.4vw;
+        color: #fff;
+      }
+    }
+  }
+
+  .page-content {
+    padding-bottom: 26vw;
+    .section-title {
+      font-size: 4.2vw;
+      color: #666666;
+      padding: 6.4vw 0 3.2vw;
+      padding-left: 4vw;
+    }
+
+    .logout {
+      width: 85.2vw;
+      height: 12vw;
+      background: #bc1724;
+      border-radius: 0.2vw;
+      text-align: center;
+      line-height: 12vw;
+      color: #ffffff;
+      font-size: 3.6vw;
+      position: fixed;
+      bottom: 24vw;
+      left: 50%;
+      transform: translateX(-50%);
+    }
+
+    .section-content {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      padding: 0 4vw;
+      .item {
+        position: relative;
+        width: 44.4vw;
+        height: 30vw;
+        background: #eee;
+        box-sizing: border-box;
+        padding-left: 3.6vw;
+        cursor: pointer;
+
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+        justify-content: center;
+        background-size: 44.4vw 30vw;
+        background-position: center center;
+        background-repeat: no-repeat;
+
+        &.club {
+          background-image: url(~assets/theme-images/normal/pc/icon-center-item-auth-club.png);
+          .icon {
+            color: #bc1724;
+          }
+        }
+
+        &.device {
+          background-image: url(~assets/theme-images/normal/pc/icon-center-item-device.png);
+          .icon {
+            color: #0a6eb1;
+          }
+        }
+
+        .auth-icon {
+          position: absolute;
+          right: 1.6vw;
+          top: 1.6vw;
+          width: 12.8vw;
+          height: 5.6vw;
+          line-height: 5.6vw;
+          text-align: center;
+          font-size: 3vw;
+          color: #fff;
+          border-radius: 0.4vw;
+
+          &.auth {
+            background: #1890ff;
+          }
+
+          &.un-auth {
+            background: #f94b4b;
+          }
+        }
+        .tip {
+          font-size: 4vw;
+          color: #fff;
+          margin-bottom: 1.2vw;
+        }
+        .btn {
+          font-size: 3vw;
+          color: #fff;
+
+          .icon {
+            display: inline-block;
+            width: 3.4vw;
+            height: 3.4vw;
+            border-radius: 50%;
+            background: #fff;
+            font-size: 2.8vw;
+            text-align: center;
+            line-height: 3.4vw;
+            margin-left: 0.8vw;
+            font-weight: bold;
+            vertical-align: 1px;
+          }
+        }
+      }
+    }
+
+    .menu-list {
+      padding: 0 4vw;
+      padding-top: 2.4vw;
+      .item {
+        width: 100%;
+        padding: 3vw 0;
+        display: flex;
+        justify-content: space-between;
+        font-size: 3.4vw;
+        border-bottom: 0.1vw solid #c2c2c2;
+
+        .el-icon-arrow-right {
+          font-size: 4vw;
+        }
+      }
+    }
+
+    .line {
+      height: 1.6vw;
+      background: #f7f7f7;
+      margin-top: 6.4vw;
+    }
+  }
+}
+</style>

+ 295 - 0
pages/_template/app/center/settings/password.vue

@@ -0,0 +1,295 @@
+<template>
+  <div class="page">
+    <div class="page-content">
+      <el-form :model="formData" :rules="rules" label-position="top" ref="form">
+        <el-form-item label="手机号" prop="mobile">
+          <el-input
+            placeholder="请输入手机号"
+            maxlength="11"
+            v-model="formData.mobile"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="验证码" prop="verifyCode">
+          <div class="verify-code">
+            <el-input
+              placeholder="请输入验证码"
+              maxlength="6"
+              v-model="formData.verifyCode"
+            ></el-input>
+            <div class="send" @click="onSend">{{ sendCodeBtnText }}</div>
+          </div>
+        </el-form-item>
+        <el-form-item label="新密码" prop="password">
+          <el-input
+            type="password"
+            placeholder="请输入新密码"
+            v-model="formData.password"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="确认密码" prop="confirmPwd">
+          <el-input
+            type="password"
+            placeholder="请输入确认密码"
+            v-model="formData.confirmPwd"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div class="submit-button">
+        <div class="back btn" @click="onBack">返回</div>
+        <div class="submit btn" @click="onSubmit">提交</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { isMobile, validPassword } from '~/utils/validator'
+import { mapGetters } from 'vuex'
+export default {
+  layout: 'app-normal',
+  data() {
+    const passwordValidate = (rule, value, callback) => {
+      console.log(value)
+      if (validPassword(value)) {
+        callback()
+      } else {
+        callback(new Error('密码只能包含英文大小写和数字'))
+      }
+    }
+    const confirmPwdValide = (rule, value, callback) => {
+      if (this.formData.password !== value) {
+        callback(new Error('两次输入的密码不一致'))
+      } else {
+        callback()
+      }
+    }
+
+    return {
+      sendStatus: 0,
+      timer: null,
+      formData: {
+        mobile: '',
+        verifyCode: '',
+        password: '',
+        confirmPwd: '',
+      },
+      rules: {
+        mobile: [
+          { required: true, message: '请输入手机号', trigger: ['blur'] },
+        ],
+        verifyCode: [
+          { required: true, message: '请输入验证码', trigger: ['blur'] },
+        ],
+        password: [
+          { required: true, message: '请输入新密码', trigger: ['blur'] },
+          { min: 6, message: '密码长度不能小于6位', trigger: ['blur'] },
+          { validator: passwordValidate, trigger: ['blur'] },
+        ],
+        confirmPwd: [
+          { required: true, message: '请输入确认密码', trigger: ['blur'] },
+          { validator: confirmPwdValide, trigger: ['blur'] },
+        ],
+      },
+    }
+  },
+  computed: {
+    ...mapGetters(['authUserId', 'routePrefix']),
+    sendCodeBtnText() {
+      return this.sendStatus === 0
+        ? '发送验证码'
+        : `再次发送${this.sendStatus}s`
+    },
+  },
+  methods: {
+    // 返回
+    onBack() {
+      this.$router.back()
+    },
+    // 提交
+    async onSubmit() {
+      try {
+        await this.$refs.form.validate()
+        this.onResetPassword()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    // 忘记密码
+    async onResetPassword() {
+      try {
+        await this.$http.api.clubUserReset({
+          mobile: this.formData.mobile,
+          verifyCode: this.formData.verifyCode,
+          password: this.formData.password,
+          authUserId: this.authUserId,
+        })
+        this.$toast('密码修改成功,请重新登录')
+        setTimeout(() => {
+          this.logout()
+        }, 2000)
+      } catch (error) {
+        console.log(error)
+      }
+    },
+
+    // 退出登录
+    logout() {
+      this.$store.dispatch('user/logout')
+      this.$removeStorage(this.routePrefix, 'userInfo')
+      this.backHome()
+    },
+
+    // 回到首页
+    backHome() {
+      window.location.href = window.location.origin + this.routePrefix
+    },
+
+    // 发送短信验证码
+    async onSend() {
+      if (this.sendStatus > 0) return
+      // 验证手机号是否合法
+      if (!isMobile(this.formData.mobile)) {
+        this.$toast('请输入正确的手机号')
+        return
+      }
+      try {
+        // 发送验证码
+        await this.$http.api.clubUserCodeSend({
+          mobile: this.formData.mobile,
+          authUserId: this.authUserId,
+          type: this.formType === 'register' ? 1 : 2,
+        })
+        this.$toast('验证码已发送')
+        // 开启倒计时
+        this.countdown()
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    countdown() {
+      this.sendStatus = 30
+      this.timer = setInterval(() => {
+        if (this.sendStatus === 0) {
+          clearInterval(this.timer)
+          return
+        }
+        this.sendStatus--
+      }, 1000)
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+@media screen and (min-width: 768px) {
+  .page {
+    position: relative;
+    min-height: calc(100vh - 80px - 80px);
+    background-color: #fff;
+    overflow: hidden;
+  }
+
+  .page-content {
+    width: 518px;
+    margin: 0 auto;
+    margin-top: 100px;
+
+    .verify-code {
+      width: 100%;
+      display: flex;
+      align-items: center;
+
+      .send {
+        flex-shrink: 0;
+        margin-left: 16px;
+        height: 40px;
+        text-align: center;
+        line-height: 40px;
+        width: 118px;
+        background: #BC1724;
+        border-radius: 4px;
+        font-size: 16px;
+        color: #fff;
+        cursor: pointer;
+      }
+    }
+
+    .submit-button {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin-top: 32px;
+      .btn {
+        text-align: center;
+        width: 118px;
+        height: 40px;
+        border-radius: 4px;
+        font-size: 16px;
+        cursor: pointer;
+        box-sizing: border-box;
+        margin: 0 16px;
+
+        &.back {
+          border: 1px solid #BC1724;
+          color: #BC1724;
+          line-height: 38px;
+        }
+        &.submit {
+          background: #BC1724;
+          color: #fff;
+          line-height: 40px;
+        }
+      }
+    }
+  }
+}
+
+@media screen and (max-width: 768px) {
+  .page-content {
+    padding: 10vw 4vw 0;
+    .verify-code {
+      width: 100%;
+      display: flex;
+      align-items: center;
+
+      .send {
+        flex-shrink: 0;
+        margin-left: 2.4vw;
+        height: 40px;
+        text-align: center;
+        line-height: 40px;
+        width: 24.2vw;
+        background: #BC1724;
+        border-radius: 0.4vw;
+        font-size: 3.4vw;
+        color: #fff;
+        cursor: pointer;
+      }
+    }
+
+    .submit-button {
+      margin-top: 20vw;
+      .btn {
+        text-align: center;
+        height: 40px;
+        border-radius: 0.4vw;
+        font-size: 3.4vw;
+        cursor: pointer;
+        box-sizing: border-box;
+        margin-bottom: 3.2vw;
+
+        &.back {
+          border: 1px solid #BC1724;
+          color: #BC1724;
+          line-height: 38px;
+        }
+        &.submit {
+          background: #BC1724;
+          color: #fff;
+          line-height: 40px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 46 - 0
pages/_template/app/center/subnav/account.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="sub-nav">
+    <div class="item" @click="onResetPassword">
+      <span>修改密码</span>
+      <span class="el-icon-arrow-right"></span>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  layout: 'app-normal',
+  data() {
+    return {}
+  },
+  computed: {
+    ...mapGetters(['routePrefix']),
+  },
+  methods: {
+    // 修改密码
+    onResetPassword() {
+      this.$router.push(`${this.routePrefix}/center/settings/password`)
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.sub-nav {
+  padding: 0 4vw;
+  padding-top: 2.4vw;
+  .item {
+    width: 100%;
+    padding: 3vw 0;
+    display: flex;
+    justify-content: space-between;
+    font-size: 3.4vw;
+    border-bottom: 0.1vw solid #c2c2c2;
+
+    .el-icon-arrow-right {
+      font-size: 4vw;
+    }
+  }
+}
+</style>

+ 18 - 18
pages/_template/app/docs/_fileId.vue

@@ -1,11 +1,6 @@
 <template>
   <div class="page">
-    <div class="page-top flex flex-col justify-center items-center">
-      <span
-        class="name mt-2"
-        v-text="supplierInfo.shopName + '产品资料'"
-      ></span>
-    </div>
+    <div class="page-top"></div>
     <div class="page-content">
       <!-- 面包屑 -->
       <el-breadcrumb separator-class="el-icon-arrow-right">
@@ -44,9 +39,14 @@
               <doc-icon :type="item.fileType" :src="item.screenshot" />
               <span
                 class="file-name"
+                v-if="item.fileType === 'article'"
                 @click="onRowClick(item)"
-                v-text="item.fileName"
-              ></span>
+              >
+                {{ item.fileName | fileNameFormat }}
+              </span>
+              <span class="file-name" v-else @click="onRowClick(item)">{{
+                item.fileName
+              }}</span>
             </div>
             <div class="col">{{ item.saveTime | dateFormat }}</div>
             <div class="col">
@@ -91,7 +91,7 @@
 <script>
 import fileListMixin from '@/mixins/fileList'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [fileListMixin],
 }
 </script>
@@ -113,10 +113,10 @@ export default {
   }
   .page-top {
     height: 360px;
-    @include themify($themes) {
-      background: themed('pc-banner-doc');
-      background-size: auto 360px;
-    }
+    background: url(~assets/theme-images/normal/pc/banner-doc.png);
+    background-size: auto 360px;
+    background-position: center;
+
     .logo {
       display: block;
       width: 120px;
@@ -176,7 +176,7 @@ export default {
         transition: all 0.4s;
 
         &:hover {
-          background: #fff1f2;
+          background: #fffaf3;
         }
 
         .section {
@@ -234,10 +234,10 @@ export default {
 @media screen and (max-width: 768px) {
   .page-top {
     height: 46vw;
-    @include themify($themes) {
-      background: themed('h5-banner-doc');
-      background-size: auto 46vw;
-    }
+    background: url(~assets/theme-images/normal/h5/banner-doc.png);
+    background-size: auto 46vw;
+    background-position: center;
+
     .logo {
       display: block;
       width: 14.8vw;

+ 1 - 1
pages/_template/app/docs/article-detail.vue

@@ -11,7 +11,7 @@
 <script>
 import articleDetailMixin from '@/mixins/articleDetail'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [articleDetailMixin],
 }
 </script>

+ 5 - 9
pages/_template/app/docs/detail.vue

@@ -3,14 +3,10 @@
     <div v-if="fileData" class="doc-header">
       <div class="info">
         <div class="cover">
-          <doc-icon
-            :type="fileData.fileType"
-            :width="32"
-            :height="32"
-            :src="fileData.screenshot"
-          />
+          <doc-icon :type="fileData.fileType" :width="32" :height="32" />
         </div>
         <div class="content">
+          <div class="name">{{ fileData.fileName }}</div>
           <div class="row">
             <span class="date">时间:{{ fileData.saveTime | dateFormat }}</span>
             <span class="size">大小:{{ fileData.fileSize | fileSize }}</span>
@@ -37,7 +33,7 @@
 <script>
 import fileDetailMixin from '@/mixins/fileDetail'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   mixins: [fileDetailMixin],
 }
 </script>
@@ -132,7 +128,7 @@ export default {
       .download {
         width: 88px;
         height: 36px;
-        background: #bc1724;
+        background: #BC1724;
         opacity: 1;
         border-radius: 2px;
         text-align: center;
@@ -231,7 +227,7 @@ export default {
       .download {
         width: 32vw;
         height: 8.8vw;
-        background: #bc1724;
+        background: #BC1724;
         opacity: 1;
         border-radius: 0.2vw;
         text-align: center;

+ 17 - 28
pages/_template/app/feedback/index.vue

@@ -1,9 +1,6 @@
 <template>
   <div class="page">
-    <div class="page-top flex flex-col justify-center items-center">
-      <!-- <img class="logo" :src="supplierInfo.logo" /> -->
-      <div class="name mt-2" v-text="supplierInfo.shopName + '意见反馈'"></div>
-    </div>
+    <div class="page-top"></div>
     <div class="page-content p-4 md:my-4">
       <textarea
         class="control p-2"
@@ -27,7 +24,7 @@
 <script>
 import feedbackMixin from '@/mixins/feedback'
 export default {
-  layout: 'app-ross',
+  layout: 'app-normal',
   mixins: [feedbackMixin],
 }
 </script>
@@ -37,10 +34,10 @@ export default {
 @media screen and (min-width: 768px) {
   .page-top {
     height: 360px;
-    @include themify($themes) {
-      background: themed('pc-banner-feedback');
-    }
+    background: url(~assets/theme-images/normal/pc/banner-feedback.png);
     background-size: auto 360px;
+    background-position: center;
+
     .logo {
       display: block;
       width: 120px;
@@ -79,17 +76,13 @@ export default {
       margin-right: auto;
       border-radius: 4px;
       font-size: 16px;
-      @include themify($themes) {
-        background-color: themed('color');
-      }
+      background-color: #bc1724;
       color: #fff;
       transition: all 0.2s;
       cursor: pointer;
 
       &:hover {
-        @include themify($themes) {
-          background-color: themed('hover-color');
-        }
+        background-color: #b41724;
       }
 
       &.disabled {
@@ -134,10 +127,9 @@ export default {
       .image-icon {
         width: 140px;
         height: 100px;
-        @include themify($themes) {
-          background: themed('pc-icon-feedback-submit') no-repeat center;
-          background-size: 140px 100px;
-        }
+        background: url(~assets/theme-images/normal/pc/icon-feedback-submit.png)
+          no-repeat center;
+        background-size: 140px 100px;
       }
     }
   }
@@ -147,10 +139,10 @@ export default {
 @media screen and (max-width: 768px) {
   .page-top {
     height: 46vw;
-    @include themify($themes) {
-      background: themed('h5-banner-feedback');
-    }
+    background: url(~assets/theme-images/normal/pc/banner-feedback.png);
     background-size: auto 46vw;
+    background-position: center;
+
     .logo {
       display: block;
       width: 14.8vw;
@@ -182,9 +174,7 @@ export default {
       height: 11.6vw;
       border-radius: 0.2vw;
       font-size: 4vw;
-      @include themify($themes) {
-        background-color: themed('color');
-      }
+      background-color: #bc1724;
       color: #fff;
 
       &.disabled {
@@ -221,10 +211,9 @@ export default {
       .image-icon {
         width: 30vw;
         height: 20vw;
-        @include themify($themes) {
-          background: themed('pc-icon-feedback-submit') no-repeat center;
-          background-size: 30vw 20vw;
-        }
+        background: url(~assets/theme-images/normal/pc/icon-feedback-submit.png)
+          no-repeat center;
+        background-size: 30vw 20vw;
       }
     }
   }

+ 8 - 4
pages/_template/app/form/club-bind.vue

@@ -2,10 +2,14 @@
   <div class="club-bind">
     <div class="form-container">
       <div class="logo">
-        <!-- <img src="~/assets/theme-images/ross/ross-logo.png" alt="" /> -->
-        <img :src="supplierInfo.logo" :alt="supplierInfo.shopName" />
+        <img :src="supplierInfo.shopName" alt="" />
+        <!-- <img :src="supplierInfo.logo" :alt="supplierInfo.shopName" /> -->
+      </div>
+      <div class="tip">
+        输入验证码即可完成账号注册及{{
+          supplierInfo.shopName
+        }}授权牌匾制作与寄送
       </div>
-      <div class="tip">输入验证码即可完成账号注册及ROSS授权牌匾制作与寄送</div>
       <div class="form">
         <el-form
           :model="formData"
@@ -63,7 +67,7 @@ import { mapGetters } from 'vuex'
 import { isMobile } from '~/utils/validator'
 import { SlideVerify } from '@/utils/libs/slide-verify'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   data() {
     var validateMobile = (rule, value, callback) => {
       if (!value || isMobile(value)) {

+ 34 - 38
pages/_template/app/form/club-register.vue

@@ -1,12 +1,6 @@
 <template>
   <div class="page">
-    <div class="page-top flex flex-col justify-center items-center">
-      <!-- <img class="logo" :src="supplierInfo.logo" /> -->
-      <div
-        class="name mt-2"
-        v-text="supplierInfo.shopName + '正品授权申请'"
-      ></div>
-    </div>
+    <div class="page-top"></div>
     <div class="page-content" v-if="!isRequest">
       <template>
         <!-- 进步条 -->
@@ -87,7 +81,7 @@ import FormClubInfo from './components/form-club-info.vue'
 import FormClubDevice from './components/form-club-device.vue'
 import { mapGetters } from 'vuex'
 export default {
-  layout: 'app',
+  layout: 'app-normal',
   components: {
     SimpleStep,
     FormClubRegister,
@@ -99,6 +93,7 @@ export default {
     return {
       isRequest: true,
       active: false,
+      isSubmit: false,
       registerType: [3],
       step: 1,
       stepList: [
@@ -179,6 +174,10 @@ export default {
     this.isRequest = true
     this.initPageForm()
   },
+  beforeDestroy() {
+    this.$toast.clear()
+    this.isSubmit = false
+  },
   methods: {
     onConfirm() {
       this.$router.push(this.routePrefix)
@@ -211,6 +210,12 @@ export default {
     },
 
     async onSubmit() {
+      this.$toast.loading({
+        message: '正在提交注册信息,请勿操作...',
+        duration: 0,
+      })
+      if (this.isSubmit) return
+      this.isSubmit = true
       const params = {
         registerType: this.registerType.join(','),
         authUserId: this.authUserId,
@@ -230,6 +235,9 @@ export default {
       } catch (error) {
         console.log(error)
         this.$toast(error.msg)
+      } finally {
+        this.$toast.clear()
+        this.isSubmit = false
       }
     },
 
@@ -334,10 +342,10 @@ export default {
 
   .page-top {
     height: 360px;
-    @include themify($themes) {
-      background: themed('pc-banner-register');
-      background-size: auto 360px;
-    }
+    background: url(~assets/theme-images/normal/pc/banner-register.png);
+    background-size: auto 360px;
+    background-position: center;
+
     .logo {
       display: block;
       width: 120px;
@@ -404,24 +412,18 @@ export default {
         cursor: pointer;
 
         &.prev {
-          @include themify($themes) {
-            border: 1px solid themed('color');
-            color: themed('color');
-          }
+          border: 1px solid #bc1724;
+          color: #bc1724;
         }
         &.next {
-          @include themify($themes) {
-            background-color: themed('color');
-            color: #fff;
-          }
+          background-color: #bc1724;
+          color: #fff;
         }
       }
       .record {
         font-size: 14px;
         cursor: pointer;
-        @include themify($themes) {
-          color: themed('color');
-        }
+        color: #bc1724;
       }
     }
 
@@ -440,10 +442,10 @@ export default {
 
   .page-top {
     height: 46vw;
-    @include themify($themes) {
-      background: themed('h5-banner-register');
-      background-size: auto 46vw;
-    }
+    background: url(~assets/theme-images/normal/h5/banner-register.png);
+    background-size: auto 46vw;
+    background-position: center;
+
     .logo {
       display: block;
       width: 14.8vw;
@@ -505,25 +507,19 @@ export default {
         cursor: pointer;
 
         &.prev {
-          @include themify($themes) {
-            border: 1px solid themed('color');
-            color: themed('color');
-          }
+          border: 1px solid #bc1724;
+          color: #bc1724;
         }
         &.next {
-          @include themify($themes) {
-            background-color: themed('color');
-            color: #fff;
-          }
+          background-color: #bc1724;
+          color: #fff;
         }
       }
       .record {
         margin-top: 4.8vw;
         font-size: 3.4vw;
         cursor: pointer;
-        @include themify($themes) {
-          color: themed('color');
-        }
+        color: #bc1724;
       }
     }
   }

+ 13 - 31
pages/_template/app/form/components/form-club-device.vue

@@ -318,6 +318,7 @@ export default {
       ]
       obj.uuid = ++this.uuid
       obj.authType = formData.authType
+      obj.relationId = formData.relationId || ''
       obj.productImageList = productImageList
       obj.invoiceImageList = invoiceImageList
       obj.productImage = formData.productImage
@@ -494,20 +495,14 @@ export default {
   ::v-deep {
     .el-input.is-active .el-input__inner,
     .el-input__inner:focus {
-      @include themify($themes) {
-        border-color: themed('color');
-      }
+      border-color: #bc1724;
     }
     .el-radio__input.is-checked + .el-radio__label {
-      @include themify($themes) {
-        color: themed('color');
-      }
+      color: #bc1724;
     }
     .el-radio__input.is-checked .el-radio__inner {
-      @include themify($themes) {
-        background-color: themed('color');
-        border-color: themed('color');
-      }
+      background-color: #bc1724;
+      border-color: #bc1724;
     }
   }
 }
@@ -545,9 +540,7 @@ export default {
       right: 0;
       text-decoration: underline;
       font-size: 14px;
-      @include themify($themes) {
-        color: themed('color');
-      }
+      color: #bc1724;
     }
 
     .param {
@@ -581,10 +574,8 @@ export default {
     margin: 0 auto;
     cursor: pointer;
 
-    @include themify($themes) {
-      border: 1px solid themed('color');
-      color: themed('color');
-    }
+    border: 1px solid #bc1724;
+    color: #bc1724;
 
     .add-icon {
       width: 20px;
@@ -603,9 +594,7 @@ export default {
         border-radius: 1px;
         content: '';
         display: block;
-        @include themify($themes) {
-          background: themed('color');
-        }
+        background: #bc1724;
       }
       &::after {
         transform: translate(-50%, -50%) rotateZ(90deg);
@@ -632,9 +621,7 @@ export default {
       top: -40px;
       right: 0;
       font-size: 3.4vw;
-      @include themify($themes) {
-        color: themed('color');
-      }
+      color: #bc1724;
     }
 
     .param {
@@ -667,11 +654,8 @@ export default {
     font-size: 3.4vw;
     margin: 0 auto;
     cursor: pointer;
-
-    @include themify($themes) {
-      border: 1px solid themed('color');
-      color: themed('color');
-    }
+    border: 1px solid #bc1724;
+    color: #bc1724;
 
     .add-icon {
       width: 20px;
@@ -690,9 +674,7 @@ export default {
         border-radius: 1px;
         content: '';
         display: block;
-        @include themify($themes) {
-          background: themed('color');
-        }
+        background: #bc1724;
       }
       &::after {
         transform: translate(-50%, -50%) rotateZ(90deg);

+ 3 - 3
pages/_template/app/form/components/form-club-info.vue

@@ -306,6 +306,8 @@ export default {
         provinceId: '',
         cityId: '',
         townId: '',
+        linkMan: '',
+        linkMobile: '',
       },
       rules: {
         name: [
@@ -613,9 +615,7 @@ export default {
   ::v-deep {
     .el-input.is-active .el-input__inner,
     .el-input__inner:focus {
-      @include themify($themes) {
-        border-color: themed('color');
-      }
+      border-color: #bc1724;
     }
   }
 }

+ 2 - 6
pages/_template/app/form/components/form-club-register.vue

@@ -211,9 +211,7 @@ export default {
   ::v-deep {
     .el-input.is-active .el-input__inner,
     .el-input__inner:focus {
-      @include themify($themes) {
-        border-color: themed('color');
-      }
+      border-color: #bc1724;
     }
   }
 }
@@ -222,9 +220,7 @@ export default {
   .send {
     cursor: pointer;
     white-space: nowrap;
-    @include themify($themes) {
-      color: themed('color');
-    }
+    color: #bc1724;
   }
 }
 </style>

Some files were not shown because too many files changed in this diff