admin base

This commit is contained in:
xiaomlove
2021-04-22 03:24:59 +08:00
parent b822536283
commit 92f22c9560
26 changed files with 891 additions and 75 deletions
+46 -1
View File
@@ -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",
+3 -1
View File
@@ -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

+172 -40
View File
@@ -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
View 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
View 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>
+2 -1
View File
@@ -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
View File
@@ -0,0 +1,50 @@
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(), // hash模式:createWebHashHistoryhistory模式: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
View 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
View 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
View 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
View File
@@ -0,0 +1,3 @@
<template>
<div>Agent Allow Form</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<template>
<div>Agent Allow Index</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<template>
<div>Dashboard</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<template>
<div>Exam Form</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<template>
<div>Exam Index</div>
</template>
+128
View 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
View File
@@ -0,0 +1,3 @@
<template>
<div>User Form</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<template>
<div>User Index</div>
</template>
+7 -6
View File
@@ -5,10 +5,11 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasFactory, Notifiable;
use HasFactory, Notifiable, HasApiTokens;
public $timestamps = false;
@@ -31,7 +32,7 @@ class User extends Authenticatable
const CLASS_MODERATOR = "13";
const CLASS_ADMINISTRATOR = "14";
const CLASS_SYSOP = "15";
const CLASS_STAFFLEADER = "16";
const CLASS_STAFF_LEADER = "16";
public static $classes = [
self::CLASS_PEASANT => ['text' => 'Peasant'],
@@ -42,7 +43,7 @@ class User extends Authenticatable
self::CLASS_INSANE_USER => ['text' => 'Insane User'],
self::CLASS_VETERAN_USER => ['text' => 'Veteran User'],
self::CLASS_EXTREME_USER => ['text' => 'Extreme User'],
self::CLASS_ULTIMATE_USER => ['text' => 'Eltimate User'],
self::CLASS_ULTIMATE_USER => ['text' => 'Ultimate User'],
self::CLASS_NEXUS_MASTER => ['text' => 'Nexus Master'],
self::CLASS_VIP => ['text' => 'Vip'],
self::CLASS_RETIREE => ['text' => 'Retiree'],
@@ -50,10 +51,10 @@ class User extends Authenticatable
self::CLASS_MODERATOR => ['text' => 'Moderator'],
self::CLASS_ADMINISTRATOR => ['text' => 'Administrator'],
self::CLASS_SYSOP => ['text' => 'Sysop'],
self::CLASS_STAFFLEADER => ['text' => 'Staff Leader'],
self::CLASS_STAFF_LEADER => ['text' => 'Staff Leader'],
];
public function getClassTextAttribute()
public function getClassTextAttribute(): string
{
return self::$classes[$this->class]['text'] ?? '';
}
@@ -66,7 +67,7 @@ class User extends Authenticatable
* @param \DateTimeInterface $date
* @return string
*/
protected function serializeDate(\DateTimeInterface $date)
protected function serializeDate(\DateTimeInterface $date): string
{
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
}
@@ -0,0 +1,7 @@
<?php
namespace App\Repositories;
class AuthenticateRepository extends BaseRepository
{
}
+8 -7
View File
@@ -23,17 +23,18 @@
},
"require": {
"php": "^7.3|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"laravel/framework": "^8.12",
"laravel/tinker": "^2.5",
"ext-gd": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-mysqli": "*",
"ext-json": "*",
"swiftmailer/swiftmailer": "^6.2",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "~6.0",
"imdbphp/imdbphp": "^6.4"
"imdbphp/imdbphp": "^6.4",
"laravel/framework": "^8.12",
"laravel/sanctum": "^2.10",
"laravel/tinker": "^2.5",
"swiftmailer/swiftmailer": "^6.2"
},
"require-dev": {
"facade/ignition": "^2.5",
Generated
+74 -4
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "99863a7fe1f8432a8d7f4e39f28eb77e",
"content-hash": "1e34544d001a98aace85e50adb9ef74e",
"packages": [
{
"name": "asm89/stack-cors",
@@ -1104,6 +1104,76 @@
],
"time": "2021-03-30T21:34:17+00:00"
},
{
"name": "laravel/sanctum",
"version": "v2.10.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
"reference": "a08cfee365c6b6df3e91c8f43b92f7163ffc8a94"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/sanctum/zipball/a08cfee365c6b6df3e91c8f43b92f7163ffc8a94",
"reference": "a08cfee365c6b6df3e91c8f43b92f7163ffc8a94",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"illuminate/contracts": "^6.9|^7.0|^8.0",
"illuminate/database": "^6.9|^7.0|^8.0",
"illuminate/support": "^6.9|^7.0|^8.0",
"php": "^7.2|^8.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.0|^5.0|^6.0",
"phpunit/phpunit": "^8.0|^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
},
"laravel": {
"providers": [
"Laravel\\Sanctum\\SanctumServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Laravel\\Sanctum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.",
"keywords": [
"auth",
"laravel",
"sanctum"
],
"support": {
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
"time": "2021-04-20T16:20:46+00:00"
},
{
"name": "laravel/tinker",
"version": "v2.6.1",
@@ -7572,10 +7642,10 @@
"platform": {
"php": "^7.3|^8.0",
"ext-gd": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-mysqli": "*",
"ext-json": "*"
"ext-mysqli": "*"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"
"plugin-api-version": "2.0.0"
}
+50
View File
@@ -0,0 +1,50 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,'.parse_url(env('APP_URL'), PHP_URL_HOST)
)),
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. If this value is null, personal access tokens do
| not expire. This won't tweak the lifetime of first-party sessions.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],
];
@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
}
+15 -15
View File
@@ -369,7 +369,7 @@ function format_comment($text, $strip_html = true, $xssclean = false, $newtab =
return $s;
}
function highlight($search,$subject,$hlstart='<b><font class="striking">',$hlend="</font></b>")
function highlight($search,$subject,$hlstart='<b><font class="striking">',$hlend="</font></b>")
{
$srchlen=strlen($search); // lenght of searched string
@@ -408,7 +408,7 @@ function get_user_class_name($class, $compact = false, $b_colored = false, $I18N
}
$this_lang_functions = $current_user_lang_functions;
}
$class_name = "";
switch ($class)
{
@@ -431,7 +431,7 @@ function get_user_class_name($class, $compact = false, $b_colored = false, $I18N
case UC_SYSOP: {$class_name = $this_lang_functions['text_sysops']; break;}
case UC_STAFFLEADER: {$class_name = $this_lang_functions['text_staff_leader']; break;}
}
switch ($class)
{
case UC_PEASANT: {$class_name_color = $en_lang_functions['text_peasant']; break;}
@@ -453,7 +453,7 @@ function get_user_class_name($class, $compact = false, $b_colored = false, $I18N
case UC_SYSOP: {$class_name_color = $en_lang_functions['text_sysops']; break;}
case UC_STAFFLEADER: {$class_name_color = $en_lang_functions['text_staff_leader']; break;}
}
$class_name = ( $compact == true ? str_replace(" ", "",$class_name) : $class_name);
if ($class_name) return ($b_colored == true ? "<b class='" . str_replace(" ", "",$class_name_color) . "_Name'>" . $class_name . "</b>" : $class_name);
}
@@ -981,12 +981,12 @@ function begin_compose($title = "",$type="new", $body="", $hassubject=true, $sub
if ($title)
print("<h1 align=\"center\">".$title."</h1>");
switch ($type){
case 'new':
case 'new':
{
$framename = $lang_functions['text_new'];
break;
}
case 'reply':
case 'reply':
{
$framename = $lang_functions['text_reply'];
break;
@@ -1117,7 +1117,7 @@ function get_torrent_2_user_value($user_snatched_arr)
}
else // torrent already deleted, half blind guess, be conservative
{
if($user_snatched_arr['finished'] == 'no' && $user_snatched_arr['uploaded'] > 0 && $user_snatched_arr['downloaded'] == 0) // possibly owner
{
$torrent_2_user_value *= 0.55; //conservative
@@ -2095,7 +2095,7 @@ function validlang($langid) {
function get_if_restricted_is_open()
{
global $sptime;
global $sptime;
// it's sunday
if($sptime == 'yes' && (date("w",time()) == '0' || (date("w",time()) == 6) && (date("G",time()) >=12 && date("G",time()) <=23)))
{
@@ -2256,7 +2256,7 @@ function stdhead($title = "", $msgalert = true, $script = "", $place = "")
global $Advertisement;
$Cache->setLanguage($CURLANGDIR);
$Advertisement = new ADVERTISEMENT($CURUSER['id']);
$cssupdatedate = $cssdate_tweak;
// Variable for Start Time
@@ -2379,7 +2379,7 @@ if ($enabledonation == 'yes'){?>
<tr><td id="nav_block" class="text" align="center">
<?php if (!$CURUSER) { ?>
<a href="login.php"><font class="big"><b><?php echo $lang_functions['text_login'] ?></b></font></a> / <a href="signup.php"><font class="big"><b><?php echo $lang_functions['text_signup'] ?></b></font></a>
<?php }
<?php }
else {
begin_main_frame();
menu ();
@@ -2432,7 +2432,7 @@ else {
$unread = get_row_count("messages","WHERE receiver=" . sqlesc($CURUSER["id"]) . " AND unread='yes'");
$Cache->cache_value('user_'.$CURUSER["id"].'_unread_message_count', $unread, 60);
}
$inboxpic = "<img class=\"".($unread ? "inboxnew" : "inbox")."\" src=\"pic/trans.gif\" alt=\"inbox\" title=\"".($unread ? $lang_functions['title_inbox_new_messages'] : $lang_functions['title_inbox_no_new_messages'])."\" />";
$attend_desk = new Attendance($CURUSER['id']);
$attendance = $attend_desk->check();
@@ -3269,7 +3269,7 @@ foreach ($rows as $row)
else
print("<td class=\"rowfollow nowrap\">".$lang_functions['text_none']."</td>\n");
}
if ($CURUSER['showcomnum'] != 'no')
{
print("<td class=\"rowfollow\">");
@@ -3675,7 +3675,7 @@ function getimdb($imdb_id, $cache_stamp, $mode = 'minor')
$tagline = $movie->tagline ();
switch ($mode)
{
case 'minor' :
case 'minor' :
{
$autodata = "<font class=\"big\"><b>".$title."</b></font> (".$year.") <br /><strong><font color=\"DarkRed\">".$lang_functions['text_imdb'].": </font></strong>".$imdbrating." <strong><font color=\"DarkRed\">".$lang_functions['text_country'].": </font></strong>".$countries." <strong><font color=\"DarkRed\">".$lang_functions['text_genres'].": </font></strong>".$genres."<br />".$director_or_creator."<strong><font color=\"DarkRed\"> ".$lang_functions['text_starring'].": </font></strong>".$casts."<br /><p><strong>".$tagline."</strong></p>";
break;
@@ -3724,7 +3724,7 @@ $smallth
}
return $autodata;
}
case "2" :
case "2" :
{
return false;
break;
@@ -4118,7 +4118,7 @@ function set_forum_moderators($name, $forumid, $limit=3){
}
function get_plain_username($id){
$row = get_user_row($id);
$row = get_user_row($id);
if ($row)
$username = $row['username'];
else $username = "";