mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-14 12:30:49 +08:00
admin base
This commit is contained in:
47
admin/package-lock.json
generated
47
admin/package-lock.json
generated
@@ -7,8 +7,10 @@
|
||||
"": {
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"element-plus": "^1.0.2-beta.40",
|
||||
"vue": "^3.0.5"
|
||||
"vue": "^3.0.5",
|
||||
"vue-router": "^4.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^1.2.1",
|
||||
@@ -158,6 +160,14 @@
|
||||
"resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-3.5.1.tgz",
|
||||
"integrity": "sha1-zWK5aIskZfSEIOJ620d2CrG1VZ8="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npm.taobao.org/axios/download/axios-0.21.1.tgz",
|
||||
"integrity": "sha1-IlY0gZYvTWvemnbVFu8OXTwJsrg=",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz",
|
||||
@@ -254,6 +264,14 @@
|
||||
"resolved": "https://registry.npm.taobao.org/estree-walker/download/estree-walker-2.0.2.tgz?cache=0&sync_timestamp=1611956983677&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festree-walker%2Fdownload%2Festree-walker-2.0.2.tgz",
|
||||
"integrity": "sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw="
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.3.tgz",
|
||||
"integrity": "sha1-5VmK1QF0wbxOhyMB6CrCzZf5Amc=",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npm.taobao.org/fsevents/download/fsevents-2.3.2.tgz",
|
||||
@@ -628,6 +646,14 @@
|
||||
"@vue/shared": "3.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.6.tgz",
|
||||
"integrity": "sha1-kXUNtQfSZkLyJbDsYGRWjl/kSNY=",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz",
|
||||
@@ -764,6 +790,14 @@
|
||||
"resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-3.5.1.tgz",
|
||||
"integrity": "sha1-zWK5aIskZfSEIOJ620d2CrG1VZ8="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npm.taobao.org/axios/download/axios-0.21.1.tgz",
|
||||
"integrity": "sha1-IlY0gZYvTWvemnbVFu8OXTwJsrg=",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz",
|
||||
@@ -839,6 +873,11 @@
|
||||
"resolved": "https://registry.npm.taobao.org/estree-walker/download/estree-walker-2.0.2.tgz?cache=0&sync_timestamp=1611956983677&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festree-walker%2Fdownload%2Festree-walker-2.0.2.tgz",
|
||||
"integrity": "sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.3.tgz",
|
||||
"integrity": "sha1-5VmK1QF0wbxOhyMB6CrCzZf5Amc="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npm.taobao.org/fsevents/download/fsevents-2.3.2.tgz",
|
||||
@@ -1138,6 +1177,12 @@
|
||||
"@vue/shared": "3.0.11"
|
||||
}
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.6.tgz",
|
||||
"integrity": "sha1-kXUNtQfSZkLyJbDsYGRWjl/kSNY=",
|
||||
"requires": {}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz",
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"element-plus": "^1.0.2-beta.40",
|
||||
"vue": "^3.0.5"
|
||||
"vue": "^3.0.5",
|
||||
"vue-router": "^4.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^1.2.1",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -1,56 +1,188 @@
|
||||
<template>
|
||||
<img alt="Vue logo" src="./assets/logo.png" />
|
||||
<HelloWorld msg="Hello Vue 3 + Vite" />
|
||||
<el-button type="primary"> Element UI </el-button>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="12">Left</el-col>
|
||||
<el-col :span="12">Right</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form>
|
||||
<el-form-item label="测试" label-width="120px">
|
||||
<el-checkbox-group v-model="checkList">
|
||||
<el-checkbox label="复选框 A"></el-checkbox>
|
||||
<el-checkbox label="复选框 B"></el-checkbox>
|
||||
<el-checkbox label="复选框 C"></el-checkbox>
|
||||
<el-checkbox label="禁用" disabled></el-checkbox>
|
||||
<el-checkbox label="选中且禁用" disabled></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div class="layout">
|
||||
<el-container v-if="state.showMenu" class="container">
|
||||
<el-aside class="aside">
|
||||
<div class="head">
|
||||
<div>
|
||||
<!-- <img src="http://demo.nexusphp.org/favicon.ico" alt="logo">-->
|
||||
<span>NexusPHP</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line" />
|
||||
<el-menu
|
||||
:default-openeds="state.defaultOpen"
|
||||
background-color="#222832"
|
||||
text-color="#fff"
|
||||
:router="true"
|
||||
:default-active='state.currentPath'
|
||||
>
|
||||
<el-menu-item index="/"><i class="el-icon-odometer" />Dashboard</el-menu-item>
|
||||
<el-submenu index="2">
|
||||
<template #title>
|
||||
<span>User</span>
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<el-menu-item index="/user"><i class="el-icon-user" />User list</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-submenu>
|
||||
<el-submenu index="3">
|
||||
<template #title>
|
||||
<span>System</span>
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<el-menu-item index="/agent-allow"><i class="el-icon-menu" />Agent allow</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
<el-menu-item-group>
|
||||
<el-menu-item index="/exam"><i class="el-icon-menu" />Exam</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
<el-container class="content">
|
||||
<Header />
|
||||
<div class="main">
|
||||
<router-view />
|
||||
</div>
|
||||
<Footer />
|
||||
</el-container>
|
||||
</el-container>
|
||||
<el-container v-else class="container">
|
||||
<router-view />
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
|
||||
import { reactive } from 'vue'
|
||||
import Header from './components/Header.vue'
|
||||
import Footer from './components/Footer.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { pathMap, localGet } from './utils'
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
HelloWorld
|
||||
Header,
|
||||
Footer
|
||||
},
|
||||
setup(props, context) {
|
||||
console.log(props, context)
|
||||
const checkList = [];
|
||||
setup() {
|
||||
const noMenu = ['/login']
|
||||
const router = useRouter()
|
||||
const state = reactive({
|
||||
defaultOpen: ['1', '2', '3', '4'],
|
||||
showMenu: true,
|
||||
currentPath: '/dashboard',
|
||||
count: {
|
||||
number: 1
|
||||
}
|
||||
})
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.path == '/login') {
|
||||
// 如果路径是 /login 则正常执行
|
||||
next()
|
||||
} else {
|
||||
// 如果不是 /login,判断是否有 token
|
||||
if (!localGet('token')) {
|
||||
// 如果没有,则跳至登录页面
|
||||
next({ path: '/login' })
|
||||
} else {
|
||||
// 否则继续执行
|
||||
next()
|
||||
}
|
||||
}
|
||||
state.showMenu = !noMenu.includes(to.path)
|
||||
state.currentPath = to.path
|
||||
document.title = pathMap[to.name]
|
||||
})
|
||||
return {
|
||||
checkList
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This starter template is using Vue 3 experimental <script setup> SFCs
|
||||
// Check out https://github.com/vuejs/rfcs/blob/script-setup-2/active-rfcs/0000-script-setup.md
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
<style scoped>
|
||||
.layout {
|
||||
min-height: 100vh;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.container {
|
||||
height: 100vh;
|
||||
}
|
||||
.aside {
|
||||
width: 200px!important;
|
||||
background-color: #222832;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: none;
|
||||
overflow: -moz-scrollbars-none;
|
||||
}
|
||||
.aside::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 50px;
|
||||
}
|
||||
.head > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.head img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.head span {
|
||||
font-size: 20px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.line {
|
||||
border-top: 1px solid hsla(0,0%,100%,.05);
|
||||
border-bottom: 1px solid rgba(0,0,0,.2);
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
.main {
|
||||
height: calc(100vh - 100px);
|
||||
overflow: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-menu {
|
||||
border-right: none!important;
|
||||
}
|
||||
.el-submenu {
|
||||
border-top: 1px solid hsla(0, 0%, 100%, .05);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .2);
|
||||
}
|
||||
.el-submenu:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
.el-submenu [class^="el-icon-"] {
|
||||
vertical-align: -1px!important;
|
||||
}
|
||||
a {
|
||||
color: #409eff;
|
||||
text-decoration: none;
|
||||
}
|
||||
.el-pagination {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.el-popper__arrow {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
25
admin/src/components/Footer.vue
Normal file
25
admin/src/components/Footer.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div class="footer">
|
||||
<div class="left">Designed By Xiaomlove</div>
|
||||
<div class="right">
|
||||
<a target="_blank" href="https://nexusphp.org/">nexusphp.org</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Footer'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.footer {
|
||||
height: 50px;
|
||||
border-top: 1px solid #e9e9e9;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
122
admin/src/components/Header.vue
Normal file
122
admin/src/components/Header.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="left">
|
||||
<i v-if="hasBack" class="el-icon-back" @click="back"></i>
|
||||
<span style="font-size: 20px">{{ name }}</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
:width="320"
|
||||
trigger="click"
|
||||
popper-class="popper-user-box"
|
||||
>
|
||||
<template #reference>
|
||||
<div class="author">
|
||||
<i class="icon el-icon-s-custom" />
|
||||
{{ userInfo && userInfo.nickName || '' }}
|
||||
<i class="el-icon-caret-bottom" />
|
||||
</div>
|
||||
</template>
|
||||
<div class="nickname">
|
||||
<p>登录名:{{ userInfo && userInfo.loginUserName || '' }}</p>
|
||||
<p>昵称:{{ userInfo && userInfo.nickName || '' }}</p>
|
||||
<el-tag size="small" effect="dark" class="logout" @click="logout">退出</el-tag>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, reactive, toRefs } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import axios from '../utils/axios'
|
||||
import { localRemove, pathMap } from '../utils'
|
||||
export default {
|
||||
name: 'Header',
|
||||
setup() {
|
||||
const router = useRouter()
|
||||
const state = reactive({
|
||||
name: 'dashboard',
|
||||
userInfo: null,
|
||||
hasBack: false
|
||||
})
|
||||
onMounted(() => {
|
||||
const pathname = window.location.hash.split('/')[1] || ''
|
||||
if (!['login'].includes(pathname)) {
|
||||
// getUserInfo()
|
||||
}
|
||||
})
|
||||
const getUserInfo = async () => {
|
||||
const userInfo = await axios.get('/adminUser/profile')
|
||||
state.userInfo = userInfo
|
||||
}
|
||||
const logout = () => {
|
||||
axios.delete('/logout').then(() => {
|
||||
localRemove('token')
|
||||
router.push({ path: '/login' })
|
||||
})
|
||||
}
|
||||
const back = () => {
|
||||
router.back()
|
||||
}
|
||||
router.afterEach((to) => {
|
||||
console.log('to', to)
|
||||
const { id } = to.query
|
||||
state.name = pathMap[to.name]
|
||||
if (id && to.name == 'add') {
|
||||
state.name = '编辑商品'
|
||||
}
|
||||
state.hasBack = ['level2', 'level3', 'order_detail'].includes(to.name)
|
||||
})
|
||||
return {
|
||||
...toRefs(state),
|
||||
logout,
|
||||
back
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.header {
|
||||
height: 50px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.el-icon-back {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 4px;
|
||||
border-radius: 50px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.right > div > .icon{
|
||||
font-size: 18px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.author {
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.popper-user-box {
|
||||
background: url('https://s.yezgea02.com/lingling-h5/static/account-banner-bg.png') 50% 50% no-repeat!important;
|
||||
background-size: cover!important;
|
||||
border-radius: 0!important;
|
||||
}
|
||||
.popper-user-box .nickname {
|
||||
position: relative;
|
||||
color: #ffffff;
|
||||
}
|
||||
.popper-user-box .nickname .logout {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
3
admin/src/main.js
vendored
3
admin/src/main.js
vendored
@@ -1,5 +1,6 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import ElementPlus from 'element-plus'
|
||||
import router from './router/index'
|
||||
import 'element-plus/lib/theme-chalk/index.css'
|
||||
createApp(App).use(ElementPlus).mount('#app')
|
||||
createApp(App).use(ElementPlus).use(router).mount('#app')
|
||||
|
||||
50
admin/src/router/index.js
vendored
Normal file
50
admin/src/router/index.js
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(), // hash模式:createWebHashHistory,history模式:createWebHistory
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'dashboard',
|
||||
component: () => import('../views/dashboard/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('../views/login.vue')
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: 'user',
|
||||
component: () => import('../views/user/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/user-form',
|
||||
name: 'user-form',
|
||||
component: () => import('../views/user/form.vue')
|
||||
},
|
||||
{
|
||||
path: '/exam',
|
||||
name: 'exam',
|
||||
component: () => import('../views/exam/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/exam-form',
|
||||
name: 'exam-form',
|
||||
component: () => import('../views/exam/form.vue')
|
||||
},
|
||||
{
|
||||
path: '/agent-allow',
|
||||
name: 'agent-allow',
|
||||
component: () => import('../views/agent-allow/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/agent-allow-form',
|
||||
name: 'agent-allow-form',
|
||||
component: () => import('../views/agent-allow/form.vue')
|
||||
},
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
export default router
|
||||
47
admin/src/utils/api.js
vendored
Normal file
47
admin/src/utils/api.js
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import axios from "./axios";
|
||||
|
||||
const api = {
|
||||
listAllowAgent: (params = {}) => {
|
||||
return axios.get('agent-allow', {params: params});
|
||||
},
|
||||
storeAllowAgent: (params = {}) => {
|
||||
return axios.post('agent-allow', params);
|
||||
},
|
||||
updateAllowAgent: (id, params = {}) => {
|
||||
return axios.put('agent-allow/' + id, params);
|
||||
},
|
||||
getAllowAgent: (id) => {
|
||||
return axios.get('agent-allow/' + id);
|
||||
},
|
||||
deleteAllowAgent: (id) => {
|
||||
return axios.delete('agent-allow/' + id);
|
||||
},
|
||||
|
||||
listUser: (params = {}) => {
|
||||
return axios.get('user', {params: params});
|
||||
},
|
||||
storeUser: (params = {}) => {
|
||||
return axios.post('user', params);
|
||||
},
|
||||
|
||||
listExam: (params = {}) => {
|
||||
return axios.get('exam', {params: params});
|
||||
},
|
||||
storeExam: (params = {}) => {
|
||||
return axios.post('exam', params);
|
||||
},
|
||||
updateExam: (id, params = {}) => {
|
||||
return axios.put('exam/' + id, params);
|
||||
},
|
||||
getExam: (id) => {
|
||||
return axios.get('exam/' + id);
|
||||
},
|
||||
deleteExam: (id) => {
|
||||
return axios.delete('exam/' + id);
|
||||
},
|
||||
listClass: (params = {}) => {
|
||||
return axios.get('class', {params: params});
|
||||
},
|
||||
}
|
||||
|
||||
export default api
|
||||
28
admin/src/utils/axios.js
vendored
Normal file
28
admin/src/utils/axios.js
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import axios from 'axios'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
axios.defaults.baseURL = 'http://nexus-php8.tinyhd.net'
|
||||
axios.defaults.withCredentials = true
|
||||
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
|
||||
axios.defaults.headers['Content-Type'] = 'application/json'
|
||||
axios.defaults.headers['Accept'] = 'application/json'
|
||||
|
||||
// 请求拦截器,内部根据返回值,重新组装,统一管理。
|
||||
axios.interceptors.response.use(res => {
|
||||
console.log(res)
|
||||
if (typeof res.data !== 'object') {
|
||||
ElMessage.error('Server Error 1')
|
||||
return Promise.reject(res)
|
||||
}
|
||||
if (res.data.ret && res.data.ret != 0) {
|
||||
ElMessage.error(res.data.msg)
|
||||
return Promise.reject(res.data)
|
||||
}
|
||||
return res.data
|
||||
}, error => {
|
||||
console.log(error.response)
|
||||
ElMessage.error(error.response.data.msg || 'Server Error 2')
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
export default axios
|
||||
50
admin/src/utils/index.js
vendored
Normal file
50
admin/src/utils/index.js
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
export function localGet (key) {
|
||||
const value = window.localStorage.getItem(key)
|
||||
try {
|
||||
return JSON.parse(window.localStorage.getItem(key))
|
||||
} catch (error) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
export function localSet (key, value) {
|
||||
window.localStorage.setItem(key, JSON.stringify(value))
|
||||
}
|
||||
|
||||
export function localRemove (key) {
|
||||
window.localStorage.removeItem(key)
|
||||
}
|
||||
|
||||
// 判断内容是否含有表情字符,现有数据库不支持。
|
||||
export function hasEmoji (str = '') {
|
||||
const reg = /[^\u0020-\u007E\u00A0-\u00BE\u2E80-\uA4CF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF\u0080-\u009F\u2000-\u201f\u2026\u2022\u20ac\r\n]/g;
|
||||
return str.match(reg) && str.match(reg).length
|
||||
}
|
||||
|
||||
// 单张图片上传
|
||||
export const uploadImgServer = 'http://backend-api-02.newbee.ltd/manage-api/v1/upload/file'
|
||||
// 多张图片上传
|
||||
export const uploadImgsServer = 'http://backend-api-02.newbee.ltd/manage-api/v1/upload/files'
|
||||
|
||||
export const pathMap = {
|
||||
login: '登录',
|
||||
introduce: '系统介绍',
|
||||
dashboard: 'Dashboard',
|
||||
add: '添加商品',
|
||||
swiper: '轮播图配置',
|
||||
hot: '热销商品配置',
|
||||
new: '新品上线配置',
|
||||
recommend: '为你推荐配置',
|
||||
category: '分类管理',
|
||||
level2: '分类二级管理',
|
||||
level3: '分类三级管理',
|
||||
good: '商品管理',
|
||||
guest: '会员管理',
|
||||
order: '订单管理',
|
||||
order_detail: '订单详情',
|
||||
account: '修改账户',
|
||||
'agent-allow': 'Agent allow',
|
||||
'agent-allow-form': 'Agent allow form',
|
||||
'user': 'User',
|
||||
'user-form': 'User form',
|
||||
}
|
||||
3
admin/src/views/agent-allow/form.vue
Normal file
3
admin/src/views/agent-allow/form.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Agent Allow Form</div>
|
||||
</template>
|
||||
3
admin/src/views/agent-allow/index.vue
Normal file
3
admin/src/views/agent-allow/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Agent Allow Index</div>
|
||||
</template>
|
||||
3
admin/src/views/dashboard/index.vue
Normal file
3
admin/src/views/dashboard/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Dashboard</div>
|
||||
</template>
|
||||
3
admin/src/views/exam/form.vue
Normal file
3
admin/src/views/exam/form.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Exam Form</div>
|
||||
</template>
|
||||
3
admin/src/views/exam/index.vue
Normal file
3
admin/src/views/exam/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Exam Index</div>
|
||||
</template>
|
||||
128
admin/src/views/login.vue
Normal file
128
admin/src/views/login.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<div class="login-body">
|
||||
<div class="login-container">
|
||||
<div class="head">
|
||||
<img class="logo" src="http://demo.nexusphp.org/favicon.ico" />
|
||||
<div class="name">
|
||||
<div class="title">NexusPHP</div>
|
||||
<div class="tips">Management system - v1.6</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-form label-position="top" :rules="rules" :model="ruleForm" ref="loginForm" class="login-form">
|
||||
<el-form-item label="Username" prop="username">
|
||||
<el-input type="text" v-model.trim="ruleForm.username" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="Password" prop="password">
|
||||
<el-input type="password" v-model.trim="ruleForm.password" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="margin-top: 50px">
|
||||
<!-- <div style="color: #333">登录表示您已同意<a>《服务条款》</a></div>-->
|
||||
<el-button style="width: 100%" type="primary" @click="submitForm">Submit</el-button>
|
||||
<!-- <el-checkbox v-model="checked" @change="!checked">下次自动登录</el-checkbox>-->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from '../utils/axios'
|
||||
import { reactive, ref, toRefs } from 'vue'
|
||||
import { localSet } from '../utils'
|
||||
export default {
|
||||
name: 'Login',
|
||||
setup() {
|
||||
const loginForm = ref(null)
|
||||
const state = reactive({
|
||||
ruleForm: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
checked: true,
|
||||
rules: {
|
||||
username: [
|
||||
{ required: 'true', }
|
||||
],
|
||||
password: [
|
||||
{ required: 'true', }
|
||||
]
|
||||
}
|
||||
})
|
||||
const submitForm = async () => {
|
||||
loginForm.value.validate((valid) => {
|
||||
if (valid) {
|
||||
axios.post('/adminUser/login', {
|
||||
userName: state.ruleForm.username || '',
|
||||
passwordMd5: md5(state.ruleForm.password)
|
||||
}).then(res => {
|
||||
localSet('token', res)
|
||||
window.location.href = '/'
|
||||
})
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
const resetForm = () => {
|
||||
loginForm.value.resetFields();
|
||||
}
|
||||
return {
|
||||
...toRefs(state),
|
||||
loginForm,
|
||||
submitForm,
|
||||
resetForm
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
/* background-image: linear-gradient(25deg, #077f7c, #3aa693, #5ecfaa, #7ffac2); */
|
||||
}
|
||||
.login-container {
|
||||
width: 420px;
|
||||
height: 500px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 21px 41px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.head {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 40px 0 20px 0;
|
||||
}
|
||||
.head img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.head .title {
|
||||
font-size: 28px;
|
||||
color: #1BAEAE;
|
||||
font-weight: bold;
|
||||
}
|
||||
.head .tips {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.login-form {
|
||||
width: 70%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.el-form--label-top .el-form-item__label {
|
||||
padding: 0;
|
||||
}
|
||||
.login-form .el-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
</style>
|
||||
3
admin/src/views/user/form.vue
Normal file
3
admin/src/views/user/form.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>User Form</div>
|
||||
</template>
|
||||
3
admin/src/views/user/index.vue
Normal file
3
admin/src/views/user/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>User Index</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user