From c51749d5167575f0a82180fe0e475396bfad2c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cyiyousong=E2=80=9D?= <鈥測ousong_yi@foxmail.com鈥�> Date: Mon, 15 Jul 2024 13:56:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- portal-manager-ui/admin/src/api/user.js | 10 + .../components/licenseHint/LicenseHint.vue | 229 ++++++++++++++++++ .../admin/src/components/licenseHint/index.js | 26 ++ portal-manager-ui/admin/src/main.js | 3 + .../admin/src/request/request.js | 4 +- portal-manager-ui/admin/src/router/index.js | 4 + .../admin/src/store/modules/user.js | 12 + .../admin/src/views/signIn/signIn.vue | 26 +- 8 files changed, 311 insertions(+), 3 deletions(-) create mode 100644 portal-manager-ui/admin/src/components/licenseHint/LicenseHint.vue create mode 100644 portal-manager-ui/admin/src/components/licenseHint/index.js diff --git a/portal-manager-ui/admin/src/api/user.js b/portal-manager-ui/admin/src/api/user.js index ca54a2b3..cc39d461 100644 --- a/portal-manager-ui/admin/src/api/user.js +++ b/portal-manager-ui/admin/src/api/user.js @@ -28,3 +28,13 @@ export function editPassword(params) { export function changeForgotPassword(params) { return http.post(`${baseURL}/zwfw/user/forgot/password`, params); } + +// 璇佷功鏈夋晥鏈熸娴� +export function checkCipher(params) { + return http.get(`${baseURL}/zwfw/cipher/check`, params); +} + +// 璇佷功涓婁紶 +export function uploadCipher(params) { + return http.post(`${baseURL}/zwfw/cipher/upload`, params); +} diff --git a/portal-manager-ui/admin/src/components/licenseHint/LicenseHint.vue b/portal-manager-ui/admin/src/components/licenseHint/LicenseHint.vue new file mode 100644 index 00000000..b42eea63 --- /dev/null +++ b/portal-manager-ui/admin/src/components/licenseHint/LicenseHint.vue @@ -0,0 +1,229 @@ +<template> + <div class="license-hint" v-if="show"> + <div class="card"> + <div class="header"> + <span class="icon"> + <svg + fill="currentColor" + viewBox="0 0 20 20" + xmlns="http://www.w3.org/2000/svg" + > + <path + clip-rule="evenodd" + d="M18 3a1 1 0 00-1.447-.894L8.763 6H5a3 3 0 000 6h.28l1.771 5.316A1 1 0 008 18h1a1 1 0 001-1v-4.382l6.553 3.276A1 1 0 0018 15V3z" + fill-rule="evenodd" + ></path> + </svg> + </span> + <p class="alert">璇佷功杩囨湡鎻愮ず锛�</p> + </div> + + <p class="message">{{ licenseInfo.msg }}</p> + + <div class="actions"> + <a-button class="read" :loading="loading" @click="handleUpload"> + 鐐瑰嚮涓婁紶鏂拌瘉涔� + </a-button> + + <a-button + class="mark-as-read" + :disabled="isDisabled" + @click="handleClose" + > + 鍏抽棴寮圭獥<span v-if="time">锛坽{ time }}锛�</span> + </a-button> + </div> + </div> + </div> +</template> + +<script> +import { uploadCipher, checkCipher } from "@/api/user"; +import { mapMutations, mapState } from "vuex"; +export default { + data() { + return { + accept: "application/x-zip-compressed", + loading: false, + timer: null, + isDisabled: true, + time: 0, + show: true, + }; + }, + computed: { + ...mapState("user", ["licenseInfo"]), + }, + created() { + this.countDown(); + }, + methods: { + ...mapMutations("user", ["set_licenseInfo"]), + countDown() { + this.time = this.duration; + this.timer = setInterval(() => { + this.time -= 1; + if (this.time <= 0) { + this.isDisabled = false; + this.time = 0; + clearInterval(this.timer); + } + }, 1000); + }, + handleClose() { + // if (this.isDisabled) return; + this.show = false; + }, + async handleUpload() { + let file = await this.getFile(); + if (!file) return; + this.loading = true; + let formData = new FormData(); + formData.append("file", file[0]); + let res = await uploadCipher(formData); + this.loading = false; + if (res.code == 1) { + this.checkCipher(); + } + }, + // 妫€娴嬬郴缁熻瘉涔� + async checkCipher() { + let res = await checkCipher(); + if (res.code == 1) { + let { startTime, endTime } = res.data; + let msg = `璇佷功涓婁紶鎴愬姛锛岃瘉涔︽湁鏁堟湡锛�${startTime} 鑷� ${endTime}`; + this.set_licenseInfo({ + isExpire: false, + msg: "", + }); + this.$message.success(msg); + this.show = false; + } else { + this.set_licenseInfo({ + isExpire: true, + msg: res.msg, + }); + } + }, + + // 鑾峰彇鏂囦欢 + getFile() { + let input = document.createElement("input"); + document.body.appendChild(input); + return new Promise((resolve, reject) => { + Object.assign(input, { + accept: this.accept, + onchange: () => { + input.files ? resolve(input.files) : reject(); + }, + multiple: false, + onerror: reject, + type: "file", + hidden: true, + value: null, + }); + input.click(); + document.body.removeChild(input); + }); + }, + }, + beforeDestroy() { + clearInterval(this.timer); + }, +}; +</script> + +<style lang="less" scoped> +.license-hint { + width: 100%; + height: 100%; + position: fixed; + left: 0px; + top: 0px; + display: flex; + justify-content: center; + align-items: center; + background-color: rgba(0, 0, 0, 0.5); + z-index: 1000; + .card { + width: 320px; + border-radius: 16px; + background-color: #fff; + padding: 16px; + } + + .header { + display: flex; + align-items: center; + grid-gap: 16px; + gap: 16px; + } + + .icon { + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: #0857e8; + padding: 8px; + color: rgba(255, 255, 255, 1); + } + + .icon svg { + height: 16px; + width: 16px; + } + + .alert { + font-weight: 600; + color: rgba(107, 114, 128, 1); + } + + .message { + margin-top: 16px; + color: rgba(107, 114, 128, 1); + line-height: 24px; + } + + .actions { + margin-top: 20px; + } + + /deep/.ant-upload { + width: 100%; + } + + .mark-as-read, + .read { + width: 100%; + height: 44px; + // display: flex; + // align-items: center; + // justify-content: center; + // cursor: pointer; + border: none; + border-radius: 8px; + font-weight: 600; + } + + .read { + background-color: #0857e8; + color: rgba(255, 255, 255, 1); + } + + .mark-as-read { + margin-top: 8px; + background-color: rgba(249, 250, 251, 1); + color: rgba(107, 114, 128, 1); + transition: all 0.15s ease; + } + + .mark-as-read:hover { + background-color: rgb(230, 231, 233); + } + // .mark-as-read[disabled] { + // cursor: not-allowed; + // } +} +</style> diff --git a/portal-manager-ui/admin/src/components/licenseHint/index.js b/portal-manager-ui/admin/src/components/licenseHint/index.js new file mode 100644 index 00000000..fc922ed9 --- /dev/null +++ b/portal-manager-ui/admin/src/components/licenseHint/index.js @@ -0,0 +1,26 @@ +import vue from "vue"; +import LicenseHintModal from "./LicenseHint.vue"; +import store from "@/store"; // 瀵煎叆 Vuex store 瀹炰緥 +const licenseHintModal = vue.extend(LicenseHintModal); +function showLicenseHintModal(duration = 5) { + const existingModal = document.getElementById("licenseHintModal"); + if (!existingModal) { + const dom = new licenseHintModal({ + store, + el: document.createElement("div"), + data() { + return { + duration: duration, + }; + }, + }); + dom.$el.id = "licenseHintModal"; + document.body.appendChild(dom.$el); + } +} + +function registryModal() { + vue.prototype.$licenseHintModal = showLicenseHintModal; +} + +export default registryModal; diff --git a/portal-manager-ui/admin/src/main.js b/portal-manager-ui/admin/src/main.js index 513d5034..24fd767c 100644 --- a/portal-manager-ui/admin/src/main.js +++ b/portal-manager-ui/admin/src/main.js @@ -63,6 +63,9 @@ Vue.prototype.$bus = new Vue(); // swiper import "swiper/css/swiper.min.css"; +// 娉ㄥ唽璇佷功杩囨湡鎻愮ず寮圭獥 +import registryModal from "@/components/licenseHint"; +Vue.use(registryModal); Vue.config.productionTip = false; // 鍥剧墖棰勮 diff --git a/portal-manager-ui/admin/src/request/request.js b/portal-manager-ui/admin/src/request/request.js index ac481913..eb3ec08b 100644 --- a/portal-manager-ui/admin/src/request/request.js +++ b/portal-manager-ui/admin/src/request/request.js @@ -42,7 +42,7 @@ axios.interceptors.response.use( message.error({ content: msg, maxCount: 1, - duration: 1, + duration: 2, }); if (msg === "闈炴硶鐢ㄦ埛,涓嶅彲璁块棶") { store.commit("user/reset"); @@ -117,7 +117,7 @@ axios.interceptors.response.use( message.error({ message: error.message, maxCount: 1, - duration: 1, + duration: 2, }); return Promise.resolve(error.response); diff --git a/portal-manager-ui/admin/src/router/index.js b/portal-manager-ui/admin/src/router/index.js index d362a677..5f4803ab 100644 --- a/portal-manager-ui/admin/src/router/index.js +++ b/portal-manager-ui/admin/src/router/index.js @@ -27,6 +27,10 @@ router.beforeEach((to, from, next) => { // let bol = hasIntersection(toRootPathArr, routerPath); if (islogin) { next(); + let licenseInfo = store.getters["user/licenseInfo"]; + if (licenseInfo.isExpire) { + Vue.prototype.$licenseHintModal(); + } // if (routerPath.includes(to.path) || bol) { // next(); // } diff --git a/portal-manager-ui/admin/src/store/modules/user.js b/portal-manager-ui/admin/src/store/modules/user.js index a0b786d1..6217484f 100644 --- a/portal-manager-ui/admin/src/store/modules/user.js +++ b/portal-manager-ui/admin/src/store/modules/user.js @@ -12,6 +12,11 @@ export default { siteId: "", // 绔欑偣id searForm: {}, // 鎶ヨ〃鎼滅储 routerList: [], // 鐢ㄦ埛鏉冮檺璺敱 + licenseInfo: { + // 绯荤粺璇佷功淇℃伅 + isExpire: false, // 鏄惁杩囨湡, + msg: "", // 杩囨湡鎻愮ず淇℃伅 + }, }, getters: { siteId: (state) => state.siteId, @@ -29,6 +34,9 @@ export default { siteTreeList(state) { return state.siteList; }, + licenseInfo(state) { + return state.licenseInfo; + }, }, mutations: { SET_routerList(state, routerList) { @@ -58,6 +66,10 @@ export default { set_siteId(state, siteId) { state.siteId = siteId; }, + set_licenseInfo(state, { isExpire, msg }) { + state.licenseInfo.isExpire = isExpire; + state.licenseInfo.msg = msg; + }, // 閲嶇疆鎵€鏈変粨搴撶姸鎬� reset: () => {}, }, diff --git a/portal-manager-ui/admin/src/views/signIn/signIn.vue b/portal-manager-ui/admin/src/views/signIn/signIn.vue index 7974b423..202d5917 100644 --- a/portal-manager-ui/admin/src/views/signIn/signIn.vue +++ b/portal-manager-ui/admin/src/views/signIn/signIn.vue @@ -248,7 +248,12 @@ <script> import Swiper from "swiper"; -import { LoginInterface, changeForgotPassword, getSlogan } from "@/api/user.js"; +import { + LoginInterface, + changeForgotPassword, + getSlogan, + checkCipher, +} from "@/api/user.js"; import { mapMutations, mapState } from "vuex"; import { changeAccount, changePassWord } from "@/utils/js/validate"; import { encrypt, findSitesById } from "@/utils"; @@ -329,7 +334,9 @@ export default { this.createCode(); }, mounted() { + this.checkCipher(); this.initSwiper(); + this.$licenseHintModal(); }, methods: { ...mapMutations("user", [ @@ -337,7 +344,24 @@ export default { "SET_USERDATA", "set_siteList", "SET_routerList", + "set_licenseInfo", ]), + // 妫€娴嬬郴缁熻瘉涔︽槸鍚﹁繃鏈� + async checkCipher() { + let res = await checkCipher(); + if (res.code == 1) { + this.set_licenseInfo({ + isExpire: false, + msg: "", + }); + } else { + this.set_licenseInfo({ + isExpire: true, + msg: res.msg, + }); + this.$licenseHintModal(); + } + }, getTitle() { getSlogan("signImg").then((res) => { if (res.code == 1) { -- 2.24.3