Commit 1b757d69 by zhengjie

代码优化,结构调整,进度50%

parent 6c06d893
......@@ -13,7 +13,7 @@ export default {
/**
* @description 此处修改网站名称
*/
webName: 'eladmin',
webName: 'EL-ADMIN',
/**
* @description 是否只保持一个子菜单的展开
*/
......
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1561614515233" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3833" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M807.049 391.258c0.946-9.62 1.45-19.37 1.45-29.239 0-163.7-132.706-296.406-296.406-296.406S215.687 198.318 215.687 362.02c0 9.802 0.498 19.486 1.432 29.043-43.925 18.95-74.675 62.638-74.675 113.516v330.363c0 68.25 55.328 123.58 123.58 123.58h491.672c68.25 0 123.578-55.328 123.578-123.58V504.578c0-50.704-30.54-94.267-74.225-113.32zM510.917 165.905c109.134 0 197.604 88.47 197.604 197.603 0 5.895-0.275 11.726-0.782 17.49H314.094a200.097 200.097 0 0 1-0.782-17.49c0.002-109.132 88.472-197.603 197.605-197.603z" p-id="3834" fill="#8a8a8a"></path></svg>
\ No newline at end of file
<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1561614445035" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2702" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M914.285769 802.889143q0 68.534857-41.691429 108.251429t-110.884571 39.716571l-499.419429 0q-69.12 0-110.884571-39.716571t-41.691429-108.251429q0-30.281143 1.974857-59.172571t7.972571-62.317714 15.140571-62.025143 24.576-55.734857 35.401143-46.299429 48.859429-30.573714 63.707429-11.410286q5.12 0 23.990857 12.288t42.569143 27.428571 61.732571 27.428571 76.288 12.288 76.288-12.288 61.732571-27.428571 42.569143-27.428571 23.990857-12.288q34.889143 0 63.707429 11.410286t48.859429 30.573714 35.401143 46.299429 24.576 55.734857 15.140571 62.025143 7.972571 62.317714 1.974857 59.172571zM731.428626 292.571429q0 90.843429-64.292571 155.136t-155.136 64.292571-155.136-64.292571-64.292571-155.136 64.292571-155.136 155.136-64.292571 155.136 64.292571 64.292571 155.136z" p-id="2703" fill="#8a8a8a"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1561614261684" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1777" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M963.801169 218.170758a72.850542 72.850542 0 0 0-57.513586-63.903984 1357.959666 1357.959666 0 0 1-185.960594-42.815669A690.80207 690.80207 0 0 1 554.17663 14.317049a76.045741 76.045741 0 0 0-88.826539 0 435.825173 435.825173 0 0 1-167.428438 96.495016 624.341926 624.341926 0 0 1-180.848276 44.732789 67.738223 67.738223 0 0 0-56.874546 63.903984S58.281712 379.847839 58.281712 521.075644c0 255.615937 301.626806 502.924356 452.440208 502.924356s406.42934-174.457877 447.32789-499.090117c10.224637-191.711953 3.195199-306.100085 3.195199-306.100085zM799.567929 415.63407l-315.046642 297.153527a42.815669 42.815669 0 0 1-52.401267 5.112318l-8.307518-7.029438L249.993665 530.022202a42.815669 42.815669 0 0 1 63.903984-58.791666L457.042574 621.404899l283.73369-268.396734a42.815669 42.815669 0 1 1 58.791665 63.903984" p-id="1778" fill="#8a8a8a"></path></svg>
\ No newline at end of file
......@@ -4,7 +4,7 @@ import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '../views/layout/Layout'
import Layout from '../layout/Layout'
/**
* hidden: true if `hidden:true` will not show in the sidebar(default is false)
......@@ -22,17 +22,17 @@ import Layout from '../views/layout/Layout'
export const constantRouterMap = [
{ path: '/login',
meta: { title: '登录', noCache: true },
component: () => import('@/views/login/index'),
component: () => import('@/views/login'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/errorPage/404'),
component: () => import('@/views/features/404'),
hidden: true
},
{
path: '/401',
component: () => import('@/views/errorPage/401'),
component: () => import('@/views/features/401'),
hidden: true
},
{
......@@ -42,7 +42,7 @@ export const constantRouterMap = [
children: [
{
path: '/redirect/:path*',
component: () => import('@/views/redirect/index')
component: () => import('@/views/features/redirect')
}
]
},
......@@ -53,7 +53,7 @@ export const constantRouterMap = [
children: [
{
path: 'dashboard',
component: () => import('@/views/dashboard/index'),
component: () => import('@/views/home'),
name: '首页',
meta: { title: '首页', icon: 'index', noCache: true, affix: true }
}
......
import { constantRouterMap } from '@/router/routers'
import Layout from '@/views/layout/Layout'
import Layout from '@/layout/Layout'
const permission = {
state: {
......
<template>
<div class="dashboard-container">
<component :is="currentRole"/>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import adminDashboard from './admin'
import { count } from '@/api/visits'
/**
* 记录访问,只有页面刷新或者第一次加载才会记录
*/
count().then(res => {})
export default {
name: 'Dashboard',
components: { adminDashboard },
data() {
return {
currentRole: 'adminDashboard'
}
},
computed: {
...mapGetters([
'roles'
])
}
}
</script>
......@@ -4,7 +4,7 @@
<el-col :span="12">
<h1 class="text-jumbo text-ginormous">Oops!</h1>
图片来源<a href="https://zh.airbnb.com/" target="_blank">airbnb</a> 页面
<h2>你没有权限去该页面</h2>
<h2>你没有权限去操作</h2>
<h6>如有不满请联系你领导</h6>
<ul class="list-unstyled">
<li>或者你可以去:</li>
......
<template>
<div class="dashboard-container">
<div class="dashboard-editor-container">
<panel-group/>
......@@ -24,28 +25,41 @@
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import PanelGroup from './components/PanelGroup'
import LineChart from './components/LineChart'
import RaddarChart from './components/RaddarChart'
import PieChart from './components/PieChart'
import BarChart from './components/BarChart'
import { mapGetters } from 'vuex'
import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
import { count } from '@/api/visits'
/**
* 记录访问,只有页面刷新或者第一次加载才会记录
*/
count().then(res => {})
export default {
name: 'DashboardAdmin',
name: 'Dashboard',
components: {
PanelGroup,
LineChart,
RaddarChart,
PieChart,
BarChart
BarChart },
computed: {
...mapGetters([
'roles'
])
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard-editor-container {
.dashboard-editor-container {
padding: 18px 22px 22px 22px;
background-color: rgb(240, 242, 245);
.chart-wrapper {
......@@ -53,5 +67,5 @@ export default {
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
}
</style>
<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
<h3 class="title">el-admin 后台管理系统</h3>
<h3 class="title">EL-ADMIN 后台管理系统</h3>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon" style="height: 39px;width: 13px;margin-left: 2px;" />
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon" style="height: 39px;width: 13px;margin-left: 2px;" />
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 60%" @keyup.enter.native="handleLogin"/>
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode">
</div>
......@@ -122,7 +124,7 @@ export default {
justify-content: center;
align-items: center;
height: 100%;
background-image:url( https://aurora-1255840532.cos.ap-chengdu.myqcloud.com/1547428971990.jpg);
background-image:url( https://docs-1255840532.cos.ap-shanghai.myqcloud.com/3968.jpg );
background-size: cover;
}
.title {
......@@ -134,7 +136,7 @@ export default {
.login-form {
border-radius: 6px;
background: #ffffff;
width: 380px;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
......@@ -142,6 +144,9 @@ export default {
height: 38px;
}
}
.input-icon{
height: 39px;width: 14px;margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
......
<template>
<div class="app-container">
<eHeader :query="query"/>
<!--工具栏-->
<div class="head-container">
<!-- 搜索 -->
<el-input v-model="query.value" clearable placeholder="输入关键词搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<div style="display: inline-block;">
<!-- 清空缓存 -->
<el-button v-permission="['ADMIN','REDIS_ALL','REDIS_DELETE']" :loading="deleteAllLoading" type="warning" size="mini" class="filter-item" icon="el-icon-delete" @click="deleteAll">清空缓存</el-button>
</div>
</div>
<!--表格渲染-->
<el-table v-loading="loading" :data="data" size="small" style="width: 100%;">
<el-table-column label="序号" width="80" align="center">
......@@ -47,14 +56,12 @@
<script>
import checkPermission from '@/utils/permission' // 权限判断函数
import initData from '@/mixins/initData'
import { del } from '@/api/redis'
import eHeader from './module/header'
import { del, delAll } from '@/api/redis'
export default {
components: { eHeader },
mixins: [initData],
data() {
return {
delLoading: false, sup_this: this, permissions: []
delLoading: false, sup_this: this, permissions: [], deleteAllLoading: false
}
},
created() {
......@@ -93,6 +100,24 @@ export default {
this.$refs[index].doClose()
console.log(err.response.data.message)
})
},
toQuery() {
this.page = 0
this.init()
},
deleteAll() {
this.$confirm('你确定要清空缓存数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.deleteAllLoading = true
delAll().then(res => {
this.page = 0
this.init()
this.deleteAllLoading = false
})
})
}
}
}
......
<template>
<div class="head-container">
<!-- 搜索 -->
<el-input v-model="query.value" clearable placeholder="输入关键词搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<div style="display: inline-block;">
<!-- 清空缓存 -->
<el-button v-permission="['ADMIN','REDIS_ALL','REDIS_DELETE']" :loading="deleteAllLoading" type="warning" size="mini" class="filter-item" icon="el-icon-delete" @click="deleteAll">清空缓存</el-button>
</div>
</div>
</template>
<script>
import { delAll } from '@/api/redis'
// 查询条件
export default {
props: {
query: {
type: Object,
required: true
}
},
data() {
return {
deleteAllLoading: false
}
},
methods: {
toQuery() {
this.$parent.page = 0
this.$parent.init()
},
deleteAll() {
this.deleteAllLoading = true
delAll().then(res => {
this.$parent.page = 0
this.$parent.init()
this.deleteAllLoading = false
})
}
}
}
</script>
......@@ -81,7 +81,7 @@ export default {
// 导出
download() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
import('@/utils/export2Excel').then(excel => {
const tHeader = ['ID', '用户名', '邮箱', '头像地址', '状态', '注册日期', '最后修改密码日期']
const filterVal = ['id', 'username', 'email', 'avatar', 'enabled', 'createTime', 'lastPasswordResetTime']
const data = this.formatJson(filterVal, this.sup_this.data)
......
......@@ -7,17 +7,35 @@
<ToPay/>
</el-tab-pane>
<el-tab-pane label="使用说明" name="third">
<Description/>
<div>
<blockquote class="my-blockquote">注意</blockquote>
<pre class="my-code">
测试所用参数都是沙箱环境,仅供测试使用,申请地址:<a style="color: #00a0e9" href="https://openhome.alipay.com/platform/appDaily.htm?tab=info" target="_blank">支付宝开发平台</a>
如需付款测试,请使用
账号:uuxesw9745@sandbox.com
密码与支付密码:111111</pre>
<blockquote class="my-blockquote"> 支付设置</blockquote>
<pre class="my-code">
// 支付提供两个接口,
// PC端与手机端,并且在前端使用代码识别
if (/(Android)/i.test(navigator.userAgent)){ // 判断是否为Android手机
url = "/aliPay/toPayAsWeb"
}else if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){ // 判断是否为苹果手机
url = "/aliPay/toPayAsWeb"
} else {
url = "/aliPay/toPayAsPC"
}</pre>
</div>
</el-tab-pane>
</el-tabs>
</template>
<script>
import Config from './module/config'
import ToPay from './module/toPay'
import Description from './module/description'
import Config from './config'
import ToPay from './toPay'
import '@/styles/description.scss'
export default {
components: { Config, ToPay, Description },
components: { Config, ToPay },
data() {
return {
activeName: 'second'
......
<template>
<div>
<blockquote class="my-blockquote">注意</blockquote>
<pre class="my-code">
测试所用参数都是沙箱环境,仅供测试所用,申请地址:<a style="color: #00a0e9" href="https://openhome.alipay.com/platform/appDaily.htm?tab=info" target="_blank">支付宝开发平台</a>
如需付款测试,请使用
账号:uuxesw9745@sandbox.com
密码:111111
支付密码:111111
文明测试谢谢</pre>
<blockquote class="my-blockquote"> 支付设置</blockquote>
<pre class="my-code">
支付提供两个测试地址
PC端与手机端,并且使用如下代码识别
if (/(Android)/i.test(navigator.userAgent)){ // 判断是否为Android手机
url = "/aliPay/toPayAsWeb"
}else if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){ // 判断是否为苹果手机
url = "/aliPay/toPayAsWeb"
} else {
url = "/aliPay/toPayAsPC"
}</pre>
<blockquote class="my-blockquote">更多帮助</blockquote>
<pre class="my-code">更多帮助请查看系统源码</pre>
</div>
</template>
<script>
import '@/styles/description.scss'
export default {
name: 'Description'
}
</script>
<style scoped>
</style>
......@@ -7,17 +7,28 @@
<Send/>
</el-tab-pane>
<el-tab-pane label="使用说明" name="third">
<Description/>
<div>
<blockquote class="my-blockquote"> 邮件服务器配置</blockquote>
<pre class="my-code">
# 邮件服务器的SMTP地址,可选,默认为smtp
# 邮件服务器的SMTP端口,可选,默认465或者25
# 发件人(必须正确,否则发送失败)
# 用户名,默认为发件人邮箱前缀
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,如QQ和163等等)
# 是否开启ssl,默认开启</pre>
<blockquote class="my-blockquote">更多帮助</blockquote>
<pre class="my-code">更多帮助请查看文档:<a style="color:#009688" href="http://hutool.mydoc.io/#text_319499" target="_black">hutool工具包</a></pre>
</div>
</el-tab-pane>
</el-tabs>
</template>
<script>
import Config from './module/config'
import Send from './module/send'
import Description from './module/description'
import Config from './config'
import Send from './send'
import '@/styles/description.scss'
export default {
components: { Config, Send, Description },
components: { Config, Send },
data() {
return {
activeName: 'second'
......
<template>
<div>
<blockquote class="my-blockquote">注意</blockquote>
<pre class="my-code">
邮件服务器必须支持并打开SMTP协议,详细请查看相关帮助说明
配置文件的样例中提供的是我测试邮件功能注册的sina.com邮箱
帐号密码公开,供测试使用,存入数据库的密码会加密处理,请文明测试</pre>
<blockquote class="my-blockquote"> 邮件服务器配置</blockquote>
<pre class="my-code">
# 邮件服务器的SMTP地址,可选,默认为smtp
# 邮件服务器的SMTP端口,可选,默认465或者25
# 发件人(必须正确,否则发送失败)
# 用户名,默认为发件人邮箱前缀
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,如QQ和163等等)
# 是否开启ssl,默认开启</pre>
<blockquote class="my-blockquote">发送邮箱</blockquote>
<pre class="my-code">
MailAccount account = new MailAccount();
account.setHost("smtp.sina.com");
account.setPort("465");
account.setAuth(true);
account.setFrom("auaur@sina.com");
account.setUser("eladmin");
account.setPass("pass");
# 倒数第二个参数:是否为http格式
MailUtil.send(account, CollUtil.newArrayList("zhengjie@tom.com"), "测试", "邮件来自eladmin测试", true,file...);</pre>
<blockquote class="my-blockquote">更多帮助</blockquote>
<pre class="my-code">更多帮助请查看文档:<a style="color:#009688" href="http://hutool.mydoc.io/#text_319499" target="_black">hutool工具包</a></pre>
</div>
</template>
<script>
import '@/styles/description.scss'
export default {
name: 'Description'
}
</script>
<style scoped>
</style>
<template>
<div class="app-container">
<eHeader :query="query"/>
<!--工具栏-->
<div class="head-container">
<!--搜索-->
<el-input v-model="query.filename" clearable placeholder="输入文件名" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<!-- 上传 -->
<div style="display: inline-block;margin: 0px 2px;">
<el-button
v-permission="['ADMIN','PICTURE_ALL','PICTURE_UPLOAD']"
class="filter-item"
size="mini"
type="primary"
icon="el-icon-upload"
@click="dialog = true">上传图片</el-button>
</div>
<div v-permission="['ADMIN','PICTURE_ALL','PICTURE_DELETE']" style="display: inline-block;">
<el-button
:loading="delAllLoading"
:disabled="data.length === 0 || $refs.table.selection.length === 0"
class="filter-item"
size="mini"
type="danger"
icon="el-icon-delete"
@click="open">删除</el-button>
</div>
</div>
<!--上传图片-->
<el-dialog :visible.sync="dialog" append-to-body width="600px" @close="doSubmit">
<el-upload
:on-preview="handlePictureCardPreview"
:before-remove="handleBeforeRemove"
:on-success="handleSuccess"
:on-error="handleError"
:headers="headers"
:file-list="fileList"
:action="imagesUploadApi"
list-type="picture-card">
<i class="el-icon-plus"/>
</el-upload>
<el-dialog :append-to-body="true" :visible.sync="dialogVisible">
<img :src="dialogImageUrl" width="100%" alt="">
</el-dialog>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table v-loading="loading" ref="table" :data="data" size="small" style="width: 100%;">
<el-table-column type="selection" width="55"/>
......@@ -49,17 +94,31 @@
<script>
import checkPermission from '@/utils/permission' // 权限判断函数
import initData from '@/mixins/initData'
import { del } from '@/api/picture'
import { parseTime } from '@/utils/index'
import eHeader from './module/header'
import { mapGetters } from 'vuex'
import { del, delAll } from '@/api/picture'
import { getToken } from '@/utils/auth'
export default {
components: { eHeader },
mixins: [initData],
data() {
return {
delLoading: false, sup_this: this
delLoading: false, downloadLoading: false,
delAllLoading: false,
headers: {
'Authorization': 'Bearer ' + getToken()
},
dialog: false,
dialogImageUrl: '',
dialogVisible: false,
fileList: [],
pictures: []
}
},
computed: {
...mapGetters([
'imagesUploadApi'
])
},
created() {
this.$nextTick(() => {
this.init()
......@@ -72,10 +131,9 @@ export default {
this.url = 'api/pictures'
const sort = 'id,desc'
const query = this.query
const type = query.type
const value = query.value
const filename = query.filename
this.params = { page: this.page, size: this.size, sort: sort }
if (type && value) { this.params[type] = value }
if (filename) { this.params[filename] = filename }
return true
},
subDelete(id) {
......@@ -95,6 +153,74 @@ export default {
this.$refs[id].doClose()
console.log(err.response.data.message)
})
},
toQuery() {
this.page = 0
this.init()
},
doDelete() {
this.delAllLoading = true
const data = this.$refs.table.selection
const ids = []
for (let i = 0; i < data.length; i++) {
ids.push(data[i].id)
}
delAll(ids).then(res => {
this.delAllLoading = false
this.init()
this.dleChangePage(ids.length)
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delAllLoading = false
console.log(err.response.data.message)
})
},
open() {
this.$confirm('你确定删除选中的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doDelete()
})
},
handleSuccess(response, file, fileList) {
const uid = file.uid
const id = response.id
this.pictures.push({ uid, id })
},
handleBeforeRemove(file, fileList) {
for (let i = 0; i < this.pictures.length; i++) {
if (this.pictures[i].uid === file.uid) {
del(this.pictures[i].id).then(res => {})
return true
}
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
// 刷新列表数据
doSubmit() {
this.fileList = []
this.dialogVisible = false
this.dialogImageUrl = ''
this.dialog = false
this.init()
},
// 监听上传失败
handleError(e, file, fileList) {
const msg = JSON.parse(e.message)
this.$notify({
title: msg.message,
type: 'error',
duration: 2500
})
}
}
}
......
<template>
<el-dialog :visible.sync="dialog" append-to-body width="600px" @close="doSubmit">
<el-upload
:on-preview="handlePictureCardPreview"
:before-remove="handleBeforeRemove"
:on-success="handleSuccess"
:on-error="handleError"
:headers="headers"
:file-list="fileList"
:action="imagesUploadApi"
list-type="picture-card">
<i class="el-icon-plus"/>
</el-upload>
<el-dialog :append-to-body="true" :visible.sync="dialogVisible">
<img :src="dialogImageUrl" width="100%" alt="">
</el-dialog>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
</template>
<script>
import { mapGetters } from 'vuex'
import { del } from '@/api/picture'
import { getToken } from '@/utils/auth'
export default {
data() {
return {
headers: {
'Authorization': 'Bearer ' + getToken()
},
dialog: false,
dialogImageUrl: '',
dialogVisible: false,
fileList: [],
pictures: []
}
},
computed: {
...mapGetters([
'imagesUploadApi'
])
},
methods: {
handleSuccess(response, file, fileList) {
const uid = file.uid
const id = response.id
this.pictures.push({ uid, id })
},
handleBeforeRemove(file, fileList) {
for (let i = 0; i < this.pictures.length; i++) {
if (this.pictures[i].uid === file.uid) {
del(this.pictures[i].id).then(res => {})
return true
}
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
// 刷新列表数据
doSubmit() {
this.fileList = []
this.dialogVisible = false
this.dialogImageUrl = ''
this.dialog = false
this.$parent.$parent.init()
},
// 监听上传失败
handleError(e, file, fileList) {
const msg = JSON.parse(e.message)
this.$notify({
title: msg.message,
type: 'error',
duration: 2500
})
}
}
}
</script>
<style scoped>
</style>
<template>
<div class="head-container">
<!--搜索-->
<el-input v-model="query.value" clearable placeholder="输入关键字搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-select v-model="query.type" clearable placeholder="类型" class="filter-item" style="width: 130px">
<el-option v-for="item in queryTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
</el-select>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<!-- 上传 -->
<div style="display: inline-block;margin: 0px 2px;">
<el-button
v-permission="['ADMIN','PICTURE_ALL','PICTURE_UPLOAD']"
class="filter-item"
size="mini"
type="primary"
icon="el-icon-upload"
@click="$refs.form.dialog = true">上传图片</el-button>
<eForm ref="form"/>
</div>
<div v-permission="['ADMIN','PICTURE_ALL','PICTURE_DELETE']" style="display: inline-block;">
<el-button
:loading="delLoading"
:disabled="$parent.data.length === 0 || $parent.$refs.table.selection.length === 0"
class="filter-item"
size="mini"
type="danger"
icon="el-icon-delete"
@click="open">删除</el-button>
</div>
</div>
</template>
<script>
import eForm from './form'
import { delAll } from '@/api/picture'
// 查询条件
export default {
components: { eForm },
props: {
query: {
type: Object,
required: true
}
},
data() {
return {
downloadLoading: false,
delLoading: false,
queryTypeOptions: [
{ key: 'filename', display_name: '文件名' },
{ key: 'username', display_name: '用户名' }
]
}
},
methods: {
toQuery() {
this.$parent.page = 0
this.$parent.init()
},
doDelete() {
this.delLoading = true
const data = this.$parent.$refs.table.selection
const ids = []
for (let i = 0; i < data.length; i++) {
ids.push(data[i].id)
}
delAll(ids).then(res => {
this.delLoading = false
this.$parent.init()
this.$parent.dleChangePage(ids.length)
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
console.log(err.response.data.message)
})
},
open() {
this.$confirm('你确定删除选中的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doDelete()
})
}
}
}
</script>
......@@ -7,17 +7,27 @@
<List/>
</el-tab-pane>
<el-tab-pane label="使用说明" name="third">
<Description/>
<div>
<blockquote class="my-blockquote">注意</blockquote>
<pre class="my-code">
1、配置时外链域名需带上协议,也就是必须http/https开头
2、如果七牛云中存在数据,使用同步按钮即可将数据同步到数据库
3、本次集成了七牛云的常用操作,如:上传,下载,删除,同步,支持私有空间上传下载</pre>
<blockquote class="my-blockquote">更多帮助</blockquote>
<pre class="my-code">更多帮助请查看系统源码,或者七牛云java开发文档
七牛云官网:<a style="color: #00a2d4" href="https://sso.qiniu.com/" target="_blank">https://sso.qiniu.com/</a>
七牛云java开发文档:<a style="color: #00a2d4" href="https://developer.qiniu.com/kodo/sdk/1239/java#3" target="_blank">https://developer.qiniu.com/kodo/sdk/1239/java#3</a></pre>
</div>
</el-tab-pane>
</el-tabs>
</template>
<script>
import Config from './module/config'
import List from './module/list'
import Description from './module/description'
import Config from './config'
import List from './list'
import '@/styles/description.scss'
export default {
components: { Config, List, Description },
components: { Config, List },
data() {
return {
activeName: 'second'
......
<template>
<div class="app-container">
<eHeader :query="query"/>
<div class="app-container" style="padding: 8px;">
<!-- 工具栏 -->
<div class="head-container">
<!-- 搜索 -->
<el-input v-model="query.value" clearable placeholder="输入文件名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<!-- 上传 -->
<div style="display: inline-block;margin: 0px 2px;">
<el-button class="filter-item" size="mini" type="primary" icon="el-icon-upload" @click="dialog = true">上传文件</el-button>
</div>
<!-- 同步 -->
<el-button :icon="icon" class="filter-item" size="mini" type="warning" @click="synchronize">同步数据</el-button>
<!-- 多选删除 -->
<div style="display: inline-block;margin: 0px 2px;">
<el-button
v-permission="['ADMIN','PICTURE_ALL','PICTURE_DELETE']"
:loading="delAllLoading"
:disabled="data.length === 0 || $refs.table.selection.length === 0"
class="filter-item"
size="mini"
type="danger"
icon="el-icon-delete"
@click="open">删除</el-button>
</div>
</div>
<!-- 文件上传 -->
<el-dialog :visible.sync="dialog" append-to-body width="500px" @close="doSubmit">
<el-upload
:before-remove="handleBeforeRemove"
:on-success="handleSuccess"
:on-error="handleError"
:file-list="fileList"
:headers="headers"
:action="qiNiuUploadApi"
class="upload-demo"
multiple>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" style="display: block;" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table v-loading="loading" ref="table" :data="data" size="small" style="width: 100%;">
<el-table-column type="selection" width="55"/>
......@@ -59,20 +100,25 @@
<script>
import checkPermission from '@/utils/permission' // 权限判断函数
import initData from '@/mixins/initData'
import { del, download } from '@/api/qiniu'
import { del, download, sync, delAll } from '@/api/qiniu'
import { parseTime } from '@/utils/index'
import eHeader from './module/header'
import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth'
export default {
components: { eHeader },
mixins: [initData],
data() {
return {
url: '',
// 新窗口的引用
newWin: null,
downloadLoading: false, delLoading: false, sup_this: this
icon: 'el-icon-refresh', delAllLoading: false,
url: '', headers: { 'Authorization': 'Bearer ' + getToken() }, dialog: false,
dialogImageUrl: '', dialogVisible: false, fileList: [], files: [],
newWin: null, downloadLoading: false, delLoading: false
}
},
computed: {
...mapGetters([
'qiNiuUploadApi'
])
},
watch: {
url(newVal, oldVal) {
if (newVal && this.newWin) {
......@@ -92,6 +138,10 @@ export default {
methods: {
parseTime,
checkPermission,
toQuery() {
this.page = 0
this.init()
},
beforeInit() {
this.url = 'api/qiNiuContent'
const sort = 'id,desc'
......@@ -136,6 +186,89 @@ export default {
return name.substring(dot + 1)
}
return name
},
handleSuccess(response, file, fileList) {
const uid = file.uid
const id = response.id
this.files.push({ uid, id })
},
handleBeforeRemove(file, fileList) {
for (let i = 0; i < this.files.length; i++) {
if (this.files[i].uid === file.uid) {
del(this.files[i].id).then(res => {})
return true
}
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
// 刷新列表数据
doSubmit() {
this.fileList = []
this.dialogVisible = false
this.dialogImageUrl = ''
this.dialog = false
this.init()
},
// 监听上传失败
handleError(e, file, fileList) {
const msg = JSON.parse(e.message)
this.$notify({
title: msg.message,
type: 'error',
duration: 2500
})
},
synchronize() {
this.icon = 'el-icon-loading'
this.buttonName = '同步中'
sync().then(res => {
this.icon = 'el-icon-refresh'
this.buttonName = '同步数据'
this.$message({
showClose: true,
message: '数据同步成功',
type: 'success',
duration: 1500
})
this.toQuery()
}).catch(err => {
this.icon = 'el-icon-refresh'
this.buttonName = '同步数据'
console.log(err.response.data.message)
})
},
doDelete() {
this.delAllLoading = true
const data = this.$refs.table.selection
const ids = []
for (let i = 0; i < data.length; i++) {
ids.push(data[i].id)
}
delAll(ids).then(res => {
this.delAllLoading = false
this.dleChangePage(ids.length)
this.init()
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delAllLoading = false
console.log(err.response.data.message)
})
},
open() {
this.$confirm('你确定删除选中的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doDelete()
})
}
}
}
......
<template>
<div>
<blockquote class="my-blockquote">注意</blockquote>
<pre class="my-code">
1、配置时外链域名需带上协议,也就是必须http/https开头
2、如果七牛云中存在数据,使用同步按钮即可将数据同步到数据库
3、本次集成了七牛云的常用操作,如:上传,下载,删除,同步,支持私有空间上传下载
4、项目中配置存入数据库,如需测试,请使用临时空间进行测试,测试完成及时修改配置,反正数据泄露</pre>
<blockquote class="my-blockquote"> 开始使用</blockquote>
<pre class="my-code">
#引入依赖
&lt;dependency&gt;
&lt;groupId&gt;com.qiniu&lt;/groupId&gt;
&lt;artifactId&gt;qiniu-java-sdk&lt;/artifactId&gt;
&lt;version&gt;[7.2.0, 7.2.99]&lt;/version&gt;
&lt;dependency&gt;
#简单的上传文件
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone0());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
try {
byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(uploadBytes, key, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
} catch (UnsupportedEncodingException ex) {
//ignore
}</pre>
<blockquote class="my-blockquote">更多帮助</blockquote>
<pre class="my-code">更多帮助请查看系统源码,或者七牛云java开发文档
七牛云官网:<a style="color: #00a2d4" href="https://sso.qiniu.com/" target="_blank">https://sso.qiniu.com/</a>
七牛云java开发文档:<a style="color: #00a2d4" href="https://developer.qiniu.com/kodo/sdk/1239/java#3" target="_blank">https://developer.qiniu.com/kodo/sdk/1239/java#3</a></pre>
</div>
</template>
<script>
import '@/styles/description.scss'
export default {
name: 'Description'
}
</script>
<style scoped>
</style>
<template>
<el-dialog :visible.sync="dialog" append-to-body width="500px" @close="doSubmit">
<el-upload
:before-remove="handleBeforeRemove"
:on-success="handleSuccess"
:on-error="handleError"
:file-list="fileList"
:headers="headers"
:action="qiNiuUploadApi"
class="upload-demo"
multiple>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" style="display: block;" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
</template>
<script>
import { mapGetters } from 'vuex'
import { del } from '@/api/qiniu'
import { getToken } from '@/utils/auth'
export default {
data() {
return {
headers: {
'Authorization': 'Bearer ' + getToken()
},
dialog: false,
dialogImageUrl: '',
dialogVisible: false,
fileList: [],
files: []
}
},
computed: {
...mapGetters([
'qiNiuUploadApi'
])
},
methods: {
handleSuccess(response, file, fileList) {
const uid = file.uid
const id = response.id
this.files.push({ uid, id })
},
handleBeforeRemove(file, fileList) {
for (let i = 0; i < this.files.length; i++) {
if (this.files[i].uid === file.uid) {
del(this.files[i].id).then(res => {})
return true
}
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
// 刷新列表数据
doSubmit() {
this.fileList = []
this.dialogVisible = false
this.dialogImageUrl = ''
this.dialog = false
this.$parent.$parent.init()
},
// 监听上传失败
handleError(e, file, fileList) {
const msg = JSON.parse(e.message)
this.$notify({
title: msg.message,
type: 'error',
duration: 2500
})
}
}
}
</script>
<style scoped>
</style>
<template>
<div class="head-container">
<!-- 搜索 -->
<el-input v-model="query.value" clearable placeholder="输入文件名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<!-- 上传 -->
<div style="display: inline-block;margin: 0px 2px;">
<el-button
class="filter-item"
size="mini"
type="primary"
icon="el-icon-upload"
@click="$refs.form.dialog = true">上传文件</el-button>
<eForm ref="form"/>
</div>
<!-- 同步 -->
<el-button :icon="icon" class="filter-item" size="mini" type="warning" @click="synchronize">{{ buttonName }}</el-button>
<div style="display: inline-block;margin: 0px 2px;">
<el-button
v-permission="['ADMIN','PICTURE_ALL','PICTURE_DELETE']"
:loading="delLoading"
:disabled="$parent.data.length === 0 || $parent.$refs.table.selection.length === 0"
class="filter-item"
size="mini"
type="danger"
icon="el-icon-delete"
@click="open">删除</el-button>
</div>
</div>
</template>
<script>
import eForm from './form'
import { sync, delAll } from '@/api/qiniu'
// 查询条件
export default {
components: { eForm },
props: {
query: {
type: Object,
required: true
}
},
data() {
return {
icon: 'el-icon-refresh',
buttonName: '同步数据',
delLoading: false
}
},
methods: {
toQuery() {
this.$parent.page = 0
this.$parent.init()
},
synchronize() {
this.icon = 'el-icon-loading'
this.buttonName = '同步中'
sync().then(res => {
this.icon = 'el-icon-refresh'
this.buttonName = '同步数据'
this.$message({
showClose: true,
message: '数据同步成功',
type: 'success',
duration: 1500
})
this.toQuery()
}).catch(err => {
this.icon = 'el-icon-refresh'
this.buttonName = '同步数据'
console.log(err.response.data.message)
})
},
doDelete() {
this.delLoading = true
const data = this.$parent.$refs.table.selection
const ids = []
for (let i = 0; i < data.length; i++) {
ids.push(data[i].id)
}
delAll(ids).then(res => {
this.delLoading = false
this.$parent.dleChangePage(ids.length)
this.$parent.init()
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
console.log(err.response.data.message)
})
},
open() {
this.$confirm('你确定删除选中的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doDelete()
})
}
}
}
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment