【二開】CRMEB開源版按鈕權限控制

【二開】CRMEB開源版按鈕權限控制

使用方法

v-unique_auth="'order-refund'"
<el-dropdown-itemv-unique_auth="'order-refund'">立即退款</el-dropdown-item
>

或者 滿足其中一個即可

v-unique_auth="['order-delete','order-dels']"

通過管理端權限維護按鈕即可

1. 存儲權限

template/admin/src/pages/account/login/index.vue

登錄成功后存儲

Local.set('unique_auth', data.unique_auth);

完整代碼

<template><div class="page-account"><div class="container" :class="[fullWidth > 768 ? 'containerSamll' : 'containerBig']"><swiper :options="swiperOption" class="swiperPross" v-if="fullWidth > 768"><swiper-slide class="swiperPic" v-for="(item, index) in swiperList" :key="index"><img :src="item.slide" alt="" /></swiper-slide><div class="swiper-pagination" slot="pagination"></div></swiper><div class="index_from page-account-container from-wh"><div class="page-account-top"><div class="page-account-top-logo"><img :src="login_logo" alt="logo" style="width: 100%; height: 74px" /></div></div><el-form ref="formInline" :model="formInline" :rules="ruleInline" @keyup.enter="handleSubmit('formInline')"><el-form-item prop="username"><el-inputtype="text"v-model="formInline.username"prefix="ios-contact-outline"placeholder="請輸入用戶名"size="large"/></el-form-item><el-form-item prop="password"><el-inputtype="password"v-model="formInline.password"prefix="ios-lock-outline"placeholder="請輸入密碼"size="large"show-password/></el-form-item><!-- <el-form-item prop="code"><div class="code"><el-inputtype="text"v-model="formInline.code"prefix="ios-keypad-outline"placeholder="請輸入驗證碼"size="large"/><img :src="imgcode" class="pictrue" v-db-click @click="captchas" /></div></el-form-item> --><el-form-item class="pt10"><el-buttontype="primary":loading="loading"size="large"v-db-click@click="handleSubmit('formInline')"class="btn">登錄</el-button></el-form-item></el-form></div></div><Verify@success="success"captchaType="blockPuzzle":imgSize="{ width: '330px', height: '155px' }"ref="verify"></Verify><div class="footer"><div class="pull-right" v-if="copyright">{{ copyright }}</div><div class="pull-right" v-else>Copyright ? 2014-2025 <a href="https://www.crmeb.com" target="_blank">{{ version }}</a></div></div></div>
</template>
<script>
import { AccountLogin, loginInfoApi } from '@/api/account';
import { getWorkermanUrl } from '@/api/kefu';
import { setCookies } from '@/libs/util';
import '@/assets/js/canvas-nest.min';
import Verify from '@/components/verifition/Verify';
import { PrevLoading } from '@/utils/loading.js';
import { formatFlatteningRoutes, findFirstNonNullChildren } from '@/libs/system';
import { Local } from '@/utils/storage.js';export default {components: {Verify,},data() {return {fullWidth: document.documentElement.clientWidth,swiperOption: {pagination: '.swiper-pagination',autoplay: true,},loading: false,isShow: false,imgcode: '',formInline: {username: '',password: '',},ruleInline: {username: [{ required: true, message: '請輸入用戶名', trigger: 'blur' }],password: [{ required: true, message: '請輸入密碼', trigger: 'blur' }],},login_captcha: 0,login_logo: '',swiperList: [],defaultSwiperList: require('@/assets/images/sw.png'),key: '',copyright: '',version: '',timer: null,};},created() {document.onkeydown = (e) => {if (this.$route.name === 'login' && (e.keyCode === 13 || e.which === 13)) {this.handleSubmit('formInline');}};window.addEventListener('resize', this.handleResize);},mounted() {this.$nextTick(() => {this.handleResize();this.swiperData();});},beforeDestroy() {window.removeEventListener('resize', this.handleResize);document.onkeydown = null;const canvas = document.getElementsByTagName('canvas')[0];if (canvas) canvas.removeAttribute('class', 'index_bg');},methods: {swiperData() {loginInfoApi().then((res) => {const data = res.data || {};document.title = `${data.site_name} - 登錄`;localStorage.setItem('ADMIN_TITLE', data.site_name || '');this.$store.commit('setAdminTitle', data.site_name);this.login_logo = data.login_logo || require('@/assets/images/logo.png');this.swiperList = data.slide && data.slide.length ? data.slide : [{ slide: this.defaultSwiperList }];this.key = data.key;this.copyright = data.copyright;this.version = data.version;this.login_captcha = data.login_captcha;}).catch((err) => {this.$message.error(err);this.login_logo = require('@/assets/images/logo.png');this.swiperList = [{ slide: this.defaultSwiperList }];});},success(params) {this.closeModel(params);},closeModel(params) {this.isShow = false;this.loading = true;AccountLogin({account: this.formInline.username,pwd: this.formInline.password,key: this.key,captchaType: 'blockPuzzle',captchaVerification: params ? params.captchaVerification : '',}).then(async (res) => {const data = res.data;const expires = this.getExpiresTime(data.expires_time);setCookies('uuid', data.user_info.id, expires);setCookies('token', data.token, expires);setCookies('expires_time', data.expires_time, expires);Local.set('PERMISSIONS', data.site_func);Local.set('unique_auth', data.unique_auth);this.$store.commit('userInfo/uniqueAuth', data.unique_auth);this.$store.commit('userInfo/userInfo', data.user_info);this.$store.commit('menus/setopenMenus', []);this.$store.commit('menus/getmenusNav', data.menus);this.$store.dispatch('routesList/setRoutesList', data.menus);const arr = formatFlatteningRoutes(this.$router.options.routes);this.formatTwoStageRoutes(arr);this.$store.commit('menus/setOneLvMenus', arr);const routes = formatFlatteningRoutes(data.menus);this.$store.commit('menus/setOneLvRoute', routes);this.$store.commit('userInfo/name', data.user_info.account);this.$store.commit('userInfo/avatar', data.user_info.head_pic);this.$store.commit('userInfo/access', data.unique_auth);this.$store.commit('userInfo/logo', data.logo);this.$store.commit('userInfo/logoSmall', data.logo_square);this.$store.commit('userInfo/version', data.version);this.$store.commit('userInfo/newOrderAudioLink', data.newOrderAudioLink);this.login_captcha = 0;try {if (data.queue === false) {this.$notify.warning({title: '溫馨提示',dangerouslyUseHTMLString: true,message:'您的【消息隊列】未開啟,沒有開啟會導致異步任務無法執行。請盡快執行命令開啟!!<a href="https://doc.crmeb.com/single/v54/13667" target="_blank">點擊查看開啟方法</a>',duration: 30000,});}if (data.timer === false) {setTimeout(() => {this.$notify.warning({title: '溫馨提示',dangerouslyUseHTMLString: true,message:'您的【定時任務】未開啟,沒有開啟會導致自動收貨、未支付自動取消訂單、訂單自動好評、拼團到期退款等任務無法正常執行。請盡快執行命令開啟!!<a href="https://doc.crmeb.com/single/v54/13667" target="_blank">點擊查看開啟方法</a>',duration: 30000,});}, 0);}this.checkSocket();} catch (e) {}PrevLoading.start();this.$router.push({path: data.menus.length ? findFirstNonNullChildren(data.menus).path : this.$routeProStr + '/',});}).catch((res) => {const data = res || {};this.$message.error(data.msg || '登錄失敗');if (res && res.data) this.login_captcha = res.data.login_captcha;}).finally(() => {setTimeout(() => {this.loading = false;}, 1000);});},formatTwoStageRoutes(arr) {if (!arr.length) return false;const cacheList = [];arr.forEach((v) => {if (v && v.meta && v.meta.keepAlive) {cacheList.push(v.name);}});if (cacheList.length) {this.$store.dispatch('keepAliveNames/setCacheKeepAlive', cacheList);}},checkSocket() {getWorkermanUrl().then((res) => {const url = res.data.admin;let isNotice = false;const socket = new window.WebSocket(url);socket.onopen = () => {isNotice = true;socket.close();};socket.onerror = socket.onclose = () => {if (!isNotice) {isNotice = true;this.$notify.warning({title: '溫馨提示',message:'您的【長連接】未開啟,沒有開啟會導致系統默認客服無法使用,后臺訂單通知無法收到。請盡快執行命令開啟!!<a href="https://doc.crmeb.com/single/v54/13667" target="_blank">點擊查看開啟方法</a>',dangerouslyUseHTMLString: true,duration: 30000,});}};});},getExpiresTime(expiresTime) {const nowTimeNum = Math.round(Date.now() / 1000);const expiresTimeNum = expiresTime - nowTimeNum;return parseFloat(expiresTimeNum / 60 / 60 / 24);},closefail() {this.$message.error('校驗錯誤');},handleResize() {this.fullWidth = document.documentElement.clientWidth;const canvas = document.getElementsByTagName('canvas')[0];if (canvas) {if (this.fullWidth < 768) {canvas.removeAttribute('class', 'index_bg');} else {canvas.className = 'index_bg';}}},handleSubmit(name) {this.$refs[name].validate((valid) => {if (valid) {if (this.login_captcha === 1) {this.$refs.verify.show();} else {this.closeModel();}}});},},
};
</script>
<style lang="scss" scoped>
.page-account {display: flex;width: 100%;background-image: url('../../../assets/images/bg.jpg');background-size: cover;background-position: center;flex-direction: column;justify-content: center;align-items: center;height: 100vh;overflow: auto;
}
.page-account .code {display: flex;align-items: center;justify-content: center;
}
.page-account .code .pictrue {height: 40px;
}
.swiperPross {border-radius: 12px 0px 0px 12px;
}
.swiperPross,
.swiperPic,
.swiperPic img {width: 510px;height: 100%;
}
.swiperPic img {width: 100%;height: 100%;
}
.container {height: 400px !important;padding: 0 !important;border-radius: 12px;z-index: 1;display: flex;
}
.containerSamll {/* width: 56% !important; */background: #fff !important;
}
.containerBig {width: auto !important;background: #f7f7f7 !important;
}
.index_from {padding: 32px 40px 32px 40px;height: 400px;box-sizing: border-box;
}
.page-account-top {padding: 20px 0 24px 0 !important;box-sizing: border-box !important;display: flex;justify-content: center;
}
.page-account-container {border-radius: 0px 6px 6px 0px;
}
.btn {width: 100%;background: linear-gradient(90deg, rgba(25, 180, 241, 1) 0%, rgba(14, 115, 232, 1) 100%) !important;
}
.captchaBox {width: 310px;
}input {display: block;width: 290px;line-height: 40px;margin: 10px 0;padding: 0 10px;outline: none;border: 1px solid #c8cccf;border-radius: 4px;color: #6a6f77;
}#msg {width: 100%;line-height: 40px;font-size: 14px;text-align: center;
}a:link,
a:visited,
a:hover,
a:active {margin-left: 100px;color: #0366d6;
}
.index_from ::v-deep .ivu-input-large {font-size: 14px !important;
}
.from-wh {width: 400px;
}
.pull-right {float: right !important;
}
::v-deep .el-button--primary {border: none;
}
::v-deep .el-button {padding: 13px 20px !important;
}
.pull-right {float: right !important;color: #666;
}
.pull-right a {margin-left: 0;color: #666;
}
.footer {position: fixed;bottom: 0;width: 100%;left: 0;margin: 0;background: rgba(255, 255, 255, 0.8);border-top: 1px solid #e7eaec;overflow: hidden;padding: 10px 20px;height: 36px;line-height: 18px;z-index: 999;
}
</style>

2. 創建權限驗證 js

template/admin/src/directive/module/unique_auth.js

import { Local } from '@/utils/storage.js';/*** 判斷傳入的 key 是否在數組 arr 中存在* @param {string} key - 待判斷的字符串* @returns {boolean} - 返回布爾值,表示是否有權限*/
function checkArray(key) {// seckill 秒殺 bargain 砍價 combination 拼團let arr = Local.get('unique_auth'); // 定義一個數組,包含三種類型if(!key){return false;}if(key instanceof Array){for (let i = 0; i < key.length; i++){let keytmp = key[i]if(!keytmp){continue}let index = arr.indexOf(keytmp); // 獲取 key 在數組中的索引console.info('所有權限', index, keytmp, arr)if (index > -1) {// 如果索引大于 -1,說明 key 存在于數組中return true; // 有權限} else {return false; // 無權限}}return false}let index = arr.indexOf(key); // 獲取 key 在數組中的索引console.info('所有權限', index, key, arr)if (index > -1) {// 如果索引大于 -1,說明 key 存在于數組中return true; // 有權限} else {return false; // 無權限}
}/*** @description 一個Vue指令,用于控制組件的顯示和隱藏* @param {Object} el - 指令綁定的DOM元素* @param {Object} binding - 指令綁定的對象*/
const unique_auth = {inserted: function (el, binding) {console.info('權限驗證', binding.value, el)let permission = binding.value; // 獲取到 v-permission的值if (permission) {let hasPermission = checkArray(permission); // 調用checkArray函數判斷是否有權限if (!hasPermission) {console.info('無權限', permission)// 沒有權限 移除Dom元素el.parentNode && el.parentNode.removeChild(el);}}},
};export default unique_auth;

3. 配置directives

import unique_auth from './module/unique_auth';const directives = {draggable,clipboard,auth,permission, unique_auth,dbClick,
};

template/admin/src/directive/directives.js

import draggable from './module/draggable';
import clipboard from './module/clipboard';
import auth from './module/auth';
import permission from './module/permission';
import dbClick from './module/dbClick';
import unique_auth from './module/unique_auth';const directives = {draggable,clipboard,auth,permission, unique_auth,dbClick,
};export default directives;

4.配置指令

  Vue.directive('unique_auth', directive.unique_auth);

template/admin/src/directive/index.js

import directive from './directives';const importDirective = (Vue) => {/*** 拖拽指令 v-draggable="options"* options = {*  trigger: /這里傳入作為拖拽觸發器的CSS選擇器/,*  body:    /這里傳入需要移動容器的CSS選擇器/,*  recover: /拖動結束之后是否恢復到原來的位置/* }*/Vue.directive('draggable', directive.draggable);/*** clipboard指令 v-draggable="options"* options = {*  value:    /在輸入框中使用v-model綁定的值/,*  success:  /復制成功后的回調/,*  error:    /復制失敗后的回調/* }*/Vue.directive('clipboard', directive.clipboard);/*** v-auth="['string-string']"* */Vue.directive('auth', directive.auth);Vue.directive('permission', directive.permission);Vue.directive('unique_auth', directive.unique_auth);Vue.directive('dbClick', directive.dbClick);
};export default importDirective;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96476.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96476.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96476.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AOSP源碼下載及編譯錯誤解決

源碼下載 軟件下載sudo apt-get updatesudo apt-get install gitsudo apt-get install curlsudo apt-get install adbsudo apt-get install reposudo apt-get install vimsudo apt-get install -y git devscripts equivs config-package-dev debhelper-compat golang curl配置g…

實驗-高級acl(簡單)

實驗-高級acl&#xff08;簡單&#xff09;預習一、實驗設備二、拓撲圖三、配置3.1、網絡互通3.2、配置ACL3.3、取消配置步驟1&#xff1a;先移除接口上的ACL應用步驟2&#xff1a;修改或刪除ACL中的錯誤規則方法A&#xff1a;直接刪除錯誤規則&#xff08;保留其他正確規則&am…

IoC / DI 實操

1. 建三層類包結構&#xff1a;com.lib ├─ config ├─ controller ├─ service ├─ repository ├─ model └─ annotation // 自定義限定符① 實體 Bookpackage com.lib.model; public class Book {private Integer id;private String title;// 全參構造 gette…

AdsPower RPA 從excel中依次讀取多個TikTok賬號對多個TikTok賬號目標發送信息

多個賬號對多個目標發送子場景 B&#xff1a;多個賬號向“不同的”目標循環發送&#xff08;最復雜的群發邏輯&#xff09;流程&#xff1a;Excel表中有一個“目標用戶”列表。RPA流程會進行嵌套循環&#xff1a;外層循環&#xff1a;遍歷Excel中的每一行數據&#xff08;即每一…

擴散模型進化史

一幅精美的圖片&#xff0c;一段精彩的視頻&#xff0c;可能始于一片純粹的噪聲。 2024年的計算機視覺頂會CVPR上&#xff0c;擴散模型成為絕對主角。從圖像生成到視頻理解&#xff0c;從超分辨率到3D建模&#xff0c;擴散模型正以驚人的速度重塑著AIGC&#xff08;AI生成內容&…

一次 Linux 高負載 (Load) 異常問題排查實錄

一次 Linux 高負載&#xff08;Load&#xff09;異常排查實錄一、背景及排查過程材料二、排查分析2.1Load 的真正含義2.2&#xff1a;確認異常進程2.3&#xff1a;線程卡在哪&#xff08;wchan&#xff09;2.4&#xff1a;perf 采樣&#xff08;用戶態/內核態熱點&#xff09;2…

淺析Linux進程信號處理機制:基本原理及應用

文章目錄概述信號類型可靠信號與不可靠信號Fatal信號與Non Fatal信號不可捕獲/忽略信號信號工作機制信號處理方式信號嵌套處理信號使用信號發送kill命令注冊信號處理函數信號安全與函數可重入性可重入函數線程安全與可重入性相關參考概述 Linux信號機制是進程間通信的一種方式…

【學習K230-例程19】GT6700-TCP-Client

B站視頻 TCP TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff0c;傳輸控制協議/網際協議&#xff09;是指能夠在多個不同網絡間實現信息傳輸的協議簇。TCP/IP 協議不僅僅指的是 TCP和 IP 兩個協議&#xff0c;而是指一個由 FTP、SMTP、TCP、UDP、I…

o2oa待辦流程和已辦流程表

在o2oa系統中每個用戶有兩種唯一標識&#xff1a;第一種是姓名個人釘釘ID&#xff08;或者o2oa創建該用戶時設置的id&#xff09;ORG_PERSON.xdistinguishedName劉準3013692136672430P第二種是姓名所在部門的釘釘id個人釘釘idORG_IDENTITY.xdistinguishedName劉準966488616_301…

QT零基礎入門教程

基礎篇第一章 QT 基礎認知1.1 什么是 QT&#xff08;What&#xff09;?定義&#xff1a;跨平臺 C 應用開發框架&#xff0c;不僅用于 UI 設計&#xff0c;還包含核心功能&#xff08;如事件、網絡、數據庫&#xff09;。?核心特性&#xff1a;?跨平臺&#xff1a;一套代碼支…

遠程依賴管理新范式:cpolar賦能Nexus全球協作

文章目錄 前言一. Docker安裝Nexus二. 本地訪問Nexus三. Linux安裝Cpolar四. 配置Nexus界面公網地址五. 遠程訪問 Nexus界面六. 固定Nexus公網地址七. 固定地址訪問Nexus 前言 Nexus作為一款企業級倉庫管理工具&#xff0c;其核心功能在于集中管理各類軟件依賴&#xff0c;提供…

Prompt技術深度解析:從基礎原理到前沿應用的全面指南

引言 在人工智能技術飛速發展的今天&#xff0c;Prompt技術&#xff08;提示詞工程&#xff09;已成為連接人類智慧與機器智能的重要橋梁。隨著GPT-4、Claude、Gemini等大型語言模型的廣泛應用&#xff0c;如何有效地與這些AI系統進行交互&#xff0c;已成為決定AI應用成功與否…

性能測試工具Jmeter之java.net.BindException: Address already in use

首先請參考連接&#xff1a;https://blog.csdn.net/weixin_46190208/article/details/115229733 。配置完注冊表后一般就能解決問題。但并未解決我的問題 注冊表的MaxUserPort&#xff0c;TcpTimedWaitDelay兩個參數我只能配置MaxUserPort&#xff0c;設置TcpTimedWaitDelay后&…

JDK 新特性

JDK 新特性引入模塊Java 9 開始引入了模塊&#xff08;Module&#xff09;&#xff0c;目的是為了管理依賴。使用模塊可以按需打包 JRE 和進一步限制類的訪問權限。接口支持私有方法JAVA 9 開始&#xff0c;接口里可以添加私有方法&#xff0c;JAVA 8 對接口增加了默認方法的支…

如何高效應對網站反爬蟲策略?

現在大型網站的反爬策略越來越高明了&#xff0c;不僅是對IP訪問頻率、User-Agent請求頭進行異常識別&#xff0c;還會分析IP地址、瀏覽器指紋、JS動態加載、API逆向、行為模式等方式各種設卡&#xff0c;動不動跳出五花八門的驗證碼&#xff0c;非常難搞。 怎么應對反爬是個系…

c++ shared_ptr理解

不是一個智能指針對于一個計數器嗎&#xff1f;怎么變成共有資源的計數器了&#xff1f;你的意思是多個對象共用一個計數器&#xff1f;你問到了 std::shared_ptr 最核心、最精妙的設計機制&#xff01;你的問題非常深刻&#xff1a;“不是一個智能指針對應一個計數器嗎&#x…

002 Rust環境搭建

Rust環境搭建 現在很多集成開發環境(IDE)基本上都支持Rust開發。官方公布的支持工具&#xff1a;https://www.rust-lang.org/zh-CN/tools 這里以Windows 10 64位系統 Visual Studio Code為例來搭建Rust開發環境。 Rust安裝 Rust 的編譯工具依賴 C 語言的編譯工具&#xff0…

【Unity進階】Unity發布PC端,隱藏并自定義默認標題欄

開發環境&#xff1a; Unity2019.3.16f1c1 - 個人版 Visual Studio Community 2019 Windows10 專業版 x64嘿&#xff0c;各位朋友們&#xff01;當咱們歡歡喜喜地把項目打包成PC平臺的exe窗口程序&#xff0c;準備在電腦上一展游戲風采時&#xff0c;卻發現冒出來個Windows風格…

國產延時芯片EH3B05上電延時3秒開關機芯片方案超低功耗

EH3B05-4941-24A1延時開關芯片是一款專為低功耗電子產品設計的高效時序控制器件&#xff0c;其核心功能在于提供精確的多通道延時信號輸出。該芯片采用SOT23-6超小封裝&#xff0c;體積僅為2.9mm2.8mm1.3mm&#xff0c;特別適合空間受限的便攜式設備。其工作電壓范圍覆蓋2.0V至…

大數據與財務管理專業如何轉型做金融科技?

在數字經濟加速演進的今天&#xff0c;金融行業的邊界正在被數據與技術重新定義。傳統金融崗位正經歷深刻變革&#xff0c;而"金融科技"&#xff08;FinTech&#xff09;作為技術與金融深度融合的產物&#xff0c;已成為行業轉型升級的核心引擎。越來越多具備數據背景…