首页
关于
Search
1
AdGuardHome 安装及部署教程
40,713 阅读
2
搭建基于telegram的无限网盘
10,102 阅读
3
关于微软Azure学生白嫖指南
9,718 阅读
4
Oracle开放全部端口并关闭防火墙
9,499 阅读
5
最新Cloudflare免费自选IP教程(非Partner)
9,331 阅读
默认分类
技术搬砖
教学设计
故事奇谈
生活琐事
错题分析
精品软件
登录
Search
标签搜索
docker
张至顺
PHP
图床
Cloudflare
金刚长寿功
PT
qBittorrent
阿里云
onedrive
telegram
代理
青龙
python
内网穿透
一键
telegraph
ipv6
cf_workers
serv00
myedunote
累计撰写
101
篇文章
累计收到
1
条评论
首页
栏目
默认分类
技术搬砖
教学设计
故事奇谈
生活琐事
错题分析
精品软件
页面
关于
搜索到
1
篇与
订阅管理
的结果
2023-11-22
自建Sub-Store订阅管理转换教程
Github Peng-YM大佬的Sub-Store提供了几乎全平台的代理转换,Loon、Surge等可以安装其提供的模块直接使用,本教程是将Sub-Store搭建为网站,更方便clash等使用一、前期准备域名,托管到 cloudflare(其它地方也行,但是 CF 相对比较方便)证书,免费证书三个月,自动续订即可服务器vps,配置高点,不要太低服务器需要安装好nginx,建议小白安装好宝塔面板,部署好基本环境二、部署过程1、域名设置在 cloudflare 的域名 DNS 记录里面添加两个 A 记录,一个是 substore.domain.com, 一个是 subapi.domain.com (实际 A 记录的名字随意,只要你能区分就行)见下图例子:备注:后面的代理黄云勾不勾随意,如果你用其它第三方 ssl 证书可以不勾,如果用 CF 的证书就勾上。2、克隆项目名称地址前端 Sub-Store-Front-Endhttps://github.com/sub-store-org/Sub-Store-Front-End.git后端 Sub-Store/backendhttps://github.com/sub-store-org/Sub-Store.git使用 git clone + 地址的方式克隆3、安装 node和pnpm环境,pm2管理器①下载和安装 fnm(Node.js 版本管理器)curl -fsSL https://fnm.vercel.app/install | bash看上一步的提示复制粘贴 不要抄下面的②根据上一步提示执行命令:看上一步的提示复制粘贴 不要抄下面的③安装 node.jsfnm install v16.13.2④安装 PNPM 软件包管理器curl -fsSL https://get.pnpm.io/install.sh | sh -看上一步的提示复制粘贴 不要抄下面的⑤根据上一步提示执行命令:看上一步的提示复制粘贴 不要抄下面的⑥安装 pnpmnpm i pnpm -g⑦安装pm2项目管理器进入宝塔面板软件商店安装pm2项目管理器4、前端修改编译①修改后端接口地址宝塔自带文件管理器打开项目根目录 Sub-Store-Front-End文件夹下的.env.production文件,将文件里线上环境接口地址改为自己准备的域名,比如https://subapi.domain.com/token,token尽量复杂,下面Nginx配置需要用到,本文这里填https://subapi.domain.com/UV3yVmNYreAhkVgP②添加登录页面由于是要部署到服务器上,即为公开的,所以还需要一个登陆页面,阻止任何人访问在项目根目录下的src/views下新建Login.vue文件Login.vue代码如下:<template> <div class='wrapper'> <div>欢迎使用</div> <nut-form :model-value='formData' ref='ruleForm'> <nut-form-item label='用户名' prop='name' required :rules="[{ required: true, message: '请填写用户名' }]"> <input class='nut-input-text' @blur="customBlurValidate('name')" v-model='formData.name' placeholder='请输入用户名' type='text' /> </nut-form-item> <nut-form-item label='密码' prop='pwd' required :rules="[ { required: true, message: '请填写密码' }, // { validator: customValidator, message: '必须输入数字' }, // { regex: /^(\d{1,2}|1\d{2}|200000000)$/, message: '必须输入0-200000000区间' } ]"> <input class='nut-input-text' v-model='formData.pwd' placeholder='请输入密码' type='text' /> </nut-form-item> <nut-cell> <nut-button type='primary' size='small' style='margin-right: 10px' @click='submit'>登录</nut-button> <nut-button size='small' @click='reset'>重置</nut-button> </nut-cell> </nut-form> </div> </template> <script lang='ts'> import { Notify, Toast } from '@nutui/nutui'; import { ref, reactive } from 'vue'; import { useRouter } from 'vue-router'; export default { setup() { const router = useRouter(); const formData = reactive({ name: '', pwd: '', }); const validate = (item: any) => { console.log(item); }; const ruleForm = ref<any>(null); const submit = () => { ruleForm.value.validate().then(({ valid, errors }: any) => { if (valid) { console.log('success', formData); if (formData.name == 'name') { if (formData.pwd == 'password') { Notify.success('登录成功,欢迎回来!',{ duration: 1000 }); Toast.loading('', { cover: false // 透明罩 }); sessionStorage.setItem('token', 'token') // 临时存储,关闭标签后就清除 setTimeout(() => { router.push({path: '/sub'}); // router.replace('/sub') Toast.hide(); }, 1200); } else { Notify.danger('密码错误!'); } } else { Notify.warn('用户不存在!'); } } else { console.log('error submit!!', errors); } }); }; const reset = () => { ruleForm.value.reset(); }; // 失去焦点校验 const customBlurValidate = (prop: string) => { ruleForm.value.validate(prop).then(({ valid, errors }: any) => { if (valid) { console.log('success', formData); } else { console.log('error submit!!', errors); } }); }; // 函数校验 const customValidator = (val: string) => /^\d+$/.test(val); // Promise 异步校验 const asyncValidator = (val: string) => { return new Promise((resolve) => { Toast.loading('模拟异步验证中...'); setTimeout(() => { Toast.hide(); resolve(/^400(-?)[0-9]{7}$|^1\d{10}$|^0[0-9]{2,3}-[0-9]{7,8}$/.test(val)); }, 1000); }); }; return { ruleForm, formData, validate, customValidator, asyncValidator, customBlurValidate, submit, reset }; }, }; </script> <style lang='scss' scoped> .wrapper { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; flex-direction: column; h3 { padding-bottom: 24px; } } </style>修改代码中的用户名、密码、token示例:if (formData.name == 'zqzess') { if (formData.pwd == 'zqzess') { Notify.success('登录成功,欢迎回来!',{ duration: 1000 }); Toast.loading('', { cover: false // 透明罩 }); sessionStorage.setItem('token', 'code') // 临时存储,关闭标签后就清除此处sessionStorage.setItem('token', 'code')定义的token为code,一定要记住,后面路由会用到此处formData.name == 'zqzess'定义的zqzess即为用户名此处formData.pwd == 'zqzess'定义的zqzess即为密码这种明文写在代码里面账号密码其实也不安全,仅作为一个简单的认证,以后有机会再改写需要后端认证的登陆③修改路由接下来需要把登陆页面添加至路由里面,并加入拦截,没有token的需要跳转登陆页项目根目录,/src/router/index.ts,添加:import Login from '@/views/Login.vue';接着修改根路由,将如下代码修改为图片上的,就是将第一个path: '/'改为path: '/sub'接着添加登陆路由,在path: '/:pathMatch(.*)'代码后面添加{ path: '/:pathMatch(.*)', component: NotFound, meta: { title: 'notFound', needTabBar: false, needNavBack: true, }, }, { path: '/', component: Login, meta: { title: 'login', needTabBar: false, needNavBack: false, }, }在本页最后一行export default router;上面添加路由拦截此处if (token === null || token === '' || token !== 'code') {的code即为上面登陆页填写的tokenrouter.beforeEach((to, from, next) => { // let token = window.localStorage.getItem('token') // let type = window.localStorage.getItem('type') if (to.path === '/' || to.path === '/login' || to.path === '/error') { // console.log("允许直接访问") next(); } else { // let token = window.localStorage.getItem('token') // 长期存储 let token = window.sessionStorage.getItem('token') // 临时存储,关闭标签后就清除 // console.log("需要token") if (token === null || token === '' || token !== 'code') { // console.log("无token,跳转登录") next('/'); } else { // console.log("有token") next(); } } }); export default router;接着修改根目录,/src/views/SubEditor.vue,由于代码较多,可以直接搜索router.replace,会跳转到相应代码把router.replace('/')改为router.replace('/sub')④登陆页的命名与翻译根目录/src/locales/en.ts可以使用搜索notFound: '404 Not Found',,再此行下面添加login: 'Login',根目录/src/locales/zh.ts搜索notFound: '地址未找到',,再此行下面添加login: '登录',至此已经全部结束,接下来就是打包发布并部署服务器⑤前端打包在前端 Sub-Store-Front-End文件夹下执行,安装依赖pnpm install在前端 Sub-Store-Front-End文件夹下执行,执行打包命令pnpm build打包好后,根目录会多出dist文件夹,此文件夹就是打包好的网站文件,也是我们需要发布服务器的5、部署后端进入后端项目里的backend文件夹,进入开源后端项目最新Releases下载执行文件cd /root/Sub-Store/backend wget https://github.com/sub-store-org/Sub-Store/releases/download/2.14.99/sub-store.min.js之后,执行pnpm i完成后再执行:pm2 start sub-store.min.js完成后继续执行:pm2 save如果成功,至此后端已经成功启动pm2常用命令pm2 list pm2 log <name> pm2 stop id pm2 delete id6、配置网站宝塔面板添加站点,并配置好证书将之前打包好的dist文件夹里面的所有文件剪切到substore.domain.com站点根目录,不要复制整体dist文件夹,而是里面的单个文件subapi.domain.com域名配置反代,进入站点设置location /UV3yVmNYreAhkVgP/{ //API-token 也要根据需要修改,尽量复杂 proxy_pass http://127.0.0.1:3000/; }三、使用教程进入网站https://substore.domain.com,输入之前设置的用户名和密码进入我的——后端设置如果后端是之前设置的线上环境地址,就不用管了,可以直接转换节点了如果不是,需要手动添加新后端并保存好,名称随意,链接填刚刚反代的地址,https://subapi.domain.com/UV3yVmNYreAhkVgP参考文章:https://www.whitemoon.top/posts/e36e6bfe.htmlhttps://www.evan888.top/1974/
2023年11月22日
3,538 阅读
0 评论
2 点赞