├── static ├── .gitkeep └── favicon.ico ├── bower.json ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── dist ├── google7be00fa6c7c3c70e.html ├── static │ ├── favicon.ico │ ├── img │ │ ├── login_bg.b922ceb.jpg │ │ └── emoji_sprite.7bc98f0.png │ └── js │ │ ├── manifest.f01cb571378191d65270.js │ │ └── manifest.f01cb571378191d65270.js.map └── index.html ├── tmp ├── UI │ ├── preview.png │ ├── preview (1).png │ ├── cub-logo-4_1.gif │ ├── mochrpratama_chat_module_exploration.jpg │ └── mochrpratama_-_chat_module_light_preview.jpg └── table.md ├── src ├── assets │ ├── images │ │ ├── logo.png │ │ ├── poster.jpg │ │ ├── login_bg.jpg │ │ ├── emoji_sprite.png │ │ ├── userinfo_bg.jpg │ │ ├── emoji │ │ │ ├── icon- (1).png │ │ │ ├── icon- (2).png │ │ │ ├── icon- (3).png │ │ │ ├── icon- (4).png │ │ │ ├── icon- (5).png │ │ │ ├── icon- (6).png │ │ │ ├── icon- (7).png │ │ │ ├── icon- (8).png │ │ │ ├── icon- (9).png │ │ │ ├── icon- (10).png │ │ │ ├── icon- (11).png │ │ │ ├── icon- (12).png │ │ │ ├── icon- (13).png │ │ │ ├── icon- (14).png │ │ │ ├── icon- (15).png │ │ │ ├── icon- (16).png │ │ │ ├── icon- (17).png │ │ │ ├── icon- (18).png │ │ │ ├── icon- (19).png │ │ │ ├── icon- (20).png │ │ │ ├── icon- (21).png │ │ │ ├── icon- (22).png │ │ │ ├── icon- (23).png │ │ │ ├── icon- (24).png │ │ │ ├── icon- (25).png │ │ │ ├── icon- (26).png │ │ │ ├── icon- (27).png │ │ │ ├── icon- (28).png │ │ │ ├── icon- (29).png │ │ │ ├── icon- (30).png │ │ │ ├── icon- (31).png │ │ │ ├── icon- (32).png │ │ │ ├── icon- (33).png │ │ │ ├── icon- (34).png │ │ │ ├── icon- (35).png │ │ │ ├── icon- (36).png │ │ │ ├── icon- (37).png │ │ │ ├── icon- (38).png │ │ │ ├── icon- (39).png │ │ │ ├── icon- (40).png │ │ │ ├── icon- (41).png │ │ │ ├── icon- (42).png │ │ │ ├── icon- (43).png │ │ │ ├── icon- (44).png │ │ │ ├── icon- (45).png │ │ │ ├── icon- (46).png │ │ │ ├── icon- (47).png │ │ │ ├── icon- (48).png │ │ │ ├── icon- (49).png │ │ │ ├── icon- (50).png │ │ │ ├── icon- (51).png │ │ │ ├── icon- (52).png │ │ │ ├── icon- (53).png │ │ │ ├── icon- (54).png │ │ │ ├── icon- (55).png │ │ │ ├── icon- (56).png │ │ │ ├── icon- (57).png │ │ │ ├── icon- (58).png │ │ │ ├── icon- (59).png │ │ │ ├── icon- (60).png │ │ │ ├── icon- (61).png │ │ │ ├── icon- (62).png │ │ │ ├── icon- (63).png │ │ │ ├── icon- (64).png │ │ │ ├── icon- (65).png │ │ │ ├── icon- (66).png │ │ │ ├── icon- (67).png │ │ │ ├── icon- (68).png │ │ │ ├── icon- (69).png │ │ │ ├── icon- (70).png │ │ │ ├── icon- (71).png │ │ │ ├── icon- (72).png │ │ │ ├── icon- (73).png │ │ │ └── icon- (74).png │ │ └── avatar_placehold.png │ └── css │ │ └── emoji.css ├── api │ ├── config.js │ └── index.js ├── components │ ├── Backtop.vue │ ├── Emoji.vue │ ├── Upload.vue │ ├── SettingsPublic.vue │ ├── Snackbar.vue │ ├── Me.vue │ ├── PostDetail.vue │ ├── Sidebar.vue │ ├── Config.vue │ ├── SettingsSelf.vue │ ├── RegistForm.vue │ ├── Settings.vue │ ├── PostForm.vue │ ├── SettingsUpload.vue │ ├── ImageFinder.vue │ ├── ImagePop.vue │ ├── RegistUserInfoForm.vue │ ├── Fileupload.vue │ └── Chatroom.vue ├── utils │ ├── storage.js │ └── common.js ├── main.js ├── pages │ ├── Init.vue │ └── Home.vue ├── router │ └── index.js ├── config │ └── particleConfig.js ├── store │ └── index.js └── App.vue ├── server ├── .gitignore ├── gitconf ├── api │ ├── utils │ │ ├── createToken.js │ │ ├── conf.js │ │ └── qiniu.js │ ├── routes │ │ └── qiniuRoute.js │ └── controllers │ │ └── qiniuController.js ├── LICENSE ├── package.json └── server.js ├── .gitignore ├── .editorconfig ├── .postcssrc.js ├── .babelrc ├── gitconf ├── LICENSE ├── gulpfile.js ├── index.html ├── package.json └── README.md /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-blog", 3 | "dependencies": {} 4 | } -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /dist/google7be00fa6c7c3c70e.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google7be00fa6c7c3c70e.html -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /tmp/UI/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/tmp/UI/preview.png -------------------------------------------------------------------------------- /tmp/UI/preview (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/tmp/UI/preview (1).png -------------------------------------------------------------------------------- /dist/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/dist/static/favicon.ico -------------------------------------------------------------------------------- /tmp/UI/cub-logo-4_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/tmp/UI/cub-logo-4_1.gif -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/poster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/poster.jpg -------------------------------------------------------------------------------- /src/assets/images/login_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/login_bg.jpg -------------------------------------------------------------------------------- /src/assets/images/emoji_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji_sprite.png -------------------------------------------------------------------------------- /src/assets/images/userinfo_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/userinfo_bg.jpg -------------------------------------------------------------------------------- /tmp/table.md: -------------------------------------------------------------------------------- 1 | ## 用户信息 2 | 用户名 3 | 密码 4 | 别名 5 | 性别 6 | 年龄 7 | 国家 -》下拉列表 8 | 城市 -》下拉列表 9 | token 权限访问接口 10 | -------------------------------------------------------------------------------- /dist/static/img/login_bg.b922ceb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/dist/static/img/login_bg.b922ceb.jpg -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | bower_components/ 7 | -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (1).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (2).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (3).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (4).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (5).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (6).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (7).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (8).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (9).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (9).png -------------------------------------------------------------------------------- /server/gitconf: -------------------------------------------------------------------------------- 1 | [remote "heroku"] 2 | url = https://git.heroku.com/qiniu-server.git 3 | fetch = +refs/heads/*:refs/remotes/heroku/* 4 | -------------------------------------------------------------------------------- /src/assets/images/avatar_placehold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/avatar_placehold.png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (10).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (10).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (11).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (11).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (12).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (12).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (13).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (13).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (14).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (14).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (15).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (15).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (16).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (16).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (17).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (17).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (18).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (18).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (19).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (19).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (20).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (20).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (21).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (21).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (22).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (22).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (23).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (23).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (24).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (24).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (25).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (25).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (26).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (26).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (27).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (27).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (28).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (28).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (29).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (29).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (30).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (30).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (31).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (31).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (32).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (32).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (33).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (33).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (34).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (34).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (35).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (35).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (36).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (36).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (37).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (37).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (38).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (38).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (39).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (39).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (40).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (40).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (41).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (41).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (42).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (42).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (43).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (43).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (44).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (44).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (45).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (45).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (46).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (46).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (47).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (47).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (48).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (48).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (49).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (49).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (50).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (50).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (51).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (51).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (52).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (52).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (53).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (53).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (54).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (54).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (55).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (55).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (56).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (56).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (57).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (57).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (58).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (58).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (59).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (59).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (60).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (60).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (61).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (61).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (62).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (62).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (63).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (63).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (64).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (64).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (65).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (65).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (66).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (66).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (67).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (67).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (68).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (68).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (69).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (69).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (70).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (70).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (71).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (71).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (72).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (72).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (73).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (73).png -------------------------------------------------------------------------------- /src/assets/images/emoji/icon- (74).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/src/assets/images/emoji/icon- (74).png -------------------------------------------------------------------------------- /dist/static/img/emoji_sprite.7bc98f0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/dist/static/img/emoji_sprite.7bc98f0.png -------------------------------------------------------------------------------- /tmp/UI/mochrpratama_chat_module_exploration.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/tmp/UI/mochrpratama_chat_module_exploration.jpg -------------------------------------------------------------------------------- /tmp/UI/mochrpratama_-_chat_module_light_preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex1504/vue-qiniu-image-bed/HEAD/tmp/UI/mochrpratama_-_chat_module_light_preview.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | bower_components/ 7 | .package-lock.json 8 | .vscode 9 | .idea 10 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserlist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false, 8 | "env": { 9 | "test": { 10 | "presets": ["env", "stage-2"], 11 | "plugins": [ "istanbul" ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /server/api/utils/createToken.js: -------------------------------------------------------------------------------- 1 | var { jsonTokenSecret, saltRounds, tokenExp } = require('../settings/settings') 2 | var jwt = require('jsonwebtoken') 3 | 4 | module.exports = function() { 5 | var token = jwt.sign({ 6 | exp: tokenExp 7 | }, jsonTokenSecret); 8 | 9 | return token; 10 | } -------------------------------------------------------------------------------- /gitconf: -------------------------------------------------------------------------------- 1 | [remote "origin"] 2 | url = https://github.com/alex1504/vue-qiniu-image-bed.git 3 | fetch = +refs/heads/*:refs/remotes/origin/* 4 | [branch "master"] 5 | remote = origin 6 | merge = refs/heads/master 7 | [remote "coding"] 8 | url = https://git.coding.net/alex1504/vue-qiniu-image-bed.git 9 | fetch = +refs/heads/*:refs/remotes/coding/* -------------------------------------------------------------------------------- /server/api/routes/qiniuRoute.js: -------------------------------------------------------------------------------- 1 | module.exports = function (app) { 2 | const qiniu = require('../controllers/qiniuController') 3 | 4 | app.route('/qiniuAuth') 5 | .post(qiniu.renderUploadToken); 6 | 7 | app.route('/upload') 8 | .post(qiniu.uploadFile); 9 | 10 | app.route('/imageInfo') 11 | .post(qiniu.getImageInfo); 12 | 13 | app.route('/imageList') 14 | .post(qiniu.getImageList); 15 | 16 | app.route('/image/delete') 17 | .post(qiniu.deleteImage); 18 | 19 | app.route('/upload/fetch') 20 | .post(qiniu.fetchAndUpload); 21 | } 22 | -------------------------------------------------------------------------------- /src/api/config.js: -------------------------------------------------------------------------------- 1 | import storage from '../utils/storage' 2 | 3 | export const auth = { 4 | accessKey: storage.get("qiniu-settings") && storage.get("qiniu-settings").accessKey, 5 | secretKey: storage.get("qiniu-settings") && storage.get("qiniu-settings").secretKey, 6 | bucket: storage.get("qiniu-settings") && storage.get("qiniu-settings").bucket 7 | }; 8 | 9 | export const publicSettings = { 10 | accessKey: "542DypDdMKrx6xAMN1Ce_kWmtKTLKK5U8x842JYP", 11 | secretKey: "Knt7eUNDHt-by7Nyq_VZWMsnpyt46BNYwfePODsL", 12 | bucket: "image", 13 | domain: "http://qiniu1.huzerui.com" 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/Backtop.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /src/utils/storage.js: -------------------------------------------------------------------------------- 1 | const uniquePrefix = 'xabcdervqq' 2 | export default { 3 | detect: function () { 4 | return (window.localStorage !== 'undefined') ? true : false 5 | }, 6 | get: function (key) { 7 | key = `${uniquePrefix}-${key}` 8 | var value = localStorage.getItem(key); 9 | try { 10 | return JSON.parse(value); 11 | } catch (err) { 12 | return value; 13 | } 14 | }, 15 | set: function (key, value) { 16 | if (typeof value == 'object') { 17 | value = JSON.stringify(value); 18 | } 19 | key = `${uniquePrefix}-${key}` 20 | return localStorage.setItem(key, value); 21 | }, 22 | remove: function (key) { 23 | return localStorage.removeItem(key); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/Emoji.vue: -------------------------------------------------------------------------------- 1 | 6 | 30 | 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Zerui Hu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /server/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 alex1504 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import MuseUI from 'muse-ui' 7 | import 'muse-ui/dist/muse-ui.css' 8 | import store from './store/index.js' 9 | import VueClipboard from 'vue-clipboard2' 10 | import infiniteScroll from 'vue-infinite-scroll' 11 | 12 | 13 | Vue.use(MuseUI); 14 | Vue.use(VueClipboard); 15 | Vue.use(infiniteScroll); 16 | 17 | Vue.config.productionTip = false; 18 | 19 | new Vue({ 20 | el: '#app', 21 | router, 22 | store, 23 | template: '', 24 | components: {App}, 25 | methods: { 26 | // 获取当前路由名称 27 | getActiveRoute: function () { 28 | return this.$route.name 29 | }, 30 | // 提交当前路由名称 31 | commitActiveRoute: function () { 32 | var activeRoute = this.getActiveRoute(); 33 | this.$store.commit('ACTIVE_ROUTE_CHANGE', { 34 | 'activeRoute': activeRoute 35 | }) 36 | }, 37 | }, 38 | mounted: function () { 39 | // 初始提交路由名称 40 | this.commitActiveRoute(); 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-express-app-server", 3 | "main": "server.js", 4 | "version": "7.1.0", 5 | "engine": { 6 | "node": "*", 7 | "npm": "*" 8 | }, 9 | "scripts": { 10 | "start": "node server.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/alex1504/vue-qiniu-image-bed.git" 15 | }, 16 | "dependencies": { 17 | "agentkeepalive": "3.3.0", 18 | "bcrypt": "^1.0.2", 19 | "body-parser": "^1.17.2", 20 | "cors": "^2.8.4", 21 | "crc32": "0.2.2", 22 | "express": "^4.15.3", 23 | "formidable": "^1.1.1", 24 | "formstream": "1.1.0", 25 | "jsonwebtoken": "^7.4.1", 26 | "lodash": "^4.17.4", 27 | "mime": "1.3.6", 28 | "mongoose": "^4.10.5", 29 | "qiniu": "^7.1.0", 30 | "superagent": "^3.7.0", 31 | "tunnel-agent": "0.6.0", 32 | "urlencode": "1.1.0", 33 | "urllib": "2.22.0" 34 | }, 35 | "devDependencies": { 36 | "nodemon": "^1.11.0", 37 | "@types/node": "^8.0.3", 38 | "blanket": "*", 39 | "mocha": "*", 40 | "pedding": "*", 41 | "should": "1.2.2", 42 | "travis-cov": "*" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var merge = require('merge-stream'); 3 | var imagemin = require('gulp-imagemin'); 4 | var buffer = require('vinyl-buffer'); 5 | var spritesmith = require('gulp.spritesmith'); 6 | 7 | gulp.task('sprite', function() { 8 | // Generate our spritesheet 9 | var spriteData = gulp.src('img/icon-?*.png').pipe(spritesmith({ 10 | imgName: 'icon_sprite.png', 11 | cssName: 'icon_sprite.css', 12 | cssVarMap: function(sprite) { 13 | sprite.name = sprite.name.replace("icon-", ""); 14 | }, 15 | imgPath: '../images/emoji_sprite.png' 16 | })); 17 | 18 | // Pipe image stream through image optimizer and onto disk 19 | var imgStream = spriteData.img 20 | // DEV: We must buffer our stream into a Buffer for `imagemin` 21 | .pipe(buffer()) 22 | .pipe(imagemin()) 23 | .pipe(gulp.dest('src/imgs/')); 24 | 25 | // Pipe CSS stream through CSS optimizer and onto disk 26 | var cssStream = spriteData.css 27 | .pipe(gulp.dest('src/css/')); 28 | 29 | // Return a merged stream to handle both `end` events 30 | return merge(imgStream, cssStream); 31 | }); -------------------------------------------------------------------------------- /src/components/Upload.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 31 | 32 | 49 | -------------------------------------------------------------------------------- /src/components/SettingsPublic.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 30 | 31 | 40 | -------------------------------------------------------------------------------- /dist/static/js/manifest.f01cb571378191d65270.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,i){for(var u,a,f,s=0,l=[];s 2 |
3 | 4 |
5 | 6 | 7 | 51 | 52 | 67 | -------------------------------------------------------------------------------- /src/utils/common.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import storage from './storage' 3 | import {publicSettings} from '../api/config'; 4 | 5 | export default { 6 | getPublicSettings() { 7 | return publicSettings 8 | }, 9 | getQiniuAuth() { 10 | const qiniuFlag = storage.get("qiniu-active"); 11 | const privateSettings = storage.get("qiniu-settings"); 12 | if (qiniuFlag == 1) { 13 | return { 14 | accessKey: 15 | (privateSettings && 16 | privateSettings.accessKey) || 17 | "", 18 | secretKey: 19 | (privateSettings && 20 | privateSettings.secretKey) || 21 | "", 22 | bucket: 23 | (privateSettings && 24 | privateSettings.bucket) || 25 | "", 26 | domain: 27 | (privateSettings && 28 | privateSettings.domain) || 29 | "" 30 | }; 31 | } else if (qiniuFlag == 2) { 32 | return publicSettings 33 | } 34 | }, 35 | isSetQiniuAuth() { 36 | return storage.get("qiniu-settings") != null 37 | }, 38 | getFormatDate(ms) { 39 | const aDate = new Date(ms); 40 | const year = aDate.getFullYear(); 41 | const month = aDate.getMonth() + 1; 42 | const date = aDate.getDate(); 43 | return `${year}-${month}-${date}` 44 | 45 | }, 46 | debounce(func, wait, immediate) { 47 | var timeout, result; 48 | var debounced = function () { 49 | var context = this; 50 | var args = arguments; 51 | if (timeout) clearTimeout(timeout); 52 | if (immediate) { 53 | var callNow = !timeout; 54 | timeout = setTimeout(function () { 55 | timeout = null; 56 | }, wait) 57 | if (callNow) result = func.apply(context, args) 58 | } else { 59 | timeout = setTimeout(function () { 60 | func.apply(context, args) 61 | }, wait); 62 | } 63 | return result; 64 | }; 65 | debounced.cancel = function () { 66 | clearTimeout(timeout); 67 | timeout = null; 68 | }; 69 | 70 | return debounced; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/pages/Init.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 36 | 37 | 38 | 79 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 牛牛图床 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 26 | 40 | 41 | 42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/components/Me.vue: -------------------------------------------------------------------------------- 1 | 32 | 68 | 79 | -------------------------------------------------------------------------------- /src/components/PostDetail.vue: -------------------------------------------------------------------------------- 1 | 25 | 55 | 85 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Init from '@/pages/Init' 4 | import Home from '@/pages/Home' 5 | import Config from '@/components/Config' 6 | import RegistForm from '@/components/RegistForm' 7 | import RegistUserInfoForm from '@/components/RegistUserInfoForm' 8 | import ImageFinder from '@/components/ImageFinder' 9 | import Upload from '@/components/Upload' 10 | import Chatroom from '@/components/Chatroom' 11 | import NewPost from '@/components/PostForm' 12 | import PostDetail from '@/components/PostDetail' 13 | import ImageList from '@/components/ImageList' 14 | import Me from '@/components/Me' 15 | import Settings from '@/components/Settings' 16 | import Util from '../utils/common' 17 | 18 | Vue.use(Router) 19 | 20 | export default new Router({ 21 | routes: [{ 22 | path: '/', 23 | name: 'Init', 24 | component: Init, 25 | children: [{ 26 | name: 'Config', 27 | path: 'config', 28 | component: Config, 29 | }, { 30 | name: 'RegistForm', 31 | path: 'regist', 32 | component: RegistForm 33 | }, { 34 | name: 'RegistUserInfoForm', 35 | path: 'regist/confirm', 36 | component: RegistUserInfoForm 37 | }] 38 | }, { 39 | path: '/home', 40 | name: 'Home', 41 | component: Home, 42 | redirect: { 43 | name: 'Upload' 44 | }, 45 | children: [{ 46 | name: 'ImageFinder', 47 | path: 'imageFinder', 48 | component: ImageFinder 49 | },{ 50 | name: 'Upload', 51 | path: 'upload', 52 | component: Upload 53 | }, { 54 | name: 'Chatroom', 55 | path: 'chatroom', 56 | component: Chatroom 57 | }, { 58 | name: 'NewPost', 59 | path: 'newpost', 60 | component: NewPost 61 | }, { 62 | name: 'PostDetail', 63 | path: 'postDetail/:id', 64 | component: PostDetail 65 | }, { 66 | name: 'ImageList', 67 | path: 'imageList', 68 | component: ImageList 69 | }, { 70 | name: 'Me', 71 | path: 'me', 72 | component: Me 73 | }, { 74 | name: 'Settings', 75 | path: 'settings', 76 | component: Settings 77 | }] 78 | }, { 79 | path: '*', 80 | name: 'root', 81 | redirect: { 82 | name: 'Upload' 83 | } 84 | }] 85 | }) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Niu-Niu-Image-Bed", 3 | "version": "1.0.0", 4 | "description": "Free bed, bed outside the chain, image upload, CDN acceleration", 5 | "author": "alex1504 ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "server": "nodemon server/server.js" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.16.2", 15 | "bcrypt": "^1.0.2", 16 | "body-parser": "^1.17.2", 17 | "express": "^4.15.3", 18 | "jsonwebtoken": "^7.4.1", 19 | "lodash": "^4.17.4", 20 | "moment": "^2.18.1", 21 | "mongoose": "^4.10.5", 22 | "muse-ui": "^2.0.3", 23 | "node-sass": "^4.5.3", 24 | "socket.io": "^2.0.3", 25 | "vue": "^2.3.3", 26 | "vue-awesome-swiper": "^2.4.2", 27 | "vue-clipboard2": "0.0.6", 28 | "vue-infinite-scroll": "^2.0.2", 29 | "vue-router": "^2.3.1", 30 | "vuex": "^2.3.1" 31 | }, 32 | "devDependencies": { 33 | "autoprefixer": "^6.7.2", 34 | "babel-core": "^6.22.1", 35 | "babel-loader": "^6.2.10", 36 | "babel-plugin-transform-runtime": "^6.22.0", 37 | "babel-preset-env": "^1.3.2", 38 | "babel-preset-stage-2": "^6.22.0", 39 | "babel-register": "^6.22.0", 40 | "bcrypt": "^1.0.2", 41 | "chalk": "^1.1.3", 42 | "connect-history-api-fallback": "^1.3.0", 43 | "copy-webpack-plugin": "^4.0.1", 44 | "cross-env": "^5.1.0", 45 | "css-loader": "^0.28.0", 46 | "eventsource-polyfill": "^0.9.6", 47 | "extract-text-webpack-plugin": "^2.0.0", 48 | "file-loader": "^0.11.1", 49 | "friendly-errors-webpack-plugin": "^1.1.3", 50 | "html-webpack-plugin": "^2.28.0", 51 | "http-proxy-middleware": "^0.17.3", 52 | "node-sass": "^4.5.3", 53 | "nodemon": "^1.11.0", 54 | "opn": "^4.0.2", 55 | "optimize-css-assets-webpack-plugin": "^1.3.0", 56 | "ora": "^1.2.0", 57 | "prerender-spa-plugin": "^2.1.0", 58 | "rimraf": "^2.6.0", 59 | "sass-loader": "^6.0.5", 60 | "semver": "^5.3.0", 61 | "shelljs": "^0.7.6", 62 | "url-loader": "^0.5.8", 63 | "vue-loader": "^12.1.0", 64 | "vue-style-loader": "^3.0.1", 65 | "vue-template-compiler": "^2.3.3", 66 | "webpack": "^2.6.1", 67 | "webpack-bundle-analyzer": "^2.2.1", 68 | "webpack-dev-middleware": "^1.10.0", 69 | "webpack-hot-middleware": "^2.18.0", 70 | "webpack-merge": "^4.1.0" 71 | }, 72 | "engines": { 73 | "node": ">= 4.0.0", 74 | "npm": ">= 3.0.0" 75 | }, 76 | "browserslist": [ 77 | "> 1%", 78 | "last 2 versions", 79 | "not ie <= 8" 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /src/config/particleConfig.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | "particles": { 3 | "number": { 4 | "value": 50, 5 | "density": { 6 | "enable": true, 7 | "value_area": 800 8 | } 9 | }, 10 | "color": { 11 | "value": "#ffffff" 12 | }, 13 | "shape": { 14 | "type": "circle", 15 | "stroke": { 16 | "width": 0, 17 | "color": "#000000" 18 | }, 19 | "polygon": { 20 | "nb_sides": 5 21 | }, 22 | "image": { 23 | "src": "img/github.svg", 24 | "width": 100, 25 | "height": 100 26 | } 27 | }, 28 | "opacity": { 29 | "value": 0.5, 30 | "random": false, 31 | "anim": { 32 | "enable": false, 33 | "speed": 1, 34 | "opacity_min": 0.1, 35 | "sync": false 36 | } 37 | }, 38 | "size": { 39 | "value": 3, 40 | "random": true, 41 | "anim": { 42 | "enable": false, 43 | "speed": 40, 44 | "size_min": 0.1, 45 | "sync": false 46 | } 47 | }, 48 | "line_linked": { 49 | "enable": true, 50 | "distance": 150, 51 | "color": "#ffffff", 52 | "opacity": 0.4, 53 | "width": 1 54 | }, 55 | "move": { 56 | "enable": true, 57 | "speed": 10, 58 | "direction": "none", 59 | "random": false, 60 | "straight": false, 61 | "out_mode": "out", 62 | "bounce": false, 63 | "attract": { 64 | "enable": false, 65 | "rotateX": 600, 66 | "rotateY": 1200 67 | } 68 | } 69 | }, 70 | "interactivity": { 71 | "detect_on": "canvas", 72 | "events": { 73 | "onhover": { 74 | "enable": true, 75 | "mode": "grab" 76 | }, 77 | "onclick": { 78 | "enable": true, 79 | "mode": "push" 80 | }, 81 | "resize": true 82 | }, 83 | "modes": { 84 | "grab": { 85 | "distance": 140, 86 | "line_linked": { 87 | "opacity": 1 88 | } 89 | }, 90 | "bubble": { 91 | "distance": 400, 92 | "size": 40, 93 | "duration": 2, 94 | "opacity": 8, 95 | "speed": 3 96 | }, 97 | "repulse": { 98 | "distance": 200, 99 | "duration": 0.4 100 | }, 101 | "push": { 102 | "particles_nb": 4 103 | }, 104 | "remove": { 105 | "particles_nb": 2 106 | } 107 | } 108 | }, 109 | "retina_detect": true 110 | } 111 | 112 | export default config -------------------------------------------------------------------------------- /src/pages/Home.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 63 | 64 | 103 | -------------------------------------------------------------------------------- /server/api/utils/conf.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const os = require('os'); 4 | const pkg = require('../../package.json'); 5 | 6 | exports.ACCESS_KEY = 'ZpcVLm3mhM_jvHaZQEbSRc9lad2t8FlN1eZKCWk6'; 7 | exports.SECRET_KEY = '9XWvOR9wLeoIRugYVu7xsHW1Z9k2NVw054AtuSDK'; 8 | 9 | var defaultUserAgent = function() { 10 | return 'QiniuNodejs/' + pkg.version + ' (' + os.type() + '; ' + os.platform() + 11 | '; ' + os.arch() + '; )'; 12 | } 13 | 14 | exports.USER_AGENT = defaultUserAgent(); 15 | exports.BLOCK_SIZE = 4 * 1024 * 1024; //4MB, never change 16 | 17 | //define api form mime type 18 | exports.FormMimeUrl = "application/x-www-form-urlencoded"; 19 | exports.FormMimeJson = "application/json"; 20 | exports.FormMimeRaw = "application/octet-stream"; 21 | exports.RS_HOST = "http://rs.qiniu.com"; 22 | exports.RPC_TIMEOUT = 120000; //120s 23 | 24 | //proxy 25 | exports.RPC_HTTP_AGENT = null; 26 | exports.RPC_HTTPS_AGENT = null; 27 | 28 | exports.Config = function Config(options) { 29 | options = options || {}; 30 | //use http or https protocol 31 | this.useHttpsDomain = options.useHttpsDomain || false; 32 | //use cdn accerlated domains 33 | this.useCdnDomain = options.useCdnDomain || true; 34 | //zone of the bucket 35 | //z0 huadong, z1 huabei, z2 huanan, na0 beimei 36 | this.zone = options.zone || null; 37 | this.zoneExpire = options.zoneExpire || -1; 38 | } 39 | 40 | exports.Zone = function(srcUpHosts, cdnUpHosts, ioHost, rsHost, rsfHost, 41 | apiHost) { 42 | this.srcUpHosts = srcUpHosts || {}; 43 | this.cdnUpHosts = cdnUpHosts || {}; 44 | this.ioHost = ioHost || ""; 45 | this.rsHost = rsHost || "rs.qiniu.com"; 46 | this.rsfHost = rsfHost || "rsf.qiniu.com"; 47 | this.apiHost = apiHost || "api.qiniu.com"; 48 | var dotIndex = this.ioHost.indexOf("."); 49 | if (dotIndex != -1) { 50 | var ioTag = this.ioHost.substring(0, dotIndex); 51 | var zoneSepIndex = ioTag.indexOf("-"); 52 | if (zoneSepIndex != -1) { 53 | var zoneTag = ioTag.substring(zoneSepIndex + 1); 54 | switch (zoneTag) { 55 | case "z1": 56 | this.rsHost = "rs-z1.qiniu.com"; 57 | this.rsfHost = "rsf-z1.qiniu.com"; 58 | this.apiHost = "api-z1.qiniu.com"; 59 | break; 60 | case "z2": 61 | this.rsHost = "rs-z2.qiniu.com"; 62 | this.rsfHost = "rsf-z2.qiniu.com"; 63 | this.apiHost = "api-z2.qiniu.com"; 64 | break; 65 | case "na0": 66 | this.rsHost = "rs-na0.qiniu.com"; 67 | this.rsfHost = "rsf-na0.qiniu.com"; 68 | this.apiHost = "api-na0.qiniu.com"; 69 | break; 70 | default: 71 | this.rsHost = "rs.qiniu.com"; 72 | this.rsfHost = "rsf.qiniu.com"; 73 | this.apiHost = "api.qiniu.com"; 74 | break; 75 | } 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/components/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 71 | 72 | 105 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | module: { 6 | // module.rules is the same as module.loaders in 1.x 7 | rules: [{ 8 | test: /\.vue$/, 9 | loader: 'vue-loader', 10 | // vue-loader options goes here 11 | options: { 12 | loaders: { 13 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map 14 | // the "scss" and "sass" values for the lang attribute to the right configs here. 15 | // other preprocessors should work out of the box, no loader config like this nessessary. 16 | 'scss': 'vue-style-loader!css-loader!sass-loader', 17 | 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax' 18 | } 19 | // other vue-loader options go here 20 | } 21 | }, { 22 | test: /\.scss$/, 23 | loader: 'style!css!sass', 24 | }, { 25 | test: /\.js$/, 26 | loader: 'babel-loader', 27 | exclude: /node_modules/ 28 | }, { 29 | test: /\.(png|jpg|gif|svg)$/, 30 | loader: 'file-loader', 31 | options: { 32 | name: '[name].[ext]?[hash]' 33 | } 34 | }] 35 | }, 36 | build: { 37 | env: require('./prod.env'), 38 | index: path.resolve(__dirname, '../dist/index.html'), 39 | assetsRoot: path.resolve(__dirname, '../dist'), 40 | assetsSubDirectory: 'static', 41 | assetsPublicPath: '/', 42 | productionSourceMap: true, 43 | // Gzip off by default as many popular static hosts such as 44 | // Surge or Netlify already gzip all static assets for you. 45 | // Before setting to `true`, make sure to: 46 | // npm install --save-dev compression-webpack-plugin 47 | productionGzip: false, 48 | productionGzipExtensions: ['js', 'css'], 49 | // Run the build command with an extra argument to 50 | // View the bundle analyzer report after build finishes: 51 | // `npm run build --report` 52 | // Set to `true` or `false` to always turn it on or off 53 | bundleAnalyzerReport: process.env.npm_config_report 54 | }, 55 | dev: { 56 | env: require('./dev.env'), 57 | port: 8080, 58 | autoOpenBrowser: true, 59 | assetsSubDirectory: 'static', 60 | assetsPublicPath: '/', 61 | // 本地开发环境接口代理,将localhost:8080/api 映射到 localhost:3000 62 | proxyTable: { 63 | '/api': { 64 | target: 'http://localhost:3000', 65 | changeOrigin: true, 66 | pathRewrite: { 67 | '^/api': '' 68 | } 69 | } 70 | }, 71 | // CSS Sourcemaps off by default because relative paths are "buggy" 72 | // with this option, according to the CSS-Loader README 73 | // (https://github.com/webpack/css-loader#sourcemaps) 74 | // In our experience, they generally work as expected, 75 | // just be aware of this issue when enabling this option. 76 | cssSourceMap: false 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/components/Config.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 54 | 55 | 56 | 105 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import storage from '../utils/storage' 4 | import Util from '../utils/common' 5 | Vue.use(Vuex); 6 | 7 | const store = new Vuex.Store({ 8 | state: { 9 | // 当前路由名称 10 | activeRoute: 'ImageFinder', 11 | // Emoji折叠展开状态 12 | isEmoji: false, 13 | // snackbar 状态 14 | snackbar: false, 15 | // snackbar文字 16 | snackMsg: '', 17 | // 注册用户名 18 | registUsername: '', 19 | // 注册密码 20 | registPassword: '', 21 | // 当前用户 22 | username: storage.get('loginInfo') && storage.get('loginInfo').username || '', 23 | // token 24 | token: storage.get('token') || '', 25 | // post封面 26 | poster: '', 27 | // 浮层是否显示 28 | isImagePop: false, 29 | // 浮层预览主体图片路径 30 | imgview: '', 31 | // 加载spiner显示 32 | isSpiner: false, 33 | // 七牛图片list数量是否变化 34 | isPicListChange: true, 35 | // 七牛API授权 36 | qiniuAuth: Util.getQiniuAuth(), 37 | // 上传文件名前缀 38 | uploadOptions: storage.get("uploadOptions") || null 39 | 40 | }, 41 | getters: { 42 | // 当前所属菜单 43 | activeMenu(state) { 44 | var mapIndex = { 45 | "ImageFinder": '1', 46 | "Upload": '2', 47 | "ImageList": '3', 48 | "Settings": '4', 49 | 'Chatroom': '5', 50 | 'NewPost': '6', 51 | "Me": '7', 52 | } 53 | return mapIndex[state.activeRoute] 54 | } 55 | }, 56 | mutations: { 57 | ACTIVE_ROUTE_CHANGE: function(state, payload) { 58 | state.activeRoute = payload.activeRoute 59 | }, 60 | EMOJI_SHOW_CHANGE: function(state, payload) { 61 | state.isEmoji = payload.isEmoji 62 | }, 63 | SNACK_BAR_CHANGE: function(state, payload) { 64 | state.snackbar = payload.snackbar; 65 | state.snackMsg = payload.snackMsg; 66 | }, 67 | REGIST_USER_INFO_CHANGE: function(state, payload) { 68 | state.registUsername = payload.registUsername; 69 | state.registPassword = payload.registPassword; 70 | }, 71 | USERNAME_CHANGE: function(state, payload) { 72 | state.username = payload.username; 73 | }, 74 | TOKEN_CHANGE: function(state, payload) { 75 | state.token = payload.token; 76 | }, 77 | POSTER_CHANGE: function(state, payload) { 78 | state.poster = payload.poster; 79 | }, 80 | IMAGE_POP_CHANGE: function(state, payload) { 81 | state.isImagePop = payload.isImagePop; 82 | state.imgview = payload.imgview 83 | }, 84 | SPINER_CHANGE: function(state, payload) { 85 | state.isSpiner = payload.isSpiner; 86 | }, 87 | PICLIST_CHANGE: function(state, payload) { 88 | state.isPicListChange = payload.isPicListChange; 89 | }, 90 | QINIU_AUTH_CHANGE: function(state, payload) { 91 | state.qiniuAuth = payload.qiniuAuth; 92 | }, 93 | UPLOAD_OPTIONS_CHANGE: function(state, payload) { 94 | state.uploadOptions = payload.uploadOptions; 95 | }, 96 | } 97 | }) 98 | 99 | export default store -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 82 | 124 | -------------------------------------------------------------------------------- /src/components/SettingsSelf.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 80 | 81 | 90 | -------------------------------------------------------------------------------- /src/components/RegistForm.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 72 | 73 | 74 | 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EN 2 | ## Cow-Bed 3 | A single page application for Qiniu image management which using Vue-cli(base on [museui](http://www.muse-ui.org)), front-end and back-end seperation. The back-end is based on express and Qiniu [nodejs-SDK](https://github.com/qiniu/nodejs-sdk). 4 | (Public zone is invalid) 5 | ![preview](http://qiniu1.huzerui.com/blog/17-10-26/30600390.jpg) 6 | 7 | ## Project Address: 8 | Source address: https://github.com/alex1504/vue-qiniu-image-bed 9 | Online address:http://cowbed.huzerui.com 10 | 11 | ## Function Development 12 | - [x] Private space and public space switching 13 | - [x] Upload with input element, drag file to upload, upload online pictures URL 14 | - [x] Outer chain replication (markdown) 15 | - [x] Picture management, preview, download, batch delete 16 | - [ ] Picture management by date 17 | - [ ] Picture rename 18 | - [ ] Audio and video resource management 19 | 20 | ## Technology Stack 21 | Front-end: 22 | - Vue2:Vue2.0 progressive MVVM framework 23 | - Vuex:Sharing state between different components 24 | - Vue-router:Single page application routing management plug-in 25 | - Axios:Http request tool 26 | - SASS(SCSS):CSS preprocessing language 27 | - Webpack:Automated building tools 28 | - Localstorage:Local storage 29 | 30 | Backend: 31 | - Express:A concise and flexible framework for node.js Web applications 32 | - cors(Middleware):Cross domain resource sharing 33 | - body-parse(Middleware):Parsing the request body 34 | - formidable(Middleware):Node.js module for parsing form data (form-data) 35 | - nodemon:Monitor modify auto restart node service plug-in 36 | 37 | ## Local Preview 38 | ```javascript 39 | git clone https://github.com/alex1504/vue-qiniu-image-bed.git 40 | cd https://github.com/alex1504/vue-qiniu-image-bed.git 41 | // Installation front-end dependency 42 | npm install 43 | cd server 44 | // Installation backend dependency 45 | npm install 46 | cd ../ 47 | npm run dev 48 | // Open another git process 49 | npm run server 50 | ``` 51 | 52 | ## Others 53 | 1. Using **localStorage** to save seven cattle authorization data. 54 | 2. Some resource libraries are introduced by CDN, which is provided by [**bootCDN**] (http://www.bootcdn.cn/). 55 | 3. If you have any questions, feedbacks or suggestions, please submit them to issue. 56 | 4. Welcome to **fork and star**, your support is the driving force for me to move forward. 57 | 58 | # CN 59 | ## 牛牛图床 60 | Vue-cli脚手架构建的七牛图片管理图床单页应用(基于[museui](http://www.muse-ui.org),前后端分离,后端基于express及七牛[nodejs-SDK](https://github.com/qiniu/nodejs-sdk)开发。(公共空间已失效) 61 | ![preview](http://qiniu1.huzerui.com/blog/17-10-26/30600390.jpg) 62 | 63 | ## 项目地址: 64 | 源码地址:https://github.com/alex1504/vue-qiniu-image-bed 65 | 在线地址:http://cowbed.huzerui.com 66 | 67 | ## 功能开发 68 | - [x] 私人空间、公共空间切换 69 | - [x] 控件上传、拖拽本地图片上传、在线图片URL上传 70 | - [x] 外链复制(markdown) 71 | - [x] 图片管理、预览、下载、批量删除 72 | - [ ] 图片分日期管理 73 | - [ ] 图片重命名 74 | - [ ] 音频、视频资源管理 75 | 76 | ## 技术栈 77 | 前端: 78 | - Vue2:Vue2.0渐进式MVVM框架 79 | - Vuex:实现不同组件之间的状态共享 80 | - Vue-router:单页应用路由管理插件 81 | - Axios:Http请求工具 82 | - SASS(SCSS):css预处理语言 83 | - Webpack:自动化构建工具 84 | - Localstorage:本地存储 85 | 86 | 后端: 87 | - Express:简洁而灵活的 node.js Web应用框架 88 | - cors(中间件):跨域资源共享 89 | - body-parse(中间件):对请求体进行解析 90 | - formidable(中间件):解析表单数据(form-data)的Node.js模块 91 | - nodemon:监听修改自动重启node服务插件 92 | 93 | ## 本地预览 94 | ```javascript 95 | git clone https://github.com/alex1504/vue-qiniu-image-bed.git 96 | cd https://github.com/alex1504/vue-qiniu-image-bed.git 97 | // 安装前端依赖 98 | npm install 99 | cd server 100 | // 安装后端依赖 101 | npm install 102 | cd ../ 103 | npm run dev 104 | // 开启另一个git进程 105 | npm run server 106 | ``` 107 | 108 | ## 其他 109 | 1. 项目前端使用**localStorage**保存七牛授权数据 110 | 2. 部分资源库采用CDN方式引入,由[**bootCDN**](http://www.bootcdn.cn/)提供 111 | 3. 若有任何问题、反馈或者建议,请提交issue中。 112 | 4. 若项目对你有所帮助,别忘了**star**一下。 113 | -------------------------------------------------------------------------------- /src/components/Settings.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 120 | 121 | 139 | -------------------------------------------------------------------------------- /server/api/utils/qiniu.js: -------------------------------------------------------------------------------- 1 | var url = require('url'); 2 | var crypto = require('crypto'); 3 | var conf = require('./conf'); 4 | 5 | // Check Timestamp Expired or not 6 | exports.isTimestampExpired = function(timestamp) { 7 | return timestamp < parseInt(Date.now() / 1000); 8 | } 9 | 10 | // Encoded Entry 11 | exports.encodedEntry = function(bucket, key) { 12 | return exports.urlsafeBase64Encode(bucket + (key ? ':' + key : '')); 13 | } 14 | 15 | // Get accessKey from uptoken 16 | exports.getAKFromUptoken = function(uploadToken) { 17 | var sepIndex = uploadToken.indexOf(":"); 18 | return uploadToken.substring(0, sepIndex); 19 | } 20 | 21 | // Get bucket from uptoken 22 | exports.getBucketFromUptoken = function(uploadToken) { 23 | var sepIndex = uploadToken.lastIndexOf(":"); 24 | var encodedPutPolicy = uploadToken.substring(sepIndex + 1); 25 | var putPolicy = exports.urlSafeBase64Decode(encodedPutPolicy); 26 | var putPolicyObj = JSON.parse(putPolicy); 27 | var scope = putPolicyObj.scope; 28 | var scopeSepIndex = scope.indexOf(":"); 29 | if (scopeSepIndex == -1) { 30 | return scope; 31 | } else { 32 | return scope.substring(0, scopeSepIndex); 33 | } 34 | } 35 | 36 | 37 | exports.base64ToUrlSafe = function(v) { 38 | return v.replace(/\//g, '_').replace(/\+/g, '-'); 39 | } 40 | 41 | exports.urlSafeToBase64 = function(v) { 42 | return v.replace(/\_/g, '/').replace(/\-/g, '+'); 43 | } 44 | 45 | // UrlSafe Base64 Decode 46 | exports.urlsafeBase64Encode = function(jsonFlags) { 47 | var encoded = new Buffer(jsonFlags).toString('base64'); 48 | return exports.base64ToUrlSafe(encoded); 49 | } 50 | 51 | // UrlSafe Base64 Decode 52 | exports.urlSafeBase64Decode = function(fromStr) { 53 | return new Buffer(exports.urlSafeToBase64(fromStr), 'base64').toString(); 54 | } 55 | 56 | // Hmac-sha1 Crypt 57 | exports.hmacSha1 = function(encodedFlags, secretKey) { 58 | /* 59 | *return value already encoded with base64 60 | * */ 61 | var hmac = crypto.createHmac('sha1', secretKey); 62 | hmac.update(encodedFlags); 63 | return hmac.digest('base64'); 64 | } 65 | 66 | // 创建 AccessToken 凭证 67 | // @param mac AK&SK对象 68 | // @param requestURI 请求URL 69 | // @param reqBody 请求Body,仅当请求的 ContentType 为 70 | // application/x-www-form-urlencoded时才需要传入该参数 71 | exports.generateAccessToken = function(mac, requestURI, reqBody) { 72 | var u = url.parse(requestURI); 73 | var path = u.path; 74 | var access = path + '\n'; 75 | 76 | if (reqBody) { 77 | access += reqBody; 78 | } 79 | 80 | var digest = exports.hmacSha1(access, mac.secretKey); 81 | var safeDigest = exports.base64ToUrlSafe(digest); 82 | return 'QBox ' + mac.accessKey + ':' + safeDigest; 83 | } 84 | 85 | // 创建 AccessToken 凭证 86 | // @param mac AK&SK对象 87 | // @param requestURI 请求URL 88 | // @param reqMethod 请求方法,例如 GET,POST 89 | // @param reqContentType 请求类型,例如 application/json 或者 application/x-www-form-urlencoded 90 | // @param reqBody 请求Body,仅当请求的 ContentType 为 application/json 或者 91 | // application/x-www-form-urlencoded 时才需要传入该参数 92 | exports.generateAccessTokenV2 = function (mac, requestURI, reqMethod, reqContentType, reqBody) { 93 | var u = url.parse(requestURI); 94 | var path = u.path; 95 | var query = u.query; 96 | var host = u.host; 97 | var port = u.port; 98 | 99 | var access = reqMethod.toUpperCase() + ' ' + path; 100 | if (query) { 101 | access += '?' + query; 102 | } 103 | // add host 104 | access += '\nHost: ' + host; 105 | // add port 106 | if (port) { 107 | access += ':' + port; 108 | } 109 | 110 | // add content type 111 | if (reqContentType && (reqContentType=="application/json" || reqContentType=="application/x-www-form-urlencoded")) { 112 | access += '\nContent-Type: ' + reqContentType; 113 | } 114 | 115 | access += '\n\n'; 116 | 117 | // add reqbody 118 | if (reqBody) { 119 | access += reqBody; 120 | } 121 | 122 | console.log(access); 123 | 124 | var digest = exports.hmacSha1(access, mac.secretKey); 125 | var safeDigest = exports.base64ToUrlSafe(digest); 126 | return 'Qiniu ' + mac.accessKey + ':' + safeDigest; 127 | } 128 | 129 | // 校验七牛上传回调的Authorization 130 | // @param mac AK&SK对象 131 | // @param requestURI 回调的URL中的requestURI 132 | // @param reqBody 请求Body,仅当请求的ContentType为 133 | // application/x-www-form-urlencoded时才需要传入该参数 134 | // @param callbackAuth 回调时请求的Authorization头部值 135 | exports.isQiniuCallback = function(mac, requestURI, reqBody, callbackAuth) { 136 | var auth = exports.generateAccessToken(mac, requestURI, reqBody); 137 | return auth === callbackAuth; 138 | } -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import storage from '../utils/storage' 3 | 4 | if (process.env.NODE_ENV == 'development') { 5 | axios.defaults.baseURL = '/api'; 6 | } else { 7 | axios.defaults.baseURL = 'http://193.112.174.142:3000'; 8 | } 9 | 10 | export default { 11 | uploadFile(auth, files, uploadOptions) { 12 | return new Promise((resolve, reject) => { 13 | const formData = new FormData(); 14 | Array.prototype.forEach.call(files, (file, index) => { 15 | formData.append("file" + index, file, file.name); 16 | }) 17 | for (let key in auth) { 18 | formData.append(key, auth[key]) 19 | } 20 | if (uploadOptions) { 21 | formData.append('isCustom', "1") 22 | formData.append('prefix', uploadOptions.prefix) 23 | } 24 | console.log(formData) 25 | const config = { 26 | headers: { 27 | "Content-Type": "multipart/form-data" 28 | } 29 | }; 30 | axios.post("/upload", formData, config).then(res => { 31 | resolve(res) 32 | }).catch(err => { 33 | reject(err) 34 | }); 35 | }) 36 | }, 37 | uploadFetchUrl(obj) { 38 | return new Promise((resolve, reject) => { 39 | let postData = { 40 | accessKey: obj.accessKey, 41 | secretKey: obj.secretKey, 42 | bucket: obj.bucket, 43 | fetchUrl: obj.fetchUrl 44 | } 45 | if (obj.uploadOptions) { 46 | postData.isCustom = "1" 47 | postData.prefix = obj.uploadOptions.prefix 48 | } 49 | axios.post("/upload/fetch", postData).then(res => { 50 | resolve(res) 51 | }).catch(err => { 52 | reject(err) 53 | }); 54 | }) 55 | }, 56 | getImageList(auth, marker, limit) { 57 | return new Promise((resolve, reject) => { 58 | axios.post("/imageList", { 59 | accessKey: auth.accessKey, 60 | secretKey: auth.secretKey, 61 | bucket: auth.bucket, 62 | marker: marker, 63 | limit: limit 64 | }).then(res => { 65 | resolve(res) 66 | }).catch(err => { 67 | reject(err) 68 | }); 69 | }) 70 | }, 71 | deleteImage(obj) { 72 | return new Promise((resolve, reject) => { 73 | axios.post("/image/delete", { 74 | accessKey: obj.accessKey, 75 | secretKey: obj.secretKey, 76 | bucket: obj.bucket, 77 | fileName: obj.fileName 78 | }).then(res => { 79 | resolve(res) 80 | }).catch(err => { 81 | reject(err) 82 | }); 83 | }) 84 | }, 85 | shareImage(info) { 86 | return new Promise((resolve, reject) => { 87 | var Image = AV.Object.extend('Image'); 88 | var image = new Image(); 89 | image.set('title', info.title); 90 | image.set('keyword', info.keyword); 91 | image.set('type', info.type); 92 | image.set('source', info.source); 93 | image.save().then(function (image) { 94 | resolve(image) 95 | console.log('New object created with objectId: ' + image.id); 96 | }, function (error) { 97 | reject(error) 98 | // 异常处理 99 | console.error('Failed to create new object, with error message: ' + error.message); 100 | }); 101 | }) 102 | }, 103 | searchImage(word) { 104 | return new Promise((resolve, reject) => { 105 | const titleQuery = new AV.Query('Image'); 106 | titleQuery.contains('title', word); 107 | 108 | const keywordQuery = new AV.Query('Image'); 109 | keywordQuery.equalTo('keyword', word); 110 | 111 | const typeQuery = new AV.Query('Image'); 112 | typeQuery.equalTo('type', word); 113 | 114 | const query = AV.Query.or(titleQuery, keywordQuery, typeQuery); 115 | 116 | query.find().then(function (res) { 117 | res = res.map(obj => { 118 | return obj.attributes 119 | }) 120 | resolve(res) 121 | }, function (error) { 122 | console.log(error) 123 | reject(error) 124 | }); 125 | }) 126 | }, 127 | getShareImage() { 128 | return new Promise((resolve, reject) => { 129 | const query = new AV.Query('Image'); 130 | query.find().then(function (res) { 131 | res = res.map(obj => { 132 | return { 133 | ...obj.attributes, 134 | id: obj.id, 135 | createdAt: new Date(obj.createdAt).getTime() 136 | } 137 | }) 138 | resolve(res) 139 | }, function (error) { 140 | console.log(error) 141 | reject(error) 142 | }); 143 | 144 | }) 145 | }, 146 | updateImageCount(id) { 147 | return new Promise((resolve, reject) => { 148 | var image = AV.Object.createWithoutData('Image', id); 149 | image.save().then(function (image) { 150 | image.increment('count', 1); 151 | image.save().then(function (res) { 152 | resolve(res) 153 | }, function (error) { 154 | reject(error) 155 | }); 156 | }) 157 | }); 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/components/PostForm.vue: -------------------------------------------------------------------------------- 1 | 21 | 129 | 154 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 牛牛图床

牛牛图床

AccessKey



SecretKey



Bucket



Domain
19 | http://ory715icu.bkt.clouddn.com 20 |



21 | 请设置七牛配置,可先跳过后续配置 22 |
23 | -------------------------------------------------------------------------------- /src/components/SettingsUpload.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 113 | 114 | 153 | -------------------------------------------------------------------------------- /src/components/ImageFinder.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 133 | 134 | 187 | -------------------------------------------------------------------------------- /src/components/ImagePop.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 184 | 185 | 284 | -------------------------------------------------------------------------------- /server/api/controllers/qiniuController.js: -------------------------------------------------------------------------------- 1 | const qiniu = require('qiniu') 2 | const request = require('superagent') 3 | const formidable = require('formidable') 4 | const util = require('util'); 5 | const qiniuUtil = require('../utils/qiniu') 6 | const bodyParser = require('body-parser') 7 | 8 | function renderUniFileName(type) { 9 | const map = { 10 | "jpg": new RegExp(/jpg|jpeg/), 11 | "png": new RegExp(/png/), 12 | "gif": new RegExp(/gif/) 13 | } 14 | let ext = ""; 15 | if (map.jpg.test(type)) { 16 | ext = ".jpg" 17 | } 18 | if (map.png.test(type)) { 19 | ext = ".png" 20 | } 21 | if (map.gif.test(type)) { 22 | ext = ".gif" 23 | } 24 | const newDate = new Date(Date.now()); 25 | const year = newDate.getFullYear(); 26 | const month = newDate.getMonth() + 1; 27 | const date = newDate.getDate(); 28 | const randomNum = Math.floor(Math.random() * 99999999); 29 | return `${year}-${month}-${date}/${randomNum}${ext}` 30 | } 31 | 32 | /** 33 | * [renderUploadToken Function] 34 | * @param fields: {{object}} 35 | */ 36 | function renderUploadToken(fields) { 37 | const accessKey = fields.accessKey || ''; 38 | const secretKey = fields.secretKey || ''; 39 | const bucket = fields.bucket || ''; 40 | 41 | const mac = new qiniu.auth.digest.Mac(accessKey, secretKey); 42 | 43 | const options = { 44 | scope: bucket, 45 | }; 46 | 47 | const putPolicy = new qiniu.rs.PutPolicy(options); 48 | const uploadToken = putPolicy.uploadToken(mac); 49 | 50 | return uploadToken 51 | 52 | }; 53 | 54 | 55 | /** 56 | * [uploadFile Function] 57 | * @param accessKey: {{string}} 58 | * @param secretKey: {{string}} 59 | * @param bucket:: {{string}} 60 | */ 61 | function uploadFile(req, res) { 62 | const form = new formidable.IncomingForm(); 63 | 64 | const uploadPromises = [] 65 | form.parse(req, function (err, fields, files) { 66 | for (var fileKey in files) { 67 | const file = files[fileKey]; 68 | const fileName = file.name; 69 | const isCustom = fields.isCustom; 70 | const prefix = fields.prefix || ''; 71 | const localFile = file.path; 72 | const config = new qiniu.conf.Config(); 73 | const formUploader = new qiniu.form_up.FormUploader(config); 74 | const putExtra = new qiniu.form_up.PutExtra(); 75 | const uploadToken = renderUploadToken(fields); 76 | 77 | let key = ''; 78 | if (isCustom == '1') { 79 | // 用户自定义前缀 80 | key = prefix + fileName; 81 | } else { 82 | // 默认前缀 83 | key = renderUniFileName(file.type); 84 | } 85 | 86 | const uploadPromise = new Promise((resolve, reject) => { 87 | // 文件上传 88 | formUploader.putFile(uploadToken, key, localFile, putExtra, function (respErr, 89 | respBody, respInfo) { 90 | if (respErr) { 91 | reject(respErr); 92 | return; 93 | } 94 | console.log(respBody) 95 | if (respInfo.statusCode == 200) { 96 | resolve({ 97 | hash: respInfo.data.hash, 98 | key: respInfo.data.key, 99 | code: respInfo.statusCode 100 | }) 101 | } else { 102 | reject(respBody) 103 | console.log(respInfo.statusCode); 104 | } 105 | }); 106 | 107 | }) 108 | uploadPromises.push(uploadPromise) 109 | } 110 | Promise.all(uploadPromises) 111 | .then(resp => { 112 | res.json(resp) 113 | }) 114 | .catch(err => { 115 | res.json({ 116 | code: 614, 117 | msg: err.error 118 | }) 119 | }) 120 | 121 | }); 122 | }; 123 | 124 | 125 | function fetchAndUpload(req, res) { 126 | const accessKey = req.body.accessKey || ''; 127 | const secretKey = req.body.secretKey || ''; 128 | const bucket = req.body.bucket || ''; 129 | const fetchUrl = req.body.fetchUrl || ''; 130 | const isCustom = req.body.isCustom || -1; 131 | const prefix = req.body.prefix || ''; 132 | const matchType = fetchUrl.match(/\.jpg|\.jpeg|\.png|\.gif$/) 133 | 134 | if (!fetchUrl) { 135 | res.json({ 136 | code: 400, 137 | msg: '参数fetchUrl不能为空' 138 | }) 139 | return; 140 | } 141 | 142 | if (!matchType) { 143 | res.json({ 144 | code: 415, 145 | msg: '只支持图片链接' 146 | }) 147 | return; 148 | } 149 | const mac = new qiniu.auth.digest.Mac(accessKey, secretKey); 150 | const config = new qiniu.conf.Config(); 151 | const bucketManager = new qiniu.rs.BucketManager(mac, config); 152 | const fileName = fetchUrl.match(/[^\/\\]+$/) && fetchUrl.match(/[^\/\\]+$/)[0]; 153 | 154 | let key = ''; 155 | if (isCustom == '1') { 156 | // 用户自定义前缀 157 | key = prefix + fileName; 158 | } else { 159 | // 默认前缀 160 | key = renderUniFileName(matchType[0]); 161 | } 162 | 163 | bucketManager.fetch(fetchUrl, bucket, key, function (err, respBody, respInfo) { 164 | if (err) { 165 | console.log(err); 166 | res.json({ 167 | code: 204, 168 | msg: err.error 169 | }) 170 | return; 171 | //throw err; 172 | } else { 173 | if (respInfo.statusCode == 200) { 174 | res.json({ 175 | code: 200, 176 | hash: respBody.hash, 177 | key: respBody.key 178 | }) 179 | } else { 180 | console.log(respInfo) 181 | res.json({ 182 | code: respInfo.status, 183 | error: respBody.error 184 | }) 185 | } 186 | } 187 | }); 188 | } 189 | 190 | /** 191 | * [getImageInfo Function] 192 | * @param accessKey: {{string}} 193 | * @param secretKey: {{string}} 194 | * @param bucket:: {{string}} 195 | * @param fileName: {{string}} 196 | */ 197 | function getImageInfo(req, res) { 198 | const accessKey = req.body.accessKey || ''; 199 | const secretKey = req.body.secretKey || ''; 200 | const bucket = req.body.bucket || ''; 201 | 202 | var mac = new qiniu.auth.digest.Mac(accessKey, secretKey); 203 | var config = new qiniu.conf.Config(); 204 | var bucketManager = new qiniu.rs.BucketManager(mac, config); 205 | 206 | 207 | var key = req.body.fileName || ''; 208 | bucketManager.stat(bucket, key, function (err, respBody, respInfo) { 209 | if (err) { 210 | console.log(err); 211 | throw err; 212 | } else { 213 | if (respInfo.statusCode == 200) { 214 | res.json(respBody) 215 | console.log(respBody.hash); 216 | console.log(respBody.fsize); 217 | console.log(respBody.mimeType); 218 | console.log(respBody.putTime); 219 | console.log(respBody.type); 220 | } else { 221 | res.json({ 222 | code: respInfo.statusCode, 223 | error: respBody.error 224 | }) 225 | console.log(respInfo.statusCode); 226 | console.log(respBody.error); 227 | } 228 | } 229 | }); 230 | } 231 | 232 | /** 233 | * [getImageList Function] 234 | * @param accessKey: {{string}} 235 | * @param secretKey: {{string}} 236 | * @param bucket:: {{string}} 237 | */ 238 | function getImageList(req, res) { 239 | const accessKey = req.body.accessKey || '' 240 | const secretKey = req.body.secretKey || '' 241 | const bucket = req.body.bucket || '' 242 | const marker = req.body.marker || '' 243 | const limit = req.body.limit || 20 244 | 245 | console.log(accessKey) 246 | var mac = new qiniu.auth.digest.Mac(accessKey, secretKey); 247 | 248 | if (!Object.keys(req.body).length) { 249 | req.body = ""; 250 | } 251 | const accessToken = qiniuUtil.generateAccessToken(mac, "http://rsf.qbox.me/list?bucket=" + bucket + '&limit=' + limit + '&marker=' + marker) 252 | request 253 | .post('http://rsf.qbox.me/list?bucket=' + bucket + '&limit=' + limit + '&marker=' + marker) 254 | .timeout(10000) 255 | .set('Host', 'rsf.qbox.me') 256 | .set('Content-Type', 'application/x-www-form-urlencoded') 257 | .set('Authorization', accessToken) 258 | .end((err, resp) => { 259 | if (err) { 260 | console.log(err); 261 | res.json({ 262 | code: 204, 263 | msg: '请求七牛资源失败,请重试' 264 | }) 265 | return; 266 | } 267 | if (resp.status == 200) { 268 | let data = resp.text.replace(/\\/, ""); 269 | data = JSON.parse(data) 270 | data.items.sort((obj1, obj2) => { 271 | return obj2.putTime - obj1.putTime; 272 | }); 273 | res.json({ 274 | code: 200, 275 | data: data 276 | }) 277 | } else { 278 | res.json({ 279 | code: resp.status, 280 | msg: JSON.parse(resp.text).error 281 | }) 282 | } 283 | }); 284 | } 285 | 286 | 287 | /** 288 | * [deleteImage Function] 289 | * @param accessKey: {{string}} 290 | * @param secretKey: {{string}} 291 | * @param bucket: {{string}} 292 | * @param fileName: {{string}} 293 | */ 294 | function deleteImage(req, res) { 295 | const accessKey = req.body.accessKey || ''; 296 | const secretKey = req.body.secretKey || ''; 297 | const bucket = req.body.bucket || ''; 298 | const fileName = req.body.fileName || ''; 299 | 300 | var mac = new qiniu.auth.digest.Mac(accessKey, secretKey); 301 | if (!Object.keys(req.body).length) { 302 | req.body = ""; 303 | } 304 | 305 | const encodeEntry = qiniuUtil.encodedEntry(bucket, fileName); 306 | const accessToken = qiniuUtil.generateAccessToken(mac, "http://rs.qiniu.com/delete/" + encodeEntry) 307 | 308 | request 309 | .post("http://rs.qiniu.com/delete/" + encodeEntry) 310 | .set('Host', 'rs.qiniu.com') 311 | .set('Content-Type', 'application/x-www-form-urlencoded') 312 | .set('Authorization', accessToken) 313 | .end((err, resp) => { 314 | if (resp.status == 200) { 315 | res.json({ 316 | code: 200, 317 | msg: "删除成功" 318 | }) 319 | } else { 320 | res.json({ 321 | code: resp.status, 322 | msg: JSON.parse(resp.text).error 323 | }) 324 | } 325 | }); 326 | } 327 | 328 | 329 | module.exports = { 330 | renderUploadToken, 331 | uploadFile, 332 | getImageInfo, 333 | getImageList, 334 | deleteImage, 335 | fetchAndUpload 336 | } 337 | -------------------------------------------------------------------------------- /src/components/RegistUserInfoForm.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 200 | 201 | 202 | 304 | -------------------------------------------------------------------------------- /src/components/Fileupload.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 275 | 276 | 396 | -------------------------------------------------------------------------------- /dist/static/js/manifest.f01cb571378191d65270.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///static/js/manifest.f01cb571378191d65270.js","webpack:///webpack/bootstrap c73f32de0c106f32dab3"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","parentJsonpFunction","window","chunkIds","moreModules","executeModules","chunkId","result","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","shift","s","2","e","onScriptComplete","script","onerror","onload","clearTimeout","timeout","chunk","Error","undefined","installedChunkData","Promise","resolve","promise","reject","head","document","getElementsByTagName","createElement","type","charset","async","nc","setAttribute","src","p","0","1","setTimeout","appendChild","m","c","value","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","oe","err","console","error"],"mappings":"CAAS,SAAUA,GCuCnB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAI,EAAAJ,EACAK,GAAA,EACAH,WAUA,OANAJ,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,GAGAI,EAAAE,GAAA,EAGAF,EAAAD,QA1DA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,GAAAX,GAAAY,EAAAC,EAAAT,EAAA,EAAAU,KACQV,EAAAK,EAAAM,OAAoBX,IAC5BQ,EAAAH,EAAAL,GACAY,EAAAJ,IACAE,EAAAG,KAAAD,EAAAJ,GAAA,IAEAI,EAAAJ,GAAA,CAEA,KAAAZ,IAAAU,GACAQ,OAAAC,UAAAC,eAAAd,KAAAI,EAAAV,KACAF,EAAAE,GAAAU,EAAAV,GAIA,KADAO,KAAAE,EAAAC,EAAAC,GACAG,EAAAC,QACAD,EAAAO,SAEA,IAAAV,EACA,IAAAP,EAAA,EAAYA,EAAAO,EAAAI,OAA2BX,IACvCS,EAAAd,IAAAuB,EAAAX,EAAAP,GAGA,OAAAS,GAIA,IAAAZ,MAGAe,GACAO,EAAA,EA6BAxB,GAAAyB,EAAA,SAAAZ,GA+BA,QAAAa,KAEAC,EAAAC,QAAAD,EAAAE,OAAA,KACAC,aAAAC,EACA,IAAAC,GAAAf,EAAAJ,EACA,KAAAmB,IACAA,GACAA,EAAA,MAAAC,OAAA,iBAAApB,EAAA,aAEAI,EAAAJ,OAAAqB,IAvCA,GAAAC,GAAAlB,EAAAJ,EACA,QAAAsB,EACA,UAAAC,SAAA,SAAAC,GAA0CA,KAI1C,IAAAF,EACA,MAAAA,GAAA,EAIA,IAAAG,GAAA,GAAAF,SAAA,SAAAC,EAAAE,GACAJ,EAAAlB,EAAAJ,IAAAwB,EAAAE,IAEAJ,GAAA,GAAAG,CAGA,IAAAE,GAAAC,SAAAC,qBAAA,WACAf,EAAAc,SAAAE,cAAA,SACAhB,GAAAiB,KAAA,kBACAjB,EAAAkB,QAAA,QACAlB,EAAAmB,OAAA,EACAnB,EAAAI,QAAA,KAEA/B,EAAA+C,IACApB,EAAAqB,aAAA,QAAAhD,EAAA+C,IAEApB,EAAAsB,IAAAjD,EAAAkD,EAAA,aAAArC,EAAA,KAAwEsC,EAAA,uBAAAC,EAAA,wBAAsDvC,GAAA,KAC9H,IAAAkB,GAAAsB,WAAA3B,EAAA,KAgBA,OAfAC,GAAAC,QAAAD,EAAAE,OAAAH,EAaAc,EAAAc,YAAA3B,GAEAW,GAIAtC,EAAAuD,EAAAxD,EAGAC,EAAAwD,EAAAtD,EAGAF,EAAAK,EAAA,SAAAoD,GAA2C,MAAAA,IAG3CzD,EAAA0D,EAAA,SAAAvD,EAAAwD,EAAAC,GACA5D,EAAA6D,EAAA1D,EAAAwD,IACAxC,OAAA2C,eAAA3D,EAAAwD,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMA5D,EAAAkE,EAAA,SAAA9D,GACA,GAAAwD,GAAAxD,KAAA+D,WACA,WAA2B,MAAA/D,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAJ,GAAA0D,EAAAE,EAAA,IAAAA,GACAA,GAIA5D,EAAA6D,EAAA,SAAAO,EAAAC,GAAsD,MAAAlD,QAAAC,UAAAC,eAAAd,KAAA6D,EAAAC,IAGtDrE,EAAAkD,EAAA,IAGAlD,EAAAsE,GAAA,SAAAC,GAA8D,KAApBC,SAAAC,MAAAF,GAAoBA","file":"static/js/manifest.f01cb571378191d65270.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId]) {\n/******/ \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n/******/ \t\t\t}\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n/******/ \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n/******/ \t\twhile(resolves.length) {\n/******/ \t\t\tresolves.shift()();\n/******/ \t\t}\n/******/ \t\tif(executeModules) {\n/******/ \t\t\tfor(i=0; i < executeModules.length; i++) {\n/******/ \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\treturn result;\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// objects to store loaded and loading chunks\n/******/ \tvar installedChunks = {\n/******/ \t\t2: 0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId) {\n/******/ \t\tvar installedChunkData = installedChunks[chunkId];\n/******/ \t\tif(installedChunkData === 0) {\n/******/ \t\t\treturn new Promise(function(resolve) { resolve(); });\n/******/ \t\t}\n/******/\n/******/ \t\t// a Promise means \"currently loading\".\n/******/ \t\tif(installedChunkData) {\n/******/ \t\t\treturn installedChunkData[2];\n/******/ \t\t}\n/******/\n/******/ \t\t// setup Promise in chunk cache\n/******/ \t\tvar promise = new Promise(function(resolve, reject) {\n/******/ \t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n/******/ \t\t});\n/******/ \t\tinstalledChunkData[2] = promise;\n/******/\n/******/ \t\t// start chunk loading\n/******/ \t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\tvar script = document.createElement('script');\n/******/ \t\tscript.type = 'text/javascript';\n/******/ \t\tscript.charset = 'utf-8';\n/******/ \t\tscript.async = true;\n/******/ \t\tscript.timeout = 120000;\n/******/\n/******/ \t\tif (__webpack_require__.nc) {\n/******/ \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n/******/ \t\t}\n/******/ \t\tscript.src = __webpack_require__.p + \"static/js/\" + chunkId + \".\" + {\"0\":\"f727d4bf6000fac3f5f1\",\"1\":\"55f860a19d7bce3f74ce\"}[chunkId] + \".js\";\n/******/ \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n/******/ \t\tscript.onerror = script.onload = onScriptComplete;\n/******/ \t\tfunction onScriptComplete() {\n/******/ \t\t\t// avoid mem leaks in IE.\n/******/ \t\t\tscript.onerror = script.onload = null;\n/******/ \t\t\tclearTimeout(timeout);\n/******/ \t\t\tvar chunk = installedChunks[chunkId];\n/******/ \t\t\tif(chunk !== 0) {\n/******/ \t\t\t\tif(chunk) {\n/******/ \t\t\t\t\tchunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n/******/ \t\t\t\t}\n/******/ \t\t\t\tinstalledChunks[chunkId] = undefined;\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t\thead.appendChild(script);\n/******/\n/******/ \t\treturn promise;\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// on error function for async loading\n/******/ \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n/******/ })\n/************************************************************************/\n/******/ ([]);\n\n\n// WEBPACK FOOTER //\n// static/js/manifest.f01cb571378191d65270.js"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData === 0) {\n \t\t\treturn new Promise(function(resolve) { resolve(); });\n \t\t}\n\n \t\t// a Promise means \"currently loading\".\n \t\tif(installedChunkData) {\n \t\t\treturn installedChunkData[2];\n \t\t}\n\n \t\t// setup Promise in chunk cache\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunkData[2] = promise;\n\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"static/js/\" + chunkId + \".\" + {\"0\":\"f727d4bf6000fac3f5f1\",\"1\":\"55f860a19d7bce3f74ce\"}[chunkId] + \".js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) {\n \t\t\t\t\tchunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\t}\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n \t\thead.appendChild(script);\n\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap c73f32de0c106f32dab3"],"sourceRoot":""} -------------------------------------------------------------------------------- /src/assets/css/emoji.css: -------------------------------------------------------------------------------- 1 | /* 2 | Icon classes can be used entirely standalone. They are named after their original file names. 3 | 4 | Example usage in HTML: 5 | 6 | `display: block` sprite: 7 |
8 | 9 | To change `display`e.g. `display: inline-block;`), we suggest using a common CSS class: 10 | 11 | // CSS 12 | .icon { 13 | display: inline-block; 14 | } 15 | 16 | // HTML 17 | 18 | */ 19 | 20 | .icon { 21 | display: inline-block; 22 | vertical-align: middle; 23 | width: 20px; 24 | height: 20px; 25 | } 26 | 27 | .icon-1 { 28 | background-image: url(../images/emoji_sprite.png); 29 | background-position: -32px 0px; 30 | width: 32px; 31 | height: 32px; 32 | } 33 | 34 | .icon-10 { 35 | background-image: url(../images/emoji_sprite.png); 36 | background-position: -192px -32px; 37 | width: 32px; 38 | height: 32px; 39 | } 40 | 41 | .icon-11 { 42 | background-image: url(../images/emoji_sprite.png); 43 | background-position: 0px -32px; 44 | width: 32px; 45 | height: 32px; 46 | } 47 | 48 | .icon-12 { 49 | background-image: url(../images/emoji_sprite.png); 50 | background-position: -32px -32px; 51 | width: 32px; 52 | height: 32px; 53 | } 54 | 55 | .icon-13 { 56 | background-image: url(../images/emoji_sprite.png); 57 | background-position: -64px 0px; 58 | width: 32px; 59 | height: 32px; 60 | } 61 | 62 | .icon-14 { 63 | background-image: url(../images/emoji_sprite.png); 64 | background-position: -64px -32px; 65 | width: 32px; 66 | height: 32px; 67 | } 68 | 69 | .icon-15 { 70 | background-image: url(../images/emoji_sprite.png); 71 | background-position: 0px -64px; 72 | width: 32px; 73 | height: 32px; 74 | } 75 | 76 | .icon-16 { 77 | background-image: url(../images/emoji_sprite.png); 78 | background-position: -32px -64px; 79 | width: 32px; 80 | height: 32px; 81 | } 82 | 83 | .icon-17 { 84 | background-image: url(../images/emoji_sprite.png); 85 | background-position: -64px -64px; 86 | width: 32px; 87 | height: 32px; 88 | } 89 | 90 | .icon-18 { 91 | background-image: url(../images/emoji_sprite.png); 92 | background-position: -96px 0px; 93 | width: 32px; 94 | height: 32px; 95 | } 96 | 97 | .icon-19 { 98 | background-image: url(../images/emoji_sprite.png); 99 | background-position: -96px -32px; 100 | width: 32px; 101 | height: 32px; 102 | } 103 | 104 | .icon-2 { 105 | background-image: url(../images/emoji_sprite.png); 106 | background-position: -96px -64px; 107 | width: 32px; 108 | height: 32px; 109 | } 110 | 111 | .icon-20 { 112 | background-image: url(../images/emoji_sprite.png); 113 | background-position: 0px -96px; 114 | width: 32px; 115 | height: 32px; 116 | } 117 | 118 | .icon-21 { 119 | background-image: url(../images/emoji_sprite.png); 120 | background-position: -32px -96px; 121 | width: 32px; 122 | height: 32px; 123 | } 124 | 125 | .icon-22 { 126 | background-image: url(../images/emoji_sprite.png); 127 | background-position: -64px -96px; 128 | width: 32px; 129 | height: 32px; 130 | } 131 | 132 | .icon-23 { 133 | background-image: url(../images/emoji_sprite.png); 134 | background-position: -96px -96px; 135 | width: 32px; 136 | height: 32px; 137 | } 138 | 139 | .icon-24 { 140 | background-image: url(../images/emoji_sprite.png); 141 | background-position: -128px 0px; 142 | width: 32px; 143 | height: 32px; 144 | } 145 | 146 | .icon-25 { 147 | background-image: url(../images/emoji_sprite.png); 148 | background-position: -128px -32px; 149 | width: 32px; 150 | height: 32px; 151 | } 152 | 153 | .icon-26 { 154 | background-image: url(../images/emoji_sprite.png); 155 | background-position: -128px -64px; 156 | width: 32px; 157 | height: 32px; 158 | } 159 | 160 | .icon-27 { 161 | background-image: url(../images/emoji_sprite.png); 162 | background-position: -128px -96px; 163 | width: 32px; 164 | height: 32px; 165 | } 166 | 167 | .icon-28 { 168 | background-image: url(../images/emoji_sprite.png); 169 | background-position: 0px -128px; 170 | width: 32px; 171 | height: 32px; 172 | } 173 | 174 | .icon-29 { 175 | background-image: url(../images/emoji_sprite.png); 176 | background-position: -32px -128px; 177 | width: 32px; 178 | height: 32px; 179 | } 180 | 181 | .icon-3 { 182 | background-image: url(../images/emoji_sprite.png); 183 | background-position: -64px -128px; 184 | width: 32px; 185 | height: 32px; 186 | } 187 | 188 | .icon-30 { 189 | background-image: url(../images/emoji_sprite.png); 190 | background-position: -96px -128px; 191 | width: 32px; 192 | height: 32px; 193 | } 194 | 195 | .icon-31 { 196 | background-image: url(../images/emoji_sprite.png); 197 | background-position: -128px -128px; 198 | width: 32px; 199 | height: 32px; 200 | } 201 | 202 | .icon-32 { 203 | background-image: url(../images/emoji_sprite.png); 204 | background-position: -160px 0px; 205 | width: 32px; 206 | height: 32px; 207 | } 208 | 209 | .icon-33 { 210 | background-image: url(../images/emoji_sprite.png); 211 | background-position: -160px -32px; 212 | width: 32px; 213 | height: 32px; 214 | } 215 | 216 | .icon-34 { 217 | background-image: url(../images/emoji_sprite.png); 218 | background-position: -160px -64px; 219 | width: 32px; 220 | height: 32px; 221 | } 222 | 223 | .icon-35 { 224 | background-image: url(../images/emoji_sprite.png); 225 | background-position: -160px -96px; 226 | width: 32px; 227 | height: 32px; 228 | } 229 | 230 | .icon-36 { 231 | background-image: url(../images/emoji_sprite.png); 232 | background-position: -160px -128px; 233 | width: 32px; 234 | height: 32px; 235 | } 236 | 237 | .icon-37 { 238 | background-image: url(../images/emoji_sprite.png); 239 | background-position: 0px -160px; 240 | width: 32px; 241 | height: 32px; 242 | } 243 | 244 | .icon-38 { 245 | background-image: url(../images/emoji_sprite.png); 246 | background-position: -32px -160px; 247 | width: 32px; 248 | height: 32px; 249 | } 250 | 251 | .icon-39 { 252 | background-image: url(../images/emoji_sprite.png); 253 | background-position: -64px -160px; 254 | width: 32px; 255 | height: 32px; 256 | } 257 | 258 | .icon-4 { 259 | background-image: url(../images/emoji_sprite.png); 260 | background-position: -96px -160px; 261 | width: 32px; 262 | height: 32px; 263 | } 264 | 265 | .icon-40 { 266 | background-image: url(../images/emoji_sprite.png); 267 | background-position: -128px -160px; 268 | width: 32px; 269 | height: 32px; 270 | } 271 | 272 | .icon-41 { 273 | background-image: url(../images/emoji_sprite.png); 274 | background-position: -160px -160px; 275 | width: 32px; 276 | height: 32px; 277 | } 278 | 279 | .icon-42 { 280 | background-image: url(../images/emoji_sprite.png); 281 | background-position: -192px 0px; 282 | width: 32px; 283 | height: 32px; 284 | } 285 | 286 | .icon-43 { 287 | background-image: url(../images/emoji_sprite.png); 288 | background-position: 0px 0px; 289 | width: 32px; 290 | height: 32px; 291 | } 292 | 293 | .icon-44 { 294 | background-image: url(../images/emoji_sprite.png); 295 | background-position: -192px -64px; 296 | width: 32px; 297 | height: 32px; 298 | } 299 | 300 | .icon-45 { 301 | background-image: url(../images/emoji_sprite.png); 302 | background-position: -192px -96px; 303 | width: 32px; 304 | height: 32px; 305 | } 306 | 307 | .icon-46 { 308 | background-image: url(../images/emoji_sprite.png); 309 | background-position: -192px -128px; 310 | width: 32px; 311 | height: 32px; 312 | } 313 | 314 | .icon-47 { 315 | background-image: url(../images/emoji_sprite.png); 316 | background-position: -192px -160px; 317 | width: 32px; 318 | height: 32px; 319 | } 320 | 321 | .icon-48 { 322 | background-image: url(../images/emoji_sprite.png); 323 | background-position: 0px -192px; 324 | width: 32px; 325 | height: 32px; 326 | } 327 | 328 | .icon-49 { 329 | background-image: url(../images/emoji_sprite.png); 330 | background-position: -32px -192px; 331 | width: 32px; 332 | height: 32px; 333 | } 334 | 335 | .icon-5 { 336 | background-image: url(../images/emoji_sprite.png); 337 | background-position: -64px -192px; 338 | width: 32px; 339 | height: 32px; 340 | } 341 | 342 | .icon-50 { 343 | background-image: url(../images/emoji_sprite.png); 344 | background-position: -96px -192px; 345 | width: 32px; 346 | height: 32px; 347 | } 348 | 349 | .icon-51 { 350 | background-image: url(../images/emoji_sprite.png); 351 | background-position: -128px -192px; 352 | width: 32px; 353 | height: 32px; 354 | } 355 | 356 | .icon-52 { 357 | background-image: url(../images/emoji_sprite.png); 358 | background-position: -160px -192px; 359 | width: 32px; 360 | height: 32px; 361 | } 362 | 363 | .icon-53 { 364 | background-image: url(../images/emoji_sprite.png); 365 | background-position: -192px -192px; 366 | width: 32px; 367 | height: 32px; 368 | } 369 | 370 | .icon-54 { 371 | background-image: url(../images/emoji_sprite.png); 372 | background-position: -224px 0px; 373 | width: 32px; 374 | height: 32px; 375 | } 376 | 377 | .icon-55 { 378 | background-image: url(../images/emoji_sprite.png); 379 | background-position: -224px -32px; 380 | width: 32px; 381 | height: 32px; 382 | } 383 | 384 | .icon-56 { 385 | background-image: url(../images/emoji_sprite.png); 386 | background-position: -224px -64px; 387 | width: 32px; 388 | height: 32px; 389 | } 390 | 391 | .icon-57 { 392 | background-image: url(../images/emoji_sprite.png); 393 | background-position: -224px -96px; 394 | width: 32px; 395 | height: 32px; 396 | } 397 | 398 | .icon-58 { 399 | background-image: url(../images/emoji_sprite.png); 400 | background-position: -224px -128px; 401 | width: 32px; 402 | height: 32px; 403 | } 404 | 405 | .icon-59 { 406 | background-image: url(../images/emoji_sprite.png); 407 | background-position: -224px -160px; 408 | width: 32px; 409 | height: 32px; 410 | } 411 | 412 | .icon-6 { 413 | background-image: url(../images/emoji_sprite.png); 414 | background-position: -224px -192px; 415 | width: 32px; 416 | height: 32px; 417 | } 418 | 419 | .icon-60 { 420 | background-image: url(../images/emoji_sprite.png); 421 | background-position: 0px -224px; 422 | width: 32px; 423 | height: 32px; 424 | } 425 | 426 | .icon-61 { 427 | background-image: url(../images/emoji_sprite.png); 428 | background-position: -32px -224px; 429 | width: 32px; 430 | height: 32px; 431 | } 432 | 433 | .icon-62 { 434 | background-image: url(../images/emoji_sprite.png); 435 | background-position: -64px -224px; 436 | width: 32px; 437 | height: 32px; 438 | } 439 | 440 | .icon-63 { 441 | background-image: url(../images/emoji_sprite.png); 442 | background-position: -96px -224px; 443 | width: 32px; 444 | height: 32px; 445 | } 446 | 447 | .icon-64 { 448 | background-image: url(../images/emoji_sprite.png); 449 | background-position: -128px -224px; 450 | width: 32px; 451 | height: 32px; 452 | } 453 | 454 | .icon-65 { 455 | background-image: url(../images/emoji_sprite.png); 456 | background-position: -160px -224px; 457 | width: 32px; 458 | height: 32px; 459 | } 460 | 461 | .icon-66 { 462 | background-image: url(../images/emoji_sprite.png); 463 | background-position: -192px -224px; 464 | width: 32px; 465 | height: 32px; 466 | } 467 | 468 | .icon-67 { 469 | background-image: url(../images/emoji_sprite.png); 470 | background-position: -224px -224px; 471 | width: 32px; 472 | height: 32px; 473 | } 474 | 475 | .icon-68 { 476 | background-image: url(../images/emoji_sprite.png); 477 | background-position: -256px 0px; 478 | width: 32px; 479 | height: 32px; 480 | } 481 | 482 | .icon-69 { 483 | background-image: url(../images/emoji_sprite.png); 484 | background-position: -256px -32px; 485 | width: 32px; 486 | height: 32px; 487 | } 488 | 489 | .icon-7 { 490 | background-image: url(../images/emoji_sprite.png); 491 | background-position: -256px -64px; 492 | width: 32px; 493 | height: 32px; 494 | } 495 | 496 | .icon-70 { 497 | background-image: url(../images/emoji_sprite.png); 498 | background-position: -256px -96px; 499 | width: 32px; 500 | height: 32px; 501 | } 502 | 503 | .icon-71 { 504 | background-image: url(../images/emoji_sprite.png); 505 | background-position: -256px -128px; 506 | width: 32px; 507 | height: 32px; 508 | } 509 | 510 | .icon-72 { 511 | background-image: url(../images/emoji_sprite.png); 512 | background-position: -256px -160px; 513 | width: 32px; 514 | height: 32px; 515 | } 516 | 517 | .icon-73 { 518 | background-image: url(../images/emoji_sprite.png); 519 | background-position: -256px -192px; 520 | width: 32px; 521 | height: 32px; 522 | } 523 | 524 | .icon-74 { 525 | background-image: url(../images/emoji_sprite.png); 526 | background-position: -256px -224px; 527 | width: 32px; 528 | height: 32px; 529 | } 530 | 531 | .icon-8 { 532 | background-image: url(../images/emoji_sprite.png); 533 | background-position: 0px -256px; 534 | width: 32px; 535 | height: 32px; 536 | } 537 | 538 | .icon-9 { 539 | background-image: url(../images/emoji_sprite.png); 540 | background-position: -32px -256px; 541 | width: 32px; 542 | height: 32px; 543 | } -------------------------------------------------------------------------------- /src/components/Chatroom.vue: -------------------------------------------------------------------------------- 1 | 81 | 82 | 218 | 650 | --------------------------------------------------------------------------------