guhongwei 2 年之前
父节点
当前提交
dc2f9f4835

+ 0 - 46
README.md

@@ -1,46 +0,0 @@
-# jcyjdt_studio
-
-This template should help get you started developing with Vue 3 in Vite.
-
-## Recommended IDE Setup
-
-[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
-
-## Type Support for `.vue` Imports in TS
-
-TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
-
-If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
-
-1. Disable the built-in TypeScript Extension
-    1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
-    2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
-2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
-
-## Customize configuration
-
-See [Vite Configuration Reference](https://vitejs.dev/config/).
-
-## Project Setup
-
-```sh
-npm install
-```
-
-### Compile and Hot-Reload for Development
-
-```sh
-npm run dev
-```
-
-### Type-Check, Compile and Minify for Production
-
-```sh
-npm run build
-```
-
-### Lint with [ESLint](https://eslint.org/)
-
-```sh
-npm run lint
-```

+ 1 - 1
index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <link rel="icon" href="/favicon.ico">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Vite App</title>
+    <title>加载中...</title>
   </head>
   <body>
     <div id="app"></div>

+ 1 - 3
src/App.vue

@@ -1,8 +1,6 @@
 <template>
   <div>
-    <Suspense>
-      <router-view />
-    </Suspense>
+    <router-view />
   </div>
 </template>
 

+ 3 - 8
src/main.ts

@@ -1,26 +1,21 @@
 import { createApp } from 'vue';
 import { createPinia } from 'pinia';
-
 import App from './App.vue';
 import router from './router';
-
-import './assets/main.css';
-import 'animate.css';
-
 import ElementPlus from 'element-plus';
 import 'element-plus/theme-chalk/index.css';
 import locale from 'element-plus/lib/locale/lang/zh-cn';
 import moment from 'moment';
-import _ from 'lodash';
+import '@/assets/main.css';
+import 'animate.css';
 import * as ElementPlusIconsVue from '@element-plus/icons-vue';
 const app = createApp(App);
-app.config.globalProperties.$limit = parseInt(import.meta.env.VITE_APP_PAGE_SIZE) || 10;
 app.use(createPinia());
 app.use(router);
 app.use(ElementPlus, { locale });
-
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   app.component(key, component);
 }
 app.config.globalProperties.$moment = moment;
+app.config.globalProperties.$limit = parseInt(import.meta.env.VITE_APP_PAGE_SIZE) || 10;
 app.mount('#app');

+ 8 - 52
src/router/index.ts

@@ -1,34 +1,8 @@
 import { createRouter, createWebHistory } from 'vue-router';
 import store from '@/stores/counter';
-
-// 公共
-import common from './module/common';
-// 管理员
-import admin from './module/admin';
-// 个人用户
-import users from './module/users';
-// 企业用户
-import unit from './module/unit';
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
   routes: [
-    // 公共
-    ...common,
-    // {
-    //   path: '/homeIndex',
-    //   meta: { title: '基础研究动态管理平台', is_filter: true },
-    //   component: () => import('@common/src/components/studio-one-green/home.vue'),
-    //   children: [
-    //     {
-    //       path: '/homeIndex',
-    //       meta: { title: '基础研究动态管理平台', is_filter: true },
-    //       component: () => import('@/views/home/index.vue'),
-    //     },
-    //     ...admin,
-    //     ...users,
-    //     ...unit,
-    //   ],
-    // },
     {
       path: '/',
       meta: { title: '基础研究动态管理平台', is_filter: true },
@@ -50,33 +24,15 @@ router.beforeEach((to, from, next) => {
   if (token) {
     // let user = jwt.decode(token);
     const user = {
-      _id: '63b511fa2f41cd4838e478bb',
-      account: 'sunit',
-      card: '220182199603257020',
-      name: '公司负责人',
-      nick_name: '长春市福瑞科技有限公司',
-      email: '1946230922@qq.com',
-      phone: '13174420325',
-      unit_name: '长春市福瑞科技有限公司',
-      unit_address: '长春市朝阳区前进大街1244号',
-      prove: [
-        {
-          id: '20230104134319',
-          name: 'free.png',
-          uri: '/files/jcyjdt/register/20230104134319.png',
-          url: 'http://broadcast.waityou24.cn/files/jcyjdt/register/20230104134319.png',
-          uid: 1672810999458,
-          status: 'success',
-        },
-      ],
-      role: ['63b628619bb09c9905df137b', '63b64a9435df6c6862e0c882', '63b64b4435df6c6862e12d84', '63b62cf19bb09c9905e17543'],
-      exam_status: '1',
-      is_studio: 'Y',
-      role_type: '3',
-      iat: 1679033671,
-      exp: 1679206471,
+      _id: '63b3ed3e404c08bbd8539965',
+      account: 'admin',
+      name: '管理员',
+      role: ['63b641cf35df6c6862df5d39', '63b628199bb09c9905def4cc', '63b64b1f35df6c6862e11bf2', '63b62cac9bb09c9905e14857'],
+      is_super: false,
+      role_type: '1',
+      iat: 1679041521,
+      exp: 1679214321,
     };
-    console.log(store);
     store.commit('setUser', user, { root: true });
     next();
   } else {

+ 0 - 126
src/router/module/admin.ts

@@ -1,126 +0,0 @@
-export default [
-  // 用户管理
-  {
-    path: '/center/users/company',
-    meta: { title: '依托单位', is_filter: true },
-    component: () => import('@/views/center/users/company/index.vue'),
-  },
-  {
-    path: '/center/users/company/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/center/users/company/info.vue'),
-  },
-  {
-    path: '/center/users/scientist',
-    meta: { title: '科学家', is_filter: true },
-    component: () => import('@/views/center/users/scientist/index.vue'),
-  },
-  {
-    path: '/center/users/scientist/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/center/users/scientist/info.vue'),
-  },
-  // 科学家工作室
-  {
-    path: '/center/studio/info',
-    meta: { title: '信息列表', is_filter: true },
-    component: () => import('@/views/center/studio/info/index.vue'),
-  },
-  {
-    path: '/center/studio/info/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/center/studio/info/info.vue'),
-  },
-  {
-    path: '/center/studio/info/export',
-    meta: { title: '导出PDF', is_filter: true },
-    component: () => import('@/views/center/studio/info/export.vue'),
-  },
-  {
-    path: '/center/studio/year',
-    meta: { title: '年度报告', is_filter: true },
-    component: () => import('@/views/center/studio/year/index.vue'),
-  },
-  {
-    path: '/center/studio/flair',
-    meta: { title: '保留资质', is_filter: true },
-    component: () => import('@/views/center/studio/flair/index.vue'),
-  },
-  // 技术供求
-  {
-    path: '/center/supplydemand/support',
-    meta: { title: '技术支持', is_filter: true },
-    component: () => import('@/views/center/supplydemand/support/index.vue'),
-  },
-  {
-    path: '/center/supplydemand/support/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/center/supplydemand/support/info.vue'),
-  },
-  {
-    path: '/center/supplydemand/demand',
-    meta: { title: '技术需求', is_filter: true },
-    component: () => import('@/views/center/supplydemand/demand/index.vue'),
-  },
-  {
-    path: '/center/supplydemand/demand/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/center/supplydemand/demand/info.vue'),
-  },
-  // 其他内容
-  {
-    path: '/center/other/achieve',
-    meta: { title: '成果展示', is_filter: true },
-    component: () => import('@/views/center/other/achieve/index.vue'),
-  },
-  {
-    path: '/center/other/achieve/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/center/other/achieve/info.vue'),
-  },
-  {
-    path: '/center/other/notice',
-    meta: { title: '通知公告', is_filter: true },
-    component: () => import('@/views/center/other/notice/index.vue'),
-  },
-  {
-    path: '/center/other/notice/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/center/other/notice/add.vue'),
-  },
-  {
-    path: '/center/other/download',
-    meta: { title: '相关下载', is_filter: true },
-    component: () => import('@/views/center/other/download/index.vue'),
-  },
-  {
-    path: '/center/other/download/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/center/other/download/add.vue'),
-  },
-  {
-    path: '/center/other/contact',
-    meta: { title: '联系处室', is_filter: true },
-    component: () => import('@/views/center/other/contact/index.vue'),
-  },
-  {
-    path: '/center/other/message',
-    meta: { title: '系统消息', is_filter: true },
-    component: () => import('@/views/center/other/message/index.vue'),
-  },
-  {
-    path: '/center/other/message',
-    meta: { title: '系统消息', is_filter: true },
-    component: () => import('@/views/center/other/message/index.vue'),
-  },
-  {
-    path: '/center/other/message/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/center/other/message/add.vue'),
-  },
-  {
-    path: '/userInfo/center',
-    meta: { title: '个人中心', is_filter: true },
-    component: () => import('@/views/userInfo/center/index.vue'),
-  },
-];

+ 0 - 1
src/router/module/common.ts

@@ -1 +0,0 @@
-export default [];

+ 0 - 94
src/router/module/unit.ts

@@ -1,94 +0,0 @@
-export default [
-  // 个人中心
-  {
-    path: '/unit/center',
-    meta: { title: '个人中心', is_filter: true },
-    component: () => import('@/views/unit/center/index.vue'),
-  },
-  {
-    path: '/unit/builddesire',
-    meta: { title: '发布工作室建设意愿', is_filter: true },
-    component: () => import('@/views/unit/builddesire/index.vue'),
-  },
-  {
-    path: '/unit/builddesire/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/unit/builddesire/add.vue'),
-  },
-  // 科学家工作室申报
-  {
-    path: '/unit/studio',
-    meta: { title: '科学家工作室', is_filter: true },
-    component: () => import('@/views/unit/studio/index.vue'),
-  },
-  {
-    path: '/unit/studio/add',
-    meta: { title: '申报进度', is_filter: true },
-    component: () => import('@/views/unit/studio/add.vue'),
-  },
-  {
-    path: '/unit/scientist',
-    meta: { title: '入驻科学家', is_filter: true },
-    component: () => import('@/views/unit/scientist/index.vue'),
-  },
-  {
-    path: '/unit/scientist/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/unit/scientist/add.vue'),
-  },
-  {
-    path: '/unit/achieve',
-    meta: { title: '发布合作成果', is_filter: true },
-    component: () => import('@/views/unit/achieve/index.vue'),
-  },
-  {
-    path: '/unit/achieve/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/unit/achieve/add.vue'),
-  },
-  {
-    path: '/unit/achieve/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/unit/achieve/info.vue'),
-  },
-  {
-    path: '/unit/yearreport',
-    meta: { title: '年度报告', is_filter: true },
-    component: () => import('@/views/unit/yearreport/index.vue'),
-  },
-  {
-    path: '/unit/yearreport/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/unit/yearreport/add.vue'),
-  },
-  {
-    path: '/unit/applyflair',
-    meta: { title: '保留资质', is_filter: true },
-    component: () => import('@/views/unit/applyflair/index.vue'),
-  },
-  {
-    path: '/unit/applyflair/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/unit/applyflair/add.vue'),
-  },
-  {
-    path: '/unit/contactoffice',
-    meta: { title: '联系处室', is_filter: true },
-    component: () => import('@/views/unit/contactoffice/index.vue'),
-  },
-  {
-    path: '/unit/demand',
-    meta: { title: '发布技术需求', is_filter: true },
-    component: () => import('@/views/unit/demand/index.vue'),
-  },
-  {
-    path: '/unit/demand/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/unit/demand/add.vue'),
-  },
-  {
-    path: '/unit/demand/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/unit/demand/info.vue'),
-  },
-];

+ 0 - 33
src/router/module/users.ts

@@ -1,33 +0,0 @@
-export default [
-  // 个人中心
-  {
-    path: '/user/center',
-    meta: { title: '个人中心', is_filter: true },
-    component: () => import('@/views/user/center/index.vue'),
-  },
-  {
-    path: '/user/scientist/studio',
-    meta: { title: '入驻科学家工作室', is_filter: true },
-    component: () => import('@/views/user/scientist/studio/index.vue'),
-  },
-  {
-    path: '/user/scientist/studio/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/user/scientist/studio/info.vue'),
-  },
-  {
-    path: '/user/support',
-    meta: { title: '发布技术支持', is_filter: true },
-    component: () => import('@/views/user/support/index.vue'),
-  },
-  {
-    path: '/user/support/add',
-    meta: { title: '信息管理', is_filter: true },
-    component: () => import('@/views/user/support/add.vue'),
-  },
-  {
-    path: '/user/support/info',
-    meta: { title: '详细信息', is_filter: true },
-    component: () => import('@/views/user/support/info.vue'),
-  },
-];

+ 4 - 0
src/stores/counter.ts

@@ -29,6 +29,10 @@
 
 import * as ustate from '@common/src/stores/user/state';
 import * as umutations from '@common/src/stores/user/mutations';
+// // 平台项目管理
+// import * as module from '@common/src/stores/admin/module';
+// // 角色
+// import * as role from '@common/src/stores/admin/role';
 import { createStore } from 'vuex';
 const store = createStore({
   state: { ...ustate },

+ 150 - 0
src/util/axios-wrapper.ts

@@ -0,0 +1,150 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import _ from 'lodash';
+import Axios from 'axios';
+import { Util, Error } from 'naf-core';
+// import { Indicator } from 'mint-ui';
+import type { IOptionsType, IQueryType, IRequestResult } from './types.util';
+
+const { trimData, isNullOrUndefined } = Util;
+const { ErrorCode } = Error;
+
+let currentRequests = 0;
+
+// // 参数类型设置
+// type valueType = string | number | object | boolean | Array<any>;
+// type queryType = string | number | boolean;
+
+// export interface IQueryType {
+//   [props: string]: queryType;
+// }
+// export interface IOptionsType {
+//   [props: string]: valueType;
+// }
+
+// export interface IRequestResult {
+//   errcode: string | number;
+//   errmsg: string | number;
+//   details?: string;
+//   [props: string]: any;
+// }
+
+export class AxiosWrapper {
+  constructor({ baseUrl = import.meta.env.VITE_REQUEST_BASE, unwrap = true } = {}) {
+    this.baseUrl = baseUrl;
+    this.unwrap = unwrap;
+  }
+  baseUrl: string;
+  unwrap: boolean;
+
+  // 替换uri中的参数变量
+  static merge(uri: string, query: IQueryType) {
+    if (!uri.includes(':')) {
+      return uri;
+    }
+    const keys = [];
+    const regexp = /\/:([a-z0-9_]+)/gi;
+    let res;
+    // eslint-disable-next-line no-cond-assign
+    while ((res = regexp.exec(uri)) != null) {
+      keys.push(res[1]);
+    }
+    keys.forEach((key) => {
+      const val = _.get(query, key);
+      if (!isNullOrUndefined(val)) {
+        uri = uri.replace(`:${key}`, `${val}`);
+      }
+    });
+    return uri;
+  }
+
+  $get(uri: string, query?: IQueryType, options?: IOptionsType) {
+    return this.$request(uri, undefined, query, options);
+  }
+
+  $post(uri: string, data: object = {}, query?: IQueryType, options?: IOptionsType) {
+    return this.$request(uri, data, query, options);
+  }
+  $delete(uri: string, data: object = {}, query?: IQueryType, options: IOptionsType = {}) {
+    options = { ...options, method: 'delete' };
+    return this.$request(uri, data, query, options);
+  }
+  async $request(uri: string, data?: object, query?: IQueryType, options?: IOptionsType) {
+    if (query && _.isObject(query)) {
+      const keys = Object.keys(query);
+      for (const key of keys) {
+        const val = _.get(query, key);
+        if (val === '') {
+          delete query[key];
+        }
+      }
+    }
+    if (_.isObject(query) && _.isObject(options)) {
+      options = { ...options, params: query, method: 'get' };
+    } else if (_.isObject(query) && !query.params) {
+      options = { params: query };
+    } else if (_.isObject(query) && query.params) {
+      options = query;
+    }
+    if (!options) options = {};
+    if (options.params) options.params = trimData(options.params, null, null);
+    const params = _.get(options, 'params');
+    const url = AxiosWrapper.merge(uri, params as IQueryType);
+    currentRequests += 1;
+    // Indicator.open({
+    //   spinnerType: 'fading-circle',
+    // });
+    try {
+      let returnData: any;
+      const axios = Axios.create({
+        baseURL: this.baseUrl,
+      });
+      // if (util.token && util.token !== null) axios.defaults.headers.common.Authorization = util.token;
+      const token = localStorage.getItem('token');
+      const apiToken = sessionStorage.getItem('apiToken');
+      if (token) axios.defaults.headers.common['token'] = token;
+      if (apiToken) axios.defaults.headers.common['api-token'] = apiToken;
+      const res = await axios.request({
+        method: isNullOrUndefined(data) ? 'get' : 'post',
+        url,
+        data,
+        responseType: 'json',
+        ...options,
+      });
+      const returnRes: IRequestResult = res.data;
+      const { errcode, errmsg, details } = returnRes;
+      if (errcode) {
+        console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
+        return returnRes;
+      }
+      // unwrap data
+      if (this.unwrap) {
+        returnData = returnRes;
+      }
+      // 处理apiToken
+      const { apiToken: at, ...others } = returnData;
+      if (at) sessionStorage.setItem('apiToken', at);
+      return others;
+    } catch (err: any) {
+      let errmsg = '接口请求失败,请稍后重试';
+      if (err.response) {
+        const { status } = err.response;
+        if (status === 401) errmsg = '用户认证失败,请重新登录';
+        if (status === 403) errmsg = '当前用户不允许执行该操作';
+      }
+      console.error(
+        `[AxiosWrapper] 接口请求失败: ${err.config && err.config.url} - 
+        ${err.message}`
+      );
+      return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
+    } finally {
+      /* eslint-disable */
+      currentRequests -= 1;
+      if (currentRequests <= 0) {
+        currentRequests = 0;
+        // Indicator.close();
+      }
+    }
+  }
+}

+ 29 - 0
src/util/types.util.ts

@@ -0,0 +1,29 @@
+// 参数类型设置
+type valueType = string | number | Object | boolean | Array<any>;
+type queryType = string | number | boolean;
+
+export interface IQueryType {
+  [props: string]: queryType;
+}
+export interface IOptionsType {
+  [props: string]: valueType;
+}
+
+export interface IRequestResult {
+  errcode: string | number;
+  errmsg: string | number;
+  details?: string;
+  [props: string]: any;
+}
+export interface IQueryResult {
+  errcode?: string | number;
+  errmsg?: string | number;
+  data: valueType;
+  total: number;
+}
+
+export interface IQueryParams {
+  skip?: number;
+  limit?: number;
+  [props: string]: any;
+}

+ 1 - 4
src/views/home/index.vue

@@ -6,8 +6,5 @@
   </div>
 </template>
 
-<script setup lang="ts">
-import type { Ref } from 'vue';
-import { ref, toRefs } from 'vue';
-</script>
+<script setup lang="ts"></script>
 <style scoped></style>

+ 1 - 4
src/views/index.vue

@@ -6,8 +6,5 @@
   </div>
 </template>
 
-<script setup lang="ts">
-import type { Ref } from 'vue';
-import { ref, toRefs } from 'vue';
-</script>
+<script setup lang="ts"></script>
 <style scoped></style>

+ 5 - 0
tsconfig.json

@@ -2,6 +2,11 @@
   "extends": "@vue/tsconfig/tsconfig.web.json",
   "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "../common/src/stores/user", "../common/src/stores/user"],
   "compilerOptions": {
+    "target": "esnext",
+    "module": "esnext",
+    "strict": false,
+    "jsx": "preserve",
+    "moduleResolution": "node",
     "baseUrl": ".",
     "paths": {
       "@/*": ["./src/*"]

+ 10 - 2
vite.config.ts

@@ -1,14 +1,22 @@
 import { fileURLToPath, URL } from 'node:url';
-
 import { defineConfig } from 'vite';
 import vue from '@vitejs/plugin-vue';
 const path = require('path');
 const common = path.resolve(__dirname, '../common');
-// https://vitejs.dev/config/
 export default defineConfig({
   plugins: [vue()],
   server: {
     port: 20001,
+    proxy: {
+      '/files': {
+        target: 'http://basic.waityou24.cn',
+      },
+      '/jcyjdtglpt/v1/api': {
+        target: 'http://basic.waityou24.cn',
+        changeOrigin: true,
+        ws: false,
+      },
+    },
   },
   resolve: {
     alias: {