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
@@ -98,13 +98,14 @@ export default {
</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;
}
.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>
@@ -45,23 +45,26 @@
export default {
name: 'SplitPaneDemo',
methods: {
resize() {}
resize() {
}
}
}
</script>
<style lang="scss" scoped>
.wrap{
height:300px;
.paneL{
background-color:red;
height:100%;
width:100%;
.wrap {
height: 300px;
.paneL {
background-color: red;
height: 100%;
width: 100%;
}
.paneR{
.paneR {
background-color: blue;
height:100%;
width:100%;
height: 100%;
width: 100%;
}
}
</style>
@@ -11,8 +11,7 @@
</el-card>
</template>
<script>
import MyWebSocket from '@/utils/websocket'
import { mapGetters } from 'vuex'
import CsWsClient from '@/utils/CsWsClient'
export default {
data() {
@@ -22,12 +21,6 @@ export default {
responseTxt: ''
}
},
computed: {
...mapGetters([
'websocketApi',
'user'
])
},
// mounted() {},
destroyed() {
if (this.client) {
@@ -39,7 +32,7 @@ export default {
// 获取mapGetters中的值
// console.error('userInfo', this.user)
const that = this
that.client = new MyWebSocket(that, that.websocketApi.replaceAll('{sid}', that.user.username))
that.client = new CsWsClient(that)
that.client.connect(function(event) {
console.info('=============== MyWebSocket:event', event)
}, function(msgEvent) {
@@ -20,6 +20,7 @@
import { Message } from 'element-ui'
import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth'
export default {
name: 'CuteFileUpload',
props: {
@@ -18,6 +18,7 @@
import { Message } from 'element-ui'
import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth'
export default {
name: 'CuteFileUpload',
props: {
@@ -27,6 +27,7 @@ import 'codemirror/mode/sql/sql'
import 'codemirror/mode/vue/vue'
import 'codemirror/mode/xml/xml'
import { Message } from 'element-ui'
const SupportModeList = ['yaml', 'java', 'go', 'swift', 'dockerfile', 'groovy', 'lua', 'perl', 'python', 'ruby', 'sql', 'xml', 'vue']
export default {
name: 'CuteCodeEditor',
@@ -14,8 +14,20 @@
@selection-change="onTableSelectionChange"
>
<el-table-column v-if="mode === 'multi'" type="selection" width="55" />
<el-table-column v-for="(column, index) in crud.columns" :key="index" :label="column.label" :prop="column.prop" :formatter="column.formatter ? column.formatter : null" />
<el-table-column v-if="crud.operateColumn" :width="crud.operateColumn.width" label="操作" :formatter="crud.operateColumn.formatter" :fixed="crud.operateColumn.fixed" />
<el-table-column
v-for="(column, index) in crud.columns"
:key="index"
:label="column.label"
:prop="column.prop"
:formatter="column.formatter ? column.formatter : null"
/>
<el-table-column
v-if="crud.operateColumn"
:width="crud.operateColumn.width"
label="操作"
:formatter="crud.operateColumn.formatter"
:fixed="crud.operateColumn.fixed"
/>
</el-table>
<el-pagination
:current-page="pageProps.current"
@@ -31,6 +43,7 @@
<script>
import Sortable from 'sortablejs'
export default {
name: 'CuteDragTable',
props: {
@@ -13,6 +13,7 @@ import 'codemirror/lib/codemirror.css'
// 主题预览地址 https://blog.csdn.net/qq_41694291/article/details/106429772
import 'codemirror/theme/darcula.css'
import 'codemirror/mode/javascript/javascript'
export default {
name: 'CuteJavaEditor',
props: {
@@ -15,10 +15,11 @@
</template>
<script>
import { upload } from '@/utils/upload'
import { mapGetters } from 'vuex'
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
import { UploadFile } from '@/utils/CsDomUtil'
const dynamicHeight = 160
export default {
name: 'CuteMarkdown',
@@ -52,7 +53,7 @@ export default {
methods: {
imgAdd(pos, $file) {
const that = this
upload(that.imagesUploadApi, $file).then(res => {
UploadFile(that.imagesUploadApi, $file).then(res => {
const data = res.data
const url = that.baseApi + '/file/' + data.type + '/' + data.realName
that.$refs.md.$img2Url(pos, url)
@@ -61,7 +61,9 @@
<el-row>
<el-col :span="12" style="text-align: left">
<!-- 流水线状态为fail,且节点支持重试 -->
<div v-if="pipelineData.currentNodeStatus === 'fail' && pipelineData.retry === true">
<div
v-if="pipelineData.currentNodeStatus && pipelineData.currentNodeStatus === 'fail' && pipelineData.retry === true"
>
<div class="box-buttons">
<el-button
type="text"
@@ -69,7 +71,7 @@
:style="{
padding: 0,
margin: '0 10px 0 10px',
color: statusColorConst.success.color
color: statusColorConst.running.color
}"
@click="onNodeRetryClick"
>
@@ -79,7 +81,7 @@
</div>
<!-- 流水线状态为success,且有需要满足条件的操作按钮 -->
<div
v-else-if="pipelineData.currentNodeStatus === statusColorConst.success.code && pipelineData.buttons && pipelineData.buttons.length > 0"
v-else-if="pipelineData.currentNodeStatus && pipelineData.currentNodeStatus === statusColorConst.success.code && pipelineData.buttons && pipelineData.buttons.length > 0"
>
<div class="box-buttons">
<el-button
@@ -90,7 +92,7 @@
:style="{
padding: 0,
margin: '0 10px 0 10px',
color: ['apply','agree','ok','success'].includes(buttonItem.code) ? 'green' : 'red',
color: ['apply','agree','ok','success'].includes(buttonItem.code) ? statusColorConst.running.color : statusColorConst.fail.color,
display: ['success', 'fail'].includes(buttonItem.code) && pipelineData.status === buttonItem.code ? '' : 'none'
}"
@click="onNodeOperationClick(buttonItem)"
@@ -101,7 +103,7 @@
</div>
<!-- 流水线状态非pending,且有操作按钮 -->
<div
v-else-if="pipelineData.currentNodeStatus !== statusColorConst.pending.code && pipelineData.buttons && pipelineData.buttons.length > 0"
v-else-if="pipelineData.currentNodeStatus && pipelineData.currentNodeStatus !== statusColorConst.pending.code && pipelineData.buttons && pipelineData.buttons.length > 0"
>
<div class="box-buttons">
<el-button
@@ -112,7 +114,7 @@
:style="{
padding: 0,
margin: '0 10px 0 10px',
color: ['apply','agree','ok','success'].includes(buttonItem.code) ? 'green' : 'red'
color: ['apply','agree','ok','success'].includes(buttonItem.code) ? statusColorConst.running.color : statusColorConst.fail.color
}"
@click="onNodeOperationClick(buttonItem)"
>
@@ -160,7 +162,7 @@ export default {
return {
statusColorConst: {
pending: { code: 'pending', label: '未开始', color: '#C0C4CC' },
running: { code: 'running', label: '运行中', color: '#67C23A' },
running: { code: 'running', label: '运行中', color: '#409EFF' },
success: { code: 'success', label: '执行成功', color: '#67C23A' },
fail: { code: 'fail', label: '执行失败', color: '#F56C6C' }
},
@@ -265,8 +267,8 @@ export default {
</script>
<style scoped>
.box-card {
width: 240px; /* 卡片宽度 */
max-width: 240px; /* 卡片宽度 */
width: 260px; /* 卡片宽度 */
max-width: 260px; /* 卡片宽度 */
padding: 10px;
background-color: #fff; /* 背景颜色 */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
@@ -28,8 +28,9 @@
import { mapGetters } from 'vuex'
import '@wangeditor/editor/dist/css/style.css'
import { Message } from 'element-ui'
import { upload } from '@/utils/upload'
import { Toolbar, Editor } from '@wangeditor/editor-for-vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { UploadFile } from '@/utils/CsDomUtil'
export default {
name: 'CuteRichTextEditor',
components: { Toolbar, Editor },
@@ -62,7 +63,7 @@ export default {
allowedFileTypes: ['image/*'],
// 自定义上传
async customUpload(file, insertFn) { // JS 语法
upload(that.imagesUploadApi, file).then(res => {
UploadFile(that.imagesUploadApi, file).then(res => {
const data = res.data
const url = that.baseApi + '/file/' + data.dateGroup + '/' + data.realName
// 最后插入图片
@@ -14,8 +14,20 @@
@selection-change="onTableSelectionChange"
>
<el-table-column v-if="mode === 'multi'" type="selection" width="55" />
<el-table-column v-for="(column, index) in crud.columns" :key="index" :label="column.label" :prop="column.prop" :formatter="column.formatter ? column.formatter : null" />
<el-table-column v-if="crud.operateColumn" :width="crud.operateColumn.width" label="操作" :formatter="crud.operateColumn.formatter" :fixed="crud.operateColumn.fixed" />
<el-table-column
v-for="(column, index) in crud.columns"
:key="index"
:label="column.label"
:prop="column.prop"
:formatter="column.formatter ? column.formatter : null"
/>
<el-table-column
v-if="crud.operateColumn"
:width="crud.operateColumn.width"
label="操作"
:formatter="crud.operateColumn.formatter"
:fixed="crud.operateColumn.fixed"
/>
</el-table>
<el-pagination
:current-page="pageProps.current"
@@ -13,6 +13,7 @@ import 'codemirror/lib/codemirror.css'
// 主题预览地址 https://blog.csdn.net/qq_41694291/article/details/106429772
import 'codemirror/theme/darcula.css'
import 'codemirror/mode/yaml/yaml'
export default {
name: 'CuteYamlEditor',
props: {
@@ -40,9 +40,10 @@
</template>
<script>
import clipboard from '@/utils/clipboard'
import clipboard from '@/plugins/ClipboardPlugin'
import svgIcons from './svg-icons'
import elementIcons from './element-icons'
export default {
name: 'Icons',
data() {
@@ -75,6 +76,7 @@ export default {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.icon-item {
margin: 20px;
height: 85px;
@@ -85,11 +87,13 @@ export default {
color: #24292e;
cursor: pointer;
}
span {
display: block;
font-size: 16px;
margin-top: 10px;
}
.disabled {
pointer-events: none;
}
@@ -42,9 +42,9 @@
</template>
<script>
import { DateUtil } from '@/utils/myUtil'
import DictService from '@/api/system/dict'
import CuteDragTable from '@/views/components/dev/CuteDragTable.vue'
import { FormatRowDateTimeStr } from '@/utils/CsUtil'
export default {
name: 'CuteDragTableDemo',
@@ -74,7 +74,7 @@ export default {
columns: [
{ prop: 'name', label: '名称' },
{ prop: 'description', label: '描述' },
{ prop: 'createTime', label: '创建时间', formatter: DateUtil.formatRowDateTime },
{ prop: 'createTime', label: '创建时间', formatter: FormatRowDateTimeStr },
{ prop: 'createBy', label: '创建人' }
],
operateColumn: {
@@ -11,6 +11,7 @@
import Clipboard from 'clipboard'
import { Message } from 'element-ui'
import CuteOneKeyCopy from '@/views/components/dev/CuteOneKeyCopy'
export default {
components: { CuteOneKeyCopy },
data() {
@@ -54,6 +55,7 @@ export default {
color: #333;
cursor: pointer;
}
#btn:active {
background-color: #ddd;
color: #666;
@@ -1,19 +1,28 @@
<template>
<div>
<el-divider>演示:动态流水线 <el-button type="primary" @click="startPipelineTest">启动流水线</el-button></el-divider>
<el-divider>演示:动态流水线
<el-button
v-prevent-re-click
type="primary"
:loading="dynamicStartButtonLoading"
:disabled="dynamicStartButtonLoading"
@click="startPipelineTest"
>{{ dynamicStartupStatusMap[dynamicStartupStatus].label }}
</el-button>
</el-divider>
<div class="box-pipeline">
<div v-if="dynamicList && dynamicList.length > 0" class="box-pipeline-content">
<div v-if="dynamicInstance.nodes && dynamicInstance.nodes.length > 0" class="box-pipeline-content">
<cute-pipeline-node
v-for="(template, index) in dynamicList"
v-for="(template, index) in dynamicInstance.nodes"
:key="template.code"
:template-data.sync="dynamicList[index]"
:template-data.sync="dynamicInstance.nodes[index]"
/>
</div>
<div v-else class="box-pipeline-content">
<cute-pipeline-node
v-for="(template, index) in templateList"
v-for="(template, index) in dynamicTemplate"
:key="template.code"
:template-data.sync="templateList[index]"
:template-data.sync="dynamicTemplate[index]"
/>
</div>
</div>
@@ -28,9 +37,9 @@
</div>
<div v-else class="box-pipeline-content">
<cute-pipeline-node
v-for="(template, index) in templateList"
v-for="(template, index) in defaultTemplate"
:key="template.code"
:template-data.sync="templateList[index]"
:template-data.sync="defaultTemplate[index]"
/>
</div>
</div>
@@ -45,9 +54,9 @@
</div>
<div v-else class="box-pipeline-content">
<cute-pipeline-node
v-for="(template, index) in templateList"
v-for="(template, index) in defaultTemplate"
:key="template.code"
:template-data.sync="templateList[index]"
:template-data.sync="defaultTemplate[index]"
/>
</div>
</div>
@@ -57,15 +66,18 @@
<script>
import CutePipelineNode from '@/views/components/dev/CutePipelineNode'
import { formatDateTimeStr } from '@/utils'
import { startPipeline, queryLastPipelineDetail } from '@/api/devops/pipeline'
import { getPipelineTemplate } from '@/api/devops/pipelineTemplate'
import { queryLastPipelineDetail, restartPipeline, startPipeline } from '@/api/devops/pipelineInstance'
import { CountArraysObjectByPropKey, FormatDateTimeStr } from '@/utils/CsUtil'
import CsMessage from '@/utils/elementui/CsMessage'
export default {
name: 'CutePipelineNodeDemo',
components: { CutePipelineNode },
data() {
return {
templateList: [
// 静态模板
defaultTemplate: [
{
code: 'node_init',
type: 'service',
@@ -438,46 +450,96 @@ export default {
}
],
// 动态流水线
dynamicStartupStatus: 'start',
dynamicStartupStatusMap: {
start: { label: '启动', code: 'start' },
restart: { label: '重新启动', code: 'restart' }
},
dynamicStartButtonLoading: false,
dynamicTemplate: [],
dynamicHook: null,
dynamicList: [],
dynamicInstanceId: ''
dynamicInstance: {}
}
},
mounted() {
this.refreshData()
this.initPipelineTemplate(4)
const pipelineInstanceId = sessionStorage.getItem('pipelineInstanceId')
if (pipelineInstanceId) {
this.fetchLastDetail(pipelineInstanceId)
}
},
methods: {
refreshData() {
// 成功
for (const datum of this.dataList2) {
if (datum.status === 'running') {
datum.updateTime = formatDateTimeStr(new Date())
datum.updateTime = FormatDateTimeStr(new Date())
}
}
this.dataList2 = [...this.dataList2]
// 失败或重试
for (const datum of this.dataList3) {
if (datum.status === 'running') {
datum.updateTime = formatDateTimeStr(new Date())
datum.updateTime = FormatDateTimeStr(new Date())
}
}
this.dataList3 = [...this.dataList3]
},
startPipelineTest() {
async initPipelineTemplate(templateId) {
const pipelineTemplate = await getPipelineTemplate(templateId)
if (pipelineTemplate && pipelineTemplate.template) {
try {
this.dynamicTemplate = JSON.parse(pipelineTemplate.template)
} catch (e) {
// ignore
}
}
},
async fetchLastDetail(instanceId) {
const that = this
if (that.dynamicHook) {
clearInterval(that.dynamicHook)
const intervalTime = 2000
setTimeout(() => {
that.dynamicHook = setInterval(() => {
queryLastPipelineDetail(instanceId).then((data) => {
that.dynamicInstance = data
// 判断流水线是否结束
const successCount = CountArraysObjectByPropKey(data.nodes, 'status', 'success')
if (that.dynamicTemplate && that.dynamicTemplate.length === successCount) {
clearInterval(that.dynamicHook)
that.dynamicHook = null
that.dynamicStartupStatus = that.dynamicStartupStatusMap.start.code
} else {
that.dynamicStartupStatus = that.dynamicStartupStatusMap.restart.code
}
})
}, intervalTime)
that.dynamicStartButtonLoading = false
}, 2000)
},
async startPipelineTest() {
const that = this
try {
if (that.dynamicHook) {
clearInterval(that.dynamicHook)
}
that.dynamicStartButtonLoading = true
// 这里的 dynamicStartupStatus状态,需要后期与上下文关联后,初始化的时候带入最近一个流水线实例
// let result
// if (that.dynamicStartupStatus === that.dynamicStartupStatusMap.start.code) {
// result = await restartPipeline()
// CsMessage.Success('流水线重新启动成功')
// } else {
// result = await startPipeline()
// CsMessage.Success('流水线启动成功')
// }
const result = await startPipeline()
CsMessage.Success('流水线启动成功')
await that.fetchLastDetail(result.instanceId)
sessionStorage.setItem('pipelineInstanceId', result.instanceId)
} catch (e) {
that.dynamicStartButtonLoading = false
}
startPipeline().then((instanceId) => {
that.dynamicInstanceId = instanceId
setTimeout(() => {
that.dynamicHook = setInterval(() => {
queryLastPipelineDetail(that.dynamicInstanceId).then((data) => {
that.dynamicList = data
})
}, 1000)
}, 2000)
})
}
}
}
@@ -489,15 +551,19 @@ export default {
white-space: nowrap; /* 防止内容换行,使所有内容在一行显示 */
padding: 30px 20px 30px 20px;
}
.box-pipeline::-webkit-scrollbar {
height: 5px; /* 设置水平滚动条高度 */
}
.box-pipeline::-webkit-scrollbar-track {
background: #f1f1f1; /* 滚动条底色 */
}
.box-pipeline::-webkit-scrollbar-thumb {
background: #DCDFE6; /* 滚动条颜色 */
}
.box-pipeline-content {
display: inline-block; /* 使内容水平排列 */
white-space: nowrap; /* 防止内容换行 */
@@ -68,10 +68,10 @@
<script>
import CuteSimpleTable from '@/views/components/dev/CuteSimpleTable'
import { DateUtil } from '@/utils/myUtil'
import DictService from '@/api/system/dict'
import CuteFormDialog from '@/views/components/dev/CuteFormDialog'
import CuteFormDrawer from '@/views/components/dev/CuteFormDrawer'
import { FormatRowDateTimeStr } from '@/utils/CsUtil'
export default {
name: 'CuteSimpleTableDemo',
@@ -101,7 +101,7 @@ export default {
columns: [
{ prop: 'name', label: '名称' },
{ prop: 'description', label: '描述' },
{ prop: 'createTime', label: '创建时间', formatter: DateUtil.formatRowDateTime },
{ prop: 'createTime', label: '创建时间', formatter: FormatRowDateTimeStr },
{ prop: 'createBy', label: '创建人' }
],
operateColumn: {
@@ -4,9 +4,10 @@
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
require('echarts/theme/macarons') // echarts theme
export default {
mixins: [resize],
props: {
@@ -160,7 +160,7 @@ export default {
}
}
@media (max-width:550px) {
@media (max-width: 550px) {
.card-panel-description {
display: none;
}
@@ -1,4 +1,4 @@
import { debounce } from '@/utils'
import { DeBounce } from '@/utils/CsUtil'
export default {
data() {
@@ -8,7 +8,7 @@ export default {
}
},
mounted() {
this.$_resizeHandler = debounce(() => {
this.$_resizeHandler = DeBounce(() => {
if (this.chart) {
this.chart.resize()
}
+41 -33
View File
@@ -49,41 +49,49 @@ export default {
</script>
<style lang="scss" scoped>
.errPage-container {
width: 800px;
max-width: 100%;
margin: 100px auto;
.pan-back-btn {
background: #008489;
color: #fff;
border: none!important;
.errPage-container {
width: 800px;
max-width: 100%;
margin: 100px auto;
.pan-back-btn {
background: #008489;
color: #fff;
border: none !important;
}
.pan-gif {
margin: 0 auto;
display: block;
}
.pan-img {
display: block;
margin: 0 auto;
width: 100%;
}
.text-jumbo {
font-size: 60px;
font-weight: 700;
color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
}
.pan-gif {
margin: 0 auto;
display: block;
}
.pan-img {
display: block;
margin: 0 auto;
width: 100%;
}
.text-jumbo {
font-size: 60px;
font-weight: 700;
color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
}
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
</style>
+16 -2
View File
@@ -30,27 +30,32 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.wscn-http404-container{
transform: translate(-50%,-50%);
.wscn-http404-container {
transform: translate(-50%, -50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
@@ -62,6 +67,7 @@ export default {
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
@@ -73,6 +79,7 @@ export default {
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
@@ -84,6 +91,7 @@ export default {
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
@@ -152,12 +160,14 @@ export default {
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
@@ -169,6 +179,7 @@ export default {
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
@@ -181,6 +192,7 @@ export default {
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
@@ -192,6 +204,7 @@ export default {
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
@@ -210,6 +223,7 @@ export default {
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
+35 -20
View File
@@ -36,6 +36,7 @@ import LineChart from './dashboard/LineChart'
import RadarChart from '@/components/Echarts/RadarChart'
import PieChart from '@/components/Echarts/PieChart'
import BarChart from '@/components/Echarts/BarChart'
import CsMessage from '@/utils/elementui/CsMessage'
const lineChartData = {
newVisitis: {
@@ -71,6 +72,20 @@ export default {
lineChartData: lineChartData.newVisitis
}
},
mounted() {
// setTimeout(() => {
// CsMessage.Info('CsMessage Info')
// }, 1000)
// setTimeout(() => {
// CsMessage.Warning('CsMessage Warning')
// }, 2000)
// setTimeout(() => {
// CsMessage.Error('CsMessage Error')
// }, 3000)
// setTimeout(() => {
// CsMessage.Success('CsMessage Success')
// }, 4000)
},
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
@@ -80,28 +95,28 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.github-corner {
position: absolute;
top: 0;
border: 0;
right: 0;
}
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
.github-corner {
position: absolute;
top: 0;
border: 0;
right: 0;
}
@media (max-width:1024px) {
.chart-wrapper {
padding: 8px;
}
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width: 1024px) {
.chart-wrapper {
padding: 8px;
}
}
</style>
+31 -5
View File
@@ -1,6 +1,13 @@
<template>
<div class="login" :style="'background-image:url('+ Background +');'">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
label-position="left"
label-width="0px"
class="login-form"
>
<h3 class="title">
CuteJava 后台管理系统
</h3>
@@ -10,12 +17,24 @@
</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">
<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 input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @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">
@@ -26,7 +45,13 @@
记住我
</el-checkbox>
<el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
@@ -42,12 +67,13 @@
</template>
<script>
import { encrypt } from '@/utils/rsaEncrypt'
import { encrypt } from '@/utils/CsRsaUtil'
import Config from '@/settings'
import { getCodeImg } from '@/api/login'
import Cookies from 'js-cookie'
import qs from 'qs'
import Background from '@/assets/images/background.jpeg'
export default {
name: 'Login',
data() {
@@ -27,7 +27,7 @@ export default {
}
</script>
<style scoped>
.my-code a{
color:#009688;
}
.my-code a {
color: #009688;
}
</style>
+45 -15
View File
@@ -4,9 +4,25 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.name" clearable size="small" placeholder="输入部门名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.name"
clearable
size="small"
placeholder="输入部门名称搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select v-model="query.enabled" clearable size="small" placeholder="状态" class="filter-item" style="width: 90px" @change="crud.toQuery">
<el-select
v-model="query.enabled"
clearable
size="small"
placeholder="状态"
class="filter-item"
style="width: 90px"
@change="crud.toQuery"
>
<el-option v-for="item in enabledTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<rrOperation />
@@ -14,7 +30,14 @@
<crudOperation :permission="permission" />
</div>
<!--表单组件-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="500px"
>
<el-form ref="form" inline :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="部门名称" prop="name">
<el-input v-model="form.name" style="width: 370px;" />
@@ -44,7 +67,9 @@
/>
</el-form-item>
<el-form-item label="状态" prop="enabled">
<el-radio v-for="item in dict.dept_status" :key="item.id" v-model="form.enabled" :label="item.value">{{ item.label }}</el-radio>
<el-radio v-for="item in dict.dept_status" :key="item.id" v-model="form.enabled" :label="item.value">
{{ item.label }}
</el-radio>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -80,7 +105,13 @@
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','dept:edit','dept:del'])" label="操作" width="130px" align="center" fixed="right">
<el-table-column
v-if="checkPer(['admin','dept:edit','dept:del'])"
label="操作"
width="130px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
@@ -96,10 +127,9 @@
<script>
import crudDept from '@/api/system/dept'
import Treeselect from '@riophae/vue-treeselect'
import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
@@ -254,13 +284,13 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
::v-deep .vue-treeselect__control, ::v-deep .vue-treeselect__placeholder, ::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
@@ -8,12 +8,27 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.label" clearable size="small" placeholder="输入字典标签查询" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery" />
<el-input
v-model="query.label"
clearable
size="small"
placeholder="输入字典标签查询"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="toQuery"
/>
<rrOperation />
</div>
</div>
<!--表单组件-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title" width="500px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible="crud.status.cu > 0"
:title="crud.status.title"
width="500px"
>
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="字典标签" prop="label">
<el-input v-model="form.label" style="width: 370px;" />
@@ -22,7 +37,13 @@
<el-input v-model="form.value" style="width: 370px;" />
</el-form-item>
<el-form-item label="排序" prop="dictSort">
<el-input-number v-model.number="form.dictSort" :min="0" :max="999" controls-position="right" style="width: 370px;" />
<el-input-number
v-model.number="form.dictSort"
:min="0"
:max="999"
controls-position="right"
style="width: 370px;"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -31,14 +52,27 @@
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" highlight-current-row style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
highlight-current-row
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column label="所属字典">
{{ query.dictName }}
</el-table-column>
<el-table-column prop="label" label="字典标签" />
<el-table-column prop="value" label="字典值" />
<el-table-column prop="dictSort" label="排序" />
<el-table-column v-if="checkPer(['admin','dict:edit','dict:del'])" label="操作" width="130px" align="center" fixed="right">
<el-table-column
v-if="checkPer(['admin','dict:edit','dict:del'])"
label="操作"
width="130px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
@@ -55,7 +89,7 @@
<script>
import crudDictDetail from '@/api/system/dictDetail'
import CRUD, { presenter, header, form } from '@crud/crud'
import CRUD, { form, header, presenter } from '@crud/crud'
import pagination from '@crud/Pagination'
import rrOperation from '@crud/RR.operation'
import udOperation from '@crud/UD.operation'
@@ -66,7 +100,8 @@ export default {
components: { pagination, rrOperation, udOperation },
cruds() {
return [
CRUD({ title: '字典详情', url: 'api/dictDetail', query: { dictName: '' },
CRUD({
title: '字典详情', url: 'api/dictDetail', query: { dictName: '' },
crudMethod: { ...crudDictDetail },
optShow: {
add: true,
@@ -109,7 +144,7 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
+36 -6
View File
@@ -1,7 +1,14 @@
<template>
<div class="app-container">
<!--表单组件-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title" width="500px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible="crud.status.cu > 0"
:title="crud.status.title"
width="500px"
>
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="字典名称" prop="name">
<el-input v-model="form.name" style="width: 370px;" />
@@ -23,17 +30,39 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" clearable size="small" placeholder="输入名称或者描述搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.blurry"
clearable
size="small"
placeholder="输入名称或者描述搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" highlight-current-row style="width: 100%;" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
highlight-current-row
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
@current-change="handleCurrentChange"
>
<el-table-column type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="name" label="名称" />
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" />
<el-table-column v-if="checkPer(['admin','dict:edit','dict:del'])" label="操作" width="130px" align="center" fixed="right">
<el-table-column
v-if="checkPer(['admin','dict:edit','dict:del'])"
label="操作"
width="130px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
@@ -59,7 +88,8 @@
type="primary"
icon="el-icon-plus"
@click="$refs.dictDetail && $refs.dictDetail.crud.toAdd()"
>新增</el-button>
>新增
</el-button>
</div>
<dictDetail ref="dictDetail" :permission="permission" />
</el-card>
@@ -71,7 +101,7 @@
<script>
import dictDetail from './dictDetail'
import crudDict from '@/api/system/dict'
import CRUD, { presenter, header, form } from '@crud/crud'
import CRUD, { form, header, presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import rrOperation from '@crud/RR.operation'
@@ -4,6 +4,7 @@
<script>
import { mapGetters } from 'vuex'
import elFrame from '@/components/Iframe/index'
export default {
name: 'DruidSqlConsole',
components: { elFrame },
@@ -28,6 +28,7 @@
<script>
import { getLastEmailConfig, modifyEmailConfig } from '@/api/system/email'
export default {
name: 'Config',
data() {
@@ -17,7 +17,11 @@
# 密码(注意,某些邮箱需要为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>
<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>
@@ -26,6 +30,7 @@
<script>
import Config from './config.vue'
import Send from './send.vue'
export default {
name: 'Email',
components: { Config, Send },
+20 -11
View File
@@ -8,16 +8,24 @@
<el-input v-model="form.tos" style="width: 646px" placeholder="请输入收件地址,多个地址英文逗号,隔开" />
</el-form-item>
<div ref="editor" class="editor" />
<el-button :loading="loading" style="margin-left:1.6%;margin-bottom: 30px" size="medium" type="primary" @click="doSubmit">发送邮件</el-button>
<el-button
:loading="loading"
style="margin-left:1.6%;margin-bottom: 30px"
size="medium"
type="primary"
@click="doSubmit"
>发送邮件
</el-button>
</el-form>
</div>
</template>
<script>
import { sendEmail } from '@/api/system/email'
import { upload } from '@/utils/upload'
import { mapGetters } from 'vuex'
import E from 'wangeditor'
import { UploadFile } from '@/utils/CsDomUtil'
export default {
name: 'Index',
data() {
@@ -49,7 +57,7 @@ export default {
// files 是 input 中选中的文件列表
// insert 是获取图片 url 后,插入到编辑器的方法
files.forEach(image => {
upload(_this.imagesUploadApi, image).then(res => {
UploadFile(_this.imagesUploadApi, image).then(res => {
const data = res.data
const url = _this.baseApi + '/file/' + data.type + '/' + data.realName
insert(url)
@@ -87,12 +95,13 @@ export default {
</script>
<style scoped>
.editor{
text-align:left;
margin: 20px;
width: 730px;
}
::v-deep .w-e-text-container {
height: 360px !important;
}
.editor {
text-align: left;
margin: 20px;
width: 730px;
}
::v-deep .w-e-text-container {
height: 360px !important;
}
</style>
+11 -4
View File
@@ -6,7 +6,13 @@
<crudOperation :permission="permission" />
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="jobSort" label="排序">
@@ -56,6 +62,7 @@ import CRUD, { presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import udOperation from '@crud/UD.operation'
export default {
name: 'Job',
components: { eHeader, eForm, crudOperation, pagination, udOperation },
@@ -103,7 +110,7 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
@@ -104,7 +104,7 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
@@ -2,9 +2,25 @@
<div
v-if="crud.props.searchToggle"
>
<el-input v-model="query.name" clearable size="small" placeholder="输入岗位名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.name"
clearable
size="small"
placeholder="输入岗位名称搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select v-model="query.enabled" clearable size="small" placeholder="状态" class="filter-item" style="width: 90px" @change="crud.toQuery">
<el-select
v-model="query.enabled"
clearable
size="small"
placeholder="状态"
class="filter-item"
style="width: 90px"
@change="crud.toQuery"
>
<el-option v-for="item in dict.dict.job_status" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<rrOperation />
@@ -15,6 +31,7 @@
import { header } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { rrOperation, DateRangePicker },
mixins: [header()],
+85 -20
View File
@@ -4,14 +4,29 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.blurry"
clearable
size="small"
placeholder="模糊搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!--表单渲染-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="580px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="580px"
>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="form.type" size="mini" style="width: 178px">
@@ -29,7 +44,13 @@
>
<IconSelect ref="iconSelect" @selected="selected" />
<el-input slot="reference" v-model="form.icon" style="width: 450px;" placeholder="点击选择图标" readonly>
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 32px;width: 16px;" />
<svg-icon
v-if="form.icon"
slot="prefix"
:icon-class="form.icon"
class="el-input__icon"
style="height: 32px;width: 16px;"
/>
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
</el-input>
</el-popover>
@@ -53,24 +74,47 @@
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.type.toString() !== '2'" label="菜单标题" prop="title">
<el-input v-model="form.title" :style=" form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'" placeholder="菜单标题" />
<el-input
v-model="form.title"
:style=" form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'"
placeholder="菜单标题"
/>
</el-form-item>
<el-form-item v-if="form.type.toString() === '2'" label="按钮名称" prop="title">
<el-input v-model="form.title" placeholder="按钮名称" style="width: 178px;" />
</el-form-item>
<el-form-item v-show="form.type.toString() !== '0'" label="权限标识" prop="permission">
<el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="权限标识" style="width: 178px;" />
<el-input
v-model="form.permission"
:disabled="form.iFrame.toString() === 'true'"
placeholder="权限标识"
style="width: 178px;"
/>
</el-form-item>
<el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path">
<el-input v-model="form.path" placeholder="路由地址" style="width: 178px;" />
</el-form-item>
<el-form-item label="菜单排序" prop="menuSort">
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" style="width: 178px;" />
<el-input-number
v-model.number="form.menuSort"
:min="0"
:max="999"
controls-position="right"
style="width: 178px;"
/>
</el-form-item>
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName">
<el-form-item
v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'"
label="组件名称"
prop="componentName"
>
<el-input v-model="form.componentName" style="width: 450px;" placeholder="匹配组件内Name字段" />
</el-form-item>
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component">
<el-form-item
v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'"
label="组件路径"
prop="component"
>
<el-input v-model="form.component" style="width: 450px;" placeholder="组件路径" />
</el-form-item>
<el-form-item label="上级类目" prop="pid">
@@ -134,7 +178,13 @@
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" width="135px" />
<el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="130px" align="center" fixed="right">
<el-table-column
v-if="checkPer(['admin','menu:edit','menu:del'])"
label="操作"
width="130px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
@@ -150,17 +200,31 @@
<script>
import crudMenu from '@/api/system/menu'
import IconSelect from '@/components/IconSelect'
import Treeselect from '@riophae/vue-treeselect'
import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import DateRangePicker from '@/components/DateRangePicker'
// crud交由presenter持有
const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iFrame: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null }
const defaultForm = {
id: null,
title: null,
menuSort: 999,
path: null,
component: null,
componentName: null,
iFrame: false,
roles: [],
pid: 0,
icon: null,
cache: false,
hidden: false,
type: 0,
permission: null
}
export default {
name: 'Menu',
components: { Treeselect, IconSelect, crudOperation, rrOperation, udOperation, DateRangePicker },
@@ -246,11 +310,12 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__control, ::v-deep .vue-treeselect__placeholder, ::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
</style>
@@ -2,7 +2,15 @@
<div class="app-container">
<div class="head-container">
<div v-if="crud.props.searchToggle">
<el-input v-model="query.userName" clearable size="small" placeholder="输入用户名称查询" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.userName"
clearable
size="small"
placeholder="输入用户名称查询"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<rrOperation />
</div>
<crudOperation>
@@ -21,7 +29,13 @@
</crudOperation>
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="uid" label="会话编号" />
<el-table-column prop="userName" label="用户名" />
@@ -42,7 +56,13 @@
<p>确定强制退出该用户吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="$refs[scope.$index].doClose()">取消</el-button>
<el-button :loading="delLoading" type="primary" size="mini" @click="delMethod(scope.row.key, scope.$index)">确定</el-button>
<el-button
:loading="delLoading"
type="primary"
size="mini"
@click="delMethod(scope.row.key, scope.$index)"
>确定
</el-button>
</div>
<el-button slot="reference" size="mini" type="text">强退</el-button>
</el-popover>
@@ -56,7 +76,7 @@
<script>
import { kickOutUser } from '@/api/system/online'
import CRUD, { presenter, header, crud } from '@crud/crud'
import CRUD, { crud, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
@@ -91,7 +111,8 @@ export default {
type: 'warning'
}).then(() => {
this.delMethod(datas)
}).catch(() => {})
}).catch(() => {
})
},
// 踢出用户
delMethod(key, index) {
@@ -4,7 +4,15 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.jobName" clearable size="small" placeholder="输入任务名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery" />
<el-input
v-model="query.jobName"
clearable
size="small"
placeholder="输入任务名称搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
@@ -17,12 +25,20 @@
type="info"
icon="el-icon-tickets"
@click="doLog"
>日志</el-button>
>日志
</el-button>
</crudOperation>
<Log ref="log" />
</div>
<!--Form表单-->
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" append-to-body width="730px">
<el-dialog
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
append-to-body
width="730px"
>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="100px">
<el-form-item label="任务名称" prop="jobName">
<el-input v-model="form.jobName" style="width: 220px;" />
@@ -70,7 +86,13 @@
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="id" label="任务ID" />
<el-table-column :show-overflow-tooltip="true" prop="jobName" label="任务名称" />
@@ -80,16 +102,45 @@
<el-table-column :show-overflow-tooltip="true" prop="cronExpression" label="cron表达式" />
<el-table-column :show-overflow-tooltip="true" prop="isPause" width="90px" label="状态">
<template slot-scope="scope">
<el-tag :type="scope.row.isPause ? 'warning' : 'success'">{{ scope.row.isPause ? '已暂停' : '运行中' }}</el-tag>
<el-tag :type="scope.row.isPause ? 'warning' : 'success'">{{
scope.row.isPause ? '已暂停' : '运行中'
}}
</el-tag>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="description" width="150px" label="描述" />
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="136px" label="创建日期" />
<el-table-column v-if="checkPer(['admin','quartzJob:edit','quartzJob:del'])" label="操作" width="170px" align="center" fixed="right">
<el-table-column
v-if="checkPer(['admin','quartzJob:edit','quartzJob:del'])"
label="操作"
width="170px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<el-button v-permission="['admin','quartzJob:edit']" size="mini" style="margin-right: 3px;" type="text" @click="crud.toEdit(scope.row)">编辑</el-button>
<el-button v-permission="['admin','quartzJob:edit']" style="margin-left: -2px" type="text" size="mini" @click="execute(scope.row.id)">执行</el-button>
<el-button v-permission="['admin','quartzJob:edit']" style="margin-left: 3px" type="text" size="mini" @click="updateStatus(scope.row.id,scope.row.isPause ? '恢复' : '暂停')">
<el-button
v-permission="['admin','quartzJob:edit']"
size="mini"
style="margin-right: 3px;"
type="text"
@click="crud.toEdit(scope.row)"
>编辑
</el-button>
<el-button
v-permission="['admin','quartzJob:edit']"
style="margin-left: -2px"
type="text"
size="mini"
@click="execute(scope.row.id)"
>执行
</el-button>
<el-button
v-permission="['admin','quartzJob:edit']"
style="margin-left: 3px"
type="text"
size="mini"
@click="updateStatus(scope.row.id,scope.row.isPause ? '恢复' : '暂停')"
>
{{ scope.row.isPause ? '恢复' : '暂停' }}
</el-button>
<el-popover
@@ -101,7 +152,8 @@
<p>确定停止并删除该任务吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="$refs[scope.row.id].doClose()">取消</el-button>
<el-button :loading="delLoading" type="primary" size="mini" @click="delMethod(scope.row.id)">确定</el-button>
<el-button :loading="delLoading" type="primary" size="mini" @click="delMethod(scope.row.id)">确定
</el-button>
</div>
<el-button slot="reference" type="text" size="mini">删除</el-button>
</el-popover>
@@ -116,13 +168,26 @@
<script>
import crudJob from '@/api/system/quartzJob'
import Log from './log'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import DateRangePicker from '@/components/DateRangePicker'
const defaultForm = { id: null, jobName: null, subTask: null, beanName: null, methodName: null, params: null, cronExpression: null, pauseAfterFailure: true, isPause: false, personInCharge: null, email: null, description: null }
const defaultForm = {
id: null,
jobName: null,
subTask: null,
beanName: null,
methodName: null,
params: null,
cronExpression: null,
pauseAfterFailure: true,
isPause: false,
personInCharge: null,
email: null,
description: null
}
export default {
name: 'QuartzJob',
components: { Log, pagination, crudOperation, rrOperation, DateRangePicker },
@@ -2,9 +2,25 @@
<el-dialog :visible.sync="dialog" append-to-body title="执行日志" width="88%">
<!-- 搜索 -->
<div class="head-container">
<el-input v-model="query.jobName" clearable size="small" placeholder="输入任务名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery" />
<el-input
v-model="query.jobName"
clearable
size="small"
placeholder="输入任务名称搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select v-model="query.isSuccess" placeholder="日志状态" clearable size="small" class="filter-item" style="width: 110px" @change="toQuery">
<el-select
v-model="query.isSuccess"
placeholder="日志状态"
clearable
size="small"
class="filter-item"
style="width: 110px"
@change="toQuery"
>
<el-option v-for="item in enabledTypeOptions" :key="item.key" :label="item.displayName" :value="item.key" />
</el-select>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
@@ -17,7 +33,8 @@
type="warning"
icon="el-icon-download"
@click="downloadMethod"
>导出</el-button>
>导出
</el-button>
</div>
</div>
<!--表格渲染-->
@@ -29,13 +46,22 @@
<el-table-column :show-overflow-tooltip="true" prop="cronExpression" label="cron表达式" />
<el-table-column prop="createTime" label="异常详情" width="110px">
<template slot-scope="scope">
<el-button v-show="scope.row.exceptionDetail" size="mini" type="text" @click="info(scope.row.exceptionDetail)">查看详情</el-button>
<el-button
v-show="scope.row.exceptionDetail"
size="mini"
type="text"
@click="info(scope.row.exceptionDetail)"
>查看详情
</el-button>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" align="center" prop="time" width="100px" label="耗时(毫秒)" />
<el-table-column align="center" prop="isSuccess" width="80px" label="状态">
<template slot-scope="scope">
<el-tag :type="scope.row.isSuccess ? 'success' : 'danger'">{{ scope.row.isSuccess ? '成功' : '失败' }}</el-tag>
<el-tag :type="scope.row.isSuccess ? 'success' : 'danger'">{{
scope.row.isSuccess ? '成功' : '失败'
}}
</el-tag>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期" />
@@ -59,6 +85,7 @@
<script>
import crud from '@/mixins/crud'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { DateRangePicker },
// Mixins 是一种包含多个组件选项的对象。可以将 mixin 作为组件的一个选项引入,从而在该组件中“混入”这个对象的选项。通过这种方式,mixins 可以帮助你实现功能复用,减少重复代码。
@@ -96,11 +123,12 @@ export default {
</script>
<style scoped>
.java.hljs{
color: #444;
background: #ffffff !important;
}
::v-deep .el-dialog__body{
padding: 0 20px 10px 20px !important;
}
.java.hljs {
color: #444;
background: #ffffff !important;
}
::v-deep .el-dialog__body {
padding: 0 20px 10px 20px !important;
}
</style>
+55 -23
View File
@@ -4,14 +4,29 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.blurry"
size="small"
clearable
placeholder="输入名称或者描述搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!-- 表单渲染 -->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="520px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="520px"
>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" style="width: 380px;" />
@@ -58,7 +73,15 @@
<div slot="header" class="clearfix">
<span class="role-span">角色列表</span>
</div>
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
<el-table
ref="table"
v-loading="crud.loading"
highlight-current-row
style="width: 100%;"
:data="crud.data"
@selection-change="crud.selectionChangeHandler"
@current-change="handleCurrentChange"
>
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="dataScope" label="数据权限" />
@@ -69,7 +92,13 @@
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right">
<el-table-column
v-if="checkPer(['admin','roles:edit','roles:del'])"
label="操作"
width="130px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
v-if="scope.row.level >= level"
@@ -99,7 +128,8 @@
style="float: right; padding: 6px 9px"
type="primary"
@click="saveMenu"
>保存</el-button>
>保存
</el-button>
</div>
<el-tree
ref="menu"
@@ -123,15 +153,14 @@
<script>
import crudRoles from '@/api/system/role'
import { queryDeptList, queryDeptSuperiorTree } from '@/api/system/dept'
import { queryMenuListByPid, queryChildMenuSet } from '@/api/system/menu'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import { queryChildMenuSet, queryMenuListByPid } from '@/api/system/menu'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import DateRangePicker from '@/components/DateRangePicker'
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 }
@@ -352,21 +381,24 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss">
.role-span {
font-weight: bold;color: #303133;
font-size: 15px;
}
.role-span {
font-weight: bold;
color: #303133;
font-size: 15px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value{
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item{
border: 0;
padding: 0;
}
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value {
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item {
border: 0;
padding: 0;
}
</style>
@@ -1,5 +1,10 @@
<template>
<div v-loading="!show" element-loading-text="数据加载中..." :style="!show ? 'height: 500px' : 'height: 100%'" class="app-container">
<div
v-loading="!show"
element-loading-text="数据加载中..."
:style="!show ? 'height: 500px' : 'height: 100%'"
class="app-container"
>
<div v-if="show">
<el-card class="box-card">
<div style="color: #666;font-size: 13px;">
@@ -139,6 +144,7 @@ import ECharts from 'vue-echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/component/polar'
import { initDataByPost } from '@/api/data'
export default {
name: 'ServerMonitor',
components: {
@@ -251,41 +257,47 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .box-card {
margin-bottom: 5px;
span {
margin-right: 28px;
}
.el-icon-refresh {
margin-right: 10px;
float: right;
cursor:pointer;
}
::v-deep .box-card {
margin-bottom: 5px;
span {
margin-right: 28px;
}
.cpu, .memory, .swap, .disk {
width: 20%;
float: left;
padding-bottom: 20px;
margin-right: 5%;
}
.title {
text-align: center;
font-size: 15px;
font-weight: 500;
color: #999;
margin-bottom: 16px;
}
.footer {
text-align: center;
font-size: 15px;
font-weight: 500;
color: #999;
margin-top: -5px;
margin-bottom: 10px;
}
.content {
text-align: center;
margin-top: 5px;
margin-bottom: 5px;
.el-icon-refresh {
margin-right: 10px;
float: right;
cursor: pointer;
}
}
.cpu, .memory, .swap, .disk {
width: 20%;
float: left;
padding-bottom: 20px;
margin-right: 5%;
}
.title {
text-align: center;
font-size: 15px;
font-weight: 500;
color: #999;
margin-bottom: 16px;
}
.footer {
text-align: center;
font-size: 15px;
font-weight: 500;
color: #999;
margin-top: -5px;
margin-bottom: 10px;
}
.content {
text-align: center;
margin-top: 5px;
margin-bottom: 5px;
}
</style>
@@ -12,6 +12,7 @@
<script>
import Local from './local/index.vue'
import Oss from './oss/index.vue'
export default {
name: 'Storage',
components: { Local, Oss },
@@ -4,7 +4,15 @@
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" clearable size="small" placeholder="输入内容模糊搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-input
v-model="query.blurry"
clearable
size="small"
placeholder="输入内容模糊搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
@@ -23,7 +31,14 @@
</crudOperation>
</div>
<!--表单组件-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.add ? '文件上传' : '编辑文件'" width="500px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.add ? '文件上传' : '编辑文件'"
width="500px"
>
<el-form ref="form" :model="form" size="small" label-width="80px">
<el-form-item label="文件名">
<el-input v-model="form.name" style="width: 370px;" />
@@ -52,7 +67,13 @@
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="name" label="文件名">
<template slot-scope="scope">
@@ -105,7 +126,7 @@
import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth'
import crudFile from '@/api/system/localStorage'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
@@ -175,10 +196,11 @@ export default {
</script>
<style scoped>
::v-deep .el-image__error, .el-image__placeholder{
background: none;
}
::v-deep .el-image-viewer__wrapper{
top: 55px;
}
::v-deep .el-image__error, .el-image__placeholder {
background: none;
}
::v-deep .el-image-viewer__wrapper {
top: 55px;
}
</style>
@@ -95,7 +95,7 @@
import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth'
import crudFile from '@/api/system/ossStorage'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
+76 -30
View File
@@ -9,7 +9,12 @@
<div>
<div style="text-align: center">
<div class="el-upload">
<img :src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar" title="点击上传头像" class="avatar" @click="toggleShow">
<img
:src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar"
title="点击上传头像"
class="avatar"
@click="toggleShow"
>
<myUpload
v-model="show"
:headers="headers"
@@ -19,13 +24,36 @@
</div>
</div>
<ul class="user-info">
<li><div style="height: 100%"><svg-icon icon-class="login" /> 登录账号<div class="user-right">{{ user.username }}</div></div></li>
<li><svg-icon icon-class="user1" /> 用户昵称 <div class="user-right">{{ user.nickName }}</div></li>
<li><svg-icon icon-class="dept" /> 所属部门 <div class="user-right"> {{ user.dept.name }}</div></li>
<li><svg-icon icon-class="phone" /> 手机号码 <div class="user-right">{{ user.phone }}</div></li>
<li><svg-icon icon-class="email" /> 用户邮箱 <div class="user-right">{{ user.email }}</div></li>
<li>
<svg-icon icon-class="anq" /> 安全设置
<div style="height: 100%">
<svg-icon icon-class="login" />
登录账号
<div class="user-right">{{ user.username }}</div>
</div>
</li>
<li>
<svg-icon icon-class="user1" />
用户昵称
<div class="user-right">{{ user.nickName }}</div>
</li>
<li>
<svg-icon icon-class="dept" />
所属部门
<div class="user-right"> {{ user.dept.name }}</div>
</li>
<li>
<svg-icon icon-class="phone" />
手机号码
<div class="user-right">{{ user.phone }}</div>
</li>
<li>
<svg-icon icon-class="email" />
用户邮箱
<div class="user-right">{{ user.email }}</div>
</li>
<li>
<svg-icon icon-class="anq" />
安全设置
<div class="user-right">
<a @click="$refs.pass.dialog = true">修改密码</a>
<a @click="$refs.email.dialog = true">修改邮箱</a>
@@ -40,7 +68,14 @@
<el-card class="box-card">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="用户资料" name="first">
<el-form ref="form" :model="form" :rules="rules" style="margin-top: 10px;" size="small" label-width="65px">
<el-form
ref="form"
:model="form"
:rules="rules"
style="margin-top: 10px;"
size="small"
label-width="65px"
>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" style="width: 35%" />
<span style="color: #C0C0C0;margin-left: 10px;">用户昵称不作为登录使用</span>
@@ -78,7 +113,10 @@
align="right"
>
<template slot="header">
<div style="display:inline-block;float: right;cursor: pointer" @click="init">创建日期<i class="el-icon-refresh" style="margin-left: 40px" /></div>
<div style="display:inline-block;float: right;cursor: pointer" @click="init">创建日期<i
class="el-icon-refresh"
style="margin-left: 40px"
/></div>
</template>
<template slot-scope="scope">
<span>{{ scope.row.createTime }}</span>
@@ -111,10 +149,11 @@ import updatePass from './center/updatePass'
import updateEmail from './center/updateEmail'
import { getToken } from '@/utils/auth'
import store from '@/store'
import { isvalidPhone } from '@/utils/validate'
import { isvalidPhone } from '@/utils/CsValidateUtil'
import crud from '@/mixins/crud'
import { editUser } from '@/api/system/user'
import Avatar from '@/assets/images/avatar.png'
export default {
name: 'Center',
components: { updatePass, updateEmail, myUpload },
@@ -159,7 +198,8 @@ export default {
},
created() {
this.form = { id: this.user.id, nickName: this.user.nickName, gender: this.user.gender, phone: this.user.phone }
store.dispatch('GetInfo').then(() => {})
store.dispatch('GetInfo').then(() => {
})
},
methods: {
toggleShow() {
@@ -175,7 +215,8 @@ export default {
return true
},
cropUploadSuccess(jsonData, field) {
store.dispatch('GetInfo').then(() => {})
store.dispatch('GetInfo').then(() => {
})
},
doSubmit() {
if (this.$refs['form']) {
@@ -184,7 +225,8 @@ export default {
this.saveLoading = true
editUser(this.form).then(() => {
this.editSuccessNotify()
store.dispatch('GetInfo').then(() => {})
store.dispatch('GetInfo').then(() => {
})
this.saveLoading = false
}).catch(() => {
this.saveLoading = false
@@ -198,24 +240,28 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss">
.avatar {
width: 120px;
height: 120px;
border-radius: 50%;
.avatar {
width: 120px;
height: 120px;
border-radius: 50%;
}
.user-info {
padding-left: 0;
list-style: none;
li {
border-bottom: 1px solid #F0F3F4;
padding: 11px 0;
font-size: 13px;
}
.user-info {
padding-left: 0;
list-style: none;
li{
border-bottom: 1px solid #F0F3F4;
padding: 11px 0;
font-size: 13px;
}
.user-right {
float: right;
a{
color: #317EF3;
}
.user-right {
float: right;
a {
color: #317EF3;
}
}
}
</style>
@@ -1,10 +1,21 @@
<template>
<div style="display: inline-block;">
<el-dialog :visible.sync="dialog" :close-on-click-modal="false" :before-close="cancel" :title="title" append-to-body width="475px" @close="cancel">
<el-dialog
:visible.sync="dialog"
:close-on-click-modal="false"
:before-close="cancel"
:title="title"
append-to-body
width="475px"
@close="cancel"
>
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="88px">
<el-form-item label="新邮箱" prop="email">
<el-input v-model="form.email" auto-complete="on" style="width: 200px;" />
<el-button :loading="codeLoading" :disabled="isDisabled" size="small" @click="sendCode">{{ buttonName }}</el-button>
<el-button :loading="codeLoading" :disabled="isDisabled" size="small" @click="sendCode">{{
buttonName
}}
</el-button>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input v-model="form.code" style="width: 320px;" />
@@ -23,9 +34,10 @@
<script>
import store from '@/store'
import { validEmail } from '@/utils/validate'
import { validEmail } from '@/utils/CsValidateUtil'
import { updateEmail } from '@/api/system/user'
import { sendResetEmailCaptcha } from '@/api/system/code'
export default {
props: {
email: {
@@ -109,7 +121,8 @@ export default {
type: 'success',
duration: 1500
})
store.dispatch('GetInfo').then(() => {})
store.dispatch('GetInfo').then(() => {
})
}).catch(err => {
this.loading = false
console.log(err.response.data.message)
@@ -1,6 +1,14 @@
<template>
<div style="display: inline-block">
<el-dialog :visible.sync="dialog" :close-on-click-modal="false" :before-close="cancel" :title="title" append-to-body width="500px" @close="cancel">
<el-dialog
:visible.sync="dialog"
:close-on-click-modal="false"
:before-close="cancel"
:title="title"
append-to-body
width="500px"
@close="cancel"
>
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="88px">
<el-form-item label="旧密码" prop="oldPass">
<el-input v-model="form.oldPass" type="password" auto-complete="on" style="width: 370px;" />
@@ -23,6 +31,7 @@
<script>
import store from '@/store'
import { updatePass } from '@/api/system/user'
export default {
data() {
const confirmPass = (rule, value, callback) => {
+46 -17
View File
@@ -52,7 +52,14 @@
</crudOperation>
</div>
<!--表单渲染-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="555px">
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="555px"
>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="66px">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" @keydown.native="keydown($event)" />
@@ -104,7 +111,8 @@
v-for="item in dict.user_status"
:key="item.id"
:label="item.value"
>{{ item.label }}</el-radio>
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item style="margin-bottom: 0;" label="角色" prop="roleDatas" class="is-required">
@@ -133,7 +141,13 @@
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="username" label="用户名" />
<el-table-column :show-overflow-tooltip="true" prop="nickName" label="昵称" />
@@ -182,24 +196,35 @@
<script>
import crudUser from '@/api/system/user'
import { isvalidPhone } from '@/utils/validate'
import { isvalidPhone } from '@/utils/CsValidateUtil'
import { queryDeptList, queryDeptSuperiorTree } from '@/api/system/dept'
import { queryRoleList, getLevel } from '@/api/system/role'
import { getLevel, queryRoleList } from '@/api/system/role'
import { queryAllEnableJob } from '@/api/system/job'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import DateRangePicker from '@/components/DateRangePicker'
import Treeselect from '@riophae/vue-treeselect'
import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import { mapGetters } from 'vuex'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import CuteDeptTree from '@/views/components/business/CuteDeptTree'
let userRoles = []
let userJobs = []
const defaultForm = { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null }
const defaultForm = {
id: null,
username: null,
nickName: null,
gender: '男',
email: null,
enabled: 'false',
roles: [],
jobs: [],
dept: { id: null },
phone: null
}
export default {
name: 'User',
components: { CuteDeptTree, Treeselect, crudOperation, rrOperation, udOperation, pagination, DateRangePicker },
@@ -446,19 +471,22 @@ export default {
getRoles() {
queryRoleList().then(res => {
this.roles = res
}).catch(() => { })
}).catch(() => {
})
},
// 获取弹窗内岗位数据
getJobs() {
queryAllEnableJob().then(res => {
this.jobs = res.content
}).catch(() => { })
}).catch(() => {
})
},
// 获取权限级别
getRoleLevel() {
getLevel().then(res => {
this.level = res.level
}).catch(() => { })
}).catch(() => {
})
},
checkboxT(row, rowIndex) {
return row.id !== this.user.id
@@ -476,7 +504,8 @@ export default {
console.log(ids)
crudUser.resetPwd(ids).then(() => {
this.crud.notify('重置成功, 用户新密码:123456', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {})
}).catch(() => {
})
}).catch(() => {
})
}
@@ -485,8 +514,8 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
::v-deep .vue-treeselect__control, ::v-deep .vue-treeselect__placeholder, ::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
</style>