├── .babelrc
├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── LICENSE
├── README.md
├── babel.config.js
├── package.json
├── public
├── favicon.ico
├── index.html
└── robots.txt
├── src
├── App.vue
├── api
│ ├── boxApi.js
│ ├── commonApi.js
│ └── userApi.js
├── assets
│ ├── css
│ │ ├── global.scss
│ │ └── reset.scss
│ ├── iconfont
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ ├── iconfont.woff
│ │ └── iconfont.woff2
│ ├── img
│ │ ├── bg.gif
│ │ └── bg.png
│ └── js
│ │ └── bjxt.js
├── components
│ ├── common
│ │ ├── Add.vue
│ │ ├── BackgroundEffect.vue
│ │ ├── LeaveMsg.vue
│ │ ├── Music.vue
│ │ ├── Notice.vue
│ │ ├── People.vue
│ │ ├── Sort.vue
│ │ ├── ToHot.vue
│ │ ├── ToMall.vue
│ │ ├── ToNav.vue
│ │ └── Weather.vue
│ ├── dialog
│ │ ├── AddBoxDialog.vue
│ │ ├── AddListDialog.vue
│ │ ├── AddSearchSiteDialog.vue
│ │ ├── ImageDialog.vue
│ │ ├── LeaveMsgDialog.vue
│ │ ├── MsgReplyDialog.vue
│ │ ├── MusicSettingDialog.vue
│ │ ├── NoticeDialog.vue
│ │ ├── UpdateBoxDialog.vue
│ │ ├── UpdateListDialog.vue
│ │ ├── UpdateSearchSiteDialog.vue
│ │ ├── ViewMsgDialog.vue
│ │ ├── WeatherDialog.vue
│ │ └── WechatDialog.vue
│ ├── drawer
│ │ └── AddDrawer.vue
│ ├── item
│ │ ├── MsgItem.vue
│ │ └── NavItem.vue
│ ├── step
│ │ └── FindPassStep.vue
│ └── user
│ │ ├── Bottom.vue
│ │ ├── Left.vue
│ │ └── Top.vue
├── config
│ ├── TransformData.js
│ ├── code.js
│ ├── config.js
│ ├── events.js
│ ├── getInfo.js
│ ├── guide.json
│ ├── http.js
│ ├── keys.js
│ ├── strings.js
│ └── updateNotes.json
├── element
│ └── index.js
├── main.js
├── router
│ └── index.js
├── store
│ ├── index.js
│ ├── mutations.js
│ └── state.js
├── util
│ ├── isMobile.js
│ └── utils.js
└── views
│ ├── Index.vue
│ ├── Search.vue
│ ├── TokenAdd.vue
│ ├── User.vue
│ ├── index
│ ├── Footer.vue
│ ├── Header.vue
│ ├── Nav.vue
│ ├── RightBar.vue
│ └── Search.vue
│ └── user
│ ├── AboutUs.vue
│ ├── BoxConfig.vue
│ ├── ExportConfig.vue
│ ├── Home.vue
│ ├── ImportConfig.vue
│ ├── ListConfig.vue
│ ├── ModifyPass.vue
│ ├── MsgConfig.vue
│ ├── NoticeConfig.vue
│ ├── Profile.vue
│ ├── SearchSiteConfig.vue
│ ├── SiteConfig.vue
│ ├── UpdateNote.vue
│ └── UserLogin.vue
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | [
4 | "component",
5 | {
6 | "libraryName": "element-ui",
7 | "styleLibraryName": "theme-chalk"
8 | }
9 | ]
10 | ]
11 | }
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | 'extends': [
7 | 'plugin:vue/essential',
8 | 'eslint:recommended'
9 | ],
10 | parserOptions: {
11 | parser: 'babel-eslint'
12 | },
13 | rules: {
14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### 优聚集
2 |
3 | 2020年初,疫情肆虐,想着以后的规划,结果是毫无规划,可能我就是随波逐流、活在当下的人。
4 |
5 |
6 |
7 | 不管怎么说,我也希望以后能自由职业且能不饿肚子,为此,为了锻炼技能,写了优聚集这个前后端分离的项目。
8 |
9 |
10 |
11 | 这是第一次写较大规模的Vue.js 应用
12 |
13 | 这也是第一次写较大规模的SpringBoot应用
14 |
15 |
16 |
17 | 第一次写,肯定就是巨难看和维护,这点我有自知之明,但是我希望你们不要说出来。我自己知道就行。所以,于2021年我完全从零开始重构了优聚集,前端虽也是Vue.js,但是也是完全重写了。后端用golang重构。不得不说,golang没有像springboot这类似的大统一框架,对于某些方面来说也是好事,我可以完全决定我的后台应用怎么架构。而不是被springboot规定死了:你就该在这个目录写这个东西…
18 |
19 |
20 |
21 | ### 仓库
22 |
23 | 前端仓库(Vue.js):[https://github.com/Xwudao/ujuji_frontend](https://github.com/Xwudao/ujuji_frontend)
24 |
25 | 后端仓库(SpringBoot):[https://github.com/Xwudao/ujuji_backend](https://github.com/Xwudao/ujuji_backend)
26 |
27 |
28 |
29 | ### 声明
30 |
31 | 1、
32 |
33 | 尽管我已经仔细检查过代码,但是不可避免的可能代码中依旧有一些我个人的私密信息,尤其是诸如邮箱密码之类的,如果被发现了,那么请告知我,或者最起码请不要用它干一些危险的事情,谢谢合作。
34 |
35 | 2、
36 |
37 | 因为本套代码之初并不是为了开源而写的,所以对于一些测试中的敏感信息我都是直接写死在代码中的,所以如果您发现了一些私密信息请告知我。
38 |
39 |
40 |
41 | 3、
42 |
43 | 本套代码是基于Vue2.js
44 |
45 | 这套代码和现在的优聚集 [https://ujuji.com/](https://ujuji.com/) 有很大区别,因为现在的优聚集网站时是我完全在2021年通过golang重构了的。**所以当您发现这和优聚集https://ujuji.com/ 差别很大时,很正常,因为现有优聚集是重构之后的版本。**
46 |
47 |
48 |
49 | 4、
50 |
51 | 如果您想自己部署优聚集前后端项目,最起码得有以下知识点:
52 |
53 | - Node.js
54 | - Vue.js
55 | - Javascript
56 |
57 |
58 |
59 | ### 构建
60 |
61 | 1、修改配置文件`src\config\config.js`
62 |
63 | 您最起码得修改这一个配置我呢见,其余的,我也忘了,有一些背景图片,赞赏二维码应该是写死在代码里面的,可能需要你找找…
64 |
65 | - 修改后台服务器地址:
66 |
67 | ```javascript
68 | let url;
69 | if (process.env.NODE_ENV === 'production') {
70 | url = 'https://api.ujuji.com'
71 | } else {
72 | url = 'http://localhost:4037'
73 | }
74 | ```
75 |
76 | 上面的http://localhost:4037 是本地开发环境的后台服务器地址,https://api.ujuji.com 是线上后台服务器地址
77 |
78 |
79 | 2、当基本配置修改完后,就可以构建了:
80 |
81 | 执行(需要Nodejs环境)
82 |
83 | ```bash
84 | npm i
85 | ```
86 |
87 | 构建:
88 |
89 | ```
90 | npm run build
91 | ```
92 |
93 |
94 |
95 | 成功后,会输出:
96 |
97 | ```ini
98 | File Size Gzipped
99 |
100 | dist\js\chunk-vendors.7dea26e0.js 587.00 KiB 160.49 KiB
101 | dist\js\chunk-d225f4dc.edb1e5e0.js 457.38 KiB 139.79 KiB
102 | dist\js\app.3793e2c6.js 54.83 KiB 16.93 KiB
103 | dist\js\chunk-3a3be80e.e9fbef86.js 17.79 KiB 5.94 KiB
104 | dist\js\chunk-49d141fb.a96c2f31.js 16.15 KiB 5.63 KiB
105 | dist\js\chunk-2304eda0.2f1c8d34.js 14.27 KiB 3.98 KiB
106 | dist\js\chunk-b851b192.f72d5b6f.js 14.02 KiB 3.49 KiB
107 | dist\js\chunk-05d7e486.666513f8.js 13.73 KiB 4.69 KiB
108 | dist\js\chunk-10c0c0ac.f3d8a8a1.js 12.26 KiB 3.45 KiB
109 | dist\js\chunk-1d8d5dbe.18b0d22f.js 10.31 KiB 3.08 KiB
110 | dist\js\chunk-4147566f.96f48fad.js 7.40 KiB 2.48 KiB
111 | dist\js\chunk-71414ebd.a8aa982a.js 7.28 KiB 2.29 KiB
112 | dist\js\chunk-18609744.b586d9ff.js 6.08 KiB 1.96 KiB
113 | dist\js\chunk-22de37c4.3677e01d.js 5.84 KiB 2.13 KiB
114 | dist\js\chunk-772f45f6.89282213.js 5.68 KiB 2.46 KiB
115 | dist\js\chunk-2e227146.4c3af2c2.js 4.86 KiB 2.15 KiB
116 | dist\js\chunk-2d2134f8.d57a94a9.js 2.59 KiB 1.23 KiB
117 | dist\js\chunk-11fbe2c4.f726b5da.js 2.25 KiB 1.09 KiB
118 | dist\js\chunk-2d0bff6a.0d05008e.js 1.97 KiB 0.99 KiB
119 | dist\js\chunk-350dbcac.65ad8f0c.js 1.80 KiB 0.91 KiB
120 | dist\js\chunk-2fd8105c.e4c1219d.js 1.56 KiB 0.73 KiB
121 | dist\css\chunk-vendors.b87d1f59.css 208.08 KiB 33.54 KiB
122 | dist\css\app.ea1689dd.css 16.43 KiB 8.13 KiB
123 | dist\css\chunk-2fd8105c.6e27bbcb.css 2.54 KiB 0.86 KiB
124 | dist\css\chunk-d225f4dc.b5e4bbcb.css 1.25 KiB 0.42 KiB
125 | dist\css\chunk-11fbe2c4.bd7e1ba0.css 0.69 KiB 0.31 KiB
126 | dist\css\chunk-1d8d5dbe.3a0848fc.css 0.51 KiB 0.25 KiB
127 | dist\css\chunk-4147566f.eb28eeef.css 0.48 KiB 0.24 KiB
128 | dist\css\chunk-05d7e486.1ae9b438.css 0.40 KiB 0.21 KiB
129 | dist\css\chunk-350dbcac.a836ecb7.css 0.34 KiB 0.19 KiB
130 | dist\css\chunk-71414ebd.530fb09f.css 0.28 KiB 0.17 KiB
131 | dist\css\chunk-22de37c4.ec67429c.css 0.25 KiB 0.16 KiB
132 | dist\css\chunk-49d141fb.daa62c3a.css 0.25 KiB 0.14 KiB
133 | dist\css\chunk-3a3be80e.8781878b.css 0.19 KiB 0.13 KiB
134 | dist\css\chunk-2e227146.23590e22.css 0.13 KiB 0.12 KiB
135 | dist\css\chunk-18609744.961bc328.css 0.12 KiB 0.10 KiB
136 | dist\css\chunk-2304eda0.27c6ebd0.css 0.12 KiB 0.11 KiB
137 | dist\css\chunk-b851b192.5fa2fcc7.css 0.12 KiB 0.11 KiB
138 | dist\css\chunk-10c0c0ac.d98e47c9.css 0.10 KiB 0.10 KiB
139 | dist\css\chunk-772f45f6.0e433876.css 0.00 KiB 0.02 KiB
140 |
141 | Images and other types of assets omitted.
142 | ```
143 |
144 | 构建出的产物是:
145 |
146 | `dist\`
147 |
148 | 简单来说把整个dist目录里面的内容放到静态服务器上就行
149 |
150 |
151 |
152 | ****
153 |
154 |
155 |
156 | 好了,基本配置的就完了,**懂Node.js会Vue.js不用我说都知道怎么弄,不会的,我写再多也是一脸懵**
157 |
158 |
159 |
160 | 如果有哪位大神愿意出一个详细的教程,有视频更好,欢迎@我
161 |
162 |
163 |
164 | ### 感谢
165 |
166 |
167 |
168 | 感谢Jetbrains 这家伟大的IDE开发公司,他们的全家桶极其好用
169 |
170 | [https://jetbrains.com/](https://jetbrains.com/)
171 |
172 |
173 |
174 | ### 协议
175 |
176 | 使用本代码请保留前端界面到 https://ujuji.com 的链接
177 |
178 | Apache License 2.0
179 |
180 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ujuji_navigation",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "awe-dnd": "^0.3.4",
12 | "axios": "^0.19.2",
13 | "bookmark-file-parser": "^0.12.6",
14 | "clipboard": "^2.0.6",
15 | "core-js": "^3.6.4",
16 | "element-ui": "^2.13.2",
17 | "vue": "^2.6.11",
18 | "vue-router": "^3.1.6",
19 | "vuex": "^3.1.3",
20 | "xlsx-oc": "^1.0.2"
21 | },
22 | "devDependencies": {
23 | "@vue/cli-plugin-babel": "^4.3.0",
24 | "@vue/cli-plugin-eslint": "^4.3.0",
25 | "@vue/cli-service": "^4.3.0",
26 | "babel-eslint": "^10.1.0",
27 | "babel-plugin-component": "^1.1.1",
28 | "eslint": "^7.6.0",
29 | "eslint-plugin-vue": "^6.2.2",
30 | "node-sass": "^4.12.0",
31 | "sass-loader": "^8.0.2",
32 | "vue-template-compiler": "^2.6.11"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
20 |
21 | 优质网站 | 优聚集
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
30 |
31 |
53 |
--------------------------------------------------------------------------------
/src/api/boxApi.js:
--------------------------------------------------------------------------------
1 | import http from '../config/http';
2 |
3 | export const reqBoxData = (userId) => {
4 | return http.get('/user/box/user/' + userId)
5 | }
6 | export const reqBoxesByToken = (token) => {
7 | return http.get(`/public/allBoxes/token/${token}`)
8 | }
9 |
10 | export const reqAddLink = (token, data) => {
11 | return http.post(`/public/token/${token}`, {...data})
12 | }
13 |
--------------------------------------------------------------------------------
/src/api/commonApi.js:
--------------------------------------------------------------------------------
1 | import http from '../config/http'
2 |
3 | export const reqTQData = (city = '') => {
4 | return http.get('/public/weather?city='+city)
5 | }
6 |
--------------------------------------------------------------------------------
/src/api/userApi.js:
--------------------------------------------------------------------------------
1 | import http from '../config/http';
2 |
3 | export const reqImportBox = (data) => {
4 | return http.post('/user/box/import', {...data})
5 | }
6 | export const reqUserInfo = () => {
7 | return http.get('/auth/info')
8 | }
9 |
10 | export const reqGenerateToken = () => {
11 | return http.post('/auth/token')
12 | }
13 |
--------------------------------------------------------------------------------
/src/assets/css/global.scss:
--------------------------------------------------------------------------------
1 | html, body, #app {
2 | width: 100%;
3 | height: 100%;
4 | }
5 |
6 | .search {
7 | .search-input {
8 | input {
9 | background-color: rgba(0, 0, 0, .2) !important;
10 | border-top-left-radius: 25px;
11 | border-bottom-left-radius: 25px;
12 | padding: 0 1.5rem;
13 | border-width: 0;
14 | color: white;
15 | transition: all .1s;
16 |
17 | &:hover {
18 | transition: all .1s;
19 | background-color: rgba(0, 0, 0, .5) !important;
20 | }
21 | }
22 |
23 | //.el-input-group__append {
24 | // background: transparent;
25 | // border: none;
26 | // border-width: 0 !important;
27 | //}
28 | .el-input-group__append {
29 | background-color: rgba(0, 0, 0, .2);
30 | color: white;
31 | font-size: 18px;
32 | border-top-right-radius: 25px;
33 | border-bottom-right-radius: 25px;
34 | border-width: 0;
35 | cursor: pointer;
36 | }
37 | }
38 |
39 | }
40 |
41 | .el-drawer, .el-drawer__header > :first-child {
42 | &:focus {
43 | outline: none !important;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/assets/css/reset.scss:
--------------------------------------------------------------------------------
1 | body, div, li, ul, ol {
2 | font-family: Arial, sans-serif;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | body {
8 | //background-color: #eeeeee;
9 | font-size: 16px;
10 | }
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/src/assets/iconfont/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/src/assets/iconfont/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/src/assets/iconfont/iconfont.woff
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/src/assets/iconfont/iconfont.woff2
--------------------------------------------------------------------------------
/src/assets/img/bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/src/assets/img/bg.gif
--------------------------------------------------------------------------------
/src/assets/img/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xwudao/ujuji_frontend/5e0904054e32ef4cc34641520b269a9d2fc02ec2/src/assets/img/bg.png
--------------------------------------------------------------------------------
/src/assets/js/bjxt.js:
--------------------------------------------------------------------------------
1 | !function () {
2 | //封装方法,压缩之后减少文件大小
3 | function get_attribute(node, attr, default_value) {
4 | return node.getAttribute(attr) || default_value;
5 | }
6 |
7 | //封装方法,压缩之后减少文件大小
8 | function get_by_tagname(name) {
9 | return document.getElementsByTagName(name);
10 | }
11 |
12 | //获取配置参数
13 | function get_config_option() {
14 | var scripts = get_by_tagname("script"),
15 | script_len = scripts.length,
16 | script = scripts[script_len - 1]; //当前加载的script
17 | return {
18 | l: script_len, //长度,用于生成id用
19 | z: get_attribute(script, "zIndex", -1), //z-index
20 | o: get_attribute(script, "opacity", 0.5), //opacity
21 | c: get_attribute(script, "color", "255,255,255"), //color
22 | n: get_attribute(script, "count", 99) //count
23 | };
24 | }
25 |
26 | //设置canvas的高宽
27 | function set_canvas_size() {
28 | canvas_width = the_canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
29 | canvas_height = the_canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
30 | }
31 |
32 | //绘制过程
33 | function draw_canvas() {
34 | context.clearRect(0, 0, canvas_width, canvas_height);
35 | //随机的线条和当前位置联合数组
36 | var all_array = [current_point].concat(random_lines);
37 | var e, i, d, x_dist, y_dist, dist; //临时节点
38 | //遍历处理每一个点
39 | random_lines.forEach(function (r) {
40 | r.x += r.xa,
41 | r.y += r.ya, //移动
42 | r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1,
43 | r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1, //碰到边界,反向反弹
44 | context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); //绘制一个宽高为1的点
45 | for (i = 0; i < all_array.length; i++) {
46 | e = all_array[i];
47 | //不是当前点
48 | if (r !== e && null !== e.x && null !== e.y) {
49 | x_dist = r.x - e.x, //x轴距离 l
50 | y_dist = r.y - e.y, //y轴距离 n
51 | dist = x_dist * x_dist + y_dist * y_dist; //总距离, m
52 | dist < e.max && (e === current_point && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), //靠近的时候加速
53 | d = (e.max - dist) / e.max,
54 | context.beginPath(),
55 | context.lineWidth = d / 2,
56 | context.strokeStyle = "rgba(" + config.c + "," + (d + 0.2) + ")",
57 | context.moveTo(r.x, r.y),
58 | context.lineTo(e.x, e.y),
59 | context.stroke());
60 | }
61 | }
62 | all_array.splice(all_array.indexOf(r), 1);
63 |
64 | }), frame_func(draw_canvas);
65 | }
66 |
67 | //创建画布,并添加到body中
68 | var the_canvas = document.createElement("canvas"), //画布
69 | config = get_config_option(), //配置
70 | canvas_id = "c_n" + config.l, //canvas id
71 | context = the_canvas.getContext("2d"), canvas_width, canvas_height,
72 | frame_func = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (func) {
73 | window.setTimeout(func, 1000 / 45);
74 | }, random = Math.random,
75 | current_point = {
76 | x: null, //当前鼠标x
77 | y: null, //当前鼠标y
78 | max: 20000
79 | };
80 | the_canvas.id = canvas_id;
81 | the_canvas.style.cssText = "position:fixed;top:0;left:0;z-index:" + config.z + ";opacity:" + config.o;
82 | get_by_tagname("body")[0].appendChild(the_canvas);
83 | //初始化画布大小
84 |
85 | set_canvas_size(), window.onresize = set_canvas_size;
86 | //当时鼠标位置存储,离开的时候,释放当前位置信息
87 | window.onmousemove = function (e) {
88 | e = e || window.event, current_point.x = e.clientX, current_point.y = e.clientY;
89 | }, window.onmouseout = function () {
90 | current_point.x = null, current_point.y = null;
91 | };
92 | //随机生成config.n条线位置信息
93 | for (var random_lines = [], i = 0; config.n > i; i++) {
94 | var x = random() * canvas_width, //随机位置
95 | y = random() * canvas_height,
96 | xa = 2 * random() - 1, //随机运动方向
97 | ya = 2 * random() - 1;
98 | random_lines.push({
99 | x: x,
100 | y: y,
101 | xa: xa,
102 | ya: ya,
103 | max: 6000 //沾附距离
104 | });
105 | }
106 | //0.1秒后绘制
107 | setTimeout(function () {
108 | draw_canvas();
109 | }, 100);
110 | }();
--------------------------------------------------------------------------------
/src/components/common/Add.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
39 |
40 |
50 |
--------------------------------------------------------------------------------
/src/components/common/BackgroundEffect.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
37 |
38 |
--------------------------------------------------------------------------------
/src/components/common/LeaveMsg.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
40 |
41 |
--------------------------------------------------------------------------------
/src/components/common/Music.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
67 |
68 |
94 |
--------------------------------------------------------------------------------
/src/components/common/Notice.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
34 |
35 |
46 |
--------------------------------------------------------------------------------
/src/components/common/People.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
31 |
32 |
--------------------------------------------------------------------------------
/src/components/common/Sort.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
47 |
48 |
58 |
--------------------------------------------------------------------------------
/src/components/common/ToHot.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
28 |
29 |
39 |
--------------------------------------------------------------------------------
/src/components/common/ToMall.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
33 |
34 |
44 |
--------------------------------------------------------------------------------
/src/components/common/ToNav.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
37 |
38 |
48 |
--------------------------------------------------------------------------------
/src/components/common/Weather.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
45 |
46 |
56 |
--------------------------------------------------------------------------------
/src/components/dialog/AddBoxDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
15 |
16 |
17 |
19 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
36 |
37 |
38 |
39 |
133 |
134 |
--------------------------------------------------------------------------------
/src/components/dialog/AddListDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
15 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
43 |
44 |
45 |
49 |
50 |
51 |
52 |
130 |
131 |
--------------------------------------------------------------------------------
/src/components/dialog/AddSearchSiteDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
15 |
16 |
17 |
19 |
20 |
21 |
24 |
25 |
26 |
30 |
31 |
32 |
33 |
108 |
109 |
--------------------------------------------------------------------------------
/src/components/dialog/ImageDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 为了统一图标的风格,强烈建议使用此工具,生成统一的图标风格
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 文字颜色:
15 |
16 | 背景颜色
17 |
18 |
19 |
20 |
21 |
22 | 复制链接
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 |
90 |
91 |
--------------------------------------------------------------------------------
/src/components/dialog/MsgReplyDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 | 提交
14 |
15 |
16 |
17 |
18 |
19 |
60 |
61 |
--------------------------------------------------------------------------------
/src/components/dialog/MusicSettingDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 | 背景音乐设置
14 |
19 |
20 |
21 |
22 |
26 |
27 |
28 | 如何获取网易云永久音乐外链,请细看这里
31 |
32 |
33 | 背景图片设置
34 | 清空
35 |
36 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
131 |
132 |
152 |
--------------------------------------------------------------------------------
/src/components/dialog/NoticeDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | 站长暂未设置公告哟!
10 |
11 |
12 |
13 |
35 |
36 |
--------------------------------------------------------------------------------
/src/components/dialog/UpdateBoxDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
15 |
16 |
17 |
19 |
20 |
21 |
22 |
24 |
25 |
26 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
134 |
135 |
--------------------------------------------------------------------------------
/src/components/dialog/UpdateListDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
41 |
42 |
43 |
46 |
47 |
48 |
52 |
53 |
54 |
55 |
152 |
153 |
156 |
--------------------------------------------------------------------------------
/src/components/dialog/UpdateSearchSiteDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
15 |
16 |
17 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
31 |
32 |
33 |
34 |
111 |
112 |
--------------------------------------------------------------------------------
/src/components/dialog/ViewMsgDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
45 |
46 |
--------------------------------------------------------------------------------
/src/components/dialog/WeatherDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 | 地区:
10 |
12 |
13 |
14 |
15 |
62 |
63 |
69 |
--------------------------------------------------------------------------------
/src/components/dialog/WechatDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
12 | 交流、反馈、优质网站推荐,都在【迷思爱】公众号
13 |
14 |
15 |
16 |
17 |
34 |
35 |
--------------------------------------------------------------------------------
/src/components/drawer/AddDrawer.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
19 |
20 |
21 |
23 |
28 |
29 |
30 |
31 |
32 |
35 |
36 |
37 |
40 |
41 |
42 |
45 |
46 |
47 |
48 |
51 |
52 |
53 | 提交
54 |
55 |
56 |
57 |
58 |
59 |
157 |
158 |
163 |
--------------------------------------------------------------------------------
/src/components/item/MsgItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 置顶
5 | 留言
6 |
7 |
8 |
9 |
10 |
11 |
12 |
回复:
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
28 |
--------------------------------------------------------------------------------
/src/components/item/NavItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
![]()
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
23 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
38 |
41 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
114 |
115 |
268 |
--------------------------------------------------------------------------------
/src/components/user/Bottom.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ©
5 |
6 | 优聚集
7 |
8 |
9 |
10 |
11 |
29 |
30 |
--------------------------------------------------------------------------------
/src/components/user/Left.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 管理首页
7 |
8 |
9 |
10 | 站点配置
11 |
12 |
13 |
14 | 个人中心
15 |
16 |
17 |
18 |
19 | 公告设置
20 |
21 |
22 |
23 |
24 | 留言管理
25 |
26 |
27 |
28 |
29 | 盒子管理
30 |
31 |
32 |
33 | 列表管理
34 |
35 |
36 |
37 | 搜索配置
38 |
39 |
40 |
41 |
42 | 导出功能
43 |
44 |
45 |
46 |
47 | 导入功能
48 |
49 |
50 |
51 |
52 | 更新日记
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 关于我们
62 |
63 |
64 |
65 |
66 |
67 |
168 |
169 |
180 |
--------------------------------------------------------------------------------
/src/components/user/Top.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
40 |
41 |
--------------------------------------------------------------------------------
/src/config/TransformData.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | export default new Vue();
--------------------------------------------------------------------------------
/src/config/code.js:
--------------------------------------------------------------------------------
1 | export const SUCCESS_CODE = 1000;
2 | export const ADD_SUCCESS_CODE = 30002;
3 |
--------------------------------------------------------------------------------
/src/config/config.js:
--------------------------------------------------------------------------------
1 | const UPDATE_NOTE_SHOW_KEY = 'updateNote-v26';
2 | const MAIN_URL = 'https://ujuji.com';
3 | const BASE_URL = 'https://[suffix].ujuji.com/';
4 | const IMAGE_URL = 'http://api.misiai.com/favicon/api1.php?bgc=[bgColor]&color=[textColor]&str=[text]';
5 | const FAVICON_API_URL = 'https://i.olsh.me/icon?size=80..120..200&url=';
6 | const BING_IMAGE_URL = 'https://tool.misiyu.cn/api/bing';
7 | const HUA_WEI_CLOUD_URL = 'https://www.misiyu.cn/article/157.html';
8 | const TAOKE_URL = [
9 | 'https://shop.misiai.com',
10 | 'https://mall.misiai.com'
11 | ];
12 | const MALL_URL='https://mall.misiai.com'
13 | const MOBILE_BACKGROUND_COLOR = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAAA0CAIAAAC7EdcxAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABOSURBVGhD7c5BDQAwEAShGlv/tqqCxyWDAt6uaew19hp7jb3GXmOvsdfYa+w19hp7jb3GXmOvsdfYa+w19hp7jb3GXmOvsdfYa+xdG28fFp+RnV5AzWkAAAAASUVORK5CYII=';
14 | // const FAVICON_API_URL = 'https://api.byi.pw/favicon/?url=';
15 | const BING_IMG_API_URL = 'https://api2.misiai.com/bing/v1/today';
16 | // const BING_IMG_API_URL = 'https://common.misiai.com/public/bing';
17 | const ANIME_IMG_API_URL = 'https://api.ixiaowai.cn/api/api.php';
18 | const SEARCH_SITE_URL = 'https://search.ujuji.com/';
19 | const NAV_SITE_URL = 'https://nav.ujuji.com/';
20 | const LZPAN_URL = 'https://lzpan.com'
21 | const HOT_HUB_URL = 'https://ihothub.com/';
22 | const KEY_ORDER = 'box_orders';
23 | const KEY_SEARCH_INDEX = 'key_search_site_index';
24 | const KEY_BACKGROUND_IMAGE = 'key_background_image'
25 | const EVENT_SET_BGI = 'event_set_background_image'
26 |
27 | exports.MALL_URL = MALL_URL;
28 | exports.EVENT_SET_BGI = EVENT_SET_BGI;
29 | exports.KEY_BACKGROUND_IMAGE = KEY_BACKGROUND_IMAGE;
30 | exports.LZPAN_URL = LZPAN_URL;
31 | exports.NAV_SITE_URL = NAV_SITE_URL;
32 | exports.HOT_HUB_URL = HOT_HUB_URL;
33 | exports.SEARCH_SITE_URL = SEARCH_SITE_URL;
34 | exports.KEY_SEARCH_INDEX = KEY_SEARCH_INDEX;
35 | exports.ANIME_IMG_API_URL = ANIME_IMG_API_URL;
36 | exports.BING_IMG_API_URL = BING_IMG_API_URL;
37 | exports.KEY_ORDER = KEY_ORDER;
38 | exports.MAIN_URL = MAIN_URL;
39 | exports.MOBILE_BACKGROUND_COLOR = MOBILE_BACKGROUND_COLOR;
40 | exports.UPDATE_NOTE_SHOW_KEY = UPDATE_NOTE_SHOW_KEY;
41 | exports.BASE_URL = BASE_URL;
42 | exports.HUA_WEI_CLOUD_URL = HUA_WEI_CLOUD_URL;
43 | exports.TAOKE_URL = TAOKE_URL;
44 | exports.IMAGE_URL = IMAGE_URL;
45 | exports.FAVICON_API_URL = FAVICON_API_URL;
46 | exports.BING_IMGAE_URL = BING_IMAGE_URL;
47 |
--------------------------------------------------------------------------------
/src/config/events.js:
--------------------------------------------------------------------------------
1 | export const EVENT_WEATHER = 'event_weather';
2 | export const EVENT_OPEN_WEATHER_DIALOG = 'openWeatherDialog';
3 | export const EVENT_CLOSE_WEATHER_DIALOG = 'closeWeatherDialog';
4 |
--------------------------------------------------------------------------------
/src/config/getInfo.js:
--------------------------------------------------------------------------------
1 | function getUserInfo() {
2 | let d = localStorage.getItem('userInfo');
3 | return JSON.parse(d) || [];
4 |
5 | }
6 |
7 | function isMobile() {
8 | const sUserAgent = navigator.userAgent.toLowerCase();
9 | return /ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(sUserAgent);
10 | }
11 |
12 | exports.getUserInfo = getUserInfo();
13 | exports.isMobile = isMobile();
--------------------------------------------------------------------------------
/src/config/guide.json:
--------------------------------------------------------------------------------
1 | {
2 | "guides": [
3 | {
4 | "url": "https://www.misiyu.cn/article/149.html",
5 | "title": "[优聚集]用户使用说明书"
6 | },
7 | {
8 | "url": "https://www.misiyu.cn/article/150.html",
9 | "title": "[优聚集]用户使用与免责申明"
10 | },
11 | {
12 | "url": "https://www.misiyu.cn/article/151.html",
13 | "title": "[优聚集]用户背景音乐和背景图片设置"
14 | },
15 | {
16 | "url": "https://www.misiyu.cn/article/152.html",
17 | "title": "[优聚集]首页添加搜索站点"
18 | },
19 | {
20 | "url": "https://www.misiyu.cn/article/154.html",
21 | "title": "[优聚集]支持设置盒子的颜色了(额外说明)"
22 | },
23 | {
24 | "url": "https://www.misiyu.cn/article/164.html",
25 | "title": "[优聚集]快捷添加一个站点链接"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/src/config/http.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import router from "../router";
3 | import store from "../store";
4 |
5 | let url;
6 | if (process.env.NODE_ENV === 'production') {
7 | url = 'https://api.ujuji.com'
8 | } else {
9 | url = 'http://localhost:4037'
10 | }
11 | axios.defaults.baseURL = url;
12 | axios.defaults.headers.common['Content-Type'] = 'application/json';
13 | // axios.defaults.headers.common['Authorization'] = store.state.token;
14 | axios.interceptors.request.use(
15 | config => {
16 | config.headers['Authorization'] = 'Bearer ' + store.state.token;
17 | return config;
18 | }
19 | )
20 | axios.interceptors.response.use(
21 | (responses) => responses,
22 | (error) => {
23 | if (error.response && error.response.status === 403) {
24 | console.log(error);
25 | localStorage.removeItem('token');
26 | router.push({name: "UserLogin"});
27 | return new Promise(() => {
28 | }) // pending的promise,中止promise链
29 | }
30 | }
31 | );
32 | export default axios;
--------------------------------------------------------------------------------
/src/config/keys.js:
--------------------------------------------------------------------------------
1 | export const KEY_WEATHER = 'key_weather';
2 |
--------------------------------------------------------------------------------
/src/config/strings.js:
--------------------------------------------------------------------------------
1 | export const REQ_BOXES_DATA_ERROR = '请求分类数据错误'
2 | export const TOKEN_PARAM_REQUIRED = '您的请求未携带token,所以本次请求无效'
3 | export const REQ_DATA_ERROR = '本次请求失败,请稍后重试'
4 | export const TEXT_COPY_SUCCESS = '复制成功'
5 | export const TEXT_COPY_FAIL = '复制失败'
6 |
--------------------------------------------------------------------------------
/src/config/updateNotes.json:
--------------------------------------------------------------------------------
1 | {
2 | "activities": [
3 | {
4 | "content": "上线快捷添加链接功能",
5 | "timestamp": "2020-12-31 20:58:01",
6 | "color": "#0bbd87"
7 | },
8 | {
9 | "content": "登录用户可在首页直接添加站点",
10 | "timestamp": "2020-12-12 14:44:01",
11 | "color": "#0bbd87"
12 | },
13 | {
14 | "content": "后台可设置是否显示站点前的图标",
15 | "timestamp": "2020-09-19 09:44:01",
16 | "color": "#0bbd87"
17 | },
18 | {
19 | "content": "更换天气预报,现在首页可设置天气预报地区了!",
20 | "timestamp": "2020-08-14 16:35:21",
21 | "color": "#0bbd87"
22 | },
23 | {
24 | "content": "现在支持导入浏览器书签了(后缀为:.html)",
25 | "timestamp": "2020-08-12 15:35:21",
26 | "color": "#0bbd87"
27 | },
28 | {
29 | "content": "现在可导入盒子(书签)了,尽情测试【请勿滥用此功能】",
30 | "timestamp": "2020-08-05 15:35:21",
31 | "color": "#0bbd87"
32 | },
33 | {
34 | "content": "后台可以设置带有密码的盒子是否显示在首页(用户自己登录了,那么默认肯定也会显示且不需要输入密码)",
35 | "timestamp": "2020-07-22 11:35:21",
36 | "color": "#0bbd87"
37 | },
38 | {
39 | "content": "现在登录用户可以直接看到需要输入密码的盒子内容,游客则需要输入密码",
40 | "timestamp": "2020-07-16 11:35:21",
41 | "color": "#0bbd87"
42 | },
43 | {
44 | "content": "增加手机端背景可单独设置的功能,由于浏览器原因,在手机端背景图片并不能很好的固定,导致很难看。所以可单独为手机端设置一张合适的背景",
45 | "timestamp": "2020-07-07 07:35:21",
46 | "color": "#0bbd87"
47 | },
48 | {
49 | "content": "增加随机背景的选择,目前有两个:【必应美图】【二次元美图】,前者每日一换,后者随机更换",
50 | "timestamp": "2020-07-06 11:11:42",
51 | "color": "#0bbd87"
52 | },
53 | {
54 | "content": "用户可自定义首页的背景音乐啦~没有自定义的,就使用后台站长设定的音乐",
55 | "timestamp": "2020-07-05 08:45:52",
56 | "color": "#0bbd87"
57 | },
58 | {
59 | "content": "增加找回密码功能(通过电子邮箱)",
60 | "timestamp": "2020-07-02 09:41:49",
61 | "color": "#0bbd87"
62 | },
63 | {
64 | "content": "新增两种导出方式(Csv、TXT),欢迎体验导出功能,不让辛苦添加的网址因网站问题而丢失",
65 | "timestamp": "2020-06-29 17:16:59",
66 | "color": "#0bbd87"
67 | },
68 | {
69 | "content": "1、完善体验,添加、修改时,可以直接回车了,不用点击【提交】按钮。2、更改验证码样式,简单明了。",
70 | "timestamp": "2020-06-28 11:36:15",
71 | "color": "#0bbd87"
72 | },
73 | {
74 | "content": "首页,用户可拖动盒子排序,来自定义盒子的顺序",
75 | "timestamp": "2020-06-27 18:34:44",
76 | "color": "#0bbd87"
77 | },
78 | {
79 | "content": "首页音乐设定: 默认自动播放,用户手动点击暂停了,那么下次就不会自动播放了(就需要手动)",
80 | "timestamp": "2020-06-27 11:32:05",
81 | "color": "#0bbd87"
82 | },
83 | {
84 | "content": "目前可以设置搜索站点的文字颜色了,路径:站点配置->颜色配置->站点搜索",
85 | "timestamp": "2020-06-17 18:07:31",
86 | "color": "#0bbd87"
87 | },
88 | {
89 | "content": "增加盒子颜色的配置,这样对于背景图片就有更好的选择了。【对于这点,有些颜色知识需要额外说一下,可看[管理首页]的指导文章】",
90 | "timestamp": "2020-06-16 13:16:54",
91 | "color": "#0bbd87"
92 | },
93 | {
94 | "content": "目前需要用户手动点击音乐按钮,首页才会播放音乐,这样也许对不喜欢音乐的用户,是个好事",
95 | "timestamp": "2020-06-13 20:37:58",
96 | "color": "#0bbd87"
97 | },
98 | {
99 | "content": "增加首页的搜索网站自定义",
100 | "timestamp": "2020-06-11 14:12:26",
101 | "color": "#0bbd87"
102 | },
103 | {
104 | "content": "增加留言功能,有bug请到主站留言",
105 | "timestamp": "2020-06-10 19:56:41",
106 | "color": "#0bbd87"
107 | },
108 | {
109 | "content": "增加导出功能,成果不因意外而白费,现在可自行导出备份啦!",
110 | "timestamp": "2020-06-09 08:37:54",
111 | "color": "#0bbd87"
112 | },
113 | {
114 | "content": "增加长公告设置,原来的变为站点欢迎提示",
115 | "timestamp": "2020-06-08 13:27:37",
116 | "color": "#0bbd87"
117 | },
118 | {
119 | "content": "现在可以设置导航首页的背景音乐啦!",
120 | "timestamp": "2020-06-06 16:55:30",
121 | "color": "#0bbd87"
122 | },
123 | {
124 | "content": "现在可以给盒子设置访问密码啦,需要输入密码才能访问盒子内容(请勿滥用此功能,否则会被封号)",
125 | "timestamp": "2020-06-06 07:33:12",
126 | "color": "#0bbd87"
127 | },
128 | {
129 | "content": "增加公告模块,现在可以给访问导航的朋友设置一段话啦",
130 | "timestamp": "2020-06-3 17:44:35",
131 | "color": "#0bbd87"
132 | },
133 | {
134 | "content": "增加盒子、列表的本地检索(搜索标题)功能",
135 | "timestamp": "2020-06-3 10:53:03",
136 | "color": "#0bbd87"
137 | },
138 | {
139 | "content": "完全开放二级域名权限,现在不会跳转到顶级域名后缀",
140 | "timestamp": "2020-06-1 09:03:10",
141 | "color": "#0bbd87"
142 | },
143 | {
144 | "content": "支持设置盒子、站点列表的颜色",
145 | "timestamp": "2020-05-31 12:02:55",
146 | "color": "#0bbd87"
147 | },
148 | {
149 | "content": "不指定站点图标的话,就默认尝试使用其站点自身的图标",
150 | "timestamp": "2020-05-28 09:59:47",
151 | "color": "#0bbd87"
152 | },
153 | {
154 | "content": "可配置站点标题、描述的文字颜色",
155 | "timestamp": "2020-05-28 09:59:47",
156 | "color": "#0bbd87"
157 | }
158 | ]
159 | }
160 |
--------------------------------------------------------------------------------
/src/element/index.js:
--------------------------------------------------------------------------------
1 | // 导入自己需要的组件
2 | import {
3 | Notification, Loading, Message, Upload, Divider,
4 | Card, Form, FormItem, Input, Button, Table, TableColumn, Badge, MessageBox,
5 | Tooltip, Select, Option, Alert, InputNumber, ColorPicker, Timeline, TimelineItem,
6 | RadioGroup, Radio,
7 | Backtop, Tag, Pagination, Checkbox, Step, Steps, Switch,
8 | Dialog, Row, Col, TabPane, Tabs, MenuItem, Submenu, Menu, Drawer
9 | } from 'element-ui'
10 |
11 | const element = {
12 | install: function (Vue) {
13 | Vue.use(Divider);
14 | Vue.use(Drawer);
15 | Vue.use(Upload);
16 | Vue.use(Radio);
17 | Vue.use(RadioGroup);
18 | Vue.use(Switch);
19 | Vue.use(Checkbox);
20 | Vue.use(Steps);
21 | Vue.use(Step);
22 | Vue.use(Pagination);
23 | Vue.use(Tag);
24 | Vue.use(Timeline);
25 | Vue.use(Backtop);
26 | Vue.use(TimelineItem);
27 | Vue.use(ColorPicker);
28 | Vue.use(InputNumber);
29 | Vue.use(Alert);
30 | Vue.use(Option);
31 | Vue.use(Select);
32 | Vue.use(Badge);
33 | Vue.use(Tooltip);
34 | Vue.use(Table);
35 | Vue.use(TableColumn);
36 | Vue.use(Loading.directive);
37 | Vue.prototype.$notify = Notification;
38 | Vue.prototype.$confirm = MessageBox.confirm;
39 | Vue.prototype.$message = Message;
40 | Vue.use(Dialog);
41 | Vue.use(Row);
42 | Vue.use(Col);
43 | Vue.use(TabPane);
44 | Vue.use(Tabs);
45 | Vue.use(Submenu);
46 | Vue.use(Card);
47 | Vue.use(Menu);
48 | Vue.use(MenuItem);
49 | Vue.use(FormItem);
50 | Vue.use(Form);
51 | Vue.use(Input);
52 | Vue.use(Button);
53 | }
54 | };
55 | export default element
56 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import axios from './config/http';
6 |
7 | Vue.config.productionTip = false
8 |
9 | import VueDND from 'awe-dnd';
10 |
11 |
12 | Vue.use(VueDND);//拖拽排序
13 | Vue.prototype.$http = axios;
14 | // css样式还是需要全部引入
15 | import 'element-ui/lib/theme-chalk/index.css'
16 | import element from './element/index';
17 |
18 | // 重置样式
19 | import "./assets/css/reset.scss";
20 |
21 | Vue.use(element);
22 |
23 | router.beforeEach((to, from, next) => {
24 | if (to.meta.title) {
25 | document.title = to.meta.title;
26 | }
27 | next();
28 | });
29 |
30 | // iconfont
31 | import "./assets/iconfont/iconfont.css";
32 | // global
33 | import "./assets/css/global.scss";
34 |
35 | new Vue({
36 | router,
37 | store,
38 | render: h => h(App)
39 | }).$mount('#app')
40 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | // import Home from '../views/Home.vue'
4 | // import UserHome from "../views/user/UserHome";
5 | // import User from "../views/User";
6 | import Index from "../views/Index";
7 |
8 | Vue.use(VueRouter)
9 |
10 | const routes = [
11 | // {
12 | // path: '/',
13 | // name: 'Home',
14 | // component: Home
15 | // },
16 | {
17 | path: '/user',
18 | component: () => import("../views/User"),
19 | meta: {
20 | title: '控制台 | 优聚集'
21 | },
22 | children: [
23 | {
24 | path: '/',
25 | name: 'HomeConfig',
26 | component: () => import("../views/user/Home"),
27 | meta: {
28 | title: '控制台首页 | 优聚集'
29 | },
30 | },
31 | {
32 | path: '/profile',
33 | name: 'Profile',
34 | component: () => import("../views/user/Profile"),
35 | meta: {
36 | title: '个人中心 | 优聚集'
37 | },
38 | },
39 | {
40 | path: 'siteConfig',
41 | name: 'SiteConfig',
42 | component: () => import("../views/user/SiteConfig"),
43 | meta: {
44 | title: '站点配置 | 优聚集'
45 | },
46 | },
47 | {
48 | path: 'boxConfig',
49 | name: 'BoxConfig',
50 | component: () => import("../views/user/BoxConfig"),
51 | meta: {
52 | title: '盒子管理 | 优聚集'
53 | },
54 | },
55 | {
56 | path: 'importConfig',
57 | name: 'ImportConfig',
58 | component: () => import("../views/user/ImportConfig"),
59 | meta: {
60 | title: '导入功能 | 优聚集'
61 | },
62 | },
63 | {
64 | path: 'exportConfig',
65 | name: 'ExportConfig',
66 | component: () => import("../views/user/ExportConfig"),
67 | meta: {
68 | title: '导出功能 | 优聚集'
69 | },
70 | },
71 | {
72 | path: 'msgConfig',
73 | name: 'MsgConfig',
74 | component: () => import("../views/user/MsgConfig"),
75 | meta: {
76 | title: '留言管理 | 优聚集'
77 | },
78 | },
79 | {
80 | path: 'searchSiteConfig',
81 | name: 'SearchSiteConfig',
82 | component: () => import("../views/user/SearchSiteConfig"),
83 | meta: {
84 | title: '搜索站点配置 | 优聚集'
85 | },
86 | },
87 | {
88 | path: 'aboutUs',
89 | name: 'AboutUs',
90 | component: () => import("../views/user/AboutUs"),
91 | meta: {
92 | title: '关于我们 | 优聚集'
93 | },
94 | },
95 | {
96 | path: 'noticeConfig',
97 | name: 'NoticeConfig',
98 | component: () => import("../views/user/NoticeConfig"),
99 | meta: {
100 | title: '公告配置 | 优聚集'
101 | },
102 | },
103 | {
104 | path: 'listConfig',
105 | name: 'ListConfig',
106 | component: () => import("../views/user/ListConfig"),
107 | meta: {
108 | title: '列表管理 | 优聚集'
109 | },
110 | },
111 | {
112 | path: 'modifyPass',
113 | name: 'ModifyPass',
114 | component: () => import("../views/user/ModifyPass"),
115 | meta: {
116 | title: '修改密码 | 优聚集'
117 | },
118 | },
119 | {
120 | path: 'updateNote',
121 | name: 'UpdateNote',
122 | component: () => import("../views/user/UpdateNote"),
123 | meta: {
124 | title: '更新日记 | 优聚集'
125 | },
126 | },
127 | ]
128 | },
129 | {
130 | path: '/search',
131 | name: 'Search',
132 | component: () => import("../views/Search"),
133 | meta: {
134 | title: '搜索 | 优聚集'
135 | },
136 | },
137 | {
138 | path: '/token_add',
139 | name: 'TokenAdd',
140 | component: () => import("../views/TokenAdd"),
141 | meta: {
142 | title: '快速添加链接 | 优聚集'
143 | },
144 | },
145 | {
146 | path: '/userLogin',
147 | name: 'UserLogin',
148 | component: () => import("../views/user/UserLogin"),
149 | meta: {
150 | title: '用户登录 | 优聚集'
151 | },
152 | },
153 | {
154 | path: '/findPass',
155 | name: 'FindPass',
156 | component: () => import("../components/step/FindPassStep"),
157 | meta: {
158 | title: '找回密码 | 优聚集'
159 | },
160 | },
161 | {
162 | path: '/',
163 | name: 'Index',
164 | component: Index,
165 | meta: {
166 | title: '优质网站 | 优聚集'
167 | },
168 | // children: [
169 | // {
170 | // path: '/:suffix',
171 | // name: 'Index2',
172 | // component: Index,
173 | // meta: {
174 | // title: '优质网站 | 优聚集'
175 | // },
176 | // }
177 | // ]
178 | }
179 | ]
180 |
181 | const router = new VueRouter({
182 | mode: 'history',
183 | routes
184 | })
185 |
186 | export default router
187 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import state from "@/store/state";
4 | import mutations from "@/store/mutations";
5 | Vue.use(Vuex)
6 |
7 | export default new Vuex.Store({
8 | state,
9 | mutations,
10 | actions: {},
11 | modules: {}
12 | })
13 |
--------------------------------------------------------------------------------
/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | export default {
2 | changeSort(state, val) {
3 | state.sort = val;
4 | },
5 | changeCity(state, val) {
6 | state.city = val;
7 | },
8 | changeUserId(state, val) {
9 | state.userId = val;
10 | },
11 | changePlayMusic(state, val) {
12 | state.playMusic = val;
13 | },
14 | changeSiteUserId(state, val) {
15 | state.siteUserId = val;
16 | },
17 | changeBackgroundImage(state, val) {
18 | state.backgroundImage = val;
19 | },
20 | changeBackgroundMusic(state, val) {
21 | state.backgroundMusic = val;
22 | },
23 | changeIndexLoading(state, val) {
24 | state.indexLoading = val;
25 | },
26 | changeSuffix(state, val) {
27 | state.suffix = val;
28 | },
29 | changeDefaultSuffix(state, val) {
30 | state.defaultSuffix = val;
31 | },
32 | changeUsername(state, val) {
33 | state.username = val;
34 | },
35 | changeToken(state, val) {
36 | state.token = val;
37 | },
38 |
39 | changeUserInfo(state, val) {
40 | state.userInfo = val;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/store/state.js:
--------------------------------------------------------------------------------
1 | import {KEY_WEATHER} from "@/config/keys";
2 |
3 | const state = {
4 | token: '',
5 | userInfo: {},
6 | userId: -1,
7 | username: '',
8 | suffix: '',
9 | city: '',
10 | defaultSuffix: '',
11 | indexLoading: false,
12 | backgroundImage: '',
13 | backgroundMusic: '',
14 | siteUserId: -1,
15 | playMusic: false,
16 | sort: false,
17 | }
18 |
19 | let city = localStorage.getItem(KEY_WEATHER) || '';
20 | if (city) {
21 | state.city = city
22 | }
23 |
24 | export default state
25 |
--------------------------------------------------------------------------------
/src/util/isMobile.js:
--------------------------------------------------------------------------------
1 | function isMobile() {
2 | const sUserAgent = navigator.userAgent.toLowerCase();
3 | return /ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(sUserAgent);
4 | }
5 |
6 | export default isMobile;
--------------------------------------------------------------------------------
/src/util/utils.js:
--------------------------------------------------------------------------------
1 | function toFloat(value) {
2 |
3 | value = Math.round(parseFloat(value) * 100) / 100;
4 |
5 | if (value.toString().indexOf(".") < 0) {
6 |
7 | value = value.toString() + ".00";
8 |
9 | }
10 | return value;
11 | }
12 |
13 | function getWeekDate() {
14 | let now = new Date();
15 | let day = now.getDay();
16 | let weeks = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
17 | return weeks[day];
18 | }
19 |
20 | function getScrollTop() {
21 | var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
22 | if (document.body) {
23 | bodyScrollTop = document.body.scrollTop;
24 | }
25 | if (document.documentElement) {
26 | documentScrollTop = document.documentElement.scrollTop;
27 | }
28 | scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
29 | return scrollTop;
30 | }
31 |
32 | //文档的总高度
33 |
34 | function getScrollHeight() {
35 | var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
36 | if (document.body) {
37 | bodyScrollHeight = document.body.scrollHeight;
38 | }
39 | if (document.documentElement) {
40 | documentScrollHeight = document.documentElement.scrollHeight;
41 | }
42 | scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
43 | return scrollHeight;
44 | }
45 |
46 | //浏览器视口的高度
47 |
48 | function getWindowHeight() {
49 | var windowHeight = 0;
50 | if (document.compatMode === "CSS1Compat") {
51 | windowHeight = document.documentElement.clientHeight;
52 | } else {
53 | windowHeight = document.body.clientHeight;
54 | }
55 | return windowHeight;
56 | }
57 |
58 | function jumpUrl(url) {
59 | let ok = window.open(url, '_blank')
60 | if (!ok) {
61 | window.location.href = url;
62 | }
63 | }
64 |
65 |
66 | //是否是手机
67 | function isMobile() {
68 | const sUserAgent = navigator.userAgent.toLowerCase();
69 | return /ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(sUserAgent);
70 | }
71 |
72 | //是否是平板
73 | function isIpad() {
74 | let ua = navigator.userAgent.toLowerCase();
75 | return ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
76 |
77 | }
78 |
79 | function resetNoteVer(nowVer) {
80 | let exec = /^updateNote-v(\d+)$/ig.exec(nowVer);
81 | // console.log(exec);
82 | let n = parseInt(exec[1]);
83 | // console.log(n);
84 | for (let i = 0; i < n; i++) {
85 | localStorage.removeItem(nowVer.replace(n, i));
86 | }
87 | }
88 |
89 | exports.resetNoteVer = resetNoteVer;
90 | exports.isIpad = isIpad;
91 | exports.isMobile = isMobile;
92 | exports.jumpUrl = jumpUrl;
93 | exports.getWindowHeight = getWindowHeight;
94 | exports.getScrollHeight = getScrollHeight;
95 | exports.getScrollTop = getScrollTop;
96 | exports.toFloat = toFloat;
97 | exports.getWeekDate = getWeekDate;
98 |
--------------------------------------------------------------------------------
/src/views/Index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
102 |
103 |
151 |
--------------------------------------------------------------------------------
/src/views/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 搜索
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |

20 |
fsdffds
21 |
22 |
23 | 介绍文字
24 |
25 |
26 |
27 |
29 | 链接
30 |
31 |
32 |
33 |
34 |
35 |
36 |
41 |
42 |
--------------------------------------------------------------------------------
/src/views/TokenAdd.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 快捷添加
8 | 返回来源页
9 |
10 |
11 |
13 |
14 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
27 |
30 |
31 |
32 |
33 | 添加
34 |
35 |
36 |
37 |
38 | 请勿使用该功能将含有个人信息的链接添加至公共盒子,具体查看【此篇帖子】的[注意事项]栏
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
138 |
139 |
151 |
--------------------------------------------------------------------------------
/src/views/User.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
97 |
98 |
101 |
--------------------------------------------------------------------------------
/src/views/index/Footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
66 |
67 |
96 |
--------------------------------------------------------------------------------
/src/views/index/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
81 |
82 |
116 |
--------------------------------------------------------------------------------
/src/views/index/Nav.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
13 |
14 |
15 |
16 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
185 |
186 |
--------------------------------------------------------------------------------
/src/views/index/RightBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
63 |
64 |
83 |
--------------------------------------------------------------------------------
/src/views/index/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
105 |
106 |
157 |
--------------------------------------------------------------------------------
/src/views/user/AboutUs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 关于我们
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 赞赏、捐赠纯属自愿,是否捐赠都不会影响任何功能的使用
21 |
22 |

25 |

28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
40 |
41 |
--------------------------------------------------------------------------------
/src/views/user/ExportConfig.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 导出功能
6 |
12 |
13 |
14 |
15 |
16 | 导出Markdown
17 |
18 | 导出Csv
19 |
20 |
21 | 导出Txt
22 |
23 |
24 |
25 |
26 |
28 |
29 | 点此复制
30 |
31 |
32 |
33 | 1、目前支持Markdown、Csv、TXT格式的导出,Markdown导出后可复制到这里(https://mdliker.com/)查看效果
35 |
36 |
37 | 2、Csv导出:Csv文件用Office、WPS打开即可,可能会被Office报有错误,点是(修复)即可
38 |
39 |
40 | 3、Txt、Csv导出可能有浏览器兼容性问题,建议使用Chrome内核的浏览器(如Google Chrome、国产QQ、搜狗、360都可)
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
201 |
202 |
230 |
--------------------------------------------------------------------------------
/src/views/user/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 控制首页
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 未读留言:
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
69 |
70 |
--------------------------------------------------------------------------------
/src/views/user/ImportConfig.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 导入功能
6 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
提示:[此处]仅能上传经过本站导出的,格式为.csv 的文件,其余不支持!
20 |
21 |
22 |
23 |
25 |
26 |
27 |
提示:[此处]仅能上传从Chrome内核到浏览器导出的,格式为.html 的文件,其余不支持!且仅支持第一级书签目录!
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
{{ box.boxTitle }}
37 |
38 |
39 |
[{{ i + 1 }}] {{ item.title }}
40 |
41 |
42 |
43 |
44 |
45 | 导入
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
199 |
200 |
287 |
--------------------------------------------------------------------------------
/src/views/user/ModifyPass.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 修改密码
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 修改
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
99 |
100 |
--------------------------------------------------------------------------------
/src/views/user/NoticeConfig.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 提交
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
86 |
87 |
--------------------------------------------------------------------------------
/src/views/user/SearchSiteConfig.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 搜索管理
6 |
7 |
8 |
10 |
11 | 如何配置,请参考这里
13 |
17 |
20 |
21 | {{ scope.row.name }}
22 |
23 |
24 |
27 |
28 | {{ scope.row.notice }}
29 |
30 |
31 |
34 |
35 | {{ scope.row.siteOrder }}
36 |
37 |
38 |
41 |
42 | {{ processLink(scope.row.searchUrl) }}
43 |
44 |
45 |
46 |
47 | 编辑
50 |
51 | 删除
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
147 |
148 |
--------------------------------------------------------------------------------
/src/views/user/UpdateNote.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 更新日记
7 |
8 |
9 |
17 | {{activity.content}}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
40 |
41 |
46 |
--------------------------------------------------------------------------------