Ver Fonte

'异步组件'

周杰伦 há 4 anos atrás
pai
commit
8339580be7

+ 1 - 1
operation-frontend/.env.development

@@ -1,3 +1,3 @@
 NODE_ENV=development
 VUE_APP_PREVIEW=true
-VUE_APP_API_BASE_URL=http://192.168.1.20:38090
+VUE_APP_API_BASE_URL=http://192.168.1.148:38090

+ 3 - 2
operation-frontend/src/components/GlobalHeader/AvatarDropdown.vue

@@ -57,8 +57,9 @@ export default {
           // return new Promise((resolve, reject) => {
           //   setTimeout(Math.random() > 0.5 ? resolve : reject, 1500)
           // }).catch(() => console.log('Oops errors!'))
-          return this.$store.dispatch('Logout').then(() => {
-            this.$router.push({ name: 'login' })
+          return this.$store.dispatch('Logout').then((res) => {
+            console.log(res)
+            this.$router.push('/user')
           })
         },
         onCancel () {}

+ 1 - 0
operation-frontend/src/components/Model/index.vue

@@ -7,6 +7,7 @@
     @ok="handleOk"
     @cancel="handleCancel"
     class="model"
+    :destroyOnClose="true"
   >
     <slot></slot>
   </a-modal>

+ 46 - 26
operation-frontend/src/config/router.config.js

@@ -17,34 +17,54 @@ export const asyncRouterMap = [
     redirect: '/dashboard/workplace',
     children: [
       // dashboard
+      // {
+      //   path: '/dashboard',
+      //   name: 'dashboard',
+      //   redirect: '/dashboard/workplace',
+      //   component: RouteView,
+      //   meta: { title: 'menu.dashboard', keepAlive: true, icon: bxAnaalyse },
+      //   children: [
+      //     {
+      //       path: '/dashboard/analysis/:pageNo([1-9]\\d*)?',
+      //       name: 'Analysis',
+      //       component: () => import('@/views/dashboard/Analysis'),
+      //       meta: { title: 'menu.dashboard.analysis', keepAlive: false }
+      //     },
+      //     // 外部链接
+      //     {
+      //       path: 'https://www.baidu.com/',
+      //       name: 'Monitor',
+      //       meta: { title: 'menu.dashboard.monitor', target: '_blank' }
+      //     },
+      //     {
+      //       path: '/dashboard/workplace',
+      //       name: 'Workplace',
+      //       component: () => import('@/views/dashboard/Workplace'),
+      //       meta: { title: 'menu.dashboard.workplace', keepAlive: true }
+      //     }
+      //   ]
+      // },
+      // {
+      //   path: '/dashboard',
+      //   name: 'dashboard',
+      //   redirect: '/dashboard/workplace',
+      //   component: RouteView,
+      //   meta: { title: '运营中心', keepAlive: true, icon: bxAnaalyse },
+      //   children: [
+      //     {
+      //       path: '/dashboard/workplace',
+      //       name: 'Workplace',
+      //       component: () => import('@/views/dashboard/Workplace'),
+      //       meta: { title: 'menu.dashboard.workplace', keepAlive: true }
+      //     }
+      //   ]
+      // },
       {
-        path: '/dashboard',
-        name: 'dashboard',
-        redirect: '/dashboard/workplace',
-        component: RouteView,
-        meta: { title: 'menu.dashboard', keepAlive: true, icon: bxAnaalyse, permission: [ 'dashboard' ] },
-        children: [
-          {
-            path: '/dashboard/analysis/:pageNo([1-9]\\d*)?',
-            name: 'Analysis',
-            component: () => import('@/views/dashboard/Analysis'),
-            meta: { title: 'menu.dashboard.analysis', keepAlive: false, permission: [ 'dashboard' ] }
-          },
-          // 外部链接
-          {
-            path: 'https://www.baidu.com/',
-            name: 'Monitor',
-            meta: { title: 'menu.dashboard.monitor', target: '_blank' }
-          },
-          {
-            path: '/dashboard/workplace',
-            name: 'Workplace',
-            component: () => import('@/views/dashboard/Workplace'),
-            meta: { title: 'menu.dashboard.workplace', keepAlive: true, permission: [ 'dashboard' ] }
-          }
-        ]
+        path: '/operation',
+        name: 'operation',
+        component: () => import('@/views/operation'),
+        meta: { title: '运营中心', keepAlive: true, icon: bxAnaalyse }
       },
-
       // forms
       {
         path: '/form',

+ 5 - 0
operation-frontend/src/global.less

@@ -97,3 +97,8 @@ ol {
 .cp {
   cursor: pointer;
 }
+
+
+img {
+  object-fit: cover;
+}

+ 14 - 10
operation-frontend/src/layouts/BasicLayout.vue

@@ -33,14 +33,15 @@
 import { SettingDrawer, updateTheme } from '@ant-design-vue/pro-layout'
 import { i18nRender } from '@/locales'
 import { mapState } from 'vuex'
-import { CONTENT_WIDTH_TYPE, SIDEBAR_TYPE, TOGGLE_MOBILE_TYPE } from '@/store/mutation-types'
+// import { CONTENT_WIDTH_TYPE, SIDEBAR_TYPE, TOGGLE_MOBILE_TYPE } from '@/store/mutation-types'
+import { CONTENT_WIDTH_TYPE } from '@/store/mutation-types'
 
 import defaultSettings from '@/config/defaultSettings'
 import RightContent from '@/components/GlobalHeader/RightContent'
 import GlobalFooter from '@/components/GlobalFooter'
 import Ads from '@/components/Other/CarbonAds'
 import LogoSvg from '../assets/logo.svg?inline'
-
+import { asyncRouterMap } from '@/config/router.config.js'
 export default {
   name: 'BasicLayout',
   components: {
@@ -90,15 +91,18 @@ export default {
     })
   },
   created () {
-    const routes = this.mainMenu.find(item => item.path === '/')
-    this.menus = (routes && routes.children) || []
+    // const routes = this.mainMenu.find(item => item.path === '/')
+    // this.menus = (routes && routes.children) || []
     // 处理侧栏收起状态
-    this.$watch('collapsed', () => {
-      this.$store.commit(SIDEBAR_TYPE, this.collapsed)
-    })
-    this.$watch('isMobile', () => {
-      this.$store.commit(TOGGLE_MOBILE_TYPE, this.isMobile)
-    })
+    // this.$watch('collapsed', () => {
+    //   this.$store.commit(SIDEBAR_TYPE, this.collapsed)
+    // })
+    // this.$watch('isMobile', () => {
+    //   this.$store.commit(TOGGLE_MOBILE_TYPE, this.isMobile)
+    // })
+     this.menus = asyncRouterMap.find((item) => item.path === '/').children
+      // this.menus = this.mainMenu.find((item) => item.path === '/').children
+      this.collapsed = !this.sidebarOpened
   },
   mounted () {
     const userAgent = navigator.userAgent

+ 3 - 3
operation-frontend/src/layouts/UserLayout.vue

@@ -18,12 +18,12 @@
 
       <div class="footer">
         <div class="links">
+          <a href="_self">运营</a>
+          <a href="_self">管理</a>
           <a href="_self">帮助</a>
-          <a href="_self">隐私</a>
-          <a href="_self">条款</a>
         </div>
         <div class="copyright">
-          Copyright &copy; 2018 vueComponent
+          Copyright &copy; 2020 - serven idiot
         </div>
       </div>
     </div>

+ 1 - 1
operation-frontend/src/main.js

@@ -17,7 +17,7 @@ import SlideVerify from 'vue-monoplasty-slide-verify'
 
 import bootstrap from './core/bootstrap'
 import './core/lazy_use'
-import './permission' // permission control
+// import './permission' // permission control
 import './utils/filter' // global filter
 import './global.less'
 Vue.use(SlideVerify)

+ 8 - 3
operation-frontend/src/router/index.js

@@ -1,6 +1,6 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-import { constantRouterMap } from '@/config/router.config'
+import { constantRouterMap, asyncRouterMap } from '@/config/router.config'
 
 // hack router push callback
 const originalPush = Router.prototype.push
@@ -10,8 +10,13 @@ Router.prototype.push = function push (location, onResolve, onReject) {
 }
 
 Vue.use(Router)
-
+//   mode: 'history',
 export default new Router({
   mode: 'history',
-  routes: constantRouterMap
+  // routes: constantRouterMap,
+  // base: process.env.BASE_URL,
+  // base: '/api',
+  scrollBehavior: () => ({ y: 0 }),
+  routes: constantRouterMap.concat(asyncRouterMap)
 })
+//  base: '/api',

+ 32 - 16
operation-frontend/src/store/modules/user.js

@@ -3,15 +3,17 @@
 // import { ACCESS_TOKEN } from '@/store/mutation-types'
 // import { welcome } from '@/utils/util'
 import { Login } from '@/api/user'
+import { getItem, removeItem } from '@/utils/storage'
 
 const user = {
   state: {
-    token: '',
+    token: getItem('token') || '',
     name: '',
     welcome: '',
     avatar: '',
     roles: [],
-    info: {}
+    info: {},
+    userInfo: {}
   },
 
   mutations: {
@@ -30,6 +32,10 @@ const user = {
     },
     SET_INFO: (state, info) => {
       state.info = info
+    },
+
+    SET_USERINFO: (state, info) => {
+      state.userInfo = { ...info }
     }
   },
 
@@ -40,8 +46,14 @@ const user = {
         console.log(userInfo)
         const data = await Login(userInfo)
         console.log(data)
+        try {
+          commit('SET_USERINFO', data.data)
+          resolve(data)
+        } catch (e) {
+          reject(e)
+        }
       })
-    }
+    },
 
     // Login ({ commit }, userInfo) {
     //   return new Promise((resolve, reject) => {
@@ -87,19 +99,23 @@ const user = {
     //   })
     // },
 
-    // Logout ({ commit, state }) {
-    //   return new Promise((resolve) => {
-    //     logout(state.token).then(() => {
-    //       resolve()
-    //     }).catch(() => {
-    //       resolve()
-    //     }).finally(() => {
-    //       commit('SET_TOKEN', '')
-    //       commit('SET_ROLES', [])
-    //       storage.remove(ACCESS_TOKEN)
-    //     })
-    //   })
-    // }
+    Logout ({ commit, state }) {
+      return new Promise((resolve) => {
+        // commit('SET_TOKEN', '')
+        // commit('SET_ROLES', [])
+        removeItem('token')
+        resolve({ res: '2' })
+        // logout(state.token).then(() => {
+        //   resolve()
+        // }).catch(() => {
+        //   resolve()
+        // }).finally(() => {
+        //   commit('SET_TOKEN', '')
+        //   commit('SET_ROLES', [])
+
+        // })
+      })
+    }
 
   }
 }

+ 1 - 0
operation-frontend/src/utils/global.js

@@ -0,0 +1 @@
+// 定义全局方法

+ 6 - 0
operation-frontend/src/utils/request.js

@@ -5,6 +5,7 @@ import notification from 'ant-design-vue/es/notification'
 import { VueAxios } from './axios'
 import { ACCESS_TOKEN } from '@/store/mutation-types'
 import { message } from 'ant-design-vue'
+import { setItem } from '@/utils/storage'
 console.log(process.env)
 // 创建 axios 实例
 const request = axios.create({
@@ -68,6 +69,11 @@ request.interceptors.request.use(config => {
 // response interceptor
 request.interceptors.response.use((response) => {
   console.log(response)
+
+  if (response.headers.hasOwnProperty('auth_token')) {
+    setItem('token', response.headers.auth_token)
+  }
+
   if (response.data.code === 500) {
     message.error(response.data.message)
   }

+ 21 - 0
operation-frontend/src/utils/storage.js

@@ -0,0 +1,21 @@
+// 获取
+export const getItem = (key) => {
+   const data = window.localStorage.getItem(key)
+   console.log(data)
+   if (typeof data !== 'string') {
+     return JSON.parse(data)
+   } else {
+    return data
+   }
+}
+
+// 存储
+export const setItem = (key, value) => {
+    const data = typeof value === 'object' ? JSON.stringify(value) : value
+    window.localStorage.setItem(key, data)
+}
+
+// 移除
+export const removeItem = (key) => {
+    window.localStorage.removeItem(key)
+}

+ 120 - 0
operation-frontend/src/views/operation/Statistic.vue

@@ -0,0 +1,120 @@
+<template>
+  <div class="Statistic">
+    <!-- 指标总览 -->
+    <div class="indicator">
+      <div class="indicator-label">
+        指标总览<span>(所有认证号昨日指标)</span>
+      </div>
+      <div class="indicator-statistic">
+        <a-row>
+          <a-col
+            class="indicator-statistic"
+            :xs="12"
+            :sm="12"
+            :md="4"
+            :lg="4"
+            :xl="4"
+            v-for="(item, index) in statistic"
+            :key="index">
+            <div class="indicator-statistic-item-label">
+              {{ item.label }}
+            </div>
+            <div class="indicator-statistic-item-count">
+              {{ item.count }}
+              <a-icon type="arrow-up" class="arrow-up" :style="{ fontSize: '16px', color: '#52c41a' }"/>
+            </div>
+            <div class="indicator-statistic-item-rate">
+              {{ item.rate }}
+            </div>
+          </a-col>
+          <!-- </div> -->
+        </a-row>
+      </div>
+    </div>
+    <!--  -->
+  </div>
+</template>
+
+<script>
+const statistic = [
+    {
+        label: '昨日新增',
+        count: 80,
+        rate: '151.52%'
+    },
+    {
+        label: '昨日取关',
+        count: 80,
+        rate: '151.52%'
+    },
+    {
+        label: '昨日净增',
+        count: 80,
+        rate: '151.52%'
+    },
+    {
+        label: '昨日活跃',
+        count: 80,
+        rate: '151.52%'
+    },
+    {
+        label: '总粉丝',
+        count: 80,
+        rate: '151.52%'
+    }
+]
+export default {
+  name: 'Statistic',
+  data () {
+      return {
+           statistic
+      }
+  }
+}
+</script>
+<style scoped lang="less">
+.Statistic {
+    .indicator {
+        width: 100%;
+        // height: 164px;
+        background-color: #fff;
+        padding: 20px;
+        &-label {
+            font-size: 16px;
+            font-weight: 900;
+            color: #323233;
+            span {
+                display: inline-block;
+                font-size: 14px;
+                color: #969799;
+                margin-left: 7px;
+                font-weight: 400;
+            }
+        }
+        .indicator-statistic {
+            // display: flex;
+            margin-left: 30px;
+            margin-top: 10px;
+            &-item {
+                &-label {
+
+                }
+                &-count {
+                    font-size: 28px;
+                    color: #333;
+                    display: flex;
+                    justify-content: flex-start;
+                    align-items: center;
+                    .arrow-up {
+                      margin-left: 5px;
+                    }
+                }
+                &-rate {
+                    color: #666;
+                    font-size: 14px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 145 - 0
operation-frontend/src/views/operation/data-view/index.vue

@@ -0,0 +1,145 @@
+<template>
+  <div class="DataView">
+    <!-- 公众号 -->
+    <div class="official-accounts tabs">
+      <a-row>
+        <a-col
+          :xs="12"
+          :sm="12"
+          :md="4"
+          :lg="4"
+          :xl="4"
+          :class="['official-accounts-item', 'cp', index === currentTabsIndex ? 'official-accounts-item-active' : '' ]"
+          @click="currentTabs(index)"
+          v-for="(item, index) in arr"
+          :key="index">
+          <img class="official-accounts-item-img" :src="item.img" alt="">  {{ item.name }}
+        </a-col>
+      </a-row>
+
+    </div>
+    <!-- 数据统计 -->
+    <a-row class="statictis">
+      <a-col :span="4" v-for="(item , index) in statictis" :key="index">
+        <a-card>
+          <a-statistic
+            :title="item.title"
+            :value="item.count"
+            :precision="2"
+            suffix="%"
+            :value-style="{ color: item.count > 0 ? '#3f8600' : '#cf1322' }"
+            style="margin-right: 50px"
+
+          >
+
+            <template #prefix>
+              <a-icon :type="item.count > 0 ? 'arrow-up' : 'arrow-down'" />
+            </template>
+          </a-statistic>
+        </a-card>
+      </a-col>
+    </a-row>
+  </div>
+</template>
+
+<script>
+const official = [
+    {
+        img: 'http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJ7PXOg8UQskrEjqSwywYib5UYqjyAdKTr1ickq03BDOg9xtWIk108SsfHzd6PIXERRkVQSj9pXKsmw/132',
+        name: '逻辑狗'
+    }
+]
+
+const arr = []
+for (let i = 0; i < 5; i++) {
+    arr.push({
+        id: 1,
+        img: 'http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJ7PXOg8UQskrEjqSwywYib5UYqjyAdKTr1ickq03BDOg9xtWIk108SsfHzd6PIXERRkVQSj9pXKsmw/132',
+        name: `逻辑狗${i}`
+    })
+}
+
+arr.push({ name: 'serve-idiot', img: 'https://avatars1.githubusercontent.com/u/71005599?s=88&v=4' })
+const statictis = [
+    {
+        title: '昨日新增',
+        count: 20,
+        rate: '50%'
+    },
+    {
+        title: '昨日取关',
+        count: 20,
+        rate: '50%'
+    },
+    {
+        title: '昨日净增',
+        count: -3,
+        rate: '50%'
+    },
+    {
+        title: '昨日活跃',
+        count: 20,
+        rate: '50%'
+    },
+    {
+        title: '总粉丝',
+        count: -5,
+        rate: '50%'
+    },
+    {
+        title: '昨日阅读',
+        count: 20,
+        rate: '50%'
+    }
+]
+export default {
+  name: 'DataView',
+  data () {
+      return {
+          official,
+          arr,
+          currentTabsIndex: 0,
+          statictis
+      }
+  },
+  methods: {
+      currentTabs (index) {
+        this.currentTabsIndex = index
+      }
+  }
+}
+</script>
+<style scoped lang="less">
+.DataView {
+    width: 100%;
+    height: 500px;
+    background-color: #fff;
+    .official-accounts {
+        background-color: #f0f2f5;
+        // display: flex;
+        // border: 1px solid #d9d9d9;
+        &-item {
+            height: 40px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            border-bottom: 1px solid #d9d9d9;
+            border-top: 1px solid #d9d9d9;
+            &-img {
+                width: 30px;
+                height: 30px;
+                margin-right: 5px;
+            }
+        }
+        &-item-active {
+            background-color: #fff;
+            font-size: 18px;
+            border-bottom: 1px solid #fff;
+            box-sizing: border-box;
+        }
+    }
+    .statictis {
+        padding: 20px;
+    }
+}
+</style>

+ 26 - 0
operation-frontend/src/views/operation/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="OperationCenter">
+    <statistic class="statistic"/>
+    <data-view />
+  </div>
+
+</template>
+
+<script>
+import Statistic from './Statistic'
+import DataView from './data-view'
+export default {
+  name: 'OperationCenter',
+  components: {
+      Statistic,
+      DataView
+  }
+}
+</script>
+<style scoped lang="less">
+.OperationCenter {
+    .statistic {
+        margin-bottom: 20px;
+    }
+}
+</style>

+ 25 - 19
operation-frontend/src/views/user/Login.vue

@@ -93,7 +93,7 @@ import md5 from 'md5'
 // import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
 import { mapActions } from 'vuex'
 import SDialog from '@/components/Model'
-// import { timeFix } from '@/utils/util'
+import { timeFix } from '@/utils/util'
 // import { getSmsCaptcha, get2step } from '@/api/login'
 // import { getVerifyCode } from '@/api/user'
 export default {
@@ -188,7 +188,12 @@ export default {
       loginParams.password = md5(loginParams.password)
       const data = await Login(loginParams)
       console.log(data)
-    }
+      if (data.code === 200) {
+        this.loginSuccess()
+      } else {
+        this.visible = false
+      }
+    },
 
     // getCaptcha (e) {
     //   e.preventDefault()
@@ -233,29 +238,29 @@ export default {
     //     this.stepCaptchaVisible = false
     //   })
     // },
-    // loginSuccess (res) {
-    //   console.log(res)
+     loginSuccess () {
       // check res.homePage define, set $router.push name res.homePage
       // Why not enter onComplete
-      /*
-      this.$router.push({ name: 'analysis' }, () => {
-        console.log('onComplete')
+
+      // this.$router.push({ name: 'analysis' }, () => {
+      //   console.log('onComplete')
+      //   this.$notification.success({
+      //     message: '欢迎',
+      //     description: `${timeFix()},欢迎回来`
+      //   })
+      // })
+    // this.$router.push({ name: 'BasicForm' })
+    // console.log('hello')
+      this.$router.push('/operation')
+      // 延迟 1 秒显示欢迎信息
+      setTimeout(() => {
         this.$notification.success({
           message: '欢迎',
           description: `${timeFix()},欢迎回来`
         })
-      })
-      */
-      // this.$router.push({ path: '/' })
-      // 延迟 1 秒显示欢迎信息
-    //   setTimeout(() => {
-    //     this.$notification.success({
-    //       message: '欢迎',
-    //       description: `${timeFix()},欢迎回来`
-    //     })
-    //   }, 1000)
-    //   this.isLoginError = false
-    // },
+      }, 1000)
+      this.isLoginError = false
+    }
     // requestFailed (err) {
     //   this.isLoginError = true
     //   this.$notification['error']({
@@ -265,6 +270,7 @@ export default {
     //   })
     // }
   }
+
 }
 </script>
 

+ 5 - 3
operation-frontend/vue.config.js

@@ -106,10 +106,12 @@ const vueConfig = {
     // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        target: 'http://192.168.1.20:38090',
+        target: 'http://192.168.1.148:38090',
         ws: false,
-        changeOrigin: true
-
+        changeOrigin: true,
+        pathRewrite: {
+          '^/api': ''
+        }
       }
     }
   },