From a71741e0a8b64dd7108e99cd6a62cc0f0cd9c57e Mon Sep 17 00:00:00 2001 From: szdot Date: Wed, 20 Sep 2023 21:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 17 + src/App.vue | 16 + src/components/Breadcrumb.vue | 75 +++ src/components/ControllerTabs.vue | 530 ++++++++++++++++++ src/components/MapBox.vue | 467 +++++++++++++++ src/components/PlaneStatus.vue | 78 +++ src/components/QuestTabs.vue | 205 +++++++ src/components/Selection.vue | 43 ++ src/components/Tag/HeartTag.vue | 89 +++ src/components/Tag/PublicTag.vue | 73 +++ src/main.js | 25 + src/permission.js | 56 ++ src/router/index.js | 167 ++++++ src/settings.js | 30 + src/store/index.js | 410 ++++++++++++++ src/store/modules/app.js | 63 +++ src/store/modules/settings.js | 38 ++ src/store/modules/user.js | 42 ++ src/styles/element-ui.scss | 67 +++ src/styles/index.scss | 302 ++++++++++ src/styles/myIcon.scss | 1 + src/styles/theme.scss | 41 ++ src/styles/transition.scss | 48 ++ src/utils/api/index.js | 68 +++ src/utils/api/table.js | 38 ++ src/utils/api/user.js | 24 + src/utils/index.js | 131 +++++ src/utils/mqtt/index.js | 89 +++ src/views/404.vue | 254 +++++++++ src/views/layout/components/BlogBox.vue | 87 +++ src/views/layout/components/headbar.vue | 254 +++++++++ .../layout/components/main/home/index.vue | 83 +++ .../layout/components/main/planes/index.vue | 142 +++++ .../layout/components/main/register/add.vue | 156 ++++++ .../main/register/crosFrequency.vue | 112 ++++ .../layout/components/main/register/index.vue | 144 +++++ .../layout/components/main/route/add.vue | 228 ++++++++ .../layout/components/main/route/index.vue | 127 +++++ src/views/layout/components/main/site/add.vue | 260 +++++++++ .../layout/components/main/site/index.vue | 143 +++++ src/views/layout/components/menubar.vue | 204 +++++++ src/views/layout/index.vue | 162 ++++++ src/views/login.vue | 188 +++++++ 43 files changed, 5777 insertions(+) create mode 100644 public/index.html create mode 100644 src/App.vue create mode 100644 src/components/Breadcrumb.vue create mode 100644 src/components/ControllerTabs.vue create mode 100644 src/components/MapBox.vue create mode 100644 src/components/PlaneStatus.vue create mode 100644 src/components/QuestTabs.vue create mode 100644 src/components/Selection.vue create mode 100644 src/components/Tag/HeartTag.vue create mode 100644 src/components/Tag/PublicTag.vue create mode 100644 src/main.js create mode 100644 src/permission.js create mode 100644 src/router/index.js create mode 100644 src/settings.js create mode 100644 src/store/index.js create mode 100644 src/store/modules/app.js create mode 100644 src/store/modules/settings.js create mode 100644 src/store/modules/user.js create mode 100644 src/styles/element-ui.scss create mode 100644 src/styles/index.scss create mode 100644 src/styles/myIcon.scss create mode 100644 src/styles/theme.scss create mode 100644 src/styles/transition.scss create mode 100644 src/utils/api/index.js create mode 100644 src/utils/api/table.js create mode 100644 src/utils/api/user.js create mode 100644 src/utils/index.js create mode 100644 src/utils/mqtt/index.js create mode 100644 src/views/404.vue create mode 100644 src/views/layout/components/BlogBox.vue create mode 100644 src/views/layout/components/headbar.vue create mode 100644 src/views/layout/components/main/home/index.vue create mode 100644 src/views/layout/components/main/planes/index.vue create mode 100644 src/views/layout/components/main/register/add.vue create mode 100644 src/views/layout/components/main/register/crosFrequency.vue create mode 100644 src/views/layout/components/main/register/index.vue create mode 100644 src/views/layout/components/main/route/add.vue create mode 100644 src/views/layout/components/main/route/index.vue create mode 100644 src/views/layout/components/main/site/add.vue create mode 100644 src/views/layout/components/main/site/index.vue create mode 100644 src/views/layout/components/menubar.vue create mode 100644 src/views/layout/index.vue create mode 100644 src/views/login.vue diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..4123528 --- /dev/null +++ b/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + <%= htmlWebpackPlugin.options.title %> + + + +
+ + + diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..7d1d7e7 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,16 @@ + + + + diff --git a/src/components/Breadcrumb.vue b/src/components/Breadcrumb.vue new file mode 100644 index 0000000..dd8e209 --- /dev/null +++ b/src/components/Breadcrumb.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/components/ControllerTabs.vue b/src/components/ControllerTabs.vue new file mode 100644 index 0000000..aadd6a8 --- /dev/null +++ b/src/components/ControllerTabs.vue @@ -0,0 +1,530 @@ + + + + + diff --git a/src/components/MapBox.vue b/src/components/MapBox.vue new file mode 100644 index 0000000..9edaa8f --- /dev/null +++ b/src/components/MapBox.vue @@ -0,0 +1,467 @@ + + + + + diff --git a/src/components/PlaneStatus.vue b/src/components/PlaneStatus.vue new file mode 100644 index 0000000..6306aab --- /dev/null +++ b/src/components/PlaneStatus.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/src/components/QuestTabs.vue b/src/components/QuestTabs.vue new file mode 100644 index 0000000..4de0400 --- /dev/null +++ b/src/components/QuestTabs.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/src/components/Selection.vue b/src/components/Selection.vue new file mode 100644 index 0000000..ed04b4d --- /dev/null +++ b/src/components/Selection.vue @@ -0,0 +1,43 @@ + + + diff --git a/src/components/Tag/HeartTag.vue b/src/components/Tag/HeartTag.vue new file mode 100644 index 0000000..152ad88 --- /dev/null +++ b/src/components/Tag/HeartTag.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/src/components/Tag/PublicTag.vue b/src/components/Tag/PublicTag.vue new file mode 100644 index 0000000..17efc7d --- /dev/null +++ b/src/components/Tag/PublicTag.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..41198f1 --- /dev/null +++ b/src/main.js @@ -0,0 +1,25 @@ +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import store from './store' +import '@/permission' // 路由守卫 +import 'normalize.css/normalize.css'// A modern alternative to CSS resets +import '@/styles/index.scss'// 全局 css +import '@/styles/myIcon.scss'// 阿里巴巴图标 +import 'mapbox-gl/dist/mapbox-gl.css' + +// ElementUI +import ElementUI from 'element-ui' +import 'element-ui/lib/theme-chalk/index.css' +import 'element-ui/lib/theme-chalk/base.css'// fade/zoom 等 +import locale from 'element-ui/lib/locale/lang/zh-CN' // 引入中文语言包 +Vue.use(ElementUI, { locale }) + +// 设置vue创建时 提示信息 false不提示 +Vue.config.productionTip = false + +new Vue({ + router, + store, + render: h => h(App) +}).$mount('#app') diff --git a/src/permission.js b/src/permission.js new file mode 100644 index 0000000..73b229f --- /dev/null +++ b/src/permission.js @@ -0,0 +1,56 @@ +import router from './router' +import store from './store' +import NProgress from 'nprogress' // 进度条 +import 'nprogress/nprogress.css' // 进度条 style + +NProgress.configure({ showSpinner: false }) // 进度条 Configuration + +/** + * @description: 路由守卫 + */ +router.beforeEach((to, from, next) => { + // start 进度条 + NProgress.start() + // 设置title + document.title = getPageTitle(to.meta.title) + // 路由 + store.commit('user/initUser')// 用户信息初始化 PS:token不存在 执行且执行一次 + const token = store.state.user.token + if (token === null) { + if (to.path === '/login') { + next() + NProgress.done() + } else { + next('/login') + NProgress.done() + } + } else { + if (to.path === '/login') { + next('/') + NProgress.done() + } else { + next() + NProgress.done() + } + } +}) + +/** + * @description: 路由完成 结束进度条 + */ +router.afterEach(() => { + NProgress.done() // 结束进度条 +}) + +/** + * @description: mateTile 和 全局title 组合 + * @return: title + * @param {*} pageTitle 路由mate.tiele + */ +function getPageTitle (pageTitle) { + if (pageTitle) { + return `${pageTitle} - ${store.state.settings.title}` + } else { + return store.state.settings.title + } +} diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..2470f8d --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,167 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' +import Login from '@/views/login' +import Page404 from '@/views/404' +import Layout from '@/views/layout/index' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/login', + name: 'Login', + component: Login, + meta: { title: '登录' }, + roles: ['admin', 'editor'], + hidden: true + }, + { + path: '/404', + name: 'Page404', + component: Page404, + meta: { title: '404' }, + roles: ['admin', 'editor'], + hidden: true + }, + { + path: '/', + redirect: '/home/index', + hidden: true + }, + { + path: '/home', + component: Layout, + meta: { title: '概况', icon: 'iconfont icon-fuwudiqiu' }, + redirect: '/home/index', + roles: ['admin', 'editor'], + children: [ + { + path: '/home/index', + name: 'Home', + component: () => import('@/views/layout/components/main/home/index'), + meta: { title: '全图概况', icon: 'iconfont icon-fuwudiqiu' }, + roles: ['admin', 'editor'] + } + ] + }, + { + path: '/register', + component: Layout, + redirect: '/register/index', + meta: { title: '飞机管理', icon: 'el-icon-edit-outline' }, + roles: ['admin', 'editor'], + children: [ + { + path: '/register/index', + component: () => import('@/views/layout/components/main/register/index'), + meta: { title: '飞机列表', icon: 'el-icon-tickets' }, + roles: ['admin', 'editor'] + }, + { + path: '/register/add/', + component: () => import('@/views/layout/components/main/register/add'), + meta: { title: '添加飞机', icon: 'el-icon-plus' }, + roles: ['admin', 'editor'] + }, + { + path: '/register/edit/:id', + component: () => import('@/views/layout/components/main/register/add'), + meta: { title: '更新飞机', icon: 'el-icon-edit' }, + roles: ['admin', 'editor'], + hidden: true + }, + { + path: '/register/crosFrequency', + component: () => import('@/views/layout/components/main/register/crosFrequency'), + meta: { title: '飞机对频', icon: 'el-icon-link' }, + roles: ['admin', 'editor'] + } + ] + }, + { + path: '/route', + component: Layout, + redirect: '/route/index', + meta: { title: '航线管理', icon: 'iconfont icon-feihangluxian' }, + roles: ['admin', 'editor'], + children: [ + { + path: '/route/index', + component: () => import('@/views/layout/components/main/route/index'), + meta: { title: '航线列表', icon: 'iconfont icon-a-05-1-1jihuazhihanggenzong' }, + roles: ['admin', 'editor'] + }, + { + path: '/route/add/', + component: () => import('@/views/layout/components/main/route/add'), + meta: { title: '设计航线', icon: 'iconfont icon-huizhi' }, + roles: ['admin', 'editor'] + }, + { + path: '/route/edit/:id', + component: () => import('@/views/layout/components/main/route/add'), + meta: { title: '编辑航线', icon: 'iconfont icon-huizhi' }, + roles: ['admin', 'editor'], + hidden: true + } + ] + }, + { + path: '/site', + component: Layout, + redirect: '/site/index', + meta: { title: '站点管理', icon: 'iconfont icon-zhandianguanli' }, + roles: ['admin', 'editor'], + children: [ + { + path: '/site/index', + component: () => import('@/views/layout/components/main/site/index'), + meta: { title: '站点列表', icon: 'el-icon-tickets' }, + roles: ['admin', 'editor'] + }, + { + path: '/site/add/', + component: () => import('@/views/layout/components/main/site/add'), + meta: { title: '添加站点', icon: 'el-icon-plus' }, + roles: ['admin', 'editor'] + }, + { + path: '/site/edit/:id', + component: () => import('@/views/layout/components/main/site/add'), + meta: { title: '更新站点', icon: 'el-icon-edit' }, + roles: ['admin', 'editor'], + hidden: true + } + ] + }, + { + path: '/planes', + component: Layout, + redirect: '/planes/index', + meta: { title: '无人机', icon: 'iconfont icon-wurenji' }, + roles: ['admin', 'editor'], + children: [ + { + path: '/planes/index/:id/:name', // 动态加载路由时加ID参数 + name: 'Planes', + component: () => import('@/views/layout/components/main/planes/index'), + meta: { title: '飞机加载中', icon: 'el-icon-loading' }, + roles: ['admin', 'editor'] + } + ] + }, + { + path: '*', + redirect: '/404', + roles: ['admin', 'editor'], + hidden: true + } +] + +const router = new VueRouter({ + mode: 'history', + base: process.env.BASE_URL, + routes +}) + +export default router diff --git a/src/settings.js b/src/settings.js new file mode 100644 index 0000000..872ff5f --- /dev/null +++ b/src/settings.js @@ -0,0 +1,30 @@ +module.exports = { + + /** + * @description: 全局title + */ + title: '送餐系统', + + /** + * @description: api服务器 + * host 主站 + * api接口地址 + * api常规接口路径 + * api登录接口路径 + */ + host: 'https://szdot.top', + baseURL: 'https://szdot.top/flycube.php', + apiPath: '/mpApi/Index/', + apiLoginPath: '/mpApi/Login/', + /** + * @description: mqtt服务器 + * mqttHost 地址 + * mqttPort 端口 + * mqttUserName 用户名 + * mqttPassword 密码 + */ + mqttHost: 'wss://szdot.top', + mqttPort: 8083, + mqttUserName: 'admin', + mqttPassword: '123456' +} diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..be6f1f6 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,410 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import app from './modules/app' +import settings from './modules/settings' +import user from './modules/user' +import api from '@/utils/api' +import { Message, MessageBox } from 'element-ui' + +Vue.use(Vuex) + +const store = new Vuex.Store({ + state: { + adminList: [], // 管理员列表 + airList: [], // 所有飞机列表 + siteList: [], // 站点列表 + routeList: [], // 航线列表 + questList: [], // 订单列表 + logList: [], // 操作日志列表 + crosFrequency: null // 对频macadd + }, + mutations: { + /** + * @description: 设置管理员列表 + */ + setAdminList (state, list) { + state.adminList = list + }, + /** + * @description: 设置飞机列表 + */ + setAirList (state, list) { + state.airList = list + }, + /** + * @description: 设置站点列表 + */ + setSiteList (state, list) { + state.siteList = list + }, + /** + * @description: 设置航线列表 + */ + setRouteList (state, list) { + state.routeList = list + }, + /** + * @description: 设置订单列表 + */ + setQuestList (state, list) { + state.questList = list + }, + /** + * @description: 向操作日志列表最后插入新的信息 + * @param {*} logData + */ + insertNewLog (state, logData) { + state.logList.push(logData) + }, + /** + * @description: 登记对频信息 + */ + setCrosFrequency (state, macAdd) { + state.crosFrequency = macAdd + } + }, + actions: { + /** + * @description: 获取管理员列表 + */ + async fetchAdminList ({ commit }) { + const res = await api.get('getAdminList') + if (res.data.status === 1) { + commit('setAdminList', res.data.adminList) + } else { + Message.error(res.data.msg) + } + }, + /** + * @description: 获取飞机列表 + */ + async fetchAirList ({ commit, state }) { + const res = await api.get('getAirList') + res.data.airList.forEach(plane => { + plane.planeState = { // 飞机状态初始化字段 + heartBeat: null, // 心跳 + heartRandom: null, // 每次接收到心跳创建一个随机数 用于watch监听 + voltagBattery: null, // 电压信息 + currentBattery: null, // 电流信息 + batteryRemaining: null, // 电池电量 + positionAlt: null, // 高度信息 + groundSpeed: null, // 对地速度 + satCount: null, // 卫星数量 + latitude: null, // 纬度 + longitude: null, // 经度 + fixType: null, // 定位状态 + state: 1, // 飞机状态 默认初始状态为1 + pingNet: null, // 网速测试 + getPlaneMode: null, // 飞机模式 + loadweight: null, // 重量 + hookstatus: null, // 钩子状态 + position: []// [[经度,维度,海拔高度]]累计数组 + } + }) + if (res.data.status === 1) { + commit('setAirList', res.data.airList) + } else { + commit('setSiteList', []) + Message.warning(res.data.msg) + } + return res.data.airList + }, + /** + * @description: 创建新飞机 + * @param {*} form 表单.飞机信息 + * @return {*} 服务器返回信息 + */ + async fetchAddAir ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('shop_id', form.shop_id) + params.append('name', form.name) + params.append('date', form.date) + if (form.state) { + params.append('state', '1') + } else { + params.append('state', '0') + } + params.append('desc', form.desc) + const res = await api.post('addAir', params) + if (res.data.status === 1) { + await dispatch('fetchAirList')// 刷新飞机列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 更新新飞机数据 + * @param {*} form 表单.飞机信息 + * @return {*} 服务器返回信息 + */ + async fetchSaveAir ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('shop_id', form.shop_id) + params.append('name', form.name) + params.append('date', form.date) + if (form.state) { + params.append('state', '1') + } else { + params.append('state', '0') + } + params.append('desc', form.desc) + params.append('id', form.id) + const res = await api.post('saveAir', params) + if (res.data.status === 1) { + await dispatch('fetchAirList')// 刷新飞机列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 删除指定序号飞机 + * @param {*} idArray 飞机序号数组 + */ + fetchDelAir ({ dispatch }, idArr) { + if (idArr.length === 0) { + Message.error('未勾选记录') + } else { + MessageBox.confirm('请谨慎操作 确认删除?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + const params = new URLSearchParams() + params.append('idArr', idArr) + api.post('deleteAir', params).then(res => { + if (res.data.status === 1) { + Message.success(res.data.msg) + dispatch('fetchAirList')// 刷新飞机列表 + } else { + Message.error(res.data.msg) + } + }) + }).catch(() => { + Message.info('取消操作') + }) + } + }, + /** + * @description: 获取站点列表 + */ + async fetchSiteList ({ commit }) { + const res = await api.get('getSiteList') + if (res.data.status === 1) { + commit('setSiteList', res.data.siteList) + } else { + commit('setSiteList', []) + Message.warning(res.data.msg) + } + }, + /** + * @description: 锁定站点 + * @param {*} form 表单.站点信息 + * @return {*} 服务器返回信息 + */ + async fetchLockSite ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('id', form.id) + params.append('runing', form.runing) + const res = await api.post('lockSite', params) + if (res.data.status === 1) { + await dispatch('fetchSiteList')// 刷新站点列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 创建新站点 + * @param {*} form 表单.站点信息 + * @return {*} 服务器返回信息 + */ + async fetchAddSite ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('shop_id', form.shop_id) + params.append('sitename', form.sitename) + params.append('desc', form.desc) + params.append('upFile', form.upFile) + params.append('size', form.size) + params.append('bindroute', form.bindroute) + const res = await api.post('addSite', params) + if (res.data.status === 1) { + await dispatch('fetchSiteList')// 刷新站点列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 创建新站点 + * @param {*} form 表单.站点信息 + * @return {*} 服务器返回信息 + */ + async fetchSaveSite ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('id', form.id) + params.append('shop_id', form.shop_id) + params.append('sitename', form.sitename) + params.append('desc', form.desc) + params.append('upFile', form.upFile) + params.append('size', form.size) + params.append('bindroute', form.bindroute) + const res = await api.post('saveSite', params) + if (res.data.status === 1) { + await dispatch('fetchSiteList')// 刷新站点列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 删除指定序号站点 + * @param {*} idArray 站点序号数组 + */ + fetchDelSite ({ dispatch }, idArr) { + if (idArr.length === 0) { + Message.error('未勾选记录') + } else { + MessageBox.confirm('请谨慎操作 确认删除?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + const params = new URLSearchParams() + params.append('idArr', idArr) + api.post('deleteSite', params).then(res => { + if (res.data.status === 1) { + Message.success(res.data.msg) + dispatch('fetchSiteList')// 刷新站点列表 + } else { + Message.error(res.data.msg) + } + }) + }).catch(() => { + Message.info('取消操作') + }) + } + }, + /** + * @description: 获取航线列表 + */ + async fetchRouteList ({ commit }) { + const res = await api.get('getRouteList') + if (res.data.status === 1) { + commit('setRouteList', res.data.routeList) + } else { + Message.warning(res.data.msg) + } + return res.data.routeList + }, + /** + * @description: 创建新航线 + * @param {*} form 表单.航线信息 + * @return {*} 服务器返回信息 + */ + async fetchAddRoute ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('shop_id', form.shop_id) + params.append('name', form.name) + params.append('desc', form.desc) + params.append('upFile', form.upFile) + const res = await api.post('addRoute', params) + if (res.data.status === 1) { + await dispatch('fetchRouteList')// 刷新站点列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 更新航线 + * @param {*} form 表单.航线信息 + * @return {*} 服务器返回信息 + */ + async fetchSaveRoute ({ dispatch }, form) { + const params = new URLSearchParams() + params.append('id', form.id) + params.append('shop_id', form.shop_id) + params.append('name', form.name) + params.append('desc', form.desc) + params.append('upFile', form.upFile) + const res = await api.post('saveRoute', params) + if (res.data.status === 1) { + await dispatch('fetchRouteList')// 刷新站点列表 + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + return res + }, + /** + * @description: 删除指定序号航线 + * @param {*} idArray 航线序号数组 + */ + fetchDelRoute ({ dispatch }, idArr) { + if (idArr.length === 0) { + Message.error('未勾选记录') + } else { + MessageBox.confirm('请谨慎操作 确认删除?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + const params = new URLSearchParams() + params.append('idArr', idArr) + api.post('deleteRoute', params).then(res => { + if (res.data.status === 1) { + Message.success(res.data.msg) + dispatch('fetchRouteList')// 刷新航线列表 + dispatch('fetchSiteList')// 刷新站点列表 + } else { + Message.error(res.data.msg) + } + }) + }).catch(() => { + Message.info('取消操作') + }) + } + }, + /** + * @description: 获取订单列表 ps:待发货及待收货 并且不是退款成功状态 + * @return {*} 列表 + */ + async fetchQuestList ({ commit }) { + const res = await api.get('getQuestList') + if (res.data.status === 1) { + commit('setQuestList', res.data.questList) + } + return res + }, + /** + * @description: 向操作日志插入信息 并在积攒多条之后 向服务器提交 + * @param {logData} content 日志内容 logData.color 时间 + * @param {logData} color 标点颜色 默认#409EFF + * @param {logData} timestamp 插入时间 默认当前时间 + */ + fetchLog ({ commit }, logData) { + /* 插入日志 */ + logData.color = typeof logData.color !== 'undefined' ? logData.color : '#409EFF' + logData.timestamp = typeof logData.timestamp !== 'undefined' ? logData.color : new Date().getTime() + commit('insertNewLog', logData) + /* 积攒 向服务器提交 日志 待续写... */ + } + }, + modules: { + app, + settings, + user + }, + getters: { + } +}) + +export default store diff --git a/src/store/modules/app.js b/src/store/modules/app.js new file mode 100644 index 0000000..1ea3db4 --- /dev/null +++ b/src/store/modules/app.js @@ -0,0 +1,63 @@ +const state = { + mqttState: false, // mqtt连接状态 + isCollapse: localStorage.getItem('isCollapse') ? !!+localStorage.getItem('isCollapse') : true, // 侧边导航栏 显隐 + isMobile: null, // 是否是pc端 true电脑端 false为移动端 + defaultLngLat: null, // 地图默认经纬度 + defaultZoom: null // 地图默认缩放 +} + +const mutations = { + // 导航栏 显隐 + setCollapse () { + state.isCollapse = !state.isCollapse + if (state.isCollapse) { + localStorage.setItem('isCollapse', 1) + } else { + localStorage.setItem('isCollapse', 0) + } + }, + // 判断是否pc端 还是移动端 true电脑端 false移动端 + setIsMobile () { + const userAgentInfo = navigator.userAgent + const agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'] + for (let i = 0; i < agents.length; i++) { + if (userAgentInfo.indexOf(agents[i]) > 0) { + state.isMobile = false + break + } else { + state.isMobile = true + } + } + }, + // 设置地图默认经纬度 + setDefaultLngLat (state, lngLat) { + state.defaultLngLat = lngLat + localStorage.setItem('defaultLngLat', JSON.stringify(lngLat)) + }, + // 设置地图默认缩放值 + setDefaultZoom (state, zoom) { + state.defaultZoom = zoom + localStorage.setItem('defaultZoom', zoom) + } +} + +const actions = { +} +const getters = { + // 获取地图默认经纬度 缓存中没有从 localStorage中获取 也没有设置为0 + getDefaultLngLat () { + return state.defaultLngLat !== null ? state.defaultLngLat : localStorage.getItem('defaultLngLat') !== null ? JSON.parse(localStorage.getItem('defaultLngLat')) : { lng: 0, lat: 0 } + }, + // 获取地图默认缩放值 缓存中没有从 localStorage中获取 也没有设置为1 + getDefaultZoom () { + return state.defaultZoom !== null ? state.defaultZoom : localStorage.getItem('defaultZoom') !== null ? localStorage.getItem('defaultZoom') : 1 + } +} + +export default { + namespaced: true, + state, + mutations, + actions, + getters +} diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js new file mode 100644 index 0000000..94814f3 --- /dev/null +++ b/src/store/modules/settings.js @@ -0,0 +1,38 @@ +import defaultSettings from '@/settings' + +const { + title, + host, + baseURL, + apiPath, + apiLoginPath, + mqttHost, + mqttPort, + mqttUserName, + mqttPassword +} = defaultSettings + +const state = { + title: title, + host: host, + baseURL: baseURL, + apiPath: apiPath, + apiLoginPath: apiLoginPath, + mqttHost: mqttHost, + mqttPort: mqttPort, + mqttUserName: mqttUserName, + mqttPassword: mqttPassword +} + +const mutations = { +} + +const actions = { +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/src/store/modules/user.js b/src/store/modules/user.js new file mode 100644 index 0000000..f77b048 --- /dev/null +++ b/src/store/modules/user.js @@ -0,0 +1,42 @@ +export default { + namespaced: true, + state: { + token: null, + name: null, + uname: null, + photo: null, + shop_id: null, + power: null + }, + mutations: { + // 用户信息初始化 + initUser (state) { + if (state.token == null) { + if (localStorage.getItem('token') != null) { + state.token = localStorage.getItem('token') + state.name = localStorage.getItem('name') + state.uname = localStorage.getItem('uname') + state.photo = localStorage.getItem('photo') + state.shop_id = localStorage.getItem('shop_id') + state.power = localStorage.getItem('power') + } + } + }, + // 清除用户信息 + destroyUser (state) { + state.token = null + state.name = null + state.uname = null + state.photo = null + state.shop_id = null + state.power = null + localStorage.removeItem('token') + } + }, + actions: { + // 异步 清除用户信息 + async destroyUserAsync (context) { + await context.commit('destroyUser') + } + } +} diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss new file mode 100644 index 0000000..d917c21 --- /dev/null +++ b/src/styles/element-ui.scss @@ -0,0 +1,67 @@ +// cover some element-ui styles + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + + +// to fixed https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + + } +} +.el-upload-dragger { + width: 178px !important; + height: 178px !important; +} + +// dropdown +.el-dropdown-menu { + a { + display: block + } +} + +// to fix el-date-picker css style +.el-range-separator { + box-sizing: content-box; +} + + +.navbarBadge .is-fixed { + right: 30px !important; + top: 10px !important; +} + +.el-drawer__header{ + margin-bottom:15px; +} + +.el-tabs__nav .is-top{ + cursor: pointer; +} +.el-tabs__header{ + margin-bottom: -16px; +} \ No newline at end of file diff --git a/src/styles/index.scss b/src/styles/index.scss new file mode 100644 index 0000000..a98786f --- /dev/null +++ b/src/styles/index.scss @@ -0,0 +1,302 @@ +@import "@/styles/theme.scss"; +@import '@/styles/element-ui.scss'; +@import '@/styles/transition.scss'; + +//通用 +* { + margin: 0px; + padding: 0px; +} + +html { + height: 100%; +} + +body { + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; + font-size: 14px; + color: $maintext-color; +} + + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.router-link-active { + color: $maintext-color; + text-decoration: none !important; +} + +a { + text-decoration: none !important; +} + +a:focus, +a:active { + outline: none !important; +} + +div:focus { + outline: none; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +label { + font-weight: 700; +} + +.animation { + -webkit-transition: all 0.2s ease; + -moz-transition: all 0.2s ease; + -ms-transition: all 0.2s ease; + -o-transition: all 0.2s ease; + transition: all 0.2s ease; +} + +// main-container global css +.app-container { + padding: 20px; + background-color: #fefefe; + height: 100%; +} + +//mapboxgl +.mapboxgl-ctrl-bottom-left a { + display: none !important; +} + +.mapboxgl-ctrl.mapboxgl-ctrl-attrib { + display: none !important; +} + + +//public +.borderLN { + border-top-left-radius: 0px !important; + border-bottom-left-radius: 0px !important; +} + +.borderRN { + border-top-right-radius: 0px !important; + border-bottom-right-radius: 0px !important; +} + +.l { + float: left !important; +} + +.r { + float: right !important; +} + +.clearB { + clear: both !important; +} + +.border { + border: 1px solid #DCDFE6; +} + +.mainFontColor { + color: #303133 !important; +} + +.normalFontColor { + color: #606266 !important; +} + +.secondaryFontColor { + color: #909399 !important; +} + +.seatFontColor { + color: #C0C4CC !important; +} + +.fc { + text-align: center; +} + +.fr { + text-align: right; +} + +.vm { + vertical-align: middle; +} + +.bg-white { + background-color: $white-color; +} + +.border-b-n { + border-bottom: none !important; +} + +.border-t-n { + border-top: none !important; +} + +.border-l-n { + border-left: none !important; +} + +.border-r-n { + border-right: none !important; +} + +.border-n { + border: none !important; +} + +.fb { + font-weight: bold; +} + +.el-row { + margin-top: 10px; + + .el-header { + color: $maintext-color; + padding: 0px; + background-color: $border4-color; + } + + .el-main { + padding: 0px; + } +} + +//m-l-0 p-l-0 马根 帕丁 +$position: ( + "t":"top", + "b":"bottom", + "l":"left", + "r":"right", +); +$type: ( + "p":"padding", + "m":"margin" +); + +@each $item in $type { + @each $list in $position { + @for $i from 0 through 20 { + $val: $i * 1; + + .#{nth($item,1)}-#{nth($list,1)}-#{$val} { + #{nth($item,2)}-#{nth($list,2)}: #{$val}px !important; + } + } + + @for $i from 4 through 20 { + $val: $i * 5; + + .#{nth($item,1)}-#{nth($list,1)}-#{$val} { + #{nth($item,2)}-#{nth($list,2)}: #{$val}px !important; + } + } + } +} + +//m-0 p-0 马根 帕丁 +$type: ( + "p":"padding", + "m":"margin" +); + +@each $item in $type { + @for $i from 0 through 100 { + $val: $i * 1; + + .#{nth($item,1)}-#{$val} { + #{nth($item,2)}: #{$val}px !important; + } + } +} + +//w-10 h-10 宽度百分比 高度百分比 +$type: ( + "w":"width", + "h":"height" +); +$mark: ( + "%" +); + +@each $item in $type { + @for $i from 0 through 10 { + $val: $i * 10; + + .#{nth($item,1)}-#{$val} { + #{nth($item,2)}: #{$val}#{$mark}; + } + } +} + +//w-10px h-10px 宽度px 高度px 参数10 20 30... +$type: ( + "w":"width", + "h":"height" +); + +@each $item in $type { + @for $i from 1 through 80 { + $val: $i*10; + + .#{nth($item,1)}-#{$val}px { + #{nth($item,2)}: #{$val}px; + } + } +} + +//f-s-12 设置字体大小 1-50 60-200 50之前1递增 60以后10递增 +$type: ( + "f-s":"font-size", +); + +@each $item in $type { + @for $val from 1 through 50 { + .#{nth($item,1)}-#{$val} { + #{nth($item,2)}: #{$val}px !important; + } + } + + @for $i from 6 through 20 { + $val: $i*10; + + .#{nth($item,1)}-#{$val} { + #{nth($item,2)}: #{$val}px !important; + } + } +} + +//l-h-50 字体行高 12-100 1递增 +$type: ( + "l-h":"line-height", +); + +@each $item in $type { + @for $val from 12 through 100 { + .#{nth($item,1)}-#{$val} { + #{nth($item,2)}: #{$val}px !important; + } + } +} \ No newline at end of file diff --git a/src/styles/myIcon.scss b/src/styles/myIcon.scss new file mode 100644 index 0000000..b5cdd97 --- /dev/null +++ b/src/styles/myIcon.scss @@ -0,0 +1 @@ +@import 'https://at.alicdn.com/t/c/font_3703467_4teeodr1wrk.css'; //iconfont阿里巴巴 \ No newline at end of file diff --git a/src/styles/theme.scss b/src/styles/theme.scss new file mode 100644 index 0000000..1ac01dd --- /dev/null +++ b/src/styles/theme.scss @@ -0,0 +1,41 @@ +//变量主题颜色 +//主色 +$brand-color: #409EFF; +//辅色 +$success-color: #67C23A; +$warning-color: #E6A23C; +$danger-color: #F56C6C; +//字体颜色 +$info-color: #909399; +$maintext-color: #303133; +$normaltext-color: #606266; +$secondarytext-color: #909399; +$holdtext-color: #C0C4CC; +//边框颜色 +$border1-color: #DCDFE6; +$border2-color: #E4E7ED; +$border3-color: #EBEEF5; +$border4-color: #F2F6FC; +//基础 +$black-color: #000000; +$white-color: #FFFFFF; +$graylight-color: #F2F6FC; + +:export { + brand-color: $brand-color; + success-color: $success-color; + warning-color: $warning-color; + danger-color: $danger-color; + info-color: $info-color; + maintext-color: $maintext-color; + normaltext-color: $normaltext-color; + secondarytext-color: $secondarytext-color; + holdtext-color: $holdtext-color; + border1-color: $border1-color; + border2-color: $border2-color; + border3-color: $border3-color; + border4-color: $border4-color; + black-color: $black-color; + white-color: $white-color; + graylight-color: $graylight-color; +} \ No newline at end of file diff --git a/src/styles/transition.scss b/src/styles/transition.scss new file mode 100644 index 0000000..4cb27cc --- /dev/null +++ b/src/styles/transition.scss @@ -0,0 +1,48 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/utils/api/index.js b/src/utils/api/index.js new file mode 100644 index 0000000..3166b18 --- /dev/null +++ b/src/utils/api/index.js @@ -0,0 +1,68 @@ +import axios from 'axios' +import router from '@/router' +import store from '@/store' + +// axios缺省设置 +axios.defaults.baseURL = store.state.settings.baseURL +// axios.defaults.headers.post['Content-Type'] = 'application/json' +export default { + get, + post +} +/** + * @description: 异步 get方法 访问api + * @return: json.data对象 + * @param {string} controller 控制器名称 + * @param {bool} islogin 默认为index路径 否则访问login路径 + */ +async function get (controller, islogin = false) { + const path = init(islogin) + try { + const res = await axios.get(path + controller) + if (res.data.status === -1) { // 权限过期 + localStorage.removeItem('token') + router.go(0) + } + return res + } catch (error) { + console.error('Error fetching data:', error) + throw error + } +} +/** + * @description: 异步 post方法 访问api + * @return: json.data对象 + * @param {string} controller 控制器名称 + * @param {obj} params post参数 + * @param {bool} islogin 默认为index路径 否则访问login路径 + */ +async function post (controller, params, islogin = false) { + const path = init(islogin) + try { + const res = await axios.post(path + controller, params) + if (res.data.status === -1) { // 权限过期 + localStorage.removeItem('token') + router.go(0) + } + return res + } catch (error) { + console.error('Error fetching data:', error) + throw error + } +} +/** + * @description: 判断访问常规还是登录接口路径 设置token头文件 + * @return {*} 接口路径 + * @param {bool} islogin + */ +function init (islogin) { + let path + if (islogin) { + axios.defaults.headers.common.Token = 'login' + path = store.state.settings.apiLoginPath + } else { + axios.defaults.headers.common.Token = store.state.user.token + path = store.state.settings.apiPath + } + return path +} diff --git a/src/utils/api/table.js b/src/utils/api/table.js new file mode 100644 index 0000000..fb37fd9 --- /dev/null +++ b/src/utils/api/table.js @@ -0,0 +1,38 @@ +import store from '@/store' +import api from '@/utils/api' +// import { Message, MessageBox } from 'element-ui' +import { Message } from 'element-ui' + +/** +* @description: 向对频api 提交数据 +*/ +export async function apiCrosFrequency (params) { + const data = new URLSearchParams()// post对象参数 转成 字符串连接 + data.append('macAdd', params.macAdd) + data.append('id', params.id) + const res = await api.post('crosFrequency', data) + if (res.data.status === 1) { + Message.success(res.data.msg) + store.dispatch('fetchAirList')// 更新飞机列表 + } else { + Message.error(res.data.msg) + } +} +/** + * @description: 向改变订单承接任务api 提交数据 () + * @param {*} id 订单id + * @param {*} state "quest"修改quest字段 "status"修改status字段 + */ +export function questAss (id, state, val) { + const data = new URLSearchParams()// post对象参数 转成 字符串连接 + data.append('id', id) + data.append('state', state) + data.append('val', val) + api.post('questAss', data).then(res => { + if (res.data.status === 1) { + Message.success(res.data.msg) + } else { + Message.error(res.data.msg) + } + }) +} diff --git a/src/utils/api/user.js b/src/utils/api/user.js new file mode 100644 index 0000000..0130c81 --- /dev/null +++ b/src/utils/api/user.js @@ -0,0 +1,24 @@ +import api from '@/utils/api' +import router from '@/router' +import { Message } from 'element-ui' + +export function login (params) { + const data = new URLSearchParams()// post对象参数 转成 字符串连接 + data.append('username', params.username) + data.append('password', params.password) + api.post('login', data, true).then( + res => { + if (res.data.status === 1) { + localStorage.setItem('token', res.data.token) + localStorage.setItem('name', res.data.adminInfo.name) + localStorage.setItem('uname', res.data.adminInfo.uname) + localStorage.setItem('photo', res.data.adminInfo.photo) + localStorage.setItem('shop_id', res.data.adminInfo.shop_id) + localStorage.setItem('power', res.data.adminInfo.power) + router.replace('/') + } else { + Message.error(res.data.msg) + } + } + ) +} diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..a1bf290 --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,131 @@ +/** + * Parse the time to string + * @param {(Object|string|number)} time + * @param {string} cFormat + * @returns {string | null} + */ +export function parseTime (time, cFormat) { + if (arguments.length === 0 || !time) { + return null + } + const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string')) { + if ((/^[0-9]+$/.test(time))) { + time = parseInt(time) + } else { + time = time.replace(new RegExp(/-/gm), '/') + } + } + + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + // eslint-disable-next-line camelcase + const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { + const value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } + return value.toString().padStart(2, '0') + }) + // eslint-disable-next-line camelcase + return time_str +} + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export function formatTime (time, option) { + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '月' + + d.getDate() + + '日' + + d.getHours() + + '时' + + d.getMinutes() + + '分' + ) + } +} + +/** + * @param {string} url + * @returns {Object} + */ +export function param2Obj (url) { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} + +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal (path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +/** + * @description: 统计当前被选中的ID组 + * @return: 被选中记录 的ID组 + * @param {*} selection 列表中被选中的记录 + */ +export function countSelIdArr (selection) { + const idArr = [] + selection.map((item) => idArr.push(item.id)) + return idArr +} diff --git a/src/utils/mqtt/index.js b/src/utils/mqtt/index.js new file mode 100644 index 0000000..fbd1da7 --- /dev/null +++ b/src/utils/mqtt/index.js @@ -0,0 +1,89 @@ +import mqtt from 'mqtt' +import store from '@/store' + +export default { + client: null, // mqtt连接 对象 + url: store.state.settings.mqttHost, // mqtt服务器地址 + options: { // mqtt服务器 参数配置 + port: store.state.settings.mqttPort, + connectTimeout: 3000, + clientId: store.state.user.shop_id, + clean: true, + keepalive: 60, + username: store.state.settings.mqttUserName, + password: store.state.settings.mqttPassword + }, + mqttConf, + mqttDestroy, + doSubscribe, + publishFun +} + +/** + * @Description: mqtt对象初始化 + */ +function mqttConf () { + if (!this.client) { + // 链接mqtt + this.client = mqtt.connect(this.url, this.options) + // mqtt服务器中断 + this.client.on('error', () => { + store.dispatch('fetchLog', { content: '指令服务器异常中断' }) + }) + // 端口之后复连 + this.client.on('reconnect', () => { + store.dispatch('fetchLog', { content: '重新连接指令服务器' }) + }) + // 监听断开连接事件 + this.client.on('offline', () => { + store.dispatch('fetchLog', { content: '指令服务器异常中断' }) + store.state.app.mqttState = false // 标记mqtt链接失败 掉线 + }) + } +} +/** + * @description: 获取主题消息 + * @param {string} topic 主题名称 + * @param {fun} callBack 回调 传一个对象{topic订阅的主题,msg接收到主题的数据} 在父级给获取 + */ +function doSubscribe (topic, callBack) { + // 订阅主题 + this.client.on('connect', () => { + if (store.state.app.mqttState === false) { + store.dispatch('fetchLog', { content: '成功连接指令服务器' }) + } + store.state.app.mqttState = true // 标记mqtt链接成功 在线 + // 订阅一个主题 + this.client.subscribe(topic, { qos: 2 }, err => { + if (!err) { + store.dispatch('fetchLog', { content: topic + '主题订阅成功' }) + } else { + store.dispatch('fetchLog', { content: topic + '主题订阅失败' }) + } + }) + }) + // 获取订阅主题的消息 + this.client.on('message', (topic, message) => { + callBack({ topic: topic, msg: message.toString() }) + }) +} +/** + * @description: 向指定topic发送消息 + * @param {*} topic 发送信息到的主题 不包括前缀 + * @param {*} msg 要发送的信息 + */ +function publishFun (topic, msg) { + // topic要保持一致 + this.client.publish(topic, msg, { + qos: 2 + }) +} +/** + * @Description: 销毁mqtt对象 + */ +function mqttDestroy () { + if (this.client) { + this.client.end() // 离开页面的时候 关闭mqtt连接 + this.client = null + } +} diff --git a/src/views/404.vue b/src/views/404.vue new file mode 100644 index 0000000..fec855c --- /dev/null +++ b/src/views/404.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/src/views/layout/components/BlogBox.vue b/src/views/layout/components/BlogBox.vue new file mode 100644 index 0000000..13ac7e6 --- /dev/null +++ b/src/views/layout/components/BlogBox.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/src/views/layout/components/headbar.vue b/src/views/layout/components/headbar.vue new file mode 100644 index 0000000..737a39e --- /dev/null +++ b/src/views/layout/components/headbar.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/src/views/layout/components/main/home/index.vue b/src/views/layout/components/main/home/index.vue new file mode 100644 index 0000000..0bb018a --- /dev/null +++ b/src/views/layout/components/main/home/index.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/views/layout/components/main/planes/index.vue b/src/views/layout/components/main/planes/index.vue new file mode 100644 index 0000000..2036e54 --- /dev/null +++ b/src/views/layout/components/main/planes/index.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/src/views/layout/components/main/register/add.vue b/src/views/layout/components/main/register/add.vue new file mode 100644 index 0000000..9d6e492 --- /dev/null +++ b/src/views/layout/components/main/register/add.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/src/views/layout/components/main/register/crosFrequency.vue b/src/views/layout/components/main/register/crosFrequency.vue new file mode 100644 index 0000000..1afcb67 --- /dev/null +++ b/src/views/layout/components/main/register/crosFrequency.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/src/views/layout/components/main/register/index.vue b/src/views/layout/components/main/register/index.vue new file mode 100644 index 0000000..9a0e8e8 --- /dev/null +++ b/src/views/layout/components/main/register/index.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/views/layout/components/main/route/add.vue b/src/views/layout/components/main/route/add.vue new file mode 100644 index 0000000..5c3ea28 --- /dev/null +++ b/src/views/layout/components/main/route/add.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/src/views/layout/components/main/route/index.vue b/src/views/layout/components/main/route/index.vue new file mode 100644 index 0000000..eb9545c --- /dev/null +++ b/src/views/layout/components/main/route/index.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/src/views/layout/components/main/site/add.vue b/src/views/layout/components/main/site/add.vue new file mode 100644 index 0000000..69dbcee --- /dev/null +++ b/src/views/layout/components/main/site/add.vue @@ -0,0 +1,260 @@ + + + + + diff --git a/src/views/layout/components/main/site/index.vue b/src/views/layout/components/main/site/index.vue new file mode 100644 index 0000000..e9925ab --- /dev/null +++ b/src/views/layout/components/main/site/index.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/src/views/layout/components/menubar.vue b/src/views/layout/components/menubar.vue new file mode 100644 index 0000000..99a40f2 --- /dev/null +++ b/src/views/layout/components/menubar.vue @@ -0,0 +1,204 @@ + + + + + diff --git a/src/views/layout/index.vue b/src/views/layout/index.vue new file mode 100644 index 0000000..40cbc00 --- /dev/null +++ b/src/views/layout/index.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..8631cd3 --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,188 @@ + + + + + + +