refactor(front): 重构前端组件和 API

- 更新了多个组件的样式和结构
- 重命名了一些 API 文件
- 添加了新的 API 接口
- 优化了部分代码的可读性和性能
This commit is contained in:
2025-07-23 20:58:15 +08:00
parent 091c056cd0
commit 902173a9e9
111 changed files with 1841 additions and 1198 deletions
@@ -2,7 +2,9 @@
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{
item.meta.title
}}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
@@ -73,6 +75,7 @@ export default {
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
@@ -123,15 +123,21 @@ export default {
props: {
permission: {
type: Object,
default: () => { return {} }
default: () => {
return {}
}
},
hiddenColumns: {
type: Array,
default: () => { return [] }
default: () => {
return []
}
},
ignoreColumns: {
type: Array,
default: () => { return [] }
default: () => {
return []
}
}
},
data() {
@@ -253,16 +259,18 @@ export default {
</script>
<style>
.crud-opts {
padding: 4px 0;
display: -webkit-flex;
display: flex;
align-items: center;
}
.crud-opts .crud-opts-right {
margin-left: auto;
}
.crud-opts .crud-opts-right span {
float: left;
}
.crud-opts {
padding: 4px 0;
display: -webkit-flex;
display: flex;
align-items: center;
}
.crud-opts .crud-opts-right {
margin-left: auto;
}
.crud-opts .crud-opts-right span {
float: left;
}
</style>
@@ -12,6 +12,7 @@
</template>
<script>
import { pagination } from '@crud/crud'
export default {
mixins: [pagination()]
}
@@ -1,12 +1,26 @@
<!--搜索与重置-->
<template>
<span>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="crud.toQuery">搜索</el-button>
<el-button v-if="crud.optShow.reset" class="filter-item" size="mini" type="warning" icon="el-icon-refresh-left" @click="crud.resetQuery()">重置</el-button>
<el-button
class="filter-item"
size="mini"
type="success"
icon="el-icon-search"
@click="crud.toQuery"
>搜索</el-button>
<el-button
v-if="crud.optShow.reset"
class="filter-item"
size="mini"
type="warning"
icon="el-icon-refresh-left"
@click="crud.resetQuery()"
>重置</el-button>
</span>
</template>
<script>
import { crud } from '@crud/crud'
export default {
mixins: [crud()],
props: {
@@ -1,18 +1,48 @@
<template>
<div>
<el-button v-permission="permission.edit" :loading="crud.status.cu === 2" :disabled="disabledEdit" size="mini" type="primary" icon="el-icon-edit" @click.stop="crud.toEdit(data)" />
<el-popover v-model="pop" v-permission="permission.del" placement="top" width="180" trigger="manual" @show="onPopoverShow" @hide="onPopoverHide">
<el-button
v-permission="permission.edit"
:loading="crud.status.cu === 2"
:disabled="disabledEdit"
size="mini"
type="primary"
icon="el-icon-edit"
@click.stop="crud.toEdit(data)"
/>
<el-popover
v-model="pop"
v-permission="permission.del"
placement="top"
width="180"
trigger="manual"
@show="onPopoverShow"
@hide="onPopoverHide"
>
<p>{{ msg }}</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="doCancel">取消</el-button>
<el-button :loading="crud.dataStatus[crud.getDataId(data)].delete === 2" type="primary" size="mini" @click="crud.doDelete(data)">确定</el-button>
<el-button
:loading="crud.dataStatus[crud.getDataId(data)].delete === 2"
type="primary"
size="mini"
@click="crud.doDelete(data)"
>确定
</el-button>
</div>
<el-button slot="reference" :disabled="disabledDle" type="danger" icon="el-icon-delete" size="mini" @click.stop="toDelete" />
<el-button
slot="reference"
:disabled="disabledDle"
type="danger"
icon="el-icon-delete"
size="mini"
@click.stop="toDelete"
/>
</el-popover>
</div>
</template>
<script>
import CRUD, { crud } from '@crud/crud'
export default {
mixins: [crud()],
props: {
+17 -11
View File
@@ -1,6 +1,6 @@
import { download, initData } from '@/api/data'
import { downloadFile, parseTime } from '@/utils/index'
import Vue from 'vue'
import { DownloadFile } from '@/utils/CsDomUtil'
/**
* CRUD配置
@@ -30,15 +30,20 @@ function CRUD(options) {
// Form 表单
form: {},
// 重置表单
defaultForm: () => {},
defaultForm: () => {
},
// 等待时间
time: 50,
// CRUD Method
crudMethod: {
add: (form) => {},
del: (id) => {},
edit: (form) => {},
get: (id) => {}
add: (form) => {
},
del: (id) => {
},
edit: (form) => {
},
get: (id) => {
}
},
// 主页操作栏显示哪些按钮
optShow: {
@@ -328,7 +333,7 @@ function CRUD(options) {
doExport() {
crud.downloadLoading = true
download(crud.url + '/download', crud.getQueryParams()).then(result => {
downloadFile(result, crud.title + '数据', 'xlsx')
DownloadFile(result, crud.title + '数据', 'xlsx')
crud.downloadLoading = false
}).catch(() => {
crud.downloadLoading = false
@@ -419,6 +424,7 @@ function CRUD(options) {
*/
resetDataStatus() {
const dataStatus = {}
function resetStatus(datas) {
datas.forEach(e => {
dataStatus[crud.getDataId(e)] = {
@@ -430,6 +436,7 @@ function CRUD(options) {
}
})
}
resetStatus(crud.data)
crud.dataStatus = dataStatus
},
@@ -461,7 +468,9 @@ function CRUD(options) {
*/
selectChange(selection, row) {
// 如果selection中存在row代表是选中,否则是取消选中
if (selection.find(val => { return crud.getDataId(val) === crud.getDataId(row) })) {
if (selection.find(val => {
return crud.getDataId(val) === crud.getDataId(row)
})) {
if (row.children) {
row.children.forEach(val => {
crud.getTable().toggleRowSelection(val, true)
@@ -674,9 +683,6 @@ function presenter(crud) {
})
this.crud = this.$crud['defalut'] || cruds[0]
},
methods: {
parseTime
},
created() {
for (const k in this.$crud) {
if (this.$crud[k].queryOnPresenterCreated) {
@@ -4,8 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
const animationDuration = 6000
@@ -31,7 +32,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,8 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -29,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,8 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
const animationDuration = 3000
@@ -31,7 +32,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -4,9 +4,9 @@
<script>
import echarts from 'echarts'
import { DeBounce } from '@/utils/CsUtil'
require('echarts/theme/macarons') // echarts theme
import { debounce } from '@/utils'
export default {
props: {
@@ -30,7 +30,7 @@ export default {
},
mounted() {
this.initChart()
this.__resizeHandler = debounce(() => {
this.__resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
@@ -1,5 +1,10 @@
<template>
<a href="https://github.com/odboy-tianjun/cutejava" target="_blank" class="github-corner" aria-label="View source on Github">
<a
href="https://github.com/odboy-tianjun/cutejava"
target="_blank"
class="github-corner"
aria-label="View source on Github"
>
<svg
width="80"
height="80"
@@ -43,10 +48,11 @@
}
}
@media (max-width:500px) {
@media (max-width: 500px) {
.github-corner:hover .octo-arm {
animation: none
}
.github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out
}
@@ -8,7 +8,9 @@
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
<path
d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
/>
</svg>
</div>
</template>
@@ -106,7 +106,9 @@ export default {
for (const router of routes) {
// skip hidden router
if (router.hidden) { continue }
if (router.hidden) {
continue
}
const data = {
path: !this.ishttp(router.path) ? path.resolve(basePath, router.path) : router.path,
@@ -167,7 +169,7 @@ export default {
display: inline-block;
vertical-align: middle;
::v-deep .el-input__inner {
::v-deep .el-input__inner {
border-radius: 0;
border: 0;
padding-left: 0;
@@ -1,6 +1,13 @@
<template>
<div class="icon-body">
<el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons">
<el-input
v-model="name"
style="position: relative;"
clearable
placeholder="请输入图标名称"
@clear="filterIcons"
@input.native="filterIcons"
>
<i slot="suffix" class="el-icon-search el-input__icon" />
</el-input>
<div class="icon-list">
@@ -14,6 +21,7 @@
<script>
import icons from './requireIcons'
export default {
name: 'IconSelect',
data() {
@@ -42,26 +50,29 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.icon-body {
width: 100%;
padding: 10px;
.icon-list {
height: 200px;
overflow-y: scroll;
div {
height: 30px;
line-height: 30px;
margin-bottom: -5px;
cursor: pointer;
width: 33%;
float: left;
}
span {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.icon-body {
width: 100%;
padding: 10px;
.icon-list {
height: 200px;
overflow-y: scroll;
div {
height: 30px;
line-height: 30px;
margin-bottom: -5px;
cursor: pointer;
width: 33%;
float: left;
}
span {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
}
}
</style>
@@ -1,4 +1,3 @@
const req = require.context('../../assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()
@@ -95,6 +95,7 @@ export default {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
@@ -10,7 +10,7 @@
</template>
<script>
import { addClass, removeClass } from '@/utils'
import { AddClass, RemoveClass } from '@/utils/CsDomUtil'
export default {
name: 'RightPanel',
@@ -46,9 +46,9 @@ export default {
this.addEventClick()
}
if (value) {
addClass(document.body, 'showRightPanel')
AddClass(document.body, 'showRightPanel')
} else {
removeClass(document.body, 'showRightPanel')
RemoveClass(document.body, 'showRightPanel')
}
}
},
@@ -81,69 +81,70 @@ export default {
</script>
<style>
.showRightPanel {
overflow: hidden;
position: relative;
width: calc(100% - 15px);
}
.showRightPanel {
overflow: hidden;
position: relative;
width: calc(100% - 15px);
}
</style>
<style lang="scss" scoped>
.rightPanel-background {
position: fixed;
top: 0;
left: 0;
opacity: 0;
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
background: rgba(0, 0, 0, .2);
z-index: -1;
}
.rightPanel {
width: 100%;
max-width: 260px;
height: 100vh;
position: fixed;
top: 0;
right: 0;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
transition: all .25s cubic-bezier(.7, .3, .1, 1);
transform: translate(100%);
background: #fff;
z-index: 40000;
}
.show {
transition: all .3s cubic-bezier(.7, .3, .1, 1);
.rightPanel-background {
position: fixed;
top: 0;
left: 0;
opacity: 0;
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
background: rgba(0, 0, 0, .2);
z-index: -1;
z-index: 20000;
opacity: 1;
width: 100%;
height: 100%;
}
.rightPanel {
width: 100%;
max-width: 260px;
height: 100vh;
position: fixed;
top: 0;
right: 0;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
transition: all .25s cubic-bezier(.7, .3, .1, 1);
transform: translate(100%);
background: #fff;
z-index: 40000;
transform: translate(0);
}
}
.show {
transition: all .3s cubic-bezier(.7, .3, .1, 1);
.handle-button {
width: 48px;
height: 48px;
position: absolute;
left: -48px;
text-align: center;
font-size: 24px;
border-radius: 6px 0 0 6px !important;
z-index: 0;
pointer-events: auto;
cursor: pointer;
color: #fff;
line-height: 48px;
.rightPanel-background {
z-index: 20000;
opacity: 1;
width: 100%;
height: 100%;
}
.rightPanel {
transform: translate(0);
}
}
.handle-button {
width: 48px;
height: 48px;
position: absolute;
left: -48px;
text-align: center;
i {
font-size: 24px;
border-radius: 6px 0 0 6px !important;
z-index: 0;
pointer-events: auto;
cursor: pointer;
color: #fff;
line-height: 48px;
i {
font-size: 24px;
line-height: 48px;
}
}
}
</style>
@@ -4,9 +4,15 @@
<svg-icon class-name="size-icon" icon-class="size" />
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">
<el-dropdown-item
v-for="item of sizeOptions"
:key="item.value"
:disabled="size===item.value"
:command="item.value"
>
{{
item.label }}
item.label
}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@@ -7,7 +7,7 @@
<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
import { IsExternal } from '@/utils/CsValidateUtil'
export default {
name: 'SvgIcon',
@@ -23,7 +23,7 @@ export default {
},
computed: {
isExternal() {
return isExternal(this.iconClass)
return IsExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
@@ -56,7 +56,7 @@ export default {
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
mask-size: cover !important;
display: inline-block;
}
</style>
@@ -11,6 +11,7 @@
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
import Cookies from 'js-cookie'
export default {
data() {
return {