vue+vuex+vue-router+socket.io+koa2+mongodb+pm2自動化部署+圖靈機器人+[npm script打包,cdn同步,服務器上傳一個命令全搞定]javascript
登錄註冊css
獲取聊天記錄(包含前端分頁優化)前端
發送文字,表情,文件消息vue
建立羣組,添加羣組,羣組搜索java
修改我的信息,羣組信息git
圖片裁剪壓縮上傳github
私聊vue-router
圖靈機器人接入mongodb
定時任務爬取電影和btc等數字貨幣的價格並使用socket.io實時推送給全部客戶端vuex
前端一鍵打包同步到七牛cdn並上傳到服務器的實現
server端的pm2自動部署
後端的代碼暫時不開放出來,由於涉及到不少我的的配置數據,若是實在須要能夠加微信 MSC199312 (須要付費0.0!),畢竟這個小項目斷斷續續也作了幾個星期,也還花了些心思,並且涉及的知識點也都仍是很廣很實用的,還望理解,其實主要緣由仍是窮[淚奔]
客戶端 main.js
import Vue from 'vue' import App from './App' import router from './router' import VueLazyload from 'vue-lazyload' import store from '@/store' import io from 'socket.io-client' import '@/assets/js/remChange' import '@/assets/js/request' // import { wxConfig, updateShare } from '@/assets/js/wxenv' import '@/assets/css/common.scss' import 'swiper/dist/css/swiper.min.css' import config from '@/assets/js/config' import filters from '@/assets/js/filters' import { openToast } from '@/assets/js/tools' Vue.config.productionTip = false // 初始化全局過濾器 Object.keys(filters).forEach(item => { Vue.filter(item, filters[item]) }) // 懶加載 Vue.use(VueLazyload, { attempt: 1, // preLoad: 1.3, error: require('./assets/images/404.png'), loading: require('./assets/images/loading-img2.gif'), // the default is ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend'] listenEvents: [ 'scroll' ] }) Vue.prototype.$config = config router.beforeEach((to, from, next) => { // 若是未匹配到路由 if (to.matched.length === 0) { // 若是上級也未匹配到路由則跳轉登陸頁面,若是上級能匹配到則轉上級路由 from.name ? next({ name: from.name }) : next('/') } else { // 路由切換時改變頁面標題 document.querySelector('title').innerHTML = to.name // 統計代碼 if (to.path) _czc.push(['_trackPageview', '/#' + to.fullPath], '') next() } }) // 路由變化從新配置微信分享 router.afterEach(to => { // wxConfig(() => updateShare()) }) // socket.io 初始化 const socket = io.connect(config.socketBase) Vue.prototype.$socket = socket Vue.prototype.$socketEmiter = (name, data) => { store.commit('isLoading', true) return new Promise((resolve) => { socket.emit(name, data, res => { console.log(`${name}>>>`, res) store.commit('isLoading', false) if (res.status === 1) { resolve(res.data) } else { openToast({ msg: res.message, duration: 1500 }) } }) }) } /* eslint-disable no-new */ const app = new Vue({ el: '#app', router, store, template: '<App/>', components: { App } })
server端 app.js
const Koa = require('koa') const { resolve } = require('path') const glob = require('glob') const { connectDatabase, initAllSchema, initDefaultUser } = require('./database/init') const config = require('./config') const useMiddlewares = app => { glob.sync(resolve(__dirname, './middlewares', '**/*.js')).forEach(item => { require(item)(app) }) } (async () => { console.log('數據庫初始化...') await connectDatabase() initAllSchema() await initDefaultUser() const app = new Koa() console.log('掛載socket.io...') const server = require('http').Server(app.callback()) const io = require('socket.io').listen(server) require('./socket')(io) // 暴露出io可在其餘地方作推送功能 module.exports.io = io console.log('掛載中間件...') useMiddlewares(app) console.log('初始化定時任務...') // 多了進行一下封裝? require('./tools/crawlMovie') require('./tools/crawlCoin') server.listen(config.server.PORT, () => { console.log('正在監聽' + config.server.PORT + '端口...') }) })()