初始化项目
4
.browserslistrc
Normal file
@@ -0,0 +1,4 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
not ie 11
|
2
.env.development
Normal file
@@ -0,0 +1,2 @@
|
||||
VUE_APP_API_BASE_URL='http://beta.admin.pekolive.com'
|
||||
VUE_APP_DEBUG_MODE=true
|
2
.env.production
Normal file
@@ -0,0 +1,2 @@
|
||||
VUE_APP_API_BASE_URL=http://admin.pekolive.com
|
||||
VUE_APP_DEBUG_MODE=false
|
19
.eslintrc.js
Normal file
@@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
jquery: true
|
||||
},
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended'
|
||||
],
|
||||
parserOptions: {
|
||||
parser: '@babel/eslint-parser'
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-unused-vars': 'off'
|
||||
}
|
||||
}
|
23
.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
24
README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# piko-admin-h5
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
5
babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
19
jsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
12821
package-lock.json
generated
Normal file
45
package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "piko-admin-h5",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve --mode development",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"admin-lte": "^2.3.2",
|
||||
"axios": "^1.5.0",
|
||||
"bootstrap": "^3.3.5",
|
||||
"bootstrap-datepicker": "^1.10.0",
|
||||
"bootstrap-multiselect": "^0.9.15",
|
||||
"bootstrap-select": "^1.13.18",
|
||||
"bootstrap-table": "^1.10.1",
|
||||
"core-js": "^3.8.3",
|
||||
"eonasdan-bootstrap-datetimepicker": "^4.17.49",
|
||||
"font-awesome": "^4.6.3",
|
||||
"ionicons": "^2.0.1",
|
||||
"jquery.md5": "^1.0.0",
|
||||
"knockout": "^3.5.1",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^11.1.3",
|
||||
"node-sass": "^9.0.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"sass": "^1.67.0",
|
||||
"sass-loader": "^13.3.2",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
40
public/index.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/bootstrap-combobox/1.1.8/css/bootstrap-combobox.css">
|
||||
<link rel="stylesheet"
|
||||
href="https://cdn.bootcdn.net/ajax/libs/jQuery-Validation-Engine/2.6.2/validationEngine.jquery.css">
|
||||
<link rel="stylesheet"
|
||||
href="https://cdn.bootcdn.net/ajax/libs/bootstrap-multiselect/1.1.1/css/bootstrap-multiselect.css">
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-combobox/1.1.8/js/bootstrap-combobox.min.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/jQuery-Validation-Engine/2.6.2/jquery.validationEngine.js"></script>
|
||||
<script
|
||||
src="https://cdn.bootcdn.net/ajax/libs/jQuery-Validation-Engine/2.6.2/languages/jquery.validationEngine-zh_CN.js"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-multiselect/1.1.1/js/bootstrap-multiselect.min.js"></script>
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<title>
|
||||
<%= htmlWebpackPlugin.options.title %>
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
|
||||
</html>
|
18
src/App.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "app",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {},
|
||||
created() {},
|
||||
methods: {},
|
||||
computed: {}
|
||||
};
|
||||
</script>
|
8
src/api/common/menu.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
export function getMenuAll() {
|
||||
return request({
|
||||
url: '/admin/menu/getall',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
15
src/api/common/user.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
export function getUser(adminId) {
|
||||
return request({
|
||||
url: '/admin/user/getone?uid=' + adminId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return request({
|
||||
url: '/login/logout',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
BIN
src/assets/images/backgrounds/Thumbs.db
Normal file
BIN
src/assets/images/backgrounds/b1.jpg
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
src/assets/images/backgrounds/b2.jpg
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
src/assets/images/backgrounds/b3.jpg
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
src/assets/images/backgrounds/b4.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
src/assets/images/login_bg.png
Normal file
After Width: | Height: | Size: 150 B |
BIN
src/assets/images/logo.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/images/man.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
20
src/components/footer/index.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<footer class="main-footer">
|
||||
<div class="pull-right hidden-xs">
|
||||
<b>Version</b> 2.0.0
|
||||
</div>
|
||||
<strong>Copyright © 2023 <a href="">触海网络</a>.</strong> All rights
|
||||
reserved.
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FooterView',
|
||||
components: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
102
src/components/header/index.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<!-- Main Header -->
|
||||
<header class="main-header">
|
||||
<!-- Logo -->
|
||||
<a class="logo">
|
||||
<!-- mini logo for sidebar mini 50x50 pixels -->
|
||||
<span class="logo-mini"><b>P</b>K</span>
|
||||
<!-- logo for regular state and mobile devices -->
|
||||
<span class="logo-lg"><b>piko</b>管理系统</span>
|
||||
</a>
|
||||
<!-- Header Navbar: style can be found in header.less -->
|
||||
<nav class="navbar navbar-static-top" role="navigation">
|
||||
<!-- Sidebar toggle button-->
|
||||
<a class="sidebar-toggle" data-toggle="offcanvas" role="button">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
</a>
|
||||
<!-- Navbar Right Menu -->
|
||||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
<!-- User Account: style can be found in dropdown.less -->
|
||||
<li class="dropdown user user-menu">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" style="height:50px;">
|
||||
<img :src="avatar" class="user-image" :alt="username">
|
||||
<span class="hidden-xs"><span :text="username">{{ username }}</span></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<!-- User image -->
|
||||
<li class="user-header">
|
||||
<img :src="avatar" class="img-circle" :alt="username" />
|
||||
<p>
|
||||
<span :text="username">{{ username }}</span>
|
||||
<small>上次登录:<span
|
||||
:text="lastTime">{{ lastTime }}</span></small>
|
||||
</p>
|
||||
</li>
|
||||
<!-- Menu Footer-->
|
||||
<li class="user-footer">
|
||||
<div class="pull-right">
|
||||
<a @click="logout" class="btn btn-default btn-flat" id="signOut">退出</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<!-- Left side column. contains the logo and sidebar -->
|
||||
<aside class="main-sidebar">
|
||||
<!-- sidebar: style can be found in sidebar.less -->
|
||||
<section class="sidebar">
|
||||
<!-- Sidebar user panel -->
|
||||
<div class="user-panel">
|
||||
<div class="pull-left image">
|
||||
<img :src="avatar" class="img-circle" :alt="username">
|
||||
</div>
|
||||
<div class="pull-left info">
|
||||
<p><span :text="username">{{ username }}</span></p>
|
||||
<a><i class="fa fa-circle text-success"></i> Online</a>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="sidebar-menu" id="mainMenu">
|
||||
<li class="header">MAIN NAVIGATION</li>
|
||||
</ul>
|
||||
</section>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
import store from '@/store';
|
||||
|
||||
export default {
|
||||
name: 'HeaderView',
|
||||
data() {
|
||||
return {
|
||||
username: "",
|
||||
avatar: "",
|
||||
lastTime: ""
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getUser();
|
||||
this.username = store.getters.username;
|
||||
this.avatar = store.getters.avatar;
|
||||
this.lastTime = store.getters.lastTime;
|
||||
},
|
||||
methods: {
|
||||
async getUser() {
|
||||
await store.dispatch('getUser', store.getters.adminId);
|
||||
},
|
||||
logout() {
|
||||
store.dispatch('logout');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
147
src/components/maintainer/index.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<!-- Left side column. contains the logo and sidebar -->
|
||||
<aside class="main-sidebar" style="height: 100%; overflow: hidden; overflow: scroll;">
|
||||
<!-- sidebar: style can be found in sidebar.less -->
|
||||
<section class="sidebar">
|
||||
<!-- Sidebar user panel (optional) -->
|
||||
<div class="user-panel">
|
||||
<div class="pull-left image">
|
||||
<img :src="avatar" class="img-circle" :alt="username">
|
||||
</div>
|
||||
<div class="pull-left info">
|
||||
<p>{{ username }}</p>
|
||||
<!-- Status -->
|
||||
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- search form (Optional) -->
|
||||
<form method="get" class="sidebar-form" onsubmit="return false;">
|
||||
<div class="input-group">
|
||||
<input type="text" name="q" class="form-control" placeholder="Search...">
|
||||
<span class="input-group-btn">
|
||||
<button name="search" id="search-btn" class="btn btn-flat" @click="search">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<!-- /.search form -->
|
||||
<!-- Sidebar Menu -->
|
||||
<ul class="sidebar-menu">
|
||||
<li class="header">主导航</li>
|
||||
<!-- Optionally, you can add icons to the links -->
|
||||
<li v-for="(parent, parentIndex) in parentMenus" :key="parent" :data-index="parentIndex" class="treeview">
|
||||
<a>
|
||||
<i :class="[parent.icon ? parent.icon : 'fa fa-link']"></i>
|
||||
<span>{{ parent.name }}</span>
|
||||
<span class="label pull-right bg-yellow" id='`ic${parent.id}`'>
|
||||
{{ getChildLength(parent.id) }}
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu" id='`menu${parent.id}`'>
|
||||
<li v-for="(child, childIndex) in getChilds(parent.id)" :key="child" :data-index="childIndex">
|
||||
<a :data-url="child.path" @click="handleClick(child)">
|
||||
<i :class="[child.icon && child.icon != '' ? child.icon : 'fa fa-circle-o text-yellow']"></i>
|
||||
<span>{{ child.name }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- /.sidebar-menu -->
|
||||
</section>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper" style="height: 100%;">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header" :style="[childMenu.name && childMenu.name != '' ? 'display:block;' : 'display:none;']">
|
||||
<h1>
|
||||
{{ childMenu.name }}
|
||||
<small>{{ childMenu.description }}</small>
|
||||
</h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#"><i class="fa fa-dashboard"></i> {{ childMenu.parentName }}</a></li>
|
||||
<li class="active">{{ childMenu.name }}</li>
|
||||
</ol>
|
||||
</section>
|
||||
<!-- Main content -->
|
||||
<section class="content" style="height: 100%; overflow: hidden; overflow: scroll;">
|
||||
<!-- Your Page Content Here -->
|
||||
<component :is="componentName"></component>
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store';
|
||||
|
||||
import { notifyNotice } from '@/utils/notify';
|
||||
|
||||
export default {
|
||||
name: 'MaintainerView',
|
||||
data() {
|
||||
return {
|
||||
componentName: "",
|
||||
username: "",
|
||||
avatar: "",
|
||||
parentMenus: [],
|
||||
childMenus: [],
|
||||
childMenu: {
|
||||
name: "",
|
||||
parentName: "",
|
||||
description: "",
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
notifyNotice();
|
||||
this.getMenu();
|
||||
this.username = store.getters.username;
|
||||
this.avatar = store.getters.avatar;
|
||||
this.parentMenus = store.getters.parentMenus;
|
||||
this.childMenus = store.getters.childMenus;
|
||||
},
|
||||
methods: {
|
||||
async getMenu() {
|
||||
await store.dispatch('getMenu');
|
||||
},
|
||||
getChilds(parentId) {
|
||||
return this.childMenus.filter(v => v.parentid == parentId);
|
||||
},
|
||||
getChildLength(parentId) {
|
||||
return this.childMenus.filter(v => v.parentid == parentId).length;
|
||||
},
|
||||
handleClick(menu) {
|
||||
this.childMenu.name = menu.name;
|
||||
this.childMenu.parentName = menu.parentstr;
|
||||
this.childMenu.description = menu.description;
|
||||
store.dispatch('getViewComponent', menu.path).then(componentName => {
|
||||
this.componentName = componentName;
|
||||
});
|
||||
},
|
||||
search() {
|
||||
let text = $("input[type='text']").val();
|
||||
this.childMenus = store.getters.childMenus.filter(v => v.name.indexOf(text) >= 0);
|
||||
if (!this.childMenus.length || this.childMenus.length == 0) {
|
||||
this.parentMenus = store.getters.parentMenus.filter(v => v.name.indexOf(text) >= 0);
|
||||
} else {
|
||||
let parentIds = this.childMenus.map(v => v.parentid);
|
||||
let parentMenus = store.getters.parentMenus.filter(v => v.name.indexOf(text) >= 0);
|
||||
if (parentMenus && parentMenus.length > 0) {
|
||||
parentMenus.forEach(v => {
|
||||
parentIds.push(v.id);
|
||||
});
|
||||
}
|
||||
this.parentMenus = store.getters.parentMenus.filter(v1 => parentIds.filter(v2 => v1.id == v2).length > 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import '../../css/main.css';
|
||||
</style>
|
8
src/constants/global.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
KEY: "piko",
|
||||
EXCLUDES: [
|
||||
"/login/login.action",
|
||||
"/login/sendSmsCode.action",
|
||||
],
|
||||
NEED_LOGOUT: "needLogout",
|
||||
};
|
216
src/css/login.css
Normal file
@@ -0,0 +1,216 @@
|
||||
@charset "utf-8";
|
||||
|
||||
/* CSS Document */
|
||||
.main_box {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -160px;
|
||||
margin-left: -250px;
|
||||
padding: 30px;
|
||||
width: 500px;
|
||||
height: 320px;
|
||||
background: url(../assets/images/login_bg.png);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.main_box .setting {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.main_box .setting a {
|
||||
color: #FF6600;
|
||||
}
|
||||
|
||||
.main_box .setting a:hover {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.login_logo {
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login_logo img {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.login_msg {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.login_form {
|
||||
padding-top: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.login_box .form-control {
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
width: auto;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.login_box .form-control.x319 {
|
||||
width: 319px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
outline: none;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.login_box .form-control.x164 {
|
||||
width: 164px;
|
||||
}
|
||||
|
||||
.login_box .form-group {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login_box .form-group label.t {
|
||||
/*width: 120px;*/
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.login_box .form-group.space {
|
||||
padding-top: 15px;
|
||||
border-top: 1px #FFF dotted;
|
||||
}
|
||||
|
||||
.login_box .form-group img {
|
||||
margin-top: 1px;
|
||||
height: 32px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.login_box .m {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 动态背景设置 */
|
||||
#bubble-wrapper {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(to bottom right, #00BFFF, #00FFFF);
|
||||
}
|
||||
|
||||
#bubble-wrapper li {
|
||||
position: absolute;
|
||||
bottom: -160px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
list-style: none;
|
||||
animation: square 15s infinite;
|
||||
transition-timing-function: linear;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(1) {
|
||||
left: 10%;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(2) {
|
||||
left: 20%;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
animation-delay: 2s;
|
||||
animation-duration: 7s;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(3) {
|
||||
left: 25%;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(4) {
|
||||
left: 40%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
animation-duration: 8s;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(5) {
|
||||
left: 70%;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(6) {
|
||||
left: 80%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
animation-delay: 3s;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(7) {
|
||||
left: 32%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(8) {
|
||||
left: 55%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
animation-delay: 4s;
|
||||
animation-duration: 15s;
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(9) {
|
||||
left: 25%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
animation-delay: 2s;
|
||||
animation-duration: 12s;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
#bubble-wrapper li:nth-child(10) {
|
||||
left: 85%;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
animation-delay: 5s;
|
||||
}
|
||||
|
||||
@keyframes square {
|
||||
0% {
|
||||
opacity: 0.5;
|
||||
transform: translateY(0px) rotate(45deg);
|
||||
}
|
||||
|
||||
25% {
|
||||
opacity: 0.75;
|
||||
transform: translateY(-400px) rotate(90deg)
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: translateY(-600px) rotate(135deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(-1000px) rotate(180deg);
|
||||
}
|
||||
}
|
9
src/css/main.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@charset "utf-8";
|
||||
|
||||
.tbar {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.tbar span {
|
||||
cursor: pointer;
|
||||
}
|
99
src/css/supersized.css
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
|
||||
Supersized - Fullscreen Slideshow jQuery Plugin
|
||||
Version : 3.2.7
|
||||
Site : www.buildinternet.com/project/supersized
|
||||
|
||||
Author : Sam Dunn
|
||||
Company : One Mighty Roar (www.onemightyroar.com)
|
||||
License : MIT License / GPL License
|
||||
|
||||
*/
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #111;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#supersized {
|
||||
display: block;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
z-index: -999;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#supersized img {
|
||||
width: auto;
|
||||
height: auto;
|
||||
position: relative;
|
||||
display: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#supersized.speed img {
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
image-rendering: -moz-crisp-edges;
|
||||
}
|
||||
|
||||
/*Speed*/
|
||||
|
||||
#supersized.quality img {
|
||||
-ms-interpolation-mode: bicubic;
|
||||
image-rendering: optimizeQuality;
|
||||
}
|
||||
|
||||
/*Quality*/
|
||||
|
||||
#supersized li {
|
||||
display: block;
|
||||
list-style: none;
|
||||
z-index: -30;
|
||||
position: fixed;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
#supersized a {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#supersized li.prevslide {
|
||||
z-index: -20;
|
||||
}
|
||||
|
||||
#supersized li.activeslide {
|
||||
z-index: -10;
|
||||
}
|
||||
|
||||
#supersized li.image-loading img {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#supersized li.prevslide img,
|
||||
#supersized li.activeslide img {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#supersized img {
|
||||
max-width: none !important
|
||||
}
|
35
src/main.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
|
||||
import 'jquery.md5'
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import 'bootstrap/dist/js/bootstrap.min.js'
|
||||
|
||||
import 'font-awesome/css/font-awesome.min.css'
|
||||
import 'ionicons/css/ionicons.min.css'
|
||||
|
||||
import 'admin-lte/dist/css/AdminLTE.min.css'
|
||||
import 'admin-lte/dist/css/skins/skin-blue.min.css'
|
||||
import 'admin-lte/dist/js/app.min.js'
|
||||
|
||||
import 'bootstrap-table/dist/bootstrap-table.css'
|
||||
import 'bootstrap-table/dist/bootstrap-table.js'
|
||||
import 'bootstrap-table/dist/locale/bootstrap-table-zh-CN.js'
|
||||
import 'bootstrap-table/dist/extensions/editable/bootstrap-table-editable.js'
|
||||
|
||||
import 'bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css'
|
||||
import 'bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js'
|
||||
import 'bootstrap-datepicker/dist/locales/bootstrap-datepicker.zh-CN.min.js'
|
||||
|
||||
import 'eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css'
|
||||
import 'eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js'
|
||||
|
||||
import 'bootstrap-select/dist/css/bootstrap-select.css'
|
||||
import 'bootstrap-select/dist/js/bootstrap-select.min.js'
|
||||
|
||||
import components from '@/utils/components.js'
|
||||
|
||||
createApp(App).use(store).use(router).use(components).mount('#app')
|
28
src/router/index.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import HomeView from '../views/home/index.vue'
|
||||
import LoginView from '../views/login/index.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'login',
|
||||
component: LoginView
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: '/discoveryAdmin',
|
||||
name: 'discoveryAdmin',
|
||||
component: () => import('../views/discovery/DiscoveryAdminView.vue')
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
25
src/store/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { createStore } from 'vuex'
|
||||
import user from './modules/user'
|
||||
import menu from './modules/menu'
|
||||
|
||||
export default createStore({
|
||||
state: {
|
||||
},
|
||||
getters: {
|
||||
adminUser: state => state.user,
|
||||
adminId: state => state.user.adminId,
|
||||
username: state => state.user.username,
|
||||
avatar: state => state.user.avatar,
|
||||
lastTime: state => state.user.lastTime,
|
||||
parentMenus: state => state.menu.parentMenus,
|
||||
childMenus: state => state.menu.childMenus,
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
user,
|
||||
menu,
|
||||
}
|
||||
})
|
61
src/store/modules/menu.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { getMenuAll } from '@/api/common/menu';
|
||||
import { setStore, getStore } from '@/utils/store';
|
||||
import { toCamelCase, upperFirst } from '@/utils/string';
|
||||
|
||||
export default {
|
||||
state: {
|
||||
parentMenus: getStore({ name: 'parent_menus' }) || [],
|
||||
childMenus: getStore({ name: 'child_menus' }) || [],
|
||||
},
|
||||
mutations: {
|
||||
setParentMenus(state, parentMenus) {
|
||||
state.parentMenus = parentMenus;
|
||||
setStore({
|
||||
name: "parent_menus",
|
||||
content: state.parentMenus,
|
||||
type: "session"
|
||||
});
|
||||
},
|
||||
setChildMenus(state, childMenus) {
|
||||
state.childMenus = childMenus;
|
||||
setStore({
|
||||
name: "child_menus",
|
||||
content: state.childMenus,
|
||||
type: "session"
|
||||
});
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async getMenu({ commit }) {
|
||||
const res = await getMenuAll();
|
||||
if (res) {
|
||||
const sortBy = (a, b) => {
|
||||
if (a.showorder > b.showorder) {
|
||||
return -1;
|
||||
} else if (a.showorder < b.showorder) {
|
||||
return 1;
|
||||
} else {
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
};
|
||||
if (res.parents && res.parents.length > 0) {
|
||||
const parents = res.parents.sort(sortBy);
|
||||
commit('setParentMenus', parents);
|
||||
}
|
||||
if (res.childs && res.childs.length > 0) {
|
||||
const childs = res.childs.sort(sortBy);
|
||||
commit('setChildMenus', childs);
|
||||
}
|
||||
}
|
||||
},
|
||||
getViewComponent(context, path) {
|
||||
let component = "";
|
||||
if (path && path.endsWith('.html')) {
|
||||
const pathArray = path.split('/');
|
||||
const routeName = toCamelCase(pathArray[pathArray.length - 1].replace('.html', ''));
|
||||
component = upperFirst(routeName) + 'View';
|
||||
}
|
||||
return component;
|
||||
}
|
||||
},
|
||||
};
|
85
src/store/modules/user.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import router from '@/router';
|
||||
import { setStore, getStore } from '@/utils/store';
|
||||
import { getUser, logout } from '@/api/common/user';
|
||||
import { dateFormat } from '@/utils/date';
|
||||
|
||||
import avatar from '@/assets/images/man.jpg';
|
||||
|
||||
export default {
|
||||
state: {
|
||||
adminId: getStore({ name: 'admin_id' }) || 0,
|
||||
username: getStore({ name: 'username' }) || "",
|
||||
avatar: getStore({ name: 'avatar' }) || "",
|
||||
lastTime: getStore({ name: 'last_time' }) || "",
|
||||
},
|
||||
mutations: {
|
||||
updateUser(state, user) {
|
||||
if (user.adminId) {
|
||||
console.log(user.adminId);
|
||||
state.adminId = user.adminId;
|
||||
setStore({
|
||||
name: "admin_id",
|
||||
content: state.adminId,
|
||||
type: "session"
|
||||
});
|
||||
}
|
||||
if (user.username) {
|
||||
console.log(user.username);
|
||||
state.username = user.username;
|
||||
setStore({
|
||||
name: "username",
|
||||
content: state.username,
|
||||
type: "session"
|
||||
});
|
||||
}
|
||||
let userAvatar = user.avatar;
|
||||
if (userAvatar) {
|
||||
if (userAvatar != "") {
|
||||
userAvatar = userAvatar.startsWith('https') || userAvatar.startsWith('http') || avatar;
|
||||
}
|
||||
state.avatar = userAvatar;
|
||||
setStore({
|
||||
name: "avatar",
|
||||
content: state.avatar,
|
||||
type: "session"
|
||||
});
|
||||
}
|
||||
if (user.lastTime) {
|
||||
state.lastTime = user.lastTime;
|
||||
setStore({
|
||||
name: "last_time",
|
||||
content: state.lastTime,
|
||||
type: "session"
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async getUser({ commit }, adminId) {
|
||||
const res = await getUser(adminId);
|
||||
var data = res.entity || {};
|
||||
commit("updateUser", {
|
||||
avatar: data.headimg,
|
||||
lastTime: dateFormat(new Date(data.lastlogin))
|
||||
});
|
||||
return data;
|
||||
},
|
||||
logout({ commit }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout()
|
||||
.then(res => {
|
||||
commit("updateUser", {
|
||||
adminId: 0,
|
||||
username: "",
|
||||
avatar: "",
|
||||
lastTime: ""
|
||||
});
|
||||
resolve(res);
|
||||
router.push("/");
|
||||
}).catch(() => {
|
||||
reject();
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
195
src/utils/ajaxfileupload.js
Normal file
@@ -0,0 +1,195 @@
|
||||
jQuery.extend({
|
||||
handleError: function (s, xhr, status, e) {
|
||||
// If a local callback was specified, fire it
|
||||
if (s.error) {
|
||||
s.error.call(s.context || s, xhr, status, e);
|
||||
}
|
||||
|
||||
// Fire the global callback
|
||||
if (s.global) {
|
||||
(s.context ? jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e]);
|
||||
}
|
||||
},
|
||||
createUploadIframe: function (id, uri) {
|
||||
//create frame
|
||||
var frameId = 'jUploadFrame' + id;
|
||||
var io;
|
||||
if (window.ActiveXObject) {
|
||||
io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
|
||||
if (typeof uri == 'boolean') {
|
||||
io.src = 'javascript:false';
|
||||
}
|
||||
else if (typeof uri == 'string') {
|
||||
io.src = uri;
|
||||
}
|
||||
}
|
||||
else {
|
||||
io = document.createElement('iframe');
|
||||
io.id = frameId;
|
||||
io.name = frameId;
|
||||
}
|
||||
io.style.position = 'absolute';
|
||||
io.style.top = '-1000px';
|
||||
io.style.left = '-1000px';
|
||||
|
||||
document.body.appendChild(io);
|
||||
|
||||
return io
|
||||
},
|
||||
createUploadForm: function (id, fileElementId) {
|
||||
//create form
|
||||
var formId = 'jUploadForm' + id;
|
||||
var fileId = 'jUploadFile' + id;
|
||||
var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
|
||||
var oldElement = $('#' + fileElementId);
|
||||
var newElement = $(oldElement).clone();
|
||||
$(oldElement).attr('id', fileId);
|
||||
$(oldElement).before(newElement);
|
||||
$(oldElement).appendTo(form);
|
||||
//set attributes
|
||||
$(form).css('position', 'absolute');
|
||||
$(form).css('top', '-1200px');
|
||||
$(form).css('left', '-1200px');
|
||||
$(form).appendTo('body');
|
||||
return form;
|
||||
},
|
||||
|
||||
ajaxFileUpload: function (s) {
|
||||
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
|
||||
s = jQuery.extend({}, jQuery.ajaxSettings, s);
|
||||
var id = s.fileElementId;
|
||||
var form = jQuery.createUploadForm(id, s.fileElementId);
|
||||
var frameId = 'jUploadFrame' + id;
|
||||
var formId = 'jUploadForm' + id;
|
||||
// Watch for a new set of requests
|
||||
if (s.global && !jQuery.active++) {
|
||||
jQuery.event.trigger("ajaxStart");
|
||||
}
|
||||
var requestDone = false;
|
||||
// Create the request object
|
||||
var xml = {}
|
||||
if (s.global)
|
||||
jQuery.event.trigger("ajaxSend", [xml, s]);
|
||||
// Wait for a response to come back
|
||||
var uploadCallback = function (isTimeout) {
|
||||
var io = document.getElementById(frameId);
|
||||
try {
|
||||
if (io.contentWindow) {
|
||||
xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
|
||||
xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
|
||||
|
||||
} else if (io.contentDocument) {
|
||||
xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
|
||||
xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
|
||||
}
|
||||
} catch (e) {
|
||||
jQuery.handleError(s, xml, null, e);
|
||||
}
|
||||
if (xml || isTimeout == "timeout") {
|
||||
requestDone = true;
|
||||
var status;
|
||||
try {
|
||||
status = isTimeout != "timeout" ? "success" : "error";
|
||||
// Make sure that the request was successful or notmodified
|
||||
if (status != "error") {
|
||||
// process the data (runs the xml through httpData regardless of callback)
|
||||
var data = jQuery.uploadHttpData(xml, s.dataType);
|
||||
// If a local callback was specified, fire it and pass it the data
|
||||
if (s.success)
|
||||
s.success(data, status);
|
||||
|
||||
// Fire the global callback
|
||||
if (s.global)
|
||||
jQuery.event.trigger("ajaxSuccess", [xml, s]);
|
||||
} else
|
||||
jQuery.handleError(s, xml, status);
|
||||
} catch (e) {
|
||||
status = "error";
|
||||
jQuery.handleError(s, xml, status, e);
|
||||
}
|
||||
|
||||
// The request was completed
|
||||
if (s.global)
|
||||
jQuery.event.trigger("ajaxComplete", [xml, s]);
|
||||
|
||||
// Handle the global AJAX counter
|
||||
if (s.global && ! --jQuery.active)
|
||||
jQuery.event.trigger("ajaxStop");
|
||||
|
||||
// Process result
|
||||
if (s.complete)
|
||||
s.complete(xml, status);
|
||||
|
||||
jQuery(io).unbind()
|
||||
|
||||
setTimeout(function () {
|
||||
try {
|
||||
$(io).remove();
|
||||
$(form).remove();
|
||||
|
||||
} catch (e) {
|
||||
jQuery.handleError(s, xml, null, e);
|
||||
}
|
||||
|
||||
}, 100)
|
||||
|
||||
xml = null
|
||||
|
||||
}
|
||||
}
|
||||
// Timeout checker
|
||||
if (s.timeout > 0) {
|
||||
setTimeout(function () {
|
||||
// Check to see if the request is still happening
|
||||
if (!requestDone) uploadCallback("timeout");
|
||||
}, s.timeout);
|
||||
}
|
||||
try {
|
||||
form = $('#' + formId);
|
||||
$(form).attr('action', s.url);
|
||||
$(form).attr('method', 'POST');
|
||||
$(form).attr('target', frameId);
|
||||
if (form.encoding) {
|
||||
form.encoding = 'multipart/form-data';
|
||||
}
|
||||
else {
|
||||
form.enctype = 'multipart/form-data';
|
||||
}
|
||||
$(form).submit();
|
||||
|
||||
} catch (e) {
|
||||
jQuery.handleError(s, xml, null, e);
|
||||
}
|
||||
if (window.attachEvent) {
|
||||
document.getElementById(frameId).attachEvent('onload', uploadCallback);
|
||||
}
|
||||
else {
|
||||
document.getElementById(frameId).addEventListener('load', uploadCallback, false);
|
||||
}
|
||||
return { abort: function () { } };
|
||||
|
||||
},
|
||||
|
||||
uploadHttpData: function (r, type) {
|
||||
var data = !type;
|
||||
data = type == "xml" || data ? r.responseXML : r.responseText;
|
||||
// If the type is "script", eval it in global context
|
||||
if (type == "script")
|
||||
jQuery.globalEval(data);
|
||||
// Get the JavaScript object, if JSON is used.
|
||||
if (type == "json")
|
||||
data = r.responseText;
|
||||
var start = data.indexOf(">");
|
||||
if (start != -1) {
|
||||
var end = data.indexOf("<", start + 1);
|
||||
if (end != -1) {
|
||||
data = data.substring(start + 1, end);
|
||||
}
|
||||
}
|
||||
eval("data = " + data);
|
||||
// evaluate scripts within html
|
||||
if (type == "html")
|
||||
jQuery("<div>").html(data).evalScripts();
|
||||
return data;
|
||||
}
|
||||
})
|
42
src/utils/bootstrap-table-helper.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
export default {
|
||||
idstr: null,
|
||||
// 是否有且只选择了一项
|
||||
isSelectOne: function (idstr) {
|
||||
if ($(idstr).bootstrapTable('getSelections').length == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
//是否选择了至少一项
|
||||
hasSelectAny: function (idstr) {
|
||||
if ($(idstr).bootstrapTable('getSelections').length > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// 获取选择的一项
|
||||
getOneSelectItem: function (idstr) {
|
||||
return $(idstr).bootstrapTable('getSelections')[0];
|
||||
},
|
||||
// 已经选择的记录
|
||||
getAllSelectItems: function (idstr) {
|
||||
return $(idstr).bootstrapTable('getSelections');
|
||||
},
|
||||
getRowByUniqueId: function (idstr, id) {
|
||||
return $(idstr).bootstrapTable('getRowByUniqueId', id);
|
||||
},
|
||||
// 已选择的项数量
|
||||
selectLength: function (idstr) {
|
||||
return $(idstr).bootstrapTable('getSelections').length;
|
||||
},
|
||||
// 刷新
|
||||
doRefresh: function (idstr) {
|
||||
$(idstr).bootstrapTable('refresh');
|
||||
},
|
||||
unCheckAll: function (idstr) {
|
||||
$(idstr).bootstrapTable('uncheckAll');
|
||||
},
|
||||
doRefreshAndToPage1: function (idstr) {
|
||||
$(idstr).bootstrapTable('selectPage', 1);
|
||||
},
|
||||
}
|
14
src/utils/components.js
Normal file
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
install: function (Vue) {
|
||||
const files = require.context('@/views', true, /\.vue$/)
|
||||
let components = {};
|
||||
files.keys().forEach(key => {
|
||||
components[key.replace(/(\.\/|\.vue)/g, '')] = files(key).default;
|
||||
});
|
||||
Object.keys(components).forEach(item => {
|
||||
if (components[item].name) {
|
||||
Vue.component(components[item].name, components[item]);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
49
src/utils/date.js
Normal file
@@ -0,0 +1,49 @@
|
||||
export const calcDate = (date1, date2) => {
|
||||
var date3 = date2 - date1;
|
||||
var days = Math.floor(date3 / (24 * 3600 * 1000));
|
||||
// 计算天数后剩余的毫秒数
|
||||
var leave1 = date3 % (24 * 3600 * 1000);
|
||||
var hours = Math.floor(leave1 / (3600 * 1000));
|
||||
// 计算小时数后剩余的毫秒数
|
||||
var leave2 = leave1 % (3600 * 1000);
|
||||
var minutes = Math.floor(leave2 / (60 * 1000));
|
||||
// 计算分钟数后剩余的毫秒数
|
||||
var leave3 = leave2 % (60 * 1000);
|
||||
var seconds = Math.round(date3 / 1000);
|
||||
return {
|
||||
leave1,
|
||||
leave2,
|
||||
leave3,
|
||||
days: days,
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
seconds: seconds
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化
|
||||
*/
|
||||
export function dateFormat(date) {
|
||||
let format = 'yyyy-MM-dd hh:mm:ss';
|
||||
if (date != 'Invalid Date') {
|
||||
var o = {
|
||||
"M+": date.getMonth() + 1, //month
|
||||
"d+": date.getDate(), //day
|
||||
"h+": date.getHours(), //hour
|
||||
"m+": date.getMinutes(), //minute
|
||||
"s+": date.getSeconds(), //second
|
||||
"q+": Math.floor((date.getMonth() + 3) / 3), //quarter
|
||||
"S": date.getMilliseconds() //millisecond
|
||||
}
|
||||
if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
|
||||
(date.getFullYear() + "").substr(4 - RegExp.$1.length));
|
||||
for (var k in o)
|
||||
if (new RegExp("(" + k + ")").test(format))
|
||||
format = format.replace(RegExp.$1,
|
||||
RegExp.$1.length == 1 ? o[k] :
|
||||
("00" + o[k]).substr(("" + o[k]).length));
|
||||
return format;
|
||||
}
|
||||
return '';
|
||||
}
|
59
src/utils/notify.js
Normal file
@@ -0,0 +1,59 @@
|
||||
export const notifyNotice = () => {
|
||||
var notifyInterval;
|
||||
console.log(window.Notification.permission);
|
||||
if (window.Notification) {
|
||||
$.ajax({
|
||||
url: "/admin/dynamic/verify/notifySwitch.action",
|
||||
success: function (json) {
|
||||
if (json == 'true') {
|
||||
notifyInterval = setInterval(notify, 50000);
|
||||
console.log('notifyInterval : ' + notifyInterval);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('浏览器不支持Notification');
|
||||
}
|
||||
|
||||
function notify() {
|
||||
$.ajax({
|
||||
url: "/admin/dynamic/verify/notify.action",
|
||||
success: function (json) {
|
||||
if (json != null && json != "" && json != undefined && json != 'undefined') {
|
||||
var dynamicCount = json.dynamic;
|
||||
var voiceCount = json.voice;
|
||||
if ((dynamicCount != null && dynamicCount > 0) || (voiceCount != null && voiceCount > 0)) {
|
||||
if (Notification.permission == "granted") {
|
||||
popNotice(dynamicCount, voiceCount);
|
||||
} else if (Notification.permission != "denied") {
|
||||
Notification.requestPermission(function (permission) {
|
||||
console.log(permission);
|
||||
popNotice(dynamicCount, voiceCount);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function popNotice(dynamic, voice) {
|
||||
if (Notification.permission == "granted") {
|
||||
var bodyStr = '您有';
|
||||
if (dynamic) {
|
||||
bodyStr += '【' + dynamic + '】条待审核动态';
|
||||
}
|
||||
if (voice) {
|
||||
bodyStr += '【' + voice + '】条待审核声音瓶子';
|
||||
}
|
||||
var notification = new Notification("【66后台】系统推送", {
|
||||
body: bodyStr,
|
||||
type: 'info',
|
||||
offset: 100,
|
||||
});
|
||||
notification.onclick = function () {
|
||||
notification.close();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
49
src/utils/request.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import axios from "axios";
|
||||
import store from "@/store";
|
||||
import global from "@/constants/global";
|
||||
|
||||
const service = axios.create();
|
||||
|
||||
service.interceptors.request.use(config => {
|
||||
return config;
|
||||
}, error => {
|
||||
Promise.reject(error);
|
||||
});
|
||||
|
||||
service.interceptors.response.use(res => {
|
||||
userLogout(res.headers[global.NEED_LOGOUT]);
|
||||
return res.data;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
$.ajaxSetup({
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
beforeSend: function(xhr) {
|
||||
console.log(xhr);
|
||||
},
|
||||
complete: function(xhr) {
|
||||
userLogout(xhr.getResponseHeader(global.NEED_LOGOUT));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 强制退出
|
||||
*/
|
||||
function userLogout(needLogout) {
|
||||
try {
|
||||
if (global.NEED_LOGOUT == needLogout) {
|
||||
var win = window;
|
||||
while (win != win.top) {
|
||||
win = win.top;
|
||||
}
|
||||
store.dispatch("logout");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
export default service;
|
118
src/utils/store.js
Normal file
@@ -0,0 +1,118 @@
|
||||
import { validateNull } from '@/utils/validate';
|
||||
import global from '@/constants/global';
|
||||
|
||||
const keyName = global.KEY + '_';
|
||||
|
||||
/**
|
||||
* 存储localStorage
|
||||
*/
|
||||
export const setStore = (params = {}) => {
|
||||
let {
|
||||
name,
|
||||
content,
|
||||
type,
|
||||
} = params;
|
||||
name = keyName + name;
|
||||
let obj = {
|
||||
dataType: typeof (content),
|
||||
content: content,
|
||||
type: type,
|
||||
datetime: new Date().getTime()
|
||||
};
|
||||
if (type) window.sessionStorage.setItem(name, JSON.stringify(obj));
|
||||
else window.localStorage.setItem(name, JSON.stringify(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取localStorage
|
||||
*/
|
||||
export const getStore = (params = {}) => {
|
||||
let {
|
||||
name,
|
||||
debug
|
||||
} = params;
|
||||
name = keyName + name;
|
||||
let obj = {},
|
||||
content;
|
||||
obj = window.sessionStorage.getItem(name);
|
||||
if (validateNull(obj)) obj = window.localStorage.getItem(name);
|
||||
if (validateNull(obj)) return;
|
||||
try {
|
||||
obj = JSON.parse(obj);
|
||||
} catch {
|
||||
return obj;
|
||||
}
|
||||
if (debug) {
|
||||
return obj;
|
||||
}
|
||||
if (obj.dataType == 'string') {
|
||||
content = obj.content;
|
||||
} else if (obj.dataType == 'number') {
|
||||
content = Number(obj.content);
|
||||
} else if (obj.dataType == 'boolean') {
|
||||
content = eval(obj.content);
|
||||
} else if (obj.dataType == 'object') {
|
||||
content = obj.content;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除localStorage
|
||||
*/
|
||||
export const removeStore = (params = {}) => {
|
||||
let {
|
||||
name,
|
||||
type
|
||||
} = params;
|
||||
name = keyName + name;
|
||||
if (type) {
|
||||
window.sessionStorage.removeItem(name);
|
||||
} else {
|
||||
window.localStorage.removeItem(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部localStorage
|
||||
*/
|
||||
export const getAllStore = (params = {}) => {
|
||||
let list = [];
|
||||
let {
|
||||
type
|
||||
} = params;
|
||||
if (type) {
|
||||
for (let i = 0; i <= window.sessionStorage.length; i++) {
|
||||
list.push({
|
||||
name: window.sessionStorage.key(i),
|
||||
content: getStore({
|
||||
name: window.sessionStorage.key(i),
|
||||
type: 'session'
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i <= window.localStorage.length; i++) {
|
||||
list.push({
|
||||
name: window.localStorage.key(i),
|
||||
content: getStore({
|
||||
name: window.localStorage.key(i),
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空全部localStorage
|
||||
*/
|
||||
export const clearStore = (params = {}) => {
|
||||
let { type } = params;
|
||||
if (type) {
|
||||
window.sessionStorage.clear();
|
||||
} else {
|
||||
window.localStorage.clear();
|
||||
}
|
||||
}
|
22
src/utils/string.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 下划线转驼峰
|
||||
*/
|
||||
export function toCamelCase(str) {
|
||||
return str.replace(/_[a-z]/g, function (s) {
|
||||
return s.substring(1).toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 首字母大写
|
||||
*/
|
||||
export function upperFirst(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首字母小写
|
||||
*/
|
||||
export function lowerFirst(str) {
|
||||
return str.charAt(0).toLowerCase() + str.slice(1);
|
||||
}
|
20
src/utils/validate.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 判断是否为空
|
||||
*/
|
||||
export function validateNull(val) {
|
||||
if (typeof val === 'boolean') {
|
||||
return false;
|
||||
}
|
||||
if (typeof val === 'number') {
|
||||
return false;
|
||||
}
|
||||
if (val instanceof Array) {
|
||||
if (val.length == 0) return true;
|
||||
} else if (val instanceof Object) {
|
||||
if (JSON.stringify(val) === '{}') return true;
|
||||
} else {
|
||||
if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '') return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
5
src/views/AboutView.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<h1>This is an about page</h1>
|
||||
</div>
|
||||
</template>
|
766
src/views/discovery/DiscoveryAdminView.vue
Normal file
@@ -0,0 +1,766 @@
|
||||
<template>
|
||||
<section class="content">
|
||||
<div class="box box-primary">
|
||||
<div class="box-body">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1 id="itemTitle"></h1>
|
||||
</section>
|
||||
<!-- .content -->
|
||||
<div id="table"></div>
|
||||
<div id="toolbar">
|
||||
名称:<input type="text" class="input-sm" name="name" id="searchName">
|
||||
|
||||
上架:<select name="displayType" id="searchDisplayType" class="input-sm">
|
||||
<option value="0">--全部--</option>
|
||||
<option value="1">上架</option>
|
||||
<option value="2">下架</option>
|
||||
</select>
|
||||
app:
|
||||
<select name="searchAppId" id="searchAppId" class="input-m">
|
||||
<option value="">--全部--</option>
|
||||
</select>
|
||||
|
||||
跳转类型:<select name="jumpType" id="searchJumpType" class="input-sm">
|
||||
<option value="0">--全部--</option>
|
||||
<option value="1">跳转链接</option>
|
||||
<option value="2">跳转房间</option>
|
||||
<option value="3">跳转游戏</option>
|
||||
<option value="5">跳转App页面</option>
|
||||
</select>
|
||||
|
||||
<button id="btnSearch" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-search"></i>搜索
|
||||
</button>
|
||||
<button id="btnAdd" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-add"></i>增加
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--新增/编辑发现弹窗-->
|
||||
<div class="modal fade" id="discoveryModal" tabindex="-1" role="dialog" aria-labelledby="modalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||||
aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="discoveryModalLabel">新增</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-horizontal" id="discoveryForm">
|
||||
<input type="hidden" id="editId">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-sm-3 control-label">名称:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control validate[required]" name="name" id="name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">跳转类型:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="radio" name="jumpType" id="link" value="1">跳转链接
|
||||
<input type="radio" name="jumpType" id="room" value="2">跳转房间
|
||||
<input type="radio" name="jumpType" id="game" value="3">跳转游戏
|
||||
<input type="radio" name="jumpType" id="app" value="5">跳转App页面
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display:none" id="linkGroup">
|
||||
<label for="jumpLink" class="col-sm-3 control-label">跳转链接:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="link" id="jumpLink">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display:none" id="roomGroup">
|
||||
<label for="jumpRoom" class="col-sm-3 control-label">跳转房间:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="roomId" id="jumpRoom">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display:none" id="gameGroup">
|
||||
<label for="jumpGame" class="col-sm-3 control-label">跳转游戏:</label>
|
||||
<input type="hidden" id="gameId">
|
||||
<select name="jumpGame" id="jumpGame" class="col-sm-7 input-sm">
|
||||
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display:none" id="jumpAppGroup">
|
||||
|
||||
<label for="routerType" class="col-sm-3 control-label">跳转类型值:</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="col-sm-3 form-control" name="routerType" id="routerType">
|
||||
</div>
|
||||
|
||||
<label for="routerValue" class="col-sm-3 control-label">跳转参数值:</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="col-sm-3 form-control" name="routerValue" id="routerValue">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pic" class="col-sm-3 control-label">活动图片(大图):</label>
|
||||
<div class="col-sm-9">
|
||||
<img src="" id="picImage" style="width:250px;height:90px;" alt="">
|
||||
<input type="file" id="picFile" name="uploadFile"
|
||||
accept="image/gif,image/jpeg,image/jpg,image/png,image/svga">
|
||||
<button class="btn btn-success" type="button"
|
||||
onclick="uploadfile('picFile','picImage','pic','picInfo')">上传</button>
|
||||
<input type="hidden" id="pic" name="icon" class="form-control" />
|
||||
<span id="picInfo" style="color:red;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pic" class="col-sm-3 control-label">活动图片(小图):</label>
|
||||
<div class="col-sm-9">
|
||||
<img src="" id="picMinImage" style="width:250px;height:90px;" alt="">
|
||||
<input type="file" id="picMinFile" name="uploadFile"
|
||||
accept="image/gif,image/jpeg,image/jpg,image/png,image/svga">
|
||||
<button class="btn btn-success" type="button"
|
||||
onclick="uploadfile('picMinFile','picMinImage','minPic','minPicInfo')">上传</button>
|
||||
<input type="hidden" id="minPic" name="icon" class="form-control" />
|
||||
<span id="minPicInfo" style="color:red;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">活动类型:</label>
|
||||
<div class="col-sm-9">
|
||||
<label class="radio-inline"><input type="radio" name="activityType" id="noOne" value=""
|
||||
checked>无</label>
|
||||
<label class="radio-inline"><input type="radio" name="activityType" id="sign"
|
||||
value="1">签到</label>
|
||||
<label class="radio-inline"><input type="radio" name="activityType" id="task"
|
||||
value="2">任务</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">是否上架:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="radio" name="displayType" id="up" value="1">是
|
||||
<input type="radio" name="displayType" id="down" value="2">否
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="appId" class="col-sm-3 control-label">app:</label>
|
||||
<select name="appId" id="appId" class="col-sm-2 validate[required]">
|
||||
<option value="">请选择...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="seqNo" class="col-sm-3 control-label">排序:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="seqNo" id="seqNo">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
<button type="button" class="btn btn-primary" id="add">提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TableHelper from '@/utils/bootstrap-table-helper';
|
||||
import '@/utils/ajaxfileupload';
|
||||
|
||||
var app = {};
|
||||
var validApp = {};
|
||||
export default {
|
||||
name: "DiscoveryAdminView",
|
||||
created() {
|
||||
this.$nextTick(function () {
|
||||
this.initData();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
$(function () {
|
||||
getAppNames();
|
||||
function getAppNames() {
|
||||
$.get('/admin/appName/listAll', {}, function (res) {
|
||||
if (res.rows.length > 0) {
|
||||
renderSelect(res.rows);
|
||||
renderAppObj(res.rows);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function renderSelect(data) {
|
||||
var $select = $('#searchAppId');
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var $option = $('<option value="' + data[i].app + '" />');
|
||||
$option.html(data[i].appName);
|
||||
$select.append($option);
|
||||
}
|
||||
}
|
||||
|
||||
function renderAppObj(rows) {
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var row = rows[i];
|
||||
app[row.app] = row.appName;
|
||||
// 有效的app
|
||||
if (row.status == 1) {
|
||||
validApp[row.app] = row.appName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#table').bootstrapTable('destroy');
|
||||
//初始化表格数据
|
||||
initTable();
|
||||
// 查询刷新
|
||||
$('#btnSearch').on('click', function () {
|
||||
$('#table').bootstrapTable('destroy');
|
||||
initTable();
|
||||
});
|
||||
// 新增家族弹窗
|
||||
$("#btnAdd").on("click", function () {
|
||||
clearForm("discoveryForm");
|
||||
// 处理appId
|
||||
$('#appId').empty();
|
||||
$('#appId').append('<option value="">请选择...</option>');
|
||||
for (var key in validApp) {
|
||||
$('#appId').append('<option value="' + key + '">' + validApp[key] + '</option>');
|
||||
}
|
||||
|
||||
$("#link").prop("checked", true);
|
||||
$("#up").prop("checked", true);
|
||||
$("#linkGroup").show();
|
||||
$("#jumpAppGroup").hide();
|
||||
$("#discoveryModal").modal('show');
|
||||
$("#jumpLink").removeClass("validate[required]");
|
||||
$("#jumpRoom").removeClass("validate[required]");
|
||||
$("#jumpGame").removeClass("validate[required]");
|
||||
$("#app").removeClass("validate[required]");
|
||||
$("#noOne").prop("checked", true);
|
||||
|
||||
});
|
||||
|
||||
//跳转链接
|
||||
$("#link").on("click", function () {
|
||||
$("#linkGroup").show();
|
||||
$("#roomGroup").hide();
|
||||
$("#gameGroup").hide();
|
||||
$("#jumpAppGroup").hide();
|
||||
});
|
||||
|
||||
//跳转房间
|
||||
$("#room").on("click", function () {
|
||||
$("#linkGroup").hide();
|
||||
$("#roomGroup").show();
|
||||
$("#gameGroup").hide();
|
||||
$("#jumpAppGroup").hide();
|
||||
});
|
||||
|
||||
//跳转游戏
|
||||
$("#game").on("click", function () {
|
||||
$("#linkGroup").hide();
|
||||
$("#roomGroup").hide();
|
||||
$("#jumpAppGroup").hide();
|
||||
getGame();
|
||||
});
|
||||
//跳转App页面
|
||||
$("#app").on("click", function () {
|
||||
$("#linkGroup").hide();
|
||||
$("#roomGroup").hide();
|
||||
$("#gameGroup").hide();
|
||||
$("#jumpAppGroup").show();
|
||||
});
|
||||
|
||||
|
||||
|
||||
//新增发现保存
|
||||
$("#add").on("click", function () {
|
||||
var id = $("#editId").val();
|
||||
var name = $("#name").val();
|
||||
var appId = $("#appId").val();
|
||||
var isLink = $("#link").is(":checked");
|
||||
var isRoom = $("#room").is(":checked");
|
||||
var isGame = $("#game").is(":checked");
|
||||
var isApp = $("#app").is(":checked");
|
||||
var jumpType = null;
|
||||
var link = null;
|
||||
var roomId = null;
|
||||
var gameId = null;
|
||||
var routerType = null;
|
||||
var routerValue = null;
|
||||
if (isLink) {
|
||||
jumpType = "1";
|
||||
link = $("#jumpLink").val();
|
||||
$("#jumpLink").addClass("validate[required]");
|
||||
} else if (isRoom) {
|
||||
jumpType = "2";
|
||||
roomId = $("#jumpRoom").val();
|
||||
$("#jumpRoom").addClass("validate[required]");
|
||||
} else if (isGame) {
|
||||
jumpType = "3";
|
||||
gameId = $("#jumpGame").val();
|
||||
$("#jumpGame").addClass("validate[required]");
|
||||
} else if (isApp) {
|
||||
jumpType = "5";
|
||||
routerType = $("#routerType").val();
|
||||
routerValue = $("#routerValue").val();
|
||||
$("#routerType").addClass("validate[required]");
|
||||
}
|
||||
if (jumpType == null) {
|
||||
$("#tipMsg").text("请选择跳转类型");
|
||||
$("#tipModal").modal('show');
|
||||
return;
|
||||
}
|
||||
if (!$('#appId').val()) {
|
||||
$("#tipMsg").text("请选择app");
|
||||
$("#tipModal").modal('show');
|
||||
return;
|
||||
}
|
||||
var displayType = null;
|
||||
var up = $("#up").is(":checked");
|
||||
var down = $("#down").is(":checked");
|
||||
if (up) {
|
||||
displayType = "1";
|
||||
} else if (down) {
|
||||
displayType = "2";
|
||||
}
|
||||
var icon = $("#pic").val();
|
||||
var minImage = $("#minPic").val();
|
||||
var seqNo = $("#seqNo").val();
|
||||
var activityType = null;
|
||||
var sign = $("#sign").is(":checked");
|
||||
var task = $("#task").is(":checked");
|
||||
if (sign) {
|
||||
activityType = "1";
|
||||
} else if (task) {
|
||||
activityType = "2";
|
||||
}
|
||||
|
||||
if ($("#discoveryForm").validationEngine('validate')) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: '/admin/discovery/saveOrUpdate.action',
|
||||
data: {
|
||||
id: id,
|
||||
name: name,
|
||||
icon: icon,
|
||||
displayType: displayType,
|
||||
jumpType: jumpType,
|
||||
roomUid: roomId,
|
||||
link: link,
|
||||
gameId: gameId,
|
||||
seqNo: seqNo,
|
||||
routerType: routerType,
|
||||
routerValue: routerValue,
|
||||
activityType: activityType,
|
||||
minImage: minImage,
|
||||
appId: appId
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function (json) {
|
||||
if (json.success == 'true') {
|
||||
$("#tipMsg").text("保存成功");
|
||||
$("#tipModal").modal('show');
|
||||
TableHelper.doRefresh("#table");
|
||||
$("#discoveryModal").modal('hide');
|
||||
} else {
|
||||
$("#tipMsg").text("保存失败." + json.msg);
|
||||
$("#tipModal").modal('show');
|
||||
TableHelper.doRefresh("#table");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#table").on("click", '.opt-edit', function () {
|
||||
clearForm("discoveryForm");
|
||||
// 处理appId
|
||||
$('#appId').empty();
|
||||
$('#appId').append('<option value="">请选择...</option>');
|
||||
for (var key in app) {
|
||||
$('#appId').append('<option value="' + key + '">' + app[key] + '</option>');
|
||||
}
|
||||
|
||||
var id = $(this).attr("data-id");
|
||||
$.ajax({
|
||||
type: "get",
|
||||
url: "/admin/discovery/getById.action",
|
||||
data: { id: id },
|
||||
dataType: "json",
|
||||
success: function (json) {
|
||||
if (json) {
|
||||
$("#editId").val(id);
|
||||
$("#name").val(json.name);
|
||||
$("#appId").val(json.appId);
|
||||
if (json.jumpType == "1") {
|
||||
$("#linkGroup").show();
|
||||
$("#roomGroup").hide();
|
||||
$("#gameGroup").hide();
|
||||
$("#jumpAppGroup").hide();
|
||||
$("#link").prop("checked", true);
|
||||
$("#room").prop("checked", false);
|
||||
$("#game").prop("checked", false);
|
||||
$("#app").prop("checked", false);
|
||||
$("#jumpLink").val(json.link);
|
||||
} else if (json.jumpType == "2") {
|
||||
$("#linkGroup").hide();
|
||||
$("#roomGroup").show();
|
||||
$("#gameGroup").hide();
|
||||
$("#jumpAppGroup").hide();
|
||||
$("#link").prop("checked", false);
|
||||
$("#room").prop("checked", true);
|
||||
$("#game").prop("checked", false);
|
||||
$("#app").prop("checked", false);
|
||||
$("#jumpRoom").val(json.roomUid);
|
||||
} else if (json.jumpType == "3") {
|
||||
$("#linkGroup").hide();
|
||||
$("#roomGroup").hide();
|
||||
$("#jumpAppGroup").hide();
|
||||
$("#gameGroup").show();
|
||||
$("#link").prop("checked", false);
|
||||
$("#room").prop("checked", false);
|
||||
$("#game").prop("checked", true);
|
||||
$("#app").prop("checked", false);
|
||||
$("#gameId").val(json.gameId);
|
||||
getGame();
|
||||
} else if (json.jumpType == "5") {
|
||||
$("#linkGroup").hide();
|
||||
$("#roomGroup").hide();
|
||||
$("#gameGroup").hide();
|
||||
$("#jumpAppGroup").show();
|
||||
$("#link").prop("checked", false);
|
||||
$("#room").prop("checked", false);
|
||||
$("#game").prop("checked", false);
|
||||
$("#app").prop("checked", true);
|
||||
$("#jumpLink").val(json.link);
|
||||
$("#routerType").val(json.routerType);
|
||||
$("#routerValue").val(json.routerValue);
|
||||
}
|
||||
if (json.displayType == '1') {
|
||||
$("#up").prop("checked", true);
|
||||
$("#down").prop("checked", false);
|
||||
} else if (json.displayType == '2') {
|
||||
$("#up").prop("checked", false);
|
||||
$("#down").prop("checked", true);
|
||||
}
|
||||
if (json.activityType == '1') {
|
||||
$("#sign").prop("checked", true);
|
||||
$("#task").prop("checked", false);
|
||||
} else if (json.activityType == '2') {
|
||||
$("#sign").prop("checked", false);
|
||||
$("#task").prop("checked", true);
|
||||
}
|
||||
$("#seqNo").val(json.seqNo);
|
||||
// 设置礼物图片
|
||||
$('#pic').val(json.icon);
|
||||
$('#picImage').attr("src", json.icon);
|
||||
if (json.icon != '') {
|
||||
$("#picInfo").html('已上传');
|
||||
} else {
|
||||
$("#picInfo").html('未上传');
|
||||
}
|
||||
$('#minPic').val(json.minImage);
|
||||
$('#picMinImage').attr("src", json.minImage);
|
||||
if (json.icon != '') {
|
||||
$("#minPicInfo").html('已上传');
|
||||
} else {
|
||||
$("#minPicInfo").html('未上传');
|
||||
}
|
||||
// 打开编辑弹窗
|
||||
$("#discoveryModal").modal('show');
|
||||
} else {
|
||||
$("#tipMsg").text("获取菜单信息出错");
|
||||
$("#tipModal").modal('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//删除发现(逻辑删除)
|
||||
$("#table").on("click", ".opt-del", function () {
|
||||
var id = $(this).attr("data-id");
|
||||
if (confirm("你确认删除该记录吗?" +
|
||||
"\r\n删除后再也不能找回,请谨慎操作!")) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: "/admin/discovery/saveOrUpdate.action",
|
||||
data: {
|
||||
'id': id,
|
||||
'status': '0'
|
||||
},
|
||||
dataType: "json",
|
||||
success: function (json) {
|
||||
if (json.success == 'true') {
|
||||
$("#tipMsg").text("删除成功");
|
||||
$("#tipModal").modal('show');
|
||||
TableHelper.doRefresh("#table");
|
||||
} else {
|
||||
$("#tipMsg").text("删除失败");
|
||||
$("#tipModal").modal('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function uploadfile(file, image, path, info) {
|
||||
$(this).attr('disabled', "true");
|
||||
$.ajaxFileUpload({
|
||||
fileElementId: file, //需要上传的文件域的ID,即<input type="file">的ID。
|
||||
url: '/admin/upload/img', //后台方法的路径
|
||||
type: 'post', //当要提交自定义参数时,这个参数要设置成post
|
||||
dataType: 'json', //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
|
||||
secureuri: false, //是否启用安全提交,默认为false。
|
||||
async: true, //是否是异步
|
||||
success: function (json) { //提交成功后自动执行的处理函数,参数data就是服务器返回的数据。
|
||||
if (json.path) {
|
||||
$('#' + path).val(json.path);
|
||||
$('#' + image).attr("src", json.path);
|
||||
if (json.path != '') {
|
||||
$("#" + info).html('已上传成功');
|
||||
} else {
|
||||
$("#" + info).html('未上传成功');
|
||||
}
|
||||
console.log(json.path);
|
||||
|
||||
} else {
|
||||
$("#tipMsg").text(json.msg);
|
||||
$("#tipModal").modal('show');
|
||||
}
|
||||
},
|
||||
error: function (data, status, e) { //提交失败自动执行的处理函数。
|
||||
$(this).removeAttr("disabled");
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clearForm(formId) {
|
||||
var $form = $('#' + formId);
|
||||
$form.find('input').val('');
|
||||
$form.find('select').val('');
|
||||
$form.find('textarea').val('');
|
||||
$form.find('input:radio').attr("checked", false);
|
||||
$form.find('img').attr("src", "");
|
||||
$form.find('span').html("");
|
||||
}
|
||||
|
||||
function getGame() {
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
url: '/admin/discovery/queryGame.action',
|
||||
data: {},
|
||||
dataType: 'json',
|
||||
success: function (json) {
|
||||
if (json) {
|
||||
var gameStr = "";
|
||||
if (json != null && json.length > 0) {
|
||||
for (var i = 0; i < json.length; i++) {
|
||||
gameStr = gameStr + "<option value='" + json[i].id + "'>" + json[i].name + "</option>";
|
||||
}
|
||||
}
|
||||
$("#jumpGame").html(gameStr);
|
||||
var gameId = $("#gameId").val();
|
||||
if (gameId != null && gameId != "") {
|
||||
$("#jumpGame").find("option[value='" + gameId + "']").attr("selected", "selected");
|
||||
}
|
||||
$("#gameGroup").show();
|
||||
} else {
|
||||
$("#tipMsg").text("查询游戏信息失败." + json.msg);
|
||||
$("#tipModal").modal('show');
|
||||
TableHelper.doRefresh("#table");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initTable() {
|
||||
$('#table').bootstrapTable({
|
||||
columns: [
|
||||
{ field: 'tmp', title: 'id', align: 'center', checkbox: true, width: '5%', valign: 'middle' },
|
||||
{ field: 'id', title: '编号', align: 'center', width: '5%', valign: 'middle' },
|
||||
{ field: 'name', title: '名称', align: 'center', width: '5%', valign: 'middle' },
|
||||
{
|
||||
field: 'icon',
|
||||
title: '图片',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
//valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (val && val.indexOf("https") == 0) {
|
||||
return "<img src='" + val + "' height='106'>";
|
||||
} else {
|
||||
return row.value;
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'displayType',
|
||||
title: '上架',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (val == "1") {
|
||||
return "是";
|
||||
} else if (val == "2") {
|
||||
return "否";
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'jumpType',
|
||||
title: '跳转类型',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (val == 1) {
|
||||
return "跳转链接";
|
||||
} else if (val == "2") {
|
||||
return "跳转房间";
|
||||
} else if (val == "3") {
|
||||
return "跳转游戏";
|
||||
} else if (val == "5") {
|
||||
return "跳转App页面";
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'roomUid',
|
||||
title: '跳转房间',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (row.jumpType == '2') {
|
||||
return "ID:" + val;
|
||||
} else {
|
||||
return "否";
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'link',
|
||||
title: '链接',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (row.jumpType == '1') {
|
||||
return val;
|
||||
} else {
|
||||
return "否";
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
field: 'appId',
|
||||
title: 'app',
|
||||
align: 'center',
|
||||
width: '10%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
var name = app[val];
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'familyGame.name',
|
||||
title: '游戏',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (row.jumpType == '3') {
|
||||
return val;
|
||||
} else {
|
||||
return "否";
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{ field: 'seqNo', title: '排序', align: 'center', width: '5%', valign: 'middle' },
|
||||
{
|
||||
field: 'pulishTime',
|
||||
title: '发布时间',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
if (val) {
|
||||
var date = new Date(val);
|
||||
return date.format("yyyy-MM-dd hh:mm:ss");
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
width: '5%',
|
||||
valign: 'middle',
|
||||
formatter: function (val, row, index) {
|
||||
return '<button id="btnEdit" name="btnEdit" class="btn btn-sm btn-success opt-edit" data-id=' + val + '>' +
|
||||
'<i class="glyphicon glyphicon-edit"></i> 编辑</button> ' +
|
||||
'<button id="btnMove" name="btnDel" class="btn btn-sm btn-success opt-del" data-id=' + val + '>' +
|
||||
'<i class="glyphicon glyphicon-move"></i> 删除</button> ';
|
||||
}
|
||||
}
|
||||
],
|
||||
cache: false,
|
||||
striped: true,
|
||||
showRefresh: false,
|
||||
pageSize: 20,
|
||||
pagination: true,
|
||||
pageList: [20, 50, 100, 200, 300, 500],
|
||||
search: false,
|
||||
sidePagination: "server", //表示服务端请求
|
||||
//设置为undefined可以获取pageNumber,pageSize,searchText,sortName,sortOrder
|
||||
//设置为limit可以获取limit, offset, search, sort, order
|
||||
queryParamsType: "undefined",
|
||||
queryParams: function queryParams(params) { //设置查询参数
|
||||
var param = {
|
||||
page: params.pageNumber,
|
||||
pageSize: params.pageSize,
|
||||
name: $('#searchName').val(),
|
||||
appId: $('#searchAppId').val(),
|
||||
displayType: $('#searchDisplayType').val(),
|
||||
jumpType: $('#searchJumpType').val(),
|
||||
};
|
||||
return param;
|
||||
},
|
||||
toolbar: '#toolbar',
|
||||
url: '/admin/discovery/list.action',
|
||||
onLoadSuccess: function () { //加载成功时执行
|
||||
$(".bs-checkbox").css({ 'text-align': 'center', 'vertical-align': 'middle' });
|
||||
console.log("load success");
|
||||
},
|
||||
onLoadError: function () { //加载失败时执行
|
||||
console.log("load fail");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
25
src/views/home/index.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<HeaderView/>
|
||||
<MaintainerView/>
|
||||
<FooterView/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HeaderView from "@/components/header/index.vue";
|
||||
import MaintainerView from "@/components/maintainer/index.vue";
|
||||
import FooterView from "@/components/footer/index.vue";
|
||||
|
||||
export default {
|
||||
name: 'HomeView',
|
||||
components: {
|
||||
HeaderView,
|
||||
MaintainerView,
|
||||
FooterView
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
227
src/views/login/index.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<div class="main_box" :style="[smsSwitch ? 'height: 350px' : '']">
|
||||
<div class="login_box">
|
||||
<div class="login_logo">
|
||||
<span
|
||||
style="font-size:24px;color:#222;font-weight:bold;"> PIKO 管 理 系 统</span>
|
||||
</div>
|
||||
<div class="login_form">
|
||||
<form id="loginForm" method="post">
|
||||
<input type="hidden" id="smsSwitch" :value="smsSwitch" />
|
||||
<div class="form-group">
|
||||
<label for="account" class="t">账 号:</label>
|
||||
<input id="account" name="account" type="text" class="form-control x319 in" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password" class="t">密 码:</label>
|
||||
<input id="password" name="password" type="password" class="password form-control x319 in">
|
||||
</div>
|
||||
<div v-if="smsSwitch">
|
||||
<div class="form-group">
|
||||
<label for="validateCode" class="t">验证码:</label>
|
||||
<input id="validateCode" name="authCode" type="text" class="form-control x319 in"
|
||||
style="width: 210px;">
|
||||
<button type="button" id="validateSend" class="btn btn-primary btn-lg">发送验证码</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="margin-bottom: 0px;">
|
||||
<label class="t"></label>
|
||||
<span class="loginTips"></span>
|
||||
</div>
|
||||
<div class="form-group space">
|
||||
<button type="button" id="loginBtn" class="btn btn-primary btn-lg">登 录</button>
|
||||
|
||||
<input type="reset" value="重 置" class="btn btn-default btn-lg">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store';
|
||||
|
||||
var sendFlag = true;
|
||||
export default {
|
||||
name: "LoginView",
|
||||
data() {
|
||||
return {
|
||||
smsSwitch: true,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.smsSwitch = !process.env.VUE_APP_DEBUG_MODE;
|
||||
this.$nextTick(function () {
|
||||
this.initData();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
$(function () {
|
||||
var $ul = $('<ul id="bubble-wrapper"/>');
|
||||
for (var i = 0; i < 10; i++) {
|
||||
$ul.append($('<li/>'));
|
||||
}
|
||||
$("body").append($ul);
|
||||
|
||||
var rememberMe = getCookie("wolfbe.remember");
|
||||
if (rememberMe == 1) {
|
||||
var account = getCookie("wolfbe.account");
|
||||
if (account) $("#account").val(account);
|
||||
}
|
||||
|
||||
$("#loginBtn").click(function () {
|
||||
var account = $("#account").val();
|
||||
var password = $("#password").val();
|
||||
if (account.trim() == '') {
|
||||
$(".loginTips").html("账号不能为空!");
|
||||
return;
|
||||
} else if (password.trim() == '') {
|
||||
$(".loginTips").html("密码不能为空!");
|
||||
return;
|
||||
}
|
||||
password = $.md5(password);
|
||||
var param = { 'account': account, 'password': password };
|
||||
var smsSwitch = $('#smsSwitch').val();
|
||||
console.info('smsSwitch:' + smsSwitch);
|
||||
if (smsSwitch && smsSwitch == 'true') {
|
||||
var authCode = $("#validateCode").val();
|
||||
if (authCode.trim() == '') {
|
||||
$(".loginTips").html("验证码不能为空!");
|
||||
return;
|
||||
}
|
||||
authCode = $.md5(authCode);
|
||||
param = { 'account': account, 'password': password, 'authCode': authCode };
|
||||
}
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "/login/login.action",
|
||||
data: param,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
console.log("data is: " + data.success);
|
||||
//刷新验证码
|
||||
$("#validateImg").click();
|
||||
if (data.success == 'true') {
|
||||
console.log('login success!');
|
||||
var array = new String(data.msg).split('@');
|
||||
store.commit('updateUser', {
|
||||
adminId: array[0],
|
||||
username: array[1]
|
||||
});
|
||||
//处理css样式污染问题,关闭当前窗口,重新渲染
|
||||
window.close();
|
||||
window.open('#/home', '_blank');
|
||||
} else {
|
||||
if (data.msg == "4003" || data.msg == "404") {
|
||||
if (data.data == "0") {
|
||||
data.msg = "输入超过次数限制,请联系管理员";
|
||||
} else {
|
||||
data.msg = "密码或验证码错误!你今天还有" + data.data + "次重试机会";
|
||||
}
|
||||
}
|
||||
$(".loginTips").html(data.msg).css("padding", "3px 5px");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
$("#loginForm :input").not("#rememberAccount").focus(function () {
|
||||
$(".loginTips").html("").css("padding", "0");
|
||||
}).keyup(function (e) {
|
||||
var keyCode = e.which || e.keyCode;
|
||||
if (keyCode == 13) {
|
||||
$("#loginBtn").click();
|
||||
}
|
||||
});
|
||||
|
||||
$("#validateImg").click(function () {
|
||||
$(this).attr("src", "/admin/kaptcha?t=" + new Date().getTime());
|
||||
});
|
||||
|
||||
$("#validateSend").click(function () {
|
||||
var account = $("#account").val();
|
||||
if (account.trim() == '') {
|
||||
$(".loginTips").html("账号不能为空!");
|
||||
return;
|
||||
}
|
||||
if (sendFlag) {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: "/login/sendSmsCode.action",
|
||||
data: { 'account': account },
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
if (data.code == 200) {
|
||||
sendSmsSuccess();
|
||||
} else {
|
||||
$(".loginTips").html(data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function sendSmsSuccess() {
|
||||
if (sendFlag) {
|
||||
sendFlag = false;
|
||||
var time = 181;
|
||||
var timer = setInterval(() => {
|
||||
time--;
|
||||
$("#validateSend").html(time + ' 秒');
|
||||
if (time === 0) {
|
||||
clearInterval(timer);
|
||||
$("#validateSend").html('重新获取');
|
||||
sendFlag = true;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
//获取cookie的信息
|
||||
function getCookie(name) {
|
||||
var reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
|
||||
var arr = document.cookie.match(reg);
|
||||
if (arr) {
|
||||
return (arr[2]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import '../../css/supersized.css';
|
||||
@import '../../css/login.css';
|
||||
|
||||
* {
|
||||
font-family: "Helvetica Neue", Helvetica, STheiti, 微软雅黑, 宋体, Arial, Tahoma, sans-serif, serif;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 8px 25px;
|
||||
}
|
||||
|
||||
#captcha_img {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.loginTips {
|
||||
color: red;
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#validateSend {
|
||||
width: 106px;
|
||||
padding: 6px 17px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
38
vue.config.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
var webpack = require('webpack')
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true,
|
||||
chainWebpack: config => {
|
||||
config
|
||||
.plugin('html')
|
||||
.tap(args => {
|
||||
args[0].title = 'PIKO管理后台'
|
||||
return args
|
||||
})
|
||||
},
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({
|
||||
$: 'jquery',
|
||||
jQuery: 'jquery',
|
||||
'windows.jQuery': 'jquery',
|
||||
Popper: ['popper.js', 'default']
|
||||
}),
|
||||
],
|
||||
},
|
||||
devServer: {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
proxy: {
|
||||
'/': {
|
||||
ws: false,
|
||||
target: process.env.VUE_APP_API_BASE_URL,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/': ''
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|