wuhongbo 1 рік тому
батько
коміт
bd18a4c9ff

+ 7 - 0
client-tool/README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)

+ 13 - 0
client-tool/index.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="/src/assets/img/avator.jpg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title></title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 23 - 0
client-tool/package.json

@@ -0,0 +1,23 @@
+{
+  "name": "vue3-zhifou",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@element-plus/icons-vue": "^2.0.10",
+    "axios": "^1.2.0",
+    "element-plus": "^2.2.25",
+    "qs": "^6.11.0",
+    "vue": "^3.2.41",
+    "vue-router": "^4.0.13"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^3.2.0",
+    "vite": "^3.2.3"
+  }
+}

+ 1 - 0
client-tool/public/vite.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

+ 9 - 0
client-tool/src/App.vue

@@ -0,0 +1,9 @@
+<template>
+  <div>
+    <router-view></router-view>
+  </div>
+</template>
+<script setup>
+</script>
+<style scoped>
+</style>

+ 20 - 0
client-tool/src/api/user.js

@@ -0,0 +1,20 @@
+import http from '../utils/http/http.js'
+
+const login = (data) => {
+    return http.post("/user/login", data);
+};
+const getUserList = (data) => {
+    return http.get("/user/list", data);
+};
+const saveUser = (data) => {
+    return http.post("/user/save", data);
+};
+const delUser = (data) => {
+    return http.del("/user/delete", data);
+};
+const getUserDetail = (data) => {
+    return http.get("/user/detail", data);
+};
+export default {
+    login, getUserList, saveUser, delUser, getUserDetail
+}

BIN
client-tool/src/assets/img/avator.jpg


BIN
client-tool/src/assets/img/favicon.ico


+ 10 - 0
client-tool/src/assets/js/common.js

@@ -0,0 +1,10 @@
+import router from '../../router/index.js'
+export default {
+  // 路由跳转
+  changeView(url, queryParams) {
+    router.push({
+      path: url,
+      query: queryParams,
+    })
+  }
+}

+ 5 - 0
client-tool/src/assets/js/constant.js

@@ -0,0 +1,5 @@
+// 全局变量
+export default {
+  name: '知否君',
+  officialAccount: '知否技术'
+}

+ 1 - 0
client-tool/src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 18 - 0
client-tool/src/components/HelloWorld.vue

@@ -0,0 +1,18 @@
+<template>
+  <div>
+    {{ name }}
+  </div>
+</template>
+
+<script setup lang="ts">
+import { onMounted, ref } from 'vue';
+import userApi from '../api/user'
+const name = ref("关亚奇");
+  onMounted(() => {
+    userApi.getUserList().then(res=>{
+      console.log('------->');
+      console.log(res);
+    })
+  })
+</script>
+

+ 82 - 0
client-tool/src/components/Home.vue

@@ -0,0 +1,82 @@
+<template>
+  <div>
+    <p>{{ msg }}</p>
+    <p>姓名:{{ user.name }}</p>
+    <p>年龄:{{ user.age }}</p>
+    <button @click="changeAge">点击</button>
+    <p>单独姓名:{{ name }}</p>
+    <button @click="changeName">修改姓名</button>
+    <p>单独年龄:{{ age }}</p>
+    <button @click="changeRefAge">修改年龄</button>
+    <p>诗人:{{ poet }}</p>
+    <button @click="changePoet">修改诗人</button>
+    <p>computed:{{ newPoet }}</p>
+    <!-- 父子传值 -->
+    <Son :user="user" />
+  </div>
+</template>
+<script >
+import { reactive, ref, toRef, toRefs } from "@vue/reactivity";
+import { computed, watch, provide } from "vue";
+import Son from "./Son.vue";
+export default {
+  components: {
+    Son,
+  },
+  setup() {
+    let msg = "hello";
+    // reactive是一个函数,它可以将复杂数据类型变成响应式数据。
+    let user = reactive({
+      name: "张无忌",
+      age: 12,
+    });
+    const changeAge = () => {
+      user.age++;
+    };
+    // toRef是函数,将对象中某个属性为单独的响应式数据
+    const name = toRef(user, "name");
+    const changeName = () => {
+      name.value = "赵敏";
+    };
+    // toRefs是函数,将对象中所有属性为单独响应式数据
+    const refUser = toRefs(user);
+    const changeRefAge = () => {
+      refUser.age.value = 18;
+    };
+    //   ref函数,常用于简单数据类型定义为响应式数据,再修改值,获取值的时候,需要.value
+    let poet = ref("李白");
+    const changePoet = () => {
+      poet.value = "杜甫";
+    };
+    // computed 计算
+    const newPoet = computed(() => {
+      return poet.value + ",白居易";
+    });
+    // watch 监听
+    watch(user, () => {
+      console.log("user改变了");
+    });
+    watch(
+      () => user.age,
+      () => {
+        console.log("age改变了");
+      }
+    );
+    // provide
+    provide("poet", poet);
+    provide("changePoet", changePoet);
+    return {
+      msg,
+      user,
+      name,
+      changeAge,
+      changeName,
+      changeRefAge,
+      ...refUser,
+      poet,
+      changePoet,
+      newPoet,
+    };
+  },
+};
+</script>

+ 15 - 0
client-tool/src/main.js

@@ -0,0 +1,15 @@
+import { createApp } from 'vue'
+import './style.css'
+import App from './App.vue'
+import router from './router/index.js'
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+import * as Icons from '@element-plus/icons-vue'
+import commonJs from './assets/js/common'
+const app = createApp(App)
+for (let i in Icons) {
+    app.component(i, Icons[i])
+}
+app.use(router).use(ElementPlus, {  })
+app.config.globalProperties.$commonJs = commonJs
+app.mount('#app')

+ 41 - 0
client-tool/src/router/index.js

@@ -0,0 +1,41 @@
+import { createRouter, createWebHashHistory } from 'vue-router'
+const routes = [
+  {
+    path: '/',
+    redirect: '/login'
+  },
+  {
+    path: '/login',
+    name: 'login',
+    meta: {
+      title: '登录'
+    },
+    component: () => import('../view/Login.vue')
+  },
+]
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes
+})
+// 挂载路由导航守卫:to表示将要访问的路径,from表示从哪里来,next是下一个要做的操作
+router.beforeEach((to, from, next) => {
+  // 修改页面 title
+  if (to.meta.title) {
+    document.title = '万维空间OA管理系统 - ' + to.meta.title
+  }
+  // 放行登录页面
+  if (to.path === '/login') {
+    return next()
+  }
+  // 获取token
+  // const token= sessionStorage.getItem('token')
+  // if (!token) {
+  //   return next('/login')
+  // } else {
+  //   next()
+  // }
+  return next()
+})
+
+// 导出路由
+export default router

+ 17 - 0
client-tool/src/style.css

@@ -0,0 +1,17 @@
+html,
+body {
+    padding: 0px;
+    margin: 0px;
+    height: 100%;
+    background: #fff;
+}
+
+/* 表格统一样式 */
+.el-table .el-table__header-wrapper thead th,
+.el-table .el-table__fixed-header-wrapper thead th {
+    padding: 0;
+    background-color: #F9F9F9;
+    height: 50px;
+    line-height: 40px;
+    color: #283543;
+}

+ 81 - 0
client-tool/src/utils/http/axios.js

@@ -0,0 +1,81 @@
+import axios from "axios";
+import { ElMessage } from 'element-plus'
+// 1. 创建axios实例
+const instance = axios.create({
+  // 接口
+  baseURL: "/api",
+  // 超时时间
+  timeout: 50000,
+});
+// 2.请求拦截
+instance.interceptors.request.use(
+  config => {
+    let token = sessionStorage.getItem('token')
+    if (token) {
+      config.headers['token'] = token
+    }
+    return config;
+  },
+  error => {
+    //  请求发生错误,抛出异常
+    Promise.reject(error);
+  }
+);
+
+// 3.响应拦截
+instance.interceptors.response.use(
+  res => {
+    return res;
+  },
+  error => {
+    if (error && error.response) {
+      const status = error.response.status
+      switch (status) {
+        case 400:
+          ElMessage.error("请求错误");
+          break;
+        case 401:
+          ElMessage.error("未授权,请重新登录");
+          break;
+        case 403:
+          ElMessage.error("拒绝访问");
+          break;
+        case 404:
+          ElMessage.error("请求错误,未找到相应的资源");
+          break;
+        case 408:
+          ElMessage.error("请求超时");
+          break;
+        case 500:
+          ElMessage.error("服务器内部错误");
+          break;
+        case 501:
+          ElMessage.error("网络未实现");
+          break;
+        case 502:
+          ElMessage.error("网络错误");
+          break;
+        case 503:
+          ElMessage.error("服务不可用");
+          break;
+        case 504:
+          ElMessage.error("网络超时");
+          break;
+        case 505:
+          ElMessage.error("HTTP版本不支持该请求");
+          break;
+        default:
+          ElMessage.error("请求失败");
+      }
+    } else {
+      if (JSON.stringify(error).includes("timeout")) {
+        ElMessage.error("服务器响应超时,请刷新页面");
+      }
+      ElMessage.error("连接服务器失败");
+    }
+    return Promise.reject(error);
+  }
+);
+// 4.导出 axios 实例
+export default instance;
+

+ 43 - 0
client-tool/src/utils/http/http.js

@@ -0,0 +1,43 @@
+import instance from "./axios"
+
+const post = (url, data) => {
+    return new Promise((resolve, reject) => {
+        instance.post(url, data).then(res => {
+            resolve(res)
+        }).catch(err => {
+            reject(err)
+        })
+    })
+}
+const get = (url, data) => {
+    return new Promise((resolve, reject) => {
+        instance.get(url, { params: data }).then(res => {
+            resolve(res)
+        }).catch(err => {
+            reject(err)
+        })
+    })
+}
+const put = (url, data) => {
+    return new Promise((resolve, reject) => {
+        instance.put(url, data).then(res => {
+            resolve(res)
+        }).catch(err => {
+            reject(err)
+        })
+    })
+}
+
+const del = (url, data) => {
+    return new Promise((resolve, reject) => {
+        instance.delete(url, { params: data }).then(res => {
+            resolve(res)
+        }).catch(err => {
+            reject(err)
+        })
+    })
+}
+
+export default {
+    post, get, put, del
+}

+ 24 - 0
client-tool/src/view/Login.vue

@@ -0,0 +1,24 @@
+<template>
+  <div>工具</div>
+</template>
+
+<script setup>
+import userApi from '../api/user';
+import { reactive, ref, getCurrentInstance } from 'vue';
+import { ElMessage } from 'element-plus';
+import router from '../router/index';
+const { proxy } = getCurrentInstance();
+const form = reactive({
+  username: '',
+  password: '',
+});
+const ruleFormRef = ref();
+const rules = reactive({});
+
+const resetForm = () => {
+  if (!ruleFormRef) return;
+  ruleFormRef.value.resetFields();
+};
+</script>
+
+<style scoped></style>

+ 18 - 0
client-tool/vite.config.js

@@ -0,0 +1,18 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+export default defineConfig({
+  plugins: [vue()],
+  server: {
+    open: false,
+    port: 3000,
+    proxy: {
+      '/api': {
+        target: 'http://117.33.255.178:22:8082/zhifou-study', // 
+        changeOrigin: true,
+        rewrite: (path) => path.replace(/^\/api/, '')
+      },
+    },
+  },
+
+})

+ 2 - 2
client/.env.base

@@ -4,10 +4,10 @@ NODE_ENV=development
 VITE_DEV=true
 
 # 请求路径
-VITE_BASE_URL='http://localhost:48080'
+VITE_BASE_URL='http://192.168.20.130:48080'
 
 # 上传路径
-VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
+VITE_UPLOAD_URL='http://192.168.20.130:48080/admin-api/infra/file/upload'
 
 # 接口前缀
 VITE_API_BASEPATH=/dev-api

+ 11 - 0
client/src/views/OaSystem/olanTool/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div class="_OlanTool"> 规划工具 </div>
+</template>
+<script setup lang="ts">
+import type { Column } from 'element-plus'
+
+defineOptions({ name: 'OlanTool' })
+
+/** 初始化 **/
+onMounted(() => {})
+</script>

+ 9 - 0
client/src/views/system/menu/index.vue

@@ -155,6 +155,15 @@ const getList = async () => {
       if (!menu.icon) {
         menu.icon = ''
       }
+      if (!menu.permission) {
+        menu.permission = ''
+      }
+      if (!menu.component) {
+        menu.component = ''
+      }
+      if (!menu.componentName) {
+        menu.componentName = ''
+      }
     })
     list.value = handleTree(data)
   } finally {