init project
This commit is contained in:
124
nladmin-ui/src/views/components/Echarts.vue
Normal file
124
nladmin-ui/src/views/components/Echarts.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="dashboard-container">
|
||||
<div class="dashboard-editor-container">
|
||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
||||
<heat-map />
|
||||
</el-row>
|
||||
<el-row :gutter="32">
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<radar-chart />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<sunburst />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<gauge />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<div class="chart-wrapper">
|
||||
<rich />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="chart-wrapper">
|
||||
<theme-river />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="32">
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<graph />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<sankey />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :lg="8">
|
||||
<div class="chart-wrapper">
|
||||
<line3-d />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<div class="chart-wrapper">
|
||||
<scatter />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="chart-wrapper">
|
||||
<point />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
||||
<div class="chart-wrapper">
|
||||
<word-cloud />
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
||||
<div class="chart-wrapper">
|
||||
<category />
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RadarChart from '@/components/Echarts/RadarChart'
|
||||
import HeatMap from '@/components/Echarts/HeatMap'
|
||||
import Gauge from '@/components/Echarts/Gauge'
|
||||
import Rich from '@/components/Echarts/Rich'
|
||||
import ThemeRiver from '@/components/Echarts/ThemeRiver'
|
||||
import Sunburst from '@/components/Echarts/Sunburst'
|
||||
import Graph from '@/components/Echarts/Graph'
|
||||
import Sankey from '@/components/Echarts/Sankey'
|
||||
import Scatter from '@/components/Echarts/Scatter'
|
||||
import Line3D from '@/components/Echarts/Line3D'
|
||||
import Category from '@/components/Echarts/Category'
|
||||
import Point from '@/components/Echarts/Point'
|
||||
import WordCloud from '@/components/Echarts/WordCloud'
|
||||
|
||||
export default {
|
||||
name: 'Echarts',
|
||||
components: {
|
||||
Point,
|
||||
Category,
|
||||
Graph,
|
||||
HeatMap,
|
||||
RadarChart,
|
||||
Sunburst,
|
||||
Gauge,
|
||||
Rich,
|
||||
ThemeRiver,
|
||||
Sankey,
|
||||
Line3D,
|
||||
Scatter,
|
||||
WordCloud
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.dashboard-editor-container {
|
||||
padding: 18px 22px 22px 22px;
|
||||
background-color: rgb(240, 242, 245);
|
||||
.chart-wrapper {
|
||||
background: #fff;
|
||||
padding: 16px 16px 0;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
74
nladmin-ui/src/views/components/Editor.vue
Normal file
74
nladmin-ui/src/views/components/Editor.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<p class="warn-content">
|
||||
富文本基于
|
||||
<el-link type="primary" href="https://www.kancloud.cn/wangfupeng/wangeditor3/332599" target="_blank">wangEditor</el-link>
|
||||
</p>
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="15" :lg="15" :xl="15">
|
||||
<div ref="editor" class="text" />
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="9" :lg="9" :xl="9">
|
||||
<div v-html="editorContent" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { upload } from '@/utils/upload'
|
||||
import E from 'wangeditor'
|
||||
export default {
|
||||
name: 'Editor',
|
||||
data() {
|
||||
return {
|
||||
editorContent:
|
||||
`
|
||||
<ul>
|
||||
<li>更多帮助请查看官方文档:<a style="color: #42b983" target="_blank" href="https://www.kancloud.cn/wangfupeng/wangeditor3/332599">wangEditor</a></li>
|
||||
</ul>
|
||||
`
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'imagesUploadApi',
|
||||
'baseApi'
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
const _this = this
|
||||
var editor = new E(this.$refs.editor)
|
||||
// 自定义菜单配置
|
||||
editor.customConfig.zIndex = 10
|
||||
// 文件上传
|
||||
editor.customConfig.customUploadImg = function(files, insert) {
|
||||
// files 是 input 中选中的文件列表
|
||||
// insert 是获取图片 url 后,插入到编辑器的方法
|
||||
files.forEach(image => {
|
||||
upload(_this.imagesUploadApi, image).then(res => {
|
||||
const data = res.data
|
||||
const url = _this.baseApi + '/file/' + data.type + '/' + data.realName
|
||||
insert(url)
|
||||
})
|
||||
})
|
||||
}
|
||||
editor.customConfig.onchange = (html) => {
|
||||
this.editorContent = html
|
||||
}
|
||||
editor.create()
|
||||
// 初始化数据
|
||||
editor.txt.html(this.editorContent)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text {
|
||||
text-align:left;
|
||||
}
|
||||
::v-deep .w-e-text-container {
|
||||
height: 420px !important;
|
||||
}
|
||||
</style>
|
||||
46
nladmin-ui/src/views/components/MarkDown.vue
Normal file
46
nladmin-ui/src/views/components/MarkDown.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<p class="warn-content">
|
||||
Markdown 基于
|
||||
<el-link type="primary" href="https://github.com/hinesboy/mavonEditor" target="_blank">MavonEditor</el-link>
|
||||
</p>
|
||||
<mavon-editor ref="md" :style="'height:' + height" @imgAdd="imgAdd" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { upload } from '@/utils/upload'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'Markdown',
|
||||
data() {
|
||||
return {
|
||||
height: document.documentElement.clientHeight - 200 + 'px'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'imagesUploadApi',
|
||||
'baseApi'
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
window.onresize = function temp() {
|
||||
that.height = document.documentElement.clientHeight - 200 + 'px'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
imgAdd(pos, $file) {
|
||||
upload(this.imagesUploadApi, $file).then(res => {
|
||||
const data = res.data
|
||||
const url = this.baseApi + '/file/' + data.type + '/' + data.realName
|
||||
this.$refs.md.$img2Url(pos, url)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<div class="edit-down-modal">
|
||||
<vxe-input v-model="row[column.property]" class="edit-down-input" @keyup="keyupEvent" />
|
||||
<vxe-button class="edit-popup-button" status="primary" @click="popupEvent">选择</vxe-button>
|
||||
<vxe-modal
|
||||
v-model="modalVisible"
|
||||
show-footer
|
||||
class-name="vxe-table--ignore-clear edit-popup-box"
|
||||
title="选择多条"
|
||||
width="800"
|
||||
height="400"
|
||||
@confirm="confirmEvent"
|
||||
>
|
||||
<template #default>
|
||||
<vxe-grid
|
||||
ref="xGrid"
|
||||
highlight-hover-row
|
||||
auto-resize
|
||||
height="auto"
|
||||
:loading="loading"
|
||||
:pager-config="tablePage"
|
||||
:data="tableData"
|
||||
:columns="tableColumn"
|
||||
@page-change="pageChangeEvent"
|
||||
/>
|
||||
</template>
|
||||
</vxe-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'EditDownModal',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
row: null,
|
||||
column: null,
|
||||
modalVisible: false,
|
||||
loading: false,
|
||||
tableData: [],
|
||||
tableColumn1: [
|
||||
{ field: 'name', title: 'Name' },
|
||||
{ field: 'role', title: 'Role' },
|
||||
{ field: 'sex', title: 'Sex' }
|
||||
],
|
||||
tableColumn: [
|
||||
{ type: 'checkbox', width: 80 },
|
||||
{ field: 'name', title: 'Name' },
|
||||
{ field: 'role', title: 'Role' },
|
||||
{ field: 'sex', title: 'Sex' }
|
||||
],
|
||||
tablePage: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { row, column } = this.params
|
||||
this.row = row
|
||||
this.column = column
|
||||
this.getData().then(data => {
|
||||
this.tableData = data
|
||||
})
|
||||
},
|
||||
getData() {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const list = [
|
||||
{ name: 'Test1', role: '前端', sex: '男' },
|
||||
{ name: 'Test2', role: '后端', sex: '男' },
|
||||
{ name: 'Test3', role: '测试', sex: '男' },
|
||||
{ name: 'Test4', role: '设计师', sex: '女' },
|
||||
{ name: 'Test5', role: '前端', sex: '男' },
|
||||
{ name: 'Test6', role: '前端', sex: '男' },
|
||||
{ name: 'Test7', role: '前端', sex: '男' }
|
||||
]
|
||||
resolve(list)
|
||||
}, 100)
|
||||
})
|
||||
},
|
||||
popupEvent() {
|
||||
this.modalVisible = true
|
||||
},
|
||||
pageChangeEvent({ currentPage, pageSize }) {
|
||||
this.tablePage.currentPage = currentPage
|
||||
this.tablePage.pageSize = pageSize
|
||||
this.loading = true
|
||||
this.getData().then(data => {
|
||||
this.loading = false
|
||||
this.tableData = data
|
||||
})
|
||||
},
|
||||
keyupEvent() {
|
||||
const { row, column } = this
|
||||
const cellValue = row[column.property]
|
||||
this.loading = true
|
||||
this.getData().then(data => {
|
||||
this.loading = false
|
||||
if (cellValue) {
|
||||
this.tableData = data.filter(item => item.name.indexOf(cellValue) > -1)
|
||||
} else {
|
||||
this.tableData = data
|
||||
}
|
||||
})
|
||||
},
|
||||
confirmEvent() {
|
||||
const { row, column } = this
|
||||
const selectRecords = this.$refs.xGrid.getCheckboxRecords()
|
||||
row[column.property] = `${selectRecords.length}条`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.edit-down-modal {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.edit-down-pulldown {
|
||||
width: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
/*.edit-down-input /deep/ .vxe-input--inner {
|
||||
border-radius: 4px 0 0 4px;
|
||||
}*/
|
||||
.edit-popup-button.vxe-button {
|
||||
flex-shrink: 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div class="edit-down-table">
|
||||
<vxe-pulldown ref="xDown" class="edit-down-pulldown" transfer>
|
||||
<template>
|
||||
<vxe-input v-model="row[column.property]" class="edit-down-input" suffix-icon="fa fa-caret-down" @keyup="keyupEvent" @click="clickEvent" @suffix-click="suffixClick" />
|
||||
</template>
|
||||
<template #dropdown>
|
||||
<div class="edit-down-wrapper">
|
||||
<vxe-grid
|
||||
highlight-hover-row
|
||||
auto-resize
|
||||
height="auto"
|
||||
:loading="loading"
|
||||
:pager-config="tablePage"
|
||||
:data="tableData"
|
||||
:columns="tableColumn"
|
||||
@cell-click="selectEvent"
|
||||
@page-change="pageChangeEvent"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-pulldown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'EditDownTable',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
row: null,
|
||||
column: null,
|
||||
loading: false,
|
||||
tableData: [],
|
||||
tableColumn: [
|
||||
{ type: 'seq' },
|
||||
{ field: 'name', title: 'Name' },
|
||||
{ field: 'role', title: 'Role' },
|
||||
{ field: 'sex', title: 'Sex' }
|
||||
],
|
||||
tablePage: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { row, column } = this.params
|
||||
this.row = row
|
||||
this.column = column
|
||||
this.getData().then(data => {
|
||||
this.tableData = data
|
||||
})
|
||||
},
|
||||
getData() {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const list = [
|
||||
{ name: 'Test1', role: '前端', sex: '男' },
|
||||
{ name: 'Test2', role: '后端', sex: '男' },
|
||||
{ name: 'Test3', role: '测试', sex: '男' },
|
||||
{ name: 'Test4', role: '设计师', sex: '女' },
|
||||
{ name: 'Test5', role: '前端', sex: '男' },
|
||||
{ name: 'Test6', role: '前端', sex: '男' },
|
||||
{ name: 'Test7', role: '前端', sex: '男' }
|
||||
]
|
||||
resolve(list)
|
||||
}, 100)
|
||||
})
|
||||
},
|
||||
clickEvent() {
|
||||
this.$refs.xDown.showPanel()
|
||||
},
|
||||
keyupEvent() {
|
||||
const { row, column } = this
|
||||
const cellValue = row[column.property]
|
||||
this.loading = true
|
||||
this.getData().then(data => {
|
||||
this.loading = false
|
||||
if (cellValue) {
|
||||
this.tableData = data.filter(item => item.name.indexOf(cellValue) > -1)
|
||||
} else {
|
||||
this.tableData = data
|
||||
}
|
||||
})
|
||||
},
|
||||
suffixClick() {
|
||||
this.$refs.xDown.togglePanel()
|
||||
},
|
||||
pageChangeEvent({ currentPage, pageSize }) {
|
||||
this.tablePage.currentPage = currentPage
|
||||
this.tablePage.pageSize = pageSize
|
||||
this.loading = true
|
||||
this.getData().then(data => {
|
||||
this.loading = false
|
||||
this.tableData = data
|
||||
})
|
||||
},
|
||||
selectEvent(params) {
|
||||
const { row, column } = this
|
||||
row[column.property] = params.row.name
|
||||
this.$refs.xDown.hidePanel()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.edit-down-pulldown {
|
||||
width: 100%;
|
||||
}
|
||||
.edit-down-wrapper {
|
||||
width: 600px;
|
||||
height: 300px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dcdfe6;
|
||||
box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="edit-popup-modal">
|
||||
<vxe-input v-model="row[column.property]" class="edit-popup-input" placeholder="请选择" />
|
||||
<vxe-button class="edit-popup-button" icon="fa fa-list" type="text" @click="popupEvent" />
|
||||
<vxe-modal
|
||||
v-model="modalVisible"
|
||||
show-footer
|
||||
class-name="vxe-table--ignore-clear edit-popup-box"
|
||||
width="800"
|
||||
height="400"
|
||||
@confirm="confirmEvent"
|
||||
>
|
||||
<template #default>
|
||||
<vxe-grid
|
||||
ref="xGrid"
|
||||
highlight-hover-row
|
||||
auto-resize
|
||||
height="auto"
|
||||
:loading="loading"
|
||||
:pager-config="tablePage"
|
||||
:data="tableData"
|
||||
:columns="tableColumn"
|
||||
@page-change="pageChangeEvent"
|
||||
/>
|
||||
</template>
|
||||
</vxe-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'EditPopupModal',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
row: null,
|
||||
column: null,
|
||||
modalVisible: false,
|
||||
loading: false,
|
||||
tableData: [],
|
||||
tableColumn: [
|
||||
{ type: 'checkbox', width: 80 },
|
||||
{ field: 'name', title: 'Name' },
|
||||
{ field: 'role', title: 'Role' },
|
||||
{ field: 'sex', title: 'Sex' }
|
||||
],
|
||||
tablePage: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { row, column } = this.params
|
||||
this.row = row
|
||||
this.column = column
|
||||
this.getData().then(data => {
|
||||
this.tableData = data
|
||||
})
|
||||
},
|
||||
getData() {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const list = [
|
||||
{ name: 'Test1', role: '前端', sex: '男' },
|
||||
{ name: 'Test2', role: '后端', sex: '男' },
|
||||
{ name: 'Test3', role: '测试', sex: '男' },
|
||||
{ name: 'Test4', role: '设计师', sex: '女' },
|
||||
{ name: 'Test5', role: '前端', sex: '男' },
|
||||
{ name: 'Test6', role: '前端', sex: '男' },
|
||||
{ name: 'Test7', role: '前端', sex: '男' }
|
||||
]
|
||||
resolve(list)
|
||||
}, 100)
|
||||
})
|
||||
},
|
||||
popupEvent() {
|
||||
this.modalVisible = true
|
||||
},
|
||||
pageChangeEvent({ currentPage, pageSize }) {
|
||||
this.tablePage.currentPage = currentPage
|
||||
this.tablePage.pageSize = pageSize
|
||||
this.loading = true
|
||||
this.getData().then(data => {
|
||||
this.loading = false
|
||||
this.tableData = data
|
||||
})
|
||||
},
|
||||
confirmEvent() {
|
||||
const { row, column } = this
|
||||
const selectRecords = this.$refs.xGrid.getCheckboxRecords()
|
||||
row[column.property] = `${selectRecords.length}条`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.edit-popup-modal {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.edit-popup-input {
|
||||
width: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.edit-popup-button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="my-filter-complex">
|
||||
<div class="my-fc-type">
|
||||
<vxe-radio v-model="option.data.type" name="fType" label="has">包含</vxe-radio>
|
||||
<vxe-radio v-model="option.data.type" name="fType" label="eq">等于</vxe-radio>
|
||||
</div>
|
||||
<div class="my-fc-name">
|
||||
<vxe-input v-model="option.data.name" type="text" placeholder="请输入名称" @input="changeOptionEvent()" />
|
||||
</div>
|
||||
<div class="my-fc-footer">
|
||||
<vxe-button status="primary" @click="confirmEvent">确认</vxe-button>
|
||||
<vxe-button @click="resetEvent">重置</vxe-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FilterComplex',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
size: 'mini', // 被所有子组件继承 size
|
||||
column: null,
|
||||
option: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { column } = this.params
|
||||
const option = column.filters[0]
|
||||
this.column = column
|
||||
this.option = option
|
||||
},
|
||||
changeOptionEvent() {
|
||||
const { params, option } = this
|
||||
const { $panel } = params
|
||||
const checked = !!option.data.name
|
||||
$panel.changeOption(null, checked, option)
|
||||
},
|
||||
confirmEvent() {
|
||||
const { $panel } = this.params
|
||||
$panel.confirmFilter()
|
||||
},
|
||||
resetEvent() {
|
||||
const { $panel } = this.params
|
||||
$panel.resetFilter()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-filter-complex {
|
||||
width: 260px;
|
||||
padding: 5px 15px 10px 15px;
|
||||
}
|
||||
.my-filter-complex .my-fc-type {
|
||||
padding: 8px 0;
|
||||
}
|
||||
.my-filter-complex .my-fc-footer {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="my-filter-content">
|
||||
<div class="my-fc-search">
|
||||
<div class="my-fc-search-top">
|
||||
<vxe-input v-model="option.data.sVal" placeholder="搜索" suffix-icon="fa fa-search" />
|
||||
</div>
|
||||
<div class="my-fc-search-content">
|
||||
<template v-if="valList.length">
|
||||
<ul class="my-fc-search-list my-fc-search-list-head">
|
||||
<li class="my-fc-search-item">
|
||||
<vxe-checkbox v-model="isAll" @change="changeAllEvent">全选</vxe-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="my-fc-search-list my-fc-search-list-body">
|
||||
<li v-for="(item, sIndex) in valList" :key="sIndex" class="my-fc-search-item">
|
||||
<vxe-checkbox v-model="item.checked">{{ item.value }}</vxe-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="my-fc-search-empty">无匹配项</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-fc-footer">
|
||||
<vxe-button status="primary" @click="confirmFilterEvent">确认</vxe-button>
|
||||
<vxe-button @click="resetFilterEvent">重置</vxe-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import XEUtils from 'xe-utils'
|
||||
|
||||
export default {
|
||||
name: 'FilterContent',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
size: 'mini',
|
||||
isAll: false,
|
||||
option: null,
|
||||
colValList: [],
|
||||
valList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { $table, column } = this.params
|
||||
const { fullData } = $table.getTableData()
|
||||
const option = column.filters[0]
|
||||
const { vals } = option.data
|
||||
const colValList = Object.keys(XEUtils.groupBy(fullData, column.property)).map(val => {
|
||||
return {
|
||||
checked: vals.includes(val),
|
||||
value: val
|
||||
}
|
||||
})
|
||||
this.option = option
|
||||
this.colValList = colValList
|
||||
this.valList = colValList
|
||||
},
|
||||
searchEvent() {
|
||||
const { option, colValList } = this
|
||||
this.valList = option.data.sVal ? colValList.filter(item => item.value.indexOf(option.data.sVal) > -1) : colValList
|
||||
},
|
||||
changeAllEvent() {
|
||||
const { isAll } = this
|
||||
this.valList.forEach(item => {
|
||||
item.checked = isAll
|
||||
})
|
||||
},
|
||||
confirmFilterEvent(evnt) {
|
||||
const { params, option, valList } = this
|
||||
const { data } = option
|
||||
const { $panel } = params
|
||||
data.vals = valList.filter(item => item.checked).map(item => item.value)
|
||||
$panel.changeOption(evnt, true, option)
|
||||
$panel.confirmFilter()
|
||||
},
|
||||
resetFilterEvent() {
|
||||
const { $panel } = this.params
|
||||
$panel.resetFilter()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.my-filter-content {
|
||||
padding: 10px;
|
||||
user-select: none;
|
||||
}
|
||||
.my-filter-content .my-fc-search .my-fc-search-top {
|
||||
position: relative;
|
||||
padding: 5px 0;
|
||||
}
|
||||
.my-filter-content .my-fc-search .my-fc-search-top > input {
|
||||
border: 1px solid #ABABAB;
|
||||
padding: 0 20px 0 2px;
|
||||
width: 200px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.my-filter-content .my-fc-search .my-fc-search-content {
|
||||
padding: 2px 10px;
|
||||
}
|
||||
.my-filter-content .my-fc-search-empty {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.my-filter-content .my-fc-search-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.my-filter-content .my-fc-search-list-body {
|
||||
overflow: auto;
|
||||
height: 120px;
|
||||
}
|
||||
.my-filter-content .my-fc-search-list .my-fc-search-item {
|
||||
padding: 2px 0;
|
||||
display: block;
|
||||
}
|
||||
.my-filter-content .my-fc-footer {
|
||||
text-align: right;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.my-filter-content .my-fc-footer button {
|
||||
padding: 0 15px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<div class="my-filter-excel">
|
||||
<div class="my-fe-top">
|
||||
<ul class="my-fe-menu-group">
|
||||
<li class="my-fe-menu-link">
|
||||
<span>升序</span>
|
||||
</li>
|
||||
<li class="my-fe-menu-link">
|
||||
<span>倒序</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="my-fe-menu-group">
|
||||
<li class="my-fe-menu-link" @click="resetFilterEvent">
|
||||
<span>清除筛选</span>
|
||||
</li>
|
||||
<li class="my-fe-menu-link">
|
||||
<i class="fa fa-filter my-fe-menu-link-left-icon" />
|
||||
<span>筛选条件</span>
|
||||
<i class="fa fa-caret-right my-fe-menu-link-right-icon" />
|
||||
<div class="my-fe-menu-child-list">
|
||||
<ul v-for="(cList, gIndex) in caseGroups" :key="gIndex" class="my-fe-child-menu-group-list">
|
||||
<li v-for="(cItem, cIndex) in cList" :key="cIndex" class="my-fe-child-menu-item" @click="childMenuClickEvent(cItem)">
|
||||
<span>{{ cItem.label }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="my-fe-search">
|
||||
<div class="my-fe-search-top">
|
||||
<input v-model="option.data.sVal" placeholder="搜索">
|
||||
<i class="fa fa-search my-fe-search-icon" />
|
||||
</div>
|
||||
<ul class="my-fe-search-list">
|
||||
<li class="my-fe-search-item" @click="sAllEvent">
|
||||
<i class="fa fa-square-o my-fe-search-item-icon" />
|
||||
<span>(全选)</span>
|
||||
</li>
|
||||
<li v-for="(val, sIndex) in searchList" :key="sIndex" class="my-fe-search-item" @click="sItemEvent(val)">
|
||||
<i :class="[option.data.vals.indexOf(val) === -1 ? 'fa fa-square-o my-fe-search-item-icon' : 'fa fa-check-square-o my-fe-search-item-icon']" />
|
||||
<span>{{ val }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="my-fe-footer">
|
||||
<vxe-button status="primary" @click="confirmFilterEvent">确认</vxe-button>
|
||||
<vxe-button @click="resetFilterEvent">重置</vxe-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import XEUtils from 'xe-utils'
|
||||
|
||||
export default {
|
||||
name: 'FilterExcel',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
column: null,
|
||||
option: null,
|
||||
colValList: [],
|
||||
caseGroups: [
|
||||
[
|
||||
{ value: 'equal', label: '等于' },
|
||||
{ value: 'ne', label: '不等于' }
|
||||
],
|
||||
[
|
||||
{ value: 'greater', label: '大于' },
|
||||
{ value: 'ge', label: '大于或等于' },
|
||||
{ value: 'less', label: '小于' },
|
||||
{ value: 'le', label: '小于或等于' }
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
searchList() {
|
||||
const { option, colValList } = this
|
||||
return option.data.sVal ? colValList.filter(val => val.indexOf(option.data.sVal) > -1) : colValList
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { $table, column } = this.params
|
||||
const { fullData } = $table.getTableData()
|
||||
const option = column.filters[0]
|
||||
const colValList = Object.keys(XEUtils.groupBy(fullData, column.property))
|
||||
this.column = column
|
||||
this.option = option
|
||||
this.colValList = colValList
|
||||
},
|
||||
sAllEvent() {
|
||||
const { data } = this.option
|
||||
if (data.vals.length > 0) {
|
||||
data.vals = []
|
||||
} else {
|
||||
data.vals = this.colValList
|
||||
}
|
||||
},
|
||||
sItemEvent(val) {
|
||||
const { data } = this.option
|
||||
const vIndex = data.vals.indexOf(val)
|
||||
if (vIndex === -1) {
|
||||
data.vals.push(val)
|
||||
} else {
|
||||
data.vals.splice(vIndex, 1)
|
||||
}
|
||||
},
|
||||
confirmFilterEvent(evnt) {
|
||||
const { params, option } = this
|
||||
const { data } = option
|
||||
const { $panel } = params
|
||||
data.f1 = ''
|
||||
data.f2 = ''
|
||||
$panel.changeOption(evnt, true, option)
|
||||
$panel.confirmFilter()
|
||||
},
|
||||
resetFilterEvent() {
|
||||
const { $panel } = this.params
|
||||
$panel.resetFilter()
|
||||
},
|
||||
childMenuClickEvent(cItem) {
|
||||
this.$XModal.alert({ content: cItem.label })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.my-filter-excel {
|
||||
user-select: none;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 190px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1px solid #E2E4E7;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link {
|
||||
position: relative;
|
||||
padding: 4px 20px 4px 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link:hover {
|
||||
background-color: #C5C5C5;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link-left-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 6px;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link-right-icon {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 6px;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link:hover .my-fe-menu-child-list {
|
||||
display: block;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-menu-child-list {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -120px;
|
||||
width: 120px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #DADCE0;
|
||||
box-shadow: 3px 3px 4px -2px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list {
|
||||
position: relative;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 90px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1px solid #E2E4E7;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list > .my-fe-child-menu-item {
|
||||
position: relative;
|
||||
padding: 4px 20px 4px 30px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.my-filter-excel .my-fe-top .my-fe-menu-group .my-fe-menu-link .my-fe-child-menu-group-list > .my-fe-child-menu-item:hover {
|
||||
background-color: #C5C5C5;
|
||||
}
|
||||
.my-filter-excel .my-fe-search {
|
||||
padding: 0 10px 0 30px;
|
||||
}
|
||||
.my-filter-excel .my-fe-search .my-fe-search-top {
|
||||
position: relative;
|
||||
padding: 5px 0;
|
||||
}
|
||||
.my-filter-excel .my-fe-search .my-fe-search-top > input {
|
||||
border: 1px solid #ABABAB;
|
||||
padding: 0 20px 0 2px;
|
||||
width: 200px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.my-filter-excel .my-fe-search .my-fe-search-top > .my-fe-search-icon {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 10px;
|
||||
}
|
||||
.my-filter-excel .my-fe-search .my-fe-search-list {
|
||||
margin: 0;
|
||||
border: 1px solid #E2E4E7;
|
||||
padding: 2px 10px;
|
||||
overflow: auto;
|
||||
height: 140px;
|
||||
}
|
||||
.my-filter-excel .my-fe-search .my-fe-search-list .my-fe-search-item {
|
||||
cursor: pointer;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.my-filter-excel .my-fe-search .my-fe-search-list .my-fe-search-item .my-fe-search-item-icon {
|
||||
width: 16px;
|
||||
}
|
||||
.my-filter-excel .my-fe-footer {
|
||||
text-align: right;
|
||||
padding: 10px 10px 10px 0;
|
||||
}
|
||||
.my-fe-popup .my-fe-popup-filter {
|
||||
padding-left: 30px;
|
||||
}
|
||||
.my-fe-popup .my-fe-popup-filter > .my-fe-popup-filter-select {
|
||||
width: 120px;
|
||||
}
|
||||
.my-fe-popup .my-fe-popup-filter > .my-fe-popup-filter-input {
|
||||
margin-left: 15px;
|
||||
width: 380px;
|
||||
}
|
||||
.my-fe-popup .my-fe-popup-describe {
|
||||
padding: 20px 0 10px 0;
|
||||
}
|
||||
.my-fe-popup .my-fe-popup-concat {
|
||||
padding-left: 50px;
|
||||
}
|
||||
.my-fe-popup .my-fe-popup-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div class="my-filter-input">
|
||||
<vxe-input v-model="option.data" type="text" placeholder="支持回车筛选" @keyup="keyupEvent" @input="changeOptionEvent" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FilterInput',
|
||||
props: {
|
||||
params: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
column: null,
|
||||
option: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const { column } = this.params
|
||||
const option = column.filters[0]
|
||||
this.column = column
|
||||
this.option = option
|
||||
},
|
||||
changeOptionEvent() {
|
||||
const { params, option } = this
|
||||
const { $panel } = params
|
||||
const checked = !!option.data
|
||||
$panel.changeOption(null, checked, option)
|
||||
},
|
||||
keyupEvent({ $event }) {
|
||||
const { params } = this
|
||||
const { $panel } = params
|
||||
if ($event.keyCode === 13) {
|
||||
$panel.confirmFilter()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-filter-input {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<vxe-form :data="formData" @submit="searchEvent">
|
||||
<vxe-form-item field="name" title="名称">
|
||||
<template #default="{ data }">
|
||||
<vxe-input v-model="data.name" placeholder="请输入名称" clearable />
|
||||
</template>
|
||||
</vxe-form-item>
|
||||
<vxe-form-item field="sex" title="性别">
|
||||
<template #default="{ data }">
|
||||
<select v-model="data.sex" class="vxe-select">
|
||||
<option v-for="(item, index) in sexList" :key="index" :value="item.value">{{ item.label }}</option>
|
||||
</select>
|
||||
</template>
|
||||
</vxe-form-item>
|
||||
<vxe-form-item field="role" title="角色">
|
||||
<template #default="{ data }">
|
||||
<vxe-input v-model="data.role" placeholder="请输入角色" clearable />
|
||||
</template>
|
||||
</vxe-form-item>
|
||||
<vxe-form-item>
|
||||
<template #default>
|
||||
<vxe-button type="submit" status="primary">搜索</vxe-button>
|
||||
</template>
|
||||
</vxe-form-item>
|
||||
</vxe-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FormSimple',
|
||||
props: {
|
||||
formData: Object,
|
||||
params: Object,
|
||||
context: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sexList: [
|
||||
{ label: '', value: '' },
|
||||
{ label: '女', value: '0' },
|
||||
{ label: '男', value: '1' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchEvent() {
|
||||
const { $grid } = this.context
|
||||
$grid.commitProxy('reload')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
28
nladmin-ui/src/views/components/VxeTableRender/content.js
Normal file
28
nladmin-ui/src/views/components/VxeTableRender/content.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import VXETable from 'vxe-table'
|
||||
|
||||
// 创建一个简单的展开内容渲染
|
||||
VXETable.renderer.add('MyExpand', {
|
||||
renderExpand(h, renderOpts, params) {
|
||||
const { row } = params
|
||||
return [
|
||||
<ul>
|
||||
<li>
|
||||
<span>ID:</span>
|
||||
<span>{row.id}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>Name:</span>
|
||||
<span>{row.name}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>UpdateTime:</span>
|
||||
<span>{row.updateTime}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>CreateTime:</span>
|
||||
<span>{row.createTime}</span>
|
||||
</li>
|
||||
</ul>
|
||||
]
|
||||
}
|
||||
})
|
||||
12
nladmin-ui/src/views/components/VxeTableRender/default.js
Normal file
12
nladmin-ui/src/views/components/VxeTableRender/default.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import VXETable from 'vxe-table'
|
||||
// 创建一个简单的超链接渲染
|
||||
VXETable.renderer.add('MyLink', {
|
||||
// 默认显示模板
|
||||
renderDefault(h, renderOpts, params) {
|
||||
const { row, column } = params
|
||||
const { events } = renderOpts
|
||||
return [
|
||||
<a class='link' onClick={() => events.click(params)}>{row[column.property]}</a>
|
||||
]
|
||||
}
|
||||
})
|
||||
57
nladmin-ui/src/views/components/VxeTableRender/edit.js
Normal file
57
nladmin-ui/src/views/components/VxeTableRender/edit.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import Vue from 'vue'
|
||||
import VXETable from 'vxe-table'
|
||||
import EditDownTable from './components/EditDownTable.vue'
|
||||
import EditPopupModal from './components/EditPopupModal.vue'
|
||||
import EditDownModal from './components/EditDownModal.vue'
|
||||
|
||||
Vue.component(EditDownTable.name, EditDownTable)
|
||||
Vue.component(EditPopupModal.name, EditPopupModal)
|
||||
Vue.component(EditDownModal.name, EditDownModal)
|
||||
|
||||
// 创建一个简单的输入框渲染
|
||||
VXETable.renderer.add('MyInput', {
|
||||
// 激活时自动聚焦
|
||||
autofocus: '.my-cell',
|
||||
// 可编辑激活模板
|
||||
renderEdit(h, renderOpts, { row, column }) {
|
||||
return [
|
||||
<vxe-input class='my-cell' v-model={ row[column.property] } prefix-icon='fa fa-user' suffix-icon='fa fa-search' clearable></vxe-input>
|
||||
]
|
||||
},
|
||||
// 可编辑显示模板
|
||||
renderCell(h, renderOpts, { row, column }) {
|
||||
return [
|
||||
<span>{ row[column.property] }</span>
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个下拉表格渲染
|
||||
VXETable.renderer.add('EditDownTable', {
|
||||
autofocus: '.vxe-input--inner',
|
||||
renderEdit(h, renderOpts, params) {
|
||||
return [
|
||||
<edit-down-table params={ params }></edit-down-table>
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个弹窗渲染
|
||||
VXETable.renderer.add('EditPopupModal', {
|
||||
autofocus: '.vxe-input--inner',
|
||||
renderEdit(h, renderOpts, params) {
|
||||
return [
|
||||
<edit-popup-modal params={ params }></edit-popup-modal>
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个复杂的组合渲染
|
||||
VXETable.renderer.add('EditDownModal', {
|
||||
autofocus: '.vxe-input--inner',
|
||||
renderEdit(h, renderOpts, params) {
|
||||
return [
|
||||
<edit-down-modal params={ params } renderOpts={ renderOpts }></edit-down-modal>
|
||||
]
|
||||
}
|
||||
})
|
||||
13
nladmin-ui/src/views/components/VxeTableRender/empty.js
Normal file
13
nladmin-ui/src/views/components/VxeTableRender/empty.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import VXETable from 'vxe-table'
|
||||
// 创建一个简单的空内容渲染
|
||||
VXETable.renderer.add('NotData', {
|
||||
// 空内容模板
|
||||
renderEmpty() {
|
||||
return [
|
||||
<span>
|
||||
<img src='/vxe-table/static/other/img1.gif'/>
|
||||
<p>亲,没有更多数据了!</p>
|
||||
</span>
|
||||
]
|
||||
}
|
||||
})
|
||||
123
nladmin-ui/src/views/components/VxeTableRender/filter.js
Normal file
123
nladmin-ui/src/views/components/VxeTableRender/filter.js
Normal file
@@ -0,0 +1,123 @@
|
||||
import Vue from 'vue'
|
||||
import VXETable from 'vxe-table'
|
||||
import FilterInput from './components/FilterInput.vue'
|
||||
import FilterContent from './components/FilterContent.vue'
|
||||
import FilterComplex from './components/FilterComplex.vue'
|
||||
import FilterExcel from './components/FilterExcel.vue'
|
||||
|
||||
Vue.component(FilterInput.name, FilterInput)
|
||||
Vue.component(FilterContent.name, FilterContent)
|
||||
Vue.component(FilterComplex.name, FilterComplex)
|
||||
Vue.component(FilterExcel.name, FilterExcel)
|
||||
|
||||
// 创建一个简单的输入框筛选
|
||||
VXETable.renderer.add('FilterInput', {
|
||||
// 筛选模板
|
||||
renderFilter(h, renderOpts, params) {
|
||||
return [
|
||||
<filter-input params={params}></filter-input>
|
||||
]
|
||||
},
|
||||
// 重置数据方法
|
||||
filterResetMethod({ options }) {
|
||||
options.forEach(option => {
|
||||
option.data = ''
|
||||
})
|
||||
},
|
||||
// 重置筛选复原方法(当未点击确认时,该选项将被恢复为默认值)
|
||||
filterRecoverMethod({ option }) {
|
||||
option.data = ''
|
||||
},
|
||||
// 筛选方法
|
||||
filterMethod({ option, row, column }) {
|
||||
const { data } = option
|
||||
const cellValue = row[column.property]
|
||||
if (cellValue) {
|
||||
return cellValue.indexOf(data) > -1
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个条件的渲染器
|
||||
VXETable.renderer.add('FilterComplex', {
|
||||
// 不显示底部按钮,使用自定义的按钮
|
||||
isFooter: false,
|
||||
// 筛选模板
|
||||
renderFilter(h, renderOpts, params) {
|
||||
return [
|
||||
<filter-complex params={params}></filter-complex>
|
||||
]
|
||||
},
|
||||
// 重置数据方法
|
||||
filterResetMethod({ options }) {
|
||||
options.forEach(option => {
|
||||
option.data = { type: 'has', name: '' }
|
||||
})
|
||||
},
|
||||
// 筛选数据方法
|
||||
filterMethod({ option, row, column }) {
|
||||
const cellValue = row[column.property]
|
||||
const { name } = option.data
|
||||
if (cellValue) {
|
||||
return cellValue.indexOf(name) > -1
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个支持列内容的筛选
|
||||
VXETable.renderer.add('FilterContent', {
|
||||
// 不显示底部按钮,使用自定义的按钮
|
||||
isFooter: false,
|
||||
// 筛选模板
|
||||
renderFilter(h, renderOpts, params) {
|
||||
return [
|
||||
<filter-content params={params}></filter-content>
|
||||
]
|
||||
},
|
||||
// 重置数据方法
|
||||
filterResetMethod({ options }) {
|
||||
options.forEach(option => {
|
||||
option.data = { vals: [], sVal: '' }
|
||||
})
|
||||
},
|
||||
// 筛选数据方法
|
||||
filterMethod({ option, row, column }) {
|
||||
const { vals } = option.data
|
||||
const cellValue = row[column.property]
|
||||
return vals.includes(cellValue)
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个实现Excel的筛选器
|
||||
VXETable.renderer.add('FilterExcel', {
|
||||
// 不显示底部按钮,使用自定义的按钮
|
||||
isFooter: false,
|
||||
// 筛选模板
|
||||
renderFilter(h, renderOpts, params) {
|
||||
return [
|
||||
<filter-excel params={params}></filter-excel>
|
||||
]
|
||||
},
|
||||
// 重置数据方法
|
||||
filterResetMethod({ options }) {
|
||||
options.forEach(option => {
|
||||
option.data = { vals: [], sVal: '', fMenu: '', f1Type: '', f1Val: '', fMode: 'and', f2Type: '', f2Val: '' }
|
||||
})
|
||||
},
|
||||
// 筛选数据方法
|
||||
filterMethod({ option, row, column }) {
|
||||
const cellValue = row[column.property]
|
||||
const { vals, f1Type, f1Val } = option.data
|
||||
if (cellValue) {
|
||||
if (f1Type) {
|
||||
return cellValue.indexOf(f1Val) > -1
|
||||
} else if (vals.length) {
|
||||
// 通过指定值筛选
|
||||
return vals.includes(cellValue)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
23
nladmin-ui/src/views/components/VxeTableRender/form.js
Normal file
23
nladmin-ui/src/views/components/VxeTableRender/form.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import VXETable from 'vxe-table'
|
||||
// 创建一个简单的表单-输入框渲染
|
||||
VXETable.renderer.add('FormItemInput', {
|
||||
// 项内容模板
|
||||
renderItemContent(h, renderOpts, params) {
|
||||
const { data, property } = params
|
||||
const { props } = renderOpts
|
||||
return [
|
||||
<vxe-input v-model={data[property]} {...{ props }}></vxe-input>
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个简单的表单-按钮组渲染
|
||||
VXETable.renderer.add('FormItemButtonGroup', {
|
||||
// 项内容模板
|
||||
renderItemContent() {
|
||||
return [
|
||||
<vxe-button type='submit' status='primary'>查询</vxe-button>,
|
||||
<vxe-button type='reset'>重置</vxe-button>
|
||||
]
|
||||
}
|
||||
})
|
||||
7
nladmin-ui/src/views/components/VxeTableRender/index.js
Normal file
7
nladmin-ui/src/views/components/VxeTableRender/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import './default'
|
||||
import './filter'
|
||||
import './edit'
|
||||
import './content'
|
||||
import './toolbar'
|
||||
import './form'
|
||||
import './empty'
|
||||
29
nladmin-ui/src/views/components/VxeTableRender/toolbar.js
Normal file
29
nladmin-ui/src/views/components/VxeTableRender/toolbar.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import VXETable from 'vxe-table'
|
||||
// 创建一个简单的工具栏-左侧按钮渲染
|
||||
VXETable.renderer.add('ToolbarButtonDownload', {
|
||||
renderToolbarButton(h, renderOpts, params) {
|
||||
const { events = {}} = renderOpts
|
||||
const { button } = params
|
||||
return [
|
||||
<vxe-button circle icon='fa fa-cloud-download' onClick={
|
||||
() => {
|
||||
events.click(button)
|
||||
}
|
||||
}></vxe-button>
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 创建一个简单的工具栏-右侧工具渲染
|
||||
VXETable.renderer.add('ToolbarToolPrint', {
|
||||
renderToolbarTool(h, renderOpts, params) {
|
||||
const { $table } = params
|
||||
return [
|
||||
<vxe-button circle icon='fa fa-print' onClick={
|
||||
() => {
|
||||
$table.print()
|
||||
}
|
||||
}></vxe-button>
|
||||
]
|
||||
}
|
||||
})
|
||||
207
nladmin-ui/src/views/components/YamlEdit.vue
Normal file
207
nladmin-ui/src/views/components/YamlEdit.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<p class="warn-content">
|
||||
Yaml编辑器 基于
|
||||
<a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirror</a>,
|
||||
主题预览地址 <a href="https://codemirror.net/demo/theme.html#idea" target="_blank">Theme</a>
|
||||
</p>
|
||||
<Yaml :value="value" :height="height" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Yaml from '@/components/YamlEdit/index'
|
||||
export default {
|
||||
name: 'YamlEdit',
|
||||
components: { Yaml },
|
||||
data() {
|
||||
return {
|
||||
height: document.documentElement.clientHeight - 210 + 'px',
|
||||
value: '# 展示数据,如需更换主题,请在src/components/YamlEdit 目录中搜索原主题名称进行替换\n' +
|
||||
'\n' +
|
||||
'# ===================================================================\n' +
|
||||
'# Spring Boot configuration.\n' +
|
||||
'#\n' +
|
||||
'# This configuration will be overridden by the Spring profile you use,\n' +
|
||||
'# for example application-dev.yml if you use the "dev" profile.\n' +
|
||||
'#\n' +
|
||||
'# More information on profiles: https://www.jhipster.tech/profiles/\n' +
|
||||
'# More information on configuration properties: https://www.jhipster.tech/common-application-properties/\n' +
|
||||
'# ===================================================================\n' +
|
||||
'\n' +
|
||||
'# ===================================================================\n' +
|
||||
'# Standard Spring Boot properties.\n' +
|
||||
'# Full reference is available at:\n' +
|
||||
'# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html\n' +
|
||||
'# ===================================================================\n' +
|
||||
'\n' +
|
||||
'eureka:\n' +
|
||||
' client:\n' +
|
||||
' enabled: true\n' +
|
||||
' healthcheck:\n' +
|
||||
' enabled: true\n' +
|
||||
' fetch-registry: true\n' +
|
||||
' register-with-eureka: true\n' +
|
||||
' instance-info-replication-interval-seconds: 10\n' +
|
||||
' registry-fetch-interval-seconds: 10\n' +
|
||||
' instance:\n' +
|
||||
' appname: product\n' +
|
||||
' instanceId: product:${spring.application.instance-id:${random.value}}\n' +
|
||||
' #instanceId: 127.0.0.1:9080\n' +
|
||||
' lease-renewal-interval-in-seconds: 5\n' +
|
||||
' lease-expiration-duration-in-seconds: 10\n' +
|
||||
' status-page-url-path: ${management.endpoints.web.base-path}/info\n' +
|
||||
' health-check-url-path: ${management.endpoints.web.base-path}/health\n' +
|
||||
' metadata-map:\n' +
|
||||
' zone: primary # This is needed for the load balancer\n' +
|
||||
' profile: ${spring.profiles.active}\n' +
|
||||
' version: ${info.project.version:}\n' +
|
||||
' git-version: ${git.commit.id.describe:}\n' +
|
||||
' git-commit: ${git.commit.id.abbrev:}\n' +
|
||||
' git-branch: ${git.branch:}\n' +
|
||||
'ribbon:\n' +
|
||||
' ReadTimeout: 120000\n' +
|
||||
' ConnectTimeout: 300000\n' +
|
||||
' eureka:\n' +
|
||||
' enabled: true\n' +
|
||||
'zuul:\n' +
|
||||
' host:\n' +
|
||||
' connect-timeout-millis: 5000\n' +
|
||||
' max-per-route-connections: 10000\n' +
|
||||
' max-total-connections: 5000\n' +
|
||||
' socket-timeout-millis: 60000\n' +
|
||||
' semaphore:\n' +
|
||||
' max-semaphores: 500\n' +
|
||||
'\n' +
|
||||
'feign:\n' +
|
||||
' hystrix:\n' +
|
||||
' enabled: true\n' +
|
||||
' client:\n' +
|
||||
' config:\n' +
|
||||
' default:\n' +
|
||||
' connectTimeout: 500000\n' +
|
||||
' readTimeout: 500000\n' +
|
||||
'\n' +
|
||||
'# See https://github.com/Netflix/Hystrix/wiki/Configuration\n' +
|
||||
'hystrix:\n' +
|
||||
' command:\n' +
|
||||
' default:\n' +
|
||||
' circuitBreaker:\n' +
|
||||
' sleepWindowInMilliseconds: 100000\n' +
|
||||
' forceClosed: true\n' +
|
||||
' execution:\n' +
|
||||
' isolation:\n' +
|
||||
'# strategy: SEMAPHORE\n' +
|
||||
'# See https://github.com/spring-cloud/spring-cloud-netflix/issues/1330\n' +
|
||||
' thread:\n' +
|
||||
' timeoutInMilliseconds: 60000\n' +
|
||||
' shareSecurityContext: true\n' +
|
||||
'\n' +
|
||||
'management:\n' +
|
||||
' endpoints:\n' +
|
||||
' web:\n' +
|
||||
' base-path: /management\n' +
|
||||
' exposure:\n' +
|
||||
' include: ["configprops", "env", "health", "info", "threaddump"]\n' +
|
||||
' endpoint:\n' +
|
||||
' health:\n' +
|
||||
' show-details: when_authorized\n' +
|
||||
' info:\n' +
|
||||
' git:\n' +
|
||||
' mode: full\n' +
|
||||
' health:\n' +
|
||||
' mail:\n' +
|
||||
' enabled: false # When using the MailService, configure an SMTP server and set this to true\n' +
|
||||
' metrics:\n' +
|
||||
' enabled: false # http://micrometer.io/ is disabled by default, as we use http://metrics.dropwizard.io/ instead\n' +
|
||||
'\n' +
|
||||
'spring:\n' +
|
||||
' application:\n' +
|
||||
' name: product\n' +
|
||||
' jpa:\n' +
|
||||
' open-in-view: false\n' +
|
||||
' hibernate:\n' +
|
||||
' ddl-auto: update\n' +
|
||||
' naming:\n' +
|
||||
' physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy\n' +
|
||||
' implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy\n' +
|
||||
' messages:\n' +
|
||||
' basename: i18n/messages\n' +
|
||||
' mvc:\n' +
|
||||
' favicon:\n' +
|
||||
' enabled: false\n' +
|
||||
' thymeleaf:\n' +
|
||||
' mode: HTML\n' +
|
||||
'security:\n' +
|
||||
' oauth2:\n' +
|
||||
' resource:\n' +
|
||||
' filter-order: 3\n' +
|
||||
'\n' +
|
||||
'server:\n' +
|
||||
' servlet:\n' +
|
||||
' session:\n' +
|
||||
' cookie:\n' +
|
||||
' http-only: true\n' +
|
||||
'\n' +
|
||||
'# Properties to be exposed on the /info management endpoint\n' +
|
||||
'info:\n' +
|
||||
' # Comma separated list of profiles that will trigger the ribbon to show\n' +
|
||||
' display-ribbon-on-profiles: "dev"\n' +
|
||||
'\n' +
|
||||
'# ===================================================================\n' +
|
||||
'# JHipster specific properties\n' +
|
||||
'#\n' +
|
||||
'# Full reference is available at: https://www.jhipster.tech/common-application-properties/\n' +
|
||||
'# ===================================================================\n' +
|
||||
'\n' +
|
||||
'jhipster:\n' +
|
||||
' async:\n' +
|
||||
' core-pool-size: 2\n' +
|
||||
' max-pool-size: 50\n' +
|
||||
' queue-capacity: 10000\n' +
|
||||
' # By default CORS is disabled. Uncomment to enable.\n' +
|
||||
' #cors:\n' +
|
||||
' #allowed-origins: "*"\n' +
|
||||
' #allowed-methods: "*"\n' +
|
||||
' #allowed-headers: "*"\n' +
|
||||
' #exposed-headers: "Authorization,Link,X-Total-Count"\n' +
|
||||
' #allow-credentials: true\n' +
|
||||
' #max-age: 1800\n' +
|
||||
' mail:\n' +
|
||||
' from: product@localhost\n' +
|
||||
' swagger:\n' +
|
||||
' default-include-pattern: /api/.*\n' +
|
||||
' title: product API\n' +
|
||||
' description: product API documentation\n' +
|
||||
' version: 0.0.1\n' +
|
||||
' terms-of-service-url:\n' +
|
||||
' contact-name:\n' +
|
||||
' contact-url:\n' +
|
||||
' contact-email:\n' +
|
||||
' license:\n' +
|
||||
' license-url:\n' +
|
||||
'\n' +
|
||||
'# ===================================================================\n' +
|
||||
'# Application specific properties\n' +
|
||||
'# Add your own application properties here, see the ApplicationProperties class\n' +
|
||||
'# to have type-safe configuration, like in the JHipsterProperties above\n' +
|
||||
'#\n' +
|
||||
'# More documentation is available at:\n' +
|
||||
'# https://www.jhipster.tech/common-application-properties/\n' +
|
||||
'# ===================================================================\n' +
|
||||
'\n' +
|
||||
'# application:\n'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
window.onresize = function temp() {
|
||||
that.height = document.documentElement.clientHeight - 210 + 'px'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
41
nladmin-ui/src/views/components/excel/upload-excel.vue
Normal file
41
nladmin-ui/src/views/components/excel/upload-excel.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" />
|
||||
<el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;">
|
||||
<el-table-column v-for="item of tableHeader" :key="item" :prop="item" :label="item" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UploadExcelComponent from '@/components/UploadExcel/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'UploadExcel',
|
||||
components: { UploadExcelComponent },
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
tableHeader: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeUpload(file) {
|
||||
const isLt1M = file.size / 1024 / 1024 < 1
|
||||
if (isLt1M) {
|
||||
return true
|
||||
}
|
||||
|
||||
this.$message({
|
||||
message: '请不要上传大于1m的文件.',
|
||||
type: 'warning'
|
||||
})
|
||||
return false
|
||||
},
|
||||
handleSuccess({ results, header }) {
|
||||
this.tableData = results
|
||||
this.tableHeader = header
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
74
nladmin-ui/src/views/components/icons/element-icons.js
Normal file
74
nladmin-ui/src/views/components/icons/element-icons.js
Normal file
@@ -0,0 +1,74 @@
|
||||
const elementIcons = [
|
||||
'info',
|
||||
'error',
|
||||
'success',
|
||||
'warning',
|
||||
'question',
|
||||
'back',
|
||||
'arrow-left',
|
||||
'arrow-down',
|
||||
'arrow-right',
|
||||
'arrow-up',
|
||||
'caret-left',
|
||||
'caret-bottom',
|
||||
'caret-top',
|
||||
'caret-right',
|
||||
'd-arrow-left',
|
||||
'd-arrow-right',
|
||||
'minus',
|
||||
'plus',
|
||||
'remove',
|
||||
'circle-plus',
|
||||
'remove-outline',
|
||||
'circle-plus-outline',
|
||||
'close',
|
||||
'check',
|
||||
'circle-close',
|
||||
'circle-check',
|
||||
'circle-close-outline',
|
||||
'circle-check-outline',
|
||||
'zoom-out',
|
||||
'zoom-in',
|
||||
'd-caret',
|
||||
'sort',
|
||||
'sort-down',
|
||||
'sort-up',
|
||||
'tickets',
|
||||
'document',
|
||||
'goods',
|
||||
'sold-out',
|
||||
'news',
|
||||
'message',
|
||||
'date',
|
||||
'printer',
|
||||
'time',
|
||||
'bell',
|
||||
'mobile-phone',
|
||||
'service',
|
||||
'view',
|
||||
'menu',
|
||||
'more',
|
||||
'more-outline',
|
||||
'star-on',
|
||||
'star-off',
|
||||
'location',
|
||||
'location-outline',
|
||||
'phone',
|
||||
'phone-outline',
|
||||
'picture',
|
||||
'picture-outline',
|
||||
'delete',
|
||||
'search',
|
||||
'edit',
|
||||
'edit-outline',
|
||||
'rank',
|
||||
'refresh',
|
||||
'share',
|
||||
'setting',
|
||||
'upload',
|
||||
'upload2',
|
||||
'download',
|
||||
'loading'
|
||||
]
|
||||
|
||||
export default elementIcons
|
||||
97
nladmin-ui/src/views/components/icons/index.vue
Normal file
97
nladmin-ui/src/views/components/icons/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="icons-container">
|
||||
<aside>
|
||||
<a href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/icon.html" target="_blank">Add and use
|
||||
</a>
|
||||
</aside>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="Icons">
|
||||
<div class="grid">
|
||||
<div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
{{ generateIconCode(item) }}
|
||||
</div>
|
||||
<div class="icon-item">
|
||||
<svg-icon :icon-class="item" class-name="disabled" />
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="Element-UI Icons">
|
||||
<div class="grid">
|
||||
<div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
{{ generateElementIconCode(item) }}
|
||||
</div>
|
||||
<div class="icon-item">
|
||||
<i :class="'el-icon-' + item" />
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clipboard from '@/utils/clipboard'
|
||||
import svgIcons from './svg-icons'
|
||||
import elementIcons from './element-icons'
|
||||
export default {
|
||||
name: 'Icons',
|
||||
data() {
|
||||
return {
|
||||
svgIcons,
|
||||
elementIcons
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
generateIconCode(symbol) {
|
||||
return `<svg-icon icon-class="${symbol}" />`
|
||||
},
|
||||
generateElementIconCode(symbol) {
|
||||
return `<i class="el-icon-${symbol}" />`
|
||||
},
|
||||
handleClipboard(text, event) {
|
||||
clipboard(text, event)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icons-container {
|
||||
margin: 10px 20px 0;
|
||||
overflow: hidden;
|
||||
|
||||
.grid {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||
}
|
||||
.icon-item {
|
||||
margin: 20px;
|
||||
height: 85px;
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
float: left;
|
||||
font-size: 30px;
|
||||
color: #24292e;
|
||||
cursor: pointer;
|
||||
}
|
||||
span {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
10
nladmin-ui/src/views/components/icons/svg-icons.js
Normal file
10
nladmin-ui/src/views/components/icons/svg-icons.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const req = require.context('../../../assets/icons/svg', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
|
||||
const re = /\.\/(.*)\.svg/
|
||||
|
||||
const svgIcons = requireAll(req).map(i => {
|
||||
return i.match(re)[1]
|
||||
})
|
||||
|
||||
export default svgIcons
|
||||
Reference in New Issue
Block a user