Sfoglia il codice sorgente

开发账号增加工具箱入口及AES加解密页面

cfort 1 anno fa
parent
commit
4e17b4bcec

+ 50 - 0
src/layout/header-aside/components/header-tools/index.vue

@@ -0,0 +1,50 @@
+
+<template>
+    <div>
+        <el-dropdown trigger="click">
+            <el-tooltip effect="dark" content="工具箱" placement="bottom">
+                <el-button type="text" class="ibps-mr btn-text can-hover">
+                    <i class="ibps-icon-wrench" style="font-size: 18px;" />
+                </el-button>
+            </el-tooltip>
+            <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item
+                    v-for="(item, index) in tools"
+                    :key="index"
+                    :icon="item.icon"
+                    @click.native="handleShowDialog(item.visible)"
+                >{{ item.name }}</el-dropdown-item>
+            </el-dropdown-menu>
+        </el-dropdown>
+        <convert-aes
+            v-if="showConvertAes"
+            :visible.sync="showConvertAes"
+            @close="() => showConvertAes = false"
+        />
+    </div>
+</template>
+<script>
+import ConvertAes from '@/views/platform/system/tools/convertByAes.vue'
+export default {
+    components: {
+        ConvertAes
+    },
+    data () {
+        return {
+            showConvertAes: false,
+            tools: [
+                {
+                    name: 'AES加解密',
+                    visible: 'showConvertAes',
+                    icon: 'ibps-icon-unlock-alt'
+                }
+            ]
+        }
+    },
+    methods: {
+        handleShowDialog (visible) {
+            this[visible] = true
+        }
+    }
+}
+</script>

+ 3 - 0
src/layout/header-aside/layout.vue

@@ -96,6 +96,7 @@
 
                     <ibps-header-clean-cache v-if="isSuper" type="platform" />
                     <ibps-header-clean-cache v-if="isSuper" type="form" />
+                    <ibps-header-tools v-if="isSuper" />
                     <!-- <ibps-header-clean-cache v-if="isSuper" type="oauth" />
                     <ibps-header-clean-cache v-if="isSuper" type="office" /> -->
 
@@ -198,6 +199,7 @@ import IbpsHeaderUser from './components/header-user'
 import IbpsHeaderErrorLog from './components/header-error-log'
 import IbpsHeaderBaseUrl from './components/header-base-url'
 import IbpsHeaderCleanCache from './components/header-clean-cache'
+import IbpsHeaderTools from './components/header-tools'
 // import IbpsHeaderDownload from './components/header-download'
 import IbpsNotifyMonitor from '@/business/platform/socket/notify-monitor'
 import { mapState, mapGetters, mapActions } from 'vuex'
@@ -229,6 +231,7 @@ export default {
         IbpsHeaderErrorLog,
         IbpsHeaderBaseUrl,
         IbpsHeaderCleanCache,
+        IbpsHeaderTools,
         // IbpsHeaderDownload,
         IbpsNotifyMonitor
     },

+ 2 - 1
src/utils/common.js

@@ -1,6 +1,6 @@
 // 通用工具类,定义通用函数及常用接口
 import { mapValues } from 'lodash'
-import { encryptByAes } from '@/utils/encrypt'
+import { encryptByAes, decryptByAes } from '@/utils/encrypt'
 import { preview } from '@/business/platform/form/utils/custom/preview'
 import request from '@/business/platform/form/utils/custom/joinCURD'
 import pinyin4js from 'pinyin4js'
@@ -163,6 +163,7 @@ export default {
     getNextIdByAlias,
     decode,
     encryptByAes,
+    decryptByAes,
     downloadByBlob,
     sendMsg,
     saveNews,

+ 181 - 0
src/views/platform/system/tools/convertByAes.vue

@@ -0,0 +1,181 @@
+<template>
+    <el-dialog
+        :visible.sync="dialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :show-close="true"
+        append-to-body
+        fullscreen
+        class="dialog tools-dialog"
+        top="5vh"
+        @close="closeDialog"
+    >
+        <div class="tools-container">
+            <div class="title">AES加解密</div>
+            <div class="card">
+                <div class="item">
+                    <div class="label">明文</div>
+                    <div class="value">
+                        <el-input
+                            v-model="plaintext"
+                            type="textarea"
+                            :rows="10"
+                            placeholder="请输入明文"
+                        />
+                    </div>
+                </div>
+                <div class="operate-btn">
+                    <el-button
+                        type="primary"
+                        size="small"
+                        icon="ibps-icon-level-down"
+                        @click="handleEncrypt"
+                    >加密</el-button>
+                    <el-button
+                        type="warning"
+                        size="small"
+                        icon="ibps-icon-level-up"
+                        @click="handleDecrypt"
+                    >解密</el-button>
+                    <el-button
+                        type="info"
+                        size="small"
+                        icon="ibps-icon-copy"
+                        @click="handleCopy"
+                    >复制明文SQL</el-button>
+                </div>
+                <div class="item">
+                    <div class="label">密文</div>
+                    <div class="value">
+                        <el-input
+                            v-model="ciphertext"
+                            type="textarea"
+                            :rows="10"
+                            placeholder="请输入密文"
+                        />
+                    </div>
+                </div>
+            </div>
+        </div>
+    </el-dialog>
+</template>
+<script>
+
+export default {
+    props: {
+        visible: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data () {
+        return {
+            dialogVisible: this.visible,
+            plaintext: '',
+            ciphertext: ''
+        }
+    },
+    watch: {
+        visible: {
+            handler (val, oldVal) {
+                this.dialogVisible = this.visible
+            }
+        }
+    },
+    methods: {
+        handleActionEvent (key, type, index) {
+            switch (key) {
+                case 'cancel':
+                    this.handleCancel()
+                    break
+                default:
+                    break
+            }
+        },
+        handleEncrypt () {
+            if (!this.plaintext) {
+                return this.$message.warning('明文为空!')
+            }
+            this.ciphertext = this.$common.encryptByAes(this.plaintext)
+        },
+        handleDecrypt () {
+            if (!this.ciphertext) {
+                return this.$message.warning('请输入密文!')
+            }
+            const temp = this.$common.decryptByAes(this.ciphertext)
+            if (this.$utils.isEmpty(temp)) {
+                return this.$message.error('密文无效,无法解密!')
+            }
+            this.plaintext = temp
+        },
+        handleCopy () {
+            if (!this.plaintext) {
+                return this.$message.warning('明文为空!')
+            }
+            const temp = JSON.parse(this.plaintext)
+            const hasSql = temp.hasOwnProperty('sql')
+            // if (!temp.sql) {
+            //     return this.$message.warning('明文中不含SQL!')
+            // }
+            navigator.clipboard.writeText(temp.sql || this.plaintext).then(() => {
+                const msg = hasSql ? '明文SQL已复制到剪贴板!' : '明文中不含SQL,已复制所有内容到剪贴板!'
+                this.$message.success(msg)
+            }).catch(error => {
+                this.$message.success('复制失败!')
+                console.log(error)
+            })
+        },
+        closeDialog () {
+            this.$emit('close', false)
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+.tools-container {
+    width: 1080px;
+    margin: 20px auto;
+    height: calc(100% - 100px);
+    padding: 20px;
+    border: 1px solid #ccc;
+    border-radius: 10px;
+    background-color: #f9f9f9;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+    transition: transform 0.2s;
+    .title {
+        font-size: 24px;
+        font-weight: bold;
+        margin-bottom: 20px;
+        text-align: center;
+    }
+    .card {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: space-between;
+        .item {
+            width: 100%;
+            margin-bottom: 20px;
+            padding: 15px;
+            // border: 1px solid #ccc;
+            // border-radius: 5px;
+            // background-color: #fff;
+            // transition: transform 0.2s;
+            // &:hover {
+            //     transform: scale(1.01);
+            // }
+            .label {
+                font-size: 16px;
+                font-weight: bold;
+                margin-bottom: 10px;
+            }
+            .value {
+                font-size: 16px;
+                color: #666;
+            }
+        }
+        .operate-btn {
+            margin: 0 auto;
+        }
+    }
+}
+</style>