diff --git "a/\345\220\264\350\257\227\350\214\265/20240715-32.\350\217\234\345\215\225\346\240\217\347\273\204\344\273\266.md" "b/\345\220\264\350\257\227\350\214\265/20240715-32.\350\217\234\345\215\225\346\240\217\347\273\204\344\273\266.md" new file mode 100644 index 0000000000000000000000000000000000000000..5374a3b8bf1f07164b40400b7da5c80378eade56 --- /dev/null +++ "b/\345\220\264\350\257\227\350\214\265/20240715-32.\350\217\234\345\215\225\346\240\217\347\273\204\344\273\266.md" @@ -0,0 +1,55 @@ +## 菜单栏组件 + +``` + + + +``` \ No newline at end of file diff --git "a/\345\220\264\350\257\227\350\214\265/20240716-33.\345\256\236\347\216\260\350\217\234\345\215\225\346\240\217\344\270\216\346\240\207\347\255\276\346\240\217\347\232\204\347\202\271\345\207\273.md" "b/\345\220\264\350\257\227\350\214\265/20240716-33.\345\256\236\347\216\260\350\217\234\345\215\225\346\240\217\344\270\216\346\240\207\347\255\276\346\240\217\347\232\204\347\202\271\345\207\273.md" new file mode 100644 index 0000000000000000000000000000000000000000..893e3f025999afd2e9f3f7ec9ee0b12211068586 --- /dev/null +++ "b/\345\220\264\350\257\227\350\214\265/20240716-33.\345\256\236\347\216\260\350\217\234\345\215\225\346\240\217\344\270\216\346\240\207\347\255\276\346\240\217\347\232\204\347\202\271\345\207\273.md" @@ -0,0 +1,199 @@ +## 实现菜单栏与标签栏的点击 + +router.js: + +``` +import { routes } from '../route/staticRoutes'; +import { defineStore } from 'pinia'; +import { computed, reactive, ref, watch } from 'vue'; +import { useRouter, useRoute } from 'vue-router'; + +// 为了将路由实例引入进来,特意采用了setup语法,有没有注意到defineStore函数,没错,第2个参数是个函数,这就是setup语法 +export const useRouterStore = defineStore('router',()=> +{ + // 引入路由实例 + const router = useRouter(); + const route = useRoute(); + + // 以下为定义的state + const menuArr = reactive([]);// 菜单数据 + const tabArr = reactive // 标签栏数据 + ([ + { + key: '/desktop', + title: '工作台', + content: '' + }, + { + key: '/dashboard', + title: '仪表盘', + content: '' + } + ]); + + // 当前的key,用于绑定到菜单栏和标签栏的“当前项”属性 + let activeKey = ref('/desktop');//标签栏的当前标签 + const selectKeys = reactive([]); + const openKeys = reactive([]); + + // 扁平化的菜单数据,这个是计算属性,也是getters + const flatMenuArr = computed(()=> + { + let arr = flatArr(menuArr); + return arr; + }); + + // 监听路由变化,设置当前标签项和当前菜单项(菜单项有些无法展开,暂不清楚是什么问题,待解决) + watch(route, (newVal, oldVal)=> + { + // console.log(newVal); + // console.log(oldVal); + changeActiveKey(newVal.path) + }); + + // 由路由数据生成菜单数据 + function generatRoutes() + { + // 清空原来的所有菜单数据,准备重新生成 + this.menuArr.splice(0); + routes.forEach(item => + { + let menu = createMenuItemFromRoute(item); + if (menu) + { + this.menuArr.push(menu); + } + }); + }; + // 添加对象到标签数组中(如果不存在则添加) + function addTab(key) + { + var isExist = this.tabArr.filter(item => item.key === key); + if (isExist.length > 0) + { + + } + else + { + let tmp = getOjbectByKey(key, this.flatMenuArr); + let obj = + { + title: tmp.title, + content: ``, + key: key, + } + this.tabArr.push(obj); + } + }; + + // 菜单栏和标签栏点击后,改变路由的统一逻辑 + function changeActiveRoute(key) + { + router.push(key); + this.addTab(key); + // console.log(selectKeys); + // this.changeActiveKey(key); + // console.log(selectKeys); + }; + + // 改变当前项 + function changeActiveKey(key) //切换当前Key + { + // console.log('这里输出准备要修改的key值:', key); + // console.log('key值:', key); + // console.log('activeKey值:', activeKey.value); + + activeKey.value = key; + + selectKeys.splice(0); + selectKeys.push(key); + // console.log('222', selectKeys); + + let tmpArr = menuArr.map(item => item.children).flat().filter(item => item.key === key).map(item => item.key); + // console.log(tmpArr); + // console.log(menuArr); + + openKeys.splice(0).push(...tmpArr); + openKeys.push('/system'); + }; + + // 这里必须返回 + return { + menuArr, + tabArr, + openKeys, + activeKey, + selectKeys, + flatMenuArr, + generatRoutes, + addTab, + changeActiveKey, + changeActiveRoute + }; +}); + + // 一个函数,将一个路由对象,转换为左侧菜单栏对象 + const createMenuItemFromRoute = (route) => + { + if(route.meta.hide && route.meta.hide === true) + { + return; + } + // 先拿到路由中的基本信息 + let obj = + { + key: route.path, + title: route.meta.title, + label: route.meta.title, + } + // 尝试处理其下级路由,将其转化为菜单数组返回,挂载到孩子属性 + let arr = []; + if (route.children && route.children.length > 0) + { + route.children.forEach(item => + { + let tmpObj = createMenuItemFromRoute(item); + arr.push(tmpObj); + }); + + if (arr.length > 0) + { + obj.children = arr; + } + } + return obj; + }; + + // 从数组中筛选key值对应的对象 + const getOjbectByKey = function (key, arr) + { + let tmp = arr.filter(item => item.key === key); + if (tmp.length > 0) + { + return tmp[0]; + } + return undefined; + }; + + // 将数组扁平化,突然想到,这个好像可以用计算属性,嗯,就这么办,所以这个闲置了,本功能代码待清理 + const flatArr = (arr) => + { + let resArr = []; + arr.forEach(item => + { + let obj = + { + key: item.key, + title: item.title, + content: '' + } + resArr.push(obj); + if (item.children && item.children.length > 0) + { + let tmpArr = flatArr(item.children); + resArr = resArr.concat(tmpArr); + } + }); + return resArr; + } +``` \ No newline at end of file diff --git "a/\345\220\264\350\257\227\350\214\265/20240717-34.\345\256\236\347\216\260\344\270\244\346\240\217\344\271\213\351\227\264\347\232\204\344\272\222\347\202\271.md" "b/\345\220\264\350\257\227\350\214\265/20240717-34.\345\256\236\347\216\260\344\270\244\346\240\217\344\271\213\351\227\264\347\232\204\344\272\222\347\202\271.md" new file mode 100644 index 0000000000000000000000000000000000000000..d8b0ca06765c194d8c81d1fb07869a0058673bf8 --- /dev/null +++ "b/\345\220\264\350\257\227\350\214\265/20240717-34.\345\256\236\347\216\260\344\270\244\346\240\217\344\271\213\351\227\264\347\232\204\344\272\222\347\202\271.md" @@ -0,0 +1,75 @@ +## 实现两栏之间的互点 + +index.js: + +``` +import {createRouter, createWebHistory} from 'vue-router' + +import {routes} from './staticRoutes'; + +export const router=createRouter +({ + history:createWebHistory(), + routes +}); +``` + +staticRoutes.js: + +``` +import Layout from '../components/Layout.vue'; +export const routes= +[ + { + path:'/', + component:Layout, + meta:{title:'首页'}, + children: + [ + { + path:'/desktop', + component:()=>import('../views/desktop.vue'), + meta:{title:'工作台'} + }, + { + path:'/dashboard', + component:()=>import('../views/dashboard.vue'), + meta:{title:'仪表盘'} + } + ] + }, + { + path:'/system', + component:Layout, + meta:{title:'系统管理'}, + children: + [ + { + path:'/system/user', + component:()=>import('../views/user.vue'), + meta:{title:'用户管理'} + }, + { + path:'/system/role', + component:()=>import('../views/role.vue'), + meta:{title:'角色管理'} + }, + { + path:'/system/permission', + component:()=>import('../views/permission.vue'), + meta:{title:'权限管理'} + } + ] + }, + { + path:'/login', + component:()=>import("../views/login.vue"), + meta:{title:'登录',hide:true} + }, + { + path:'/:pathMatch(.*)*', + component:()=>import("../views/notfound404.vue"), + meta:{title:'NotFound',hide:true} + } +]; +``` \ No newline at end of file diff --git "a/\345\220\264\350\257\227\350\214\265/\351\203\250\347\275\262\346\234\215\345\212\241\345\231\250\347\254\224\350\256\260.md" "b/\345\220\264\350\257\227\350\214\265/\351\203\250\347\275\262\346\234\215\345\212\241\345\231\250\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..4ef22005e25d866c724fd01b9a21404b786fb2da --- /dev/null +++ "b/\345\220\264\350\257\227\350\214\265/\351\203\250\347\275\262\346\234\215\345\212\241\345\231\250\347\254\224\350\256\260.md" @@ -0,0 +1,255 @@ +## 部署服务器 + +### 一.部署前期工作 + +#### 1.安装nginx + +##### nginx的安装 + +命令:apt install nginx -y + +① 确认nginx服务状态:systemctl status nginx + +② 启动nginx服务:systemctl start nginx + +③ 关闭nginx服务:systemctl stop nginx + +④ 让nginx服务开机自启动:systemctl enable nginx + +⑤ 让nginx服务不开机自启动:systemctl diable nginx + +##### nginx的配置 + +/etc/nginx/sites-available/default + +``` +server { + listen 80; + server_name 域名名称 www.域名名称; + + root /var/www/admin-project/dist; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + location /api { + proxy_pass http://localhost:5130; // 这里填写你的后端服务器地址 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + error_page 404 /index.html; +} +``` + +/etc/nginx/sites-enabled/default + +``` +server { + listen 80; + server_name 域名名称 www.域名名称; + + root /var/www/admin-project/dist; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + location /api { + proxy_pass http://localhost:5130; // 这里填写你的后端服务器地址 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + error_page 404 /index.html; +} +``` + +#### 2.安装.NET SDK(项目打包) + +如果是自包含打包则不用下载也行(自包含打包不需要下载运行时,包内自带运行环境) + +``` +// 从Microsoft的服务器上下载Debian 12版本的软件包配置文件 +wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb +-O packages-microsoft-prod.deb + +// 安装下载的 packages-microsoft-prod.deb软件包配置文件 +sudo dpkg -i packages-microsoft-prod.deb + +// 删除本地的 packages-microsoft-prod.deb 文件,释放磁盘空间 +rm packages-microsoft-prod.deb + +sudo apt-get update + +sudo apt-get install -y dotnet-sdk-8.0 +``` + +安装好了可以使用 dotnet --version测试是否安装成功 + +#### 3.安装postgresql + +##### 创建文件存储库配置 + +``` +sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' +``` + +##### 导入存储库签名密钥 + +``` +wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - +``` + +##### 更新软件包列表 + +``` +apt update + +apt upgrade -y +``` + +##### 下载postgresql + +``` +pg_hba.conf +``` + +##### 查看状态 + +``` +systemctl status postgresql +``` + +##### 修改/etc/postgresql/16/main里的pg_hba.conf与postgresql.conf配置让其可以连接 + +``` +// md5是要密码登录的意思,防止被入侵;整个的意思是允许所有的ip地址连接 +① 修改pg_hba.conf里的:在最后一行添加上host all all 0.0.0.0/0 md5 + +// localhost改成“*”也是允许所有地址连接的意思 +② 修改postgresql.conf里的:把listen_addresses = 'localhost'的注释也就是前面的“*”去掉,接着把localhost改成“*” +``` + +##### 重新启动postgresql + +``` +systemctl restart postgresql +``` + +##### 设置数据库的用户名和密码 + +``` +// 默认超级管理员postgres +su postgres + +// 切换用户,无密码登录 +psql + +// 设置密码 +\password + +// 退出 +\q + +// 切换到root用户 +su +``` + +### 二.前端部署 + +#### 1.打包前端文件 + +进到\Front_end\admin_project执行如下代码: + +``` +npm run build +``` +得到dist文件夹,接着将其压缩成.zip形式 + +#### 2.将前端文件上传至自己的服务器 + +用自己的服务器远程登录,打开之后将dist的压缩文件夹上传至服务器的/var/www/admin-project + +上传之后要解压 + +``` +unzip dist.zip +``` + +测试 + +``` +sudo nginx -t +``` + +重新加载nginx + +``` +sudo systemctl reload nginx +``` + +至此前端部署完毕,可以访问了 + +### 三.后端部署 + +#### 1.打包后端文件 + +进到\Back_end\src\Web2024.Api执行如下代码: + +``` +1. 项目打包 +dotnet publish -c Release -o output --framework net8.0 + +2. 自包含打包(自包含打包不需要下载运行时,包内自带运行环境)// 首选 +dotnet publish -c Release -r linux-x64 --self-contained -o output +``` + +得到output文件夹,接着将其压缩成.zip形式 + +上传之后要解压 + +``` +unzip output.zip +``` + +#### 2.将前端文件上传至自己的服务器 + +用自己的服务器远程登录,打开之后将output的压缩文件夹上传至服务器的/var/www/admin-project + +#### 3.使用systemd守护进程 + +``` +// 创建一个服务文件 +sudo vim /etc/systemd/system/myapp.service + +// 配置文件 +[Unit] +Description=My .NET Application +After=network.target + +[Service] +WorkingDirectory=/var/www/admin-project/output +ExecStart=/var/www/admin-project/output/./Web2024.Api --urls "http://*:5130" +Restart=always +RestartSec=10 +SyslogIdentifier=dotnet-app +User=root +Environment=ASPNETCORE_ENVIRONMENT=Production + +[Install] +WantedBy=multi-user.target +``` + +#### 4.启动服务和启动服务 + +``` +sudo systemctl daemon-reload + +sudo systemctl enable myapp + +sudo systemctl start myapp +``` + +至此后端部署完毕,可以访问了 \ No newline at end of file