4
0
Просмотр исходного кода

1.星火版容器、用户扩展属性等部分bug2.新的打包方式biobank_spark

hanmj 6 лет назад
Родитель
Сommit
e3f31ef666
100 измененных файлов с 1787 добавлено и 2 удалено
  1. 2 2
      src/dashoo.cn/backend/api/controllers/casbin/user.go
  2. 13 0
      src/dashoo.cn/biobank_spark/Dockerfile-biobank-npm
  3. 17 0
      src/dashoo.cn/biobank_spark/docker-compose.yml
  4. 113 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/App.js
  5. 15 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/auth.middleware.js
  6. 24 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/auth.plugin.js
  7. 166 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/auth.store.js
  8. 144 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/axios.js
  9. 477 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/client.js
  10. 36 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/components/no-ssr.js
  11. 86 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-child.js
  12. 90 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-error.vue
  13. 7 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-link.js
  14. 103 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-loading.vue
  15. 44 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt.js
  16. 245 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/LICENSES
  17. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/element-icons.535877f.woff
  18. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/element-icons.732389d.ttf
  19. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/freedom.9a41c47.woff
  20. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/freedom.9a9e952.ttf
  21. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/Background.ee599d0.png
  22. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/QRcode.77de9cb.png
  23. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/avatar-default.9427a1d.jpg
  24. 29 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/avatar.163a4fa.svg
  25. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/basic.af98eae.png
  26. 154 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/freedom.0162e96.svg
  27. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/login-bg.33a8e3e.jpeg
  28. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/login_bg1.33a8e3e.jpg
  29. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo.1520abb.png
  30. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo2.39f8545.png
  31. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo3.e040e7b.png
  32. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo_white.858d9b2.png
  33. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/major.0578e82.png
  34. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/materialstorehouse.4fe636a.jpg
  35. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/special.be6b59e.png
  36. BIN
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/title_biobank.c291298.png
  37. 9 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/index.spa.html
  38. 9 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/index.ssr.html
  39. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/layouts/default.11646d6d8edf3e3f4966.js
  40. 1 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/layouts/empty.2fe37028bfb282ac8cba.js
  41. 1 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/layouts/office.5ab89413518144933e62.js
  42. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/manifest.85e92be33b3940dbc59d.js
  43. 1 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/about.70e386b9b0e632ba80b9.js
  44. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/authcode.e4a63959cb9f7e341cef.js
  45. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/allsearch/_opera/operation.01ea210b7f9e44917d41.js
  46. 1 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/allsearch/index.c1929320ffb664294f19.js
  47. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/book/_opera/operation.63bb94047e3c341f3f49.js
  48. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/book/index.d11d4af1d4b3eec20455.js
  49. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/partner/index.a3b30eb385b452942588.js
  50. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/partner/organize.a7ccc22b6a1aaf6e7b60.js
  51. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/project/_opera/operation.2f16e53a75a59b23958f.js
  52. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/project/index.76d4a24fe267c263f9cb.js
  53. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/_opera/operation.23482b8a79a890b613e3.js
  54. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/_opera/protocoledit.f26c66f2d2233dafa052.js
  55. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/index.deae3ec7f3775db7b5fa.js
  56. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/protocoladd.6c382df5cca8abaa3a8a.js
  57. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleCK/_opera/operation.ef0fd1d035d73f19bbcd.js
  58. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleCK/index.91714a92a47c658d6a15.js
  59. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleRK/_opera/operation.fdd29412842b0156715f.js
  60. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleRK/index.9452fa731bcdb1ceb171.js
  61. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampletest/_opera/operation.5eb07cdf993ad856d33f.js
  62. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampletest/index.ba5e977cfacb8f93606d.js
  63. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/service/_opera/operation.d18e8b091ba996a70361.js
  64. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/service/complated.1ffad94e062d26ed4852.js
  65. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/service/index.9d5c01e8f2a32f118e12.js
  66. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/operation.a1fe78d5cfb5c7a7e7e3.js
  67. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/operationb.9b6ffc8f866e32566240.js
  68. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/operationc.8459dbe704734223f846.js
  69. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/sourcedetail.4a0ba64caa2d0309da46.js
  70. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/sourceinfo.38be3665711e1a7f7f92.js
  71. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/sourcemicinfo.fea9debf11544a0fb127.js
  72. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/animal.4b8f117622c13e51a903.js
  73. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/index.9d0b950b6ba75b718e1c.js
  74. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/micro.da22968b904eee83046d.js
  75. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sourcextends/_opera/operation.cca02cd474c90c905915.js
  76. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sourcextends/index.619cc0cfd21f7d374204.js
  77. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/_opera/dochistory.9ab1d959a9f20adaec1c.js
  78. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/_opera/edit.8888c99162e1ccd580c5.js
  79. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/_opera/uploadnewdoc.a09e7f0834b2392bd21f.js
  80. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/add.0a0035e7bd3f27fdca5f.js
  81. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/index.30e345044f3b74f55b70.js
  82. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/_opera/donorsdetail.fe19f811e01df52f873e.js
  83. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/_opera/donorsedit.3472151b59f16c828438.js
  84. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/donorsadd.85c3a286eee6b674e1de.js
  85. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/index.416cd97bfdad55927130.js
  86. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/extends/_opera/extendsedit.a57017008dfdcce87a48.js
  87. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/extends/extendsadd.1f05d0798d4885ed5e27.js
  88. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/extends/index.26f8d1033c3e58a344f5.js
  89. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/_opera/familymandetail.cb0eb3849a50da646199.js
  90. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/_opera/familymanedit.725beb0b5ca6c3d93c61.js
  91. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/_opera/pedigreemap.23573f7bf21109ac9076.js
  92. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/familymanadd.e3f907b69deaed60aafd.js
  93. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/index.10079c805805a9766e7c.js
  94. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/_opera/flupplanedit.6bae5ab6975a23a403e9.js
  95. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/_opera/fluprecorddetail.adf526f0dd21ecb3fac8.js
  96. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/_opera/fluprecordedit.3624dc56e215592e5908.js
  97. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/flupplanadd.8d35ea806d5f0aeee89e.js
  98. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/fluprecord.b629b00026936fbd980b.js
  99. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/fluprecordadd.79dbf4047165017910c3.js
  100. 0 0
      src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/index.e2a6b43f7168306bddb2.js

+ 2 - 2
src/dashoo.cn/backend/api/controllers/casbin/user.go

@@ -135,9 +135,9 @@ func (this *UserController) List() {
 	svc := permission.GetPermissionService(utils.DBE)
 	var users []userRole.Base_User
 
-	where := "IsVisible=1 and CreateUserId='" + utils.ToStr(this.User.Id) + "' or Id = '" + utils.ToStr(this.User.Id) + "' "
+	where := "IsVisible=1 and (CreateUserId='" + utils.ToStr(this.User.Id) + "' or Id = '" + utils.ToStr(this.User.Id) + "') "
 	if keyword != "" {
-		where = where + " and Realname like '%" + keyword + "%'"
+		where = where + " and username like '%" + keyword + "%'"
 	}
 	total := svc.GetPagingEntitiesWithOrder(page.CurrentPage, page.Size, "Id", false, &users, where)
 

+ 13 - 0
src/dashoo.cn/biobank_spark/Dockerfile-biobank-npm

@@ -0,0 +1,13 @@
+FROM node:9.0-alpine
+
+ENV NODE_ENV=production
+ENV HOST 0.0.0.0
+
+# RUN mkdir /var/frontend
+COPY ./frontend /var/frontend
+WORKDIR /var/frontend
+
+RUN npm config set registry https://registry.npm.taobao.org
+RUN npm install --production
+
+# RUN npm run build

+ 17 - 0
src/dashoo.cn/biobank_spark/docker-compose.yml

@@ -0,0 +1,17 @@
+version: "3"
+services:
+ 
+  biobank:
+    build: 
+      context: .
+      dockerfile: Dockerfile-biobank-npm
+    # command: yarn start
+    command: npm run start
+    restart: always
+    ports:
+      - "9645:9645"
+
+# networks:
+  # net-php72:
+  # net-mysql:
+  # net-redis:

+ 113 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/App.js

@@ -0,0 +1,113 @@
+import Vue from 'vue'
+import NuxtLoading from './components/nuxt-loading.vue'
+
+import '../node_modules/element-ui/lib/theme-chalk/index.css'
+
+import '../src/assets/styles/main.scss'
+
+
+let layouts = {
+
+  "_default": () => import('../src/layouts/default.vue'  /* webpackChunkName: "layouts/default" */).then(m => m.default || m),
+
+  "_empty": () => import('../src/layouts/empty.vue'  /* webpackChunkName: "layouts/empty" */).then(m => m.default || m),
+
+  "_office": () => import('../src/layouts/office.vue'  /* webpackChunkName: "layouts/office" */).then(m => m.default || m)
+
+}
+
+let resolvedLayouts = {}
+
+export default {
+  head: {"title":"样本库系统","meta":[{"charset":"utf-8"},{"name":"viewport","content":"width=device-width, initial-scale=1"},{"hid":"description","name":"description","content":"样本库系统"}],"link":[{"rel":"icon","type":"image\u002Fx-icon","href":"\u002Ffavicon.ico"}],"script":[{"src":"\u002Fjs\u002Futils.js"},{"src":"\u002Fjs\u002FprintUtilities.js"}],"style":[]},
+  render(h, props) {
+    const loadingEl = h('nuxt-loading', { ref: 'loading' })
+    const layoutEl = h(this.layout || 'nuxt')
+    const templateEl = h('div', {
+      domProps: {
+        id: '__layout'
+      },
+      key: this.layoutName
+    }, [ layoutEl ])
+
+    const transitionEl = h('transition', {
+      props: {
+        name: 'layout',
+        mode: 'out-in'
+      }
+    }, [ templateEl ])
+
+    return h('div',{
+      domProps: {
+        id: '__nuxt'
+      }
+    }, [
+      loadingEl,
+      transitionEl
+    ])
+  },
+  data: () => ({
+    layout: null,
+    layoutName: ''
+  }),
+  beforeCreate () {
+    Vue.util.defineReactive(this, 'nuxt', this.$options.nuxt)
+  },
+  created () {
+    // Add this.$nuxt in child instances
+    Vue.prototype.$nuxt = this
+    // add to window so we can listen when ready
+    if (typeof window !== 'undefined') {
+      window.$nuxt = this
+    }
+    // Add $nuxt.error()
+    this.error = this.nuxt.error
+  },
+  
+  mounted () {
+    this.$loading = this.$refs.loading
+  },
+  watch: {
+    'nuxt.err': 'errorChanged'
+  },
+  
+  methods: {
+    
+    errorChanged () {
+      if (this.nuxt.err && this.$loading) {
+        if (this.$loading.fail) this.$loading.fail()
+        if (this.$loading.finish) this.$loading.finish()
+      }
+    },
+    
+    setLayout (layout) {
+      if (!layout || !resolvedLayouts['_' + layout]) layout = 'default'
+      this.layoutName = layout
+      let _layout = '_' + layout
+      this.layout = resolvedLayouts[_layout]
+      return this.layout
+    },
+    loadLayout (layout) {
+      if (!layout || !(layouts['_' + layout] || resolvedLayouts['_' + layout])) layout = 'default'
+      let _layout = '_' + layout
+      if (resolvedLayouts[_layout]) {
+        return Promise.resolve(resolvedLayouts[_layout])
+      }
+      return layouts[_layout]()
+      .then((Component) => {
+        resolvedLayouts[_layout] = Component
+        delete layouts[_layout]
+        return resolvedLayouts[_layout]
+      })
+      .catch((e) => {
+        if (this.$nuxt) {
+          return this.$nuxt.error({ statusCode: 500, message: e.message })
+        }
+      })
+    }
+  },
+  components: {
+    NuxtLoading
+  }
+}
+

+ 15 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/auth.middleware.js

@@ -0,0 +1,15 @@
+import middleware from './middleware'
+
+middleware.auth = function authMiddleware ({ store, redirect }) {
+  // If user not logged in, redirect to /login
+  if (!store.getters['auth/loggedIn']) {
+    return redirect('/login')
+  }
+}
+
+middleware['no-auth'] = function noAuthMiddleware ({ store, redirect }) {
+  // If user is already logged in, redirect to /
+  if (store.getters['auth/loggedIn']) {
+    return redirect('/')
+  }
+}

+ 24 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/auth.plugin.js

@@ -0,0 +1,24 @@
+import './auth.middleware'
+import authStore from './auth.store'
+
+export default async function (ctx, inject) {
+  const { store } = ctx
+
+  // Inject $ctx
+  inject('ctx', ctx)
+
+  // Register auth store module
+  store.registerModule('auth', authStore)
+
+  // Fetch initial state
+  try {
+    await store.dispatch('auth/fetch')
+  } catch (e) {
+    // Not authorized
+    // Check axios module is correctly registered
+    if (!ctx.$axios) {
+      /* eslint-disable no-console */
+      console.error('[@nuxtjs/auth]', 'Please make sure @nuxtjs/axios is added after this module!')
+    }
+  }
+}

+ 166 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/auth.store.js

@@ -0,0 +1,166 @@
+
+import Cookie from 'cookie'
+import Cookies from 'js-cookie'
+
+
+export default {
+  namespaced: true,
+
+  state: () => ({
+    token: null,
+    user: null
+  }),
+
+  getters: {
+    loggedIn (state) {
+      return Boolean(state.user && state.token)
+    }
+  },
+
+  mutations: {
+    // SET_USER
+    SET_USER (state, user) {
+      state.user = user
+    },
+
+    
+    // SET_TOKEN
+    SET_TOKEN (state, token) {
+      state.token = token
+    }
+    
+  },
+
+  actions: {
+    
+    // Update token
+    updateToken ({ commit }, token) {
+      // Update token in store's state
+      commit('SET_TOKEN', token)
+
+      // Set Authorization token for all axios requests
+      this.$axios.setToken(token, 'Bearer');
+
+      
+      // Update localStorage
+      if (process.browser && localStorage) {
+        if (token) {
+          localStorage.setItem('token', token)
+        } else {
+          localStorage.removeItem('token')
+        }
+      }
+      
+
+      
+      // Update cookies
+      if (process.browser) {
+        // ...Browser
+        if (token) {
+          Cookies.set('token', token)
+        } else {
+          Cookies.remove('token')
+        }
+      } else {
+        // ...Server
+        let params = {
+          domain: '/'
+        }
+        if (!token) {
+          let expires
+          let date = new Date()
+          expires = date.setDate(date.getDate() - 1)
+          params.expires = new Date(expires)
+        }
+        this.$ctx.res.setHeader('Set-Cookie', Cookie.serialize('token', token, params))
+      }
+      
+    },
+    
+
+    
+    // Fetch Token
+    fetchToken ({ dispatch }) {
+      let token
+
+      
+      // Try to extract token from localStorage
+      if (process.browser && localStorage) {
+        token = localStorage.getItem('token')
+      }
+      
+
+      
+      // Try to extract token from cookies
+      if (!token) {
+        const cookieStr = process.browser ? document.cookie : this.$ctx.req.headers.cookie
+        const cookies = Cookie.parse(cookieStr || '') || {}
+        token = cookies['token']
+      }
+      
+
+      if (token) {
+        dispatch('updateToken', token)
+      }
+    },
+    
+
+    // Reset
+    reset ({ dispatch, commit }) {
+      commit('SET_USER', null)
+      dispatch('updateToken', null)
+    },
+
+    // Fetch
+    async fetch ({ getters, state, commit, dispatch }, { endpoint = 'users/me' } = {}) {
+      
+      // Fetch and update latest token
+      dispatch('fetchToken')
+
+      // Skip if there is no token set
+      if (!state.token) {
+        return
+      }
+      
+
+      // Try to get user profile
+      try {
+        const data = await this.$axios.$get(endpoint)
+        commit('SET_USER', data)
+      } catch (e) {
+        console.error(e)
+        
+        // Reset store
+        dispatch('reset')
+        
+      }
+    },
+
+    // Login
+    async login ({ dispatch }, { fields, endpoint = 'auth' } = {}) {
+      // Send credentials to API
+      let data = await this.$axios.$post(endpoint, fields)
+
+      
+      dispatch('updateToken', data['token'])
+      
+
+      // Fetch authenticated user
+      await dispatch('fetch')
+    },
+
+    // Logout
+    async logout ({ dispatch, state }, { endpoint = 'auth/logout' } = {}) {
+      // Server side logout
+      try {
+        await this.$axios.$get(endpoint)
+      } catch (e) {
+        // eslint-disable-next-line no-console
+        console.error('Error while logging out', e)
+      }
+
+      // Reset store
+      dispatch('reset')
+    }
+  }
+}

+ 144 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/axios.js

@@ -0,0 +1,144 @@
+import Axios from 'axios'
+
+// We cannot extend Axios.prototype
+const axiosExtraProto = {}
+
+// Sets a common header
+axiosExtraProto.setHeader = function setHeader (name, value, scopes = 'common') {
+  if(!Array.isArray(scopes)) {
+    scopes = [scopes]
+  }
+  scopes.forEach(scope => {
+    if (!value) {
+      delete this.defaults.headers[scope][name];
+      return
+    }
+    this.defaults.headers[scope][name] = value
+  })
+}
+
+// Set requests token
+axiosExtraProto.setToken = function setToken (token, type, scopes = 'common') {
+    const value = !token ? null : (type ? type + ' ' : '') + token
+    this.setHeader('Authorization', value, scopes)
+}
+
+// Request helpers
+const reqMethods = [
+    'request', 'delete', 'get', 'head', 'options', // url, config
+    'post', 'put', 'patch' // url, data, config
+]
+reqMethods.forEach(method => {
+  axiosExtraProto['$' + method] = function () {
+    return this[method].apply(this, arguments).then(res => res && res.data)
+  }
+})
+
+// Setup all helpers to axios instance (Axios.prototype cannot be modified)
+function setupHelpers( axios ) {
+  for (let key in axiosExtraProto) {
+    axios[key] = axiosExtraProto[key].bind(axios)
+  }
+}
+
+const redirectError = {}
+
+// Set appreciate `statusCode` and `message` to error instance
+function errorHandler(error, ctx) {
+  if (error.response) {
+    // Error from backend (non 2xx status code)
+    // ...Auto redirect on special status codes
+    if (redirectError[error.response.status]) {
+      ctx.redirect(redirectError[error.response.status])
+    }
+    error.statusCode = error.statusCode || parseInt(error.response.status) || 500
+    error.message = error.message || error.response.statusText || (error.statusCode + ' (Internal Server Error)')
+  } else if (error.request) {
+    // Error while making request
+    error.statusCode = error.statusCode || 500
+    error.message = error.message || 'request error'
+  } else {
+    // Something happened in setting up the request that triggered an Error
+    error.statusCode = error.statusCode || 0
+    error.message = error.message || 'axios error'
+  }
+
+  return Promise.reject(error)
+}
+
+
+
+
+
+// Setup BaseURL
+const baseURL = process.browser
+  ? (process.env.API_URL_BROWSER || '//47.92.238.200:9081/api/')
+  : (process.env.API_URL || 'http://47.92.238.200:9081/api/')
+
+// Custom init hook
+
+
+export default (ctx, inject) => {
+  const { req } = ctx
+
+  // Create a fresh objects for all default header scopes
+  // Axios creates only one which is shared across SSR requests!
+  // https://github.com/mzabriskie/axios/blob/master/lib/defaults.js
+  const headers = {
+    common : {
+      'Accept': 'application/json, text/plain, */*'
+    },
+    delete: {},
+    get: {},
+    head: {},
+    post: {},
+    put: {},
+    patch: {}
+  }
+
+  
+  // Default headers
+  headers.common = (req && req.headers) ? Object.assign({}, req.headers) : {}
+  delete headers.common['accept']
+  delete headers.common['host']
+  
+
+  // Create new axios instance
+  const axios = Axios.create({
+    baseURL,
+    headers
+  })
+
+  
+  // Send credentials only to relative and API Backend requests
+  axios.interceptors.request.use(config => {
+    if (config.withCredentials === undefined) {
+      if (!/^https?:\/\//i.test(config.url) || config.url.indexOf(baseURL) === 0) {
+        config.withCredentials = true
+      }
+    }
+    return config
+  });
+  
+
+  
+
+  
+
+  
+
+  // Error handler
+  
+  axios.interceptors.response.use(undefined, err => errorHandler(err, ctx));
+  
+
+  // Inject axios to the context as $axios
+  ctx.$axios = axios
+  inject('axios', axios)
+
+  
+
+
+  // Setup axios helpers
+  setupHelpers(axios)
+}

+ 477 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/client.js

@@ -0,0 +1,477 @@
+import Vue from 'vue'
+import middleware from './middleware'
+import { createApp, NuxtError } from './index'
+import {
+  applyAsyncData,
+  sanitizeComponent,
+  resolveRouteComponents,
+  getMatchedComponents,
+  getMatchedComponentsInstances,
+  flatMapComponents,
+  setContext,
+  middlewareSeries,
+  promisify,
+  getLocation,
+  compile,
+  getQueryDiff
+} from './utils'
+
+const noopData = () => { return {} }
+const noopFetch = () => {}
+
+// Global shared references
+let _lastPaths = []
+let app
+let router
+let store
+
+// Try to rehydrate SSR data from window
+const NUXT = window.__NUXT__ || {}
+
+
+
+// Create and mount App
+createApp()
+.then(mountApp)
+.catch(err => {
+  if (err.message === 'ERR_REDIRECT') {
+    return // Wait for browser to redirect...
+  }
+  console.error('[nuxt] Error while initializing app', err)
+})
+
+function componentOption(component, key, ...args) {
+  if (!component || !component.options || !component.options[key]) {
+    return {}
+  }
+  const option = component.options[key]
+  if (typeof option === 'function') {
+    return option(...args)
+  }
+  return option
+}
+
+function mapTransitions(Components, to, from) {
+  const componentTransitions = component => {
+    const transition = componentOption(component, 'transition', to, from) || {}
+    return (typeof transition === 'string' ? { name: transition } : transition)
+  }
+
+  return Components.map(Component => {
+    // Clone original object to prevent overrides
+    const transitions = Object.assign({}, componentTransitions(Component))
+
+    // Combine transitions & prefer `leave` transitions of 'from' route
+    if (from && from.matched.length && from.matched[0].components.default) {
+      const from_transitions = componentTransitions(from.matched[0].components.default)
+      Object.keys(from_transitions)
+        .filter(key => from_transitions[key] && key.toLowerCase().indexOf('leave') !== -1)
+        .forEach(key => { transitions[key] = from_transitions[key] })
+    }
+
+    return transitions
+  })
+}
+
+async function loadAsyncComponents (to, from, next) {
+  // Check if route path changed (this._pathChanged), only if the page is not an error (for validate())
+  this._pathChanged = !!app.nuxt.err || from.path !== to.path
+  this._queryChanged = JSON.stringify(to.query) !== JSON.stringify(from.query)
+  this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : [])
+
+  
+  if (this._pathChanged && this.$loading.start) {
+    this.$loading.start()
+  }
+  
+
+  try {
+    const Components = await resolveRouteComponents(to)
+    
+    if (!this._pathChanged && this._queryChanged) {
+      // Add a marker on each component that it needs to refresh or not
+      const startLoader = Components.some((Component) => {
+        const watchQuery = Component.options.watchQuery
+        if (watchQuery === true) return true
+        if (Array.isArray(watchQuery)) {
+          return watchQuery.some((key) => this._diffQuery[key])
+        }
+        return false
+      })
+      if (startLoader && this.$loading.start) {
+        this.$loading.start()
+      }
+    }
+    
+    // Call next()
+    next()
+  } catch (err) {
+    err = err || {}
+    const statusCode = err.statusCode || err.status || (err.response && err.response.status) || 500
+    this.error({ statusCode, message: err.message })
+    this.$nuxt.$emit('routeChanged', to, from, err)
+    next(false)
+  }
+}
+
+function applySSRData(Component, ssrData) {
+  if (NUXT.serverRendered && ssrData) {
+    applyAsyncData(Component, ssrData)
+  }
+  Component._Ctor = Component
+  return Component
+}
+
+// Get matched components
+function resolveComponents(router) {
+  const path = getLocation(router.options.base, router.options.mode)
+
+  return flatMapComponents(router.match(path), async (Component, _, match, key, index) => {
+    // If component is not resolved yet, resolve it
+    if (typeof Component === 'function' && !Component.options) {
+      Component = await Component()
+    }
+    // Sanitize it and save it
+    const _Component = applySSRData(sanitizeComponent(Component), NUXT.data ? NUXT.data[index] : null)
+    match.components[key] = _Component
+    return _Component
+  })
+}
+
+function callMiddleware (Components, context, layout) {
+  let midd = ["check-auth"]
+  let unknownMiddleware = false
+
+  // If layout is undefined, only call global middleware
+  if (typeof layout !== 'undefined') {
+    midd = [] // Exclude global middleware if layout defined (already called before)
+    if (layout.middleware) {
+      midd = midd.concat(layout.middleware)
+    }
+    Components.forEach(Component => {
+      if (Component.options.middleware) {
+        midd = midd.concat(Component.options.middleware)
+      }
+    })
+  }
+
+  midd = midd.map(name => {
+    if (typeof name === 'function') return name
+    if (typeof middleware[name] !== 'function') {
+      unknownMiddleware = true
+      this.error({ statusCode: 500, message: 'Unknown middleware ' + name })
+    }
+    return middleware[name]
+  })
+
+  if (unknownMiddleware) return
+  return middlewareSeries(midd, context)
+}
+
+async function render (to, from, next) {
+  if (this._pathChanged === false && this._queryChanged === false) return next()
+
+  // nextCalled is true when redirected
+  let nextCalled = false
+  const _next = path => {
+    if (from.path === path.path && this.$loading.finish) this.$loading.finish()
+    if (from.path !== path.path && this.$loading.pause) this.$loading.pause()
+    if (nextCalled) return
+    nextCalled = true
+    const matches = []
+    _lastPaths = getMatchedComponents(from, matches).map((Component, i) => compile(from.matched[matches[i]].path)(from.params))
+    next(path)
+  }
+
+  // Update context
+  await setContext(app, {
+    route: to,
+    from,
+    next: _next.bind(this)
+  })
+  this._dateLastError = app.nuxt.dateErr
+  this._hadError = !!app.nuxt.err
+
+  // Get route's matched components
+  const matches = []
+  const Components = getMatchedComponents(to, matches)
+
+  // If no Components matched, generate 404
+  if (!Components.length) {
+    // Default layout
+    await callMiddleware.call(this, Components, app.context)
+    if (nextCalled) return
+    // Load layout for error page
+    const layout = await this.loadLayout(typeof NuxtError.layout === 'function' ? NuxtError.layout(app.context) : NuxtError.layout)
+    await callMiddleware.call(this, Components, app.context, layout)
+    if (nextCalled) return
+    // Show error page
+    app.context.error({ statusCode: 404, message: 'This page could not be found' })
+    return next()
+  }
+
+  // Update ._data and other properties if hot reloaded
+  Components.forEach(Component => {
+    if (Component._Ctor && Component._Ctor.options) {
+      Component.options.asyncData = Component._Ctor.options.asyncData
+      Component.options.fetch = Component._Ctor.options.fetch
+    }
+  })
+
+  // Apply transitions
+  this.setTransitions(mapTransitions(Components, to, from))
+
+  try {
+    // Call middleware
+    await callMiddleware.call(this, Components, app.context)
+    if (nextCalled) return
+    if (app.context._errored) return next()
+
+    // Set layout
+    let layout = Components[0].options.layout
+    if (typeof layout === 'function') {
+      layout = layout(app.context)
+    }
+    layout = await this.loadLayout(layout)
+
+    // Call middleware for layout
+    await callMiddleware.call(this, Components, app.context, layout)
+    if (nextCalled) return
+    if (app.context._errored) return next()
+
+    // Call .validate()
+    let isValid = true
+    Components.forEach(Component => {
+      if (!isValid) return
+      if (typeof Component.options.validate !== 'function') return
+      isValid = Component.options.validate({
+        params: to.params || {},
+        query : to.query  || {},
+        store
+      })
+    })
+    // ...If .validate() returned false
+    if (!isValid) {
+      this.error({ statusCode: 404, message: 'This page could not be found' })
+      return next()
+    }
+
+    // Call asyncData & fetch hooks on components matched by the route.
+    await Promise.all(Components.map((Component, i) => {
+      // Check if only children route changed
+      Component._path = compile(to.matched[matches[i]].path)(to.params)
+      Component._dataRefresh = false
+      // Check if Component need to be refreshed (call asyncData & fetch)
+      // Only if its slug has changed or is watch query changes
+      if (this._pathChanged && Component._path !== _lastPaths[i]) {
+        Component._dataRefresh = true
+      } else if (!this._pathChanged && this._queryChanged) {
+        const watchQuery = Component.options.watchQuery
+        if (watchQuery === true) {
+          Component._dataRefresh = true
+        } else if (Array.isArray(watchQuery)) {
+          Component._dataRefresh = watchQuery.some((key) => this._diffQuery[key])
+        }
+      }
+      if (!this._hadError && this._isMounted && !Component._dataRefresh) {
+        return Promise.resolve()
+      }
+
+      let promises = []
+
+      const hasAsyncData = Component.options.asyncData && typeof Component.options.asyncData === 'function'
+      const hasFetch = !!Component.options.fetch
+      const loadingIncrease = (hasAsyncData && hasFetch) ? 30 : 45
+
+      // Call asyncData(context)
+      if (hasAsyncData) {
+        const promise = promisify(Component.options.asyncData, app.context)
+        .then(asyncDataResult => {
+          applyAsyncData(Component, asyncDataResult)
+          if(this.$loading.increase) this.$loading.increase(loadingIncrease)
+        })
+        promises.push(promise)
+      }
+
+      // Call fetch(context)
+      if (hasFetch) {
+        let p = Component.options.fetch(app.context)
+        if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) {
+            p = Promise.resolve(p)
+        }
+        p.then(fetchResult => {
+          if(this.$loading.increase) this.$loading.increase(loadingIncrease)
+        })
+        promises.push(p)
+      }
+
+      return Promise.all(promises)
+    }))
+
+    // If not redirected
+    if (!nextCalled) {
+      if(this.$loading.finish) this.$loading.finish()
+      _lastPaths = Components.map((Component, i) => compile(to.matched[matches[i]].path)(to.params))
+      next()
+    }
+
+  } catch (error) {
+    if (!error) error = {}
+    _lastPaths = []
+    error.statusCode = error.statusCode || error.status || (error.response && error.response.status) || 500
+
+    // Load error layout
+    let layout = NuxtError.layout
+    if (typeof layout === 'function') {
+      layout = layout(app.context)
+    }
+    await this.loadLayout(layout)
+
+    this.error(error)
+    this.$nuxt.$emit('routeChanged', to, from, error)
+    next(false)
+  }
+}
+
+// Fix components format in matched, it's due to code-splitting of vue-router
+function normalizeComponents (to, ___) {
+  flatMapComponents(to, (Component, _, match, key) => {
+    if (typeof Component === 'object' && !Component.options) {
+      // Updated via vue-router resolveAsyncComponents()
+      Component = Vue.extend(Component)
+      Component._Ctor = Component
+      match.components[key] = Component
+    }
+    return Component
+  })
+}
+
+function showNextPage(to) {
+  // Hide error component if no error
+  if (this._hadError && this._dateLastError === this.$options.nuxt.dateErr) {
+    this.error()
+  }
+
+  // Set layout
+  let layout = this.$options.nuxt.err ? NuxtError.layout : to.matched[0].components.default.options.layout
+  if (typeof layout === 'function') {
+    layout = layout(app.context)
+  }
+  this.setLayout(layout)
+}
+
+// When navigating on a different route but the same component is used, Vue.js
+// Will not update the instance data, so we have to update $data ourselves
+function fixPrepatch(to, ___) {
+  if (this._pathChanged === false && this._queryChanged === false) return
+
+  Vue.nextTick(() => {
+    const matches = []
+    const instances = getMatchedComponentsInstances(to, matches)
+
+    instances.forEach((instance, i) => {
+      if (!instance) return
+      // if (!this._queryChanged && to.matched[matches[i]].path.indexOf(':') === -1 && to.matched[matches[i]].path.indexOf('*') === -1) return // If not a dynamic route, skip
+      if (instance.constructor._dataRefresh && _lastPaths[i] === instance.constructor._path && typeof instance.constructor.options.data === 'function') {
+        const newData = instance.constructor.options.data.call(instance)
+        for (let key in newData) {
+          Vue.set(instance.$data, key, newData[key])
+        }
+      }
+    })
+    showNextPage.call(this, to)
+    
+  })
+}
+
+function nuxtReady (_app) {
+  window._nuxtReadyCbs.forEach((cb) => {
+    if (typeof cb === 'function') {
+      cb(_app)
+    }
+  })
+  // Special JSDOM
+  if (typeof window._onNuxtLoaded === 'function') {
+    window._onNuxtLoaded(_app)
+  }
+  // Add router hooks
+  router.afterEach(function (to, from) {
+    // Wait for fixPrepatch + $data updates
+    Vue.nextTick(() => _app.$nuxt.$emit('routeChanged', to, from))
+  })
+}
+
+
+
+async function mountApp(__app) {
+  // Set global variables
+  app = __app.app
+  router = __app.router
+  store = __app.store 
+
+  // Resolve route components
+  const Components = await Promise.all(resolveComponents(router))
+
+  // Create Vue instance
+  const _app = new Vue(app)
+
+  
+    // Load layout
+  const layout = NUXT.layout || 'default'
+  await _app.loadLayout(layout)
+  _app.setLayout(layout)
+  
+
+  // Mounts Vue app to DOM element
+  const mount = () => {
+    _app.$mount('#__nuxt')
+
+    // Listen for first Vue update
+    Vue.nextTick(() => {
+      // Call window.onNuxtReady callbacks
+      nuxtReady(_app)
+      
+    })
+  }
+
+  // Enable transitions
+  _app.setTransitions = _app.$options.nuxt.setTransitions.bind(_app)
+  if (Components.length) {
+    _app.setTransitions(mapTransitions(Components, router.currentRoute))
+    _lastPaths = router.currentRoute.matched.map(route => compile(route.path)(router.currentRoute.params))
+  }
+
+  // Initialize error handler
+  _app.$loading = {} // To avoid error while _app.$nuxt does not exist
+  if (NUXT.error) _app.error(NUXT.error)
+
+  // Add router hooks
+  router.beforeEach(loadAsyncComponents.bind(_app))
+  router.beforeEach(render.bind(_app))
+  router.afterEach(normalizeComponents)
+  router.afterEach(fixPrepatch.bind(_app))
+
+  // If page already is server rendered
+  if (NUXT.serverRendered) {
+    mount()
+    return
+  }
+
+  // First render on client-side
+  render.call(_app, router.currentRoute, router.currentRoute, (path) => {
+    // If not redirected
+    if (!path) {
+      normalizeComponents(router.currentRoute, router.currentRoute)
+      showNextPage.call(_app, router.currentRoute)
+      // Dont call fixPrepatch.call(_app, router.currentRoute, router.currentRoute) since it's first render
+      mount()
+      return
+    }
+
+    // Push the path and then mount app
+    router.push(path, () => mount(), (err) => {
+      if (!err) return mount()
+      console.error(err)
+    })
+  })
+}

+ 36 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/components/no-ssr.js

@@ -0,0 +1,36 @@
+/*
+** From https://github.com/egoist/vue-no-ssr
+** With the authorization of @egoist
+*/
+export default {
+  name: 'no-ssr',
+  props: ['placeholder'],
+  data () {
+    return {
+      canRender: false
+    }
+  },
+  mounted () {
+    this.canRender = true
+  },
+  render (h) {
+    if (this.canRender) {
+      if (
+        process.env.NODE_ENV === 'development' &&
+        this.$slots.default &&
+        this.$slots.default.length > 1
+      ) {
+        throw new Error('<no-ssr> You cannot use multiple child components')
+      }
+      return this.$slots.default && this.$slots.default[0]
+    }
+    
+    return h(
+      'div',
+      {
+        class: ['no-ssr-placeholder']
+      },
+      this.$slots.placeholder || this.placeholder
+    )
+  }
+}

+ 86 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-child.js

@@ -0,0 +1,86 @@
+export default {
+  name: 'nuxt-child',
+  functional: true,
+  props: ['keepAlive'],
+  render (h, { parent, data, props }) {
+    data.nuxtChild = true
+    const _parent = parent
+    const transitions = parent.$nuxt.nuxt.transitions
+    const defaultTransition = parent.$nuxt.nuxt.defaultTransition
+
+    let depth = 0
+    while (parent) {
+      if (parent.$vnode && parent.$vnode.data.nuxtChild) {
+        depth++
+      }
+      parent = parent.$parent
+    }
+    data.nuxtChildDepth = depth
+    const transition = transitions[depth] || defaultTransition
+    let transitionProps = {}
+    transitionsKeys.forEach((key) => {
+      if (typeof transition[key] !== 'undefined') {
+        transitionProps[key] = transition[key]
+      }
+    })
+    let listeners = {}
+    listenersKeys.forEach((key) => {
+      if (typeof transition[key] === 'function') {
+        listeners[key] = transition[key].bind(_parent)
+      }
+    })
+    // Add triggerScroll event on beforeEnter (fix #1376)
+    let beforeEnter = listeners.beforeEnter
+    listeners.beforeEnter = (el) => {
+      window.$nuxt.$emit('triggerScroll')
+      if (beforeEnter) return beforeEnter.call(_parent, el)
+    }
+
+    let routerView = [
+      h('router-view', data)
+    ]
+    if (typeof props.keepAlive !== 'undefined') {
+      routerView = [
+        h('keep-alive', routerView)
+      ]
+    }
+    return h('transition', {
+      props: transitionProps,
+      on: listeners
+    }, routerView)
+  }
+}
+
+const transitionsKeys = [
+  'name',
+  'mode',
+  'appear',
+  'css',
+  'type',
+  'duration',
+  'enterClass',
+  'leaveClass',
+  'appearClass',
+  'enterActiveClass',
+  'enterActiveClass',
+  'leaveActiveClass',
+  'appearActiveClass',
+  'enterToClass',
+  'leaveToClass',
+  'appearToClass'
+]
+
+const listenersKeys = [
+  'beforeEnter',
+  'enter',
+  'afterEnter',
+  'enterCancelled',
+  'beforeLeave',
+  'leave',
+  'afterLeave',
+  'leaveCancelled',
+  'beforeAppear',
+  'appear',
+  'afterAppear',
+  'appearCancelled'
+]

+ 90 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-error.vue

@@ -0,0 +1,90 @@
+<template>
+<div class="__nuxt-error-page">
+<div class="error">
+  <svg xmlns="http://www.w3.org/2000/svg" width="90" height="90" fill="#DBE1EC" viewBox="0 0 48 48"><path d="M22 30h4v4h-4zm0-16h4v12h-4zm1.99-10C12.94 4 4 12.95 4 24s8.94 20 19.99 20S44 35.05 44 24 35.04 4 23.99 4zM24 40c-8.84 0-16-7.16-16-16S15.16 8 24 8s16 7.16 16 16-7.16 16-16 16z"/></svg>
+
+  <div class="title">{{ message }}</div>
+  <p class="description" v-if="statusCode === 404">
+    <nuxt-link class="error-link" to="/">Back to the home page</nuxt-link>
+  </p>
+  
+
+  <div class="logo">
+    <a href="https://nuxtjs.org" target="_blank" rel="noopener">Nuxt.js</a>
+  </div>
+</div>
+</div>
+</template>
+
+<script>
+export default {
+  name: 'nuxt-error',
+  props: ['error'],
+  head () {
+    return {
+      title: this.message,
+      meta: [
+        {
+          name: 'viewport',
+          content: 'width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'
+        }
+      ]
+    }
+  },
+  
+  computed: {
+    statusCode () {
+      return (this.error && this.error.statusCode) || 500
+    },
+    message () {
+      return this.error.message || 'Error'
+    }
+  }
+}
+</script>
+
+<style>
+.__nuxt-error-page {
+  padding: 1rem;
+  background: #F7F8FB;
+  color: #47494E;
+  text-align: center;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: column;
+  font-family: sans-serif;
+  font-weight: 100 !important;
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+  -webkit-font-smoothing: antialiased; 
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+}
+.__nuxt-error-page .error {
+  max-width: 450px;
+}
+.__nuxt-error-page .title {
+  font-size: 1.5rem;
+  margin-top: 15px;
+  color: #47494E;
+  margin-bottom: 8px; 
+}
+.__nuxt-error-page .description {
+  color: #7F828B;
+  line-height: 21px;
+  margin-bottom: 10px;
+}
+.__nuxt-error-page a {
+  color: #7F828B !important;
+  text-decoration: none;
+}
+.__nuxt-error-page .logo {
+  position: fixed;
+  left: 12px;
+  bottom: 12px;
+}
+</style>

+ 7 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-link.js

@@ -0,0 +1,7 @@
+export default {
+  name: 'nuxt-link',
+  functional: true,
+  render (h, { data, children }) {
+    return h('router-link', data, children)
+  }
+}

+ 103 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt-loading.vue

@@ -0,0 +1,103 @@
+<template>
+  <div class="nuxt-progress" :style="{
+    'width': percent+'%',
+    'height': height,
+    'background-color': canSuccess? color : failedColor,
+    'opacity': show ? 1 : 0
+  }"></div>
+</template>
+
+<script>
+import Vue from 'vue'
+
+export default {
+  name: 'nuxt-loading',
+  data () {
+    return {
+      percent: 0,
+      show: false,
+      canSuccess: true,
+      duration: 5000,
+      height: '2px',
+      color: '#3B8070',
+      failedColor: 'red',
+    }
+  },
+  methods: {
+    start () {
+      this.show = true
+      this.canSuccess = true
+      if (this._timer) {
+        clearInterval(this._timer)
+        this.percent = 0
+      }
+      this._cut = 10000 / Math.floor(this.duration)
+      this._timer = setInterval(() => {
+        this.increase(this._cut * Math.random())
+        if (this.percent > 95) {
+          this.finish()
+        }
+      }, 100)
+      return this
+    },
+    set (num) {
+      this.show = true
+      this.canSuccess = true
+      this.percent = Math.floor(num)
+      return this
+    },
+    get () {
+      return Math.floor(this.percent)
+    },
+    increase (num) {
+      this.percent = this.percent + Math.floor(num)
+      return this
+    },
+    decrease (num) {
+      this.percent = this.percent - Math.floor(num)
+      return this
+    },
+    finish () {
+      this.percent = 100
+      this.hide()
+      return this
+    },
+    pause () {
+      clearInterval(this._timer)
+      return this
+    },
+    hide () {
+      clearInterval(this._timer)
+      this._timer = null
+      setTimeout(() => {
+        this.show = false
+        Vue.nextTick(() => {
+          setTimeout(() => {
+            this.percent = 0
+          }, 200)
+        })
+      }, 500)
+      return this
+    },
+    fail () {
+      this.canSuccess = false
+      return this
+    }
+  }
+}
+</script>
+
+<style>
+.nuxt-progress {
+  position: fixed;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  height: 2px;
+  width: 0%;
+  transition: width 0.2s, opacity 0.4s;
+  opacity: 1;
+  background-color: #efc14e;
+  z-index: 999999;
+}
+</style>

+ 44 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/components/nuxt.js

@@ -0,0 +1,44 @@
+import Vue from 'vue'
+import NuxtChild from './nuxt-child'
+import NuxtError from '../../src/layouts/error.vue'
+import { compile } from '../utils'
+
+export default {
+  name: 'nuxt',
+  props: ['nuxtChildKey', 'keepAlive'],
+  render(h) {
+    // If there is some error
+    if (this.nuxt.err) {
+      return h('nuxt-error', {
+        props: {
+          error: this.nuxt.err
+        }
+      })
+    }
+    // Directly return nuxt child
+    return h('nuxt-child', {
+      key: this.routerViewKey,
+      props: this.$props
+    })
+  },
+  beforeCreate () {
+    Vue.util.defineReactive(this, 'nuxt', this.$root.$options.nuxt)
+  },
+  computed: {
+    routerViewKey () {
+      // If nuxtChildKey prop is given or current route has children
+      if (typeof this.nuxtChildKey !== 'undefined' || this.$route.matched.length > 1) {
+        return this.nuxtChildKey || compile(this.$route.matched[0].path)(this.$route.params)
+      }
+      const Component = this.$route.matched[0] && this.$route.matched[0].components.default
+      if (Component && Component.options && Component.options.key) {
+        return (typeof Component.options.key === 'function' ? Component.options.key(this.$route) : Component.options.key)
+      }
+      return this.$route.path
+    }
+  },
+  components: {
+    NuxtChild,
+    NuxtError
+  }
+}

+ 245 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/LICENSES

@@ -0,0 +1,245 @@
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/**!
+ * Sortable
+ * @author	RubaXa   <trash@rubaxa.org>
+ * @author	owenm    <owen23355@gmail.com>
+ * @license MIT
+ */
+
+/*!
+ * Vue.js v2.6.10
+ * (c) 2014-2019 Evan You
+ * Released under the MIT License.
+ */
+
+/*!
+ * negotiator
+ * Copyright(c) 2012 Federico Romero
+ * Copyright(c) 2012-2014 Isaac Z. Schlueter
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+/**
+ * vuex v3.1.1
+ * (c) 2019 Evan You
+ * @license MIT
+ */
+
+/*!
+ * Determine if an object is a Buffer
+ *
+ * @author   Feross Aboukhadijeh <https://feross.org>
+ * @license  MIT
+ */
+
+/*!
+ * vue-i18n v7.8.1 
+ * (c) 2018 kazuya kawaguchi
+ * Released under the MIT License.
+ */
+
+/*!
+ * vuex-class v0.2.0
+ * https://github.com/ktsn/vuex-class
+ *
+ * @license
+ * Copyright (c) 2017 katashin
+ * Released under the MIT license
+ * https://github.com/ktsn/vuex-class/blob/master/LICENSE
+ */
+
+/**
+ * Checks if an event is supported in the current execution environment.
+ *
+ * NOTE: This will not work correctly for non-generic events such as `change`,
+ * `reset`, `load`, `error`, and `select`.
+ *
+ * Borrows from Modernizr.
+ *
+ * @param {string} eventNameSuffix Event name, e.g. "click".
+ * @param {?boolean} capture Check if the capture phase is supported.
+ * @return {boolean} True if the event is supported.
+ * @internal
+ * @license Modernizr 3.0.0pre (Custom Build) | MIT
+ */
+
+/**
+  * vue-class-component v5.0.2
+  * (c) 2015-2017 Evan You
+  * @license MIT
+  */
+
+/*!
+ * @overview es6-promise - a tiny implementation of Promises/A+.
+ * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
+ * @license   Licensed under MIT license
+ *            See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
+ * @version   v4.2.8+1e68dce6
+ */
+
+/*!
+ * Chart.js v2.8.0
+ * https://www.chartjs.org
+ * (c) 2019 Chart.js Contributors
+ * Released under the MIT License
+ */
+
+/*!
+ * JavaScript Cookie v2.2.0
+ * https://github.com/js-cookie/js-cookie
+ *
+ * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
+ * Released under the MIT license
+ */
+
+/**
+ * vue-meta v1.6.0
+ * (c) 2019 Declan de Wet & Sébastien Chopin (@Atinux)
+ * @license MIT
+ */
+
+/*
+	object-assign
+	(c) Sindre Sorhus
+	@license MIT
+	*/
+
+/*!
+ * cookie
+ * Copyright(c) 2012-2014 Roman Shtylman
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */

BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/element-icons.535877f.woff


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/element-icons.732389d.ttf


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/freedom.9a41c47.woff


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/fonts/freedom.9a9e952.ttf


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/Background.ee599d0.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/QRcode.77de9cb.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/avatar-default.9427a1d.jpg


+ 29 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/avatar.163a4fa.svg

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
+    <title>头像</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <circle id="path-1" cx="11" cy="11" r="11"></circle>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="SaaS-运营首页" transform="translate(-1124.000000, -19.000000)">
+            <g id="Group-3" transform="translate(1106.000000, 0.000000)">
+                <g id="Group-2" transform="translate(18.000000, 19.000000)">
+                    <g id="头像">
+                        <mask id="mask-2" fill="white">
+                            <use xlink:href="#path-1"></use>
+                        </mask>
+                        <use id="Mask" fill="#C0CCDA" xlink:href="#path-1"></use>
+                        <g mask="url(#mask-2)" id="Shape" fill-rule="nonzero" fill="#99A9BF">
+                            <g transform="translate(1.000000, 3.000000)">
+                                <path d="M10.0043799,11.5624914 C12.7065552,11.5624914 14.8177418,9.19954205 15.1384659,5.81622683 C15.3256603,3.85928108 14.8807868,2.30196336 13.8535109,1.31210748 C12.9671454,0.457188279 11.6718691,0.0235277098 10.0044093,0.0235277098 C8.33697891,0.0235277098 7.04170261,0.457188279 6.15527833,1.31155434 C5.12803181,2.30138111 4.68365816,3.85928108 4.87038213,5.81622683 C5.19210606,9.19954205 7.30396894,11.5624914 10.0043799,11.5624914 Z"></path>
+                                <path d="M14.5921439,12.3323438 C14.3665166,12.2784564 14.1341261,12.2506539 13.8809755,12.2506539 C13.6095641,12.2506539 13.3524437,12.3039881 13.1560748,12.3991862 C13.1377259,12.4077162 11.3271208,13.3391431 10.0043799,13.3391431 C8.68163902,13.3391431 6.87100457,12.4077161 6.85274385,12.3991862 C6.6562573,12.3039881 6.39919572,12.2506539 6.12772552,12.2506539 C5.87469247,12.2506539 5.64218437,12.2784564 5.41655713,12.3323438 C3.87909836,12.6985506 0.00876614943,14.2098996 0.00876614943,16.6448734 C0.00876614943,19.0995564 5.17146353,19.9737773 10.0043505,19.9737773 C14.83662,19.9737773 19.9999055,19.0995855 19.9999055,16.6448734 C19.9999349,14.2098996 16.1296614,12.6985506 14.5921439,12.3323438 Z"></path>
+                            </g>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/basic.af98eae.png


Разница между файлами не показана из-за своего большого размера
+ 154 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/freedom.0162e96.svg


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/login-bg.33a8e3e.jpeg


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/login_bg1.33a8e3e.jpg


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo.1520abb.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo2.39f8545.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo3.e040e7b.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/logo_white.858d9b2.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/major.0578e82.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/materialstorehouse.4fe636a.jpg


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/special.be6b59e.png


BIN
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/img/title_biobank.c291298.png


+ 9 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/index.spa.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html {{ HTML_ATTRS }}>
+  <head>
+    {{ HEAD }}
+  <link href="/_nuxt/shanlan.82976de89dda.css" rel="stylesheet"></head>
+  <body {{ BODY_ATTRS }}>
+    {{ APP }}
+  <script type="text/javascript" src="/_nuxt/manifest.85e92be33b3940dbc59d.js"></script><script type="text/javascript" src="/_nuxt/vendor.85e92be33b39.js"></script><script type="text/javascript" src="/_nuxt/shanlan.7e34f9e5f7ac.js"></script></body>
+</html>

+ 9 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/index.ssr.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html {{ HTML_ATTRS }}>
+  <head>
+    {{ HEAD }}
+  </head>
+  <body {{ BODY_ATTRS }}>
+    {{ APP }}
+  </body>
+</html>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/layouts/default.11646d6d8edf3e3f4966.js


+ 1 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/layouts/empty.2fe37028bfb282ac8cba.js

@@ -0,0 +1 @@
+webpackJsonp([196],{Bz4r:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var s=n("onwN"),a=n("L+Sh"),i=!1;var r=function(t){i||n("OiTO")},o=n("VU/8")(s.a,a.a,!1,r,"data-v-4516dbbe",null);o.options.__file="src/layouts/empty.vue",e.default=o.exports},EtGP:function(t,e,n){(t.exports=n("FZ+f")(!1)).push([t.i,".app[data-v-4516dbbe]{height:100%}",""])},"L+Sh":function(t,e,n){"use strict";var s=function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"empty"},[e("nuxt")],1)};s._withStripped=!0;var a={render:s,staticRenderFns:[]};e.a=a},OiTO:function(t,e,n){var s=n("EtGP");"string"==typeof s&&(s=[[t.i,s,""]]),s.locals&&(t.exports=s.locals);n("rjj0")("34e08f7c",s,!1,{sourceMap:!1})},onwN:function(t,e,n){"use strict";e.a={}}});

+ 1 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/layouts/office.5ab89413518144933e62.js

@@ -0,0 +1 @@
+webpackJsonp([198],{"3VaV":function(t,e,n){"use strict";e.a={}},"N/rb":function(t,e,n){"use strict";var r=function(){var t=this.$createElement;return(this._self._c||t)("nuxt",{staticStyle:{height:"100%"}})};r._withStripped=!0;var i={render:r,staticRenderFns:[]};e.a=i},g1hT:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n("3VaV"),i=n("N/rb"),s=n("VU/8")(r.a,i.a,!1,null,null,null);s.options.__file="src/layouts/office.vue",e.default=s.exports}});

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/manifest.85e92be33b3940dbc59d.js


+ 1 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/about.70e386b9b0e632ba80b9.js

@@ -0,0 +1 @@
+webpackJsonp([197],{"4bUM":function(t,e,n){"use strict";var a=function(){var t=this.$createElement;this._self._c;return this._m(0)};a._withStripped=!0;var s={render:a,staticRenderFns:[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"content"},[e("h1",[this._v("About Page")]),e("p",[this._v("Hello, I am the about page :)")])])}]};e.a=s},M8Tx:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("4bUM"),s=!1;var i=function(t){s||n("T75f")},r=n("VU/8")(null,a.a,!1,i,"data-v-96c0458e",null);r.options.__file="src/pages/about.vue",e.default=r.exports},T75f:function(t,e,n){var a=n("j0wK");"string"==typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);n("rjj0")("35580fe8",a,!1,{sourceMap:!1})},j0wK:function(t,e,n){(t.exports=n("FZ+f")(!1)).push([t.i,".content[data-v-96c0458e]{padding-top:20px}",""])}});

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/authcode.e4a63959cb9f7e341cef.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/allsearch/_opera/operation.01ea210b7f9e44917d41.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/allsearch/index.c1929320ffb664294f19.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/book/_opera/operation.63bb94047e3c341f3f49.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/book/index.d11d4af1d4b3eec20455.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/partner/index.a3b30eb385b452942588.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/partner/organize.a7ccc22b6a1aaf6e7b60.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/project/_opera/operation.2f16e53a75a59b23958f.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/project/index.76d4a24fe267c263f9cb.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/_opera/operation.23482b8a79a890b613e3.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/_opera/protocoledit.f26c66f2d2233dafa052.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/index.deae3ec7f3775db7b5fa.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/protocol/protocoladd.6c382df5cca8abaa3a8a.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleCK/_opera/operation.ef0fd1d035d73f19bbcd.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleCK/index.91714a92a47c658d6a15.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleRK/_opera/operation.fdd29412842b0156715f.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampleRK/index.9452fa731bcdb1ceb171.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampletest/_opera/operation.5eb07cdf993ad856d33f.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sampletest/index.ba5e977cfacb8f93606d.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/service/_opera/operation.d18e8b091ba996a70361.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/service/complated.1ffad94e062d26ed4852.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/service/index.9d5c01e8f2a32f118e12.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/operation.a1fe78d5cfb5c7a7e7e3.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/operationb.9b6ffc8f866e32566240.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/operationc.8459dbe704734223f846.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/sourcedetail.4a0ba64caa2d0309da46.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/sourceinfo.38be3665711e1a7f7f92.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/_opera/sourcemicinfo.fea9debf11544a0fb127.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/animal.4b8f117622c13e51a903.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/index.9d0b950b6ba75b718e1c.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/source/micro.da22968b904eee83046d.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sourcextends/_opera/operation.cca02cd474c90c905915.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/biobank/sourcextends/index.619cc0cfd21f7d374204.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/_opera/dochistory.9ab1d959a9f20adaec1c.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/_opera/edit.8888c99162e1ccd580c5.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/_opera/uploadnewdoc.a09e7f0834b2392bd21f.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/add.0a0035e7bd3f27fdca5f.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/documentmanage/index.30e345044f3b74f55b70.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/_opera/donorsdetail.fe19f811e01df52f873e.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/_opera/donorsedit.3472151b59f16c828438.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/donorsadd.85c3a286eee6b674e1de.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/donors/index.416cd97bfdad55927130.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/extends/_opera/extendsedit.a57017008dfdcce87a48.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/extends/extendsadd.1f05d0798d4885ed5e27.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/extends/index.26f8d1033c3e58a344f5.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/_opera/familymandetail.cb0eb3849a50da646199.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/_opera/familymanedit.725beb0b5ca6c3d93c61.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/_opera/pedigreemap.23573f7bf21109ac9076.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/familymanadd.e3f907b69deaed60aafd.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/familyman/index.10079c805805a9766e7c.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/_opera/flupplanedit.6bae5ab6975a23a403e9.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/_opera/fluprecorddetail.adf526f0dd21ecb3fac8.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/_opera/fluprecordedit.3624dc56e215592e5908.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/flupplanadd.8d35ea806d5f0aeee89e.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/fluprecord.b629b00026936fbd980b.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/fluprecordadd.79dbf4047165017910c3.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
src/dashoo.cn/biobank_spark/frontend/.nuxt/dist/pages/donors/flupplan/index.e2a6b43f7168306bddb2.js


Некоторые файлы не были показаны из-за большого количества измененных файлов